1 2 Previous Next 29 Replies Latest reply: Jan 29, 2012 4:41 PM by Vinit Adhopia RSS

rich:extendedDataTable and Selection

Andreas Marx Newbie

A simple question, but I didn't find the answer yet: how can I get the selected row of an extendedDateTable in my backing bean? I thought @DataModelSelection should do but don't.
This is my xhmtl:


<rich:extendedDataTable value="#{exercises}" var="ex" id="exerciseTable"
    height="400px" sortMode="single" selectionMode="single"
    reRender="infoPanel">                              
     <rich:column sortable="true" sortBy="#{ex.name}"  filterBy="#{ex.name}" filterEvent="onkeyup" label="#{messages.exName}">
        <f:facet name="header">
               <h:outputText value="#{messages.exName}" />                                        
        </f:facet>
        <h:outputText value="#{ex.name}" />
        </rich:column>
        <a4j:support event="onselectionchange" reRender="infoPanel"
          ajaxSingle="true" action="#{exerciseManager.exerciseSet}"/>



The ExerciseManager looks like:


@Scope(ScopeType.CONVERSATION)
@Name("exerciseManager")
@AutoCreate
public class ExerciseManager implements Serializable {

    @DataModel
    private List<Exercise> exercises;

    @DataModelSelection
    private Exercise exercise;

    @Factory("exercises")
    public void initExercises() {
        List<Exercise> result = null;
        // some code for getting the Exercises
        exercises = result;
    }

    public void exerciseSet() {
       // I thought the selected exercise should be available now, but isn't
    }
}



May be that DataModelSelection is not available for extendedDataTable. I found some code also in this forum which uses SimpleSelection as selection and HtmlExtendedDataTable as binding for extendedDataTable. Will this work? I am surprised about that I can't find any information for such a standard problem.


Thanks

  • 1. Re: rich:extendedDataTable and Selection
    Jon Hatfield Newbie
    You should be able to pass in the datatable variable as a parameter:

    action="#{exerciseManager.exerciseSet(ex)}"

    public void exerciseSet(Excercise ex){
        //
    }

    This works in IceFaces, maybe RichFaces too.
  • 2. Re: rich:extendedDataTable and Selection
    Nikos Paraskevopoulos Novice

    Indeed this works for RichFaces too. Has nothing to do with the component library, it is due to the extensions in the EL implementation by JBoss.


    A more standard JSF way to accomplish this is with the <f:setPropertyActionListener> JSF 1.2 tag. I do not know if it works with <a:support> though.

  • 3. Re: rich:extendedDataTable and Selection
    Andreas Marx Newbie

    Jon Hatfield wrote on May 27, 2009 21:04:


    You should be able to pass in the datatable variable as a parameter:
    action="#{exerciseManager.exerciseSet(ex)}"
    
    public void exerciseSet(Excercise ex){
        //
    }
    


    This works in IceFaces, maybe RichFaces too.


    I tried out, also the <f:setPropertyActionListener> proposed by Nikos:


    <f:setPropertyActionListener value="#{ex}" target="#{exerciseManager.exercise}" />
    


    The setter-Method is called either way, but the parameter passed to the setter is always null.


    Any idea?


    Thanks

  • 4. Re: rich:extendedDataTable and Selection
    Nikos Paraskevopoulos Novice

    About the null... and just in case:


    Make sure your dataTable is inside a JSF form.

  • 5. Re: rich:extendedDataTable and Selection
    Andreas Marx Newbie

    Thanks for the reminding. The dataTable is inside a JSF form. Meanwhile I found a way to get the selected row number:
    I use the selection-attribute in the extendedDataTable:


    selection="#{exerciseManager.selection}"
    



    The corresponding variable inside ExerciseManager is of class SimpleSelection. This works but I get only the row number, which of course changes if the table gets sorted. I think that would be a dirty solution.
    Is there a running example of extendedDataTable together with Seam and onclick-Selection?


    Thanks

  • 6. Re: rich:extendedDataTable and Selection
    Nikos Paraskevopoulos Novice

    Ah, now I see...


    The methods proposed above (#{exerciseManager.exerciseSet(ex)} and <f:setPropertyActionListener>) have worked for me, but my case was pressing a commandButton/commandLink on each row. In this case JSF can associate the current row with the specific instance of the button.


    However, <a4j:support event="onselectionchange"> applies to the entire table, listening for a component-specific, client-side event. JSF does not have a current row when rendering the <a4j:support>!


    An ugly hack that I can think of is to include commandButtons/commandLinks in each row, that use the methods above. The per-row command component will be hidden with CSS (display:none). Then, create a JS function, that will be triggered from the onselectionchange event of the extended data table. The JS function must manually invoke the per-row command component action, e.g. do something like jQuery(selectedRowCommandComponent).click().


    Then there are the following properties of extendedDataTable: activeRowKey, rowKeyConverter, rowKeyVar. They may-or may not- prove useful.


    Another idea is the selection and selectionMode attribute. I.e. you will still fire an AJAX request onselectionchange, but will not rely on the setter method to get the selected row. Instead, use the selection attribute. Looking back at all the ideas, this seams the most reasonable.


    Good luck!

  • 7. Re: rich:extendedDataTable and Selection
    Andreas Marx Newbie

    Finally I got it!


    I use the selection and binding approach:


    <rich:extendedDataTable value="#{exerciseManager.exercises}" var="ex" id="exerciseTable"
         selection="#{exerciseManager.selection}" binding="#{table}" selectionMode="single"
         height="400px" sortMode="single" cellpadding="1">                              
           <a4j:support event="onselectionchange" reRender="infoPanel" requestDelay="400"
                     action="#{exerciseManager.takeSelection}" ajaxSingle="true">
           </a4j:support>                                
    .....                                   
    </rich:extendedDataTable>
    


    The binding is needed, because after sorting the table the row number provided by the selection will not point to the same object as before.


    At first I tried to use exerciseManager.table as binding. This fails because exerciseManager is a conversation scoped component which is not allowed to be bound. But the following works:


        @In(required = false)
        @Out(required = false)
        private HtmlExtendedDataTable table;
    



    Here is the code to get the selected exercise:


        public void takeSelection() {
            Iterator<Object> iterator = getSelection().getKeys();
            while (iterator.hasNext()) {
                Object key = iterator.next();
                table.setRowKey(key);
                if (table.isRowAvailable()) {
                    setExercise((Exercise) table.getRowData());
                }
            }
        }
    



    I think this is all very tricky and somehow dirty but the only solution that works for me.


    Perhaps it will help others with the same problem.

  • 8. Re: rich:extendedDataTable and Selection
    Dan Royalty Newbie

    Hi Andreas.


    Could you please post the the complete version of ExerciseManager.java that you got to work?


    Thanks,
    Dan

  • 9. Re: rich:extendedDataTable and Selection
    martin martin Newbie

    the Selection is null when the site is loaded the first time.
    i figured out that after sorting etc its not null any more.


    so i added



    <a:support event="onselectionchange"  ajaxSingle="true" />



    inside the table it works.

  • 10. Re: rich:extendedDataTable and Selection
    Andreas Marx Newbie

    Sorry for the delay. Here is the important part of ExericseManager:


    @Name("exerciseManager")
    @Scope(ScopeType.CONVERSATION)
    @AutoCreate
    public class ExerciseInSplitManager {
    
        private Exercise exercise;
    
        private String filterValue = "";
    
        @In(required = false)
        @Out(required = false)
        private HtmlExtendedDataTable table;
    
        private SimpleSelection selection;
    
        public void init() {
            exercise = // retrieve Exercise
            // Das muss hier gemacht werden, da sich sonst die extendedDataTable
            // nicht refreshed. Ist eigentlich
            // ziemlich uebel.
            setTable(null);
        }
    
        public String saveExerciseAndFinish() {
         // save Exercise
            resetTable();
            setFilterValue("");
            return "success";
        }
    
    
        public void resetTable() {
            selection = null;
            table = null;
        }
    
        public boolean filterExercise(Object current) {
            Exercise currentExercise = (Exercise) current;
            if (filterValue.length() == 0) {
                return true;
            }
            String exnamelc = currentExercise.getName().toLowerCase();
            if (filterValue.startsWith("*")) {
                return exnamelc.indexOf(filterValue.substring(1).toLowerCase()) != -1;
            }
            if (exnamelc.startsWith(filterValue.toLowerCase())) {
                return true;
            } else {
                return false;
            }
        }
    
        public String getFilterValue() {
            return filterValue;
        }
    
        public void setFilterValue(String filterValue) {
            this.filterValue = filterValue;
        }
    
        public void setSelection(SimpleSelection selection) {
            this.selection = selection;
        }
    
        public SimpleSelection getSelection() {
            return selection;
        }
    
        public void takeSelection() {
            Iterator<Object> iterator = getSelection().getKeys();
            while (iterator.hasNext()) {
                Object key = iterator.next();
                table.setRowKey(key);
                if (table.isRowAvailable()) {
                    setExercise((Exercise) table.getRowData());
                }
            }
        }
    
        public void setTable(HtmlExtendedDataTable table) {
            this.table = table;
        }
    
        public HtmlExtendedDataTable getTable() {
            return table;
        }
    
    }
    



    Hope this helps.


    Andreas

  • 11. Re: rich:extendedDataTable and Selection
    martin martin Newbie

    Andreas could you post where your libraries are?
    i have the richfaces-ui.jar in



    project.ear/project.war/WEB-INF/lib



    and the class is not found.


    should i move richfaces-ui.jar and all depending jars  into



    project.ear/lib




    or should i point to the richfaces-ui.jar directly? but i dont know how.


    thanks

  • 12. Re: rich:extendedDataTable and Selection
    martin martin Newbie

    martin martin wrote on Jun 20, 2009 12:57:



    and the class is not found.




    sorry, HtmlExtendedDataTable is not found

  • 13. Re: rich:extendedDataTable and Selection
    Andreas Marx Newbie

    It's in richfaces-ui.jar. I use richfaces 3.3.1 because it is a quite new feature. The jar must be in the classpath as any other jar.

  • 14. Re: rich:extendedDataTable and Selection
    Christopher Logan Newbie

    I have been struggling to get the extendedDataTable to work, and I came across your information.
    I see you have used the binding attribute.  I just wanted to confirm if exercises is still annotated with @DataModel:


        @DataModel
        private List<Exercise> exercises;
    ...
        @Factory("exercises")
        public void initExercises() {
            List<Exercise> result = null;
            // some code for getting the Exercises
            exercises = result;
        }
    



    I didn't see it in your exerciseManager code but you set it to the value attribute in the rich:extendeDataTable setup.


    Thank you
    -Christopher

1 2 Previous Next