Jersey
Jersey

Reputation: 81

How to get widget instance pf p:dataTable in js or JQuery

In JSF I have multiple p:dataTable that nested in an outer p:dataTable.

When user click a row in any inner dataTable, that row is selected, and previous selected row is unselected.

I use the primeface datatable widget to select row and unselectAllRows of that widget.

<script type="text/javascript">
        function selectCurrentRow(table,index){
            //How to unselect ALL tables?
            table.unselectAllRows();

            table.selectRow(index ,false);
            }
    </script>

The inner datatable:

        <p:ajax event="rowSelect" listener="#{bean.onRowSelect}"
            update=":eventDetail" />

        <p:column style="width:60px;">
            <div onmousedown="selectCurrentRow(eventTableVar_#{outerRowId}_#{outerColId},#{innerRowId});">
                <p:outputPanel id="event" styleClass="event_block">
                    <h:outputText value="#{event}" />
                </p:outputPanel>
            </div>
        </p:column>

    </p:dataTable>

The onmousedown event is where user trigger the selection process. If I remove that line, the selection will not work, I guess the reason is because I have multiple inner dataTable to select from, so I set widgetVar and use client side API to do the work.

How ever in this way I can only unselect rows of that paticular widget, other inner datatable's selected row will remain selected, That is not what I want, I want them all become unselected. But I don't know how to get the widgets of other inner dataTables.

So My Question is: How to get primeface widget instance by class or id else in JS/JQuery? or you have better solutions for my senario.

Thanks for your effort.

------------------------------------ My complete code:---------------------------------------

JSF

<h:form id="centerForm">
        <p:dataTable id="outerTable" var="user" rowIndexVar="outerRowId"
            value="#{bean.userList}">

            <p:column styleClass="user_name">
                <h:outputText value="#{user}" />
            </p:column>

            <p:columns value="#{bean.weekdays}" var="date" styleClass="weekday"
                columnIndexVar="outerColId">

                <f:facet name="header">
                    <h:outputText value="#{bean.weekdays[outerColId]}">
                        <f:convertDateTime pattern="EEE, dd MMM" />
                    </h:outputText>
                </f:facet>

                <p:dataTable id="eventTable" styleClass="innerTable"
                    rowKey="#{event}" selection="#{bean.selectedEvent}"
                    selectionMode="single"
                    widgetVar="eventTableVar_#{outerRowId}_#{outerColId}"
                    rowIndexVar="innerRowId" var="event"
                    value="#{bean.getEventList(user,date)}"
                    rendered="#{not empty bean.getEventList(user,date)}">

                    <p:ajax event="rowSelect" listener="#{bean.onRowSelect}"
                        update=":eventDetail" />

                    <p:column style="width:60px;">
                        <div onmousedown="selectCurrentRow(eventTableVar_#{outerRowId}_#{outerColId},#{innerRowId});">
                            <p:outputPanel id="event" styleClass="event_block">
                                <h:outputText value="#{event}" />
                            </p:outputPanel>
                        </div>
                    </p:column>

                </p:dataTable>
            </p:columns>
        </p:dataTable>
    </h:form>
    <p:dialog id="eventDetail">
    </p:dialog>

Bean

private List<String> userList;
    private List<String> eventList;
    private Date[] weekdays;

    private String selectedEvent;

    private Map<String, Map<Date, List<String>>> map;

    public List<String> getEventList(String eid, Date date) {
        return map.get(eid).get(date);
    }

    public void onRowSelect(){
        //do some
    }

    @PostConstruct
    public void init() {
        generateWeekdays(new Date());

        userList = new ArrayList<String>();
        userList.add("John");
        userList.add("Allice");
        userList.add("Bob");

        eventList = new ArrayList<String>();
        eventList.add("Event A");
        eventList.add("Event B");
        eventList.add("Event C");
        eventList.add("Event D");

        map=new HashMap<String, Map<Date, List<String>>> ();
        for(String user:userList){
            Map<Date, List<String>> week=new HashMap<Date, List<String>>();
            for(Date date:weekdays){
                List<String> list=new ArrayList<String>();
                week.put(date, list);
            }
            map.put(user, week);
        }
        getEventList("John",weekdays[0]).add(eventList.get(0));
        getEventList("John",weekdays[0]).add(eventList.get(1));
        getEventList("John",weekdays[2]).add(eventList.get(3));
        getEventList("John",weekdays[3]).add(eventList.get(1));
        getEventList("John",weekdays[3]).add(eventList.get(3));

        getEventList("Bob",weekdays[2]).add(eventList.get(1));
        getEventList("Bob",weekdays[2]).add(eventList.get(3));
    }


    private void generateWeekdays(Date from) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(from);
        weekdays = new Date[7];
        for (int i = 0; i < 7; i++) {
            cal.add(Calendar.DAY_OF_MONTH, 1);
            weekdays[i] = cal.getTime();
        }
    }

Upvotes: 1

Views: 4918

Answers (2)

Jersey
Jersey

Reputation: 81

I found a workaround but don't know whether it is a good one.

My initial thought is to first find the JQuery object and than get its widget object,I tried $('.innerTable').first().data() but failed.

Then I assume primeface declare its widget as global variables, so I tried Object.keys(window), and there i found the widgetVar names.(with prefix="eventTableVar_" in this case). so next thing is to make that String type name to widget Object: both window[name] and eval(name) will do the job.

So here's my workaround:

function selectCurrentRow(table,index){ 
    // get all global object keys since primeface put its widget as global
   var keys=Object.keys(window),eventTableVar; 
   // Iterate over global objects to find targeted tables witn String startwidth match 
   for(var i=0;i<keys.length;i++){
    if(keys[i].lastIndexOf("eventTableVar_",0)==0){
     //Get instance and do what you want.
     eventTableVar=window[ keys[ i ] ];
     eventTableVar.unselectAllRows();
    }
   }
   table.selectRow(index ,false);
  };

I don't think this is a very efficient method since it will iterate all the global keys, and uses String comparing to locate widget. So I am still waiting for better answers.

Also there seems other problems with nested p:dataTable. see here: drag-and-drop-in-nested-datatables

Upvotes: 1

Cjxcz Odjcayrwl
Cjxcz Odjcayrwl

Reputation: 22847

There's a direct connectiong between widgetVar and jquery selector. The widget variable has the attributes:

  • id: id attribute of the html element
  • jqId: jquery selector
  • jq: jquery object

You can browser all widgets and compare there id's. But there's also a convention for widget variable names. If you don't specify widgetVar, the widget would be:

var widgetVar = 'widget_' + element.id.replace(/:/g,'_');

I'm using PrimeFaces 3.5.

Upvotes: 0

Related Questions