How to toggle disable in primefaces components selectOneMenu and calendar? - jsf

How to toggle disable in primefaces components selectOneMenu and calendar ?
Question is when user inputs value in calendar then selectOneMenu should be disabled. But when he removes value from calendar selectOneMenu should be enabled again.
I have tried with this solution but since those components dont have action attribute I couldnt figure it out.
I dont have validation button I wolud like to use some event.

You could use the ajax event to find out if the value has been changed.
<p:calendar ... >
<p:ajax event="change" listener="#{bean.dateChange}" update="selectOneMenuId"/>
</p:calendar>
Then use something like this in your bean:
private boolean disableSelectOneMenu = true;
public void dateChange(DateSelectEvent event) {
Date date = event.getDate();
if (date == null) {
disableSelectOneMenu = true;
} else {
disableSelectOneMenu = false;
}
}
and use the disableSelectOneMenu property in you disable tag of you selectOneMenu.

Both <p:calendar/> and <p:selectOneMenu> has disabled properties. Both component has ajax events, <p:calendar/> has dateSelect and <p:selectOneMenu/> has change.
So, you need to make a bean method which will return true or false according to which selection has been made and bind it to disabled properties and update these components when selection has been made.
For example JSF part:
<p:calendar id="calendar" value="#{bean.calendar}" disabled="#{bean.calendarDisabled}">
<p:ajax event="change" update="selector calendar" process="#this"/>
</p:calendar>
<p:selectOneMenu id="selector" disabled="#{bean.calendarDisabled != true}">
<p:ajax event="change" update="selector calendar" process="#this"/>
</p:selectOneMenu>
And bean part:
public boolean calendarDisabled(){
if(calendar != null){
return false;
}else{
//...do whatever you needs basing on your requirements
}
}
Also please take a look at Primefaces manual

Related

How to update model on change / date select of p:calendar [duplicate]

I'm try to use the primefaces calendar with popup in this way:
<p:calendar pattern="yyyy-MMM-dd" value="#{controller.beginDate}" mask="true" navigator="true">
<f:ajax event="valueChange" listener="#{controller.onChange}" />
</p:calendar>
And here is the relative controller:
#ManagedBean
public class Controller {
private Date beginDate;
public Date getBeginDate() {
return beginDate;
}
public void setBeginDate(Date beginDate) {
this.beginDate = beginDate;
}
public void onChange() {
// do somethings
}
}
The problem: if I change the value from the input field, the event will be execute, but if I change it from the popup, the event will NOT execute.
Can anyone help me?
The valueChange event is only triggered by HTML DOM change event. This is indeed not triggered when the input value is manipulated by JavaScript means.
You need the dateSelect event instead. And, in PrimeFaces components, you'd better use <p:ajax> instead of <f:ajax>.
<p:calendar ...>
<p:ajax event="valueChange" listener="#{controller.onChange()}" />
<p:ajax event="dateSelect" listener="#{controller.onChange()}" />
</p:calendar>
See also:
PrimeFaces Users Guide
Try using the PrimeFaces dateSelect event.
From PrimeFaces documentation:
Calendar provides a dateSelect ajax behavior event to execute an instant ajax selection whenever a date is selected. If you define a method as a listener, it will be invoked by passing an org.primefaces.event.SelectEvent instance.
<p:calendar value="#{calendarBean.date}">
<p:ajax event="dateSelect" listener="#{bean.handleDateSelect}" />
</p:calendar>

Displaying Primefaces confirmDialog from Backing Bean

I have a Primefaces datatable and when the user clicks on a row, I display the data to edit in a form.
If the user changes the data in the form and clicks on any other row i.e if there is dirty data, I need to popup a confirmDialog to show if the user wants to save the data / discard it.
The confirmDialog does not display when I try to execute it from backing bean.
Any help is appreciated!
I have implemented it as follows:
.xhtml:
<p:dataTable id="tsTableId" value="#{transactionSetBean.studentList}" var="tsRow"
selectionMode="single" selection="#{transactionSetBean.selectedEditRec}" rowKey="#{tsRow.id}" scrollRows="10">
<p:ajax event="rowSelect" listener="#{transactionSetBean.onRowSelect}" update=":transactionSetsForm:tsEntryFrmId">
</p:ajax>
..
</p:dataTable>
ConfirmDialog:
<p:confirmDialog widgetVar="dataChangeDlg" message="Save changes Or Cancel">
<p:commandButton value="Save Changes" oncomplete="PF('dataChangeDlg').hide();"
update=":transactionSetsForm:messages :transactionSetsForm:tsEntryFrmId"
action="#{transactionSetBean.updateRecord}" />
<p:commandButton value="Cancel" onclick="PF('dataChangeDlg').hide();"
</p:confirmDialog>
Backing Bean:
public void onRowSelect(SelectEvent event)
{
String actionName = ON_ROW_SELECT;
try
{
Student selectedObj = (Student)event.getObject();
if (selectedObj != null)
{
selectedEditRec = selectedObj;
}
// if data is changed then show the dataChange dialog
if (isDataChanged())
{
setShowDataChangedDialog(true);
RequestContext context = RequestContext.getCurrentInstance();
// execute javascript and show dialog
context.execute("PF('dataChangeDlg').show();");
}
}
catch (Exception e)
{
handleException(e);
}
}
RequestContext.getCurrentInstance().execute("PF('dataChangeDlg').show();");
<p:ajax event="rowSelect" listener="#{transactionSetBean.onRowSelect}" update=":transactionSetsForm:tsEntryFrmId">
works for me.
There must be another error. maybe isDataChanged is false, wrong component ids in update or something.
With PrimeFaces >= 6.2
PrimeFaces.current().executeScript("PF('dataChangeDlg').show()");

Primefaces: selectOneMenu not reset [duplicate]

This question already has an answer here:
How to clear out and reuse p:dialog when adding new items
(1 answer)
Closed 6 years ago.
folks.
I'm stuck on the following problem. I have a modal dialog with two selectOneMenu components in it. When I close the dialog and open it again the values in selectoneMenu's are still selected. This is my menus:
<p:selectOneMenu id="fromCurrency"
value="#{dialog.exchangeRateManageContainer.currencyIdFrom}"
styleClass="ui-input-required"
required="true"
requiredMessage="#{msgs['validation.maintenance.exchangeRate.fromCurrency']}">
<f:selectItem
itemLabel="#{msgs['label.maintenance.selectCurrency']}"/>
<f:selectItems value="#{dialog.currencies}" var="currency"
itemLabel="#{currency.code}"
itemValue="#{currency.currencyId}"/>
</p:selectOneMenu>
<p:outputLabel for="toCurrency" value="#{msgs['label.maintenance.toCurrency']}" />
<p:selectOneMenu id="toCurrency"
value="#{dialog.exchangeRateManageContainer.currencyIdTo}"
styleClass="ui-input-required"
required="true"
requiredMessage="#{msgs['validation.maintenance.exchangeRate.toCurrency']}">
<f:selectItem itemLabel="#{msgs['label.maintenance.selectCurrency']}"/>
<f:selectItems value="#{dialog.currencies}" var="currency"
itemLabel="#{currency.code}"
itemValue="#{currency.currencyId}"/>
This is the cancel button:
<p:commandButton id="cancelButton"
value="#{msgs['label.button.cancel']}"
icon="ui-icon-cancel"
action="#{dialog.cancel()}"
immediate="true"
process="#this"
oncomplete="addExchangeRateDialog.hide();"/>
And this is the cancel method:
public void cancel() {
manageCurrenciesDialog = null;
}
Any help will be appreciated.
The solution for me was to add update atribut on the command buton which opens the dialog with the dialog id. And it works.
In order to reset selections, you need to set the values of your components to null.
Change your cancel method to:
public void cancel() {
manageCurrenciesDialog = null;
exchangeRateManageContainer.currencyIdFrom = null;
exchangeRateManageContainer.currencyIdTo = null;
}
Reset values of all components
I reseted values of all components by calling action to my backing bean method.
Inside of this method I assigned all values of components such as p:selectOneMenu and p:selectBooleanCheckbox to null.
It works perfectly.

Jsf calling bean method from input text when pressing enter

JSF 2.0, Mojarra 2.0.1, PrimeFaces 3.4.1
Here is a p:inputText component which is expected to call a backing bean method when the enter key is pressed.
<p:inputText id="commentInput" rendered="#{status.haveComment}"
value="#{statusBean.newComment}"
onkeypress="if (event.keyCode == 13) { onchange(); return false; }">
<f:ajax event="change" listener="#{statusBean.test}" />
</p:inputText>
While backing bean has the method of:
public void test(AjaxBehaviorEvent event) {
System.out.println("Pressed enter!");
}
It's calling method when enter key is pressed but it has more than this; unexpected behaviour case:
--Click input text
----Type some letters
------Click somewhere else in the page
--------CONSOLE: Pressed enter!
I think ajax event=change detects a change somehow and calls the method. How to convert this p:inputText component into a proper comment taker component like Facebook or others has?
This is the way how onchange event works in HTML. It is happening when text in input element is changed, but is fired when component loses focus (in your case that is the moment when you click somewhere else in the page).
You can define p:remoteCommand for test method and just write:
<p:remoteCommand name="test" actionListener="#{statusBean.test}"/>
<p:inputText id="commentInput" rendered="#{status.haveComment}"
value="#{statusBean.newComment}"
onkeypress="if (event.keyCode == 13) { test(); return false; }"/>
and in backing bean:
public void test() {
System.out.println("Pressed enter!");
}
With newer PrimeFaces versions (5+ at least) you can use p:defaultCommand instead of scripting. Though you can't use p:remoteCommand then, because p:defaultCommand needs something clickable.
<p:inputText id="input" />
<p:defaultCommand target="submit" />
<!--you can show the button to allow the user to click too, or hide it with display: none-->
<p:commandButton id="submit" style="display: none;" process="input" />
By default p:defaultCommand applies to the whole form. You could limit it with the scope attribute.

Unable to disable <p:commandButton> via ajax

I want to disable the button in case there is no value in the input text something like this:
<p:autoComplete id="ac" value="#{bean.selectedNet}"
completeMethod="#{bean.complete}"
minQueryLength="0" size="3">
<p:ajax event="itemSelect" update="genButton" listener="#{bean.handleNetChange}"/>
<p:ajax process="#this" update="genButton" />
</p:autoComplete>
<p:selectManyCheckbox id="en" layout="pageDirection" value="#{bean.selectedEntity}">
<f:selectItems value="#{bean.entityList}"/>
<p:ajax update="genButton" listener="#{bean.handleNetChange}"/>
</p:selectManyCheckbox>
<p:commandButton id="genButton" value="Generate Files"
widgetVar="startButton1"
disabled="#{bean.disableButton}"
actionListener="#{bean.generate}"
onclick="PrimeFaces.monitorDownload(showStatus, hideStatus)"
ajax="false">
<p:fileDownload value="#{bean.streamedContent}"/>
</p:commandButton>
Methods:
public void handleNetChange() {
if (!StringUtils.isBlank(selectedNet) && !selectedEntity.isEmpty()) {
disableButton = false;
} else {
disableButton = true;
}
}
public List<String> complete(String query) {
List<String> results = new ArrayList<String>();
if (StringUtils.isBlank(query)) {
selectedNet = query;
disableButton = true;
} else {
....
}
return results;
}
While the itemSelect event is working perfectly the second one is not. I can see the call to the complete method in the bean but the button is not updated
Any advise?
Seems like you can't force update just with <p:ajax process="#this" update="genButton" />.
I would try to update the button directly from the bean.
Since you are using primefaces you can use RequestContext; try to add this line to your complete method :
RequestContext.getCurrentInstance().addPartialUpdateTarget("genButton");
If you don't use prependId="false" on your wrapping form, you might need to specify the full path to the button e.g.:
RequestContext.getCurrentInstance().addPartialUpdateTarget("fooForm:genButton");
If you want to use disabled, do not use rendered property on command button.
<p:commandButton id="buttonId"
actionListener="#{controller.function}"
value="#{controller.label}"
disabled="#{controller.disableButton}" rendered="#{controller.renderButton}" />
After removing rendered, button gets disabled without any issues.

Resources