You are viewing limited content. For full access, please sign in.

Question

Question

Modern form designer get variable before submit for a html button

asked on March 26, 2024

We're working in Laserfiche cloud and ideally, in the modern form designer.

We wish to use a table with a button that points to a URL, the URL is formed from a variable within the table.  The button URL must be available before the form is submitted and this is not possible in a custom HTML control because variables are only assessable after a form is actually submitted.  I understand we must use JavaScript to get the URL content from the js selector.

We've had some success in the classic form designer where jQuery is supported.

is it possible to access a table field values from within the modern designer, can anyone share a example of how to approach that? We’re looking to form a url like https://somewebsite.com?entryID=202791 where the 202791 is a field value in a result from a lookup table.

0 0

Replies

replied on March 27, 2024 Show version history

This did work on prem for me (Forms 11 Update 5 - Version: 11.0.2311.50556).  I assume it will work in Cloud as well, but I can't promise with 100% certainty that it will work.

For this to work, you need a table which contains 1 Single Line, Number, or similar field (whose ID # you will add to line 4 of the Javascript) and 1 Custom HTML field (whose ID # you will add to line 8 of the Javascript).

This Javascript watches for changes to the first field on the table, and updates the second field (the Custom HTML element) in all rows of the table with a button that opens your link.

//Field ID for the field in the table that contains
//the Entry ID value.  Changes to this field, will
//trigger the creation of or changes to the button.
var sourceFieldID = 3;

//Field ID for the custom HTML field in the table
//that will contain the buttons.
var htmlFieldID = 2

//When changes to the sourceFieldID fields happen,
//custom HTML fields (htmlFieldID) are updated on all
//rows of the table.  The updates include a button
//that is wrapped within a link (anchor) element that
//links to the URL with the sourceFieldID as a
//parameter.
LFForm.onFieldChange( async function() {

  //Retrieve all fields in the table.
  var fieldValuesArray = await LFForm.getFieldValues({fieldId: sourceFieldID});
  var htmlFieldsArray = await LFForm.findFieldsByFieldId(htmlFieldID);
  
  //Loop through all fields in the table.
  for (let i = 0; i < fieldValuesArray.length; i++) {
    var theURL = 'https://somewebsite.com';
    var theParameter = 'entryID=' + fieldValuesArray[i];
    var newHTMLContent = '<a href="' + theURL + '?' + theParameter + '" target="_blank"><button>Click Me!</button></a>';
    LFForm.changeFieldSettings( htmlFieldsArray[i], { content: newHTMLContent } );
  }
  
}, {fieldId: sourceFieldID});

 

Good luck!

EDIT TO ADD: Here's a video of the form in progress: 

4 0
replied on March 27, 2024

That video is the requirement exactly.  Thanks for this snippet.

1 0
replied on April 23

This code works great when there are at least two rows in the table, but for some reason when there is only one row in the table it is only pulling in the first character of the source field.

Does anyone have an idea why that is happening and how to make it work when there is only one row? TIA!

Screenshot 2025-04-23 095632.png
0 0
replied on April 23 Show version history

It's how the LFForm.getFieldValues function handles a single field versus two or more of them.  With two or more, it returns an array of strings.  But with one field, it returns a single string.  Javascript treats a string as an array of single characters, so the code to loop through the values in the array, ends up looping through the characters in the string instead.

Here's a simple function I've started using to make sure it is always an array: 

//Function to return an array or convert a 
//string to an array.
function handleStringOrArray(input) {
  if (typeof input === 'string') {
    return [input];
  } else if (Array.isArray(input)) {
    return input;
  } else {
    return []; // Return an empty array for other data types
  }
}

 

With that function in place, when you get the value back from the LFForm.getFieldValues function, you can pass it into that function.  If it is an array, it just returns unaltered.  But if it is a string, it converts it to a single value array.  Like this: 

var fieldValuesArray = await LFForm.getFieldValues({fieldId: sourceFieldID});
fieldValuesArray = handleStringOrArray(fieldValuesArray);

 

There is likely other ways to handle it too.

2 0
replied on April 23

You're awesome, that works great! Thanks so much for the help! 

0 0
replied on April 23

You're welcome.

0 0
replied on March 27, 2024

You can listen for changes on the field value being populated in the table and use JS to recreate your custom html field. We are exploring an easier way to use variables in custom html fields that can update as the data changes on the form. in the meantime this should get you started.

const textFieldWithId = { fieldId: 23 };
const customHtmlFieldForUrl = { fieldId: 24 };

/**
 *
 * @param {string} id
 * @param {string=} linkText
 * @returns {string}
 */
const makeButtonLink = (id, linkText) => {
  linkText = linkText || 'Open';
  return `<a href="https://somewebsite.com?entryID=${id}" target="_blank">${linkText}</a>`;
};

LFForm.onFieldChange(async (event) => {
  const row = event.options[0].index;
  const id = LFForm.getFieldValues({ fieldId: textFieldWithId, index: row });
  // If you have a field with a friendly name, get it here
  // const friendlyName = LFForm.getFieldValues({ fieldId: 25 });

  const link = makeButtonLink(id);
  await LFForm.changeFieldSettings(customHtmlFieldForUrl, { content: link });
}, textFieldWithId);

 

3 0
replied on March 27, 2024

Thanks for this, yes - it seems a simpler way to use variables in a custom html would be very useful, something like the existing add calculation in the single line text box would do it

 

0 0
You are not allowed to follow up in this post.

Sign in to reply to this post.