Search Results for 'script'
Tap Forms Database Pro for Mac, iPhone, iPad and Apple Watch › Forums › Search › Search Results for 'script'
-
AuthorSearch Results
-
May 26, 2020 at 7:39 AM #40703
In reply to: Whether to use a script or a calculation?
Sam Moffatt
ParticipantYou don’t need to use a function but having the function allows you to use the
returnstatement to curtail execution flow. Without it you have to make sure the last value you set in your script is the value you want to set your script field to and using a function makes this neater for more complicated scripts. As you get down the track, using functions allows you an extra layer of encapsulation that can be useful for embedding scripts. I have a form script that I embed in other form scripts to do bulk creation. That works in part due to the use of a function to encapsulate the Javascript variables in a way that doesn’t interfere.You need to change the format of your script field to be a number and the formatting settings should be identical to your calculation field. By default calculation fields return numbers and by default scripts return text. Just change the return type in the script editor and then the number formatting options for the field should work to get to two decimal places.
May 26, 2020 at 2:24 AM #40702In reply to: Whether to use a script or a calculation?
Victor Warner
ParticipantSam,
Belated thanks for this detailed and very helpful explanation (although what I wish to do has changed since your post).
Just a few of follow-up questions: I assume there is no functional difference, for the purposes of Tap Forms, in using or not using a function? For example there is no difference between;
function Final_Amount() { var payment_amount = record.getFieldValue('fld-bbf051ce1505486cbfc0c924b5b41029'); var izettle_charge_id = record.getFieldValue('fld-3c44182f03494f53bdb0d253d3058589'); var izettle_net_amount_received = record.getFieldValue('fld-1e49468e17dc4ff1822860d16e893418'); if (izettle_charge_id > 0) { return "Amount paid: £" + payment_amount + "\r" + "iZettle charge: £" + izettle_charge_id + "\r" + "Net amount received: £" + izettle_net_amount_received; } return ''; } Final_Amount();And:
var izettle_charge_id = 'fld-3c44182f03494f53bdb0d253d3058589'; var izettle_charge = record.getFieldValue('fld-3c44182f03494f53bdb0d253d3058589'); var payment_amount_id = 'fld-bbf051ce1505486cbfc0c924b5b41029'; var payment_amount = record.getFieldValue('fld-bbf051ce1505486cbfc0c924b5b41029'); var izettle_net_amount_received_id = 'fld-1e49468e17dc4ff1822860d16e893418'; var izettle_net_amount_received = record.getFieldValue('fld-1e49468e17dc4ff1822860d16e893418'); if (izettle_charge > 0) { result = "Amount paid: £" + payment_amount + "\r" + "iZettle charge: £" + izettle_charge + "\r" + "Net amount received: £" + izettle_net_amount_received; } else { result = ''; } result;The second question concerns formatting of numbers. The fields used in the above example are set to numbers or a calculation, and formatted for currency. For example: “12.50”, but in using the script it appears as “12.5”. Is there a way to format the number with two decimals etc?
May 25, 2020 at 8:05 PM #40699Sam Moffatt
ParticipantYou can create a script field and when you configure it to pull a value from a field, it will automatically watch the field and trigger the script. You can then use that script field to update another field in your form with what ever value you want. You can check to see if the destination field already has a value and then opt to do nothing. Another trick I’ve done is use the script field to store the previous value of the target field so that I can evaluate if I can safely update the target field to a new calculated value or not.
At it’s simplest, create a form with three fields: your source field, your destination field and a script field. Open up your script field and Tap Forms will have created a function for you that looks like this:
function Sample_Script() { // Replace with your own code var hello_world = "Hello World!"; return hello_world; } Sample_Script();The name of my script field was called “Sample Script” so the function Tap Forms generates was called “Sample_Script”. For the simplest use case, delete out the middle bit of code so that you’re left with an empty function, it should look like this:
function Sample_Script() { } Sample_Script();Click into the text editor on the right in the area you just deleted and then on the left in the field list select the two fields we’re interested in and then click on the “ID” button. If double click the name of the two fields you are interested in, it’ll insert a one line piece of code with the field ID embedded. If you click on ID it will insert just the ID. I use the latter because it makes the rest of the code make more sense than repeating the field ID. I named my fields “Source Field” and “Destination Field” which are both text fields so when I click the “ID” button, my code now looks like this:
function Sample_Script() { var source_field_id = 'fld-eb01c448b3ba4c08a20159faca0d631c'; var destination_field_id = 'fld-ac1628a83f4f4c82b256cf362691a007'; } Sample_Script();Keep in mind the field ID’s (e.g. the
fld-1234part) will be different based on your own field ID’s and the field names will be based on your own fields. Normally we indent each time we open a brace ({) and unindent when we close (}). Let’s indent our variables. You can manually intend them with the tab key or you can click the “indent selection” button to indent the lines. Let’s see what that looks like:function Sample_Script() { var source_field_id = 'fld-eb01c448b3ba4c08a20159faca0d631c'; var destination_field_id = 'fld-ac1628a83f4f4c82b256cf362691a007'; } Sample_Script();At this point we’ve only set up a “variable” to store the internal Tap Forms field ID. The next step is to get the value of the fields to check them. I’m going to get the value of the destination field first because if it is set then we can just stop the script. Fortunately Javascript is relatively loose with it’s typing so we can check if something is “falsey” easily and for our purposes that will work:
function Sample_Script() { var source_field_id = 'fld-eb01c448b3ba4c08a20159faca0d631c'; var destination_field_id = 'fld-ac1628a83f4f4c82b256cf362691a007'; var destination_field = record.getFieldValue(destination_field_id); if (!destination_field) { } } Sample_Script();What we’ve done here is get the value of the “Destination Field” and put that in
destination_field. The next line checks to see if the value is “falsey” or otherwise negative. For Javascript a variable that is unset, undefined, null, zero, an empty string or false will be considered negative or “falsey”. The exclamation mark basically negates it so that it enters theifblock whendestination_fieldis not set. Sweet!Last step is to get the value of the source field and then copy it across. The first step is to get the field value which looks like this:
var source_field = record.getFieldValue(source_field_id);Similar to the destination field code, we use the
source_field_idto get a copy of the field value intosource_field. Next step is to set the value of the destination field:record.setFieldValue(destination_field_id, source_field);For
getFieldValuewe need to provide the field ID but forsetFieldValuewe need to give it the field ID of the field we want to set and the value we want to set it to. In this case we want to set the destination field to be the value of the source field.There is one extra line we need to do when manipulating records from scripts and that is to call
form.saveAllChanges();to save our changes. When we put that together it looks like this:function Sample_Script() { var source_field_id = 'fld-eb01c448b3ba4c08a20159faca0d631c'; var destination_field_id = 'fld-ac1628a83f4f4c82b256cf362691a007'; var destination_field = record.getFieldValue(destination_field_id); if (!destination_field) { var source_field = record.getFieldValue(source_field_id); record.setFieldValue(destination_field_id, source_field); form.saveAllChanges(); } } Sample_Script();Now all going well if you save the script and create a new record when you set a value for the source field, the destination field will be set. If it doesn’t work immediately, try clicking the “Recalculate formulas” button at the bottom of the record next to the record size and colour pickers. Some times Tap Forms doesn’t immediately connect the script update and you need to refresh it to make it check for the script field updates.
You’ll notice that if you change source field again, the destination field won’t update even if you haven’t changed the value. If this is what you want without any thing else then you’re done and you don’t need to read any more here. However if you’d like it to be a little more advanced to keep updating the value until you change it then keep reading on.
I mentioned before that I sometimes use the script field to store information about the script state. You’ll notice that the script field isn’t in the field list on the left, so to figure out the field ID of the script field, create a new form script in your form, delete the contents and put the following code in:
form.getFields().forEach(field => console.log(`${field.name}: \t${field.getId()} (${field.fieldType})`));It’s a single line and when you run it in the script editor, the console log will fill up with the details we care about, here’s the sample from my run:
25/5/20, 7:23:55 pm / Tristate / Field List Source Field: fld-eb01c448b3ba4c08a20159faca0d631c (text) Destination Field: fld-ac1628a83f4f4c82b256cf362691a007 (text) Sample Script: fld-f61256199b794f02b3e8dbb8620ee87a (script)You’ll note the ID and names will match what we used earlier. I’ll make a few changes to the script to check if the previous value matches and to save the value we set for next time. Just like before our first step is to setup a variable for the field ID. Tap Forms won’t do this for us this time so we have to do it ourselves:
var sample_script_field_id = 'fld-f61256199b794f02b3e8dbb8620ee87a';That’s relatively easy, we’ll also get the value of the field as well:
var sample_script_field = record.getFieldValue(sample_script_field_id);Very similar to the code we’ve seen already. Our next step is to integrate this together and we’re going to need to change the
ifcondition. Right now it checks to see if the destination field is empty (falsey) and set it to a value. Now we want it keep that check but add another check for if the script field had a value and if it matches, which looks like this:if (sample_script_field == destination_field)Now we can rewrite our if statement to handle these two conditions: if the destination field is empty or if the destination field equals the sample script field:
if (!destination_field || sample_script_field == destination_field)Let’s plug this in together:
function Sample_Script() { var source_field_id = 'fld-eb01c448b3ba4c08a20159faca0d631c'; var destination_field_id = 'fld-ac1628a83f4f4c82b256cf362691a007'; var sample_script_field_id = 'fld-f61256199b794f02b3e8dbb8620ee87a'; var destination_field = record.getFieldValue(destination_field_id); var sample_script_field = record.getFieldValue(sample_script_field_id); if (!destination_field || sample_script_field == destination_field) { var source_field = record.getFieldValue(source_field_id); record.setFieldValue(destination_field_id, source_field); form.saveAllChanges(); } } Sample_Script();Update the script and save it then give it a go. You’ll notice it isn’t working properly, what gives? Well we need to do one more piece, we need to return the new value when we set it for the script field. If you remember the template had a
returnline in it so we need to do that here as well. When we set the field value, we should return the value that we’re setting. Then Tap Forms will store that in our script field for us, let’s update the script to add that:function Sample_Script() { var source_field_id = 'fld-eb01c448b3ba4c08a20159faca0d631c'; var destination_field_id = 'fld-ac1628a83f4f4c82b256cf362691a007'; var sample_script_field_id = 'fld-f61256199b794f02b3e8dbb8620ee87a'; var destination_field = record.getFieldValue(destination_field_id); var sample_script_field = record.getFieldValue(sample_script_field_id); if (!destination_field || sample_script_field == destination_field) { var source_field = record.getFieldValue(source_field_id); record.setFieldValue(destination_field_id, source_field); form.saveAllChanges(); return source_field; } } Sample_Script();This will return the value that we’re trying to set. If you save the script field and then create a new record you should notice that it works correctly. You’ll also see that the script field itself also contains the same value too. Now if you go to an existing record though, the script field doesn’t have a value set yet and won’t automatically update the field value. We could fix this in code however this is a bit of an edge case. To reset those records, you just need to delete the destination value and then hit enter. This will trigger the script to run and reset the value of the field to the source field then update the script field.
For you, the next step would be to code the custom logic you want to change the destination field to based on the source field but that’s obviously something for you to do. Hopefully this helps!
May 25, 2020 at 7:07 PM #40698In reply to: Script to go to a particular layout in a Form
Brendan
KeymasterOk, thanks for the use case description.
May 25, 2020 at 6:55 PM #40697Brendan
KeymasterHi Mike,
Tap Forms has a JavaScript function called
Utils.copyTextToClipboard('Some text');andvar value = Utils.copyTextFromClipboard();. So yes, you can use a script in Tap Forms to copy and paste to the clipboard.Also, Tap Forms has automatic triggers when any of your scripts get a value from a field in your form. For example,
var amount = record.getFieldValue(amount_field_id);would cause your script to automatically execute if the value of the amount field was modified.Hope that’s the information you’re looking for. The scripting instructions are here:
https://www.tapforms.com/help-mac/5.3/en/topic/scripts
And there’s the Script Talk forum on my website where you can go to talk about scripting. There’s lots of information and sample scripts there.
Thanks,
Brendan
May 25, 2020 at 4:17 PM #40696In reply to: Script to go to a particular layout in a Form
Sam Moffatt
ParticipantI have a bunch of what I call task specific layouts that make sense for each use. A simple example is my main purchases form where I have the default layout (which itself is broken up by section headings to allow me to collapse areas), a details view that actually was inspired by my original Bento layout that has a subset of the default layout, quick entry which has the fields I generally need to change the most inputting a purchase, relationships which gives me an overview of how the record is connected to it’s related forms (line items, gallery, sibling purchase entries and shipments) and a quick details which is a much more limited overview that fits on all of my devices without scrolling. There’s a QR pane as well but I rarely use that, it was something I was experimenting with for printing and wouldn’t want to review.
I have scripting I use to jump into Tap Forms at various places (perhaps not surprising based on the forum posts) and having layout support would be useful. I could see for others having workflow integration from external applications though obviously I can only speak for my uses.
May 25, 2020 at 3:33 PM #40695In reply to: Auto create records with photos
Sam Moffatt
ParticipantI have a bunch of processes where I scan in receipts and have those automatically upload into a Tap Forms document via the CouchDB sync. I wrote a blog post on using PHP and CouchDB to upload receipts which could be modified to do a similar thing for your own project.
I have some local changes that I need to clean up as well that make it a little easier to configure but that approach would work. I use it with a scanner but if you dropped files in the directory using any program then it’ll pick them up and import them. If there is special encoding in your filename then you could also use the PHP script to extract that into a field as you import them into CouchDB as well. CouchDB sync with Tap Forms then will pull the changes back into Tap Forms where you can edit the newly uploaded entries.
I have a few different uses these days beyond my fuel receipts that I wrote in the blog post, I set one up for my work related expenses as receipts and I also now scan invoices for purchases I receive from different vendors. In the past I’ve used similar scripts to bulk import images as well, at one point I imported a copy of Digital Blasphemy’s ZIP files into a Tap Forms document.
May 25, 2020 at 2:25 PM #40694Mike Mullin
ParticipantHi Brendan,
I’m a former Ninox user and I remember it has a function called “Trigger after update” where you can create some sort of formula which extracts certain field data (i.e. text or number data) and copy/paste the data into a regular text or number field. If you then double click these regular text or number fields you can customize the data.
Let me explain why I want to do this.
I have a form called “Billable items”. This form has records with a text description field and a price field. To create an invoice I’m selecting records from this form (Link to Form). I sometimes want to change or add words to the description field or adjust a price (i.e. if I want to give my client a certain discount). I don’t want to create a new record for every adjustment because within a short amount of time the record list will expand and I lose overview of all the available records.
Is copy/pasting field data and then customizing the data something which can be done in Tap Forms using Javascript? (Sorry, I have no knowledge of Javascript (yet ;-))
Best,
Mike
May 25, 2020 at 8:33 AM #40684In reply to: Script error – what it means?
Victor Warner
ParticipantSam,
Thank for the further reply,
I eventually worked out how to use
search.getREcords()
, by replacing:
for (let rec of form.getRecords()){with
for (let rec of search.getRecords()){Just one follow-up question: Does the it only work with an advanced search and not an ordinary search (Command + F)? I have tried with an ordinary search but the script does not operate.
May 25, 2020 at 7:15 AM #40682Topic: Auto create records with photos
in forum Using Tap Forms 5Marc Reichert
ParticipantHello everyone,
Tap Forms seems like the perfect solution to what I have to do and I think I will buy the Mac version regardless of the outcome of this question.
I am not sure if I can create a fully automated solution to the following problem as I have read about the problem of local file access restrictions in this forum. Nevertheless, I did not find an entry in the forum or in the support area that was specific enough to give me a final answer and I could imagine that this could also help others.The task is to catalog a really large amount of artwork, including photographing and collecting all of the metadata like size and type with a small preview image in a database (which appears to be Tap Forms).
To achive maximum throughput, I want to print labels with barcodes in advance (they have to be durable and good thermal transfer label printers are prohibitively expensive, so printing the labels afterwards is not an option). Then I would place a barcode on the back of the artwork and scan the code in the photo software to generate coherent file names for the images. These images are saved, for example, in a shared folder.
The perfect solution from there on would be to use Automator to create a “folder action” that runs a script to generate a new database record with the image and ID based on the file name each time an image is added to the folder.Am I right that this is not possible due to the limitations of sandboxing? Or can I bypass those by sending those files to the Mac via the FTP-Connection or by directly writing them into the Tap Forms Documents area?
Are there other ways to automate something in this process?Thanks in advance
MarcMay 21, 2020 at 6:29 PM #40672In reply to: Script to go to a particular layout in a Form
Brendan
KeymasterLayouts in menu done. And working on allowing you to switch layouts from a Script.
May 21, 2020 at 9:56 AM #40670In reply to: Script to go to a particular layout in a Form
Victor Warner
ParticipantThank you for both comments.
Ideally, it would be very helpful to layouts also available from a menu, in the same that forms (and in a similar to FileMaker).
Without either JavaScript support or menu support it is not possible to ‘reach’ layouts other than manually (unless I am missing something) – particularly if you have a lot of layouts which run off the right of a page.
I do hope that Brendan can improve this area of Tap Forms in the next major update.
May 21, 2020 at 12:26 AM #40666In reply to: Missing SOME Images
Sam Moffatt
ParticipantI use sync with attachment heavy databases via CouchDB without significant issues. I can’t comment on the Nearby sync but it’s the same technology. iCloud has a long history of issues and I’m not surprised at the posts about TF having sync issues with iCloud. I also find iCloud brutally slow due to their rate limiting which is ameliorated with running ones own CouchDB server.
The one challenge with a distributed peer to peer replication topology is that when there are conflicts due to changes on multiple devices that sooner or later conflict resolution generally involves discarding a change. Nearby sync is also unidirectional so you need to make sure both sides are pulling changes otherwise you can introduce conflicts quickly (when you add a remote device to Nearby sync, you pull it’s changes but you don’t push your changes; you need to add your local device to the remote device for bidirectional sync). iCloud sync will also have this problem which I feel can be exacerbated due to the throttling it puts in place. I’ve also seen this with CouchDB as well where I need to make sure I wait for sync to finish otherwise my edit of the older version of the record can wipe out other changes.
Many moons ago there was an issue with the sync system around attachments where it would have a mismatched internal revision identifier but that has been fixed for what feels like years now and myself I’ve not seen any issues. I did run into a recent change that CouchDB 3.x set the document size limit to 8MB which broke a few records of mine that had high resolution images embedded in a notes field. That was fixed by removing said high resolution images from those fields.
I will say one thing I’ve noticed is sometimes if I pick up a device that hasn’t been sync’d for a while it can introduce some weirdness with stuff being picked up. I haven’t seen this behaviour for a while but there were some times it felt like conflict resolution got it wrong. Again with a stable CouchDB server this seems less problematic.
The other advantage of setting up a CouchDB server is you can also set up backups and versioning. You can checkout my GitHub repo for how to get it setup and running which will give you an extra safety net for both the documents and any attachments. I run this backup script on a 2011 iMac I have to keep track of my documents. I also use a backup of my documents via Time Machine as well but that’s more for ensuring I can rewind a document if something gets corrupted.
May 20, 2020 at 11:52 PM #40665In reply to: Maintaining Linked Field Values via Scripting
Sam Moffatt
ParticipantI was running into an issue where the record state for a Link field wasn’t updated properly within a script context. I ended up solving it by adding an explicit
form.saveAllChanges()after I did aaddRecordToField(). If I didn’t do that, I ended up in these weird situations where the inverse relationship metadata wasn’t setup properly which caused weirdness with script fields that were triggered. Might I suggest adding it not just at the return but each time you manipulate a link field.May 20, 2020 at 9:57 AM #40660Topic: Script to go to a particular layout in a Form
in forum Script TalkVictor Warner
ParticipantI suspect that the answer to this question is ‘no’: is it possible to use a Form script to select a particular layout in a particular form of a document?
-
AuthorSearch Results