Tap Forms – Organizer Database App for Mac, iPhone, and iPad › Forums › Script Talk › Script as field – how to get the output ?
- This topic has 18 replies, 3 voices, and was last updated 5 years, 2 months ago by Brendan.
-
AuthorPosts
-
October 11, 2019 at 4:57 AM #37052
MarcusParticipantHi Script Guys,
It’s more or less not a scripting question but how to use it in TapForms.
I do have a form with a script field, the script behind, just as simple example:
function Script() { var hello_world = "Hello World"; return hello_world; } Script();
I assumed TapForms will set this field value to “Hello World” when a recordset is added or changed ?
But it’s empty, independant of which type of value (text, number, …)
The console log shows the value, but the field stays empty.I additional added document.saveAllChanges; without any change.
Or is such a script field to be used only to set another field value by using recordset.setFieldValue(ID,value) ?
October 11, 2019 at 8:33 AM #37055
Sam MoffattParticipantI believe script fields are only executed when a referenced field is changed. Because the default snippet doesn’t reference any fields, by default it doesn’t execute. Perhaps it could be considered a bug it doesn’t run on a new record creation, calculation fields run after creation.
What you could do is get the value of every field in the form, then a change will trigger the script every time those fields change. Alternatively you can manually refresh the record after creation and it’ll force the execution of every script and calculation field. The manual refresh is done by clicking the “Recalculate formulas” button at the bottom of your record, by selected “Record” > “Refresh Selected Record” when the record is selected in the layout or you can refresh your entire form by clicking “Refresh record list” under the list view area.
When running in the script editor, not everything is persisted. If you’re working with just a single record you’ll need to manually refresh it per the above but if you want the new script field code to apply to all of your existing records you should tick “Update records when saving” next to “Done”/”Save” buttons at the bottom right of the script editor.
I’ve not found this too problematic in practice, generally you’re picking up field values to work with and when those are populated the script should execute. What is your use case for running a script at form creation?
October 11, 2019 at 8:47 AM #37056
MarcusParticipantMy use case is to calculate days between 2 dates.
I was never able to use a calculation field to get a value as number.October 11, 2019 at 11:02 AM #37057
MarcusParticipantBy using an additional number field that works:
function calcdays() { var today = new Date(); var date_id = 'fld-db4e94e8bb1a46e7b886afba72a6f2df'; var bought = record.getFieldValue(date_id); var days=today.getTime() - bought.getTime(); var days=days / (1000*3600*24); var res = record.setFieldValue('fld-1737a7de921041b3a2d6d90340537480',days); document.saveAllChanges(); } calcdays();
But is the right way to use a script field ?
The general question I have:
Is such a script field able to have a output (value) directly ?October 11, 2019 at 9:29 PM #37058
Sam MoffattParticipantThe built in calculation field has a
DAYS
function that will give you the number of days between two dates and put it in the field.The field ID detection code I think is triggered by
getFieldValue('fld-etc')
and using thevar date_id
syntax is tripping it up. It’s a little bit magical, I made my piece with it once I figured it out.In the script editor when I run the code (though changing the field ID), I also get an error reporting
TypeError: bought.getTime is not a function. (In 'bought.getTime()', 'bought.getTime' is undefined), column:46, line:4
. Take out thegetTime()
You don’t need the
document.saveAllChanges()
in this context, however in your example what you’re missing is areturn days;
at the end. Something like this I think would work better for you:function calcdays() { var today = new Date(); var bought = record.getFieldValue('fld-018ce5f02f7a4655be3e8f4377592f8b'); var days = today - bought; var days = days / (1000*3600*24); return days; } calcdays();
Here’s what that script looks like:
And in the default layout it looks like this:
That said once that script runs once, unless the “bought” field changes or your refresh the record then the script field value won’t change. There isn’t a way to automatically recalculate the value. This makes sense because Tap Forms is generating the value and saving it so that it doesn’t have to recalculate it every time. I suspect it also helps the search system by not having to regenerate the value when you search or sort too.
Another thread on age calculations is here: https://www.tapforms.com/forums/topic/age-calculations/
Attachments:
You must be logged in to view attached files.October 11, 2019 at 10:00 PM #37062
BrendanKeymastervar date_id = 'fld-db4e94e8bb1a46e7b886afba72a6f2df'; var bought = record.getFieldValue(date_id);
the above code should still trigger the script to execute when the date field changes values.
@sam, shouldn’t your example formula and script return a Number value?
The
DAYS()
function returns a Number. Your sample is returningText
.October 11, 2019 at 10:09 PM #37065
Sam MoffattParticipantThe numbers convert over to text just fine, going the other way doesn’t work generally. I reused the calc field in this test form that was already a “text” type though because the default for calc fields is number.
I could use number though for this since they’re all number, just didn’t because lazy :D
October 11, 2019 at 11:46 PM #37068
MarcusParticipantHi Guys,
thanks so far, but I‘m not sure if we‘re talking about the same.
@Sam: This Built-In calculation field is not available on an iPhone !
I do not have this TypeError like you.My screenshot shows a working method,
but I‘ve to use a script field and additional a „days“ field. What I‘d like to know if only a script field would be necessary to return the value ?However, independent of the calculation of days,
that‘s a general question:Assuming I have a simple script field:
function Script() { return 'Hello'; } Script();
1. shouldn’t the field value „Hello“ ?
2. when a script is triggered ?Attachments:
You must be logged in to view attached files.October 12, 2019 at 9:19 AM #37072
Sam MoffattParticipantCalculation field exists on iOS, all of the field types are supported on both Mac and iOS. There’s a slight difference that on iOS it wraps the field name in square brackets so it’d look like `DAYS(
[Bought];TODAY())` or similar.To your question:
1. That should return Hello
2. Script is triggered when a dependent field is changed or you refresh the field. On iOS, pull the record down to refresh the calculation manually.Looking at your screenshot, you’re still missing the
return
statement at the end. You can doreturn days;
as the last line of the method similar to thereturn 'Hello';
and it should work properly.Attachments:
You must be logged in to view attached files.October 12, 2019 at 10:28 AM #37079
MarcusParticipantI was (not yet) aware about the fx in a calculation field, using version 5 since some days.
Refresh the recordset to get a value from a script field is tricky.
Thanks, Sam.
October 12, 2019 at 2:16 PM #37081
Sam MoffattParticipantNo worries, happy to help! The Calculation field is pretty powerful, it has a bunch of built in functions for simple operations from the fx menu item.
The script field is a bit tricky however you can press the “play” button in the editor above the keyboard and it’ll run the script for you and you can see it’s output. There is also an option for a console log as well to see any debugging output. That enables you to do some iteration and testing as you go.
Attachments:
You must be logged in to view attached files.October 13, 2019 at 12:01 AM #37102
MarcusParticipantYa, got it.
I already created a bunch of helpful scripts,
I only was stuck hanging to automate with a script field rather than execute it manually.One last question:
Is there a possibility to get filtered recordsets only ?This returns ALL records:
var records=form.getRecords();
October 13, 2019 at 12:11 AM #37104
Sam MoffattParticipantCheck out the JavaScript API page: https://www.tapforms.com/help-mac/5.3/en/topic/javascript-api
If you have a named search then you can get that via
form.getSearchNamed('Search Name')
and then you can callgetRecords()
on what it returns to you.October 13, 2019 at 2:59 AM #37109
MarcusParticipantThanks.
I saw that already, but thought there‘s a possibility to apply a loop over visible (already filtered) items.I do have a search called „ToDo“, it‘s filtering 21 records.
This returns nothing:
function Test() { var records=form.getSearchNamed('ToDo'); return records.length; } Test();
What‘s wrong ?
October 13, 2019 at 9:33 AM #37114
Sam MoffattParticipantThe call to
getSearchNamed
just returns a search object, you need to callgetRecords()
on it to get a list of records, e.g.form.getSearchNamed('ToDo').getRecords()
.October 13, 2019 at 10:51 PM #37121
MarcusParticipantOk, that sounds logical.
Unfortunately it returns just a 0`function Test() {
var records=form.getSearchNamed(‘ToDo’).getRecords;
var L = records.length;
// is ZERO:
return records.length;
}Test();’
October 14, 2019 at 12:04 AM #37124
BrendanKeymaster@Marcus, check that
form
returns something and thatform.getSearchNamed('ToDo')
returns a search object. If the search is not called ‘ToDo’, then your code won’t work.October 14, 2019 at 2:53 AM #37125
MarcusParticipantOh man.
getRecords;
vs.getRecords();
getRecords();
October 14, 2019 at 12:05 PM #37128
BrendanKeymasterOops… I missed noticing that in your code. Yup, parentheses are required since
getRecords();
is a function call and not an object property. -
AuthorPosts
You must be logged in to reply to this topic.