Search Results for 'script'
-
Search Results
-
Topic: Profiler Script
One of the scripts I use a lot is my profiler. I use it to figure out timing data for how long something takes for my scripts. It’s useful for understanding where your bottlenecks are in code and for figuring out what the true slow downs are.
If you look at the very bottom of the script, there is an example/test for the script so you can see how it works. I use this with a
Script Managerform which makes including easy like this:document.getFormNamed('Script Manager').runScriptNamed('Profiler');Due to the way the tests are coded, you want to define a variable called
PARENT_SCRIPTto prevent the test from firing when being included. Generally I do this in the format ofForm Name::Script Name, e.g.:var PARENT_SCRIPT = 'Boxes::Bulk Add To Box';Using it is easy once you’ve included it:
profiler.start('Start time'); ... your code that does stuff! ... profiler.end();Profiler internally uses a stack so end closes the most recent start. If you do a
profiler.dump()you will get back a string with the profiling information formatted with indentation. Here is a copy of the test running as an example:24/2/20, 9:59:19 pm / Script Manager / Profiler Caught expected error from dump: Error: Profiler imbalance: started called 1 more times than end. Uneven profiler.end called (are you missing a start?) Dump called with index 7 and indent 0 0ms Test 1 0ms Test 2 0ms Test 3 0ms Test 4 0ms Function start 0ms Complex logic 0ms MismatchHere’s the full script:
// ========== Profiler Start ========== // // NAME: Profiler // VERSION: 1.0.0 /** * Profiler module stores timing data. */ if (profiler == undefined) var profiler = (function() { let stack = []; let entries = []; let index = 0; let indent = 0; let current = undefined; return { custom: function(start, end, message) { entries[index] = {'start': start, 'end': end, 'message': message, 'index': index, 'indent': indent}; index++; }, /** * Start a timer. * * Takes a <code>message</code> and adds it to the internal <code>logdata</code> variable * and also logs it to the console with a timestamp. */ start: function(message) { let now = new Date(); stack.push({'start': now.getTime(), 'message': message, 'index': index, 'indent': indent}); index++; indent++; }, /** * Log an error * * Takes a <code>message</code> and <code>error</code> object and then formats into an error * via <code>logMessage</code>. */ end: function(endCount = 1) { for (let i = 0; i < endCount; i++) { let now = new Date(); let entry = stack.pop(); if (entry) { entry['end'] = now.getTime(); entries[entry.index]= entry; indent--; } else { console.log('Uneven profiler.end called (are you missing a start?)'); } } }, /** * Get the internal log buffer * * Returns the raw log buffer to output elsewhere. */ dump: function(autoClose = true) { let returnValue = []; returnValue.push(<code>Dump called with index ${index} and indent ${indent}</code>); let dumpIndent = indent; if (indent > 0) { if (!autoClose) { throw Error("Profiler imbalance: started called " + indent + " more times than end."); } else { // Close out any mismatched items. this.end(indent); } } let entry = null; for(entry of entries) { let message = (entry.end - entry.start) + 'ms \t' + entry.message; returnValue.push(message.padStart(message.length + (entry.indent * 4))); } return returnValue.join('\n'); }, /** * Clear the internal state. */ reset: function() { stack = []; entries = []; index = 0; indent = 1; } } })(); // Testing section. Fake guard for testing. if (typeof PARENT_SCRIPT === 'undefined') { profiler.start('Test 1'); profiler.start('Test 2'); profiler.end(); profiler.start('Test 3'); profiler.start('Test 4'); profiler.end(); profiler.end(); profiler.end(); profiler.start('Function start'); profiler.start('Complex logic'); profiler.end(2); profiler.start('Mismatch'); try { profiler.dump(false); } catch (e) { console.log('Caught expected error from dump: ' + e); } // Call end one too many times. profiler.end(2); console.log(profiler.dump()); profiler.reset(); } // ========== Profiler End ========== //Latest version of this script is available on GitHub: https://github.com/pasamio/tftools/blob/master/scripts/js/profiler.js
Topic: Prompter Functions
Credit to @daniel_leu for this originally and I think a variant of them will be coming in the sample scripts. These are the two that I use personally and I figured I’d share them. I added this in my “Script Manager” form as “Prompter Functions”, so if you have that included already then you can add this as a new one.
If you’re going to use these, the calling function needs to be prefixed with
asyncto make it work properly.// ========== Prompter Functions Start ========== // // NAME: Prompter Functions // VERSION: 1.0 /** * Prompter Functions for using the async system to handle some requests. */ // Temporary variable to store callback details. var prompterTempVar = undefined; /** * Prompt a confirmation dialog with a simple message. * * NOTE: This method uses async, please make sure your calling method is declared 'async'. * * @param {string} text - The text to display in the dialog for the confirmation. * @param {string} continueTitle - The text for the continue button. * @param {string} cancelTitle - The text for the cancel button. * * @return {boolean} Boolean result if the user confirmed or declined the dialog. */ function promptConfirm(text, continueTitle = 'Continue', cancelTitle = 'Cancel') { return new Promise(function(resolve, reject) { let prompter = Prompter .new(); prompter.cancelButtonTitle = cancelTitle; prompter.continueButtonTitle = continueTitle; prompter.show(text, ((status) => { if (status == true) { resolve(true); } else { resolve(false); } })); }); } /** * Prompt * * NOTE: This method uses async, please make sure your calling method is declared 'async'. * * @param {string} text - The text to display in the dialog for the confirmation. * @param {string} popupName - The prefix to display for the text box of the prompt. * @param {string} [continueTitle=Continue] - The text for the continue button. * @param {string} [cancelTitle=Cancel] - The text for the cancel button. * * @return {(string|boolean)} The input text or false if cancelled. */ function promptText(text, popupName, continueTitle = 'Continue', cancelTitle = 'Cancel'){ return new Promise(function(resolve, reject) { prompterTempVar = undefined; let prompter = Prompter .new(); prompter.addParameter(popupName, 'prompterTempVar') prompter.cancelButtonTitle = cancelTitle; prompter.continueButtonTitle = continueTitle; prompter.show(text, ((status) => { if (status == true && prompterTempVar) { resolve(prompterTempVar); } else { resolve(false); } })); }); } // ========== Prompter Functions End ========== //You can also get a copy of this file here: https://github.com/pasamio/tftools/blob/master/scripts/js/prompter.js.
Hi everyone,
I am trying again to find help. The first round, including some good advise was here:
Unfortunately, I did not manage to create a workflow as I am not familiar with scripting.Here’s my goal and setting:
I want to create a home inventory which helps me finding my stuff quickly. I have two forms: one for boxes and one for the items. From the boxes form I created a one to many link as one box contains many items but one item can only be in one box at a time. Each box has a QR code, each item has a bar code.
I managed to create my forms and the relationship and search is working. The barcode search will find items and boxes.Here comes the challenges:
1) Batch entry of items using barcode
Can I pull up a box by scanning its barcode and then start a batch scan barcodes of items as I place them in the box?
2) Batch checkout of items
Let’s say I pack for a trip and remove a lot of stuff from different boxes. I guess, in the boxes form I should create a box called “Checked Out”. Is it possible to first search for an item, have the box displayed where it is and then move this item to “Checked Out”?I use my iPhone for scanning but in case this workflow only works with a dedicated barcode scanner on the desktop version, I would be happy to buy one. I am just kind of lost and couldn’t find a tutorial.
Thank you for your help, Max
Topic: Script to move text to links
Hey there. I’m trying to move from airtable to tap forms.
I can (and have) downloaded the tables from airtable to csv files. I can import these csv files as forms into tap forms. However, I cannot seem to link certain fields to other forms during the import. After I’ve toyed around a bit, I think I understand why I couldn’t do that. But maybe I’m missing something.
So I tried to build a script that would take an existing text field, and move it over to an already “linked to” form. But I’m not a script writer.
I need some help.
I have a form called “classes” with a field called “players” that has comma delimited names in it as text. I would like to have a script that goes to each “players” field, grab each name, and add them to the “linked to” field called “players-linked”.
I have another form called “players” that has each individual as a record (first name, last name, etc.).
I can code a little, but I don’t understand how to handle the loops, or selections in tap forms. I need to do this script to a handful of other fields as well. If I can get one to work, I feel confident I can modify it to make the others work. Any ideas?
Topic: Limiting Decimal Places
I’m almost embarrassed to ask this given it’s probably such a basic question. However, I could well use the following script given as an example in the TF5 manual:
var records = form.getRecords();
var revenue_total = 0;for (var index = 0, count = records.length; index < count; index++){
var theRec = records[index];
var movie_revenue = theRec.getFieldValue(‘fld-987c9aac738a4f0fa1d18395902b3fc1’);
if (movie_revenue) {
revenue_total += movie_revenue;
console.log(‘Revenue: ‘ + movie_revenue);
}
}revenue_total;
My question is this: how do I limit the revenue_total return to 2 decimal places (currency)? I am getting this sort of thing: £63.9300000000001.
Sorry if this time-wasting but I’m sure there’s a quick answer that would save me hours of fruitless futzing. Thanks.
Hi all,
as Javascript/Typescript programmer I’m used to the comfort of IDE’s like Visual Studio Code.
I would like to edit Tap Forms scripts in my preferred editing application. In the _Edit form script_ window I could imagine a button like _Edit in external editor_ which opens the script in a configured editor application and automatically syncs changes back from the editor to the Tap Forms window.What do you think?