How at a time one row can expand in <p:dataTable>? - jsf-2

In my application I have a <p:datatable> with rowExpansion column. I have a requirement to open a single row at a time. If anyone tries to expand second row, remaining first row expanded then one message will be generated saying First close the expanded row and then open another row.
How this can be implemented ? Any pointer will be very helpful to me. Thanks

As of 2015, and this question is first in Google search results, I want to add that for PrimeFaces 5.1, there is dataTable attribute rowExpandMode, when set to single - allows only one row to be shown. Example:
<p:dataTable var="line" value="#{bean.lines}" rowExpandMode="single">
It's not exactly what was asked, but I hope that it'll help to others.

You can use (I have tested it in mojarra 2.1.20 and Primefaces 3.5 and it works fine) the following solution which calls a JavaScript function when the row is expanded. When clicking on a second row, and there is another expanded row, it will trigger a click event, which will in turn collapse the previously opened row.
xhtml:
<p:ajax event="rowToggle" onstart="test();"/>
Javascript:
<script type="text/javascript">
function test(){
var i = $('.ui-row-toggler.ui-icon-circle-triangle-s').length;
if(i == 1){return;}
$('.ui-row-toggler.ui-icon-circle-triangle-s').trigger('click');
}
</script>

Check out the datatable.js file in Primefaces here. There is a javascript function called toggleExpansion.
Maybe you can override this function and call the original one when no row is expanded and show a message when another row is already expanded (and not call the original one).
Just an idea...

you can achieve this with the help of this custom method.
give 'togglerClass' this class like
<pou:column styleClass="togglerClass" style="width:16px">
<pou:rowToggler/>
</pou:column>
JavaScript code here;
function prodsToggler() {
$('.togglerClass div').click(function () {
var currentTr = $(this).closest("tr");
var $trs = $('.togglerClass').closest("tr").not(currentTr);
$trs.each(function (index, el) {
var $this = $(el),
$next = $this.next(".ui-expanded-row-content");
$this.removeClass("ui-expanded-row");
$next.remove();
$this.find(".ui-row-toggler").removeClass("ui-icon-circle-triangle-s");
});
});
}
call this method in windows ready.

Related

JQGrid setRowData event after formatter called

In response to
jQuery UI menu inside a jqGrid cell
My specific implementation of a grid has to call setRowData in numerous places. When setRowData is called, the formatter for the column will get called, and will return the <button>s when the row rebuilds in response to the setRowData.
But in the Menu example, the formatting of the buttons (the calls to .button() and .buttonset()) occur on the loadComplete. Since loadComplete obviously does not run after the setRowData, the buttons in the column display unformatted. So, say we add a button to the body:
<button id="setRowData">Set Row Data</button>
and a click event in the $(function() {})
$("#setRowData").click(function() {
var $grid = $("#list");
var data = $grid.jqGrid('getRowData', 1);
data.name = "Changed!";
$grid.jqGrid('setRowData', 1, data);
});
If you click on the button, the "My Action" and "Bla Bla" buttons show up unformatted.
So, I am looking for an event which I can hang off the setRowData for when after the <button>s have been added to the dom, so I can call .button() and .buttonset() on them again. I want to use an event, since I have a generalized routine which is doing the setRowData (in another library altogether).
Okay, I dug through the JQGrid code, and noticed there was a jqGridAfterGridComplete getting called after the setRowData finishes. So I added a:
$("#list").on("jqGridAfterGridComplete", function() {
... call the .button code again
});
to the ready function, and the styles are applied again. There may be a better way, and please feel free to offer one. But this seems to work.

Grab all fieldset elements inside div

In my ASP MVC 3 view I have a number of fieldset elements that are hidden when the page loads. Based upon a user selection of a group of radio buttons, I need to make the corresponding fieldset visible.
I'd like to do this in jquery by making an array of the fieldset elements, then cycle through them, adjusting their visibility property if they match the selected radio button or not. Is this possible?
Since there is so much code in the fieldsets I attached the screen shot below to save space/make it more readable. The fieldsets I am trying to alter are inside of the RightDiv. If you need any more detail, please let me know. Thx
You can try this:
$(function(){
$('[name="TransactionType"]').change(function(){
var id = '#' + this.className; //Get the id from the clicked radio classname
$('#RightDiv').find('fieldset').hide();// hide all fieldsets;
$('#RightDiv').find(id).show(); // show the selected one.
});
});
Just note that in your html helper you are providing the the first overload as same name for all. All is well except i believe it will create duplicate ids for each of these. You may want to override it in the HTMLattributes.
#Html.RadioButton("TransactionType", false, new{#class="Enroll", id="Radio1"})
#Html.RadioButton("TransactionType", false, new{#class="New", id="Radio2"})
Sorry, posted a bit too soon on this. Tried the following below and it worked just fine.
$(document).ready(function () {
$('input[name=TransactionType]').change(function () {
var radioValue = $(this);
var elements = [];
$('#RightDiv').children().each(function () {
elements.push($(this));
});
});
});

Drag and drop of rows primefaces datatable/datagrid?

I trying to drag and drop of rows using primefaces datatable/datagrid.But this is issue in primefaces.What is best way to integrate drag and drop of primefaces datatable/datagrid with jquery or other third party api plugin.Please suggesst to me.
You need to add some JavaScript (JQuery) in your JSF page to make Datatable sortable and to disable selection mode. Listed below doReorder() method gets the new order of the rows and save to order_q variable:
<script type="text/javascript">
$(document).ready(function () {
$('.ui-datatable tbody').sortable();
$('.ui-datatable tbody').disableSelection();
});
function doReorder() {
var order = '';
var len = $('.row').length;
$('.row').each(function (index) {
order += ($(this).text() + ((index == (len - 1)) ? '' : ';'));
});
$('#order_q').val(order);
return true;
}
</script>
Add some code to your Datatable component. You see a new column with number of the row as value with attribute styleClass set to „row” . There is a hidden variable order_q updated during execution JavaScript method doReorder() :
<p:dataTable rowIndexVar="rowIndex"
var="entry" value="#{myBean.list}" >
<p:column headerText="#">
<h:outputText styleClass="row" value="#{rowIndex}"/>
</p:column>
... (other colums as you wish)
</p:dataTable>
<h:inputHidden id="order_q" value="#{myBean.order}"/>
<p:commandButton value="Submit order" ajax="false" onclick="return doReorder()" action="#{myBean.reorder}"/>
Your bean class should contain a String field order (with getters and setters of course). The variable wil store a value from the JavaScript – the new order of our list (source data of the Datatable widget). We need to implement also a method mentioned in the xhtml - reorder() to handle action from button „Submit order”
public String reorder() {
Map < String, String > tmp = FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap();
String order = tmp.get("order_q");
if (order != null && !order.isEmpty()) {
ArrayList < YourData > reordered = new ArrayList < > ();
for (String s: order.split(";")) {
try {
Integer i = Integer.parseInt(s);
YourData data = list.get(i);
reordered.add(data);
} catch (NumberFormatException nfe) {}
}
list = reordered;
}
return null;
}
That’s all! Now you can reorder your Datatable using drag&drop feature and save the new order by clicking a button. I leave a reference to my blog where all of this is described:
http://michalu.eu/wordpress/drag-and-drop-rows-to-reorder-your-datatable-in-primefaces/
Just use
<p:dataTable draggableRows="true"
On Primefaces 5.0 DataTable documentation you can see the parameter draggableRows, like this :
draggableRows | false | Boolean | When enabled, rows can be reordered using dragdrop.
http://www.primefaces.org/documentation
As far as i know from datatables (primefaces) in my applications, they have 2 main states/modes. It may be not the correct word but i stay with it. The 1st is display only, and 2nd editing.
(In display i dont see events triggering so DnD wont work.) in editing they have a serious issue with selectivity. u have to press at the edge of the table and not in inline components reach to get the focus on the row. So The drop must be done in that area and only propably for events to trigger. If u see the examples...all drops are made on an outer component(panel etc) and the table is just updated because the ondrop event in ajax has run and changed the data the drop table will contain. That may be magic for incrementing data...but not for rearranging and updating cell or row data.
SO the answer for that up to primefaces 3.5.x is i dont think you can achieve it...I dont think you can doit with jquery either because they run client side? i havent used them before so i cant tell for sure.
A bit of rework of your forms may be needed.

Display a ListGrid from the start with all its rows expanded

I'm using SmartGWT 2.5.
I have a main grid that has its expandable rows in order to display subgrids.
I simply want to display the main grid with all its rows expanded from the start.
I tried to add a listener containing the following code:
ListGridRecord[] records = getRecords();
for (ListGridRecord rec : records) {
expandRecord(rec);
}
I tried with DataArrivedHandler and DrawAreaChangedHandler, but I just get javascript errors client-side or only parts of the rows are expanded. How can I fix this?
If you are talking about Grid Grouping, then you can use the following:
grid.setGroupStartOpen(GroupStartOpen.ALL);
listGrid.addDataArrivedHandler(new DataArrivedHandler() {
#Override
public void onDataArrived(DataArrivedEvent event) {
for (ListGridRecord rec : listGrid.getRecords()) {
listGrid.expandRecord(rec);
}
}
});
Should work (worked with previous versions..)
What error do you get?
Ok finally, I've put a timer of 100 ms within each handler.
The issue was that there was a delay before the full creation of the components (what I want to display is quite complex), and so when the handler was called, not everything was in place yet...

How to delete a jqgrid row without reloading the entire grid?

I have a webpage with multiple jqgrids each with inline editing enabled, "action" column (edit icons) enabled and pager disabled. I need to handle the delete event for each row so that I can process the delete without reloading server-side data. I've looked at the approach mentioned in jqGrid Delete a Row and it's very helpful except I have two questions that are stumping me -
Are there more details around the rp_ge parameter in the delOptions.onClickSubmit event?
My column has the delOptions set as this -
delOptions: {onclickSubmit: function(rp_ge, rowid) {return onRowDelete(rp_ge,rowid);}},processing:true }},
Is there a way to get the grid id from within that event? I'd like to have a generic function that I can use to handle delete events from all the grids on the page. The rp_ge parameter has a gbox which sometimes contains the grid id appended? But I have no idea what it is since i'm not able to figure out when it's populated, when it's not.
function onRowDelete(rp_ge, rowid) {
//hardcoded grid id.. don't like it.
var gridid = '#Grid_X';
//what is this gbox?? can i get grid id predictable from it?
//var gridid = rp_ge.gbox.replace("#gbox_", "");
var grid = $('#Grid_X');
rp_ge.processing = true;
var result = grid.delRowData(rowid);
if (result) {
$("#delmod" + grid[0].id).hide();
}
return true;
}
In the jqGrid Delete a Row approach, the code $("#delmod"+grid[0].id).hide(); is hiding the popup delete confirmation dialog manually. What I noticed is that when the dialog pops-up, jqgrid de-emphasizes the background page (makes it light greyish). But after the popup is manually closed (hidden actually?), the background remains de-emphasized. So it looks like the page doesn't have focus (or even disabled). Any way this can be fixed? This can also be seen on the demo that Oleg wrote.
Any help would be appreciated.
(PS - I would've commented on the same post but I don't have enough points to comment on someone else's answer yet.)
In answer to your second point.
Several examples by Oleg such as this one have the following modification.
$("#delmod" + grid[0].id).hide();
is replaced with
$.jgrid.hideModal(
"#delmod"+grid_id,
{gb:"#gbox_"+grid_id,jqm:rp_ge.jqModal,onClose:rp_ge.onClose}
);
This will return focus after the delete operation.

Resources