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.
Related
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'}
});
required="false" does not work in "g:select" tag
Example:
<g:select from="${}" name="select" required="false" />
and
<g:select from="${}" name="select" required="true" />
produces a html tag required (in html5)
How can I make the "g:select" produces the required or not, dynamically?
Just remove required, for eg:
<g:select id="select" from="${}" name="select"/>
You can use jquery to change the g:select to be required or not required. For example, lets say you have another
<g:select id="yesNo" from="[yes, no]">
In the gsp, use javascript:
$( "#yesNo" ).change(function() {
if($(this)[0].value == "yes") {
$( "#select" ).attr('required', 'required')
}
else {
$( "#select" ).removeProp( "required" )
}
});
Another approach is if you pass a variable required to gsp, you can use <g:if>:
In controller:
[required: "true"] //If dont want required, simply don't return required at all
In gsp:
<g:if test="${required}">
<g:select from="${}" name="select" required/>
</g:if>
<g:else>
<g:select from="${}" name="select"/>
</g:else>
<g:select from="${}" name="select" required="${false/true}" />
should work !
I have the app working using Radio buttons e.g.
#using (Html.BeginForm("SetCulture", "Home"))
{
<input type="radio" name="culture" id="en-us" value="en-us" class="culture" /> English
<input type="radio" name="culture" id="tr" value="tr" class="culture" /> Türk
}
but when i use input of image type it does not send the wanted VALUE
#using (Html.BeginForm("SetCulture", "Home"))
{
<input type="image" src="~/Content/Images/en.png" name="culture" id="en-us" value="en-us" class="culture" />
<input type="image" src="~/Content/Images/tr.png" name="culture" id="tr" value="tr" class="culture" />
}
jQuery code:
$(".culture").click(function () {
$(this).parents("form").submit(); // post form
});
HomeController Code:
public ActionResult SetCulture(string culture){
// action code here
}
I see no reason why the images wouldn't work but for some reason it happens. Any ideas?
Thank you so much
In the first code block (using <input type="radio" .. />), you form will only post back one value for culture (the value of the selected radio button).
In the second code block (using <input type="image" .. />) your form will post back the values of both inputs, so your form data is culture=en-US&culture=tr
The DefaultModelBinder will bind the first value and ignore the second value so the value of culture in the POST method will always be "en-US" irrespective of which image you click.
One option would be to disable the other input (disabled inputs do not post back a value, for example
$(".culture").click(function () {
$(this).siblings().prop('disabled', true); // disable the other input
$(this).parents("form").submit(); // post form
});
Another option for handling this is to use <img> tags in conjunction with a hidden input for the culture value
<input type="hidden" name="culture" id="culture"/>
<img src="~/Content/Images/en.png" data-culture="en-US" class="culture" />
<img src="~/Content/Images/tr.png" data-culture="tr" class="culture" />
$('.culture').click(function () {
$('#culture').val($(this).data('culture')); // update the hidden input
$('form').submit();
})
How do I use a struts submit button to submit the specific id of an object in an iterated list?
<s:form action="actionDeleteBooking">
<s:iterator var = "bookingList" value="bookings">
<s:submit label="delete booking" value = "cancel booking" theme = "simple" id="bookingid" />
</s:iterator>
</s:form>
I can do if for a radio button:
<s:form action="actionConfirmBooking">
<s:iterator var = "pathList" value="results">
<s:iterator var = "flightList" value="pathList">
<s:radio name="flightSelected" list="flightList" listKey = "flightid" id = "flightid" value = "flightid"/>
</s:iterator>
</s:iterator>
<s:submit label="Submit" />
</s:form>
if what you are trying to achieve is to have a submit button for each "row", submitting one value, then use multiple forms and an hidden field:
<s:iterator var = "bookingList" value="bookings">
<s:form action="actionDeleteBooking">
<s:hidden name="selectedItem" value="%{bookingid}" />
<s:submit label="delete booking" value="cancel booking" theme="simple" />
</s:form>
</s:iterator>
Otherwise use an <s:a />, or set a field with JavaScript, or describe better what you want.
You can use checkbox tag for the items you want to delete. You should be able to do this because you have already used similar form with s:radio.
<s:form action="actionDeleteBooking">
<s:iterator var = "bookingList" value="bookings">
<s:checkbox name="bookingids" label="bookingid" />
</s:iterator>
<s:submit label="delete bookings" value = "cancel booking" theme = "simple"/>
</s:form>
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>