rich:suggestionbox how to call bean in case user aborts selection - jsf

Old SuggestionBox component for RichFaces (version 3.3... yes, I have to maintain legacy code, weep for my fate) is pretty useful, but has one downside.
If user enter some text in input component and then click somewhere else than entry on list of suggestion, partially filled input is left as is. It is ugly and can be confusing, giving impression that something is selected when it is not.
I want to have separate call to bean in this case, allowing me to remove text, if nothing got selected.
Example code:
<h:inputText id="selectorInput" value="#{backingBean.inputText}" label="Select something:" />
<rich:suggestionbox id="suggestion" for="selectorInput" suggestionAction="#{backingBean.resolveSuggestions}" var="sug">
<a4j:support event="onselect" reRender="someForm" action="#{backingBean.select(sug)}" />
<h:column>#{sug.name}</h:column>
</rich:suggestionbox>
I tried to add a4j:support for h:inputText with event="onblur", but it is called before backingBean.select(sug) and has no way to know if something was selected or not, making it almost useless. Adding other events to suggestionbox itself appear to not work at all or even break suggestionbox.
Is there any other way?

The backing JavaScript object has a getSelectedItems() method. It returns an empty array if nothing was selected.
To get the object use
document.getElementById(clientId).component

Related

How can I use both REQUIRED and DISABLED attributes on a PrimeFaces component?

Java developer here.
The question may be confusing, so I'll give it some context: I have an inputText field that needs to be disabled if the backing bean's boolean is set to true and vice-versa.
But if the field is not disabled, it NEEDS to be filled. Like so:
<p:inputText tabIndex="3" id="someInput" maxlength="50"
disabled="#{!backingBean.idIsUnknown}"
required="#{backingBean.idIsUnknown}"
value="some text">
</p:inputText>
One works without the other, but not both at the same time. I keep getting that particular error when running the application:
Cannot set content type. Response already committed
Is there any workaround?
If i got it right, then you want to have the Field disabled if the Value of idIsUnknown is true.
So you dont need the ! in front of the Method-Call, since disabled="" sets the field to disabled if the value is true.
Also i would suggest that you dont use ! at all. Try to set the correct boolean Value in your Backing Bean already and just request the value instead of switching it in the XHTML. If necessary, make a second boolean attribute just for the disabled=""
UPDATE
Found an answer from "Makhiel" whitch might help you with your problem:
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"
Remove required attribute. Move the validation to backend.
Add some style/css to the field to make it look like required.

Update JSF in carusell

I currently try to implement a website, where an dialog, opened from an carousel, changes something in the database and the result is shown on the screen. For that, I try to update an area in the dialog. Unfortunately, updating things in an carusell does not seem to work.
I shortened the code to an minimal example, so with the following code:
<p:carousel id="page" value="#{pagebean.pages}"
var="item" numVisible="1">
<h:form id="dlg_2_form">
<h:outputText id="test_2" value="#{pagebean.value}" />
<p:remoteCommand name="update_2" update="test_2" />
Increment
</h:form>
</p:carousel>
the function pagebean.value is not called after I click on Increment, but therefore the constructor of pagebean is called when I click on Increment. So it seems like the carousel makes it impossible to update something in it.
Does anyone know, if there is an possibility to update something which is in a carousel, or if there is a workaround for this problem?
EDIT: After the discussion below, I know that Increment does work, if the scope of the corresponding bean is set to #ViewScoped. I could also trigger this button by giving it a widgetVar and accessing its click function, so this would work. Unfortunately, the Bean I want to use is SessionScoped, and with this kind of view it does not work. Has anybody an hint how to solve this problem? I could copy everything into a second Bean, which is ViewScoped, but this is not a very nice solution.

Rendering a data-table only when the bean returns a list

I have been trying to render a rich:dataTable, but fails, when it comes to its conditional rendering.I wanted to render it only if the size of the list, the backing-bean fetches from DB, is greater than zero.
JSF-2.0, RichFaces-4 are what i use.
You have to use the "render" attribute of the datatable. With it you can define if the component is rendered to the client or not. So check by EL if the list is populated.
you can do something like:
rendered="#{not empty listObject}"
and all is fine.
I always implement my database query method to never return null, if the query has no result I return an empty list. This way i'm sure I never get a nullpointerexception and I prefer then to show an empty table. Because it's easer to layout the page, when you are sure the table always exist.
Hope that helps.
The scenario is I have a groupId which I rightclick on. On the context menu, I choose Display CTNs and it should then render all the CTNs of this group in a data-table. It starts with a JavaScript call, which I call once I choose "Display CTNs". It takes care of supplying the GroupId to the a4j:jsFunction.
<rich:dataTable value="#{ctnGrpMgmtController.ctnDetailsList}"
var="ctnVar" id="ctnTable" rows="5"
rendered="#{not empty ctnDetailsList}">
The above should be rendered after the below a4j:jsFunction executes.
<a4j:jsFunction name="selectGroupForManagingCtns"
action="#{ctnGrpMgmtController.loadCTNsForAGroup}"
render="ctnListPanel,ctnTable">
<a4j:param name="name"
assignTo="#{ctnGrpMgmtController.groupId}" />
</a4j:jsFunction>
I have to do an F5 to see the component "ctnTable", which is where the problem starts.
It looks like the attribute name on the a4j:jsFunction is reRender instead of just render. Should fix it.

jsf inputtext doesn't show value from bean

I have the follow situation:
I have a bean that send to form some data, but only in outputlabel the data from the bean is displayed.
I tried to use primefaces, but the same problems persist.
my code:
<h:outputLabel value="#{Bean.name}" id="name2" />
<h:inputText value="#{Bean.name}" id="name" />
<p:inputText value="#{Bean.name}" id="name3" />
Any idea why?
You should have given the bean's code also, to help us better analyze the problem.
Normally you should check for the following:
Check whether you are specifying a correct bean name. Normally
bean's name is same as that of class, except that first letter
should be lowercase. In your case it should be #{bean.name} or else,
specify your custom name with #Named("Bean").
Check whether the getters and setters such as getName() are properly
provided. It may happen that you might have reset the name property in
your bean in the get method itself. Because of which first time it
shows you properly in outputLabel and then in next call to getName it may give you null or empty String. To check this, try put your inputText tag first, and check.
I solve my problem.
When I tried show the values, I was trying recover data from database by pass an ajax action. So, When I clicked at button to retrieve the datas, some of my inputText were set as a required. And because this the data is just displaying into label and not inside of inputtext with required. But because ajax, the request were not called correctly.
When I remove the required from inputtext, it works fine.

Seam conditional render without parsing

I'm trying to make a conditional render in my Seam application (2.2.0), to display two different controls depending on a condition.
I'm using the s:fragment tag with the render attribute, but my problem is that I want whatever the control is displayed, to have the same id:
<s:fragment render="${editable}">
<rich:calendar id="entityDate"..../>
</s:fragment>
<s:fragment render="${!editable}">
<h:outputText id="entityDate".../>
</s:fragment>
My problem is that even when the render attribute set to false, the "not to be rendered" element is parsed, and I get an exception because of the duplicated id.
I also tried with the tag <ui:remove>, which effectively removes the element before the parsing phase, so I can have something like:
<span id="myId"/>
<ui:remove>
<span id="myId"/>
</ui:remove>
Unfortunately the <ui:remove> tag doesn't allow conditional logic. Has anyone found a way to solve this?
That's only possible when you use a view build time tag such as JSTL <c:if>.
<c:if test="#{editable}">
<rich:calendar id="entityDate" />
</c:if>
<c:if test="#{!editable}">
<h:outputText id="entityDate" />
</c:if>
(note that this is not going to work within an iterablte JSF component, such as <ui:repeat>, <h:dataTable> and so on)
After all, I strongly recommend to take benefit of the disabled attribute instead, if necessary with a good shot of CSS to hide the input field borders and so on. It'll minimize the JSF view boilerplate code.
<rich:calendar id="entityDate" disabled="#{!editable}" />
Disabled inputs are separately styleable by the CSS attribute selector element[attribute], e.g.
input[disabled] {
border: 0;
}
The above removes the border of input elements with the disabled attribute present so that it look like a normal output text.
"Solve"? There is nothing to solve here: two elements in a GUI can not have the same ID. Hardly unnatural or unsound?
It's like asking: "I have a database table with two rows, I would like them both to have the same primary key value, but somehow I get these errors... has anyone managed to solve the problem and circumvent the constraints?".
Or even closer analogy: "I have two spans, one of them is invisible (has style="display: none") I would like them both to have the same id - and browsers seem not to like it, despite one of the spans being invisible".
Bottom line: rendered on not rendered, each component is still a part of the view tree, and therefore has a UNIQUE id.
I have a suspicion that you want to have some "polymorphic" code that should work with the currently visible element. Using ID for such code IS WRONG. If you show us your use case, we might find a right way to achieve the effect.
I use selenuim myself in a seam environement and i recommend using defined ids whenever possible. First you have the ability to create smaller ids which is usefull for pagesize. Second the selenium test run alot faster if you use ids for referencing instead of other selectors. I have not yet found a selenium test where you cannot handle diffrent ids. Additionally if a code fails in jsf tree creation you see which id is failing.
I see you are using sfragment with editable or not. I use the sdecorate and give the decorate an id and then "just" ed for the input and vi for the outputtext for example. This makes it easy in selenium to check the availability of edit or view components.
Would you be able to get the same results you need by putting the id tag on the fragment?
So:
<s:fragment id="entityDate">
<rich:calendar render="${editable}" />
<h:outputText render="${!editable}" />
</s:fragment>

Resources