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 - 1,231 through 1,245 (of 2,951 total)
  • Author
    Search Results
  • #44738
    Sam Moffatt
    Participant

    Since this was posted in 2014, that’s still TF3 (desktop)/TF4 (iOS) so since then TF5 came out with support for multiple documents, leveraged a new data backend, nearby sync and CouchDB/Cloudant Sync options, image fields supporting multiple images and a pop out gallery view, the scripting engine, the charting system, access controls on the Mac, the markdown field type as well as improvements to various smaller features (e.g. extra functions for the calc system). Almost all features are parity between iOS and Mac as well (layouts I think is the biggest one missing from iOS). You can check out the 5.3.19 changelog for all of the changes in the TF5 series up to the current version.

    I believe the current focus is to move to a newer data backend due to it not being supported any more and not being able to build against newer targets.

    #44718

    In reply to: Split note field?

    Sam Moffatt
    Participant

    I turned this into a video using the above sample data and script as a basis including building out two forms to track the data. I’m going to do a follow up video on how to handle the multiline fields which isn’t currently handled for next week.

    #44687
    Sam Moffatt
    Participant

    If you’ve on the child side of a 1:M relationship then you can use a calculation field or script field to copy the value of any field from the parent record.

    If you’re using M:M relationships, you’ll need a script field to merge the data together.

    I have a video covering some of this on YouTube with a library linking example and another one on using link to form fields and duplicating field values.

    DrJJWMac
    Participant

    By default, Databases for Tap Forms are stored (deeply nested) in a folder in the user’s library folder. I prefer to store my databases on a separate volume / drive. I tried to put a symlink in the default sub-folder to point to my storage folder with the hope that I could see into the volume at the splash-screen dialog box. This did not work.

    I can see preferences to change the default locations for backups and scripts. But nothing can be done to set the default for databases, and the splash-screen does not allow easy access to a different location (outside the user’s library).

    I’d hope perhaps the limitations can be lifted for a future version.

    #44663

    In reply to: Split note field?

    Sam Moffatt
    Participant

    Ok, so if you’ve got multiple entries then I’d suggest creating a second form for the data and using a link to form field to store that data in or a table field. This allows you to model the multiple entries but link it back to the main record.

    This script is a little longer than the last. I’ve put comments throughout it. You’ll need to fill in the blanks for the field ID’s which you can find via the script editor by clicking on the field and hitting ID or by looking at it’s ID in the field details panel.

    The way I’ve constructed it is something that could be optimised but I use this technique to verify the object that is constructed looks “right” and then I add in the piece to addNewRecordToField and setFieldValue at the end which actually creates the records.

    Here’s the script:

    // fieldNames is a list of field names for each line.
    const fieldNames = [
    	'event_date',
    	'squadron',
    	'location',
    	'aircraft',
    	'pilot',
    	'damage_type',
    	'comments'
    ];
    
    // aircraft details has the fields for the aircraft line.
    const aircraftDetails = ['aircraft_type', 'aircraft_sn', 'aircraft_ext'];
    
    // fieldMap maps the friendly field name to the Tap Forms field name.
    // these are the fields IDs from the link to form or table field
    const fieldMap = {
    	"event_date": "fld-001",
    	"squadron": "fld-002",
    	"damage_location": "fld-003",
    	"damage_description": "fld-004",
    	"damage_percentage": "fld-005",
    	"aircraft_type": "fld-006",
    	"aircraft_sn": "fld-007",
    	"aircraft_ext": "fld-008",
    	"pilot_rank": "fld-009",
    	"pilot_name": "fld-010",
    	"damage_type": "fld-011",
    	"comments": "fld-012"
    };
    
    // input is our sample data, in your script:
    // let input = record.getFieldValue('fld-notefieldid');
    let input = `02.08.1942
    12 Squadron
    RAF Hawkinge, tire burst on landing (20%)
    Lancaster1, SN.ZX334
    SqnLdr. Conran
    
    1) RAF Bomber Accidents
    
    1) no comment.
    
    02.08.1942
    12 Squadron
    RAF Detling, dmage while on sortie (50%)
    Lancaster1, SN.ZX334, BA-
    SqnLdr. Conran
    
    1) RAF Bomber Damage
    
    1) no comment.
    
    17.08.1943
    61 Squadron
    Hamburg, Shot down by a nightfighter (100%)
    Lancaster1, SN.ZX334, BA-
    SqnLdr. Hewitt
    
    1) RAF Bomber Losses
    
    1) no comment.`;
    
    // lineIndex the index of the line we're processing.
    let lineIndex = 0;
    
    // parsedData is an object we're going to put the data in temporarily.
    let parsedData = {};
    
    // lines is each of the lines
    let lines = input.split("\n");
    
    // process each line...
    for (let line of lines) {
    	// trim the line of extra whitespace
    	line = line.trim();
    
    	// ignore empty lines.
    	if (line.length == 0) {
    		continue;
    	}
    
    	// handle each line we're working on
    	switch (lineIndex) { 
    		// these lines pass thru the value 1:1
    		case 0:
    		case 1:
    		case 5:
    		case 6:
    			parsedData[fieldNames[lineIndex]] = line;
    			break;
    		case 2:
    			// damage line is field1, field2 (field3) so let's parse that:
    			let damagePieces = line.match(/([^,]*), (.*) \((.*)\)/);
    			if (damagePieces && damagePieces.length > 2) {
    				parsedData["damage_location"] = damagePieces[1];
    				parsedData["damage_description"] = damagePieces[2];
    				parsedData["damage_percentage"] = damagePieces[3];
    			}
    			break;
    		case 3:
    			// aircraft line appears to have two or three entries so we split
    			let aircraftPieces = line.split(',').map(elem => elem.trim());
    			// then we work through each piece of the split line
    			for (let aircraftIndex in aircraftPieces) {
    				// and put it in the relevant field
    				parsedData[aircraftDetails[aircraftIndex]] = aircraftPieces[aircraftIndex];
    			}
    			break;
    		case 4:
    			// pilot appears to be a simple space split field with two values.
    			let pilotPieces = line.split(' ').map(elem => elem.trim());
    			parsedData["pilot_rank"] = pilotPieces[0];
    			parsedData["pilot_name"] = pilotPieces[1];
    			break;
    		default:
    			console.log("Unknown Line");
    			console.log(lineIndex);
    			console.log(line);
    	}
    
    	// increment lineIndex to change which line we think we're processing
    	lineIndex++;
    
    	// if lineIndex becomes 7, we're at the end of this stanza
    	if (lineIndex > 6) {
    		// reset the lineIndex back to zero
    		lineIndex = 0;
    
    		// log out our parsed object.
    		console.log(JSON.stringify(parsedData));
    
    		// create a new entry in our link to form field
    		// remove the /* and */ lines after testing
    		/*
    		let newEntry = record.addNewRecordToField("fld-linktoformfieldid");
    		for (let fieldName in parsedData) {
    			// set the field value of the field to the value we parsed.
    			newEntry.setFieldValue(fieldMap[fieldName]), parsedData[fieldName]);
    		}
    		*/
    		// reset the parsedData object to empty.
    		parsedData = {};
    	}
    }
    
    // save all the changes we made!
    document.saveAllChanges();
    

    For the sample data, the console log looks something like this:

    {"event_date":"02.08.1942","squadron":"12 Squadron","damage_location":"RAF Hawkinge","damage_description":"tire burst on landing","damage_percentage":"20%","aircraft_type":"Lancaster1","aircraft_sn":"SN.ZX334","pilot_rank":"SqnLdr.","pilot_name":"Conran","damage_type":"1) RAF Bomber Accidents","comments":"1) no comment."}
    {"event_date":"02.08.1942","squadron":"12 Squadron","damage_location":"RAF Detling","damage_description":"dmage while on sortie","damage_percentage":"50%","aircraft_type":"Lancaster1","aircraft_sn":"SN.ZX334","aircraft_ext":"BA-","pilot_rank":"SqnLdr.","pilot_name":"Conran","damage_type":"1) RAF Bomber Damage","comments":"1) no comment."}
    {"event_date":"17.08.1943","squadron":"61 Squadron","damage_location":"Hamburg","damage_description":"Shot down by a nightfighter","damage_percentage":"100%","aircraft_type":"Lancaster1","aircraft_sn":"SN.ZX334","aircraft_ext":"BA-","pilot_rank":"SqnLdr.","pilot_name":"Hewitt","damage_type":"1) RAF Bomber Losses","comments":"1) no comment."}

    To get this to work, fill in the field ID’s (e.g. fld- prefixed items) and remove the /* and */ lines to actually create a new field in the link to form field. Might need some testing but you can see roughly what it’s doing.

    #44647

    In reply to: Split note field?

    Sam Moffatt
    Participant

    Without actual data it’s a little hard to give you a solution but something like this should make sense.

    let input = `Field 1
    Field 2
    Field 3, Field 4 Field 5
    Field 6, Field 7, Field 8
    Field 9 Field 10
    
    Field 11
    Field 12
    Field 13
    
    Field 14
    Field 15
    Field 16`;
    
    let lines = input.split("\n");
    let fields = [];
    
    fields[1] = lines[0];
    fields[2] = lines[1];
    
    let line2Pieces = lines[2].match("([^,]*), (Field .*) (Field .*)");
    fields[3] = line2Pieces[1];
    fields[4] = line2Pieces[2];
    fields[5] = line2Pieces[3];
    
    let line3Pieces = lines[3].split(",");
    fields[6] = line3Pieces[0];
    fields[7] = line3Pieces[1];
    fields[8] = line3Pieces[2];
    
    let line4Pieces = lines[4].match("(Field [0-9]*) (Field [0-9]*)");
    fields[9] = line4Pieces[1];
    fields[10] = line4Pieces[2];
    
    fields[11] = lines[6];
    fields[12] = lines[7];
    fields[13] = lines[8];
    
    fields[14] = lines[10];
    fields[15] = lines[11];
    fields[16] = lines[12];
    
    console.log(fields);
    

    I’ve used an array to store the various fields in to show how that should look parsed out. Instead of using the array (e.g. fields[1] = ...) you’d would directly set the field value (e.g. record.setFieldValue("fld-field1id", ...)).

    At a high level we split things by line, then for the lines that are purely comma separated we split them by the comma and then for the lines that are a mix, I’m using a regular expression to extract out the pieces. This is where knowing the actual form of the data would help because you can build a regular expression to capture the format.

    For example a US formatted location could be parsed this way:
    console.log("Cupertino, CA 95014".match(/([^,]*), (.*) ([0-9]*)/));

    #44645

    In reply to: Split note field?

    Emil Mitchell
    Participant

    Thank you very much for your replies. That is great that such a script can be formatted. It will save a lot of time.

    I have attached an example of how my data is formatted within the note field in question.

    The individual parts of the data that I would like to split into their own field are marked “Field 1” to “Field 16”.

    As you can see, some parts of the data are separated by commas, some are not, and some are separated by being on the next line.

    Is it still possible to split the note?

    Thank you!

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

    In reply to: Split note field?

    Sam Moffatt
    Participant

    On a similar note, I do something similar except the data I generally pull in is free form and I use a table field with a “Key” and “Value” fields inside it. It’s a similar sort of script except that you use fixed name for the key/value field names and an extra table field. There is an example of using a link to form/table fields and addNewRecordToField in the Get Movie Details from TheMovieDB API. If you know the keys are going to be unique, I also have a helper script on GitHub that scans a table field (also works with link to form fields) and expects a key/value field structure to then add only entries that are missing.

    #44641

    In reply to: Split note field?

    Brendan
    Keymaster

    Hi Emil,

    This can be done with a script.

    Here’s an example that takes the lines from a Note field and splits them into an array and then loops through the array of lines and writes each line to a separate field. I’ve made some assumptions here such as your field names have a pattern of “Field 1”, “Field 2”, “Field 3”, and so on.

    function Split_Note() {
    
    	var note_id = 'fld-c711358a858443c8805c8c98c71a03b4';
    	var note = record.getFieldValue(note_id);
    	var field_prefix = "Field ";
    	
    	if (note) {	
    		var lines = note.split("\n");
    		console.log(lines.length);
    		var fieldIndex = 1;
    		
    		for (line of lines) {
    			let field = form.getFieldNamed(field_prefix + fieldIndex);
    			if (field) {
    				console.log(field.name);
    				let field_id = field.getId();
    				record.setFieldValue(field_id, line);
    			}
    			fieldIndex++;
    		}
    	}
    	form.saveAllChanges();
    }
    
    Split_Note();

    You can see the result of running this script in my example screenshot.

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

    Topic: Split note field?

    in forum Script Talk
    Emil Mitchell
    Participant

    Dear all,

    I am rather new when it comes to technical database terms and I am hoping someone can help.

    I have a note field with approximately 5 lines of text. I have come to the conclusion that it would be better to have each piece of text within the note field within its own field.

    Is there a way to split the information within a field into separate fields using some technical scripting magic, rather than having to go back and edit them all manually?

    Thank you for your time!

    #44624
    Daniel Leu
    Participant

    Once you have your group of records using search, go to the multi-column view, set the first value and then click on the yellow dot and move it down. This will copy the value to the other fields.

    Another option would be a form script.

    Cheers, Daniel

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

    #44611
    JCK
    Participant

    Ohhhh kay. That makes sense. I realize now that I was calling the convertIMDBtoTMDB function at the wrong time.

    How do I add to a variable? Or is this something I’m confusing from coming from Shortcuts on iOS.

    The use case I’m running in to is for films with multiple directors. I’ve figured out how to loop through the results to get the names of both directors listed in the console, but I’ve run into a issue trying to add the positive results together.

    function getCrew() {
        var fullcredits = fetchCreditsFromURL();
        if (! fullcredits) {
            console.log("Request to get credits failed");
            return [];
        }
        return fullcredits.crew ? fullcredits.crew : [];
    }
    
    function getDirectors() {
         let crew = getCrew();
         for (let crewMember of crew) {
         			if (crewMember.job === 'Director') {
         				console.log(crewMember.name);
         				} continue; 
         		}
    }

    In Shortcuts, I would add an “Add to Variable” option, but there doesn’t seem to be anything like that in javascript. Adding a return function at any point seems to stop the loop, or only give the last result.

    Ideally I would like all positive results to be returned in a single string that I could add to a field. What am I doing wrong?

    #44608
    Redrock
    Participant

    Thanks much for all the info, Sam. I appreciate it. I didn’t realize TF scripts use java. I won’t tell you how long it’s been since I’ve coded, lol.

    As a former MS Access and HanDbase user, I vote for a TF enhancement to have the ability to create views where linked records can be created, edited, and displayed with their parent records—it’s a basic relational database function that could put TF at the head of the pack.

    #44603
    Sam Moffatt
    Participant

    First step is to check out the JavaScript API to get a feel for some of the stuff available.

    Next stop I’d suggest is to check out T.L. Ford’s JavaScript tutorials.

    If video is more your jive I’ve got a YouTube channel with some resources including a intro to scripting and a script field deep dive. There is also a video on link to form fields and scripting that might help as well.

    The forum has a bunch of great examples of how to use the scripting in Tap Forms. There was a recent post on using Markdown for contracts which leverages a script field to generate some Markdown output including leverage a table field. From a scripting perspective, link to form fields and table fields behave similarly so anything that works with a link to form field will work with a table field and vice versa.

    Hopefully this helps!

    #44602
    Redrock
    Participant

    Well, that explains why I couldn’t figure it out. I actually wanted to populate the linked form from the parent, in addition to simply displaying them.

    I tried using a table, but while it pulled over the child record names, there was no data.

    Scripts, huh? Sigh. Could you please point me to a reference guide?

    Thank you for the reply!

Viewing 15 results - 1,231 through 1,245 (of 2,951 total)