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

Question

Question

How do I get all fields in a Form / get table variables via Javascript?

asked on August 17, 2023

I have in many instances created a Workflow that re-creates a previously completed Forms process due to an error, accidental completion, etc.  In my experience, the "Invoke Business Process" activity in Workflow is very difficult to use with large Forms.  Selecting each Form variable one-by-one is terribly tedious and far too prone to missing something.

 

Once I have all the variable names, I can repopulate / recreate a Form using an Excel table to prepend the 'RetrieveBusinessProcessVariables' to the field name, saving a fair amount of time when repopulating Forms data.  However, getting those variables initially is still problematic.

 

If someone has other suggestions on a way to easily get all of the variable names for a given Form easily, I am open to suggestions!  My current approach is to use a stripped-down version of the Form with no pagination or special rules to worry about; just all of the fields right there.  I then use this javascript code to populate a div in a Custom HTML field:
 

function getAllFieldVariables(){
  
  $('li[attr]').each(function(){
    // get the current field's variable name
    var attrName = $(this).attr('attr');
    
    // determine if the current object is a table/collection, or a child of one
    var notCollection = $(this).attr('attrtype') != 'collection';
    var notTable = $(this).attr('attrtype') != 'table';
    var collectionName = $(this).parents('li[attrtype="collection"]').attr('attr');
    var tableName =$(this).parents('li[attrtype="table"]').attr('attr');
    
    // create the final variable name I will use to append
    var fieldVarName;
    
    // skip the actual table and collection variables, as I only need those as a prefix
    if (notTable && notCollection){
      
      // if the current field is in a collection, variable name = collection.attr
      if (collectionName)
        fieldVarName = collectionName + '.' + attrName;
      // if the current field is in a table, variable name = table\attr
      else if (tableName)
        fieldVarName = tableName + '\\' + attrName;
      // else the variable name is just the attr value
      else
        fieldVarName = attrName;
      
      // append variable name to custom html div
      $('.variableNames').append(fieldVarName + '<br>');
    }
  });
}

This mostly works pretty well.  I get a newline-delimited list of all the field variable names on the Form, EXCEPT for tables.

 

I have been completely unable to figure out how to identify the actual field variable names for fields inside a table, such that I could use it in my Invoke activity (tableName\variableName).

 

For example, in this table, I need to be able to find the variable name (Single_Line_Field) for the field under the "single" header, but I cannot find it anywhere in the tables properties or attributes when using the browser development tools.

 

Anyone have any tips or suggestions for me?!

0 0

Replies

replied on August 21, 2023 Show version history

Both great answers, thanks!  @████████'s answer more closely meets my specific circumstances, so I'm trying that out (good thinking!), but @████████, I can see your response being very helpful in other circumstances!

I would add for Matthew's suggestion that, for the variable-identifying step (left side of the "=" equation), one would need to also replace the "\" with a "." for Collection fields.

 

If anyone knows how to identify the variable name in a table I'd still be interested in that, out of academic curiosity if nothing else.

2 0
replied on August 18, 2023

It sounds like you are repopulating a new form with all the old form data.  We do the same thing for external forms, so we cant use workflow to create and assign a form to the original submitter.  Here is the JS I use:

 

   //lookup complete
    $(document).on("lookupcomplete", function() {
        console.log("Lookup Complete");

       //update Fields
        function updateField(type, id, value) {
            //If value is an array, update each value for the field
            try {
                JSON.parse(value).forEach(function(x) {
                    updateField(type, id, x);
                });
                return;
            } catch (error){}

            //Checkbox - Radio
            if (["checkbox", "radio"].includes(type)) {
                $("[id='" + id + "'] [value='" + value + "']:not(.value-imported)")
                    .prop("checked", true)
                    //.attr("lookupalt","true")
                    .addClass("value-imported")
                    .trigger("change");
            }
            //Text - LongText - Checkbox:Other - Date - Select
            if (["text", "longtext", "email", "date", "number", "select"].includes(type)) {
                $("[id='" + id + "']:not(.value-imported)")
                    .val(value)
                    //.attr("lookupalt","true")
                    .addClass("value-imported")
                    .trigger("change");
            }

        }
           //Restore Draft
    try {
      JSON.parse($("[attr='Saved_Draft_Object'] textarea").val()).forEach(function(x){
        //Expand Collections
        mI = x[1].match(/Field\d+\((\d+)\)/);
        if(mI){
            coll = $("[id^='"+x[1].split("(")[0]+"']").closest("[attrtype='table']:not(.value-imported)")
            if(coll.length && mI[1] > coll.children(".cf-collection").children().length){
                coll.children(".cf-collection-append").trigger('click');
            }
        }
        updateField(x[0],x[1].split(/-|_other$/)[0],x[2]);
      });
    }catch(error){}
    
	$('.Submit').click(function(){
       
      //Define Field Types
      fieldTypes = [
      ["text","[attrtype='text'] [id^='Field']:not([readonly])"]
      ,["longtext","[attrtype='longtext'] [id^='Field']:not([readonly])"]  
      ,["checkbox","[attrtype='checkbox'] :checked:not([readonly])"]
      ,["checkbox:other","[attrtype='checkbox'] [id$='_other_value']:not([readonly])"]
      ,["radio","[attrtype='radio'] :checked:not([readonly])"]
      ,["date","[attrtype='date'] [id^='Field']:not([readonly])"]
      ,["select","[attrtype='select'] [id^='Field']:not([readonly])"]
      ,["email","[attrtype='email'] [id^='Field']:not([readonly])"]
      ,["number","[attrtype='number'] [id^='Field']:not([readonly])"]
      ]
      //Don't capture: student_id | login_id | access_token | Saved_Draft_Object | IS_DRAFT
      nocap = "[attr='SubmissionLogin'] input, [attr='Saved_Draft_Object'] textarea, [attr='FormURL'] input, [attr='Registrationformurl'] input, [attr='curstep'] input, [attr='ApplicationStatus'] input, [attr='K12ReviewComplete'] input"   
      //Save Draft Object to "Saved_Draft_Object"
      arrayD = []
      fieldTypes.forEach(function(x){
          $(x[1]).not(nocap).filter(function(x){
              return $(this).val()
          })
          .each(function(i){
            console.log(x)
              arrayD.push([x[0],$(this)[0]['id'],$(this).val()])
          })
        });
      $("[attr='Saved_Draft_Object'] textarea").val(JSON.stringify(arrayD));
	});   

All the data on the form is saved to SQL in one column based on Submit being pushed.  If the user needs to correct it, they get an email with a unique link that inputs values in the fields for a lookup to pull back all the data they submitted.  It works for all field types and tables.  Use the nocap if there is anything you dont want saved.

1 0
replied on August 18, 2023

I agree that the "Invoke Business Process" activity in Workflow (and the "Set Business Process Variables" activity too), really needs an easier way to add variables when there are a lot of them.  Especially if you have enough that you have to scroll through the list in the token picker menu to find the next one - ugh!

I really wish there was an "Add Missing Variables" option that looked at all of the variables you already had listed in the "Starting Variable Values" box and compared to everything you had selected above, and then added everything that you selected, but haven't added yet.  That would be so helpful!

That said - for now - the workaround I use when I want a text list of those variables is to use a couple extra activities in Workflow.

  1. Add a Retrieve Business Process Variables activity and link it to the Forms process I want to get the list of variables from.
  2. Add an Assign Token Values activity and use it to get into the full functioned token editor.
  3. From the token editor, I use one hand on my mouse and one hand on my keyboard to alternate between clicking on a token from the list (the next item out of that Retrieve Business Process Variables activity) and clicking the arrow key on my keyboard (because clicking the token adds it to the token editor, but leaves it highlighted, so clicking another one will overwrite it, I use the keyboard arrow key to move after the field and unselect it.  I continue with this alternating click then arrow until I have the full list of tokens out of the Retrieve Business Process Variables activity.
  4. Check the box to "Show tokens as plain text" so that the full token text is displayed.
  5. Copy the token text and paste it into a text editor like Notepad++.
  6. Use the Find and Replace function of the text editor to clean up the tokens.  I replace the "%(RetrieveBusinessProcessVariables_" at the beginning of each value with a line break.  I replace the ")" at the end of each value with a "=".
  7. Now I have a list of every variable that I can paste back into the "Invoke Business Process" activity.
  8. And then I just delete the Retrieve Business Process Variables activity and the Assign Token Values activity that I had added temporarily.

It's a pain in the neck workaround - but it might be less of a pain that the workaround you are using with a copy of the form and special Javascript...

1 0
replied on August 21, 2023

I've started a Feature Request discussion post if anyone else thinks an improvement in the Invoke activity needs to be considered.  You may view it here:
https://answers.laserfiche.com/questions/211271/Feature-Request--Easier-way-to-add-starting-variables-in-Invoke-Business-Process

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

Sign in to reply to this post.