Primefaces Dynamic Mega Menu - Cannot remove the same component twice - jsf

I changed my static menu file (header.xhtml) with a mega menu with a model.
Like this:
<p:megaMenu model="#{menuController.megaModel}" autoDisplay="false" styleClass="menu-bar" >
</p:megaMenu>
So far so good, its working great and building just like I expected.
The problem is, on my form pages, when validation fails for the secound time...
I get this error:
javax.faces.FacesException: Cannot remove the same component twice: j_idt15:j_id2 com.sun.faces.context.StateContext$AddRemoveListener.handleAddRemoveWithAutoPrune(StateContext.java:493)
com.sun.faces.context.StateContext$AddRemoveListener.handleRemove(StateContext.java:372)
Looking at the generated HTML I cant find this String "j_idt15:j_id2", but I can find:
<div id="j_idt14:j_idt15" class="ui-menu ui-menubar ui-megamenu ui-widget ui-widget-content ui-corner-all ui-helper-clearfix menu-bar" role="menubar">
and this:
So... I really don´t understand. My MenuController is a sessionBean:
#Component
#Scope("session")
public class MenuController implements Serializable {
#PostConstruct
public void init(){
todosModulos = moduloService.findAll();
modulosAcesso = extrairModulos();
createMegaMenu();
}
...So.. some notes:
I figured out that this error occurs on versions of Mojarra above 2.1.9.
(I am using 2.1.10). So one possible solution is changing the JSF imp to My Faces.
I Tried that, but it buged my structure (my composite components stoped working and dynaForm also).
I tried some workarounds but no sucess. This is what I tried:
Overriding AbstractMenu and Marlon Patrick's solution (PT-BR).
Simply doesn´t work =[
EDIT -> Creating the MenuItem
MenuItem anItem = new MenuItem();
anItem.setOutcome(item.getOutcome());
anItem.setValue(item.getRotulo());
anItem.setIcon(item.getIcone());

From what I saw you already tried my two workarounds: overwrite AbstractMenu and put PhaseListener.
Well, what I realize is that the component that was the problem I had MenuBar and what you are trying to use is the MegaMenu, perhaps the solutions that I do not work for MegaMenu, although I believe that should work yes.
What I would say to you is to check the following:
1 - When you override the class AbstractMenu you are sure the PrimeFaces started to use it? To make sure it puts a break point there and if he sees to the execution flow. If you do not stop, because PrimeFaces is still using its own class.
2 - When attempting to use the solution with PhaseListener, which I prefer and use today, you noted that you need to replace a piece of code with your own code? Basically you'll have to remove only the actions of menu items that are links, because they are causing this problem. The menu items are actions that should remain. In my case, I knew what actions were or links by ID, then you will have to differentiate somehow believe that by also id. Also, put a break point to make sure that your PhaseListener was duly registered and that is intercepting the flow of execution.

Related

p:menubar with both dynamic and non-dynamic submenus

I am currently trying to create a p:menubar which has one dynamically created submenu, but all the other submenus should be normally declared in the xhtml. Sadly I couldn't find any information on how to do so, as it seems that you always have to create a MenuModel and use that as the model for a complete p:menubar.
When just using two separate menubars it is possible to have multiple submenus open at the same time, which leads to them overlapping. And also the spacing is wrong then.
EDIT: I can't use JSTL, so the solution with c:forEach is not possible.
It has to be dynamic because the items are loaded from the database on each request.
EDIT 2: I could use JSTL, but I still don't really grasp how this could best be accomplished. I wan't to have a menubar with some submenus being normal static ones, but one submenu is built dynamically in the code (for every request, nothing with ajax). This dynamic submenu however has multiple child submenus which have their own children in turn, so in theory I would have to somehow iterate recursively over all children.
I am using Primefaces 8.0 and JSF 2.2
Thank you Kukeltje for answering my questions, I now ended up using c:forEach like in the linked post.

faces-redirect=true not working while creating and rendering view

I am currently working on a JSF 2.2 application. As per requirements, I have created custom view handler (using ViewHandlerWrapper) for my application. All the methods are just passing to default view handler except renderView which I am overriding as follows -
private viewHandler viewHandlerWrapped = null;
renderView(FacesContext facesContext, UIViewRoot viewToRender) {
String viewId = viewToRender.getViewId();
if (viewId == some condition) {
/* Do calculation to derive viewId */
}
UIViewRoot viewRoot = viewHandlerWrapped.createView(facesContext,viewId+"?faces-redirect=true");
facesContext.setViewRoot(viewRoot);
//now let system render the view
viewHandlerWrapped.renderView(facesContext,viewRoot);
}
The above is working fine and rendering & navigation is happening as expected. The only issue is faces-redirect=true is not working. The URL seems to be always one behind.
I have gone through many answers given in stackoverflow or internet. But nowhere I am able to find how to solve this.
I think I am doing something wrong e.g. ?faces-redirect=true might not be the correct way while creating view. But I am not sure what can be done to correct this.
Can someone please help me out with this?
After struggling with this for more than 4 weeks, I finally found a way to get the correct URL (instead of previous one). I am updating my answer here in case any one else falls into same problem -
"It looks like we can not use the faces-redirect=true the way I was using while creating and rendering the pages. It should be suffixed with form action. So I have changed my code as follows -
1) actions are returned on click of a button e.g.
public string doAction {
----
return "action?faces-redirect=true";
}
2) Code is updated to use implicit navigation wherever possible. With this, I didn't need to build my custom viewhandler as navigation is happening implicitly. So, I have scrapped the viewhandler.
With above two simple steps, the correct URL is being displayed on the browser now.

disable key entry in pe:timePicker inside a p:datatable

How do I disable keyboard entry in a primefaces extensions timePicker inside a primefaces datatable ? There is no property by default like p:calendar.
Can i do it via js ?
I have to either disable keyboard entry or manipulate the component such that it hides the popup and the user can only type in values. Tried the latter using css but it failed. Please help.
Thanks !
As far as I am aware you can't do it on the component itself...YET.
What has worked for me with JSF regarding a similar issue was the Javascript/Jquery approach. For instance you take an Id or a class of certain component you want to disable the keyboard on and do the following.
$(document).ready(function() {
$("#yourComponentId").keydown(false);
});
or this:
...
$(".yourComponentClassname").on("keydown keypress keyup", false);
...
As far as I am aware if you give the component an attribute like:
... readonly = true ...
your backing bean will ignore it unless you mess around with:
FacesContext#getRenderResponse();
Hope this helps a bit.

Using binding attribute causes javax.faces.FacesException: Cannot find component with identifier

I have a problem I can't quite get a handle on.
First the context: I am developing a web application using Primefaces 3.5 (yes, unfortunately I am stuck with this old version for now), running on JBoss 7.
There is a form with id "form" encompassing all following xhtml code.
I have a component in my view which is provided by usage of the binding attribute:
<p:dashboard id="dashboard" binding="#{myBackingBean.dashboard}" />
Then sometimes I would like to perform an ajax update on this component, this is done by using the RemoteCommand component of primefaces:
<p:remoteCommand
actionListener="#{myBackingBean.someActionListener()}"
process="#this" id="myRmtCmd" oncomplete="myJsFunction();"
update=":form:dashboard" name="myRemoteCommand" />
The RemoteCommand is triggered by a clicking on a Link:
Some Text
This works pretty well so far. However after deploying this code to production I sometimes get a FacesException:
javax.faces.FacesException: Cannot find component with identifier ":form:dashboard"
referenced from "form:myRmtCmd".
This is where my problem lies because I cannot reliably reproduce this exception. My question is this: What could lead to this exception being thrown? It seems to work 95 % of the time but being the perfectionist I am (and many of you reading this are as well, I'm sure ;) ) I would like this code to work 100 % of the time. What am I missing?
Before answering please consider these constraints:
yes, i have to use the binding attribute for providing the dashboard as I need a great deal of control over what gets added to the component
to avoid using IDs I also tried updating the dashboard by its css class via one of primefaces' advanced selectors: #(.ui-dashboard) - this also does not work!
yes, it would be possible to use a commandbutton/link instead of wiring up the remotecommand component to a simple html link but in this case the link is rendered by a JSF renderer component and I made some bad experiences with dynamically adding buttons etc (due to JSF Spec Issue 790)
Cheers,
p.s.
I also had this weird behavior.
There are probably more than one component bindded to #{myBackingBean.dashboard}, so the first one sets the id and there will be no one called "dashboard".

Wicket : Can a Panel or Component react on a form submit without any boilerplate code?

I am currently evaluating Wicket and I am trying to figure out how things work.
I have a question regarding form submit and panels (or other components).
Imagine a custom wicket panel which contains a text field, doing as-you-type validation using ajax. This panel is added to a form.
How can the Panel react a form submit (let's say because javascript/ajax is unavailable)?
I am currently only aware of one solution: calling a panel's method inside the Form onSubmit() method. But this seems not like a "reusable" approach here, because I have to add boilerplate code to every form's onSubmit() which contains the panel (and every developer which use the panel must know this).
So here comes my question: Is there any way that a Panel/Component can "detect" a form submit in some way? Or is there any other solution beside this?
Thank you.
Make your panels implement org.apache.wicket.markup.html.form.IFormModelUpdateListener, and the updateModel() method should be called when the containing form is submitted and passes validation.
There's a good example of code using this by one of the wicket authors at the Wicket In Action blog.
Well, you could simply do the following:
Panel{
Form{
onSubmit(){
Panel.this.onSubmit();
}
}
protected void onSubmit(){}
}
...
This means that any panel that extends your panel need only override the onSubmit and the form no matter what it is in html will call that method. That way you can extend the panel and only override one method for each form.
With regard to form components, the framework handles it for you transparently. Forms are aware of any child form components, even if they haven't been added directly to the parent form.
I would have a Form inside that Panel. This way, you can reuse that Panel without requiring an external Form. As Forms can not be nested inside each other in HTML, Wicket will swap the inner Form(s) into 's transparently, but will make sure that each of the inner Forms takes part of the form processing (validation,..).
You can override the OnSubmit() function of the Form in your Panel. Wicket will call it for you.
what do you mean by "react"? I have only started recently with Wicket, but FWIK, form submit updates the model of a component, and then it calls onSubmit(), which you can override to take special actions beyond that. See Wicket in Action, chapter 6.
After that, the page (and it's components) get re-rendered, using the updated model, so basically, they really "react" on a submit, with quite few lines of code.
For your mentioned case with Component in a Form, have a look at the CompoundPropertyModel.
Implementing IFormSubmitListner and IFormModelUpdateListener shall call the respective methods during a form submit.
However, if you want to do some processing after form submit, I'm afraid you have no choice but to write some boilerplate code yourself.

Resources