I'm experiencing a strange problem in Spring Webflow 2:
I have three states inside my flow:
1) form to fill
2) confirmation page
3) action-state to save the model
The first state works perfectly, no problem
The second state does not reply to any submit button. totally dead, no reaction at all either client side as server side.
Do you have any ideas why?
here my flow definition:
<view-state id="step1" view="profile/step1_profile" model="profile">
<on-render>
<evaluate expression="profileReferenceData.getNationalities(flowRequestContext)"/>
<evaluate expression="profileReferenceData.getRaces(flowRequestContext)"/>
<evaluate expression="profileReferenceData.getReligions(flowRequestContext)"/>
</on-render>
<transition on="submit_step_1" to="step2">
</transition>
</view-state>
<view-state id="step2" view="profile/step2_confirmData" model="profile">
<!-- <secured attributes="ROLE_USER" /> -->
<transition on="submit_step_2" to="step3"/>
<transition on="review" to="step1" />
</view-state>
<!-- step3. Save data -->
<action-state id="step3">
<evaluate expression="profileServiceImpl.createProfileForWebFlow(profile)" />
<transition on="ok" to="done" />
<transition on="error" to="notDone" />
</action-state>
And here the second step .jsp
<tr>
<td><spring:message code="label.nationality"/>:</td>
<td><c:out value="${profile.personalData.nationality}"/></td>
</tr>
<tr>
<td><spring:message code="label.race"/>:</td>
<td><c:out value="${profile.personalData.race}"/>
</tr>
<tr>
<td><spring:message code="label.religion"/>:</td>
<td><c:out value="${profile.personalData.religion}"/>
<tr>
<td><input type="submit" value="Submit" name="_eventId_submit_step_2" /></td>
<td><input type="submit" name="_eventId_review" value="Review"/></td>
<td><input type="submit" name="_eventId_cancel" value="Cancel"/></td>
</tr>
thanks a lot
I would like to see how you declare the form... anyway, check if the action and method attributes has been added to the form tag. For example:
<form id="formId" action="${flowExecutionUrl}" method="post">
...
</form>
or in your case:
<form:form id="formId" action="${flowExecutionUrl}" method="post" modelAttribute="profile">
...
</form:form>
Hope this helps.
Related
i need to make all component editable when i clicked on h:commandLink
This my code
<p:dataTable styleClass="borderless" id="projectsTable" var="o" value="#{order.orderList}">
<p:column>
<div class="tasks">
<div class="task-item task-success">
<h:form>
<div class="task-text">
<div class="form-group">
<h:outputLabel for="projectName" value="Project Name:" />
<p:inplace effectSpeed="fast" editor="true">
<p:inputText styleClass="form-control" value="#{o.productName}" required="true" label="text" />
</p:inplace>
</div>
<div class="form-group">
<h:outputLabel for="projectURL" value="Project URL:" />
<p:inplace effectSpeed="fast" editor="true">
<p:inputText styleClass="form-control" value="#{o.price}" required="true" label="text" />
</p:inplace>
</div>
</div>
<div class="task-footer">
<div class="pull-left">
<h:commandLink >
<span class="glyphicon glyphicon-ok-circle" aria-hidden="true"></span> EDIT
</h:commandLink>
</div>
<div class="pull-right">
<h:commandLink action="#{order.deleteAction(o)}" >
<span class="glyphicon glyphicon-remove-circle" aria-hidden="true"></span> Delete
</h:commandLink>
</div>
</div>
</h:form>
</div>
</div>
that's link i need to click on it and open all h:inputText
<h:commandLink action="#{order.update(o)}">
<span class="glyphicon glyphicon-ok-circle" aria-hidden="true">
</span> EDIT
</h:commandLink>
Such as linkedIn in editProfile page when click on button appear all editable components
Examples:
Befor click button
After clicked button
First of all, every PrimeFaces component has a javascript representation which is acessible through the widgetVar.
The Inplace's widget has a method called show() that you can use to show the input field for it. Check this code out:
<p:inplace ... widgetVar="myinplace">
<p:inputText ... />
</p:inplace>
<!-- this button's click will show the input -->
<button onclick="myinplace.show()">Click Me</button>
I suggest you to set the widgetVar attribute for the inplace components and call the show method on each one of them inside a function that you can use everywhere you want:
<script>
function showInplaces() {
myinplace1.show();
myinplace2.show();
...
}
Cheers
During my lunchbreak I was curious, so I did have a quick look.
I looked at the generated source in the showcase of the first item:
<span id="j_idt88:basic" class="ui-inplace ui-hidden-container" data-widget="widget_j_idt88_basic">
<span id="j_idt88:basic_display" class="ui-inplace-display" style="display:inline">Edit Me</span>
<span id="j_idt88:basic_content" class="ui-inplace-content" style="display:none">
<input id="j_idt88:j_idt91" name="j_idt88:j_idt91" value="Edit Me" class="ui-inputfield ui-inputtext ui-widget ui-state-default ui-corner-all" role="textbox" aria-disabled="false" aria-readonly="false" type="text" />
</span>
</span>
I noticed the class='ui-inplace-display' class which is on each 'component. The following jquery code selects all inplace components that can be clicked:
$('.ui-inplace-display')
I tried this in the FireFox developer console resulting in the following output:
Object { length: 5, prevObject: Object, context: HTMLDocument → inplace.xhtml, selector: ".ui-inplace-display", 5 more… }
I know you can enable the editing by clicking on an item and so I had to find a way to click on each one. Fortunately, you can give each of them a click by just appending .click() to the selector. It will be applied to each of the components:
$('.ui-inplace-display').click()
And like mentioned, you do not need any jsf button for this, just a plain html one to execute the javascript in an onlclick:
<input onclick="$('.ui-inplace-display').click()" value="Click to edit" type="button">
works perfectly.
As you can see, it pays to learn the basics of webdevelopment before diving into using more complex frameworks since no framework ever solves all of your problems and from time to time (more often then you think), you do need a little low-level javascript
I'm using the selectManyMenu widget from Primefaces 5.3 to display the list of roles users can have in each of our apps.
<p:outputLabel value="Roles:" rendered="#{controller.enabledApp[app.id] and not empty app.roles}"/>
<p:selectManyMenu converter="#{roleConverter}" var="r" filter="true" filterMatchMode="contains" showCheckbox="true"
rendered="#{controller.enabledApp[app.id] and not empty app.roles}" value="#{app.selectedRoles}">
<f:selectItems value="#{app.roles}" var="role" itemLabel="#{role.name}" itemValue="#{role}"/>
<p:column>
<h:outputText value="#{r.name}"/>
</p:column>
</p:selectManyMenu>
The problem is, when I preload these roles from the database, populating the selectedRoles field of the app entity, Primefaces adds the ui-state-highlight CSS class to the table rows used to represent these selected roles, but it doesn't add the ui-state-active to the div that represents the checkbox.
This is what I get:
<tr class="ui-selectlistbox-item ui-corner-all ui-state-highlight" style="">
<td>
<div class="ui-chkbox ui-widget">
<div class="ui-chkbox-box ui-widget ui-corner-all ui-state-default">
<span class="ui-chkbox-icon ui-icon ui-icon-check ui-c"/>
</div>
</div>
</td>
<td>Admin</td>
</tr>
And this is what I should get:
<tr class="ui-selectlistbox-item ui-corner-all ui-state-highlight" style="">
<td>
<div class="ui-chkbox ui-widget">
<div class="ui-chkbox-box ui-widget ui-corner-all ui-state-default ui-state-active">
<span class="ui-chkbox-icon ui-icon ui-c ui-icon-check"/>
</div>
</div>
</td>
<td>Admin</td>
</tr>
I could just change the CSS to display a checked checkbox when the parent tr has the ui-state-highlight class, but I'd much rather solve the problem.
Can this be a bug in Primefaces? Do I have some error that I'm not aware of?
I have such an p:selectManyCheckbox and it works ok:
<p:selectManyCheckbox id="groups" value="#{myBean.selectedGroups}">
<f:selectItems value="#{myBean.myGroups}" var="group" itemValue="#{group.id}" itemLabel="#{group.name}"/>
</p:selectManyCheckbox>
Now I have to convert it to the Tree component (adding Group parent to data), but my PrimeFaces version 3.4.1. doesn't support such a functionality. For better customization I decided to make this selectManyCheckbox manually with html and <ui:repeat>):
<div id="j_idt25groups" class="ui-scrollpanel ui-scrollpanel-native ui-widget ui-widget-content ui-corner-all" style="height: 200px;">
<table id="groups" class="ui-selectmanycheckbox ui-widget">
<tbody>
<ui:repeat value="#{myBean.myGroups}" var="group" varStatus="status">
<tr>
<td>
<div class="ui-chkbox ui-widget">
<div class="ui-helper-hidden-accessible">
<ui:fragment rendered="#{myBean.selectedGroups.contains(group.id)}">
<input id="groups:#{status.index}" name="groups" type="checkbox" value="#{group.id}"
checked="checked">
</input>
</ui:fragment>
<ui:fragment rendered="#{not myBean.selectedGroups.contains(group.id)}">
<input id="groups:#{status.index}" name="groups" type="checkbox" value="#{group.id}">
</input>
</ui:fragment>
</div>
<div class="ui-chkbox-box ui-widget ui-corner-all ui-state-default">
<span class="ui-chkbox-icon"></span>
</div>
</div>
</td>
<td>
<label for="groups:#{status.index}">#{group.name}</label>
</td>
</tr>
</ui:repeat>
</tbody>
</table>
</div>
Now i have a problem with this code #{prpBean.selectedGroups.contains(group.id)}:
java.lang.IllegalAccessException: Class javax.el.BeanELResolver can not access a member of class java.util.Arrays$ArrayList with modifiers "public"
Is it possible to solve this problem?
Does it exists an easier way to convert such a structure to the Tree?
The contains() method of java.util.Arrays$ArrayList is not immediately accessible by Java reflection. This could be a (corner case) bug in the EL implementation being used. It may work in a different EL implementation. It may be worth a bug report to the EL implementation vendor, but it is what it is.
When creating selectedGroups, use new ArrayList() instead of Arrays#asList() and all should be well.
I have a delete confirmation dialog:
<p:confirmDialog id="deleteConfirmDialog"
header="#{i18n['confirm-deletion']}"
widgetVar="pnp_delete_confirmDialog" closeable="false"
appendToBody="true">
<f:facet name="message">
<h:outputFormat id="deleteConfirmMessage"
value="#{i18n['confirm-subscription-deletion']}">
<f:param value="#{subscriptions.deleteSelected.title}" />
</h:outputFormat>
</f:facet>
<h:form id="pnpConfirmDeleteForm">
<p:commandButton id="deleteActionConfirmed"
action="#{subscriptions.delete}" value="#{i18n['delete']}"
type="button" process="#this" update=":pnpEditForm :pnpExistingForm"
oncomplete="pnp_delete_confirmDialog.hide()" />
<p:commandLink id="deleteActionConfirmedLink"
action="#{subscriptions.delete}" process="#this"
update=":pnpEditForm :pnpExistingForm"
oncomplete="pnp_delete_confirmDialog.hide()">#{i18n['delete']}</p:commandLink>
<p:commandButton id="deleteActionCancelled" value="#{i18n['cancel']}"
type="button" onclick="pnp_delete_confirmDialog.hide()" />
</h:form>
</p:confirmDialog>
You will notice that the deleteActionConfirmed button and the deleteActionConfirmedLink link have the exact same action, process, update, and oncomplete attributes. However, the link works as expected and the button does nothing. Looking at the generated markup:
<form enctype="application/x-www-form-urlencoded"
action="/primefaces-quickstart/xhtml/pnp-configuration.xhtml" method="post"
name="pnpConfirmDeleteForm" id="pnpConfirmDeleteForm">
<input type="hidden" value="pnpConfirmDeleteForm" name="pnpConfirmDeleteForm">
<button type="button"
class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only"
name="pnpConfirmDeleteForm:deleteActionConfirmed"
id="pnpConfirmDeleteForm:deleteActionConfirmed" role="button"
aria-disabled="false">
<span class="ui-button-text">Delete</span>
</button>
<a
onclick="PrimeFaces.ab({source:'pnpConfirmDeleteForm:deleteActionConfirmedLink',process:'pnpConfirmDeleteForm:deleteActionConfirmedLink',update:'pnpEditForm pnpExistingForm',oncomplete:function(xhr,status,args){pnp_delete_confirmDialog.hide();}});return false;"
class="ui-commandlink" href="#"
id="pnpConfirmDeleteForm:deleteActionConfirmedLink">Delete</a>
<button type="button" onclick="pnp_delete_confirmDialog.hide();"
class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only"
name="pnpConfirmDeleteForm:deleteActionCancelled"
id="pnpConfirmDeleteForm:deleteActionCancelled" role="button"
aria-disabled="false">
<span class="ui-button-text">Cancel</span>
</button>
<input type="hidden" autocomplete="off"
value="7076449462381240234:-2976764560029615800" id="javax.faces.ViewState"
name="javax.faces.ViewState">
</form>
You can see that there is no onclick generated for the button, where there is for the link. Am I missing something or is this a bug in primefaces? If a bug, is there a workaround other than using links with styles to make them look like buttons?
I am using mojarra 2.1.14 with primefaces 3.4.2 on tomcat 6.0.32 (servlet 2.5, el 2.1).
ARGH... Simple mistake. The type attribute of the p:commandButton determines the behavior. It appears that by setting type='button' I have turned it into a (taken from the primefaces user guide):
Push Buttons
Push buttons are used to execute custom javascript
without causing an ajax/non-ajax request. To create a push button set
type as "button".
<p:commandButton type="button" value="Alert"
onclick="alert(‘Prime’)" />
Switching type to submit fixed this issue. Lesson learned... If using buttons, type='button' causes the component to ignore any server side action.
How come I customize the session in Liferay?Sample codes are welcome as it will help more,I am pretty new to Liferay?
To be more specific, i'll explain what i've done. Using Custom JSPs Hooks , i have overridden the $PORTAL_ROOT_HOME/html/portlet/login login.jsp and created my own jsp page and also overridden the LoginAction class.My login.jsp page looks like:
<aui:form action="" method="post">
<table>
<tr>
<td>Username :</td>
<td><input name="login" size=15 type="text" /></td>
</tr>
<tr>
<td>Password :</td>
<td><input name="password" size=15 type="password" /></td>
</tr>
</table>
<aui:button type="submit" value="sign-in"/>
</aui:form>
Now please tell upon clicking on the submit button , how can i get the login values in LoginAction.java and hence set the values to session. This is what i mean by customizing.
You should have copied the origonal login.jsp file from the start. By the looks of your codesnipsets you forgot to set the action to your loginAction. This can be done the following way:
<portlet:actionURL secure="<%= PropsValues.COMPANY_SECURITY_AUTH_REQUIRES_HTTPS || request.isSecure() %>" var="loginURL">
<portlet:param name="saveLastPath" value="0" />
<portlet:param name="struts_action" value="/login/login" />
<portlet:param name="doActionAfterLogin" value="<%= portletName.equals(PortletKeys.FAST_LOGIN) ? Boolean.TRUE.toString() : Boolean.FALSE.toString() %>" />
</portlet:actionURL>
<aui:form action="<%= loginURL %>" method="post">
<table>
<tr>
<td>Username :</td>
<td><aui:input name="login" size=15 type="text" /></td>
</tr>
<tr>
<td>Password :</td>
<td><aui:input name="password" size=15 type="password" /></td>
</tr>
</table>
<aui:button type="submit" value="sign-in"/>
</aui:form>
Please note that it is better to copy the orginal $PORTAL_ROOT_HOME/html/portlet/login/ login.jsp to your hook. Then make the modifications if any needed.
Your Hook will break / remove allot of existing functionality if the provided snipset is all you have.
To receive the parameters from the action you can use Pauls answer.
You can get login values with this code:
String login = ParamUtil.getString(request, "login");
String password = ParamUtil.getString(request, "password");
To set some values to session use this:
HttpSession session = request.getSession();
session.setAttribute("parm", "somevalue");
BR,
Paul