In the JSF and Primefaces Java applications, I have a table in which the user can dynamically add rows to add comments.
Here is the code for the comment table. Comments can be added at the touch of a button. Clicking the button will add a comment to the top of the table. Everything works fine if the user clicks the validation icon to save the text entered on a new line. However, when you save the entire page (the code is not included), only the author and date fields will be saved. Any entered text is lost.
I am trying to find a way to find out if everything is editing a line in the Primefaces data file to either save it or show a warning to the user.
This is xhtml:
<div class="ui-g-6 no-vertical-padding"> <f:event type="preRenderView" listener="#{commentController.initPage()}"/> <h:form id="CommentsForm"> <p:commandButton style="width: 1px; height: 1px; position: fixed; top: -1000px;" action="#{mainController.save}" styleClass="cleanDirtyButton"/> <p:fieldset legend="Comments" style="height: 309px"> <p:remoteCommand name="onCellEdit" update="commentTable" partialSubmit="true" ignoreAutoUpdate="true"/> <h:inputHidden id="hiddenSizeId" value="1000000"/> <h:inputHidden id="hiddenIxId" value="999999"/> <script type="text/JavaScript"> function getNewItemPos() { var noOfItems = $("#CommentsForm\\:hiddenSizeId").val(); var itemIx = $("#CommentsForm\\:hiddenIxId").val(); var bucketHt = $("#CommentsForm\\:commentTable .ui-datatable-scrollable-body").height(); var scrollHt = $("#CommentsForm\\:commentTable .ui-datatable-scrollable-body").prop("scrollHeight"); var itemHt = parseInt(scrollHt) / parseInt(noOfItems); var noItemsInBucket = parseInt(bucketHt) / parseFloat(itemHt); var itemNo = parseInt(itemIx) + 1; var targetBucket = parseInt(itemNo) / parseFloat(noItemsInBucket); var halfBucketHt = parseInt(bucketHt) / 2; var scrollPos = (parseInt(bucketHt) * (parseFloat(targetBucket) - 1)) + parseFloat(halfBucketHt); var scrollPosInt = Math.round(parseFloat(scrollPos)); $('#CommentsForm\\:commentTable .ui-datatable-scrollable-body').animate({scrollTop: scrollPosInt}); } function setCellFocus() { $('.focus_comment:visible').delay().focus(); } function cellEdit() { setTimeout(setCellFocus, 1500); $('.editTable .ui-datatable-data tr').last().find('span.ui-icon-pencil').each(function () { jQuery(this).click() }); } </script> <p:dataTable id="commentTable" widgetVar="commentTableWidget" value="#{projectForm.project.Comments}" sortOrder="DESCENDING" sortBy="#{comment.changedOn}" var="comment" editable="true" rowIndexVar="rowIndex" resizableColumns="true" scrollable="true" scrollRows="10" liveScroll="true" scrollHeight="212" style="margin-top: 5px;" emptyMessage="No comment found" styleClass="ui-corner-all plus-button editTable noBackground"> <f:facet name="footer"> <p:commandButton id="addlink" action="#{commentController.addComment()}" oncomplete="getNewItemPos();cellEdit();setCellFocus();" disabled="#{commentForm.editMode or !pR.hasPermission('PROJECTS:write')}" process="@this" partialSubmit="true" update="commentTable" value="Add Comment" styleClass="table-plus-button" icon="fa fa-plus" iconPos="right"> <p:ajax update=":CommentsForm:commentTable :CommentsForm:hiddenIxId :CommentsForm:hiddenSizeId"/> </p:commandButton> </f:facet> <p:ajax event="rowEdit" listener="#{commentController.onRowEdit}" update="commentTable" oncomplete="if (args && !args.validationFailed) {onCellEdit();} else {$('.editTable tbody.ui-datatable-data tr td .deleteButton').hide();}"/> <p:ajax event="rowEditCancel" listener="#{commentController.onRowCancel}" onsuccess="onCellEdit();" update="commentTable"/> <p:ajax event="rowEditInit" listener="#{commentForm.setEditMode(true)}" update="addlink" onstart="$('.editTable tbody.ui-datatable-data tr td .ui-icon-pencil').hide();$('.editTable tbody.ui-datatable-data tr td .deleteButton').hide();"/> <p:column width="18%" headerText="date" sortBy="#{comment.changedOn}" styleClass="align-top" sortOrder="DESCENDING"> <h:outputText value="#{comment.changedOn eq null ? (comment.createdOn eq null ? '': comment.createdOn ) : comment.changedOn}"> <f:convertDateTime type="date" pattern="dd.MM.yyyy" timeZone="CET"/> </h:outputText> </p:column> <p:column width="30%" headerText="Text"> <p:cellEditor> <f:facet name="output"> <span style="width: 100%; height: 100%"> <h:outputText escape="true" style="white-space:pre-line;" id="commentDisplay" value="#{comment.text.length() > 200 ? comment.text.substring(0, 200).concat(' ...'): comment.text}"> </h:outputText> <p:tooltip id="commentDisplayToolTip" for="commentDisplay,commentDisplayToolTipTxt" rendered="#{comment.text.length() gt 200}" beforeShow="$('.ui-tooltip:visible').hide()" myPosition="left bottom" atPosition="right bottom" hideDelay="500"> <p:outputLabel id="commentDisplayToolTipTxt" styleClass="scrollOutputLabel" value="#{comment.text}"/> </p:tooltip> </span> </f:facet> <f:facet name="input"> <p:message for="text" id="nameMsg"/> <p:inputTextarea value="#{comment.text}" id="text" onkeypress="setConfirmUnload(true); if ((($.browser.mozilla && event.ctrlKey && event.keyCode==13) ||(($.browser.msie||$.browser.chrome) && event.ctrlKey)) && ( ! (event.altKey && event.ctrlKey) ) ) {$('.editTable tbody.ui-datatable-data tr td .ui-icon-check:visible').click(); $('#buttonForm\\:speichern').addClass('unsaved'); setConfirmUnload(true); }" title="Text" styleClass="Wid90 input_mandatory focus_comment"> </p:inputTextarea> </f:facet> </p:cellEditor> </p:column> <p:column width="30%" headerText="author" sortBy="#{comment.changedBy}" styleClass="align-top" sortOrder="DESCENDING"> <h:outputText value="#{comment.changedBy eq null ? ( comment.createdBy eq null ? '' : commentController.extractUserData(comment.createdBy)) :commentController.extractUserData(comment.changedBy)}"/> </p:column> <p:column width="83" id="editor" styleClass="NoPadding align-top"> <p:rowEditor/> <h:panelGroup id="deleteSpan"> <p:commandButton id="delete" partialSubmit="true" style="height: 41px;" title="LΓΆschen" action="#{commentController.removeComment(comment)}" update="commentTable" process="@this commentTable" immediate="true" icon="fa fa-close" iconPos="center" styleClass="deleteButton Fright" disabled="#{empty commentForm.project.Comments}"> <p:confirm header="Confirmation" message="Delete Comment?" icon="ui-icon-alert"/> </p:commandButton> </h:panelGroup> </p:column> </p:dataTable> </p:fieldset> </h:form> </div>
And this is the controller:
@Named("commentController") @RequestScoped public class CommentController { // this method is executed when pressing the add-comment button: public void addComment() { Comment comment = new Comment(); commentForm.setComment(comment); final DataTable commentTable = (DataTable) FacesContext.getCurrentInstance().getViewRoot().findComponent("commentsForm:commentTable"); if (commentTable != null) { commentTable.setValueExpression("sortBy", null); commentTable.setValueExpression("sortOrder", null); } comment.setProject(projectForm.getProject); projectForm.getProject().getComments().add(comment); if (commentTable) { commentTable.processValidators(getFacesContext()); } } // not really relevant for my question, because: // this method is only called when properly ending the rowEdit by pressing the green check public void onRowEdit(RowEditEvent event) { Comment comment = (Comment) event.getObject(); if (!validateComment(comment)) { getFacesContext().validationFailed(); } else { if (comment.getId() != 0 && commentForm.getProject().getComments().contains(comment)) { projectForm.getProject().getComments().set(commentForm.getProject().getComments().indexOf(comment), comment); } commentForm.setEditMode(false); } } }
java javascript jsf datatable primefaces
Robert
source share