I wanted to add a tooltip to the columns in my table and I am using table.tagx by Spring Roo.
Because of the limitations in this tag you can't do it without changeing the tag library itself , I was able to do it and below are the steps to do that
</c:set>
Now the table will show tooltip/title for the columns in it.
Just in case if you need the whole tag file below is a copy paste of table.tagx file
<jsp:root xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:fn="http://java.sun.com/jsp/jstl/functions" xmlns:util="urn:jsptagdir:/WEB-INF/tags/util" xmlns:spring="http://www.springframework.org/tags" xmlns:form="http://www.springframework.org/tags/form" xmlns:fmt="http://java.sun.com/jsp/jstl/fmt" xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0">
<jsp:directive.tag import="java.util.ArrayList" />
<jsp:output omit-xml-declaration="yes" />
<jsp:directive.attribute name="id" type="java.lang.String" required="true" rtexprvalue="true" description="The identifier for this tag (do not change!)" />
<jsp:directive.attribute name="data" type="java.util.Collection" required="true" rtexprvalue="true" description="The collection to be displayed in the table" />
<jsp:directive.attribute name="path" type="java.lang.String" required="true" rtexprvalue="true" description="Specify the URL path" />
<jsp:directive.attribute name="typeIdFieldName" type="java.lang.String" required="false" rtexprvalue="true" description="The identifier field name for the type (defaults to 'id')" />
<jsp:directive.attribute name="create" type="java.lang.Boolean" required="false" rtexprvalue="true" description="Include 'create' link into table (default true)" />
<jsp:directive.attribute name="update" type="java.lang.Boolean" required="false" rtexprvalue="true" description="Include 'update' link into table (default true)" />
<jsp:directive.attribute name="delete" type="java.lang.Boolean" required="false" rtexprvalue="true" description="Include 'delete' link into table (default true)" />
<jsp:directive.attribute name="render" type="java.lang.Boolean" required="false" rtexprvalue="true" description="Indicate if the contents of this tag and all enclosed tags should be rendered (default 'true')" />
<jsp:directive.attribute name="z" type="java.lang.String" required="false" description="Used for checking if element has been modified (to recalculate simply provide empty string value)" />
<c:if test="${empty render or render}">
<c:set var="columnProperties" scope="request" />
<c:set var="columnLabels" scope="request" />
<c:set var="columnMaxLengths" scope="request" />
<c:set var="columnTypes" scope="request" />
<c:set var="columnDatePatterns" scope="request" />
<jsp:doBody />
<c:if test="${empty typeIdFieldName}">
<c:set var="typeIdFieldName" value="id" />
</c:if>
<c:if test="${empty update}">
<c:set var="update" value="true" />
</c:if>
<c:if test="${empty delete}">
<!-- Added by Sajjad , if this is an admin user then he should be able to delete a best practice otherwise no -->
<!--
<c:choose>
<c:when test="${user.admin}">
<c:set var="delete" value="true" />
</c:when>
<c:otherwise>
<c:set var="delete" value="true" />
</c:otherwise>
</c:choose>
-->
<c:set var="delete" value="true" />
<!-- <c:set var="delete" value="true" /> -->
</c:if>
<spring:message var="typeName" code="menu_item_${fn:toLowerCase(fn:split(id,'_')[fn:length(fn:split(id,'_')) - 1])}_new_label" htmlEscape="false" />
<c:set var="lengths" value="${fn:split(columnMaxLengths, '✏')}" scope="request" />
<c:set var="types" value="${fn:split(columnTypes, '✏')}" scope="request" />
<c:set var="patterns" value="${fn:split(columnDatePatterns, '✏')}" scope="request" />
<spring:eval var="colCounter" expression="1" />
<table>
<thead>
<tr>
<c:forTokens items="${columnLabels}" delims="${'✏'}" var="columnHeading">
<th>
<c:out value="${columnHeading}" />
<spring:eval var="colCounter" expression="colCounter + 1" />
</th>
</c:forTokens>
<th></th>
<c:if test="${update}">
<th></th>
<spring:eval var="colCounter" expression="colCounter + 1" />
</c:if>
<c:if test="${delete}">
<th></th>
<spring:eval var="colCounter" expression="colCounter + 1" />
</c:if>
</tr>
</thead>
<c:forEach items="${data}" var="item">
<tr>
<c:forTokens items="${columnProperties}" delims="${'✏'}" var="column" varStatus="num">
<c:set var="columnMaxLength" value="${lengths[num.count-1]}" />
<c:set var="columnType" value="${types[num.count-1]}" />
<c:set var="columnDatePattern" value="${patterns[num.count-1]}" />
<c:set var="colTxt">
<spring:eval expression="item[column]" htmlEscape="false" />
</c:set>
<td title="${colTxt}">
<c:choose>
<c:when test="${columnType eq 'date'}">
<spring:escapeBody>
<fmt:formatDate value="${item[column]}" pattern="${fn:escapeXml(columnDatePattern)}" var="colTxt" />
</spring:escapeBody>
</c:when>
<c:when test="${columnType eq 'calendar'}">
<spring:escapeBody>
<fmt:formatDate value="${item[column].time}" pattern="${fn:escapeXml(columnDatePattern)}" var="colTxt"/>
</spring:escapeBody>
</c:when>
<c:otherwise>
<!-- <c:set var="colTxt">
<spring:eval expression="item[column]" htmlEscape="false" />
</c:set> -->
</c:otherwise>
</c:choose>
<c:if test="${columnMaxLength ge 0}">
<c:set value="${fn:substring(colTxt, 0, columnMaxLength)}" var="colTxt" />
</c:if>
<c:out value="${colTxt}" />
</td>
</c:forTokens>
<c:set var="itemId"><spring:eval expression="item[typeIdFieldName]"/></c:set>
<td class="utilbox">
<spring:url value="${path}/${itemId}" var="show_form_url" />
<spring:url value="/resources/images/show.png" var="show_image_url" />
<spring:message arguments="${typeName}" code="entity_show" var="show_label" htmlEscape="false" />
<a href="${show_form_url}" alt="${fn:escapeXml(show_label)}" title="${fn:escapeXml(show_label)}">
<img alt="${fn:escapeXml(show_label)}" class="image" src="${show_image_url}" title="${fn:escapeXml(show_label)}" />
</a>
</td>
<c:if test="${update}">
<td class="utilbox">
<!-- Added by sajjad if the user is not the creator of this record then don't show update link -->
<c:if test="${item.networkId == user.networkId}">
<spring:url value="${path}/${itemId}" var="update_form_url">
<spring:param name="form" />
</spring:url>
<spring:url value="/resources/images/update.png" var="update_image_url" />
<spring:message arguments="${typeName}" code="entity_update" var="update_label" htmlEscape="false" />
<a href="${update_form_url}" alt="${fn:escapeXml(update_label)}" title="${fn:escapeXml(update_label)}">
<img alt="${fn:escapeXml(update_label)}" class="image" src="${update_image_url}" title="${fn:escapeXml(update_label)}" />
</a>
</c:if>
</td>
</c:if>
<c:if test="${delete}">
<td class="utilbox">
<!-- Added by sajjad if the user is not the creator of this record then don't show delete link -->
<c:if test="${item.networkId == user.networkId}">
<spring:url value="${path}/${itemId}" var="delete_form_url" />
<spring:url value="/resources/images/delete.png" var="delete_image_url" />
<form:form action="${delete_form_url}" method="DELETE">
<spring:message arguments="${typeName}" code="entity_delete" var="delete_label" htmlEscape="false" />
<c:set var="delete_confirm_msg">
<spring:escapeBody javaScriptEscape="true">
<spring:message code="entity_delete_confirm" />
</spring:escapeBody>
</c:set>
<input alt="${fn:escapeXml(delete_label)}" class="image" src="${delete_image_url}" title="${fn:escapeXml(delete_label)}" type="image" value="${fn:escapeXml(delete_label)}" onclick="return confirm('${delete_confirm_msg}');" />
<c:if test="${not empty param.page}">
<input name="page" type="hidden" value="1" />
</c:if>
<c:if test="${not empty param.size}">
<input name="size" type="hidden" value="${fn:escapeXml(param.size)}" />
</c:if>
</form:form>
</c:if>
</td>
</c:if>
</tr>
</c:forEach>
<tr class="footer">
<td colspan="${colCounter}">
<c:if test="${empty create or create}">
<span class="new">
<spring:url value="${path}" var="create_url">
<spring:param name="form" />
</spring:url>
<a href="${create_url}">
<spring:url value="/resources/images/add.png" var="create_img_url" />
<spring:message arguments="${typeName}" code="global_menu_new" var="add_message" htmlEscape="false" />
<img alt="${fn:escapeXml(add_message)}" src="${create_img_url}" title="${fn:escapeXml(add_message)}" />
</a>
</span>
<c:out value=" " />
</c:if>
<c:if test="${not empty maxPages}">
<util:pagination maxPages="${maxPages}" page="${param.page}" size="${param.size}" />
</c:if>
</td>
</tr>
</table>
</c:if>
</jsp:root>
Because of the limitations in this tag you can't do it without changeing the tag library itself , I was able to do it and below are the steps to do that
- In the the table tag file where we are trying to add a new column to this table , under the td tag I defined the parameter title as title ="${colTxt}".
- But the colTxt is defined inside the td tag , so in order to allow the above to run we will have to define the colTxt filter before td like below
<c:set var="colTxt">
<spring:eval expression="item[column]" htmlEscape="false" /></c:set>
Now the table will show tooltip/title for the columns in it.
Just in case if you need the whole tag file below is a copy paste of table.tagx file
<jsp:root xmlns:c="http://java.sun.com/jsp/jstl/core" xmlns:fn="http://java.sun.com/jsp/jstl/functions" xmlns:util="urn:jsptagdir:/WEB-INF/tags/util" xmlns:spring="http://www.springframework.org/tags" xmlns:form="http://www.springframework.org/tags/form" xmlns:fmt="http://java.sun.com/jsp/jstl/fmt" xmlns:jsp="http://java.sun.com/JSP/Page" version="2.0">
<jsp:directive.tag import="java.util.ArrayList" />
<jsp:output omit-xml-declaration="yes" />
<jsp:directive.attribute name="id" type="java.lang.String" required="true" rtexprvalue="true" description="The identifier for this tag (do not change!)" />
<jsp:directive.attribute name="data" type="java.util.Collection" required="true" rtexprvalue="true" description="The collection to be displayed in the table" />
<jsp:directive.attribute name="path" type="java.lang.String" required="true" rtexprvalue="true" description="Specify the URL path" />
<jsp:directive.attribute name="typeIdFieldName" type="java.lang.String" required="false" rtexprvalue="true" description="The identifier field name for the type (defaults to 'id')" />
<jsp:directive.attribute name="create" type="java.lang.Boolean" required="false" rtexprvalue="true" description="Include 'create' link into table (default true)" />
<jsp:directive.attribute name="update" type="java.lang.Boolean" required="false" rtexprvalue="true" description="Include 'update' link into table (default true)" />
<jsp:directive.attribute name="delete" type="java.lang.Boolean" required="false" rtexprvalue="true" description="Include 'delete' link into table (default true)" />
<jsp:directive.attribute name="render" type="java.lang.Boolean" required="false" rtexprvalue="true" description="Indicate if the contents of this tag and all enclosed tags should be rendered (default 'true')" />
<jsp:directive.attribute name="z" type="java.lang.String" required="false" description="Used for checking if element has been modified (to recalculate simply provide empty string value)" />
<c:if test="${empty render or render}">
<c:set var="columnProperties" scope="request" />
<c:set var="columnLabels" scope="request" />
<c:set var="columnMaxLengths" scope="request" />
<c:set var="columnTypes" scope="request" />
<c:set var="columnDatePatterns" scope="request" />
<jsp:doBody />
<c:if test="${empty typeIdFieldName}">
<c:set var="typeIdFieldName" value="id" />
</c:if>
<c:if test="${empty update}">
<c:set var="update" value="true" />
</c:if>
<c:if test="${empty delete}">
<!-- Added by Sajjad , if this is an admin user then he should be able to delete a best practice otherwise no -->
<!--
<c:choose>
<c:when test="${user.admin}">
<c:set var="delete" value="true" />
</c:when>
<c:otherwise>
<c:set var="delete" value="true" />
</c:otherwise>
</c:choose>
-->
<c:set var="delete" value="true" />
<!-- <c:set var="delete" value="true" /> -->
</c:if>
<spring:message var="typeName" code="menu_item_${fn:toLowerCase(fn:split(id,'_')[fn:length(fn:split(id,'_')) - 1])}_new_label" htmlEscape="false" />
<c:set var="lengths" value="${fn:split(columnMaxLengths, '✏')}" scope="request" />
<c:set var="types" value="${fn:split(columnTypes, '✏')}" scope="request" />
<c:set var="patterns" value="${fn:split(columnDatePatterns, '✏')}" scope="request" />
<spring:eval var="colCounter" expression="1" />
<table>
<thead>
<tr>
<c:forTokens items="${columnLabels}" delims="${'✏'}" var="columnHeading">
<th>
<c:out value="${columnHeading}" />
<spring:eval var="colCounter" expression="colCounter + 1" />
</th>
</c:forTokens>
<th></th>
<c:if test="${update}">
<th></th>
<spring:eval var="colCounter" expression="colCounter + 1" />
</c:if>
<c:if test="${delete}">
<th></th>
<spring:eval var="colCounter" expression="colCounter + 1" />
</c:if>
</tr>
</thead>
<c:forEach items="${data}" var="item">
<tr>
<c:forTokens items="${columnProperties}" delims="${'✏'}" var="column" varStatus="num">
<c:set var="columnMaxLength" value="${lengths[num.count-1]}" />
<c:set var="columnType" value="${types[num.count-1]}" />
<c:set var="columnDatePattern" value="${patterns[num.count-1]}" />
<c:set var="colTxt">
<spring:eval expression="item[column]" htmlEscape="false" />
</c:set>
<td title="${colTxt}">
<c:choose>
<c:when test="${columnType eq 'date'}">
<spring:escapeBody>
<fmt:formatDate value="${item[column]}" pattern="${fn:escapeXml(columnDatePattern)}" var="colTxt" />
</spring:escapeBody>
</c:when>
<c:when test="${columnType eq 'calendar'}">
<spring:escapeBody>
<fmt:formatDate value="${item[column].time}" pattern="${fn:escapeXml(columnDatePattern)}" var="colTxt"/>
</spring:escapeBody>
</c:when>
<c:otherwise>
<!-- <c:set var="colTxt">
<spring:eval expression="item[column]" htmlEscape="false" />
</c:set> -->
</c:otherwise>
</c:choose>
<c:if test="${columnMaxLength ge 0}">
<c:set value="${fn:substring(colTxt, 0, columnMaxLength)}" var="colTxt" />
</c:if>
<c:out value="${colTxt}" />
</td>
</c:forTokens>
<c:set var="itemId"><spring:eval expression="item[typeIdFieldName]"/></c:set>
<td class="utilbox">
<spring:url value="${path}/${itemId}" var="show_form_url" />
<spring:url value="/resources/images/show.png" var="show_image_url" />
<spring:message arguments="${typeName}" code="entity_show" var="show_label" htmlEscape="false" />
<a href="${show_form_url}" alt="${fn:escapeXml(show_label)}" title="${fn:escapeXml(show_label)}">
<img alt="${fn:escapeXml(show_label)}" class="image" src="${show_image_url}" title="${fn:escapeXml(show_label)}" />
</a>
</td>
<c:if test="${update}">
<td class="utilbox">
<!-- Added by sajjad if the user is not the creator of this record then don't show update link -->
<c:if test="${item.networkId == user.networkId}">
<spring:url value="${path}/${itemId}" var="update_form_url">
<spring:param name="form" />
</spring:url>
<spring:url value="/resources/images/update.png" var="update_image_url" />
<spring:message arguments="${typeName}" code="entity_update" var="update_label" htmlEscape="false" />
<a href="${update_form_url}" alt="${fn:escapeXml(update_label)}" title="${fn:escapeXml(update_label)}">
<img alt="${fn:escapeXml(update_label)}" class="image" src="${update_image_url}" title="${fn:escapeXml(update_label)}" />
</a>
</c:if>
</td>
</c:if>
<c:if test="${delete}">
<td class="utilbox">
<!-- Added by sajjad if the user is not the creator of this record then don't show delete link -->
<c:if test="${item.networkId == user.networkId}">
<spring:url value="${path}/${itemId}" var="delete_form_url" />
<spring:url value="/resources/images/delete.png" var="delete_image_url" />
<form:form action="${delete_form_url}" method="DELETE">
<spring:message arguments="${typeName}" code="entity_delete" var="delete_label" htmlEscape="false" />
<c:set var="delete_confirm_msg">
<spring:escapeBody javaScriptEscape="true">
<spring:message code="entity_delete_confirm" />
</spring:escapeBody>
</c:set>
<input alt="${fn:escapeXml(delete_label)}" class="image" src="${delete_image_url}" title="${fn:escapeXml(delete_label)}" type="image" value="${fn:escapeXml(delete_label)}" onclick="return confirm('${delete_confirm_msg}');" />
<c:if test="${not empty param.page}">
<input name="page" type="hidden" value="1" />
</c:if>
<c:if test="${not empty param.size}">
<input name="size" type="hidden" value="${fn:escapeXml(param.size)}" />
</c:if>
</form:form>
</c:if>
</td>
</c:if>
</tr>
</c:forEach>
<tr class="footer">
<td colspan="${colCounter}">
<c:if test="${empty create or create}">
<span class="new">
<spring:url value="${path}" var="create_url">
<spring:param name="form" />
</spring:url>
<a href="${create_url}">
<spring:url value="/resources/images/add.png" var="create_img_url" />
<spring:message arguments="${typeName}" code="global_menu_new" var="add_message" htmlEscape="false" />
<img alt="${fn:escapeXml(add_message)}" src="${create_img_url}" title="${fn:escapeXml(add_message)}" />
</a>
</span>
<c:out value=" " />
</c:if>
<c:if test="${not empty maxPages}">
<util:pagination maxPages="${maxPages}" page="${param.page}" size="${param.size}" />
</c:if>
</td>
</tr>
</table>
</c:if>
</jsp:root>
No comments:
Post a Comment