javajspstruts2struts2-jquerystruts2-jquery-plugin

Implementing <sj:select /> in Struts2


I am currently working with a project, I have multiple select box in my application, each values should change according to the previous value selected in the first list, here is my code, i did not get the second select list.

Here is my jsp.

<s:form id="onSelectList" action="#"> 
  <s:hidden id="c_country" name="buildingName" value="%{bean.building}"></s:hidden>
  <s:hidden id="s_state" name="blockName" value="%{bean.block}"></s:hidden>  
</s:form> 

<s:hidden name="hospitalFloor.buildingName" id="c_country" ></s:hidden>             

<s:url id="loadbuildingurl" action="loadbuildingforFloor"/>
<s:url id="loadstateurl" action="loadblockForFloor"/> 

<s:url id="loadbuildingurl" action="loadbuildingforFloor"/>
<s:url id="loadstateurl" action="loadblockForFloor"/>

<textarea maxlength="200" name="hospitalBlock.blockDescription" id="blockDescription"></textarea> 
<label class="tasks" style="vertical-align:top;"> Select Building :</label>

<sj:select tabindex="10" 
           id="docform_country"
           cssClass="form-control input-sm"
           href="%{loadbuildingurl}"
           name="bean.country"
           list="building"
           onchange="loadValue();"
           onSuccessTopics="s_countryList,s_countryList1"
           onChangeTopics="c_countryList,c_countryList1"
           deferredLoading="false"
           headerKey="-1"
           headerValue="select"
           value="%{bean.country}">
</sj:select>

<label class="tasks" style="vertical-align:top;"> Block :</label>

<sj:select tabindex="10"
           id="docform_state"
           cssClass="form-control input-sm"
           href="%{loadstateurl}"
           name="bean.state"
           list="block"
           formIds="onSelectList"
           onchange="loadValue();"
           onSuccessTopics="s_stateList,s_stateList1"
           onChangeTopics="c_stateList,c_stateList1"
           reloadTopics="c_countryList"
           deferredLoading="false"
           headerKey="-1"
           headerValue="select"
           value="%{bean.state}">
 </sj:select>

This is my struts.xml.

<action name="loadbuildingforFloor" class="hart.hospitalManagement.HospitalBuildingListForFloorAction">
    <result name="success" type="json"></result>                                    
</action>

<action name="loadblockForFloor" class="hart.hospitalManagement.HospitalBlockListForFloorAction" >
    <result name="success" type="json"></result>
</action>

This is my java action class for second selected list.

package hart.hospitalManagement;

import hart.bean.HospitalFloor;
import hart.profilemanagement.DoctorRegistrationHelper;

import java.util.Map;

import com.opensymphony.xwork2.ActionSupport;

public class HospitalBlockListForFloorAction extends ActionSupport {

    private Map<String, String> block;
    private String buildingName;
    private HospitalFloor hospitalfloor;

    public Map<String, String> getBlock() {
        return block;
    }
    public void setBlock(Map<String, String> block) {
        this.block = block;
    }
    public String getBuildingName() {
        return buildingName;
    }
    public void setBuildingName(String buildingName) {
        this.buildingName = buildingName;
    }       

    public String setBlockListForFloor()
    {    
        HospitalFloorManagementHelper hospitalFloorManagementHelper=new HospitalFloorManagementHelper();
        block=hospitalFloorManagementHelper.getBlockListForFloor(buildingName);
        System.out.println("building Name are"+buildingName);
        System.out.println("block list are"+block);
        return SUCCESS;
    }
    public String getJSON()
    {
        return setBlockListForFloor();
    }    
}

This is the helper class.

public Map<String, String> getBlockListForFloor(String buildingName)
{
    int buildingId=0;
    Map<String, String> block=new HashMap<>();
    DbConnect db=new DbConnect();
    Connection con=db.returnConnection();

    try
    {
        Statement stmt1=con.createStatement();
        Statement stmt2=con.createStatement();
        ResultSet rs1=stmt1.executeQuery("select buildingId from hospital_building where buildingName='"+buildingName+"'");
        while(rs1.next())
        {
            buildingId=rs1.getInt("buildingId");

        }
        ResultSet rs2=stmt2.executeQuery("select blockName from hospital_block where buildingId='"+buildingId+"'");
        while(rs2.next())
        {
            block.put(rs1.getString("blockName"), rs1.getString("blockName"));
        }               
    }
    catch(Exception e)
    {
        e.printStackTrace();
    }
    finally
    {
        db.closeConnection(con);
    }

    return block;
}
}

This is the bean class.

private String buildingName;
private String block;

public String getBuildingName() {
    return buildingName;
}
public void setBuildingName(String buildingName) {
    this.buildingName = buildingName;
}

But i can't get the second selected list, please anyone can help me? I am new in struts2.


Solution

  • There is a huge mess in your code. Keep in mind that:

    1. Each private property needs a Getter and a Setter (in some cases is possible to avoid them, but unless you know exactly what you are doing, always generate them); specifically, block in your bean and hospitalfloor in your action are missing them.
    2. I don't see your bean property defined anywhere, while in the JSP page you are referencing it several times (bean.state, bean.country etc).
    3. If you need to post something (and since you are posting the value from select1 to populate select2, you need it), you must put your elements inside a form. In the specific case of <sj:select/>, don't put an action attribute in the form itself, because you are already specifying an action url from the href attribute of <sj:select/>s:

      <s:form>
           <!-- stuff -->
           <sj:select ... />
           <!-- stuff -->
           <sj:select ... />
           <!-- stuff -->
      </s:form> 
      
    4. Your topics are not defined anywhere
    5. Your second select topics are recursively notifying the first select. This is wrong.

    The flow should be:

        <sj:select name = "bean.country" 
                   list = "countries" 
                listKey = "id"
              listValue = "description"
                   href = "%{loadCountriesAction}"
                  value = "%{bean.country}"
         onChangeTopics = "reloadState" 
       onCompleteTopics = "reloadState" />
    
        <sj:select name = "bean.state" 
                   list = "states" 
                listKey = "id"
              listValue = "description"
                   href = "%{loadStatesAction}"
                  value = "%{bean.state}" 
           reloadTopics = "reloadState" 
        deferredLoading = "true" />