dimo414
dimo414

Reputation: 48874

Highlight rows in a table with Struts2

I'm preprocessing some data that users upload, and I want to tell them if any lines of the data are invalid. I figured it'd make sense to check each line, if there are errors add that line number to a hashset of errorlines, then when outputting check if the current index is in the hashset, and highlight that row.

Here's the relevant jsp:

    <table>
        <tr>
            <s:iterator value="prettyNames">
                <th><s:property /></th>
            </s:iterator>
        </tr>
        <s:iterator value="importList" status="stat">
            <tr class="class="${lineErrors.contains(%{#stat.index}) ? 'highlight' : ''}"">
                <s:iterator>
                    <td><s:property /></td>
                </s:iterator>
            </tr>
        </s:iterator>
    </table>

Where highlight sets the background color red. However I get a warning in Eclipse saying ""test" does not support runtime expressions" and the page returns a 500 error, "According to TLD or attribute directive in tag file, attribute test does not accept any expressions".

What is the correct way to highlight arbitrary lines in a table?

Upvotes: 3

Views: 2197

Answers (2)

jonathan.cone
jonathan.cone

Reputation: 6706

The reason you're seeing this error is because you're trying to evaluate a standard JSP EL expression inside of a Struts2 tag attribute, in this case "test". You need to use the OGNL notation with S2 tags, like so (assuming lineErrors resolves against the ValueStack):

<table>
    <tr>
        <s:iterator value="prettyNames">
            <th><s:property /></th>
        </s:iterator>
    </tr>
    <s:iterator value="importList" status="stat">
        <s:if test="%{lineErrors.contains(#stat.index)}">
            <tr class="highlight">
                <s:iterator>
                    <td><s:property /></td>
                </s:iterator>
            </tr>
        </s:if>
        <s:else>
            <tr>
                <s:iterator>
                    <td><s:property /></td>
                </s:iterator>
            </tr>           
        </s:else>
    </s:iterator>
</table>

Of course the shorter way would be something like this, where you nest the S2 property tag inside the class attribute, but this is less readable:

<table>
    <tr>
        <s:iterator value="prettyNames">
            <th><s:property /></th>
        </s:iterator>
    </tr>
    <s:iterator value="importList" status="stat">
        <tr class="<s:property value='%{lineErrors.contains(#stat.index) ? "highlight" : ""}' />">
            <s:iterator>
                <td><s:property /></td>
            </s:iterator>
        </tr>           
    </s:iterator>
</table>

Upvotes: 1

Java Drinker
Java Drinker

Reputation: 3167

The way you have it is not valid XHTML. You cannot have the <tr> tag started where ever you please. I would re-write this as something like

<tr class="${lineErrors.contains(%{#stat.index}) ? 'highlight' : ''}">
    <!--whatever-->
</tr>

That's what I would do in something like Facelets, so probably the EL works the same way in struts. I'm not sure I understand the %{#... maddness that's happening

Upvotes: 0

Related Questions