Search code examples
javajqueryjspstruts2double-select

Refresh <s:select> tag on changing backing Java collection in Struts 2


I am using two <s:select> tags and a Java collection List is in its list attribute.

On change of the one I want to populate a second dropdown. I've used jQuery for that, it's called an action bean and populated the list with JSON response when it was returned and then set the values in the second drop down. All is working fine. JQuery code is shown below.

$(document).ready(function () {
    $('#projectNameBox').change(function (event) {
        var projectNameBoxVal = $("select#projectNameBox").val();
        alert(projectNameBoxVal);
        $.getJSON('getPackageListAction.action', {
            "projectId": projectNameBoxVal
        }, function (jsonResponse) {
            alert(jsonResponse);
            var packageNameSelectBox = $('#packageNameBox');
            packageNameSelectBox.find('option').remove();
            $.each(jsonResponse, function (key, value) {
                $('<option>').val(key).text(value).appendTo(packageNameSelectBox);
            });
        });
    });
});

Now my concern is when I updated the second backing list by calling action on change of the first, then why I have to use below code to set option data?

var packageNameSelectBox = $('#packageNameBox');
packageNameSelectBox.find('option').remove();
$.each(jsonResponse, function (key, value) {
    $('<option>').val(key).text(value).appendTo(packageNameSelectBox);
});

Can we just refresh the component to reflect changes of backing list ?


Solution

  • The code is used to modify element of HTML DOM for the second select object to reflect changes in the data model. And if it's a double select scenario, then you should repopulate the data for the second select and return it in the json result.

    You pass the parameter projectId in Ajax call that should be set by the first select in the value attribute when you make an option selection by the first select box. This parameter is set to the action property that you can use to repopulate a map for the second select box.

    The data has been made with one-to-many relationship (Project <- Package), so you can have different packages for the single project.

    Once the parameter for the projectId is set you can query only packages that belong to that project id that equals to package projectId.

    When the data for the second select box is ready you return it with json result that serializes a property that corresponds to the second select box to JSON object.

    You should have different action properties for each select box. That helps to limit a json output to serialize only the property for second select box.

    Once JSON is returned to the client then you need to modify DOM of the second select box, it just can't update itself from the JSON that you received in the Ajax callback.

    You can see the answer with code example: Populating one select menu based on another select menu using AJAX in Struts2.