Custom seperator symbol in multi pick-lists!

Tap Forms Database Pro for Mac, iPhone, iPad and Apple Watch Forums Using Tap Forms 5 Custom seperator symbol in multi pick-lists!

Viewing 9 reply threads
  • Author
    Posts
  • September 16, 2019 at 12:14 AM #36774

    Chris Ju
    Participant

    Hello Brendan,

    the automatic comma to separate entries in multi-picklists is not really convincing. Could you add an option that would allow to set up an own seperator (or none at all) for each list?

    That would be awesome!

    Thanks!
    Chris

    September 17, 2019 at 2:31 AM #36785

    Brendan
    Keymaster

    That could be useful. I’ll look into it. For now though, you could just put a value in with dashes or something like that to help you separate sections within the Pick List.

    September 17, 2019 at 2:36 AM #36787

    Chris Ju
    Participant

    The problem for now is not that I need a custom delimiter. I want nothing to be between the entries!

    Thanks a lot!

    September 17, 2019 at 2:52 AM #36789

    Brendan
    Keymaster

    Can you post a screenshot of what you’re looking for? Do you mean the entries after selection or the entries in the Pick List itself you want separated somehow?

    September 17, 2019 at 3:00 AM #36790

    Chris Ju
    Participant

    See attached screenshot! I don’t want any characters between the entries!

    Attachments:
    You must be logged in to view attached files.
    September 17, 2019 at 3:33 AM #36795

    Brendan
    Keymaster

    Ok, so the entries after you’ve selected the values.

    You could switch the Pick List Display As setting to Checkbox Button instead of using the Multi-Select option. That would give you a nice view of the values and show a checkmark beside them if they’re selected. Internally the values are stored as you see them in your screenshot. But you may prefer the way the Checkbox Button option is displayed.

    You configure that on the Pick Lists edit screen in Preferences (or from the Tools menu).

    September 17, 2019 at 3:48 AM #36796

    Chris Ju
    Participant

    Thanks for your suggestion. But that isn’t a solution in my use case, because i usually add some text and print it out within a layout. And the unselected entries should not appear on the printed paper!

    The time consuming task is to remove the commas between sentences.

    September 19, 2019 at 11:46 PM #36811

    Sam Moffatt
    Participant

    I’ve been dwelling on this a little and one of the challenges is how the pick lists are stored. It’s essentially still a text field, even with the multiple select, which is why you can tick them and also manually type items in. If you get it exactly correct, it’ll match as the pick list too. I’m not sure Brendan can easily change that using the existing field type, it needs to be a new field type dedicated to the pick list.

    As is often my solution here on the forums, you can use a script field to help you out. To make this work I did some minor tweaks, for the pick list I prefixed it with a number and colon sort of format and use that to split apart the string from the pick list. The pick list values I used look like this:

    – 1: Something, I think, that will help.
    – 2: This is, to be sure, the right path!
    – 3: The path of caution, butterfly.

    This is something that looks ok, doesn’t feel too janky but gives me a character to work with: the colon! If you need to use colons, I’d actually suggest using a pipe character (|) which is an old favourite of mine because not many people use that character in ordinary sentences.

    This has comments inline that should explain as it goes:

    // This cleans out the Tap Forms comma and space delimiter.
    function cleanString(input)
    {
    	// I had an input length check because the first array
    	// element is going to actually be empty but then I put
    	// in a filter and this if statement ended up being redundant.
    	if (input.length)
    	{
    		// What we're looking for is a space OR comma multiple
    		// times at the end of the string (the dollar sign means
    		// end of string) and we want to replace that with an
    		// empty string.
    		return input.replace(/[\s,]*$/, "");
    	}
    }
    
    // Boilerplate :D
    function Restructured() {
    	// Replace this with the field that stores your pick list.
    	var sentence = record.getFieldValue('fld-6d04efdd9e334ad29399bc3c4aef4f06');
    	
    	// Step 1: take the sentence and split it based on "Number: ", e.g. "1: ".
    	var cleaned = sentence.split(/[0-9]*: /)
    	// Step 2: Filter removes elements from an array that don't match.
    	//         In this case, if the string length is greater than zero, keep it.
    	//         The 'x' here is short hand for the array element and this could
    	//         have also been implemented as another function.
    		.filter(x => x.length > 0)
    	// Step 3: Map executes a function per element and creates a new array with
    	//         the new values. What we're doing is using "cleanString" to clean
    	//         the values and remove the Tap Forms delimeters. This could also
    	//         have been done inline too: .map(x => x.replace(/[\s,]*$/, ""))
    		.map(cleanString);
    
    	// Last but not least we return the value to our caller. In this case
    	// we're joining the array with a single space however you could also do
    	// this with a new line character (e.g. '\n') or any other string that
    	// makes sense for your use case.
    	return cleaned.join(' ');
    }
    
    Restructured();

    This function makes use of Javascript’s chaining functionality. That is where you immediately use the object returned from the earlier method with the next method. The Restructured() method itself could actually be one line completely chained but I broke it up a little to help with the explanation. Put this into a script field and it’ll automatically reformat the pick list field to what I think you actually want. You will have to mutate your pick list to the format it expects (again that number, followed by a colon and ending with a space) though you could tweak the script not to care so much about that too.

    Attachments:
    You must be logged in to view attached files.
    September 21, 2019 at 9:41 AM #36817

    Chris Ju
    Participant

    Thank you very much, Sam!

    The script works! But the result is not stored in the field! What am I doing wrong?

    It would be great, if you could give me an advice!

    Thanks!
    Chris

    September 21, 2019 at 11:29 AM #36820

    Sam Moffatt
    Participant

    The result should be stored in the script field and it won’t change the original field. The reason for this is if you change the original field via the script, it’ll break the UI selection because it will trigger as you select the options.

    My intent was that if you were using a layout to just use the script field in place of the editable field. You could flag the script field as hidden to remove the script field from the default layout but then use the script field on the layouts. This also means the UI will still work properly with the original field.

    ===

    The other thing to do would be to take the script and turn it into a form script that instead of returning the value at the end, sets the value of the field. If you bind it to a keyboard shortcut, you can then press that once you’re done with your edits to clean the field.

    To make it into a form script, change this line:

    return cleaned.join(' ');

    To:

    record.getFieldValue('fld-6d04efdd9e334ad29399bc3c4aef4f06', cleaned.join(' '));

    That’ll reset the field to the new value for you. You will also need to put document.saveAllChanges() somewhere in your script to make the change persist.

    If you have many of these fields that you want to mutate this way and you went for a form script, you could do an array of the field ID’s.

    First step of that is to change the Restructured method to accept a parameter:

    function Restructured() {
    	// Replace this with the field that stores your pick list.
    	var sentence = record.getFieldValue('fld-6d04efdd9e334ad29399bc3c4aef4f06');
    

    Is rewritten into

    function Restructured(field_id) {
    	// Replace this with the field that stores your pick list.
    	var sentence = record.getFieldValue(field_id);
    

    Update the setFieldValue at the bottom to use field_id as well.

    Then when you call into Restructured, you can just set the field ID’s into an array:

    Change:

    Restructured();

    To:

    ['fld-1', 'fld-2'].map(Restructured);
    document.saveAllChanges();

    Replacing in the list of fields you need to clean up. The beauty of this particular approach is that once the 1: placeholders are gone, assuming you don’t use colons elsewhere the field is stable so you can run it multiple times and it won’t break fields already updated. Though as I’m sure you’re aware, as soon as you rewrite that field the UI selection options will break.

    Full script:

    // This cleans out the Tap Forms comma and space delimiter.
    function cleanString(input)
    {
    	// I had an input length check because the first array
    	// element is going to actually be empty but then I put
    	// in a filter and this if statement ended up being redundant.
    	if (input.length)
    	{
    		// What we're looking for is a space OR comma multiple
    		// times at the end of the string (the dollar sign means
    		// end of string) and we want to replace that with an
    		// empty string.
    		return input.replace(/[\s,]*$/, "");
    	}
    }
    
    // Boilerplate :D
    function Restructured(field_id) {
    	// Replace this with the field that stores your pick list.
    	var sentence = record.getFieldValue(field_id);
    	
    	// Step 1: take the sentence and split it based on "Number: ", e.g. "1: ".
    	var cleaned = sentence.split(/[0-9]*: /)
    	// Step 2: Filter removes elements from an array that don't match.
    	//         In this case, if the string length is greater than zero, keep it.
    	//         The 'x' here is short hand for the array element and this could
    	//         have also been implemented as another function.
    		.filter(x => x.length > 0)
    	// Step 3: Map executes a function per element and creates a new array with
    	//         the new values. What we're doing is using "cleanString" to clean
    	//         the values and remove the Tap Forms delimeters. This could also
    	//         have been done inline too: .map(x => x.replace(/[\s,]*$/, ""))
    		.map(cleanString);
    
    	// Last but not least we return the value to our caller. In this case
    	// we're joining the array with a single space however you could also do
    	// this with a new line character (e.g. '\n') or any other string that
    	// makes sense for your use case.
    	record.setFieldValue(field_id, cleaned.join(' '));
    }
    
    ['fld-6d04efdd9e334ad29399bc3c4aef4f06'].map(Restructured);
    document.saveAllChanges();
Viewing 9 reply threads

You must be logged in to reply to this topic.