Question

I'm trying CRUD operations using a Struts jQuery grid using the struts2-jquery-grid-3.7.0 plugin as demonstrated on the showcase, Grid (Editable/Multiselect).

This is the form:

<s:form namespace="/admin_side" action="Test" validate="true" id="dataForm" name="dataForm">
    <s:url id="remoteurl" action="TestGrid" namespace="/admin_side"/>
    <s:url id="editurl" action="EditTest"/>
    <sjg:grid
        id="gridmultitable"
        caption="Example (Editable/Multiselect)"
        dataType="json"
        href="%{remoteurl}"
        pager="true"
        navigator="true"
        navigatorSearchOptions="{sopt:['eq','ne','lt','gt']}"
        navigatorEdit="true"
        navigatorView="true"
        navigatorAddOptions="{height:280, width:500, reloadAfterSubmit:true}"
        navigatorEditOptions="{height:280, width:500, reloadAfterSubmit:false}"                
        navigatorViewOptions="{height:280, width:500}"
        navigatorDelete="true"
        navigatorDeleteOptions="{height:280, width:500,reloadAfterSubmit:true}"
        gridModel="gridModel"
        rowList="5,10,15"
        rowNum="5"
        rownumbers="true"                
        editurl="%{editurl}"
        editinline="true"
        multiselect="true"
        onSelectRowTopics="rowselect">

        <sjg:gridColumn name="countryId" index="countryId" title="Id" formatter="integer" editable="false" dataType="Long" sortable="true" search="true" sorttype="integer" searchoptions="{sopt:['eq','ne','lt','gt']}"/>
        <sjg:gridColumn name="countryName" index="countryName" title="Country Name" editable="true" sortable="true" search="true" sorttype="text"/>
        <sjg:gridColumn name="countryCode" index="countryCode" title="Country Code" sortable="true" search="true" editable="true" sorttype="text"/>

    </sjg:grid>
</s:form>

A method in the corresponding action class is mapped which is called, while performing operations like adding, deleting and editing of a row.

@Namespace("/admin_side")
@ResultPath("/WEB-INF/content")
@ParentPackage(value = "json-package")
@InterceptorRefs(
    @InterceptorRef(value = "store", params = {"operationMode", "AUTOMATIC"}))
public final class TestAction extends ActionSupport implements Serializable, ModelDriven<Country>
{
    @Autowired
    private final transient CountryService countryService=null;
    private static final long serialVersionUID = 1L;

    private Country entity=new Country();
    private List<Country> gridModel=new ArrayList<Country>();

    private String oper; //Getter and setter.

    @Action(value = "EditTest",
    results = {
        @Result(name = ActionSupport.SUCCESS, location = "Test.jsp"),
        @Result(name = ActionSupport.INPUT, location = "Test.jsp")},
    interceptorRefs = {
        @InterceptorRef(value = "defaultStack", params = {"validation.validateAnnotatedMethodOnly", "true", "validation.excludeMethods", "load"})})
    public String edit() throws Exception {
        System.out.println(entity.getCountryId()+" : "+entity.getCountryName()+" : "+entity.getCountryCode()+" : "+oper);

        if(oper.equalsIgnoreCase("add")) {
             //Adding a row.   
        }
        else if(oper.equalsIgnoreCase("edit")) {
             //Editing/updating a row. 
        }
        else if(oper.equalsIgnoreCase("del")) {
             //Deleting a row.
        }
        return ActionSupport.SUCCESS;
    }

    @Override
    public Country getModel() {
        return entity;
    }

    @Action(value = "Test",
    results = {
        @Result(name = ActionSupport.SUCCESS, location = "Test.jsp"),
        @Result(name = ActionSupport.INPUT, location = "Test.jsp")},
    interceptorRefs = {
        @InterceptorRef(value = "defaultStack", params = {"validation.validateAnnotatedMethodOnly", "true", "validation.excludeMethods", "load"})})
    public String load() throws Exception {
        //This method is required to return an initial view on page load. Nothing to see here. Leave  it empty.
        return ActionSupport.SUCCESS;
    }
}

While deleting, the ID (in this case, countryId) is always null.

While editing, countryId is null because I set editable="false" to the corresponding column of the grid. When it is set to true, it is retrieved but since countryId is a primary key in the database, it should not be edited.

How to get this ID while deleting and editing (while editing, it should not be edited)?

This is not especially related to ModelDriven anymore.


EDIT:

While editing and deleting, id field of type String in an action class like,

private String id;

public String getId() {
    return id;
}

public void setId(String id) {
    this.id = id;
}

is initialized to row ID (of a selected row) of the grid in question.

While deleting of multiple rows, it is initialized to a comma separated string composed of selected IDs.

Performing operations based on row ID of the grid is unreliable. They should be done based on primary key values in the database. Is this possible?

Was it helpful?

Solution

The grid by default uses id field of the entity (if it has) as a unique key for the rows. But if your entity doesn't have such name you can use key attribute for the grid column tag to specify the column name as a key the value used to pass to the action when edit or delete operations are applied. For example

<sjg:gridColumn name="countryId"
                index="countryId"
                title="Id"
                formatter="integer"
                editable="false"
                dataType="Long"
                key="true"
                sortable="true"
                search="true"
                sorttype="integer"
                searchoptions="{sopt:['eq','ne','lt','gt']}"/>

The countryId will be used as a key value for the row in the table and this value will be populated during operations.

OTHER TIPS

just put

loadonce="true"

and search operation work.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top