0

In my Struts2 application, I have a table that is dynamically populated with data, coming from the database (via Eclipselink JPA). Below that table there's a button that became enabled as soon as a row is selected in the table (jQuery). Now, when that button is clicked, I need to know which row is currently selected, so I can access the corresponding object bean, since I need to pass the bean ID (target_id) into the next page (createexperiment2 action). So, in short, the question is: How can I access the Struts2 object bean that is contained in the selected (clicked) table row?

1. Screenshots:

Before row selection -> After row selection

2. JSP code:

<table id="targets" class="ink-table grey tableSection">
    <thead>
        <tr>
            <th colspan="5" class="align-left">Select your target:</th>
        </tr>
    </thead>
    <tbody>
        <s:if test="targets.size > 0">
            <s:iterator value="targets">
                <tr id="row_<s:property value="i"/>">
                    <td class="all-100"><a href="<s:url action="showtarget"><s:param name="id"><s:property value="target_id"/></s:param></s:url>"><s:property value="name"/></a></td>
                    <td class="all-15"><a href="<s:url action="edittarget"><s:param name="id"><s:property value="target_id"/></s:param></s:url>">edit</a></td>
                    <td class="all-5">|</td>
                    <td class="all-15"><a href="<s:url action="deletetarget"><s:param name="id"><s:property value="target_id"/></s:param></s:url>">delete</a></td>
                    <td class="all-5"><a href="help.jsp">?</a></td>
                </tr>
            </s:iterator>
        </s:if>
    </tbody>
</table>

[...]

<a href="createexperiment2" class="ink-button double-vertical-space all-25 buttonSection" id="next" disabled>Next &gt;</a>

3. jQuery code:

$(document).ready(function(){
    $('.tableSection tbody tr').click(function()
    {
        var selected = $(this).hasClass("highlight");

        $('.tableSection tbody tr').removeClass("highlight");
        $('.buttonSection').attr("disabled", false);

        if(!selected)
          $(this).addClass("highlight");
    });
});

EDIT 1:

With the help of Andrea, I've finally been able to access Struts2 functions with jQuery, the poblem is that I can only access the properties of the last bean on the table (the last one that was accessed when the JSP was rendered, which makes sense). See the updated code below, while I'll try a workaround for this:

JSP:

<s:if test="targets.size > 0">
    <s:iterator value="targets">
        <tr onclick="<s:set var="tid" value="target_id"/>">

[...]

        </tr>
    </s:iterator>
</s:if>

[...]

<script type="text/javascript">
    $(function () {
        $('.tableSection tbody tr').click(function(event) {
            alert ('<s:property value="%{#tid}" />');
        });
    });
</script>

EDIT 2:

Now I know which table row index has been clicked, but after hours of trying to assign it to a variable (using Struts tags) and send it to the action, I'm still not getting what I want. I'm not even being able to send this row index to the Action. This is frustrating. Nevertheless, that's how I got to know which row has been selected:

<tr onclick="getRow(this)">

[...]

<script>
function getRow(x) 
{
    alert("Selected row: "+x.rowIndex);

    //return x.rowIndex;
}
</script>

EDIT 3:

This time, I was finally able to send the row ID (a String), to the action. The only remaining issue is that the action gets call twice, the first one on the click event, and the other one because of the href attribute of the a HTML element, which redirects to the desired Struts2 action. Apart of being obviously inneficient, this naturally makes the variable become null on the second call to the action. Do you know how can I somehwow "merge" this 2 calls to the createxperiment2 action into only one? I've tried with the async option in the AJAX call set to false, with no success.

[first, removed the onclick event from the table tr, since I only need to know which row is highlighted when the "Next" button is pressed]. The code currently goes like this:

<script type="text/javascript">
        $('#next').click(function(event)
        {
            var row = $('.highlight').index();

            alert (row);

            $.ajax({
                method: "POST",
                url: "createexperiment2.action",
                data: { row : row }
                });
        });
</script>
Roman C
  • 49,761
  • 33
  • 66
  • 176
João Fernandes
  • 558
  • 3
  • 11
  • 29

2 Answers2

1

Q: I have assigned an ID to each table row. How can I know which one is the selected one?

Obtain the object's id with the this keyword:

$('.tableSection tbody tr').click(function(event) {
    alert (this.id);
    ...

Q: how can I use the selected table row ID to access the corresponding bean object (represented in the row itself)?

This is not clear: just submit your id and retrieve the object serverside, no matter if through AJAX or a standard form submit.

Andrea Ligios
  • 49,480
  • 26
  • 114
  • 243
  • This code indeed opens a pop-up every time I select a row, unfortunately it is empty. I've tried some variations of it's content (e.g., `event.target.target_id`, `event.id`, etc...), however in these cases it goes "worse", i.e., I get a pop-up only with "undefined" in it. What can be possibly wrong here? – João Fernandes Mar 04 '15 at 19:07
  • Ok, this time the code displays a pop-up with "row_", but without the id appended. Also, I think I've been (unconsciously) misleading you, since the value I need to get is the `id` Struts parameter that I've defined as ``, and not the `id` of the `` element itself. I've been looking at these questions: http://stackoverflow.com/questions/17226664/how-to-access-struts-2-variables-in-jquery and http://stackoverflow.com/questions/5440809/how-to-assign-sproperty-value-a-value-to-a-jsp-variable, but still with no luck yet. – João Fernandes Mar 05 '15 at 17:33
  • 1
    Please, if you still haven't figured it out, edit your question by removing the old/unrelated details, and add the missing ones that you have posted in the comment... it will be easier to spot the problem and answer the question, and at the same time easier for future readers to get the Q&A correctly – Andrea Ligios Mar 09 '15 at 15:40
  • This is driving me mad... I've been able to know which row index has been clicked, the problem now is how to retrieve the correspondent bean object & send it to the respective action. Described as "Edit 2" in the original question, above. – João Fernandes Mar 10 '15 at 18:59
  • I think you need exactly this: http://stackoverflow.com/a/25762261/1654265 . Feel free to upvote it, if it'll help – Andrea Ligios Mar 11 '15 at 09:54
  • In your #edit1 it also seems that you are trying to dynamically use struts tags in a javascript block. Struts tags are executed server-side. When the page is loaded, and the javascript block is run, the tag can't fetch any value from server anymore... for that, you need to use AJAX, that is a call to a server side component, that will be executed without submitting your page. – Andrea Ligios Mar 11 '15 at 09:57
  • Thanks for the links, Andrea. Regarding my 1st edit to the original post, yes, I empirically understood that first the Struts code runs, and only after that the JS scripts run. That's why I was only able to access the last `target_id` value (the last one in the list being loaded with `s:iterator`), and not the one that actually matches the table row that is being currently selected. Regarding your last answer, it seems like it is a much more complex situation than mine. Do you recommend a particular approach, from the 3 presented there? Maybe the AJAX call, like @Aleksandr M pointed out above? – João Fernandes Mar 11 '15 at 11:52
  • 1
    Yes, AJAX is an easy and suitable way, probably the best nowadays, according to your specs – Andrea Ligios Mar 11 '15 at 14:00
  • Thanks Andrea, I've followed your suggestion, with only one remaining issue: my Struts action gest called twice, I understand why, but I don't know how to correct this. Please see edit #3 on the original question, above. – João Fernandes Mar 12 '15 at 10:40
  • You need to remove the href attribute (use `href="javascript:void(0);"` or `href="#"`), or otherwise to prevent the default behavior of the anchor with the (guess what?) `event.preventDefault();` method in your click handler – Andrea Ligios Mar 12 '15 at 10:49
  • Removing the `href` attribute was the first thing I've done. However, despite my debugging output @ Eclipse show me that apparently everything is happening as expected (`JSP#1` -> `Action#1` - > `Action#2` -> `JSP#2`), the 2nd JSP page isn't being loaded in the browser. However, like I've said, my debugging output on the `Action#2` `execute()` method is being correclty printed on the console, so it seems that only it doesn't return `SUCCESS` (so that `JSP#2` is loaded). I've double-checked `struts.xml` and everything is apparently well _glued_ (as expected, since it was working fine before). – João Fernandes Mar 12 '15 at 11:30
  • 2
    Dude :| Your AJAX call is fine, your action is executed (now only once), the result is returned but... you are ignoring it. ADD A SUCCESS/DONE/COMPLETE handler to your AJAX jQuery function, then do something with the data returned. Like in the [example I linked above](http://stackoverflow.com/a/28276510/1654265): it's where I do `$("#main").html(data);`. Over and out, if you have other questions please ask them as new questions, this is not a *2337-questions-in-one* Q&A site :| – Andrea Ligios Mar 12 '15 at 12:50
0

Finally, the solution:

First get the ID of the object (I made it with Struts). Then, with the help of an AJAX call, send the ID to the desired action (url: attribute). Upon success of this action, define with the success: callback option where you want to redirect it.

Struts / JSP:

<s:if test="targets.size > 0">
    <s:iterator value="targets">
        <tr id="<s:property value="target_id"/>" class="highlight">

[...]

        </tr>
    </s:iterator>
</s:if>

jQuery:

<script type="text/javascript">
    $('#next').click(function(event)
    {
        var tid = $('.highlight').attr("id");

        $.ajax({
            method: "POST",
            url: "createexperiment2.action",
            data: { tid : tid },
            success:
                function()
                {
                    //alert("TID -> "+tid);
                    window.location = "loadworkloads.action";
                }
        });
    });
</script>
João Fernandes
  • 558
  • 3
  • 11
  • 29