locked
Dropdown list - show selected item on Edit screen. (HTML) RRS feed

  • Question

  • There's probably something really simple that I'm missing.

    I have a custom control on a HTML screen that generates a SELECT element with grouped options that draws the data for the list from the database.  When I edit a record that has a value selected in the list, the list does not show the selected option on screen, although when dropping down the list, the correct item IS selected in the list.  How can I get it to show the selected item on loading the form?

    (Text for selected option does not show when loading the Edit screen).

    (Option selected in the list)

    The render code for this control is as follows:

    myapp.AddEditAbsence.ReasonId_render = function (element, contentItem) {
    
        var reasonId = contentItem.value || 0;
    
        var categoryList = $('<select id="ReasonId" name="ReasonId" class="id-element" data-mini="true"></select>');
        categoryList.appendTo($(element));
    
        if (reasonId === 0) {
            $('#ReasonId').append($('<option value="0" selected></option>'));
        } else {
            $('#ReasonId').append($('<option value="0"></option>'));
        }
    
        myapp.activeDataWorkspace.ebsliveData.SortedReasonCategories().execute()
            .then(function onComplete(categories) {
                categories.results.forEach(function (cat) {
    
                    var opt = $('<optgroup label="' + cat.Category + '"></option>');
    
                    myapp.activeDataWorkspace.ebsliveData.SortedFilteredAbsenceReasons(cat.Id).execute()
                        .then(function onComplete(reasons) {
                            reasons.results.forEach(function (reason) {
                                if (reasonId === reason.Id) {
                                    opt.append('<option value="' + reason.Id + '" selected>' + reason.Reason + '</option>');
                                } else {
                                    opt.append('<option value="' + reason.Id + '">' + reason.Reason + '</option>');
                                }
                            });
                        }, function onError(error) {
                            msls.showMessageBox(error, { title: "Error loading Absence Reasons" });
                        });
    
                    $('#ReasonId').append(opt);
                });
            }, function onError(error) {
                msls.showMessageBox(error, { title: "Error loading Categories" });
            });
    
        $('#ReasonId').change(function () {
            $('#ReasonId option:selected').each(function (d) {
                contentItem.value = $(this).val();
            });
        });
    };

    Thanks for any assistance provided.

    Tuesday, June 11, 2013 3:25 PM

Answers

  • I apologize, as I assumed you were using the variation of the jQuery UI autocomplete-to-dropdown control.

    To show the selected reason when the page is rendered, let me suggest using the beforeShown method from the screen that opens the Add/Edit Absence Record.  In this method, put your promise object calling your SortedReasonCategories and the SortedFilteredAbsenceReasons.  Store the results in an array.  If a positive reasonId match is made, assign it to the screen.Absence.AbsenceReason here as well.

    In the ReasonId_render method, simply populate the Select element with the array you used to save the promise object results above.

    This is the method I use in similar situations to yours with good results.  Since the promise operation is async, it's nice to get it started early before the page is rendered.  This will also get rid of the code smell of the unnecessary global variable.  It would also be preferable if in the beforeShown you  use a chained async promise call instead of the nested one you currently have in your render method.

    Wednesday, June 12, 2013 5:45 PM

All replies

  • Don't you also need to invoke the auto-complete box select event for it to appear in the text box?

    select( event, ui )Type: autocompleteselect

    Triggered when an item is selected from the menu. The default action is to replace the text field's value with the value of the selected item.

    Canceling this event prevents the value from being updated, but does not prevent the menu from closing.

    Code examples:

    Initialize the autocomplete with the select callback specified:

    1
    2
    3
    $( ".selector" ).autocomplete({
    select: function( event, ui ) {}
    });

    Bind an event listener to the autocompleteselect event:

    1
    $( ".selector" ).on( "autocompleteselect", function( event, ui ) {} );

    Tuesday, June 11, 2013 5:00 PM
  • Thanks for your response.  The control is a HTML select list rather than an autocomplete box, and I don't particularly want to bring in JQuery UI just for one control.

    After much fiddling and a lot of swearing, I've managed to get it working with what is not a very elegant solution, but one that does work.

    I have a global variable (yes, I know...) that holds the text corresponding to the selected value in the list (or "" if nothing has been entered, i.e. a new record) which is set in the screen "created" method.

    selectedReason = (screen.Absence.AbsenceReason === undefined) ? "" : screen.Absence.AbsenceReason.Reason;

     The control _render method sets the text using

    $('#ReasonId option:selected').text(selectedReason);

    I'm sure there's a far better solution than that out there, but it will do for now!


    Wednesday, June 12, 2013 9:12 AM
  • I apologize, as I assumed you were using the variation of the jQuery UI autocomplete-to-dropdown control.

    To show the selected reason when the page is rendered, let me suggest using the beforeShown method from the screen that opens the Add/Edit Absence Record.  In this method, put your promise object calling your SortedReasonCategories and the SortedFilteredAbsenceReasons.  Store the results in an array.  If a positive reasonId match is made, assign it to the screen.Absence.AbsenceReason here as well.

    In the ReasonId_render method, simply populate the Select element with the array you used to save the promise object results above.

    This is the method I use in similar situations to yours with good results.  Since the promise operation is async, it's nice to get it started early before the page is rendered.  This will also get rid of the code smell of the unnecessary global variable.  It would also be preferable if in the beforeShown you  use a chained async promise call instead of the nested one you currently have in your render method.

    Wednesday, June 12, 2013 5:45 PM
  • Thanks again.  I'll give that a try!  :)
    Wednesday, June 12, 2013 8:37 PM