1

I am using display tag to display data in a table on a JSP (using struts 2). Now I want to give two links for each row, one for editing & one for deleting the row.

My jsp structure and what I am currently trying is :

<s:url id="editReport" action="editReport" />
<sd:div href="%{editReport}" listenTopics="editReport" formId="actionForm" showLoadingText="false" preload="false">
    <s:url id="updLists" action="updLists" />
    <sd:div href="%{updLists}" listenTopics="updLists" formId="enterDayReport" showLoadingText="false" preload="false">
        <s:form id="enterDayReport" action="enterDayReport">
            <sd:autocompleter  label="Customer " name="customer" list="customerList"  valueNotifyTopics="updLists" autoComplete="false" searchType="substring"/>
            <sd:autocompleter  label="Contact "  name="contact"  list="contactList"   valueNotifyTopics="updLists" autoComplete="false" searchType="substring"/>
            <s:select          label="Stage "    name="stage"    list="stageList"     headerKey="0" headerValue="Select" />
            <s:select          label="Type "     name="type"     list="typeList"      headerKey="0" headerValue="Select" />
            <sd:datetimepicker label="Date"      name="date"     formatLength="small" displayFormat="dd - MMM - yyyy"/>
            <s:textarea        label="Summary"   name="summary"  cols="40" rows="10"/>
            <s:submit          value="Save Report"/>
        </s:form>
    </sd:div>
</sd:div>

<s:url id="deleteReport" action="deleteReport" />
<sd:div href="%{deleteReport}" listenTopics="deleteReport" formId="actionForm" showLoadingText="false" preload="false">
    <disp:table name="dayReportsList" export="true" class="dataTable">
        <disp:column property="contactCode" title="Contact"/>
        <disp:column property="customerCode" title="Customer"/>
        <disp:column property="stage" title="Stage"/>
        <disp:column property="type" title="Type"/>
        <disp:column property="summary" title="Summary"/>
        <disp:column property="reportDate" title="Date" format="{0,date,dd-MMM-yyyy}" />
        <disp:column property="rowId" href="%{editReport}" paramId="rowID" paramProperty="rowId" title="Action">
            <s:form id="actionForm" name="actionForm">
                <s:hidden id="rowId" name="rowId" value="%{rowId}"/>  // This is not getting populated.
                <s:a onclick="dojo.event.topic.publish('editReport')">Edit<s:property value="rowId"/></s:a><br>
                <s:a onclick="dojo.event.topic.publish('deleteReport')">Delete</s:a>
            </s:form>
        </disp:column>
    </disp:table>
</sd:div>

The problem I am facing here is that, the name of the form associated with every row in the display tag is same. So when I try to access the rowId variable in my action class, I get the value of the first row's rowId only, no matter the button of which row is clicked.

I have seen some examples on stack overflow and google which use URL rewriting, but I don't want to use that.

Please advise.

Thanks!!

kanishk
  • 713
  • 4
  • 15
  • 31
  • This issue shouldn't be tagged as javascript – Munter Dec 19 '11 at 13:02
  • @Munter I was hoping that if I could set a request parameter or something like that in a javascript and then access the same in action class, it should do the trick. Then I will be able to set the parameter value to the 'rowId' and access it in the action class to know which row was clicked. Is there a way to do this ? – kanishk Dec 20 '11 at 09:16

2 Answers2

1

I think it boils down to how you publish events using dojo. I don't know well how dojo works, but your buttons do

dojo.event.topic.publish('editReport')

so I don't see how the subscriber to the "editReport" event could know which row you're trying to delete, and thus which row it must delete.

The documentation for publish shows that an argument may be passed to the publish function. Pass the rowId as argument to the subscribe function, and use this argument in the function editing/deleting the row.

Edit:

The end of the page http://struts.apache.org/2.1.8/docs/ajax-div-template.html shows an example which dynamically changes the href of a div and then refreshes the div. I would use a similar strategy: Have a unique form (rather than one form per row) to edit (or delete) the report in your page. Have each row link publish an event to a topic with the row ID as argument. Have the JavaScript function listening to the topic dynamically change the value of the hidden rowId field of the unique form, and then tells the div to refresh itself.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • Here I am not using subsciber function. The div 'listens' to a topic and when that topic gets 'published', this div gets its contents refreshed from the href mentioned, i.e. the action class. Is there a way by which I can set a parameter or a session variable in javascript, which I can access later on in action class. Will it be a good approach? – kanishk Dec 19 '11 at 17:29
  • The div takes formId as an attribute value which indicates the form whose fields will be serialized and passed as parameters to action class. But here there are multiple forms (1 for each row) how can I specify different name for each form. Or what is other way to implement this scenario. – kanishk Dec 19 '11 at 17:52
  • Thanks JB. I have understood some parts and not understood some. So I will try this out and get back to you. – kanishk Dec 20 '11 at 11:29
  • Got it working. Thanks !! The idea of having one form only and putting the table inside it made it possible. Thanks. – kanishk Dec 21 '11 at 06:37
0

For those still stuck on what is to be done, here is what I finally did to get it working.

The JSP:

<s:url id="editReport" action="editReport" />
<sd:div href="%{editReport}" listenTopics="editReport" formId="actionForm" showLoadingText="false" preload="false">
    <s:url id="updLists" action="updLists" />
    <sd:div href="%{updLists}" listenTopics="updLists" formId="enterDayReport" showLoadingText="false" preload="false">
        <s:form id="enterDayReport" action="enterDayReport">
            <sd:autocompleter  label="Customer " name="customer" list="customerList"  valueNotifyTopics="updLists" autoComplete="false" searchType="substring"/>
            <sd:autocompleter  label="Contact "  name="contact"  list="contactList"   valueNotifyTopics="updLists" autoComplete="false" searchType="substring"/>
            <s:select          label="Stage "    name="stage"    list="stageList"     headerKey="0" headerValue="Select" />
            <s:select          label="Type "     name="type"     list="typeList"      headerKey="0" headerValue="Select" />
            <sd:datetimepicker label="Date"      name="date"     formatLength="small" displayFormat="dd - MMM - yyyy"/>
            <s:textarea        label="Summary"   name="summary"  cols="40" rows="10"/>
            <s:hidden          id="filedOnDate"  name="filedOnDate"/>
            <s:submit          value="Save Report"/>
        </s:form>
    </sd:div>
</sd:div>

<s:url id="deleteReport" action="deleteReport" />
<sd:div href="%{deleteReport}" listenTopics="deleteReport" formId="actionForm"  showLoadingText="false" refreshOnShow="true" preload="false">
    <s:form id="actionForm" name="actionForm" action="">
        <disp:table uid="dayReport" name="dayReportsList" export="true" class="dataTable">
            <disp:column property="contactCode" title="Contact"/>
            <disp:column property="customerCode" title="Customer"/>
            <disp:column property="stage" title="Stage"/>
            <disp:column property="type" title="Type"/>
            <disp:column property="summary" title="Summary"/>
            <disp:column property="reportDate" title="Date" format="{0,date,dd-MMM-yyyy}" />
            <disp:column title="Action">
                <s:a href="" onclick="editEvent(event,%{#attr.dayReport.rowId});">Edit</s:a><br>
                <s:a href="" onclick="deleteEvent(event,%{#attr.dayReport.rowId});">Delete</s:a>
            </disp:column>
        </disp:table>
        <s:hidden id="rowId" name="rowId"/>
    </s:form>
</sd:div>

The JS file:

function editEvent(e,rowId)
{
    dojo.byId('rowId').value=rowId;
    dojo.event.topic.publish('editReport');
}

function deleteEvent(e,rowId)
{
    dojo.byId('rowId').value=rowId;
    dojo.event.topic.publish('deleteReport');
}

This is what is happening here:

When the edit or delete is clicked, the respective function in js is called (and the rowId is passed along). Each function first sets the value of the hidden field to the rowId value (which comes as a parameter to the function), then it punlishes a topic. When the topic is published the repective div calls an action and gets refreshed with new contents. Here I have mentioned the form id of the form in the div tag, so that the action has the value of the hidden field, which has been set to rowId in javascript.

Hope this Helps

Kanishk

kanishk
  • 713
  • 4
  • 15
  • 31