Tap Forms app icon half
Tap Forms Forum text image
Blue gradient background

Exchange tips and ideas with the Tap Forms community

Search Results for 'script'

Viewing 15 results - 2,311 through 2,325 (of 3,049 total)
  • Author
    Search Results
  • #37905
    Brendan
    Keymaster

    Hi Martin,

    You’ll just have to get the specific record first in the script:

    var thisRec = form.getRecordWithId('rec-93d0352d75c64a638dced9515827ac95');

    #37902

    In reply to: Time delay in scripts

    Grant Anderson
    Participant

    Agreed! And yeah, I’m using it as a form script as it is post-processing hundreds of records based on web lookups.

    #37890
    Sam Moffatt
    Participant

    You need to assign a variable which is the record from the other form first.

    In the Script Editor, double click on the form name to get it’d field ID and then use var otherform = record.getFieldValue('fld-id') to get the linked records. If this shows up in Tap Forms as a table then you’re going to get an array of records (1:M in the parent, M:M fields or JOIN fields), if you’re in the child of a 1:M relationship then you will get a single record (the parent).

    Then you can get the value of the fields from that record via the other form, e.g. otherform[0].getFieldValue('fld-otherid').

    #37886

    In reply to: Time delay in scripts

    Sam Moffatt
    Participant

    Even if setTimeout existed, it’d require the Javascript execution to be fully async but that would then cause potential race conditions with other scripts executing and changing values. It might make sense for form scripts but making that async in an environment like Tap Forms is a recipe for hard to debug issues that would make any seasoned operations person have nightmares.

    I have a similar use case of a large amount work that a form script is doing which pauses Tap Forms due to doing heavy network I/O. Some sort of progress bar interface that I could use to at least communicate where it’s at and maybe do a clean cancellation would be useful.

    #37874
    Brendan
    Keymaster

    Hi Rocky,

    I have a script here which continues execution after the results of the prompter are determined. Perhaps this will help you with what you want to do:

    var second_prompt;
    
    var output2 = function printOut2() {
    	console.log('second prompt: ' + second_prompt);
    }
    
    var output = function printOut(continueClicked) {
    	console.log(username + ", " + password + ", " + email_address + ", " + other_field + ", " + genre);
    		
    	if (continueClicked == true) {
    		let prompter2 = Prompter.new();
    		prompter2.addParameter('Did it work?: ', 'second_prompt')
    		.show('A second prompt', output2);
    	}
    	
    }
    
    var username;
    var password;
    var email_address;
    var other_field;
    var genre;
    var genres = ['Action & Adventure', 'Comedy', 'Drama', 'Horror', 'Science Fiction'];
    
    let prompter = Prompter.new();
    prompter.addParameter('Username: ', 'username')
    .addParameter('Password: ', 'password', 'secure')
    .addParameter('Email Address: ', 'email_address')
    .addParameter('Other: ', 'other_field')
    .addParameter('Genre: ', 'genre', 'popup', genres)
    .show('Enter a Username and Password and Stuff', output);
    

    Basically when the first prompter is run, the output of that is the execution of the output function which creates another prompter. Then that prompter is displayed. And the output of that is output2. So that’s how you can chain things together using the prompter.

    #37860
    Daniel Leu
    Participant

    I hope that one day I can use the Prompter for scanning items. Then things could be automated with a script.

    Cheers, Daniel

    ---
    See https://lab.danielleu.com/tapformspro/ for scripts and tips&tricks

    #37856
    Sam Moffatt
    Participant

    I’m not sure you can fully do what you need with a script right now, the scripting interface doesn’t have a way of scanning anything.

    That said, what you can do is use the barcode scanner the search feature has to look up the record and if you had a checkmark for registration you could add a field script to watch that checkmark field and do what ever business process you need.

    #37849
    Brendan
    Keymaster

    @George, on the iOS version in the Script Editor, there’s a button on the toolbar just above the keyboard that kind of looks like a vertical set of boxes. Those are to represent fields. When you tap on that, Tap Forms will display the list of fields with a function selector for getting the field value or the field ID. When you tap on the field, Tap Forms will insert the variable into your source code, thus giving you the field ID or the value from the record and field that you’re looking for.

    #37846
    Brendan
    Keymaster

    In the context of AppleScript, there is no current record so you have to select one first. You can’t call record.getId() because there is no current record.

    The function that handles the AppleScript command will take 3 arguments. A form, a script, and a search.

    - (void)handleRunScriptCommand:(NSScriptCommand *)command {
    	NSString *formName = command.evaluatedArguments[@"form"];
    	NSString *scriptName = command.evaluatedArguments[@"script"];
    	NSString *searchName = command.evaluatedArguments[@"search"];
     ... do stuff
    }

    Once it has all that stuff, it runs the script:

    [self runScript:form search:(TFSearch *)search record:nil script:script];

    Passing in nil for the record because there’s no current record.

    The reason for this is the script is being run outside the context of the state of the user interface. So Tap Forms doesn’t have the current record. However, I could probably modify it so that it does pass in the current record to that call. And I’ve just done that.

    #37843
    Peter Wolf
    Participant

    Doh! I am struggling to make sense of the examples although I do know Google Apps Script for Sheet. Can someone kindly help get me started with scripting my planned application?

    I have successfully imported into TF on iPhone a .csv file of names, membership numbers and some other details of ticket bookings for an event. Each ticket will have a printed QR or barcode of the person’s membership number. I wish to create a TF script which enables the QR or barcode on each ticket to be scanned by the iPhone on attendee registration, retrieving the relevant ticket and automatically completing a field in the form to record their attendance. That’s all . . .

    Thanks in hope and in advance!

    #37838

    In reply to: Time delay in scripts

    Sam Moffatt
    Participant

    The only way I can think of would be to create a busy loop and check to see if time has elapsed. Something like this should work:

    function delay(duration)
    {
    	let now = new Date();
    	let future = now.getTime() + duration;
    	while((new Date()).getTime() < future) { }
    }
    
    function Timer() {
    	console.log(new Date());
    	delay(5000);
    	console.log(new Date());
    }
    
    Timer();

    Sample Execution:

    Tue Nov 05 2019 17:58:36 GMT-0800 (PST)
    Tue Nov 05 2019 17:58:41 GMT-0800 (PST)

    There might be a better way but this will work in a pinch.

    You might want to push the logic for the delay into the method call itself. If this is running inside a big loop, it should work ok. If you have multiple field scripts that you’re executing then I’m not sure this will be as effective so give it a try first:

    var lastCalled = 0;
    
    function delay(duration)
    {
    	let now = new Date();
    	let future = now.getTime() + duration;
    	while((new Date()).getTime() < future) { }
    }
    
    function rateLimitedLogger(message, minTime = 5000)
    {
    	let now = (new Date()).getTime();
    	let nextExecution = lastCalled + minTime;
    	if (now < nextExecution)
    	{
    		console.log(<code>Waiting ${nextExecution - now}ms</code>);
    		delay(nextExecution - now);
    	}
    	lastCalled = (new Date()).getTime();
    	console.log(new Date() + ' ' + message);
    
    }
    
    function Timer() {
    	rateLimitedLogger('Message 1');
    	rateLimitedLogger('Message 2');
    	delay(3000);
    	rateLimitedLogger('Message 3');
    	delay(6000);
    	rateLimitedLogger('Message 4');
    }
    
    Timer();

    Sample output:

    Tue Nov 05 2019 18:05:40 GMT-0800 (PST) Message 1
    Waiting 4999ms
    Tue Nov 05 2019 18:05:45 GMT-0800 (PST) Message 2
    Waiting 2000ms
    Tue Nov 05 2019 18:05:50 GMT-0800 (PST) Message 3
    Tue Nov 05 2019 18:05:56 GMT-0800 (PST) Message 4
    

    Obviously you’d need to swap out the console logging for your own implementation. This should work fine though and you can see that in my case it works fine. The examples are:

    1. The first launch, should always run.
    2. An immediately following execution (should be max time though looks like we lost a millisecond)
    3. I put in a manual delay for 3000 ms to demonstrate it properly accounting for that as the offset of 2000ms.
    4. I put in a manual delay for 6000 ms to demonstrate it properly accounting for being able to run immediately.

    Depending on what you’re doing, you might want to set the last called variable from another record somewhere and update it as you’re going. This would be important for if you are changing fields that are being watched by field scripts however this sort of script will pause TF because of the nature of how it’s running.

    Are you using a form script for this that you manually execute or field scripts?

    #37835
    Nigel Hughes
    Participant

    Hi,
    I’m just starting the coding of scripts in Tap Forms but have come to a bit of a road block. My goal is to calculate the nutrients in my weekly food shop. So I’ve created my shopping list as a database – with he records being all the common shopping items and record fields properties of those items including their nutrients and the date they were last bought. However to create a summary of the total for each of the 100 odd nutrients for each week’s shopping list i have created another linked form with a JavaScript doing the totalling of each of the nutrients in all the shopping items In the first form (for a particular day). I am trying to use the function getTotalOfField to do this ona search of a days shopping (in the first database) but am running into errors in its use that I don’t understand how to get around. Following the example on the Tap Forms JavaScript API webpage I have found the search object and then used the getTotalOfField function on this. However I keep getting the error:
    TypeError: NutrientSearch_object.getMinOfField is not a function. (In ‘NutrientSearch_object.getMinOfField(nutrient_ID)’, ‘NutrientSearch_object.getMinOfField’ is undefined)
    I’ve attached screen shots of the code and resulting consult log in the hope that someone might be able to help me see what I’m doing wrong. Thanks in advance!

    Attachments:
    You must be logged in to view attached files.
    #37834
    Grant Anderson
    Participant

    Hi, I’m updating entries in my database and need to access an online barcode lookup system. It only allows lookups every 5 seconds so as not to overload the server. How can I add a time delay in a script? I tried using Javascript’s setTimeout which would call a function after a specified time but Tap Forms compiler doesn’t seem to understand that. Any ideas?

    #37832
    Daniel Leu
    Participant

    No idea what happened to my comment…. you can repost it for context. No problem with me.

    Good thing I still have my test document…. store_id and store_name_id are variables that need to be defined in your script. So this all belongs together as part of the script field options > script. This way the script know from where to fetch the necessary data.

    var store_id = 'fld-xxxx';
    var store_name_id = 'fld-xxxx';
    
    function joinChildField(childLinkId, fieldId){
    	let entries = record.getFieldValue(childLinkId);
    	var list = Array();
    	for (entry of entries){
    		list.push(entry.getFieldValue(fieldId));
    	}
    	return list.join(', ');
    }
    
    joinChildField(store_id, store_name_id);

    The function definition uses parameter names that make sense for different applications. So when you call this function with joinChildField(store_id, store_name_id);, store_id will become childLinkId and store_name_id becomes fieldId inside the function.

    Cheers, Daniel

    ---
    See https://lab.danielleu.com/tapformspro/ for scripts and tips&tricks

    #37824
    Daniel Leu
    Participant

    I have to admit that I do all my development work on a desktop…. So I’m discovering the process along with you :)

    Let’s assume you have two forms in your document, Store and Wines. When you see them, there is an ‘Edit’ button on the top right. Click on it. Now you can edit the forms. Select Wines.
    I currently have three fields: ‘Wine Name’ (text), ‘Store’ (linked field to Store form, many-to-many type because I can buy the same wine at two stores and the stores usually have many wines, inverse relationship selected), and ‘Store TXT’ (field script). Just for completeness, in the ‘Store’ form, I have ‘Store Name’ (txt), ‘Wines’ (link), ‘Wines TXT’ (script).
    Click on ‘Store TXT’ and then ‘Field Options’ then ‘Script’. This is where your field script resides.

    You already noticed the Brenan’s and my field ids are different, so will be yours! To get the one you are looking for, touch in the text field somewhere to get the keyboard view. There is a small row with symbols. The one between fx and ABC is of interest. No idea how this symbol is called. Anyway, click on it. On the top, you can select between ‘getFieldValue()’ and ‘field_id’. The background behind these two options is ugly, looks like a bug where the background is not cleared. Here we need field_id. So select field_id.
    Since we are in the Wines form, we need the id of the ‘Store’ field (link to stores) and the name of the store.
    So click on ‘Store’. Now you are back in the editor with new text like
    var store_id = 'fld-....';
    Next we need the id of the store name. So again get the keyboard view and click on the icon between fx and ABC, click on ‘Store Name’ and you are back in the script editor with something like:
    var store_name_id = 'fld-....';
    These are the two items that are custom to your from and which are different to ours.

    Now finish the code as follows:

    function joinChildField(childLinkId, fieldId){
    	let entries = record.getFieldValue(childLinkId);
    	var list = Array();
    	for (entry of entries){
    		list.push(entry.getFieldValue(fieldId));
    	}
    	return list.join(', ');
    }
    
    joinChildField(store_id, store_name_id);

    The result will appear in the ‘Stores TXT’ field. Now you got to do for the ‘Store’ form and then you can search.

    Hope you were able to follow along….

    Update: Added my TF document for your reference

    Attachments:
    You must be logged in to view attached files.

    Cheers, Daniel

    ---
    See https://lab.danielleu.com/tapformspro/ for scripts and tips&tricks

Viewing 15 results - 2,311 through 2,325 (of 3,049 total)