2

I have a simple modal popup that edits an item retrieved from the back end. The for has several input and select controls. The input form controls work properly but the select controls are not pre-populated as intended.

The basic architecture of my functions as follows:

function BootboxEditItem(id) {

   $.ajax({
      // Load back end data
   })
   .done(function(data) {

       var itemData = data;

       $.ajax({

          // Load form template for modal
          url: '/modal/item/edit-item.html',
          ......
       })
       .success: function (data) ({

           var box = bootbox.confirm({

               // Set up bootbox buttons;
           },
           callback: function(result){

               // Post edited data back to the server
           }
       )};

       box.on("shown.bs.modal", function(e) {

           // Populate the modal here using data from the backend.
           // This is where the problem lies!
       })

       box.modal("show");
   });
}

Below is the full JavaScript code:

function BootboxEditItem(id) {

var itemDao = '';

$.ajax({

    type: "GET",
    contentType: "application/json",
    url: "/api/item/edit/" + id,
    dataType: "json",
    cache: false
})
.done(function (data) {

    itemDao = data;

    $.ajax({
        type: "GET",
        url: '/modal/item/item-edit-form.html',
        success: function (data) {

            console.log(itemDao);

            var box = bootbox.confirm({

                message: data,
                title: "Edit Item: [" + itemDao.item.sysId + "]",
                buttons: {
                    cancel: {
                        label: "Cancel",
                        className: "btn-danger btn-fixed-width-100"
                    },
                    confirm: {
                        label: "Save",
                        className: "btn-success btn-fixed-width-100"
                    }
                },
                callback: function (result) {



                }
            });

            box.on("shown.bs.modal", function(e) { 

                console.log(e.currentTarget);

                var selectItemLevel = document.getElementById('editItemLevel');

                console.log(selectItemLevel);

                $(selectItemLevel).empty();

                $.each(itemDao.itemLevels, function (key, index) {

                    var opt = document.createElement('option');

                    opt.value = index;
                    opt.innerHTML = 'Level ' + index;

                    selectItemLevel.appendChild(opt);
                });

                $(e.currentTarget).find('select[name="editItemLevel"]').val(selectItemLevel);
                $(e.currentTarget).find('input[name="editIdentifier"]').val(itemDao.item.identifier);
                $(e.currentTarget).find('textarea[name="editItemValue"]').val(itemDao.item.itemValue);

            });

            box.modal('show');
        }
    });
});
}

Here is the code for the HTML file:

<form id="editItem" action="/api/items/save" method="post">

<input type="hidden" name="artifactId" id="artifactId" value="" />
<input type="hidden" name="editId" id="editId" value="" />
<input type="hidden" name="editSysId" id="editSysId" value="" />
<input type="hidden" name="editSortIndex" id="editSortIndex" value="" />

<div class="row">
    <div class="col-sm-6">
        <div class="form-group">
            <label for="editItemLevel">Item level:</label>
            <select class="form-control" id="editItemLevel" name="editItemLevel"></select>
        </div>
    </div>
    <div class="col-sm-6">
        <div class="form-group">
            <label for="editItemClass">Item class:</label>
            <select class="form-control" id="editItemClass" name="editItemClass" onchange="itemEditClassChange();"></select>
        </div>
    </div>
</div>

<div class="row" id="editRequirementRow">
    <div class="col-sm-6">
        <div class="form-group">
            <label for="editItemType">Requirement type:</label>
            <select class="form-control" id="editItemType" name="editItemType"></select>
        </div>
    </div>
    <div class="col-sm-6">
        <div class="form-group">
            <label for="createIdentTemplate">Identifier prefix:</label>
            <select class="form-control" id="editIdentTemplate" name="editIdentTemplate" onchange="itemEditIdentTemplateChange();"></select>
        </div>
    </div>
</div>

<div class="row">
    <div class="col-sm-6">
        <div class="form-group">
            <label for="createMediaType">Media type:</label>
            <select class="form-control" id="editMediaType" name="editMediaType"></select>
        </div>
    </div>
    <div class="col-sm-6" id="editIdentField">
        <div class="form-group">
            <label for="editIdentifier">Identifier:</label>
            <input type="text" class="form-control" id="editIdentifier" name="editIdentifier" />
        </div>
    </div>
</div>

<div class="form-group">
    <label for="editItemValue">Item details:</label>
    <textarea class="form-control"  rows="5" cols="50" id="editItemValue" name="editItemValue"></textarea>
</div>

And here is the output intended for one of the SELECT controls as printed by console.log();

<select class="form-control" id="editItemLevel" name="editItemLevel">
   <option value="1">Level 1</option>
   <option value="2">Level 2</option>
   <option value="3">Level 3</option>
   <option value="4">Level 4</option>
   <option value="5">Level 5</option>
   <option value="6">Level 6</option>
   <option value="7">Level 7</option>
   <option value="8">Level 8</option>
   <option value="9">Level 9</option>
   <option value="10">Level 10</option>

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
Lukuluba
  • 381
  • 1
  • 5
  • 18
  • Where do the select elements exist? Have you ensured the select elements exist in the DOM before you call the modal? Or are they supposed to be created when the modal is created? Also, are the names and ids for the selectItemLevel elements the same? – Emmanuel N K Apr 11 '17 at 08:19
  • The select controls are in the HTML loaded by the url: '/modal/item/item-edit-form.html'. The problem is that all the input controls work using the reference $(e.currentTarget).find('input[name="editIdentifier"]'), but refrence $(e.currentTarget).find('select[name="editItemLevel"]') for select does not work. They are all in the same DOM. – Lukuluba Apr 11 '17 at 08:32
  • can you post the code for item-edit-form.html. The problem is most likely an id/name referencing issue. – Emmanuel N K Apr 11 '17 at 08:38
  • I have updated the question with additional information. Thanks nilerafter24. – Lukuluba Apr 11 '17 at 08:49

2 Answers2

2

It seems your each loop is not properly appending the <option></option>.If you have chrome developer tools and you know how to use it, put a breakpoint in this function and make sure the select options are being created and added to the DOM:

  $.each(itemDao.itemLevels, function (key, index) {
            var opt = document.createElement('option');
            opt.value = index;
            opt.innerHTML = 'Level ' + index;
            selectItemLevel.appendChild(opt); //breakpoint here
        });

Also, since you are already using jQuery, you could add them to the DOM like this:

$.each(itemDao.itemLevels, function (key, index) {
      $(selectItemLevel).append('<option value="'+index+'">Level '+index+'</option>');

});
Emmanuel N K
  • 8,710
  • 1
  • 31
  • 37
1

Thanks to @nilerafetr24, but the problem was not about appending properly. Rather it was about how to get hold of the SELECT control before being shown.

Certainly, the following doesn't work document.getElementById('editItemLevel'), but the following works $(e.currentTarget).find('select[name="editItemLevel"])'.

So, my final solution is to rewrite the loop thus; after combining with the solution suggested by @nilerafetr24 which seems more efficient:

    $.each(itemDao.itemLevels, function (key, index) {

        $(e.currentTarget).find('select[name="editItemLevel"]).append('<option=value="'+index'">Level '+index+'</option');
    });
Lukuluba
  • 381
  • 1
  • 5
  • 18