locked
How to populate a select htmlhelper with Json? RRS feed

  • Question

  • User-462241089 posted

    I have several select lists in a form that are created with htmlhelpers. Their contents are Json, however.

            @Html.HiddenFor(x => x.RFIModel.PSC, new { id = "PSC-Dropdown_Value" })
    
            @Html.DropDownList("PSC", new SelectList(" "), new { @class = "PSC-Dropdown PSC-Dropdown_Value form-group form-control" })
            @Html.ValidationMessageFor(x => x.RFIModel.PSC, "", new { @class = "text-danger" })
            @Html.LabelFor(x => x.RFIModel.PSC)
    

    I figured out that I can populate these select elements with typescript. But to get the selected value to the controller when submitting the form, I have to assign the value to a hidden element. This is what "AddListeners" does.

    public PopulateDropdown(name: string, json: string[], selected: boolean): void {
        const drop: NodeListOf<HTMLSelectElement> | null = document.querySelectorAll('.' + name);
    
            if (drop != null) {
                //Assign this to 'that' so we don't confuse this'
                var that = this;
                drop.forEach(function (dropdown) {
                    dropdown.options.length = 0; // clear out existing items
                    let selectText: HTMLOptionElement = document.createElement("option");
    
                    selectText.disabled = true;
                    selectText.selected = true;
                    selectText.appendChild(document.createTextNode("Select"));
    
                    dropdown.appendChild(selectText);
                    json.forEach(function (value) {
                        let option: HTMLOptionElement = document.createElement("option");
                        if (selected) {
                            option.setAttribute('selected', 'true');
                            selected = false;
    
                            let hiddenElement: HTMLInputElement | null = document.querySelector("#" + name.toString() + "_Value");
                            if (hiddenElement != null) {
                                hiddenElement.value = value['key'];
                            }
                        }
    
                        option.setAttribute('value', value['key']);
                        option.appendChild(document.createTextNode(value['value']));
                        dropdown.appendChild(option);
                    });
                    //call AddListeners to add onchange listeners to everything to update hidden values in view
                    that.AddListeners(dropdown, name);
                });
            }
        }
    
        public AddListeners(element: HTMLSelectElement, name: string): void {
            element.addEventListener("change", function (value) {
                let hiddenElement: HTMLInputElement | null = document.querySelector("." + name.toString() + "_Value");
                if (hiddenElement != null) {
                    hiddenElement.value = this.value;
                }
            });

    Now, I thought this was working a week ago, but it doesn't seem to work anymore (may be another function clearing all the hidden elements).

    Nonetheless, I want to know, is there a better way to be doing this that what I am doing? Can I pass the json object the the htmlhelper so it populates itself without all this hassle? 

    Thursday, July 2, 2020 8:11 PM

All replies

  • User711641945 posted

    Hi MarcusAtMars,

    Did you must use typescript?If not,you could use the following code which is javascript:

    <body>
        @Html.DropDownList("PSC", new SelectList(" "), new { @class = "PSC-Dropdown PSC-Dropdown_Value form-group form-control" })
    
    </body>
    @section Scripts{
        <script>
            $(function () {
                var json = [
                    { "ID": "001", "Name": "Eurasian Collared-Dove" },
                    { "ID": "002", "Name": "Bald Eagle" },
                    { "ID": "003", "Name": "Cooper's Hawk" },
                ];
                var ele = document.getElementById('PSC');
                for (var i = 0; i < json.length; i++) {
                    // POPULATE SELECT ELEMENT WITH JSON.
                    ele.innerHTML = ele.innerHTML +
                        '<option value="' + json[i]['ID'] + '">' + json[i]['Name'] + '</option>';
                }
            });
        </script>
     }

    Result:

    Best Regards,

    Rena

    Friday, July 3, 2020 5:59 AM
  • User-474980206 posted

    or following the original logic and dropping the unnecessary hidden. to select all options, multiple needs to be set.  in plain javascript:

    const json = [
      {key: 1, value: "hi"},
      {key: 2, value: "bye"},   
    ];
    
    function PopulateDropdown (name, json, selected) {
       document.querySelectorAll('.' + name).forEach(drop => {
          // need to allow multiple selects (odd feature)
          // would of though selected was set by json data     
          if (selected && json.length > 1)
            drop.multiple = true;
    
          // clear select
          drop.length = 0;
    
          // add options
          json.forEach(r => {
              const option = document.createElement("option");
              option.value = r.key;
              option.text = r.value;
              option.selected = selected;
              drop.add(option);
          });
       });
    }
    

    Friday, July 3, 2020 3:07 PM
  • User-462241089 posted

    These still don't populate the actual select element when i select an option. The only things that seem to do the trick is defining the JSON in the HTMLHelper itself, like so:

            @Html.DropDownList("PSC", new SelectList("[
                    { "ID": "001", "Name": "Eurasian Collared-Dove" },
                    { "ID": "002", "Name": "Bald Eagle" },
                    { "ID": "003", "Name": "Cooper's Hawk" },
                ]"), new { @class = "PSC-Dropdown PSC-Dropdown_Value form-group form-control" })
    

    Any ideas?

    Monday, July 6, 2020 1:50 PM
  • User711641945 posted

    Hi MarcusAtMars,

    >These still don't populate the actual select element when i select an option.

    Could you share a screenshot about your dropdownlist when you using my code?Is there any error message?Actually it could populate the dropdownlist as my gif by using my code.

    Best Regards,

    Rena

    Thursday, July 9, 2020 5:57 AM