I have a primefaces input text area and a primefaces button. I want the button to be enabled only when there is any value entered in the text area.
<p:inputTextarea id="dumpnotes" rows="10" cols="90" value="#{postProcessedDump.keyedinContent}" style="color: #000000" styleClass="inputarea" />
<p:commandButton value="Save" actionListener="#{dumpController.saveDumpNotesContent}" update="dumpnotes" oncomplete="PF('dumpNotesSaveSuccessDialog').show();"/>
<p:inputTextarea id="dumpnotes" rows="10" cols="90" value="#{postProcessedDump.keyedinContent}" style="color: #000000" styleClass="inputarea">
<p:ajax event="keyup" update="saveButton" />
</p:inputTextarea>
<p:commandButton id="saveButton" value="Save" actionListener="#{dumpController.saveDumpNotesContent}" update="dumpnotes" oncomplete="PF('dumpNotesSaveSuccessDialog').show();" disabled="#{empty postProcessedDump.keyedinContent}" />
Edit (based on your comment):
Try to add global="false" to not trigger ajaxStatus <p:ajax event="keyup" global="false" update="saveButton" />. Depending on your PrimeFaces version, you may need to strip out the event name and only write <p:ajax global="false" update="saveButton" />
The questions seems to be rather JavaScript related so I would try the following approach.
First I would define a JavaScript function which checks whether to enable the commandButton or not:
function validateInput() {
if(document.getElementById('dumpnotes').value == '') {
document.getElementById('button').disabled = true;
} else {
document.getElementById('button').disabled = false;
}
}
So you just have to give commandButton a id (e.g. id="button") and use onkeyup event at inputTextarea like this:
<p:inputTextarea id="dumpnotes" onkeyup="validateInput()" ... />
I hope this is what you were looking for.
Related
Initially a button is disabled, and I want it to get enabled when I select a row in the datatable, but the listener is not working and I can't find the problem...
This is how the xhtml file looks like:
<h:form id="form" class="formulario">
...
<p:dataTable value="#{queryBean.offs}" var="offer" selection="#{queryBean.oferta}" rowKey="#{offer.offerNumber}" tableStyle="width:auto" >
<f:facet name="header">Ofertas disponibles</f:facet>
<p:ajax event="rowSelect" listener="#{queryBean.rowSelected}" />
...
</p:dataTable>
<center><br/>
<h:commandButton id="botonReserva" value="Reservar" disabled="true" >
<p:ajax process="form" update="form" resetValues="true" />
</h:commandButton>
...
</center>
</h:form>
And this is the bean's listener
...
public void rowSelected(SelectEvent selectEvent) {
System.out.println("Working");
//Not printing anything
}
...
I know I'm not updating the button but it is because it doesn't work, so first I want to know how to solve this. After I solve the problem I would know how to enable the button.
What could be the problem?
SOLUTION: It was because I was using a datatable with radio buttons, and I should have used event="rowSelectRadio" instead of event="rowSelect"
I have a p:dialog containing a p:dataTable; when a row gets selected I want to enable a p:commandButton and when clicked a textarea should be updated - but the textarea component appears af it was validated (red outlining) and the value is always null.
The textarea:
<c:set property="resolution" value="#{cc.attrs.resolution}" target="#{cc.attrs.bean}" />
...
<h:outputLabel for="resolution" value="#{text['task.action.resolution']}" />
<p:inputTextarea id="resolution"
rows="10"
value="#{cc.attrs.bean.resolution}"
required="true" requiredMessage="#{text['task.action.required.resolution']}"
/>
The dialog:
<p:dialog id="userNotesDialog"
widgetVar="userNotesDialogVar"
header="#{text['task.action.user_notes']}"
... >
<p:dataTable id="userNotesTable"
value="#{cc.attrs.bean.userNotesOptions}"
rendered="#{!cc.attrs.bean.userNotesOptions.isEmpty()}"
var="userNote"
selection="#{cc.attrs.bean.selectedUserNote}"
selectionMode="single" rowKey="#{userNote.id}">
<p:ajax event="rowSelect"
listener="#{cc.attrs.bean.onUserNoteSelect}"
update=":#{cc.clientId}:actionForm:chooseUserNote"
/>
<p:column>
Some content here
</p:column>
</p:dataTable>
<p:commandButton id="chooseUserNote"
disabled="#{cc.attrs.bean.selectedUserNote == null}"
value="#{text['task.action.user_notes.select']}"
action="#{cc.attrs.bean.setResolutionWithUserNote}"
oncomplete="PF('userNotesDialogVar').hide()"
update=":#{cc.clientId}:actionForm:parentPanel :#{cc.clientId}:actionForm:resolution">
<f:setPropertyActionListener target="#{cc.attrs.bean.resolution}" value="#{cc.attrs.bean.selectedUserNote.noteText}" />
</p:commandButton>
</p:dialog>
Note: the whole code is enclosed by a form (actionForm).
When the dialog is closed, the resolution component is supposed to filled with the selected value, but it appears to be null - am I missing something?
It turned out to be a forgotten c:set that was reposting the initial value to the textarea component. The problem was solved when c:set was removed.
I'm trying to use PrimeFace ajax for enable/disable the submit button and it works fine except it also resets all my p:inputText .
Here is my code:
<p:inputText value="#{loginTo.emailAddress}"
id="emailAdd"
tabindex="1"
required="true"
maxlength="50"
requiredMessage="#{appLoginParameter['AppLoginEmailRequiredMsg']}"
validatorMessage="#appLoginParameter['AppLoginEmailIncorrect']}">
</p:inputText>
<p:selectBooleanCheckbox id="eSignatureCheckBox"
value="#{loginTo.userLoginDetailTO.resetEsignFlag}"
rendered="true"
styleClass="acc-lable-name-check1">
<p:ajax event="change" update="submitButton"></p:ajax>
</p:selectBooleanCheckbox>
You are missing a opening { in:
validatorMessage="#appLoginParameter['AppLoginEmailIncorrect']}"
Should be:
validatorMessage="#{appLoginParameter['AppLoginEmailIncorrect']}"
Try that and see if that helps.
I have a CRUD page which shows data from a query (a List of domain objects) in a Primefaces datatable.
<p:dataTable
id="negozi"
var="n"
value="#{nController.theListFromQuery}"
rowKey="#{n.id}"
selection="#{nController.selected}"
selectionMode="single">
<p:column headerText="Field1">
<h:outputText value="#{n.f1}" />
</p:column>
<p:column headerText="Field2">
<h:outputText value="#{n.f2}" />
</p:column>
<p:column style="width:4%">
<p:commandButton
actionListener="#{nController.prepareEdit(n)}"
update=":editDialogId"
oncomplete="editDialog.show()"
value="Edit" />
</p:column>
...
By clicking on the edit button a dialog will be shown:
<p:dialog
header="Edit N"
widgetVar="editDialog"
id="editDialogId">
<h:form id="formDialog">
<h:panelGrid id="editDialogTable" columns="2" cellpadding="10" style="margin:0 auto;">
<p:outputLabel for="field1" value="F1:" />
<p:inputText id="field1" value="#{nController.selected.f1}" />
<p:outputLabel for="field2" value="F2:" />
<p:inputText id="field2" value="#{nController.selected.f2}" />
<p:commandButton
value="Confirm"
actionListener="#{nController.doEdit}"
update=":form"
oncomplete="editDialog.hide()"
rendered="#{nController.selected.id!=null}" />
...
It works. Now I want to make F1 a required field.
I add the "required" attribute to the inputText field and what happens?
When I try to confirm the form without the required field, the entity is not edited (that's right) but the dialog is closed (that's NOT right!)
When I reopen the dialog I can see the red highlight on the required (and invalid) field.
What I want is to prevent the dialog closing if the form is invalid.
Do I have to write some JS or will JSF help me?
The PrimeFaces ajax response puts an args object in the scope which has a validationFailed property. You could just make use of it.
oncomplete="if (args && !args.validationFailed) PF('editDialog').hide()"
(the args precheck is necessary to not cause a JS error when an exception is thrown during request)
You could refactor it to a reusable JS function as follows.
oncomplete="hideDialogOnSuccess(args, 'editDialog')"
function hideDialogOnSuccess(args, dialogWidgetVar) {
if (args && !args.validationFailed) {
PF(dialogWidgetVar).hide();
}
}
this post is now three years old, but I have found helpful, so my findings may help others.
In PF 5.x at least, it seems that the solution provided by BalusC has to be modified in two ways. (1) add the "args" argument to the call in oncomplete event hander, and (2) use the PF primefaces primitive to identify the widget in PF tables. Here is the code I am using:
oncomplete="hideDialogOnSuccess(args, PF('editDialog'))"
function hideDialogOnSuccess(args, dialogWidgetVar) {
if (args && !args.validationFailed) {
dialogWidgetVar.hide();
}
}
I believe this is the cleanest solution.
Doing this you don't need to change your buttons code.
This solution overrides the hide function prototype.
$(document).ready(function() {
PrimeFaces.widget.Dialog.prototype.originalHide = PrimeFaces.widget.Dialog.prototype.hide; // keep a reference to the original hide()
PrimeFaces.widget.Dialog.prototype.hide = function() {
var ajaxResponseArgs = arguments.callee.caller.arguments[2]; // accesses oncomplete arguments
if (ajaxResponseArgs && ajaxResponseArgs.validationFailed) {
return; // on validation error, prevent closing
}
this.originalHide();
};
});
This way, you can keep your code like:
<p:commandButton value="Save" oncomplete="videoDetalheDialogJS.hide();"
actionListener="#{videoBean.saveVideo(video)}" />
to keep the dialog Open on validation Failed, you just need set the commandButton as follows:
<p:commandButton value="save"
action="#{YourBean.yourActionMethod}"
oncomplete="if (!args.validationFailed) PF('yourDialogWidgetVar').hide()"/>
I gonna leave here a complete example:
<h:form id="ad-form">
<p:dialog id="ad-dialog" widgetVar="adDialog" modal="true" width="400"
closeOnEscape="true" resizable="false" header="Addreass">
<p:messages id="a-msgs" closable="true" />
<h:panelGrid columns="2" id="ad-painel-dialog" width="100%">
<p:outputLabel value="Country" for="country" />
<p:inputText id="country" style="width:100%"
value="#{clientSaverBean.editableAddress.country}" />
<p:outputLabel value="City" for="city" />
<p:inputText id="city"
value="#{clientSaverBean.editableAddress.city}" />
<p:outputLabel value="Zip-Code" for="zipcode" />
<p:inputText id="zipcode"
value="#{clientSaverBean.editableAddress.zipCode}" />
<p:outputLabel value="Street" for="street" />
<p:inputTextarea id="street"
value="#{clientSaverBean.editableAddress.street}" />
<p:outputLabel value="Number" for="number" />
<p:inputText id="number"
value="#{clientSaverBean.editableAddress.number}" />
<h:panelGroup />
<f:facet name="footer">
<p:commandButton value="save"
action="#{clientSaverBean.saveAddress}"
process=":ad-form:ad-dialog"
update=":ad-form:a-msgs :ad-form:ad-painel-dialog :client-form:ad-table"
oncomplete="if (!args.validationFailed) PF('adDialog').hide()"/>
</f:facet>
</h:panelGrid>
</p:dialog>
</h:form>
I have an h:selectOneMenu set up that looks something like this:
<f:view>
<h:form id="tehForm">
<h2>Header</h2><br/>
<a4j:outputPanel id="msgPanel" ajaxRendered="true">
<h:messages styleClass="message"/>
</a4j:outputPanel>
<a4j:outputPanel id="mainPanel" ajaxRendered="true"><br/>
Select an item:<br/>
<h:selectOneMenu id="itemMenu" value="#{bean.itemId}">
<f:selectItem itemValue="-1" itemLabel="Please Select..."/>
<s:selectItems value="#{bean.item}" itemValue="#{item.id}" var="item" label="#{item.name}"/>
<a4j:support event="onchange" action="#{bean.selectItem}"/>
</h:selectOneMenu>
<rich:spacer width="10px"/>
<a4j:commandLink value="Create New" action="#{bean.createNew}"
rendered="#{bean.selectedItemId != 0}"/>
<h:outputText rendered="#{bean.selectedItemId gt -1}" value="Item Name: "/><br/>
<h:inputText rendered="#{bean.selectedItemId gt -1}" value="#{bean.selectedItem.name}" maxlength="50" size="75"/><br/><br/>
<a4j:commandButton value="Save New" action="#{bean.save}" rendered="#{bean.selectedItemId == 0}"/>
<a4j:commandButton value="Save Changes" action="#{bean.save}" rendered="#{bean.selectedItemId gt 0}" oncomplete="jsRerender();" />
<a4j:jsFunction name="jsRerender" rerender="mainPanel"/>
</a4j:outputPanel>
</h:form>
</f:view>
When creating new items, the new item does show up in the drop-down, but if I change the "name" attribute of my item and save, the label doesn't change to the new name until after the next request, despite the data in the bean having changed.
So I worked around it by forcing a second call to rerender again when saving changes is complete. The trouble is, this rerenders the messages panel as well, so I nuke any messages that may have been displayed. Using limitToList="true" in the a4j:jsFunction has the same effect as not calling it.
I need suggestions; either a new target for the rerender function, or another way of approaching the problem. Thanks in advance!
Try removing the oncomplete javascript and using reRender="mainPanel":
<a4j:commandButton value="Save Changes"
action="#{bean.save}"
rendered="#{bean.selectedItemId gt 0}"
reRender="mainPanel" />
In your version I think that "Save Changes" button without reRender attribute will rerenders all the page, thus refreshing the messages.