Tap Forms – Organizer Database App for Mac, iPhone, and iPad › Forums › Script Talk › Tap Forms Javascript Scripting 101
- This topic has 8 replies, 3 voices, and was last updated 4 years, 3 months ago by T.L. Ford.
-
AuthorPosts
-
July 27, 2020 at 6:48 AM #41546
T.L. FordParticipantI just finished assembling
Tap Forms Javascript Scripting 101This beginner level tutorial:
* Teaches you how to read the scripts.
* Teaches you how to use the scripting interface.
* Teaches you how to apply the documentation.
* Teaches you how to write simple scripts.You do not need to have any experience programming or working with scripts.
http://cattail.nu/tap_forms/tap_forms_scripting_101/index.html
I wanted to answer some beginner scripting questions that I see in the forums and empower people to wield Tap Forms’ scripting power (it’s really cool!). I hope you find it helpful.
July 28, 2020 at 1:20 AM #41558
Sam MoffattParticipantLove the styling on the pages though I would have liked a more obvious “next” button to go to the next section. Look forward to seeing more expansion here though! Walk through guides for Tap Forms is something that I feel is missing but could be very useful. Perhaps you’ll end up writing “Tap Forms 5: The Missing Manual” at the end of it all.
Minor bug on the functions page, you reference
console_log
notconsole.log
. Additionallyconsole.log
will return to you the value of the property, for built-ins it’ll be a wrapper around native code though pure Javascript functions will return the implementation. Javascript is also generally referred to as a prototype based language and as such doesn’t have classes, just objects that you can extend upon (in a sense they’re all just dictionaries with some self referential sugar). It’s a slightly different approach than class based object orientated programming hierarchies.For Section 6, why did you pick the basic loop over the child records loop? As an aside third parameter comment is probably more correct than wrong because of the way Javascript treats falsey types. I wouldn’t be surprised if it’s not coerced to a boolean before being marshalled back to Objective-C.
For Section 7, the
.length
property is generally cached these days by the runtime. Google and V8 drove that optimisation which meant everyone else (including Apple) picked it up.Instead of doing string concatenation, I’d use an array and join:
let current_chores = []; ... current_chores.push(chores[index].getFieldValue(chore_id)); ... console.log(current_chores.join(", "));
A similar one solution would work for the name list as well which would make it easy to prefix or suffix titles, add middle names or more. Saves you having to deal with substring and let’s Javascript do the heavy lifting for you.
An alternative trick is to check if the string has a length and append the join characters in the middle after the first iteration of the loop:
if (current_chores.length) current_chores += ", "; current_chores += chores[index].getFieldValue(chore_id);
For the audio it sounds like fan noise, try grabbing Audacity and using it’s noise reduction plugin on the audio to see if it can clean it up. Fan noise is the bane of my own recording existence.
Looking forward to seeing what you tackle next though!
July 28, 2020 at 7:12 AM #41560
T.L. FordParticipantThank you for the feedback, Sam! It’s never possible to proofread your own work and find all of the errors (I did try). I added a “next” link to each page.
I wanted to add many more things (walk-throughs of all of the snippets, not just a couple, and some more useful examples). I ran out of time (time-sensitive projects queued) and I figured for 101, this bridges the gap between “I have never written a script in anything in my life… Help!” and “ok, I’m capable of figuring out code posted to the forums…”.
I made some decisions to “keep things as simple as possible”. For example, console.log and JavaScript – a true beginner will not understand the nuances of the under-hood implementation of JavaScript/Objective C. If I explain it as OOC, it adds a ton of web tutorials that can help explain objects which is a useful concept for grasping how to use forms, records, fields, etc. At the point in their programming career where they have jumped to a compiled language, they’ll know enough to be able to appreciate the difference. As a programmer, it’s cringeworthy. As a teacher for the utter newbie, the concept works.
I hope you don’t mind that I added your description for console.log and JavaScript as a footnote.
“For Section 6, why did you pick the basic loop over the child records loop?” – Failure to remember that such a thing existed until after I’d already done it and too lazy to go back and change it. I did mention it afterwards.
“As an aside third parameter comment” I liked Objective C data types. Oddball syntax but once you got used to it, it was nice enough. Swift data types (when I played with it) were pure [profanity deleted].
“For Section 7, the .length property is generally cached these days by the runtime. Google and V8 drove that optimisation which meant everyone else (including Apple) picked it up.” I learn something new every day. :)
I added your array / join to the downloaded zip and put a note about it on the page, because it’s definitely worth noting. I liked the additional reinforcement of string concatenation (true beginners struggle with it a bit), but array/join is more efficient. I’m a super-guru Microsoft Access VBA developer. Array.join() is a magnificent thing.
This is the same reasoning behind letting the code do the full string concatenation and then whacking off the ending comma. It keeps the inside loop block as simple as possible to focus on the process of looping. A string can be logged and easily understood. An array is very fuzzy in the minds of utter newbies.
“For the audio it sounds like fan noise” It’s definitely the computer fan – I even tried killing our air conditioning which blows just overhead and can add a hum (not very useful for the heat problem, but in this heat wave, I certainly didn’t leave it off long enough for the room temperature to change).
I ran one of the audios through Adobe Audition (the one where I sound like I’m standing in an auditorium). I have Audacity, too, but didn’t try that. I was busy grumbling at my computer. I’ve done a lot of videos. Some setting has gotten mucked up and changed the pickup threshold. I’ll get it sorted out before I do another video (my current theory is iTunes’ no-stealy implementation + Discord voice chat + SnapZ screwing up the capture, and could also have been the detour through the accidental click on my EOS Utility/OBS – next up: how to abuse your computer 101). It likely needs a reboot and some preference tweaking, but I had too many things open to do a reboot just then.
More “correct/efficient” Tap Forms walkthroughs would definitely be useful. I don’t feel savvy enough yet with Tap Forms to know the best ways. (example: why didn’t I use that Child records loop? Although I might make the lame excuse ‘so people could see how that basic loop can be edited’, which would be cool if that were the reasoning, not just my overlooking it.)
Again, I really appreciate the feedback!
July 29, 2020 at 7:22 PM #41567
Sam MoffattParticipantJavascript’s Array has a lot of fun stuff in them to make use of interesting properties, another example is
map
which lets you apply a closure to every item automatically andfilter
which can remove elements from an array.forEach
is another useful one to use plusfor (x of y)
andfor (x in y)
syntax for iteration.Here’s the same method rewritten to use
map
to extract the chore name and update some state and thenfilter
to remove the empty array elements (not exactly a good use case as we’re essentially usingmap
as a for loop or forEach construct):function Chore_Report() { let current_chores = []; let done_count = 0; let chores = 0; current_chores = record.getFieldValue('fld-08db542d325b434faea0d99cec89e1c9').map(rec => { let done = rec.getFieldValue('fld-0dba6e502e1e4151ab34d9d8afa2cd19'); chores++; if (done) { done_count++; return undefined; } else { return rec.getFieldValue('fld-2c5a9c565a7c480680659d1664daae3e'); } }).filter(chore => { return chore !== undefined }); var report = "Chores total: " + chores + ", Done: " + done_count + "\n" + current_chores.join(", "); console.log(report); return report; } Chore_Report();
To be honest I think purely correct or efficient at times isn’t as educational because there isn’t always a journey, things breaking, seeing issues as they arise and then fixing them. We learn more by the mistakes than by perfection or at the very least seeing how to overcome mistakes is useful when you run into your own issues.
Also I’m loathe to reboot though there is something screwy with the GPU in my MBP so every so often I get a kernel panic to reset things.
Look forward to seeing where to from here once you get some more time :)
July 30, 2020 at 7:56 AM #41569
T.L. FordParticipantI keep forgetting about the map function. I’m usually too busy cursing the syntax for the async/await implementation.
A 102 course would need an Array mastery section. Wouldn’t want to scare off the beginners too soon. Once people can understand a simple array and walkthrough, the other methods of using them become easier to grasp.
July 30, 2020 at 12:35 PM #41574
BrendanKeymasterThis is awesome!
Do you mind if I put a link to your tutorial in my Scripting documentation?
Thanks!
Brendan
July 30, 2020 at 5:20 PM #41575
T.L. FordParticipantI’d be honored if you’d link it in your Scripting documentation.
– T
July 30, 2020 at 9:21 PM #41576
BrendanKeymasterDone!
https://www.tapforms.com/help-mac/5.3/en/topic/scripts
The second blue banner box on the above page has a link to your tutorial.
Thanks!
July 31, 2020 at 3:41 AM #41577
T.L. FordParticipantAwesome! Thank you!
– T
-
AuthorPosts
You must be logged in to reply to this topic.