Primefaces extension sheet component on "Enter" press move the focus to the cell in the right - jsf

The default operation of the handsontable when press intro is focus the cell on the bottom, but in primefaces extension the focus go to the right, I need go to the bottom, is there some config that I can try?
I tried to modify the afterChange event with the updateSettings method but isn't work.
below the code of the sheet in the JSF way.
<pe:sheet extender="sheetExtender" id="sheet" contextMenu="true"
rowHeader="true" colHeader="true" widgetVar="sheetWidget"
var="_det" rowKey="#{_det.item}" height="300" showRowHeaders="true"
value="#{ordenSuministroController.detalles}"
readOnly="#{ordenSuministroController.instance.estado!='PENDIENTE'}"
converter="#{ordenSuministroDetConverter}"
emptyMessage="No se encontraron registros." locale="es-MX"
maxCols="5" minCols="5" movableCols="false" movableRows="true">
<f:facet name="header">
<strong>HEADER</strong>
</f:facet>
<pe:sheetcolumn headerText="Descripcion" required="true"
readOnly="#{ordenSuministroController.instance.estado!='PENDIENTE'}"
value="#{_det.descripcion}" colType="text"></pe:sheetcolumn>
<pe:sheetcolumn headerText="Unidad" value="#{_det.unidad}"
readOnly="#{ordenSuministroController.instance.estado!='PENDIENTE'}"
colType="text"></pe:sheetcolumn>
</pe:sheet>
Primefaces v7.0
Primefaces-extension v7.0.1

Based on HandsonTable documentation you an use the enterMoves function to control how the enter key moves cells. See: https://github.com/handsontable/handsontable/issues/4531
Then in the Sheet Extender code you can simply do the "extender" functionality like in the Showcase example and change the Extender to:
function sheetExtender() {
this.cfg.enterMoves = {row: 1, col: 0};
}

Related

How can I initially hide columns in a p:dataTable with p:columnToggler

I'm using PrimeFaces v.5 with this version a new component is released that ColumnToggler, when view is rendered, refreshed all checkbox are checked as a default operation.
What I need to do is;
to uncheck some columns when I initialize the view,
make p:columnToggler remember checked and unchecked options when a refresh operation occurs on p:dataTable
In Primefaces 5.2 you can set the p:column visible attribute to false
<p:column ... visible="false">
You can ofcourse use EL in the visible attribute by colum index (reordering becomes more difficult)
<p:column ... visible="#{visibilityModel.visibleList[1]}">
It hides the column at the beginning depending on the return value and you can show/hide the column through the columnToggler checkbox
By using the ajax toggle event
<p:ajax event="toggle" listener="#{viewBean.onToggle}" />
You can update the state of the visibilityModel server side
public void onToggle(ToggleEvent e) {
list.set((Integer) e.getData(), e.getVisibility() == Visibility.VISIBLE);
}
See this PrimeFaces blog entry for full example to actually keep/store the state of the visibility server side so it can be reused later
The best solution depends on the PrimeFaces version you are using.
PrimeFaces >= 5.2
See the other answer in this question.
workaround for < 5.2
You need to solve the first problem manually by overriding Primefaces' own ColumnToggler.prototype.render() function
first add styleClass="not-show-at-start" to your column that you want to insvisibe at start to access in javascript render() function;
<!--This column will not be shown at start-->
<p:column headerText="Cloumn to hide initially" width="70" styleClass="not-show-at-start">
<h:outputText value="#{entityVar.nmProcessOwner}" />
</p:column>
<!--This column will be shown at start-->
<p:column headerText="Column to show initially" width="70">
<h:outputText value="#{entityVar.nmProcessOwner}" />
</p:column>
secondy create a javascript file and paste code below in it, this function will re assign render function of ColumnToggler
PrimeFaces.widget.ColumnToggler.prototype.render = function() {
//variable for creating id referance for each checkbox in ColumnToggler
var id=0;
this.columns = this.thead.find("> tr > th:visible:not(.ui-static-column)");
this.panel = $("<div></div>").attr("id", this.cfg.id).addClass("ui-columntoggler ui-widget ui-widget-content ui-shadow ui-corner-all").append('<ul class="ui-columntoggler-items"></ul').appendTo(document.body);
this.itemContainer = this.panel.children("ul");
for (var a = 0; a < this.columns.length; a++) {
id++;
var b = this.columns.eq(a);
$('<li class="ui-columntoggler-item"><div class="ui-chkbox ui-widget"><div id="cb'+id /*creating id for each checkbox for accessing later*/+'" class="ui-chkbox-box ui-widget ui-corner-all ui-state-default ui-state-active"><span class="ui-chkbox-icon ui-icon ui-icon-check"></span></div></div><label>' + b.children(".ui-column-title").text() + "</label></li>").data("column", b.attr("id")).appendTo(this.itemContainer);
//access clumns using class reference(not-show-at-start) created in jsf page
if(b.hasClass( "not-show-at-start")){
//access checkbox using id attribute created above and uncheck it
//this will hide columns that have "not-show-at-start" class
this.uncheck($('#cb'+id));
}
}
this.hide();
}
An alternative solution could be to set directly the checkbox you want to uncheck after you load the page. It's a less elegant solution but it works. I did it this way:
<h:body onload="javascript:
$('.ui-chkbox-box')[18].click();">
By this way, after loading the page, javascript hide the column referenced by chechbox number 18 but the checkbox is still present on the columnToggler for the user to check it and show the column again if he wants to.
Greetings
Complementing Damián answer:
$(function() {
$('.ui-columntoggler-items .ui-chkbox .ui-chkbox-box').click();
});
This will do the job, clicking the columntoggler chkbox after page load..
#Edit
You should set as toggleable="false" the columns you don't want to hide (always displayed)
Reason: if you use the javascript method to "override" primefaces toggler, sometimes the datatable column shown can be displayed wrong in the layout (out of the table size, for an example, like happened with me), that's why i decided to use the method described above..

Primefaces Paginator always jumping to page 1

In PF 4.0, how do you make the paginator go to the correct page after updating a datatable and applying oncomplete="dt1Widget.filter()"?
A button in a dialog is supposed to save a certain element, then update the datatable, again apply the filters (as saved by my own DataTableRenderer), and stay on the page I was on when I opened the dialog. That means I filter by certain criteria, go to page 7, edit an element, press save and still want to be on page 7 afterwards.
My datatable
<p:dataTable id="dt1" var="tVar" value="#{regelBean.queriedElements}" scrollable="false"
paginator="true" paginatorAlwaysVisible="true" rows="10"
rowsPerPageTemplate="10,25,100" paginatorPosition="bottom" widgetVar="dt1Widget"
filteredValue="#{regelBean.filteredElements}" first="#{regelBean.paginatorFirst}">
...
<p:ajax event="page" listener="#{regelBean.onPageChange}"/>
Button inside the dialog
<p:commandButton value="Speichern #{regelBean.paginatorFirst}"
update="#form :form1:dt1" actionListener="#{regelBean.save}"
oncomplete="dt1Widget.filter(); dt1Widget.getPaginator().setPage(#{regelBean.paginatorPage});"/>
even tried this
public int getPaginatorPage() {
DataTable d = (DataTable) FacesContext.getCurrentInstance().getViewRoot().findComponent(":form1:dt1");
System.out.println("d.first " + d.getFirst()); // always 20 since I was on page 3
return d.getFirst()/10;
}
paginatorFirst on the button label is 20 when I am on page 3 (kind of expected). After saving, I will always land on page 1. Quick help is really appreciated, as I will stop working on this project in 2 days and would like to fix this issue until then. Thanks
EDIT
What the heck is going on here? I tried
<p:commandButton value="x" update=":form1:dt1"
onstart="#{regelBean.saveFirst()}; alert('A'); "
oncomplete="dt1Widget.filter(); #{regelBean.oncompl()}; alert('! #{regelBean.paginatorFirst} !');"/>
and saveFirst() is randomly (not) called. Besides, until the second alert everything is alright. But AFTER the second alert, I am sent to page 1. When I reload the page, I will land on page 3...

Datatable selection - inputTextArea doesn't have up-to-date contents

Use case
I have a dialog that contains a datatable and an inputTextArea. The datatable is filled when the user clicks a button. When some (single) row of the datatable is selected, I want the contents of this row to be inserted at the end of the inputTextArea.
Problem
When using the selection attribute of the datatable, I dont have the most recent contents in the inputTextArea. Scenario: I enter "ABC" in my inputTextArea, then click the button, then make my inputTextArea "FFF" and select a row ("dtText") from the datatable. The new contents of the inputTextArea is "ABC dtText" instead of "FFF dtText".
What I tried
I tried to add a new listener but I cannot figure out how to bring it in properly so that it is being called before the selection happens. Found nothing on google or in the PF User Guide.
I was hoping the blur event updates my ruleText, but it doesn't happen.
inputTextArea
<p:inputTextarea value="#{mrBean.selectedElement.ruleTxt}" id="rt1New" rows="20" cols="100" autoResize="false">
<f:ajax event="blur" update="duoDlgForm2" />
</p:inputTextarea>
datatable
<p:dataTable id="qPdt" var="p" value="#{regelBean.queriedParams}" rowKey="#{p}"
selection="#{mrBean.selectedParam}" selectionMode="single">
<p:ajax event="rowSelect" update="#form"/>
<p:column ...
java
public void setSelectedParam(ParamOrDBParamModel selectedParam) {
if(selectedParam != null) {
selectedElement.setRuleTxt(selectedElement.getRuleTxt() + "\n" + selectedParam.getName().trim());
How can I work with the most recent text (selectedElement.getRuleTxt) when I am inside the setSelectedParam method?
PF 4.0
EDIT: if I try jquery, what do I have to insert into my function
$('#qPdt tr').on('click', function() {
// I reach this point, now what? How to get the contents of a row when I know the type?
$("#rt1New").append( ?? )
});

p:selectOneMenu get just first value from list primefaces JSF

i have p:selectOneMenu, all values are viewed correctly but just first on my list can be chosen for example, on my list i have e-mail addresses, i can choose everyone but mail is sending just on first of them on list. My JSF code:
<p:dataTable value="#{additionalOrdersBean.additionalOrdersList}"
var="additionalOrders" rowIndexVar="lp" id="myTable" editable="true>
<p:column>
<p:selectOneMenu id="recipient" value="#{additionalOrdersBean.mailTo}" converter="#{mailConverter}" required="true" requiredMessage="#{loc['fieldRequired']}">
<f:selectItems value="#{buildingBean.buildingList2}" var="mail" itemLabel="#{mail.mail1}" itemValue="#{mail.mail1}" />
<f:selectItems value="#{buildingBean.buildingList2}" var="mail" itemLabel="#{mail.mail2}" itemValue="#{mail.mail2}" />
<f:selectItems value="#{buildingBean.buildingList2}" var="mail" itemLabel="#{mail.mail3}" itemValue="#{mail.mail3}" />
</p:selectOneMenu>
<h:message for="recipient" style="color:red"/>
<h:commandButton value="#{loc['send']}" action="#{additionalOrdersBean.sendProtocol()}" onclick="sendProtocolDialog.hide()"/>
</p:column>
</p:dataTable>
My bean:
private String mail1;
private String mail2;
private String mail3;
public List<Building> getBuildingList2() {
buildingList2 = getBldRepo().findByLocationId(lid);
return buildingList2;
}
Can anyone know how to fix it? I wont to send e-mail on choosen address not just on first on my list. Thanks
You seem to expect that only the current row is submitted when you press the command button in the row. This is untrue. The command button submits the entire form. In your particular case, the form is wrapping the whole table and thus the dropdown in every single row is submitted.
However, the value attribute of all those dropdowns are bound to one and same bean property instead of to the currently iterated row.
The consequence is, for every single row, the currently selected value is set on the bean property, hereby everytime overriding the value set by the previous row until you end up with the selected value of the last row.
You've here basically a design mistake and a fundamental misunderstanding of how basic HTML forms work. You basically need to move the form to inside the table cell in order to submit only the data contained in the same cell to the server.
<p:dataTable ...>
<p:column>
<h:form>
...
</h:form>
</p:column>
</p:dataTable>
If that is design technically not an option (for example, because you've inputs in another cells of the same row, or outside the table which also need to be sent), then you'd need to bind the value attribute to the currently iterated row instead and pass exactly that row to the command button's action method:
<p:dataTable value="#{additionalOrdersBean.additionalOrdersList}" var="additionalOrders" ...>
<p:column>
<p:selectOneMenu value="#{additionalOrders.mailTo}" ...>
...
</p:selectOneMenu>
...
<h:commandButton value="#{loc['send']}" action="#{additionalOrdersBean.sendProtocol(additionalOrders)}" ... />
</p:column>
</p:dataTable>
It's by the way not self-documenting and quite confusing to have a plural in the var name. Wouldn't you rather call it additionalOrder? Or is the javabean/entity class representing a single additional order really named AdditionalOrders?
Unrelated to the concrete problem: doing business logic in getter methods is killing your application. Just don't do that. See also Why JSF calls getters multiple times.

How to add double click listener to primefaces datatable

What i want to do is; when user clicks to row, it will select the row.When user double clicks to row, it will start cell editing. At Primefaces showcase(http://www.primefaces.org/showcase/ui/d ... nstant.jsf) it says "Instant row selection, dblclick selection and unselection is implemented using ajax behaviors." but i couldnt find where they implemented dblclick selection. Is there a way to start cell editing event with double click event?
<p:ajax event="rowDblselect">
From PrimeFaces Users Guide
Use
<p:ajax event="rowDblselect" />
in your <p:dataTable /> like this:
<p:dataTable
id="yourTableId"
value="#{yourBean.items}"
selectionMode="single"
selection="#{yourBean.selectedItem}"
var="item"
rowKey="#{item.id}">
<p:ajax
event="rowDblselect"
listener="#{yourBean.onRowDoubleClick}"
update="#form:theComponentYouWantToUpdate"
global="false" />
<!-- your columns here -->
</p:dataTable>
In your bean/controller use:
import org.primefaces.event.SelectEvent;
public void onRowDoubleClick(final SelectEvent event) {
YourObject obj = (YourObject) event.getObject();
// rest of your logic
}
Try setting dblClickSelect="true" on your table.
From the documentation:
By default, row based selection is enabled by click event, enable dblClickSelect so that clicking double on a row does the selection.

Resources