sapui5 - unable to perform expand query in OData v2 model - odata

I develop a little demo application with SAP Netweaver Gateway OData as a backend and SAPUI5 1.44 as UI. I am facing a problem with expanding data with the OData v2 model.
My OData service has 3 entity sets: INDSet, INFSet and INDINFSet. INDSet has a 1:N navigation to INDINFSet, so I'm able to get all INDINFs for particular IND via the following URL:
/sap/opu/odata/SAP/ZGW_ODATA_TEST_SRV/INDSet('IND0000001')/INDINFSet
My UI consists of 2 views:
master view: only has one table.
detail view: a form which I display as a dialog screen. The form has fields of the IND entity and a table which contains INDINFSet records.
The problem is that there is no data on detail view - neither in master entity fields, nor in details table. I don't see any requests in "Network" tab of Chrome dev tools when I open Dialog form - neither on mock server, nor on NW Gateway backend.
Here is a code in master controller which opens the form dialog:
var tbl = this.getView().byId('IndsTable');
var ctx = tbl.getContextByIndex(tbl.getSelectedIndex());
var oData = ctx.getProperty(ctx.sPath);
var sContentDensityClass = this.getOwnerComponent().getContentDensityClass();
var oView = this.getView();
var controller = sap.ui.controller("demo.modules.indform.controller.IndFormDialog");
controller._indFormDialog = oView.byId('IndFormDialog');
if (!controller._indFormDialog) {
controller._indFormDialog = sap.ui.xmlfragment(oView.getId(),
'demo.modules.indform.view.IndFormDialog', controller);
jQuery.sap.syncStyleClass(sContentDensityClass, oView,
controller._indFormDialog);
oView.addDependent(controller._indFormDialog);
}
oView.bindElement({
path: sPath,
model: 'mInd'
});
controller.openDialog(oView);
And here is the dialog itself:
<core:FragmentDefinition
xmlns="sap.m"
xmlns:mvc="sap.ui.core.mvc"
xmlns:l="sap.ui.layout"
xmlns:f="sap.ui.layout.form"
xmlns:t="sap.ui.table"
xmlns:fb="sap.ui.comp.filterbar"
xmlns:core="sap.ui.core">
<Dialog
id="IndFormDialog"
contentWidth="44rem"
contentHeight="49rem"
class="sapUiNoContentPManageing"
showHeader="false"
verticalScrolling="false"
>
<content>
<f:SimpleForm
class='IndForm'
id="IndForm"
maxContainerCols="2"
editable="false"
layout="ResponsiveGridLayout"
labelSpanL="12"
labelSpanM="12"
labelSpanS="12"
emptySpanL="0"
emptySpanM="0"
emptySpanS="0"
columnsL="2"
columnsM="2"
columnsS="2">
<f:content>
<core:Title/>
<Label text="Index code" />
<Input
type="Text"
value="{mInd>/Id}"
/>
<Label text="Index name" />
<Input
type="Text"
value="{mInd>/Sname}"
/>
<Label text="Actual till" />
<DatePicker
value="{mInd>/Eusdt}"
/>
</f:content>
</f:SimpleForm>
<t:Table
id="Infosystems"
rows="{mInd>INDINFSet}"
visibleRowCount="10"
visibleRowCountMode="Auto"
selectionMode="None"
enableSelectAll="false"
ariaLabelledBy="title"
>
<t:toolbar>
<Toolbar>
<Title
id="infosystableTitle"
text="Infosystems"
level="H3"/>
</Toolbar>
<Button
icon="sap-icon://add"
tooltip="Add record"
press="addInfosystem" >
<layoutData>
<OverflowToolbarLayoutData priority="NeverOverflow" />
</layoutData>
</Button>
</t:toolbar>
<t:columns>
<t:Column>
<Label text="Infosystem"/>
<t:template>
<ComboBox
items="{
path: 'mInfs>/INFSet',
sorter: { path: 'Name' },
templateShareable: true
}"
>
<items>
<core:Item key="{mInfs>Id}" text="{mInfs>Name}" selectedKey="{mInd>Infosys}"/>
</items>
</ComboBox>
</t:template>
</t:Column>
<t:Column
width="5em">
<Label text="Is source"/>
<t:template>
<CheckBox selected="{mInd>IsSrc}" />
</t:template>
</t:Column>
</t:columns>
</t:Table>
</content>
<buttons>
<Button
id="IndFormDialogButtonSave"
text="Save"
type="Accept"
press="onPressSave" />
<Button
id="IndFormDialogButtonCancel"
text="Close"
type='Reject'
press="onPressCancel" />
</buttons>
</Dialog>
</core:FragmentDefinition>

Could you try this? Let me know afterwards...
oView.bindElement({
path: sPath,
model: 'mInd',
parameters: {expand:'INDINFSet'}
});

Related

SAP UI5: OData Binding for Header and Detail Set in a PopOver

I am trying to bind a popover to display the line item data based on what was clicked. I am working on a header and detail ODATA set. I am able to display the popover, just having an issue displaying the clicked value. Details below. Thank you in advance.
What I want to achieve: Display 100000 in the popover when clicked.
Popover Controller code:
viewDetails: function(oEvent) {
var oEve = oEvent.getSource();
var oCtx = oEvent.getSource().getParent().getBindingContext("mAggingData");
if (!this._oEditAddPopover) {
this._oEditAddPopover = sap.ui.xmlfragment("Viewcustomeroptions", "Z_AR_AGING.view.ViewCustomerOptions",
this);
}
this.getView().addDependent(this._oEditAddPopover);
this._oEditAddPopover.bindElement(oCtx.getPath().split('/')[2]);
this._oEditAddPopover.openBy(oEve);
},
Data Path:
rows="{ path:'mAggingData>/VendorDetails', hierarchyLevelFor : 'Heirarchy', parameters: {arrayNames:['categories']} }"
View.xml Code:
<Column width="8rem" id="id_level0" sortProperty="Customer" filterProperty="Customer" class="sortingProp">
<m:Label text="Customer" id="CustomerNum"/>
<template >
<m:Link id="customerDetails" text="{mAggingData>Customer}" wrapping="false" class="applyRowHighlight" press="viewDetails"/>
</template>
</Column>
View Customer Options Pop Over - {Customer} not outputting the data in the popover:
<core:FragmentDefinition xmlns="sap.m" xmlns:core="sap.ui.core">
<Popover id="myPopover" title="{Customer}" class="sapUiPopupWithPadding" placement="Right" initialFocus="action">
<footer>
<Toolbar>
<ToolbarSpacer/>
<Button id="action" text="View Customer Details" press="navToCustomer"/>
</Toolbar>
</footer>
</Popover>
</core:FragmentDefinition>
F12 Debugger Output of SPath
Update:
Binding from HeaderSet, but it still does not give the expected output from mAggingData > VendorDetails > categories:
Output
<core:FragmentDefinition xmlns="sap.m" xmlns:core="sap.ui.core">
<Popover id="myPopover" title="{mAggingData>Customer}" class="sapUiPopupWithPadding" placement="Right" initialFocus="action">
<content>
<List id="listPopover" items = "{/CustHeadSet}">
<StandardListItem title="{Customer}"/>
</List>
</content>
<footer>
<Toolbar>
<ToolbarSpacer/>
<Button id="action" text="View Customer Details" press="navToCustomer"/>
</Toolbar>
</footer>
</Popover>
</core:FragmentDefinition>
Prefix the binding in the popover with the model name (i.e. title="{mAggingData>Customer}").

UI5 odata failed to drill down

Hello i set the binding context for an oData request, and the request is called fine.
But on ui5, i get the following error:
Failed to drill-down into Id, invalid segment: Id - ../oData/Users('44ce4852-5985-44c3-9a75-03e252747d29')?$select=Email,FirstName,Id,LastName,UserName sap.ui.model.odata.v4.lib._Cache
Controller:
onInit: function () {
this.getRouter().getRoute("userDetails").attachPatternMatched(this._onObjectMatched, this);
},
_onObjectMatched: function (oEvent) {
var sUserId = oEvent.getParameter("arguments").userId;
console.log(sUserId);
this.getView().bindElement({
path: "/Users('"+sUserId+"')",
model: "som"
});
console.log(sUserId);
},
View:
<Page >
<fLayout:SimpleForm editable="true"
layout="ResponsiveGridLayout"
title="{i18n>settings.user.title}"
labelSpanXL="3"
labelSpanL="3"
labelSpanM="3"
labelSpanS="12"
emptySpanXL="4"
emptySpanL="4"
emptySpanM="4"
emptySpanS="0"
columnsXL="1"
columnsL="1"
columnsM="1" >
<fLayout:content>
<Label text="{i18n>settings.user.id}" />
<Input editable="false" value="{som>Id}" />
<Label text="{i18n>settings.user.userimage}" />
<f:Avatar press="onAvatarPressed" imageFitType="Contain" displaySize="XL" />
<Label text="{i18n>settings.user.username}" />
<Input value="{som>UserName}" />
<Label text="{i18n>settings.user.email}" />
<Input value="{som>Email}" />
<Label text="{i18n>settings.user.firstname}" />
<Input value="{som>FirstName}" />
<Label text="{i18n>settings.user.lastname}" />
<Input value="{som>LastName}" />
</fLayout:content>
</fLayout:SimpleForm>
</Page>
I found the solution, my request was returning a list ant not a single object.

Indexed properties are getting duplicated struts2 on form submission

I need to add/edit/delete the table of objects in struts2. When I submit the form, I am getting objects duplicated.
Let me know where I made a mistake.
This is my code:
<s:form action="addPromotionLineItems" id="promotionLineItemsAddFormId">
<display:table id="data"
name="lstPromotionLineItems" sort="external" uid="row" htmlId="rowid"
class="tborder" excludedParams="*" style="width:100%" export="false">
<display:column titleKey="table.title.material" style="width:100px">
<s:property value="%{#attr.row.materialCode}" />
<s:hidden
name="lstPromotionLineItems(%{#attr.row_rowNum-1}).promotionLineItemId"
value="%{#attr.row.promotionLineItemId}" />
<s:hidden
name="lstPromotionLineItems(%{#attr.row_rowNum-1}).materialCode"
value="%{#attr.row.materialCode}" />
<s:hidden
name="lstPromotionLineItems(%{#attr.row_rowNum-1}).material.description"
value="%{#attr.row.material.description}" />
<s:hidden
name="lstPromotionLineItems(%{#attr.row_rowNum-1}).programId"
value="%{#attr.row.programId}" />
</display:column>
<display:column property="material.description"
titleKey="table.title.materialdesc" />
</s:form>
function refreshTableRecords(url,formNameId,resultId)
$.ajax({
type:'POST',
url: url,
data:$('#'+formNameId).serialize(),
success : function(response) {
$('#'+resultId).html(response);
},
error:function(data)
{
alert(data);
}
});
}
I have this content in jQuery ui modal popup.
I think when mapping to collection data in struts the syntax is not:
name="lstPromotionLineItems(%{#attr.row_rowNum-1}).promotionLineItemId"
rather:
name="lstPromotionLineItems[%{#attr.row_rowNum-1}].promotionLineItemId"
There is a slight difference in the bracketing around the row_num attribute in the input name.

Chrome/Safari POST Issues

I wrote a small shopping cart in .Net that sends someone to PayPal upon order completion to make payment. To send them to PayPal I have the following form on a generic "paypal.aspx" page that has no real user functionality on it:
<form action="http://www.paypal.com/cgi-bin/webscr" method="post" id="paypal">
<input type="hidden" name="cmd" value="_cart"/>
<input type="hidden" name="upload" value="1"/>
<input type="hidden" name="business" value="email#email.com"/>
<input type="hidden" name="tax_cart" id="tax_cart" />
<input type="hidden" name="handling_cart" id="handling_cart" />
<input type="hidden" name="return" id="return" value='<%="http://" + Request.Url.Authority + "/" %>' />
<input type="hidden" name="custom" id="custom" />
<input type="hidden" name="first_name" id="first_name" />
<input type="hidden" name="last_name" id="last_name" />
<input type="hidden" name="address1" id="address1" />
<input type="hidden" name="address2" id="address2" />
<input type="hidden" name="city" id="city" />
<input type="hidden" name="state" id="state" />
<input type="hidden" name="zip" id="zip" />
<input type="submit" id="paypalButton" value="PayPal" style="display: none; visibility: hidden;"/>
</form>
When the page containing this form loads, there is another form directly below it with a bunch of hidden fields that are filled in with data from the actual order (which is pulled based on a Guid query string value). The JavaScript in that form fills in the values that PayPal requires like this:
<form runat="server">
<asp:ScriptManager runat="server" />
<div id="ppItems">
<asp:Repeater runat="server" ID="rpItems">
<ItemTemplate>
<input type="hidden" id='<%#"hv_quantity_" + Container.ItemIndex %>' value='<%#Eval("Quantity") %>' />
<input type="hidden" id='<%#"hv_item_" + Container.ItemIndex %>' value='<%#Eval("Color") + " Tactical Hat" %>' />
<input type="hidden" id='<%#"hv_amount_" + Container.ItemIndex %>' value='<%#Eval("UnitCost", "{0:n2}") %>' />
</ItemTemplate>
</asp:Repeater>
</div>
<asp:HiddenField runat="server" ID="hvCustom" />
<asp:HiddenField runat="server" ID="hvTax" />
<asp:HiddenField runat="server" ID="hvShipping" />
<asp:HiddenField runat="server" ID="hvFirstName" />
<asp:HiddenField runat="server" ID="hvLastName" />
<asp:HiddenField runat="server" ID="hvAddress1" />
<asp:HiddenField runat="server" ID="hvAddress2" />
<asp:HiddenField runat="server" ID="hvCity" />
<asp:HiddenField runat="server" ID="hvState" />
<asp:HiddenField runat="server" ID="hvZip" />
<script type="text/javascript" language="javascript">
var paypal = document.getElementById('paypal');
function load() {
Sys.Application.remove_load(load);
//set the items
var ppItems = document.getElementById('ppItems');
var items = ppItems.getElementsByTagName('input');
var itemsCount = items.length / 3;
for (var i = 0; i < itemsCount; ++i) {
var quantity = document.getElementById('hv_quantity_' + i).value;
var item = document.getElementById('hv_item_' + i).value;
var amount = document.getElementById('hv_amount_' + i).value;
addFormItem('item_name_' + (i + 1), quantity + " " + item);
addFormItem('amount_' + (i + 1), amount);
addFormItem('quantity_' + (i + 1), quantity);
}
//set global items
var custom = document.getElementById('<%=this.hvCustom.ClientID %>').value;
document.getElementById('tax_cart').value = document.getElementById('<%=hvTax.ClientID %>').value;
document.getElementById('handling_cart').value = document.getElementById('<%=this.hvShipping.ClientID %>').value;
document.getElementById('return').value += 'thanks.aspx?p=' + custom;
document.getElementById('custom').value = custom;
document.getElementById('first_name').value = document.getElementById('<%=this.hvFirstName.ClientID %>').value;
document.getElementById('last_name').value = document.getElementById('<%=this.hvLastName.ClientID %>').value;
document.getElementById('address1').value = document.getElementById('<%=this.hvAddress1.ClientID %>').value;
document.getElementById('address2').value = document.getElementById('<%=this.hvAddress2.ClientID %>').value;
document.getElementById('city').value = document.getElementById('<%=this.hvCity.ClientID %>').value;
document.getElementById('state').value = document.getElementById('<%=this.hvState.ClientID %>').value;
document.getElementById('zip').value = document.getElementById('<%=this.hvZip.ClientID %>').value;
//submit to paypal
document.getElementById('paypalButton').click();
}
function addFormItem(name, value) {
var item = document.createElement('input');
item.setAttribute('type', 'hidden');
item.setAttribute('name', name);
item.setAttribute('id', name);
item.setAttribute('value', value);
paypal.appendChild(item);
}
Sys.Application.add_load(load);
</script>
So when this overall page loads, order detail is pulled from the database based on the query string guid value, a bunch of hidden fields are filled with the required values from the database and then the above script runs on load setting the PayPal form values and then clicking the hidden button submits everything to PayPal so the end user can pay.
The issue I have is this works great in IE7+ and FF3+, but Safari and Chrome are not playing nicely. In Chrome I get redirected to the PayPal home page instead of being asked to pay. Safari is even stranger in that both redirect to the PayPal payment screen (like IE7+ and FF3+), but on the Mac version only it doesn't pre-populate all the fields (specifically name/address), but other fields (such as amount, tax, etc.) do populate.
Can anyone provide any suggestions as to why Chrome and Safari (Mac only) don't work right, but everything else seems to?
I finally figured it out by going the old school route and redirecting instead of executing a POST:
var order = (from o in data.Orders where o.PayPal == Request.QueryString["p"] select o).Single();
//build the generic PP detail
sb.Append("http://www.paypal.com/cgi-bin/webscr/?cmd=_cart");
sb.AppendValue("upload", "1", false);
sb.AppendValue("business", "email#domain.com", true);
sb.AppendValue("handling_cart", (this.CurrentCart.Tax.HasValue ? this.CurrentCart.Tax.ToString() : "0"), false);
sb.AppendValue("return", this.Request.Url.Authority, true);
sb.AppendValue("custom", order.PayPal, true);
sb.AppendValue("first_name", (order.Customer.Name.IndexOf(" ") > -1) ? order.Customer.Name.Split(' ')[0] : order.Customer.Name, true);
sb.AppendValue("last_name", (order.Customer.Name.IndexOf(" ") > -1) ? order.Customer.Name.Split(' ')[1] : order.Customer.Name, true);
sb.AppendValue("address1", order.Customer.Address1, true);
sb.AppendValue("address2", order.Customer.Address2, true);
sb.AppendValue("city", order.Customer.City, true);
sb.AppendValue("state", order.Customer.StateProvince, true);
sb.AppendValue("zip", order.Customer.PostalCode, true);
for (int i = 0; i < order.OrderItems.Count; ++i)
{
string index = (i + 1).ToString();
sb.AppendValue("item_name_" + index, order.OrderItems[i].ProductAttribute.Name, true);
sb.AppendValue("amount_" + index, string.Format("{0:n2}", order.OrderItems[i].UnitCost), false);
sb.AppendValue("quantity_" + index, order.OrderItems[i].Quantity.ToString(), true);
}
Response.Redirect(sb.ToString());
The AppendValue method is an extension method for a StringBuilder and it looks like this:
public static void AppendValue(this StringBuilder sb, string name, string value, bool encode)
{
sb.Append("&" + name + "=" + ((encode) ? HttpUtility.UrlEncode(value) : value));
}

Struts2 pagination

My Struts2 application needs the pagination functionality applied to some records, but what I need to customize is the "Last 1 - 2 - 3 Next" appearance and also have the ability to use a combo box for the selection of how many records should be visible(10 - 20 - 30 - 40 -50).
I have tried two way to accomplish this goal:
1) use display tag library, but I'm not able to customize the appearance, because is auto-generated by the library, and I don't how implement the combo box for select how many records should be visible
2) create my own code for accomplish this functionality but is a job too long and not enough time due to the expiry.
My question is: exists some Struts2 library for realize this functionality? Or, is possible to customize the display tag library for the page scroll bar and the records combo box?
I can give insight from struts2 code base there is no functionality as described by you provided by struts2 in itself..
Regarding the Display tag i have not used them much but since they are the part of oprn source i am sure we can customize that one more thing regarding the customization of display tag ask question under display tag you will get better answer at at quick pace
I wrote a custom tld just for the purpose as below and then just use it like this:
Usage:
paginate.tag
1}">
<c:set var="showingPage"
value="${param.pageNumber == null ? 1 : param.pageNumber}" />
<c:url value="${postUrl}" var="previousUrl">
<c:param name="pageNumber" value="${showingPage - 1}" />
<c:param name="perPage" value="${perPage}" />
</c:url>
<c:url value="${postUrl}" var="nextUrl">
<c:param name="pageNumber" value="${showingPage +1}" />
<c:param name="perPage" value="${perPage}" />
</c:url>
<div class="pagination" />
<c:if test="${showingPage > 1}">
<< Previous
</c:if>
<fmt:formatNumber var="endCounter" pattern="0">
<%= totalCount % perPage > 0 ? Math.ceil(totalCount/perPage) + 1 : totalCount/perPage %>
</fmt:formatNumber>
<c:forEach begin="1" end="${endCounter}" var="index">
<c:url value="${postUrl}" var="url">
<c:param name="pageNumber" value="${index}" />
<c:param name="perPage" value="${perPage}" />
</c:url>
${index}
</c:forEach>
<c:if test="${endCounter != showingPage}">
Next >>
</c:if>
</div>
</c:if>
hi you can try struts2 jquery grid here is the code
<%# page contentType="text/html; charset=UTF-8"%>
<%# taglib prefix="s" uri="/struts-tags"%>
<%# taglib prefix="sj" uri="/struts-jquery-tags"%>
<%# taglib prefix="sjg" uri="/struts-jquery-grid-tags"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<sj:div id="resultsDiv">
<body>
<div id="mainframe">
<s:form>
<div id="sucessMsg">
<s:property value="msg" />
</div>
<s:url id="editurl" action="editUser" />
<s:url id="deleteurl" action="deleteUser" />
<script type="text/javascript">
function editLinkFormatter(cellval, options, rowObject, icon, link_class, link_action) {
//alert(rowObject.username);
return "<a href='#' onClick='javascript:openEditDialog(""+cellval+"",""+rowObject.username+"")'><font class='hyperlink'><u>" + rowObject.username + "</u></font></a>";
}
function deleteLinkFormatter(cellval, options, rowObject, icon, link_class, link_action) {
return "<a href='deleteUser?userid="+cellval+"' onClick='javascript: return delete_user()'><font class='hyperlink'><u>Delete</u></font></a>";
//return "Delete";
}
colModal: [
{name: 'userid', formatter: function (cellvalue, options, rowObject) {
return editLinkFormatter(cellvalue, options, rowObject,
'ui-icon-pencil', 'edit-link-class', 'Edit');
}},
{name: 'userid', formatter: function (cellvalue, options, rowObject) {
return deleteLinkFormatter(cellvalue, options, rowObject, icon, link_class, link_action);
}}
];
function openEditDialog(userid,username) {
$("#resultsDiv").load("<s:property value="editurl"/>?userid="+userid+"&username="+username);
}
function delete_user() {
var agree=confirm("Are you sure you want to Delete?");
if (agree){
return true;
}
else{
return false;
}
// $("#edit_Users").dialog('open');
}
function unlockerFormatter(cellval, options, rowObject, icon, link_class, link_action) {
if(rowObject.loginStatus=='Locked'){
return "<a href='unlockuser?userid=" + rowObject.userid + "')'><font class='hyperlink'><u>Locked</u></font></a>";
}
else{
return "UnLocked";
}
/* return "<a href='deleteUser?userid="+cellval+"' onClick='javascript: return deleteUser("+cellval+")'><u>Delete</u></a>"; */
//return "Delete";
}
</script>
<sj:dialog id="edit_Users" title="Edit User" autoOpen="false"
modal="true" width="800" />
<sj:div id="draggable" draggable="true">
<s:url id="remoteurl" action="viewUserstemp" />
<sjg:grid id="gridtable" caption="Users" dataType="json"
href="%{remoteurl}" pager="true" gridModel="gridModel"
rowList="10,15,20,50,100" rowNum="10" rownumbers="true" viewrecords="true"
width="800" navigator="true" navigatorView="false" navigatorDelete="false" navigatorAdd="false" navigatorEdit="false" navigatorSearch="false">
<sjg:gridColumn name="userid" index="userid" title="User Id"
sortable="false" />
<sjg:gridColumn name="userid" index="username" title="User Name"
sortable="true" formatter="editLinkFormatter" />
<sjg:gridColumn name="emailid" index="emailid" title="Email Id"
sortable="true" />
<sjg:gridColumn name="userCreatedDate" index="userCreatedDate"
title="Created Date" sortable="true" />
<sjg:gridColumn name="userModifiedDate" index="userModifiedDate"
title="Modified Date" sortable="true" />
<sjg:gridColumn name="accstatus" index="accstatus"
title="Account Status" sortable="true" />
<sjg:gridColumn name="userid" index="username" title="Delete User"
sortable="true" formatter="deleteLinkFormatter" />
<sjg:gridColumn name="loginStatus" index="loginStatus" title="Unlock User"
sortable="true" formatter="unlockerFormatter" />
</sjg:grid>
<br></br>
<s:submit action="loadUserValues" cssClass="ui-button ui-widget ui-state-default ui-corner-all ui-state-hover" name="button"
id="button" value="New User" />
<br />
</sj:div>
</s:form>
<%--
<td height="25" align="left" valign="middle">
<s:url id="url" action="unlockuser">
<s:param name="userid">
<s:property value="userid" />
</s:param>
</s:url>
<s:set name="type" value="%{loginStatus}" />
<s:if test="%{#type=='Locked'}">
<s:a href="%{url}" title="Click here to Unlock" ><s:property value="loginStatus"/></s:a>
</s:if>
<s:else>
Unlocked
</s:else> --%>
</td>
</div>
</body>
</sj:div>
</html>

Resources