Search code examples
javascriptselectmodel-view-controllerappendeach

How to append <option> from json result


I have a Db class that called trip, which should have more then one participant, I Want to have a button that each time clicked it will generate a new select element that have an <option> list of all his friend. He should be able to choose more then one friend but to the same friend twice.

I have a JsonResult function in my controller (MVC). I have button that when clicked it will add new select with option for each friend. I tried doing this:

$('#participants').append($('<div class="col-md-2"></div>'))
            .append($('<div class="input-group col-md-3"></div>')
        .append($('<span class="input-group-addon"></span>').text("Username"))
        .append($('<select name="userids" id="test" class="form-control"/>')
        .each(r, function (key, value) {
            $(this).append($('<option></option>').text(value.Text).val(value.Value))
        })
        )
        ).append($('<br>'));

Before that function I have those lines of code:

var r;
var ur = '@Url.Action("FetchFriends", "Trip")';
$.getJSON(ur, function (response) {
    if (Object.keys(response).length) {
        r = response;
    }
});

But it won't work. Anyone have any idea what will work? Thanks!


Solution

  • You can not use $.each like that. Have a look at the doc: jQuery.each() API Doc Let's assume your getJSON call actually returns the right data. And you get an array like this

    [
      {text: 'Text 1', value: 1 },
      {text: 'Text 2', value: 2 },
      {text: 'Text 3', value: 3 }
    ];
    

    I would strongly recommend writing some function to append your select and add the options, like so:

    function addSelect( $element, addonText, selectName ) {
      let $wrapper = $('<div class="col-md-2"></div>');
      let $group = $('<div class="input-group col-md-3"></div>');
      let $addon = $('<span class="input-group-addon"></span>').text(addonText);
      let $select = $('<select name="'+ selectName +'" id="'+selectName+'" class="form-control"/>');
      $group.append($addon).append($select);
      $wrapper.append($group);
      $element.append($wrapper);
    }
    

    and

    function addOptions($select, text, value) {
        $select.append($('<option></option>').text(text).val(value))
    }
    

    that way you can use these funcions in your getJSON Method like so:

    $.getJSON(ur, function (response) {
        if (Object.keys(response).length) {
          $.each(response, function(key, value) {
            addSelect($('#participants), 'username', 'userids');
            let $select = $('#userids');
            addOptions($select, value.text, value.value);
          });
        }
    });
    

    Working example:

    let r = [
    	{text: 'Text 1', value: 1 },
      {text: 'Text 2', value: 2 },
      {text: 'Text 3', value: 3 }
    ];
    
    function addSelect( $element, addonText, selectName, options ) {
    	let $wrapper = $('<div class="col-md-2"></div>');
      let $group = $('<div class="input-group col-md-3"></div>');
      let $addon = $('<span class="input-group-addon"></span>').text(addonText);
      let $select = $('<select name="'+ selectName +'" class="'+selectName+'" class="form-control"/>');
      $group.append($addon).append($select);
      $wrapper.append($group);
      $element.append($wrapper);
      $.each(options, function(key, value) {
      		addOptions($select, value.text, value.value);
      });
    }
    
    function addOptions($select, text, value) {
    	$select.append($('<option></option>').text(text).val(value))
    }
    
    let clicked = 1;
    
    $('#more').on('click', function() {
      let currentId = clicked;
      clicked++;
    	addSelect( $('#participants'), 'username ' + currentId, currentId, r );
    });
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    <div id="participants">
    
    </div>
    <button id="more">
    more
    </button>