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,396 through 1,410 (of 2,989 total)
  • Author
    Search Results
  • cf
    Participant

    While you are poking around in that code, I also ran into a crash when adding a linked record using the plus-arrow button (the one that adds a record and navigates to it). Unfortunately I am unable to create steps to reproduce since it only happens for some records/forms and not others. In the cases where the crash does occur it happens consistently.

    Linked below is the stack trace:

    https://gist.github.com/cfilipov/0a6559c7b010ac651c2dfe27cc67a6b2

    The relevant part:

    
    Application Specific Information:
    Crashing on exception: *** -[__NSArrayM objectAtIndexedSubscript:]: index 3 beyond bounds [0 .. 2]
    
    Application Specific Backtrace 1:
    0   CoreFoundation                      0x00007fff204cc6af __exceptionPreprocess + 242
    1   libobjc.A.dylib                     0x00007fff202043c9 objc_exception_throw + 48
    2   CoreFoundation                      0x00007fff20580a9a -[__NSCFString characterAtIndex:].cold.1 + 0
    3   CoreFoundation                      0x00007fff2043fe41 -[__NSArrayM objectAtIndexedSubscript:] + 169
    4   Tap Forms Mac 5                     0x000000010711c14e Tap Forms Mac 5 + 1675598
    5   AppKit                              0x00007fff22e87412 -[_NSCollectionViewDataSourceAdapter collectionView:itemForRepresentedObjectAtIndexPath:] + 435
    6   UIFoundation                        0x00007fff239e4823 -[_NSCollectionViewCore _createPreparedCellForItemAtIndexPath:withLayoutAttributes:applyAttributes:isFocused:notify:] + 100
    7   UIFoundation                        0x00007fff239e47b9 -[_NSCollectionViewCore _createPreparedCellForItemAtIndexPath:withLayoutAttributes:applyAttributes:] + 31
    8   UIFoundation                        0x00007fff239cc726 -[_NSCollectionViewCore _updateVisibleCellsNow:] + 4435
    9   UIFoundation                        0x00007fff239cdb5a -[_NSCollectionViewCore _updateVisibleCellsNow:] + 9607
    10  UIFoundation                        0x00007fff239c0a41 -[_NSCollectionViewCore _layoutItems] + 285
    11  UIFoundation                        0x00007fff23aa0829 -[_NSCollectionViewCore _itemAtIndexPath:includePrefetchedCells:] + 230
    12  UIFoundation                        0x00007fff23a9a5ac __76-[_NSCollectionViewCore _deselectItemsAtIndexPaths:animated:notifyDelegate:]_block_invoke + 37
    13  CoreFoundation                      0x00007fff2048199c __NSSET_IS_CALLING_OUT_TO_A_BLOCK__ + 7
    14  CoreFoundation                      0x00007fff204c40fc -[__NSSingleObjectSetI enumerateObjectsWithOptions:usingBlock:] + 111
    15  UIFoundation                        0x00007fff23a9a525 -[_NSCollectionViewCore _deselectItemsAtIndexPaths:animated:notifyDelegate:] + 382
    16  AppKit                              0x00007fff235f9433 -[NSCollectionView _deselectItemsAtIndexPaths:notifyDelegate:] + 144
    17  Tap Forms Mac 5                     0x000000010705d805 Tap Forms Mac 5 + 894981
    18  Tap Forms Mac 5                     0x000000010705bf21 Tap Forms Mac 5 + 888609
    

    I had three linked records and used the arrow-plus button to add a fourth.

    Daniel Leu
    Participant

    The issue you encountered is that the prompter function is not blocking. So when you access the variable after the prompter call, this access happens before you have a chance to enter anything.

    I was struggling with this for a while when it was first introduced. This is what I use now:

    
    function textPrompter(title, text="") {
    	return new Promise(function(resolve, reject) {
    		let prompter = Prompter.new();
    		prompter.cancelButtonTitle = 'Cancel';
    		prompter.continueButtonTitle = 'Continue';
    		prompter.addParameter(text,'prompterVar')
    		.show(title, ((status) => { 
    			if (status == false || prompterVar == undefined) {
    				reject('Cancel');
    			} else {
    				resolve(prompterVar);
    			}
    		}));
    	});
    }
    
    async function prompterTest() {
    	// Check textPrompter
    	try {
    		await textPrompter("Title", "Enter text") 
    		console.log(prompterVar + " entered");		
    	} catch (errorText) {
    		console.log('cancelled textPrompter: ' +errorText);
    	} finally {
    		console.log(scriptName+": Script finished at " + new Date);
    	}
    }
    	
    prompterTest();
    

    Hope this helps!

    Cheers, Daniel

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

    #44088
    Daniel Leu
    Participant

    Yeah, you need a script using the Javascript API for that.

    Cheers, Daniel

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

    #44082

    In reply to: Scripts and searching

    Sam Moffatt
    Participant

    There is an extra bit of linking metadata that would be tracked. 1:M/M:M Link to Form fields create an internal link record for each link you make and the JOIN records create a materialised search with similar data (not 100% on the internals though). There is a cost per record link but in general it’s in the order of a few hundred bytes per link and no more than a kilobyte. I think because of the underlying implementation details, the JOIN is probably a little more space efficient because some of the linking data is persisted in the records on each side.

    In my own forms, I use a JOIN link to pull the grandchildren of that record into it. The two records share a common key field (actually a calculation that joins three fields together, see the screenshot) and then the JOIN field uses the calculation field on both sides. You could set up a calculation field that uses the value of another field or also uses the 1:M link to get values.

    The other aspect is that once you have a JOIN field, you can use scripting to iterate through the records in the JOIN field and have the script add them to the 1:M field. Pseudocoding a little:

    let joinRecords = record.getFieldValue('fld-joinfieldid');
    for(let joinRecord of joinRecords) {
      record.addRecordToField(joinRecord, 'fld-1mfieldid');
    }
    document.saveAllChanges();
    

    Basically once TF has done the heavy lifting to find the records to link, add in the links via scripting. An extra step could be a script that scans all of the records or perhaps a saved search to limit the candidate set (again, make Tap Forms do the work to find the records). Then all of your old records will look like new records :D You can keep the JOIN field, hide it so you don’t see it but when you do an import it’s there with what you need ready to go.

    Attachments:
    You must be logged in to view attached files.
    #44078
    Victor Warner
    Participant

    Sam,

    Would it be possible for you to make one of your videos to demonstrate how to use the prompter interface – as what you write in the last paragraph is something I would be very interested in doing if I could work out how to implement the relevant JavaScript.

    #44077
    Victor Warner
    Participant

    I would like to request the following improvements to the user interface:

    1. For layouts – would it be possible to add a (menu) commands to go ti the default (first) layout and to the last layout in addition to the go to the next and previous layouts? In the same way for Records.

    2. For saved searches – would it be possible to add a menu option to go to a specific saved search following the postings and Sam Moffat’s suggestion at: https://www.tapforms.com/forums/topic/scripts-and-searching/#post-44036.

    #44075
    Sam Moffatt
    Participant

    If it’s a single field, or set of related fields for something like seller, I’d consider having a seller form and using a link to form field to your inventory form. Then you open the linked inventory form from the seller and that linked field is retained for each new record you create.

    If you have multiple unique fields then I agree with Daniel that a simple script that creates a new records and copies the fields from the current record to the new one and then navigates to it would make sense.

    One other trick I use for bulk importing is to use the prompter interface to present the subset of fields that I need to edit and put that into a loop. That can give you a much faster data input system because you can enter the data, hit enter to submit and then have it popup again to input the next record. I use prompters to create records in a few places where I don’t need to see the record immediately after creation as generally the prompter flow is a little quicker than going into a record in a link to field use case.

    #44073
    Daniel Leu
    Participant

    If you have to inventory so many things a day, it might be better to import the data using CSV files.

    Or you can use a simple script that creates a new record and propagates your customer fields from the current records, or duplicate a record and delete unwanted data.

    Cheers, Daniel

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

    #44061
    Sam Moffatt
    Participant

    You’re welcome to shoot me an email but I also don’t mind having the conversation on the forum. The advantage of the forum is that multiple folk can respond and it may also help the next person who has similar questions as well. That’s part of the reason I started on the YouTube videos to try to show off visually, as well as textually, potential solutions to problems. If you want, perhaps start a new thread in the script talk or otherwise my username is my email, pretty easy to find.

    #44053
    Paul Lees
    Participant

    Hi Sam,

    Im afraid most of what you did in the video was way way beyond me. I did set up a trial database and tried to copy exactly what you did but failed miserably, despite devoting some 2 hours to it against your 16 minute video!! (Guess that’s why I’m a hell pilot and not a programmer.) I kept getting a scrip error on line two when running the check on the field script and not knowing diddly couldn’t rectify it.
    I’m not sure that I will crack this one to be honest but will try again soon.
    Once again thanks for trying for me.
    Cheers

    Paul

    Sam Moffatt
    Participant

    I don’t think there is a mutliselect prompter, the documentation in general is on the Javascript API page. The prompter stuff is relatively new in the grand scheme of things and not fully fleshed out, it’s a step towards more programmatic UI interaction.

    Sam Moffatt
    Participant

    Missed the iOS bit, unfortunately no keyboard shortcuts there for scripts though that’d be cool addition as Apple positions the iPad more and more towards being keyboard friendly. It’s definitely a few taps to run a form script if you want to take that approach but it sounds like the checkbox approach mostly works for you. If you tap the currently selected record again it should refresh the display.

    The prompter stuff for your use case isn’t too bad. You need to split it up into two pieces: getting the list of items for the pick list and handling the popup event. I gather you have a way of figuring out the set of actors and then all you need to do is feed that into the prompter.

    Here is something that should do the trick, you’ll need to change the setFieldValue line to match you field name and provide an implementation for getActorNames:

    var actorName;
    
    function callbackFunction() {
    	if (actorName) {
    		console.log(actorName);
    		record.setFieldValue('fld-actorname', actorName);
    		document.saveAllChanges();
    	}
    }
    
    function getActorNames() {
    	return ['Actor 1', 'Actor 2', 'Actor 3'];
    }
    
    function popup() {
    	let prompter = Prompter.new();
    	prompter.addParameter('Actor: ', 'actorName', 'popup', getActorNames())
    		.show('Select Actor', callbackFunction);
    }
    
    popup();
    
    johnny_law
    Participant

    Sam that is a great idea, but I don’t have a Mac and am using the IOS version. That is the issue, how do I get the pop-up (no keyboard shortcuts). I have also had difficulty with the prompter and async functions. But that is because I am a novice that knows enough to cause trouble.

    Using a checkmark field is an option but I always have issues with the screen updating after execution.

    I have been putting a date/time field in that causes a form script to run when it is undefined. After the script runs it sets the current date/time

    #44038

    In reply to: Scripts and searching

    Sam Moffatt
    Participant

    Reading through your process a few times, I wonder if triggering a script might solve some of what you’re trying to do though I might be missing something. If you have data inside the records that can be actioned, you could use a script to parse that and handle it. There is a progress bar interaction and the run button turns into a spinner while a script is running (not sure if you can detect either of that with your automation but it might work).

    I’m also wondering if your pain point is linking if using a JOIN Link to Form type to do that might help with that to automatically link records together. To use the JOIN would require a shared key between the two records which if you have that along the way somewhere might make things a little easier.

    #44034

    In reply to: Scripts and searching

    Victor Warner
    Participant

    Brendan,

    Thank you for the reply. Yes, it is part of a larger automation.

    Here is the long explanation:

    A bit of background, until 2 years ago I use Filemaker to maintain my records concerning my work as a Notary Public in England. FileMaker provided many tools / features not present in Tap Forms, but also is far more complex than my needs – and also when I set it up I did not deal with some of the links between (in Tap Form terminology) Forms in quite the right way, creating two Forms than I really needed.

    When I set up (or rather re-created) the database Tap Forms I also corrected what was not working – but I have been able to go much further in automating what I need to produce for client with Tap Forms – which has made it much much much easier than with Filemaker (even though I have had to struggle with Javascript).

    I am now exporting, record by record each of the Filemaker for records prior to 2018 – typically up to 7 forms for each client (client contact details, passport details, other id, notarial act, notarised documents, time spent, disbursements) – all which were linked (for example, the client contact form is linked to the passport form and the other ID form, and each of which might contain several records).

    I have keyboard maestro macros to format the exported CSV files from FileMaker (add field names needed for the import (as the field names are different between FileMaker and Tap Forms), add a For Duplication field and a X for that field), import all the Forms into Tap Forms at one go rather than one at a time. I added an extra field (For Duplication) which just contains a X, and the saved search to find the records who with X for each Form, to easily pick out the those records and then recreate the links between the forms.

    Again with Keyboard Maestro for each Form I can automatically add the links but to create the links for all the Forms at one go I need to be able to reliably access for each Form the saved searched For duplication.

    If I was able to do so – than I can speed up the import.

    As mentioned in my previous post for some parts of the Tap Forms it is just not possible to access them with a shortcut, menu or by tabbing. But it possible to do so with UI Browser finding the GUI code to do so. An example is attached. But the AppleScript GUI code it generates does not work for the saved searches in the Forms list.

    So it is more than just saving a click. If you have any suggestions I would be very grateful to hear about them.

    Attachments:
    You must be logged in to view attached files.
Viewing 15 results - 1,396 through 1,410 (of 2,989 total)