generate outputLink action from data base - jsf-2

I have many menus of outputLink and I generated them from data base mysql
like:
<ui:repeat value="#{loginAction.subMenusBeans.subMenusBeansList}"
var="subMenusBeansList">
<ui:fragment rendered="#{menusBeansList.menuId == subMenusBeansList.menuId}" >
<h:commandLink id="circlLink" value="#{subMenusBeansList.subMenuName}"
action="{subMenusBeansList.subMenuLink}" />
</ui:fragment>
</ui:repeat>
I get value of action from database and set it to 'subMenusBeansList.subMenuLink'
output:
head quarter
main offices
offices
and so on..
when I click on any of above link
exception:
action="#{subMenusBeansList.subMenuLink}": Method not found:
I want to set action method name from database because I have many hyperlink and want to set all links action from data base and generate them to xhtml using ui:repeat but when i click on any of hyperlink's action generated from #{subMenusBeansList.subMenuLink}' throw exception
javax.servlet.ServletException: javax.el.MethodNotFoundException: /template/
templateslider.xhtml #36,135 action="#{subMenusBeansList.subMenuLink}":
Method not found: com.ss.managedbeans.SubMenusBeans#552edddd.subMenuLink()

The problem you are running in to here is that <h:outputLink action="XXXX"> actually expects a MethodExpression, which is why it is not attempting to resolve the getter for your property, "subMenuLink."
What you probably want is, as BalusC suggested, to use an ` instead. This attribute expects a ValueExpression, and should be able to resolve your property and its getter.

Related

JSF 2 + Primefaces: Need to update bean property on menu click before rendering dialog

I have a p:menuitem that needs to (1) update a backing bean property when clicked, and then (2) show a p:dialog.
This is the set up I have:
<p:menuitem value="Show Dialog"
oncomplete="dialog_widget.show();"
update=":dialog"
actionListener="#{bean.setCurrentAction}">
</p:menuitem>
<p:dialog widgetVar="dialog_widget" id="dialog" dynamic="true">
<h:form>
<p:inputText value="#{bean.record.text} />
// the proper rendering of this dialog form depends on bean.currentAction
// being set during JSF Phase 4 Update Model Values
</p:dialog>
And the backing bean:
public R getRecord() {
if (currentAction == null) {
return null;
}
return currentAction == NEW ? newRecord : selectedRecord;
}
The problem is that actionListeners and actions are only executed during Phase 5 and I need the bean.currentAction to be set before that so the dialog can be properly updated and rendered.
** A little background on what I'm trying to achieve: the dialog form is used to Create new records as well as Update exsiting records (Add and Edit Dialog). So the "currentAction" on the bean indicates which action the user is doing. Depending on which action, the form needs to use different model objects ("newRecord" or "selectedRecord") to pull and save the form data to.
Although not a very elegant solution you can use PrimeFaces' RequestContext's update method to set update target and use the execute method to show your dialog in your actionListener after setting the needed property.
If you requirement is to call the backing bean method before the dialog opens then you can go for a ajax function (i don't know whether you are allowed to use ajax in your application). for p:menuItem there is a function called onclick, where you can call a a4j:ajax function through which you can call a backing bean method and update the model before dialog opens.
By default action is called during "Invoke Application" phase. You can add immediate="true" attribute in p:menuitem tag. This will call action in "Apply Request Values" phase.

Composite Component and setPropertyActionListener

I have a composite component that have a dialog...
Inside the dialog I have the following piece of code:
<p:commandButton id="selectButton" icon="ui-icon-check" oncomplete="lookupDialog.hide();" update=":#{cc.clientId}:#{cc.attrs.fieldId}_panelGrid">
<f:setPropertyActionListener target="#{cc.attrs.targetValue}" value="#{entity}" />
</p:commandButton>
So, when the button is clicked, the dialog vanishes, but the property isn´t set.
There is no errors, no warnings, nothing! So I simply don´t know what is happening...
If you need anymore details, please just say so! :)
***EDIT
This is a related question, but not really what I want to do...
Pass Argument to a composite-component action attribute
I just need the propertyActionListener to work.
Here some extra information:
<cc:attribute name="targetValue" required="true"/>
the value:
targetValue="#{acaoController.entity.responsavel}"
Where inside the bean (acaoController)
I have an entity...
And inside the entity I have another object, that is "responsavel".
Try checking setters and getters of responsavel getting called when you close the dialog box.
Otherwise you can use Flash to pass on the value between components. In the action method of command button,
Flash flash = FaceUtil.getFacesContext().getExternalContext().getFlash();
flash.put("entity",entity);
And you can extract the value like this:
Flash flash = FaceUtil.getFacesContext().getExternalContext().getFlash();
responsavel = (Responsavel) flash.get("entity");

How to make p:selectOneMenu show current value?

I have a <p:selectOneMenu> to choose the category for an item from. By default the menu displays the first entry of someBean.selectedParty.categories as selected. But the item already has a current category at someBean.selectedItem.category that I want to be displayed/selected. How can I achieve that?
<p:selectOneMenu value="#{someBean.selectedItem.category}" converter="omnifaces.SelectItemsConverter">
<f:selectItems value="#{someBean.selectedParty.categories}" var="category" itemLabel="#{category.name}"/>
</p:selectOneMenu>
As long as the getter for someBean.selectedItem.category returns a value available in the list , it will show the value as selected.
However there are some gotchas:
1) The default value probably should be set in the bean constructor
2) The bean (someBean) cannot have the RequestScope - As every single HTTP request, including Ajax requests, would create a completely brand new instance of the bean with all properties set to default. If your bean is RequestScope, change to ViewScope
3) As you are "cascading" from someBean to selectedItem to category, note that the selectedItem and selectedParty must be the same through (not only same content but also same memory adress) or the lifecycle of JSF will stop. I guess you are setting the selected objects earlier. If you are using AJAX, try to post a "full" request to a new page with the drop-down to debug this.
4) To simplify this, you could try to move the category and categories directly into someBean so the page should look like
<p:selectOneMenu value="#{someBean.category}" converter="omnifaces.SelectItemsConverter">
<f:selectItems value="#{someBean.categories}" var="category" itemLabel="#category.name}"/>
</p:selectOneMenu>

Primefaces ManyCheckbox inside ui:repeat calls setter method only for last loop

I have a <p:selectManyCheckbox> inside <ui:repeat>, getting it's items from a List of a certain Object Class (provided by <ui:repeat>-variable) and is supposed to save the chosen items into another List of the same Object Class. But it calls the setter method #{cartBean.setSelectedExtras} only for the last entry (last iteration of <ui:repeat>).
<ui:repeat var="item" value="#{category.items}">
<p:selectManyCheckbox id="extraCheckbox" value="#{cartBean.selectedExtras}" layout="pageDirection" converter="omnifaces.SelectItemsConverter">
<f:selectItems value="#{item.items5}" var="extra" itemLabel="#{extra.name}"/>
</p:selectManyCheckbox>
</ui:repeat>
Update:
I changed the above construct just the way BalusC proposed.
Declaration in backing bean is now:
private List<List<Item>> selectedExtras = new ArrayList<List<Item>>();
When I check checkboxes that were created by the first loops of <ui:repeat> and click the <p:commandButton> inside the same <h:form> the setter method of selectedExtras is not called. When I check the checkboxes created in the last loop of <ui:repeat> and click the <p:commandButton> I get an Exception:
javax.el.PropertyNotFoundException: /lightbox-item.xhtml #57,165 value="#{cartBean.selectedExtras[iteration.index]}": null
This construct works fine for me.
As mentioned in among others the showcase page, the omnifaces.SelectItemsConverter uses by default the toString() representation of the complex object as converted item value. So if you didn't override the toString() method (so that it still defaults to com.example.SomeClass#hashcode which changes on every instantiation) and the #{item} managed bean is request scoped, then the list would basically be changing on every HTTP request. This would cause a "Validation Error: Value is not valid" error.
If you add
<p:messages autoUpdate="true" />
or
<p:growl autoUpdate="true" />
so that you get all (missing) validation/conversion messages in the UI, then you should have noticed it.
In order to utilize the omnifaces.SelectItemsConverter at its best, you should override the toString() method accordingly so that it returns a fixed and unique representation of the complex object. E.g.
#Override
public String toString() {
return "Extra[id=" + id + "]";
}
Alternatively, you could put the #{item} managed bean in a broader scope, such as the view scope.
Update as to your update, you're binding the selected values of all checkboxgroups to one and same bean property #{cartBean.selectedExtras}. This way every iteration overrides the property with the values from the current iteration round as long as until you end up with the values of the last iteration. If you've placed a debug breakpoint on the setter, you'd have noticed that.
This is not right. They should each point to a different bean property. Technically, you should have a #{item.selectedExtras} as property. But I think that this makes no sense in your current design. Better would be to make the #{cartBean.selectedExtras} an List<Item[]> or Item[][]. This way you can get them to set based on the iteration index as follows:
<ui:repeat var="item" value="#{category.items}" varStatus="iteration">
<p:selectManyCheckbox id="extraCheckbox" value="#{cartBean.selectedExtras[iteration.index]}" layout="pageDirection" converter="omnifaces.SelectItemsConverter">
<f:selectItems value="#{item.items5}" var="extra" itemLabel="#{extra.name}"/>
</p:selectManyCheckbox>
</ui:repeat>
In case of List<Item[]> you only need to make sure that you preinitialize selectedExtras with nulls as many times as there are #{category.items} in bean's (post)constructor.
for (Item item : category.getItems()) {
selectedExtras.add(null);
}
In case of Item[][], you can suffice with
selectedExtras = new Item[category.getItems().size()];

how action result in div or panel with h:commandButton

i tried to show action result in panel with this :
<p:panel id="pnl" style="margin-bottom:10px;">
<p:commandButton id="addUser" value="Ajouter" action="#{userMB.addUser}" ajax="false" target=":pnl">
but i cant get result in same page, after click i've result in new page.
as you can see i used target for this, there is a way to do it ?
Thanks in advance
Change "target" to the word "update" and remove ajax="false"
Ensure that your action method addUser either doesn't return anything (the method signature's return declaration is "void") or returns null
You may need to make your backing bean view scoped (if you do change to ViewScoped, ensure that your backing bean is Serializable)

Resources