voyent
setActionExpression and HtmlCommandButton  XML
Forum Index -> Components Go to Page: 1, 2 Next 
Author Message
posnea

Joined: 11/Jan/2008 00:00:00
Messages: 23
Offline


Hello,
the setActionExpression on HtmlCommandButton doesn`t work.
The expressed method does not react.

My code looks like this:
Code:
 ...
 FacesContext fc = FacesContext.getCurrentInstance();
 ELContext ec = fc.getELContext();
 Application app = fc.getApplication();
 ExpressionFactory factory = app.getExpressionFactory();
 
 HtmlCommandButton newButt = new HtmlCommandButton();
 MethodExpression me = factory.createMethodExpression(ec,"someBean.actionMethod", Void.TYPE,
 new Class<?>[0]);
 newButt.setActionExpression(me);
 
 


However, if i change HtmlCommandButton to HtmlCommandLink it works perfectly allright.
Is this an issue or perhaps there is something wrong with my code?

Thx
Posnea

dhagemei

Joined: 10/Mar/2008 00:00:00
Messages: 2
Offline


Hi Posnea!
Did you solve the problem ?
...my code shows the same behaviour!
philipp.bollbach@itemis.d

Joined: 06/Aug/2007 00:00:00
Messages: 8
Offline


I got the same or remarkably similar problem. I want to create the ui programmatically. I create a button and a MethodExpression and a MethodExpressionActionListener. In Addition to that I add an plain ActionListener. After that, the button is added to the enclosing form.
The construction happens in the getForm()-Method which get's called at the begining of the first request. The page looks as usual but the button does not react.
Code:
 HtmlCommandButton button= (HtmlCommandButton)app.createComponent(HtmlCommandButton.COMPONENT_TYPE);
 MethodExpression actionExpression = getMethodExpression("#{controller.doSth}");
      MethodExpressionActionListener meActionListener = new MethodExpressionActionListener(actionExpression);
       button.addActionListener(meActionListener);
       button.addActionListener(new ActionListener(){
          public void processAction(ActionEvent event) throws AbortProcessingException {
             System.out.println("event = " + event);
             }
             }); 
 form.getChildren().add(button);
 

The request that gets send to the server does not specify any events as usual when the button is constructed with its tag on a page
Code:
 | ice.event.captured= |
  | ice.event.type=onclick | 
 

Adding an ActionListener to a button that get's referenced on the page by its tag is no problem and the event gets captured. It is only a problem if I construct it programmatically.
dhagemei

Joined: 10/Mar/2008 00:00:00
Messages: 2
Offline


Hi Phillipp...
Hope this will help you...


Code:
 Class [] classList=new Class[1];
             classList[0]=ActionEvent.class;
             ExpressionFactory factory =   context.getApplication().getExpressionFactory();
 
             MethodExpressionActionListener actionListener = new MethodExpressionActionListener(factory.createMethodExpression(context.getELContext(),"#{actionBean.processAction}", null ,classList));
             button.addActionListener(actionListener);
 


The MethodExpression needs four parameters...
the ELContext,
the EL-Expression,
the return-type of the initialized function(here it is null, because the called method is void)
and a list of parameters the called method needs (In your case it is an ActionEvent, too)

Bye,
Daniel
philipp.bollbach@itemis.d

Joined: 06/Aug/2007 00:00:00
Messages: 8
Offline


Sorry but it is not. The method getMethodExpression(String name) in the code-snippet above does exactly that
Code:
    private MethodExpression getMethodExpression(String name)
    {
       Class[] argtypes = new Class[1];
       argtypes[0] = ActionEvent.class;
       FacesContext facesCtx = FacesContext.getCurrentInstance();
       ELContext elContext = facesCtx.getELContext();
       return facesCtx.getApplication().getExpressionFactory().createMethodExpression(elContext, name, null, argtypes);
    }
 


But the method from that binding is never called no matter what the EL-Expression is. It can even be a false one. JSF is not calling the ActionListener-Method but why?
philipp.bollbach@itemis.d

Joined: 06/Aug/2007 00:00:00
Messages: 8
Offline


First of all: the problem is NOT resolved. After further investigation I found out the following bits:
Code:
 	<ice:commandButton value="TestButton" binding="#{MainWindowController.button}"></ice:commandButton>
 

Binding a button from a facelets-page to a backing bean and adding the Actionlistener in the get-Method does work indeed.
Code:
      public HtmlCommandButton getButton()
    {
       button = (HtmlCommandButton)FacesContext.getCurrentInstance()
                                               .getApplication()
                                               .createComponent(HtmlCommandButton.COMPONENT_TYPE);
 
       //Does use the convenience method to create the expression
       MethodExpression actionExpression = getMethodExpression("#{MainWindowController.addTab}");
       MethodExpressionActionListener meActionListener = new MethodExpressionActionListener(actionExpression);
       button.addActionListener(meActionListener);
       button.addActionListener(new ActionListener()
       {
          public void processAction(ActionEvent event) throws AbortProcessingException
          {
             System.out.println("event = " + event);
          }
       });
       return this.button;
    }
 

But it doesn't work if the button is solely created by code and added as a child to its parent component e.g. a form (see posting above). The question is: what's the difference between the binding and the creation by the createComponent()-method?
As pointed out in the previous post, there is a javascript event fired when clicking on the programmatically created button but with the wrong properties.
Code:
 | ice.event.target= | 
 | ice.event.captured= |
 | ice.event.type=onclick | 
 

The button defined on the facelets page and bound to the backing bean does fire correct events as you can see in the browser:
Code:
 | ice.event.target=j_id9:j_id10 |
 | ice.event.captured=j_id9:j_id10 | 
 | ice.event.type=onclick | 
 


Is this a bug or am I missing a critical piece here?


philipp.bollbach@itemis.d

Joined: 06/Aug/2007 00:00:00
Messages: 8
Offline


SOLVED
If you programmatically instantiate a button and you want to add an actionlistener to it, you have to set an id via the setId()-method. Otherwise the strange behaviour described above occurs.
The code example described here is now working.
If somebody has an explanation for this, please share your wisdom with us.
hildo


Joined: 14/Nov/2007 00:00:00
Messages: 111
Offline


Late to the party. From my experience, the Javascript needs to be able to reference a component by an Id to find it. Otherwise, it doesn't know what to assign to the ice.event.target parameter. When the components are not created programmatically (i.e., from a JSP or XHTML) the ViewHandler knows to assign Id values to everything and does so. If you're creating components directly yourself, you have to do the same.

I've come across lots of components that didn't function as expected if the Id value wasn't set. I don't chalk this up as a bug, it's just a requirement for the Javascript side to work as it expects.

My 2 cents
philipp.bollbach@itemis.d

Joined: 06/Aug/2007 00:00:00
Messages: 8
Offline


sounds reasonable but the thing that confused me was that the components all had ids set in the rendered page. This seemed like the same behaviour when you don't set the ids manually if you are adding components to a page deklaratively (jsp,facelets). But it isn't. It would be nice if someone could provide us with the necessary details.

Maybe you can only add actionlisteners to components that already have an id set? If so, where can I find the corresponding documentation?
mark.collette


Joined: 07/Feb/2005 00:00:00
Messages: 1692
Offline


A lot of the time, when people are dynamically creating components, they constantly re-create them. So if they don't set a specific id, then the automatically generated id will be different each time, which means that there is no way to tie the events that the previously created component generated, back to the newly created component.
[Email]
philipp.bollbach@itemis.d

Joined: 06/Aug/2007 00:00:00
Messages: 8
Offline


ok,fair point, but what about the client-side javascript? Shouldn't the events from the components fire some ids at least? Even if you would re-create them?
In the example I provided in this thread the components are not re-created. The problem if that they have an auto-id but the javascript events do not carry this information back to the server.
mark.collette


Joined: 07/Feb/2005 00:00:00
Messages: 1692
Offline


I'd have to examine things more closely to explain what's going on. Even when we have auto-generated ids, there's still some code that has to do that. It's not obvious if your components even have those.
[Email]
thorne

Joined: 10/Jun/2008 00:00:00
Messages: 12
Offline


Hi,

I'm having a problem that might not be directly related to the topic but it seems that I have stumbled upon the right people to talk to.

I'm trying to create forms programmatically and keep getting the DOMException error that complains that I'm inserting nodes at the wrong place.

Could you guys please post just a short version of how to create components dynamically.

I've been struggling with this issue for three weeks now so I'm pretty desperate.

All good things lead to more good things
[Email]
mark.collette


Joined: 07/Feb/2005 00:00:00
Messages: 1692
Offline


thorne, can you post the stack trace?

Make sure that you're not trying to make the dynamically created components exist in several component trees. That can happen when people using the binding attribute, especially with session scoped beans.
[Email]
anil.kumar

Joined: 07/Aug/2013 05:43:57
Messages: 1
Offline


Hello,

Dynamically using of setActionListener method is not working with htmlcommandbutton while migrating jsf 1.2 to jsf 2.0.

so i have also used setActionExpression in place of setActionListener (because setActionListener is deprecated in jsf 2.0) with HtmlCommandButton but still it is not working.

if anybody have any solution please help me.........

My code looks like this .....


final HtmlCommandButton button = new HtmlCommandButton();
button.setActionListener(FacesContext.getCurrentInstance()
.getApplication().createMethodBinding("someBean.actionMethod",

new Class[] { ActionEvent.class }));

button.setId(buttonid);




and other one is.......




final HtmlCommandButton button = new HtmlCommandButton();
MethodExpression methodExpression =
FacesContext.getCurrentInstance().getApplication().getExpressionFactory().
createMethodExpression(FacesContext.getCurrentInstance().getELContext(), "someBean.actionMethod", String.class,
new Class<?>[0]);
button.setActionExpression( methodExpression);
button.setId(buttonid);

Thanks
 
Forum Index -> Components Go to Page: 1, 2 Next 
Go to:   
Powered by JForum 2.1.7ice © JForum Team