primefaces inputText sometimes not updated - jsf-2

I render a search mask from a model. One possible search mask input type is a 1 from n selection. This 1 from n type contains a p:inputText to show the selected value, a p:commandButton which opens a p:overlayPanel to select a value and another p:commandButton to clear the selected value.
In one situation the update of the clear button is not done. The ajax response does not contain the input field to update.
E. g. I have 3 of this 1 from n fields in the search mask. Choose a value for each works, clear each also works. When I assign for all a value and submit the form (executing the search) all is fine. Now I press on the clear button of 1 from n field no. 1 and value is cleared...fine. This also works for the 2nd field, but not for the last. How mentioned the update in the ajax response is missing, but the bean method is executed. Any idea? Or how can I debug it?
Code for the elements for a 1 from n field:
<ui:param name="curFieldSize" value="cc.attrs.curMaskElement.getSize()}" />
<ui:param name="curDummyCssClass" value="searchFieldChoiceDummyCssClass#{cc.attrs.curRowIndex}#{cc.attrs.curColumnIndex}" />
<p:inputText value="#{cc.attrs.curMaskElement.propertyValue}" readonly="true" styleClass="#{curDummyCssClass}" size="#{curFieldSize}"
rendered="#{curIsChoice and (curFieldSize gt 0)}">
<f:converter converterId="choiceConverterSearchMask" />
</p:inputText>
<p:inputText value="#{cc.attrs.curMaskElement.propertyValue}" readonly="true" styleClass="#{curDummyCssClass}"
rendered="#{curIsChoice and (curFieldSize le 0)}">
<f:converter converterId="choiceConverterSearchMask" />
</p:inputText>
<p:commandButton id="colChoiceSelectionButtonId" oncomplete="PF('choiceSelectionSearchVar').loadContents('#{component.clientId}');"
immediate="true" actionListener="#{searchChoiceListController.setSelectedObject(cc.attrs.curMaskElement)}"
process="#this" />
<p:commandButton immediate="true" actionListener="#{searchMaskBL.clearChoiceSelection(cc.attrs.curMaskElement)}"
update="#(.#{curDummyCssClass})" process="#this #(.#{curDummyCssClass})" />
There are 2 p:inputText because the model can define a variable size of a field or a fixed size. So defines the size attribute and one not. I haven't found a value for attribute size which is ignored in the same way by all browsers. Also I try to avoid JSTL. So I had to conditionally render the different inputText.
I am using Mojarra 2.2.10 and PF 5.2.6.
This is the rendered html for the command button to clear the input field:
<button id="searchInstancesFormId:j_idt261:1:j_idt263:1:j_idt265:colChoiceListSelectionButtonClearId" name="searchInstancesFormId:j_idt261:1:j_idt263:1:j_idt265:colChoiceListSelectionButtonClearId" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-icon-only removeChoiceValueButton" onclick="PrimeFaces.ab({s:"searchInstancesFormId:j_idt261:1:j_idt263:1:j_idt265:colChoiceListSelectionButtonClearId",u:"#(.searchFieldChoiceDummyCssClass11)"});return false;" title="Alle Werte entfernen" type="submit" role="button" aria-disabled="false"><span class="ui-button-icon-left ui-icon ui-c removeChoiceValueButtonIcon"></span><span class="ui-button-text ui-c">ui-button</span></button>
This is the html of the input field:
<input id="searchInstancesFormId:j_idt261:1:j_idt263:1:j_idt265:choiceInputSizedId" name="searchInstancesFormId:j_idt261:1:j_idt263:1:j_idt265:choiceInputSizedId" type="text" value="Debitorisch" size="50" title="choice" readonly="readonly" class="ui-inputfield ui-inputtext ui-widget ui-state-default ui-corner-all searchMaskInputElement searchMaskInputChoiceElement searchFieldChoiceDummyCssClass11" role="textbox" aria-disabled="false" aria-readonly="true">
The update is done with the css class #(.searchFieldChoiceDummyCssClass11). But I have really no clue why the last input field is not updated but all other before.
Edit: same behaviour if the update is done with id instead of css class

Related

<c:if><c:otherwise> does not work, both conditions evaluate like true

I am trying to toggle between two different command buttons depending on whether a list contains the given item ID:
<c:if test="#{roomServiceManagerBean.holdinghotelvilla.contains(hotel.hotelvillaId)}">
<p:commandButton ajax="true" id="commanddeactivate" update=":roomserviceForm:hoteltable,:roomserviceForm:msgs" actionListener="#{roomServiceManagerBean.deactivateServiceForHotel(hotel.hotelvillaId)}" icon="ui-icon-radio-off" type="submit" value="Remove Service">
<f:param name="roomserviceid" value="#{roomServiceManagerBean.roomServiceId}" />
</p:commandButton>
</c:if>
<c:otherwise>
<p:commandButton id="commandactivate" update=":roomserviceForm:hoteltable,:roomserviceForm:msgs" actionListener="#{roomServiceManagerBean.activateServiceForHotel(hotel.hotelvillaId)}" icon="ui-icon-radio-on" type="submit" value="Provide Service">
<f:param name="roomserviceid" value="#{roomServiceManagerBean.roomServiceId}" />
</p:commandButton>
</c:otherwise>
However, it fails and the both buttons appear. How is this caused and how can I solve it?
The <c:if> will in this construct fail if #{hotel} is not available during view build time but only during view render time (e.g. because it's definied as <p:dataTable var>). The <c:otherwise> is completely displaced here. It belongs to a <c:choose><c:when>. Technically, you should be using <c:if> instead with a negation in the test. Or, you should be replacing the first <c:if> by a <c:when> and wrap the whole thing in <c:choose>. However that would still fail if #{hotel} is not available during view build time.
Just use JSF component's rendered attribute instead.
<p:commandButton ... rendered="#{roomServiceManagerBean.holdinghotelvilla.contains(hotel.hotelvillaId)}">
...
</p:commandButton>
<p:commandButton ... rendered="#{not roomServiceManagerBean.holdinghotelvilla.contains(hotel.hotelvillaId)}">
...
</p:commandButton>
See also:
EL expression in c:choose, can't get it working
JSTL in JSF2 Facelets... makes sense?

Why does required="true" not fail validation when disabled="true" is specified

<a4j:outputPanel id="tapalSectionSendToPanel" ajaxsingle="true">
<h:inputText id="sendToId1" value="#{MainBean.SectionBean.sendTo}"
class="createresizedTextbox"
required="true" requiredMessage="#{msg.labl_required}"
disabled="true" />
<h:message for="sendToId1" style="color:red" />
</a4j:outputPanel>
i need to validate textbox for empty validation and should show required when i click button without entering any value in textbox. It works fine without disabled="true". Whats the alternative for my requirement.
First, required and disabled don't go well together, because they are mutually exclusive as per the JSF Spec:
required: Flag indicating that the user is required to provide a submitted value for this input component.
disabled: Flag indicating that this element must never receive focus or be included in a subsequent submit.
Like I said in the comments, you can just display a message when the user tries to submit the form without selecting a node:
<h:inputText id="sendToId1" value="#{MainBean.SectionBean.sendTo}"
styleClass="createresizedTextbox" required="true" readonly="true" />
<h:message for="sendToId1" value="#{msg.labl_required}"
rendered="#{facesContext.postback and facesContext.validationFailed}" />
As an alternative you can just display a text anywhere in your markup:
<h:outputText value="#{msg.labl_required}"
rendered="#{empty MainBean.SectionBean.sendTo}" />
disabled="true" disables the input (so it's skipped when the form is submitted), if you don't want the user to type in it use readonly="readonly"

Primefaces inputtext focus at the end of the text

Here a snippet of my JSF:
<p:tabView id="tabView" var="tab" value="#{data.tabs}" widgetVar="tabViewWidget"
activeIndex="#{data.newActiveTabIndex}">
<p:ajax event="tabClose" listener="#{logic.closeTab}" />
<p:tab title="#{tab.content.title != null ? tab.content.title : '&lt;new&gt;'}"
closable="#{tab.isClosable and data.tabs.size() > 2}">
<h:outputText value="#{tab.id} Test" />
<p:focus rendered="#{data.componentIdToFocus != null}" for="#{data.componentIdToFocus}" />
<p:inputText id="test" value="#{tab.content.title}">
<p:ajax event="keyup" listener="#{logic.setFocusingComponent}" update=":form:tabView" />
</p:inputText>
</p:tab>
</p:tabView>
The intent is that there is a textfield within each tab that updates the title of the tab while writing.
The given snippet works except that p:focus places the cursor at the beginning of the text that is already written. I want the cursor to be placed at the end of the text already written. So that a user can type and while he/she is typing the title adapts automatically.
I hope my case is clear.
Does anybody have a solution for that?
Best regards,
Florian
You can use the onfocus="this.value=this.value" trick to "deselect" the value so that the cursor automagically ends up in the end of the value. This should work as good for the <p:inputText> as it basically generates just a <input type="text"> element.
<p:inputText ... onfocus="this.value=this.value" />
See also:
Use JavaScript to place cursor at end of text in text input element
Unrelated to the concrete problem, I wouldn't use ajax and such on keyup event and an update of the whole tabview. This seems to be quite expensive. I'd rather do a simple HTML DOM traversion and manipulation here by JS/jQuery.
E.g.
<p:inputText ... onkeyup="updateTitle(this)" />
with
function updateTitle(inputInTab) {
var panelId = $(inputInTab).closest(".ui-tabs-panel").attr("id");
$("a[href='#" + panelId + "']").text(inputInTab.value);
}

OnBlur event not being fired on clicking of a commandButton?

I have developed a composite component as follows...
<composite:implementation>
<div class="numericBox">
<h:inputText id="txtInput"
size="#{cc.attrs.maxLength}"
converterMessage="#{cc.attrs.converterMessage}"
validatorMessage="#{cc.attrs.validatorMessage}"
required="#{cc.attrs.required}"
requiredMessage="#{cc.attrs.requiredMessage}"
minlength="#{cc.attrs.minLength}"
maxlength="#{cc.attrs.maxLength}"
value="#{cc.attrs.value}">
<f:ajax event="blur" render="#this err"/>
<f:ajax event="blur" render="#{cc.attrs.renderParent}" disabled="#{empty cc.attrs.renderParent}"/>
</h:inputText>
</div>
<h:panelGroup id="err">
<utils:fieldError_right id="errText" group="#{cc.clientId}-txtInput"/>
</h:panelGroup>
</div>
</composite:implementation>
And I have a command button like below..
<h:commandButton id="btnNext" styleClass="btnNext" action="#{someBean.next}"/>
Now I am using the component in the following way...(just showing the bare bone representation)
<util:numericInput label="Label" value="#{somebean.number}"
maxLength="2" optional="true" renderParent="-vehVal"
/>
<h:panelGroup id="vehVal">
<util:amountInput label="label2" value="#{someBean.nubmer2}"
rendered="#{someBean.number > 0}"
required="#{someBean.number > 0}" />
</h:panelGroup>
So basically I want to render the "amountInput" component when ever user has entered some value > 0 in the "numericInput" component.
It works fine when I enter some value in the first field and click some where in the browser. But if I enter some value in the field and click on the next button directly it takes me to the next page, without validation (rendering) the next field.
All I can understand is the onBlur event is not fired when I click on the next button. Why ?? Is there any solution??
It may be that the event is fired, but the form is also being submitted, so the next view will be rendered and you'll miss the result of the ajax event.
You may have to use a more immediate event than blur, such as keyup. Additionally, you could conditionally disable the button if someBean.number is > 0 and someBean.number2 is empty.

Highlighting entire table row if validation fails

I am working on JSF2.0 and Richfaces. I am having an requirement where I need to change the style of the form field(entire row) if the validation fails. I am using the following code to display field label and text box.
<h:panelGrid columns="2">
<h:outputLabel value="#{uit.firstname}:">
<span class="required"><strong>*</strong> </span>
</h:outputLabel>
<h:inputText value="#{editUserProfileBean.firstName}" type="text"
id="firstname" styleClass="basicFormTextBox" size="30"
required="true" requiredMessage="#{uitkem.valueRequired}"
validatorMessage="#{prod.firstNameValidator}">
<f:validateLength maximum="#{prodConf.MaxLengthForFirstName}"
minimum="#{prodConf.MinLengthForFirstName}" />
<f:validator validatorId="trimSpaces" />
</h:inputText>
</h:panelGrid>
Suppose if the validation fails, I need to hightlight the row(both label and textbox).
I can use the following code to hightlight the textbox if the validation fails. But I want to hightlight the entire row, that is not possible using the following code.
<h:inputText value="#{editUserProfileBean.firstName}" required="true" styleClass="#{not component.valid ? 'newStyleClass' : ''}" />
Can anyone help me on this?
Thanks in advance.
You could just write a tiny JS script with jQuery, or use <rich:jQuery> for that.

Resources