0

Mojara 2.1.21

I'm using primefaces editor component p:editor. The value attribute in editor is a complex EL-Statement.

<h:form>
<p:datatable value="#{bean.getItems}" var="item">
    <p:column> 
       <p:editor value="bean.A(item).value" />
    </p:column>
</p:datatable>
</h:form>
class Bean {
    public Entity A (Item i) { return ...}        
}

class Entity {
    public String getValue();
    public void setValue(String);
}

The getter Entity.getValue() is called, but the setter Entity.serValue(String) is not called, if form is submitted.

I suppose it has nothing to do with editor but a common feature of EL. How can I instruct the editor to call a setter if some changes will be made in editor by a user ?

UPDATE

The variant <p:editor value="#{multiEditorBacking.eval(editor).text}" id="textArea" /> has trouble if setter will be called. But <p:editor value="#{editor.text}" id="textArea" /> is ok. The following examples can be used for testing.

 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html" xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:p="http://primefaces.org/ui"
xmlns:fn="http://java.sun.com/jsp/jstl/functions"
xmlns:o="http://omnifaces.org/ui" xmlns:pe="http://primefaces.org/ui/extensions">


 <ui:composition>
<h:head></h:head>
<h:body>
    <h:form id="formId">
        <p:dataTable value="#{multiEditorBacking.editors}" var="editor" rowIndexVar="index" >
            <p:column>
                <p:commandButton value="Refresh" actionListener="#{multiEditorBacking.onRefresh(index)}" update="textArea"
                    process="@this" />
                          <p:editor value="#{multiEditorBacking.eval(editor).text}" id="textArea" /> 
            <!--    <p:editor value="#{editor.text}" id="textArea" /> -->
            </p:column>
        </p:dataTable>
        <p:commandButton value="Save" />
    </h:form>
</h:body>
</ui:composition>
</html>

MultiEditorBean.java

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import javax.annotation.PostConstruct;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;

@SessionScoped
@Named
public class MultiEditorBacking implements Serializable{
private List<MultiPojo> editors;
private HashMap <Integer, MultiPojo> hash = new HashMap<Integer, MultiPojo>(); 

@PostConstruct
public void init(){
    editors = new ArrayList<MultiPojo>();
    MultiPojo m = new MultiPojo();
    m.setText("hey1");      
    editors.add(m);
    hash.put(1, m);

    m=new MultiPojo();
    m.setText("adf2");
    editors.add(m);
    hash.put(2, m);

    m=new MultiPojo();
    m.setText("cjd3");
    editors.add(m);
    hash.put(3, m);
}

public MultiPojo eval (MultiPojo m){
    return m;
}

public void onRefresh (int index){

}

public List<MultiPojo> getEditors() {
    return editors;
}

public void setEditors(List<MultiPojo> editors) {
    this.editors = editors;
}

public HashMap <Integer, MultiPojo> getHash() {
    return hash;
}

public void setHash(HashMap <Integer, MultiPojo> hash) {
    this.hash = hash;
}
}

MultiPojo.java

public class MultiPojo {
private String text;

public String getText() {
    return text;
}

public void setText(String text) {
    this.text = text;
}

}
Tony
  • 2,266
  • 4
  • 33
  • 54
  • Where are your entities being stored? If the `Entity` is created when invoking the method how do you intend to keep it? Add extra info about the issue please. BTW, you are missing the `#{}` syntax for your editor's value. – Aritz Feb 26 '14 at 18:02
  • I've updated my question, with a complete example. – Tony Feb 27 '14 at 15:01

2 Answers2

2

This works for me, in Mojarra 2.2.5, using EL 2.2. Are you sure you've got that EL version enabled which allows method parameter passing? You need a Servlet 3.x container available (such as Tomcat 7) or you'll need to add the library yourself. However, it seems you've got it as #{multiEditorBacking.eval(editor).text} value for your editors is being properly evaluated.

By the way, your <ui:composition> surrounding <h:head /> and <h:body /> is unecessary. Another thing I don't like from your code is the use of @SessionScoped for pure view matters. Go with @ViewScoped unless you're explicitly dealing with session related stuff.

@SessionScoped
@Named
public class MultiEditorBacking implements Serializable {
    private List<MultiPojo> editors;
    private HashMap<Integer, MultiPojo> hash = new HashMap<Integer, MultiPojo>();

    public MultiEditorBacking() {
        editors = new ArrayList<MultiPojo>();
        MultiPojo m = new MultiPojo();
        m.setText("hey1");
        editors.add(m);
        hash.put(1, m);

        m = new MultiPojo();
        m.setText("adf2");
        editors.add(m);
        hash.put(2, m);

        m = new MultiPojo();
        m.setText("cjd3");
        editors.add(m);
        hash.put(3, m);
    }

    public MultiPojo eval(MultiPojo m) {
        return m;
    }

    public void onRefresh(int index) {
        System.out.println("Editor " + index + " refreshed");
    }

    public List<MultiPojo> getEditors() {
        return editors;
    }

    public void setEditors(List<MultiPojo> editors) {
        this.editors = editors;
    }

    public HashMap<Integer, MultiPojo> getHash() {
        return hash;
    }

    public void save() {
        System.out.println("Editors: " + editors);
    }

    public void setHash(HashMap<Integer, MultiPojo> hash) {
        this.hash = hash;
    }

    public class MultiPojo {
        private String text;

        public String getText() {
            return text;
        }

        public void setText(String text) {
            this.text = text;
        }

        @Override
        public String toString() {
            return "MultiPojo [text=" + text + "]";
        }

    }
}
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:p="http://primefaces.org/ui">

<h:head />
<h:body>
    <h:form id="formId">
        <p:dataTable value="#{multiEditorBacking.editors}" var="editor"
            rowIndexVar="index">
            <p:column>
                <p:commandButton value="Refresh"
                    actionListener="#{multiEditorBacking.onRefresh(index)}"
                    update="textArea" process="@this" />
                <p:editor value="#{multiEditorBacking.eval(editor).text}"
                    id="textArea" />
            </p:column>
        </p:dataTable>
        <p:commandButton value="Save" action="#{multiEditorBacking.save}" />
    </h:form>
</h:body>
</html>

See also:

Community
  • 1
  • 1
Aritz
  • 30,971
  • 16
  • 136
  • 217
  • Thank you for your answer and tips. I'm using JBoss7.1 and yes parameter passing is enabled. So you can save the form in example ? If I click on "Save"-Button I get an exception. I don't want to use ViewScope because I'm using CDI1.0 (JSF2.1) that does not have ViewScope (and I don't want to mix JSF-Scopes and CDI-Scopes). It is possible that you use a newer implementation of EL. – Tony Feb 28 '14 at 15:31
  • For my example, it's not view or session scope matter, you can test it with session and should work. Btw, the omnifaces utility library has a view scoped annotation for using it with cdi. JSF itself brings this choice starting from 2.2.0 version. – Aritz Feb 28 '14 at 15:42
  • After some experementig I've found the solution to this problem. I had to use braces to achieve that setter will be called. I write it as answer for the people who have the similar problems. – Tony Feb 28 '14 at 15:52
0

The solution was to use brackets in EL to get setter called.

  <p:editor value="#{(multiEditorBacking.eval(editor)).text}"
    id="textArea" />
Tony
  • 2,266
  • 4
  • 33
  • 54
  • That seems non sense. I think it has to be about the jboss el implementation. Anyway, glad to see it helped ;) – Aritz Feb 28 '14 at 16:02