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

Question

Question

Modern/ Layout Designer javaScript: get text of selected option

asked on July 29, 2024 Show version history

Here is what I have been trying so far to no avail:
 

LFForm.onFieldChange(function() {
  var d = LFForm.getFieldValues({fieldId: 175});
  var monthTxt =  d.options[d.selectedIndex].text;
  console.log(monthTxt);
}, {fieldId: 175});

I found the d.options[d.selectedIndex].text on Stack Overflow, but I am unsure how much 'normal' javaScript is compatible wit the LFForm object. EDIT: as long as you are not traversing the DOM, the LFForm object works. 

Has anyone found a way to get the selected text from a drop down? My 'plan b' is to use nested ifs defining the value where '01' = 'January', etc.. But getting a selected value seems like a fundamental thing the javaScript should be able to do. Thus the question...

Use case: I am converting from classic designer and I need both the value and the text from a drop down. It is a month dropdown where the value is a number and the drop down is the text. I have 130 lines of jQuery that are essential to the form. I am converting because unfortunately, when users add 30+ collection lines the entire form slows down to 10 second wait times every time a user clicks something. I tested in modern designer and the speed is significantly better. There is still some lag after 30+ lines but it is usable. 

 

Much thanks in advance folks :)

 

0 0

Answer

SELECTED ANSWER
replied on July 30, 2024 Show version history

Since Forms 11 Update 5 (11.0.2311) you can access the options from dropdown, radio button, and checkbox fields - part of the stuff they added to let us edit labels (like for alternate language use on a form).  It might have existed before, I'm not sure, but I do know this is working now.  Since we can get into the details of the options on the field, we can get the info about option's value and label.  At least on the drop-down, it doesn't look like it has a flag to show which option is marked, but we can get the value from the field and compare to each value in the options to see which one matches.  This might not be the most efficient way to do this, but it has worked for me in my testing.  It works something like this: 

let myFieldID = 175;

LFForm.onFieldChange(function() {
  let selectedOption = LFForm.getFieldValues({fieldId: myFieldID});
  let myOptions = LFForm.findFieldsByFieldId(myFieldID)[0].options;
  myOptions.forEach(function(element, index) {
    if (selectedOption == element.value) {
      console.log(element.label);
    }
  });
}, {fieldId: myFieldID});

 

3 0
replied on July 30, 2024 Show version history

Very nice

Instead of a foreach, you might be able to use .find

let selected = myOptions.find((x) => x.value == selectedOption);
console.log(selected.label);
3 0
replied on July 30, 2024

dang, this might actually be it. I'll test. Thanks!

0 0
replied on July 30, 2024

This is correct, although it did exist prior to this update. The getFieldValues function returns specifically the values of the field which as you found out loses its relation to the label of said value. The field object itself does include that information and you would just need to locate the field label by value in this case.

3 0

Replies

replied on July 29, 2024 Show version history

I'm not sure this is currently possible in the modern designer.

The modern designer sandboxes JavaScript so it doesn't have access to HTML (DOM) elements, which is what you would need to use the .options[index].text properties.

The getFieldValues method of the LFForm object is only returning values, not the input element and I don't see any methods for retrieving the select text vs the underlying value.

UPDATE: As Matthew noted, this can in fact be accomplished with the LFForm object.

1 0
replied on July 30, 2024 Show version history

Thanks Jason. I figured as much. On this form, I do a tremendous amount of traversing the DOM. Not sure if javaScript will be able to do the job here, but have to find out. 

Here is what I ended up doing:

//on change to .claimMonthDrop place month text into .monthVal
LFForm.onFieldChange(function() {
	var mNum = LFForm.getFieldValues({fieldId: 175});
    var mName = '';
         if (mNum == '01') {mName = 'January';} 
    else if (mNum == '02') {mName = 'February';}
    else if (mNum == '03') {mName = 'March';} 
    else if (mNum == '04') {mName = 'April';}
    else if (mNum == '05') {mName = 'May';}
    else if (mNum == '06') {mName = 'June';} 
    else if (mNum == '07') {mName = 'July';}
    else if (mNum == '08') {mName = 'August';} 
    else if (mNum == '09') {mName = 'September';}
    else if (mNum == '10') {mName = 'October';}
    else if (mNum == '11') {mName = 'November';} 
    else if (mNum == '12') {mName = 'December';}
    LFForm.setFieldValues({fieldId: 283}, mName)
}, {fieldId: 175});

 

0 0
replied on July 30, 2024 Show version history

You might be better off with a switch statement; although what you have isn't so complex that it would make a huge difference, switch statements compile and execute in a way that provides better performance.

You could use the switch to set the value directly, but I would set up a separate function with a switch statement to return the month value; this way you can just return instead of having to use break after each case.

function getMonthName(n){
  switch (n) {
    case '01':
      return 'January';
    case '02':
      return 'February';
    case '03':
      return 'March';
    case '04':
      return 'April';
    case '05':
      return 'May';
    case '06':
      return 'June';
    case '07':
      return 'July';
    case '08':
      return 'August';
    case '09':
      return 'September';
    case '10':
      return 'October';
    case '11':
      return 'November';
    case '12':
      return 'December';
    default:
      return '';
  }
}

Place that in your code, then you can just call it from your other code.

//on change to .claimMonthDrop place month text into .monthVal
LFForm.onFieldChange(function() {
    var mNum = LFForm.getFieldValues({fieldId: 175});
    var mName = getMonthName(mNum);

    LFForm.setFieldValues({fieldId: 283}, mName);

}, {fieldId: 175});

 

1 0
replied on July 30, 2024

awesome, thanks for the suggestion. This is great. There is a ton more to come so performance is a big concern.

0 0
replied on July 30, 2024

Thanks so much you all. Incredibly helpful on my javaScript journey :)

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

Sign in to reply to this post.