struts2 optiontransferselect retrieve and display value from database

JavascriptJavaJqueryJspStruts2

Javascript Problem Overview


In the jsp page, I have a <s:optiontransferselect> for swap values between left side and right side and a submit button to save.

<s:optiontransferselect 
    allowUpDownOnLeft="false"
    allowUpDownOnRight="false"
    allowSelectAll="false"
    allowAddAllToLeft="false"
    allowAddAllToRight="false"
    addToRightLabel="Go to right"
    addToLeftLabel="Go to left"	
    leftTitle="Left side values"
    headerKey="0"
    name="option"
    list= "optionList"
    rightTitle="Right side values"
    doubleHeaderKey="0"
    doubleList="selectedOptionList" 
    doubleName="selectOption"
    doubleId="selectedValues"
>
</s:optiontransferselect>

<s:submit />

I run the program, it actually can save the value from the right side. However it does not show the saved values there.

I am thinking about using javascript and use onchange event in <s:optiontransferselect> to achieve this

<script>
    function show(){
        const list = document.getElementById("selectedValues");
        for (var i = 0; i < list.options.length; i++) {
        //seems something not correct in this part but I am not sure how solve in this way 
            list.options[i].selected = true;
        }
        return true;
    }
</script>

<s:optiontransferselect 
    allowUpDownOnLeft="false"
    allowUpDownOnRight="false"
    allowSelectAll="false"
    allowAddAllToLeft="false"
    allowAddAllToRight="false"
    addToRightLabel="Go to right"
    addToLeftLabel="Go to left"	
    leftTitle="Left side values"
    headerKey="0"
    name="option"
    list= "optionList"
    rightTitle="Right side values"
    doubleHeaderKey="0"
    doubleList="selectedOptionList" 
    doubleName="selectOption"
    doubleId="selectedValues"
    onchange ="show()" <!-- onchange seems not work here -->
> 
</s:optiontransferselect>

When I run the program, the right side still cannot show the saved value.

More information about the optiontransferselect in case it is useful.

I have an action class for it.

public class OptionTransferSelectAction extends ActionSupport {
    private List<String> optionList;
    private List<String> selectedOptionList;
    //private String option;
    private  List<String> option;
    private List<String> selectOption;

    public OptionTransferSelectAction (){
        optionList=new ArrayList<String>();
        //display on the left side for selection
        optionList.add("Section A");
        optionList.add("Section B");
        optionList.add("Section C");
        optionList.add("Section D");
        optionList.add("Section E");
        optionList.add("Section F");
        optionList.add("Section G");
        optionList.add("Section H");

        selectedOptionList=new ArrayList<String>();
        //display on the right side
        //pretend it does not have any values in the first time (does not 
        //trigger the save yet)
        
    }	

    public List<String> getOptionList() {
        return optionList;
    }

    public void setOptionList(List<String> optionList) {
        this.optionList = optionList;
    }

    public List<String> getSelectedOptionList() {
        return selectedOptionList;
    }

    public void setSelectedOptionList(List<String> selectedOptionList) {
        this.selectedOptionList = selectedOptionList;
    }
    /*
    public String getOption() {
        return option;
    }

    public void setOption(String option) {
        this.option = option;
    }
    */
    public List<String> getOption() {
        return option;
    }

    public void setOption(List<String> option) {
        this.option = option;
    }


    public List<String> getSelectOption() {
        return selectOption;
    }

    public void setSelectOption(List<String> selectOption) {
        this.selectOption = selectOption;
    }
}

update

I change option from String to List<String> with the proper getter and setter. I run the code, the optiontransferselect still cannot show the saved values.

Which part I did wrong? Would someone let me know please? Thank you.

update I created a new jsp for example, success.jsp. If I selected some values to selectOption and click the submit button. the jsp file can display the values that I just submitted. I can see the saved values in the database. However the optiontransferselect still cannot show the saved values.

The success.jsp has one code which can display the value I have just submitted.

Selected Value(s) : <s:property value="selectOption"/>

In the database, I can see the saved values, so I would like to know how to let the optiontransferselect show the saved values?

another update

I try to use a button to call javascript function to show selectedValues before submit.

<script>
    function testshow() {
        var value = document.getElementById("selectedValues");
        for(var i=0;i<value.options.length; i++) {
            alert(value.options[i].innerHTML);
        }
        return true;
    }
</script>

//button to call the function
<s:submit onclick="return testshow()"/>

I run the program, when I click the button, it can show the selected values before submit, so I still don't understand why the optiontransferselect cannot get saved selected values.

Javascript Solutions


Solution 1 - Javascript

I think there are two things you need to know in order to solve your issue:

  1. The lifetime of a Struts action.
  2. How the optiontransferselect actually works.

Lifetime of a Struts Action

I start with that, because that might already solve your issue.

A new instance of a Struts action is created for each request.

That means for you when connect the attributes list (left side) and doubleList (right side) to fields in a class derived from ActionSupport - like in the example OptionTransferSelectAction above - you must ensure, that you initialize it with meaningful values, I mean values that reflect the current state you want to show to the user. In the worst case you have to fetch the values from the database with each request.

Alternatively you can inject a bean into the action with a dedicated lifetime (e.g. session scoped). I might line that out in a separate post.

(BTW I would be thankful if someone else could provide further information, if the lifetime of a Struts action can be changed directly).


How optiontransferselect works

This tag wraps up two select tags (or more specifically updownselect tags). I will line out the function of it first, because it makes us better understand optiontransferselect. (Sidenote: Contrary to JSF, Struts clearly distinguishes between attributes for get and set operations.)

To connect the select tag with the underlying data, these are the three relevant attributes:

  1. list - This is the list of all available values (=get).
  2. value - This is the list of values initially selected (=get).
  3. name - The name of the property (field) of the action where the selected values will be supplied on form submit (=set).

So the only property your action will recieve is the one connected with name. The select tag will NOT...

  • ...post back the complete list of values (the value of list) to the action.
  • ...change the values of list and value in the underlying Java class / action.

And the same is true for optiontransferselect. Which makes the semantics quite weird, because some changes (namely which values show up left and which show up right) will never be post back to the Struts action, you only can get hold of the selected values of both sides.

The major difference is that you have those three attributes now twice:

  1. list --> list for the left and doubleList for the right side.
  2. value --> value for the left and doubleValue for the right side.
  3. name --> name for the left and doubleName for the right side.

The question now is how to come by that you will only get the selected values? I would suggest to automatically select them right before submission:

<s:submit value="Save" onclick="selectAllOptions(document.getElementById('idLeft'));selectAllOptions(document.getElementById('idRight'));"/>

Where idLeft corresponds to the value of id in the optiontransferselect and idRight corresponds to the value of doubleId. With that change you would get the complete list of left and right values in name and doubleName respectively.

The code is exactly the same as for the button you would get with allowSelectAll="true" and the JavaScript method selectAllOptions is provided by Struts via the optiontransferselect.js, regardless of allowSelectAll was true or false.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionLearnerView Question on Stackoverflow
Solution 1 - JavascriptnineninesevenfourView Answer on Stackoverflow