Search Results for 'script'
Tap Forms Database Pro for Mac, iPhone, iPad and Apple Watch › Forums › Search › Search Results for 'script'
-
AuthorSearch Results
-
June 11, 2021 at 2:16 PM #44601
In reply to: iOS: Display linked child records?
Brendan
KeymasterHi Redrock,
There’s no custom layouts function on the iOS version of Tap Forms.
And linked records always display in a separate list on iOS. At some point I might change that to display like the Table field does, which displays inline on the parent record as a table of sub-records.
So if you need to display things visually like that, you would want to use a Table field instead of a Link to Form field.
Or alternatively, you could write a script which picks out a field from the Link to Form field’s form and displays that in a list of values on the parent record.
Thanks,
Brendan
June 10, 2021 at 11:38 PM #44595In reply to: Get Movie Details from TheMovieDB API (Help Needed)
Sam Moffatt
ParticipantYou’re using a bunch of global variables, each time you do
var thingthenthingbecomes a global variable when you’re doing it outside of a function. That’s why you can use the variables almost anywhere though in general that’s not best practice. The prompter uses this technique in part because it’s an async call but once we’ve stepped out of that, it’s best to use actual arguments and return values. When you dovarinside the function, it’s scoped to the function and not accessible outside it. Let’s rewrite this slightly to use an input variable forinputIDand return a value:function convertIMDBtoTMDB(inputID) { fetchURL = ` https : // api.themoviedb.org/3/find/${inputID}?api_key=${tmdbAPI}&language=en-US&external_source=imdb_id`; var tmdbResp = Utils.getJsonFromUrl(fetchURL); var tmdbID = tmdbResp.movie_results[0].id; console.log(JSON.stringify(tmdbID)) if (! tmdbID) { console.log("Request to get code failed"); return ""; } else { return tmdbID; } }Same function except we’re accepting an inputID as an argument and then returning the
tmdbID. I left thetmdbAPIalone because I feel it’s a constant more than a variable and something you’d want to leave in global scope. Where possible you want to explicitly tell a function what it’s inputs are, in this case literallyinputIDbut even in the other places it’s better to be explicit:function fetchCreditsFromURL(itemID) { fetchURL = `https://api.themoviedb.org/3/movie/${itemID}/credits?api_key=${tmdbAPI}&language=en-US`; return Utils.getJsonFromUrl(fetchURL); }That way you know where a variable is coming from and you’re less likely to have a variable in global scope accidentally trashed. Nothing in Javascript is straight forwards so I was looking for a good resource and this page on demystifying Javascript variable scope has some great details on how it works and where some of the pitfalls are.
Instead of relying on the global changing, assign it to a variable in the right scope and then pass it along to anything else that needs it. Hopefully that helps get you a little further :)
June 10, 2021 at 1:14 AM #44591In reply to: Shopping List
robinsiebler
ParticipantOk, I added the checkmark field. In addition, I added a Search Filter for unchecked items and a script you can use to remove checked items.
Attachments:
You must be logged in to view attached files.June 9, 2021 at 3:13 PM #44585In reply to: Shopping List
robinsiebler
ParticipantSO just to verify:
1. If you manually add an item to the Shopping List, the categopy is not added.
2. If you manually run the script, the category is added.
3. If you run the Shortcut the category is added.If all of that is true, I think all that I have to do is a add a field script to the Shopping List form that will update the category.
I will try that and get back to you.
June 9, 2021 at 3:06 PM #44584In reply to: Shopping List
Roger Cuthbert
ParticipantI added Naan manually and the shopping list record did not add the category.
I created a shortcut as you suggested. Added Naan to the clipboard and ran your script and the category is added correctly.
June 9, 2021 at 12:51 PM #44583In reply to: Shopping List
robinsiebler
ParticipantAnd the item you are adding is in the Product form and has a category? If so, could you try this? Add the item in question to the clipboard and just run the script ‘Get Item from Clipboard’. Let me know what happens.
June 9, 2021 at 2:33 AM #44572In reply to: Shopping List
robinsiebler
ParticipantI fixed some bugs and added a notes field. I also added another 100 products to the products form. In addition, I updated the Shortcut to prompt for a note (see screen shot). However, Siri is stupid! If you say ‘No’ when you are prompted for a note, Siri bails on the entire script! So, instead of saying ‘No’, say ‘Later’ and you will not be prompted for the note.
I should mention that you have to manually create the Shortcut using the attached screenshot as a guide. I have no clue how to share a shortcut outside of the Apple ecosystem.
Attachments:
You must be logged in to view attached files.June 7, 2021 at 6:05 PM #44565In reply to: Shopping List
robinsiebler
ParticipantI added over 200 products to the products database and also added the ‘Combine Items’ script
Attachments:
You must be logged in to view attached files.June 7, 2021 at 4:24 PM #44564In reply to: Shopping List
robinsiebler
ParticipantI added a script (Combine Items) to combine duplicate items into one.
function combineItems() { // Combine duplicate items into one item var dict = {}; var records = form.getRecords(); var item_id = 'fld-097c3d751c854b1fb4b528238d48b2c4'; var quantity_id = 'fld-285e2c9de4924b7fbba2fd8311ceb625'; for (var i = 0, count = records.length; i < count; i++){ item = records.getFieldValue(item_id); quantity = records.getFieldValue(quantity_id); record_id = records.getId(); if (dict[item] === undefined) { dict[item] = [quantity, record_id]; } else { dict[item][0] = dict[item][0] + quantity; form.deleteRecord(records); rec = form.getRecordWithId(dict[item][1]); rec.setFieldValue(quantity_id, dict[item][0]); form.saveAllChanges(); } } } combineItems();June 7, 2021 at 12:22 PM #44563In reply to: Get Movie Details from TheMovieDB API (Help Needed)
Sam Moffatt
ParticipantLet’s take a step back and look at focusing on just handling the object we’re getting back. Looking at the API, it’s returning an object and then an array for cast. Let’s look at what printing that out could look like as a script. I’m going to remove the variables in the header and prompter at the bottom just to cut down a little and let us focus.
// variables header above here function fetchCastFromURL() { fetchURL = `https://api.themoviedb.org/3/movie/${itemID}/credits?api_key=${tmdbAPI}&language=en-US`; return Utils.getJsonFromUrl(fetchURL); } function getCast() { var cast = fetchCastFromURL(); return cast; } function getData() { getCast(); } // prompter code below hereThat’s not going to do a lot beyond (hopefully) make the web request. Let’s expand
getCasta little:function getCast() { var cast = fetchCastFromURL(); console.log(JSON.stringify(cast)); return cast; }All going well you should see the same JSON representation in the console as we would see from the API. Sometimes
castcan be falsy if the request fails, so let’s handle that:function getCast() { var cast = fetchCastFromURL(); if (!cast) { console.log("Request to get cast failed"); return []; } console.log(JSON.stringify(cast)); return cast; }We’re just going to return an empty array here and log a message when we fail the request. The
castresult is actually acreditsobject, so let’s do a little rename of our methods and return the internalcastresponse:function fetchCreditsFromURL() { fetchURL = `https://api.themoviedb.org/3/movie/${itemID}/credits?api_key=${tmdbAPI}&language=en-US`; return Utils.getJsonFromUrl(fetchURL); } function getCast() { var credits = fetchCreditsFromURL(); if (!credits) { console.log("Request to get credits failed"); return []; } console.log(JSON.stringify(credits)); return credits.cast ? credits.cast : []; }When we look at the documentation,
castis listed as an optional array element inside thecreditsresponse object. This means if it is set it should becredits.cast, you can see why we renamed the variables now. The?syntax is a ternary operator and what we’re doing is checking ifcredits.castis truthy and if it is we return it otherwise we hand back an empty array.Now it’s time to expand out
getData()and we’re going to put a loop in just to see what we get back:function getData() { let cast = getCast(); for (let castMember of cast) { console.log(castMember.name); } }All going well when this is tested we should see an array of cast members’ names printed out into our console. We might have an empty array returned and if that was an error hopefully we also got a log message saying as much (e.g. the “Request to get credits failed”) but otherwise we’ve got our listing of cast members that we can iterate over now. Let’s put the bulk of
getData()back together and we’ll add some code to create a new record via a link to form field or table field:function getData() { var film = fetchDetailsFromURL(); var imdbID = film.imdb_id; console.log(imdbID) var itemIds = new Set(); var currentItemsByImdbID = {}; var allCurrentItems = form.getRecords(); for (let currentItems of allCurrentItems) { currentItemsByImdbID[currentItems.getFieldValue(imdbid_id)] = currentItems; itemIds.add(currentItems.getFieldValue(imdbid_id)); } let newRecord; if (itemIds.has("http://imdb.com/title/" + imdbID)) { Utils.alertWithMessage(film.title + ' already exists.', 'Sorry.'); } else { newRecord = form.addNewRecord(); newRecord.setFieldValues({ [title_id]: film.title, [released_id]: film.release_date, [imdbid_id]: "http://imdb.com/title/" + film.imdb_id, [summary_id]: film.overview, [runtime_id]: film.runtime, [tagline_id]: film.tagline, }); document.saveAllChanges(); let cast = getCast(); for (let castMember of cast) { let actorRecord = newRecord.addNewRecordToField(cast_table_field_id); actorRecord.setFieldValues({ [actor_id]: castMember.name, [role_id]: castMember.character, [tmdb_actor_id]: castMember.id }); document.saveAllChanges(); } } var Poster = "https://www.themoviedb.org/t/p/w1280/" + film.poster_path if (Poster != null) { newRecord.addPhotoFromUrlToField(Poster, poster_id); } form.saveAllChanges(); }We’ve pulled back in the original
getData()and I’ve added a block for getting the cast and inside it we’re usingaddNewRecordToFieldto get a new record (similar toform.addNewRecord) added to the table field of the record we just created. Behind the scenes this ensures that Tap Forms links the data for us properly. We usesetFieldValuesas was done earlier because we’re just working with a record object (albeit one that’s a record in a table). I also add in two precautionarydocument.saveAllChanges()because when dealing with record creation and record linking via the scripting interface there are some quirks that can appear and explicitly flushing the state down generally makes that more consistent. Thedocument.saveAllChanges()call is an alias forform.saveAllChanges()and does the same thing.I think this should work or at the very least get you a little closer to your journey.
June 7, 2021 at 12:15 PM #44557Topic: Shopping List
in forum Tap Forms Template Exchangerobinsiebler
ParticipantSomeone expressed and interest in this, so I am uploading it. Thanks to Sam for all his help!
This is a simple Shopping List. There are 3 forms. The actual shopping list form, a category form and a products form (which contains the items to populate the shopping list with).
Adding an item to the shopping list is done via a Siri Shortcut (see attached screenshot).
The expected input to the shortcut is <number> item. If a number is not provided, 1 is assumed. For example, you could say ‘3 Peaches’ or ‘Heavy Cream’.
When an item is added to the shopping list, it will see if it exists in the product form. If it does, the item will be also given a category (if it exists). If the item does not exist, it will be added to products, but it will not have a category (this will have to be added manually).
Items are sorted in the Shopping List alphabetically, by category.
There is only 1 script ‘Get Item From Clipboard’ and it does all the work.
Enjoy!
Attachments:
You must be logged in to view attached files.June 7, 2021 at 10:47 AM #44555Sam Moffatt
ParticipantSome of the challenges of the Shortcuts interface is that if there is any error in your script, you not only don’t get to see it but also then you get the behaviour where Shortcuts times out because it is waiting for a response that it’ll never get. One of the other issues is that if you have anything that invokes a UI interaction then that will get blocked. And finally we found out late last year that along the way Apple is nuking the clipboard contents so if you’re relying upon that then you’d be out of luck.
This does mean that it’s limited in what capabilities it can do at the moment. I was thinking about it the other day and I think if it accepted a string and returned a string to Shortcuts then we’d be able to input data into the script and it can be as structured, or unstructured, as necessary for the script to handle.
June 7, 2021 at 2:27 AM #44548Topic: Bug: Using Siri/Shortcuts to launch a script doesn’t work
in forum Script Talkrobinsiebler
ParticipantI created a document/form/script. The script worked just fine in Tap Forms. Then I added the script to Siri. I created a Shortcut that used the action to execute the script in the form. However, it did NOT work; I got an error saying that the run was taking too long.
When I switched to using the x-callback (as suggested), everything was happy.
The document in question and a screenshot of the shortcut can be found in this thread
June 7, 2021 at 12:44 AM #44546In reply to: How to create a Shopping List database
Sam Moffatt
ParticipantThe
getFieldNamedcall will return a TFField object not the field ID that you need. I think to make your code work, you’d need to do:var itemField = sl.getFieldNamed('Item'); var quantityField = sl.getFieldNamed('Quantity'); newRecord.setFieldValue(itemField.getId(), item); newRecord.setFieldValue(quantityField.getId(), quantity);Personally I use the field ID’s as inserting them is easy enough in the editor.
I also generally use the x-callback interface with the script URL to invoke Tap Forms that way. You can use “Copy Script Link” from the menu in the script editor to get a link.
June 6, 2021 at 9:40 PM #44545In reply to: How to create a Shopping List database
robinsiebler
ParticipantIs there a way to disable the pop up dialog when you run a script?
-
AuthorSearch Results