Reputation: 81
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
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
Reputation: 22847
There's a direct connectiong between widgetVar
and jquery selector. The widget variable has the attributes:
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