Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7733673
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 1, 20262026-06-01T07:03:39+00:00 2026-06-01T07:03:39+00:00

try to write a composite component that allows mutltiple text inputs. I read that

  • 0

try to write a composite component that allows mutltiple text inputs. I read that it is possible to define a backing component for a composite component, so I don’t have to write a renderer nor a handler. What I couldn’t figure out is how to delegate actions declared in composite’s xhtml to the backing component. I guess i did not yet quite understand the concept of this. Does anybody has an Idea?

I am using Tomcat 7, EL 2.2, Spring 3, Mojarra 2.1.7

This is the way i’d like to use the component:

<custom:multiInput value="#{backingBean.inputList}"/>

Where the BackingBean.java holds a list of objects:

@Component
@Scope(value="view")
public class BackingBean {
    ...
    private List<Foo> inputList;
    ....
}

The composite component multiInput.xhtml looks like this:

<cc:interface componentType="MultiInput">
    <cc:attribute name="value" required="true" type="java.util.List" />
</cc:interface>

<cc:implementation>    
    <div id="#{cc.clientId}">
        <h:dataTable value="#{cc.attrs.rows}" var="row">
            <h:column>
                <!-- here will be a selector component in order to select a foo object -->
            </h:column>
            <h:column>
               <h:commandButton value="Remove Row">
                    <f:ajax execute=":#{cc.clientId}" render=":#{cc.clientId}" listener="#{cc.removeRow(row)}" />
                </h:commandButton>
            </h:column>
            <h:column>
                <h:commandButton value="Add Row" rendered="#{cc.lastRow}">
                    <f:ajax execute=":#{cc.clientId}" render=":#{cc.clientId}" listener="#{cc.addEmptyRow()}" />
                </h:commandButton>
            </h:column>
        </h:dataTable>
    </div>    
</cc:implementation>

And here the backing component MultiInput.java:

@FacesComponent(value="MultiInput")
public class MultiInput extends UIInput implements NamingContainer, Serializable{

    ...

    @Override
    public String getFamily() {
        return "javax.faces.NamingContainer";
    }

    @Override
    public void encodeBegin(FacesContext context) throws IOException {
        initRowsFromValueAttribute();
        super.encodeBegin(context);
    }

    public void removeRow(MultiInputRow row) {
        // why is this method is never reached when clicking remove button?
    }

    public void addEmptyRow() {
        // why is this method is never reached when clicking add button?
    }

    public ListDataModel<MultiSelectRow> getRows() {
        return (ListDataModel<MultiSelectRow>) getStateHelper().eval(PropertyKeys.rows, null);
    }

    private void setRows(ListDataModel<MultiSelectRow> rows) {
        getStateHelper().put(PropertyKeys.rows, rows);
    }

    ...
}

Now – removeRow and addEmptyRow is never called on MultiInput. An ajax request is triggered but it gets lost somewhere. Why?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-01T07:03:41+00:00Added an answer on June 1, 2026 at 7:03 am

    Although I don’t understand everything in detail, I found a way to make it work. Since on each request a new instance of the backing component MultiInput is created, I had to save the state by overwriting saveState and restoreState. This way I could keep the property rows as a simple property. I also removed the encodeBegin method and overwrote getSubmittedValue.

    At least this way it is working in Mojarra. When using MyFaces with default settings, I got some serialization exceptions, but I did not get deepter into that since we will stick on Mojarra. Also MyFaces seemed to be more stricked with ajax event listeners. It required “AjaxBehaviorEvent” parameters in listener methods.

    Here the complete backing component MultInput:

    @FacesComponent(value = "MultiInput")
    public class MultiInput extends UIInput implements NamingContainer, Serializable {
    
        ListDataModel<MultiInputRow> rows;
    
        @Override
        public String getFamily() {
            return "javax.faces.NamingContainer";
        }
    
        @Override
        public Object getSubmittedValue() {
            List<Object> values = new ArrayList<Object>();
            List<MultiInputRow> wrappedData = (List<MultiInputRow>) getRows().getWrappedData();
            for (MultiInputRow row : wrappedData) {
                if (row.getValue() != null) { // only if a valid value was selected
                    values.add(row.getValue());
                }
            }
            return values;
        }
    
        public boolean isLastRow() {
            int row = getRows().getRowIndex();
            int count = getRows().getRowCount();
            return (row + 1) == count;
        }
    
        public boolean isFirstRow() {
            int row = getRows().getRowIndex();
            return 0 == row;
        }
    
        public void removeRow(AjaxBehaviorEvent e) {
            List<MultiInputRow> wrappedData = (List<MultiInputRow>) getRows().getWrappedData();
            wrappedData.remove(rows.getRowIndex());
            addRowIfEmptyList();
        }
    
        public void addEmptyRow(AjaxBehaviorEvent e) {
            List<MultiInputRow> wrappedData = (List<MultiInputRow>) getRows().getWrappedData();
            wrappedData.add(new MultiInputRow(null));
        }
    
        public ListDataModel<MultiInputRow> getRows() {
            if (rows == null) {
                rows = createRows();
                addRowIfEmptyList();
            }
            return rows;
        }
    
        public List<Object> getValues() {
            return (List<Object>) super.getValue();
        }
    
        private ListDataModel<MultiInputRow> createRows() {
            List<MultiInputRow> wrappedData = new ArrayList<MultiInputRow>();
            List<Object> values = getValues();
            if (values != null) {
                for (Object value : values) {
                    wrappedData.add(new MultiInputRow(value));
                }
            }
            return new ListDataModel<MultiInputRow>(wrappedData);
        }
    
        private void addRowIfEmptyList() {
            List<MultiInputRow> wrappedData = (List<MultiInputRow>) rows.getWrappedData();
            if (wrappedData.size() == 0) {
                wrappedData.add(new MultiInputRow(null));
            }
        }
    
        @Override
        public Object saveState(FacesContext context) {
            if (context == null) {
                throw new NullPointerException();
            }
            Object[] values = new Object[2];
            values[0] = super.saveState(context);
            values[1] = rows != null ? rows.getWrappedData() : null;
            return (values);
        }
    
        @Override
        public void restoreState(FacesContext context, Object state) {
            if (context == null) {
                throw new NullPointerException();
            }
    
            if (state == null) {
                return;
            }
            Object[] values = (Object[]) state;
            super.restoreState(context, values[0]);
            rows = values[1] != null ? new ListDataModel<MultiInputRow>((List<MultiInputRow>) values[1]) : null;
        }
    
        /**
         * Represents an editable row that holds a value that can be edited.
         */
        public class MultiInputRow {
    
            private Object value;
    
            MultiInputRow(Object value) {
                this.value = value;
            }
    
            public Object getValue() {
                return value;
            }
    
            public void setValue(Object value) {
                this.value = value;
            }
        }
    }
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I try to write a macro in clojure that sets up a namespace and
I try to write the following in latex: \begin{itemize} \item \textbf{insert(element|text)} inserts the element
I try to write a statement with Razor syntax that use mvccontrib grid where
I try to write a class that takes a tuple of functions as its
i try to write a code that show a rect in a blue frame:
I try to write a script that will reset and reinitialize the database for
i try the write c# application that for now will send some string between
I try to write vbscript, to remove the duplicated component GUID entry in component
I try to write a script that counts connected components of a graph and
I try to write warpper that parses xml files using xsl style sheet and

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.