I have two jsp page, say form.jsp and myForm.jsp.
In the first page, form.jsp, there is a radio button group (the form name is "form").
When the user submits this form, some info are retrieved from a db and with these informations the form in myForm.jsp is built (the form name is "myForm").
The problem is that when this second form is submitted, only the errors are displayed but not the form fields created from db values.
For example, I retrieve from database labels and values for two radio buttons (property="prop").
In struts-config.xml, I have:
<form-bean name="myForm" type="org.apache.struts.validator.MyValidatorActionForm">
<form-property name="prop" type="java.lang.Integer"></form-property>
</form-bean>
<action path="/form" input="/jsp/home.jsp" name="form" scope="request" type="myPackage.LoadInfo">
<forward name="Success" path="/jsp/myForm.jsp"/>
<forward name="Failure" path="/jsp/home.jsp" />
</action>
<action path="/myForm" input="/jsp/myForm.jsp" name="myForm" validate="true" scope="request" type="myPackage.MyValidatorAction">
<forward name="Success" path="/jsp/success.jsp"/>
<forward name="Failure" path="/jsp/failure.jsp"/>
</action>
In myForm.jsp:
<html:form action="/myForm">
<div><label>* <bean:message key="myForm.label"/></label>
<c:forEach var="propTypes" items="${props}">
<html:radio property="prop" value="${propTypes.value}">${propTypes.label}
</html:radio>
</c:forEach>
<html:errors property="prop" />
</div>
<div><html:submit><bean:message key="myForm.label2"/></html:submit></div>
</html:form>
In validation.xml:
After the form submit without select any radio button, the error is displayed, but not the radio buttons.
How could I maintain all the request attributes?
I tried to use scope session too, but nothing has changed:
<action path="/myForm" input="/jsp/myForm.jsp" name="myForm" validate="true" scope="session" type="myPackage.MyValidatorAction">
<forward name="Success" path="/jsp/success.jsp"/>
<forward name="Failure" path="/jsp/failure.jsp"/>
</action>
I resolved by using:
request.getSession().setAttribute("props", props);
in the Action LoadInfo called before the display of the form.
In myForm.jsp I use:
request.getSession().getAttribute("props");
Instead in the struts-config.xml, the scope remains request.
Nevertheless, this isn't a good solution, 'cause different browser tabs share the same session.
How could I resolve this issue?
Your form fields in your jsp page should have corresponding properties in your ActionForm class.
So if your jsp has a the following radio button
<html:radio name="myForm" property="name">
You need a corresponding property in your action form as follows and make sure you have the getters and setters:
public class MyClass{
private String name;
public String getName()
{
return name;
}
public void setName(String name){
this.name = name;
}
If you set it up this way, the user entered values should still be there when your page refreshes.
Related
I am having trouble getting data binding to work with custom components.
I have created an IncrementValue property that gets incremented with every button click.
The changes are reflected when binded to a Label.
However they do not work when I bind it to a Bindable property in a custom component.
In the example, I have built a custom component called Card which has two bindable properties CardTitle and CardIncrement
Is there something I'm missing as I'm new to MAUI and even Xamarin.
Github link of code snippets below: https://github.com/814k31/DataBindingExample
Card.xaml.cs
namespace DataBindingExample;
public partial class Card : VerticalStackLayout
{
public static readonly BindableProperty CardTitleProperty = BindableProperty.Create(nameof(CardTitle), typeof(string), typeof(Card), string.Empty);
public static readonly BindableProperty CardIncrementProperty = BindableProperty.Create(nameof(CardIncrement), typeof(int), typeof(Card), 0);
public string CardTitle
{
get => (string)GetValue(CardTitleProperty);
set => SetValue(CardTitleProperty, value);
}
public int CardIncrement
{
get => (int)GetValue(CardIncrementProperty);
set => SetValue(CardIncrementProperty, value);
}
public Card()
{
InitializeComponent();
BindingContext = this;
}
}
Card.xaml
<?xml version="1.0" encoding="utf-8" ?>
<VerticalStackLayout
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:databindingexample="clr-namespace:DataBindingExample"
x:DataType="databindingexample:Card"
x:Class="DataBindingExample.Card"
Spacing="25"
Padding="30,0"
VerticalOptions="Center"
BackgroundColor="red"
>
<Label
Text="{Binding CardTitle}"
SemanticProperties.HeadingLevel="Level1"
FontSize="32"
HorizontalOptions="Center"
/>
<Label
Text="{Binding CardIncrement}"
SemanticProperties.HeadingLevel="Level1"
FontSize="32"
HorizontalOptions="Center"
/>
</VerticalStackLayout>
MainPage.xml
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="DataBindingExample.MainPage"
xmlns:DataBindingExample="clr-namespace:DataBindingExample"
xmlns:ViewModels="clr-namespace:DataBindingExample.ViewModels"
x:DataType="ViewModels:MainPageViewModel"
>
<ScrollView>
<VerticalStackLayout
Spacing="25"
Padding="30,0"
VerticalOptions="Center"
>
<Label
Text="{Binding IncrementedValue}"
SemanticProperties.HeadingLevel="Level2"
FontSize="18"
HorizontalOptions="Center"
/>
<!-- Why doesnt this work? -->
<DataBindingExample:Card CardIncrement="{Binding IncrementedValue}" />
<Button
x:Name="CounterBtn"
Text="Click Me"
SemanticProperties.Hint="Counts the number of times you click"
Command="{Binding IncrementValueCommand}"
HorizontalOptions="Center"
/>
</VerticalStackLayout>
</ScrollView>
</ContentPage>
When making a custom component (that includes XAML), DO NOT set BindingContext = this;.
REASON: You want the component to use the SAME BindingContext as the page it is placed in. This happens automatically, if you do NOT set a BindingContext in the custom component.
HOWEVER, removing this line breaks all your component's xaml Bindings; you'll need to add something to the xaml, to fix this.
Or to put it another way: How refer to the card's Properties from its XAML? See the next section.
ACCESS COMPONENT PROPERTIES VIA x:Name
Solution: Give the card an x:Name, and make that the "Source" of those bindings:
<VerticalStackLayout
...
x:Name="me" <-- IMPORTANT! Change name as desired.
x:Class="DataBindingExample.Card"
>
...
<Label Text={Binding CardIncrement, Source={x:Reference me}}"
...
Notice the two parts to this solution:
In component's xaml header, define x:Name="mynamehere".
In each Binding, say that the component is the source:
, Source={x:Reference mynamehere}.
OPTIONAL: If custom component has a "ViewModel":
To have a custom component be "data-driven", pass in a parameter that controls its behavior.
This parameter could be considered a "ViewModel", but above I have specified:
DO NOT set a BindingContext (so that component has easy access to the page's BindingContext).
So unlike other uses of ViewModel, in this technique, we don't set the ViewModel as the BindingContext.
How access this ViewModel?
By saving it as a property of the component; e.g.:
public partial class MyComponent : ContentView
{
private MyViewModel VM;
public void MyComponent(MyViewModel vm)
{
InitializeComponent();
VM = vm;
}
public class MyViewModel : ObservableObject
{
[ObservableProperty]
SomeType someProperty; // This is field. Property "SomeProperty" is generated.
}
Then in xaml, we access properties of VM, using . notation:
<Label Text={Binding VM.SomeProperty, Source={x:Reference me}}"
i have to edit a row in a table using rich faces 4 and modal panel. I am new one so please tell me in details and i know to make a table in rich faces. i already searched so many things but not getting any fruitful
See answer for question "Richfaces: show details in popup [commandbutton, action and popupPanel]". It works in RichFaces 4.x with rowClick.
Or here is example with commandLink:
<a4j:commandLink action="#{actionBean.setupTransactionDetails}"
event="onclick" render="transactionDetails"
oncomplete="#{rich:component('transactionDetails')}.show()"
styleClass="rich-link">
<h:outputText value="#{res.transactionType}" />
<f:setPropertyActionListener value="#{res.transactionId}"
target="#{profile.transactionId}" />
</a4j:commandLink>
But I prefer updated version like this:
<a4j:jsFunction name="showDetail" action="#{actionBean.setupTransactionDetails}"
oncomplete="#{rich:component('transactionDetails')}.show();"
render="transactionDetails">
<a4j:param name="id" assignTo="#{profile.transactionId}"
converter="javax.faces.Long" />
</a4j:jsFunction>
<rich:dataTable id="txnTable" rows="#{referenceData.recordsPerPage}"
style="width: 100%" rowClasses="oddrow, evenrow"
value="#{profile.transactions}" var="res" sortMode="single">
<h:column width="110">
<f:facet name="header">
<h:outputText value="#{msg.transactionType}" />
</f:facet>
<a4j:commandLink onclick="showDetail('#{res.transactionId}');"
value="#{res.transactionType}" />
</h:column>
</rich:dataTable>
<rich:popupPanel id="transactionDetails" autosized="true"
style="max-height:600px;">
<!-- f:facet name="header" and f:facet name="controls" here -->
<h:form id="transactionDetailsForm">
<!-- some details here -->
</h:form>
</rich:popupPanel>
Profile backing bean
private Long transactionId; // + getter and setter
Action backing bean
public void setupTransactionDetails() {
Transaction txn = DAO.getInstance().get(Transaction.class, getProfile().getTransactionId());
transactionForm.setup(txn);
}
In case if you use EL 2.2 (or higher) you can call action bean method with parameter.
I've got a form within a p:dialog component being submitted via AJAX. The form in the dialog is via a ui:include of another .xhtml containing just the form and its components (no, I am not nesting forms; the dialog itself is not within any form). The included page's backing bean is 'ViewScoped'.
MOST things function fine:
On successful validation, the form will execute the save method; after a successful save, the dialog closes; opening a subsequent record shows proper record information from the database.
On unsuccessful validation, the submitted values persist and the dialog remains open and displays validation errors, fixing the invalid fields and resubmitting results in a successful save.
The problem comes in when the action called by the p:commandButton fails. In the event that it fails, the dialog remains open and displays "Error saving changes" via h:messages to the user; additionally, the submitted values still persist in the input fields. This is fine (and even desired) while the form remains open, however-- upon closing the dialog and reopening it, the submitted values are STILL in the text fields. This is bad because it gives the user the impression that the save did succeed (as the h:messages component is now blank due to the dialog update).
So far I have tried the following, NONE of which have remedied the problem:
1.1) Setting the backing bean of the included form to a new instance of the bean on dialog open.
1.2) Since the bean is now a new instance, I am also repopulating the address object with details from a data bean.
2.1) Disabling the close button on the dialog and adding a p:commandButton "Cancel" button with a p:resetInput component in
it to close the dialog/reset the form. (dialog closes, but submitted
values in form persist).
2.2) Calling a method from this p:commandButton that removes the RequestMap for the included form's backing bean.
2.3) Tried with the button set to both immediate=true and immediate=false.
2.4) Tried with the button set to process=#this, a similar tactic I have used to close a form to ensure it will have fresh fields upon
reopening.
You would think between setting the backing bean to a new instance, and repopulating the address object I would be seeing a fresh form, but NOPE.
Here is some of the source:
Portion of mainform.xhtml
<p:dialog id="dlgAddress"
header="Address Edit"
widgetVar="dialogAddress"
dynamic="true"
modal="false"
closable="false"
resizable="false"
styleClass="dlgAddress"
visible="#{addressform.showDlgAddress}">
<ui:include src="addressform.xhtml"/>
</p:dialog>
addressform.xhtml
<h:form id="fDlgAddress">
<div id="addresses-container">
<h:messages id="msgDlgAddress" errorClass="errormsg" infoClass="infomsg1" layout="table"/>
<h:panelGrid columns="1"
styleClass="pgAddresses"
rendered="#{!addressform.address.exists}">
<h:outputText value="No active #{addressform.address.atypCode} address found."
styleClass="record-not-exists"/>
<h:outputText value="Use the form below to create one."/>
</h:panelGrid>
<p:panelGrid columns="2"
styleClass="pgDlgForm pgAddresses">
<h:outputLabel value="Address Type"/>
<h:inputText id="atypCode1"
value="#{addressform.address.atypCode}"
disabled="true"
rendered="#{addressform.address.exists}"/>
<h:selectOneMenu id="atypCode2"
value="#{addressform.address.atypCode}"
rendered="#{!addressform.address.exists}">
<f:selectItems value="#{addressform.atypCodeList}"
var="atyp"
itemValue="#{atyp}"
itemLabel="#{atyp}"/>
</h:selectOneMenu>
<h:outputLabel value="Street 1"
for="street1"/>
<h:inputText id="street1"
value="#{addressform.address.addressLine1}"/>
<h:outputLabel value="Street 2"
for="street2"/>
<h:inputText id="street2"
value="#{addressform.address.addressLine2}"/>
<h:outputLabel value="Street 3"
for="street3"/>
<h:inputText id="street3"
value="#{addressform.address.addressLine3}"/>
<h:outputLabel value="Street 4"
for="street4"/>
<h:inputText id="street4"
value="#{addressform.address.addressLine4}"/>
<h:outputLabel value="City"
for="city"/>
<h:inputText id="city"
value="#{addressform.address.city}"
required="true"
requiredMessage="Please enter a city."/>
<h:outputLabel value="State"
for="statCode"/>
<h:selectOneMenu id="statCode"
value="#{addressform.address.stateCode}">
<f:selectItem itemLabel="Select State/Province"
itemValue=""/>
<f:selectItems value="#{states.statesList}"
var="stat"
itemValue="#{stat.statCode}"
itemLabel="#{stat.statDesc}"/>
</h:selectOneMenu>
<h:outputLabel value="Zip Code"
for="zipCode"/>
<h:inputText id="zipCode"
value="#{addressform.address.zip}"/>
<h:outputLabel value="Country"
for="natnCode"/>
<h:selectOneMenu id="natnCode"
value="#{addressform.address.nationCode}"
required="true"
requiredMessage="Please choose a nation.">
<f:selectItem itemLabel="Select Country"
itemValue=""/>
<f:selectItems value="#{nations.nationsList}"
var="natn"
itemValue="#{natn.natnCode}"
itemLabel="#{natn.natnDesc}"/>
</h:selectOneMenu>
<h:outputLabel value="From Date"
for="fromDate"/>
<p:calendar id="fromDate"
value="#{addressform.address.fromDate}"
showButtonPanel="true"/>
<h:outputLabel value="To Date"
for="toDate"/>
<p:calendar id="toDate"
value="#{addressform.address.toDate}"
showButtonPanel="true"/>
<h:outputLabel value="Inactivate"
for="inactivateAddress"
rendered="#{addressform.address.exists}"/>
<h:selectBooleanCheckbox id="inactivateAddress"
value="#{addressform.address.inactivate}"
rendered="#{addressform.address.exists}"/>
<h:outputLabel value="Delete"
for="deleteAddress"
rendered="#{addressform.address.exists}"/>
<h:selectBooleanCheckbox id="deleteAddress"
value="#{addressform.address.delete}"
rendered="#{addressform.address.exists}"/>
</p:panelGrid>
</div>
<div class="button-container">
<p:commandButton value="Save Changes"
action="#{addressform.save}"
type="submit"
ajax="true"
process="#form"
update="#form"/>
<p:commandButton value="Cancel"
process="#this"
onclick="dialogAddress.hide();">
<p:resetInput target="fDlgAddress"/>
</p:commandButton>
</div>
</h:form>
Recorddetailsform (backing bean for form from which address dialog is called)
public void showDlgAddress(){
FacesContext ctx = FacesContext.getCurrentInstance();
ELResolver resolver = ctx.getApplication().getELResolver();
RecordDetails recordDetails = (RecordDetails) resolver.getValue(ctx.getELContext(), null, "recordDetails");
//Set addressform backing bean to new instance and load address into it from recordDetails
resolver.setValue(ctx.getELContext(), null, "addressform", new Addressform());
Addressform addressform = (Addressform) resolver.getValue(ctx.getELContext(), null, "addressform");
addressform.setAddress(recordDetails.getAddress());
}
Addressform (address form's backing bean)
public void save() {
FacesContext ctx = FacesContext.getCurrentInstance();
RequestContext rctx = RequestContext.getCurrentInstance();
ELResolver resolver = ctx.getApplication().getELResolver();
Records records = (Records) resolver.getValue(ctx.getELContext(), null, "records");
RecordDetails recordDetails = (RecordDetails) resolver.getValue(ctx.getELContext(), null, "recordDetails");
Mainform mainform = (Mainform) resolver.getValue(ctx.getELContext(), null, "mainform");
Person person = (Person) resolver.getValue(ctx.getELContext(), null, "person");
//Pretty lengthy SQL stuff here. Commented out. Just wanted to display the display logic below for the dialog.
if (errorMsg != null) {//If errorMsg is not null, then error occurred.
showDlgAddress = true;//Ensures address dialog remains open in event of action error.
queueErrorMessage(errorMsg);
rctx.update("dlgAddress");
return;//break out of method on error.
} else {
showDlgAddress = false;
rctx.update("dlgAddress");
}
//If everything saves without error, repopulate address and update recordDetails dialog.
recordDetails.populateAddress(records.getSelectedRecord());
mainform.updateDlgRecordDetails();
}
Other Info:
JSF2
Primefaces 3.5
Tomcat 6.0
Netbeans
Try this:
Put your dialog inside a form (dialogInputForm)
Add the attribute update=":dialogInputForm"
Nest the resetInput tag within the button that opens the dialog and specify the target as the just created form
The commandButton:
<p:commandButton process="#this" actionListener="#{bean.prepare}" update=":dialogInputForm" oncomplete="thirdPartyDialog.show()" value="Open Input Dialog" >
<p:resetInput target=":dialogInputForm" />
</p:commandButton>
And the form which contais the dialog
<h:form id="dialogInputForm" >
... your dialog ...
</h:form>
This worked for me, place this ajax event in the dialog. When the dialog is closed, the validations will be cleaned
<p:dialog id="dlgAddress"
header="Address Edit"
widgetVar="dialogAddress"
dynamic="true"
modal="false"
closable="false"
resizable="false"
styleClass="dlgAddress"
visible="#{addressform.showDlgAddress}">
<ui:include src="addressform.xhtml"/>
<p:ajax event="close" update="dlgAddress" resetValues="true" />
</p:dialog>
I am using magento 1.7. i have tried to change wrapper of cms content but still i cannot get how i can change wrapper of cms_page.
<block type="page/html_wrapper" name="cms.wrapper" translate="label">
<label>CMS Content Wrapper</label>
<action method="setElementClass"><value>std</value></action>
<block type="cms/page" name="cms_page"/>
</block>
and html output is
<div class="std">
CMS Page content
</div>
but i want to output like this
<section class="std">
CMS Page Content
</section>
Please give me any solution
You can try following code for change div to section
<block type="page/html_wrapper" name="cms.wrapper" translate="label">
<label>CMS Content Wrapper</label>
<action method="setElementClass"><value>std</value></action>
<action method="setAttribute"><param1>html_tag_name</param1><param2>section</param2></action>
<block type="cms/page" name="cms_page"/>
</block>
this will change div to section because html_wrapper class get tag name from a function getElementTagName in app\code\core\Mage\Core\Block\Abstract\Wrapper.php
/**
* Wrapper element tag name getter
* #return string
*/
public function getElementTagName()
{
$tagName = $this->_getData('html_tag_name');
return $tagName ? $tagName : 'div';
}
so by calling setAttribute we change/set value of html_tag_name
i am unable to populate my Struts2 select drop down in my jsp page.
Note: My jsp page loads through json response.
I have a select box inside a form. But i don't t know how to populate it when my jsp page loads.
And in the same page i have a select dropdown in my Struts2 jquery grid,which i am able to populage but i don't know how to populate a drop down for my form which are out side of the grid.
Please help me regarding this issue.
my jsp page
<s:url id="selecturl" action="selectaction"/>
<s:url id="bookediturl" action="bookeditt"/>
<s:url id="bookremoteurl" action="booksetups"/>
<sjg:grid
id="bookgrid"
formIds="form2"
reloadTopics="reloadMyGrid"
caption="List of Cover Details"
dataType="json"
href="%{bookremoteurl}"
pager="true"
gridModel="gridModel"
rowList="50,100,5000"
rowNum="20"
filter="true"
filterOptions="{stringResult :false,searchOnEnter : false,enableClear : true,gridModel : true}"
rownumbers="true"
editurl="%{bookediturl}"
navigator="true"
editinline="true"
navigatorSearch="false"
autowidth="false"
width= "1550"
viewrecords="true"
navigatorRefresh="true"
navigatorDelete="true">
<sjg:gridColumn name="id" index="locationId" title="ID" formatter="integer" sortable="false" key="true"
search="false" editable="true" hidden="true" />
<sjg:gridColumn name="authLastname" index="authLastname" title="AuthorLastname" sortable="true" search="true" editrules="{required: true}"
editable="true" edittype="text" />
<sjg:gridColumn name="subjectId" title="Subject Name" editable="true" sortable="false" align="center" search="false" searchtype="select"
searchoptions="{dataUrl:'%{selecturl}'}" edittype="select" editoptions="{dataUrl:'%{selecturl}'}" />
</sjg:grid>
<div id="myDivBox" style="display:none; width :300px;position: relative;top: -30px;left: 299px;button:0px;">
<s:form action="searchkeywordss" id="form2" theme="simple" cssClass="yform">
<sj:textfield placeholder="Enter keyword to search" cssClass="txtbox" size="42" maxLength="255" name="keywordsearch"/>
<sj:select href="%{selecturl}" name="countryselect" list="%{lstsub}" listKey="id" listValue="subjectName" theme="jquery" cssStyle="margin-top:4px;"/>
<sj:a button="true" id="btnid" cssStyle="position: relative;top: 0px;left: 09px;" onClickTopics="reloadMyGrid">Find</sj:a>
</s:form>
</div>
struts.xml
<action name="booksetups" class="v.esoft.actions.bookdetails.BookdetailsAction" >
<result name="success" type="json"/>
<result name="login" type="redirect"> /index.jsp </result>
</action>
<action name="selectaction" class="v.esoft.actions.bookdetails.SelectAction">
<result name="success">/select.jsp</result>
</action>
You should only use the sj:select like below
<sj:select href="%{selecturl}" name="countryselect" list="subjectList" listKey="id" listValue="subjectName" theme="jquery" cssStyle="margin-top:4px;"/>
where selecturl returns a json response, subjectList is name of list in the json reponse which contains the options
Your selectaction should have a json response, but what you have now is an action returning a jsp so it would not work. If you cannot change it, you should create another action which returns json.