PrimeFaces Tree scrollable fixed size - primefaces

I have a huge tree component in my primefaces application. The tree has hundreds of nodes and I want the tree to have fixed height in my UI with vertical scroll to navigate the nodees.
Can someone help me figure this out?
Thanks

Put that tree in a panel and then apply style to that panel. For example:
<p:outputPanel style="width: 100%;height: 100px;overflow: auto;display: block">
<p:tree value="#{bean.root}">
<p:treeNode>
<h:outputText value="#{doc}" />
</p:treeNode>
</p:tree>
</p:outputPanel>

I use p:scrollPanel
<p:scrollPanel style="height:450px;width:500px;">
<p:tree ...>
</p:tree>
</p:scrollPanel>

p:scrollPanel does not work well.
Use: p:layout
Here an example:
<p:layout style="max-width:800px;min-height:300px;width:800px;height:300px;">
<p:layoutUnit position="north">
<p:panelGrid columns="2" columnClasses="label,value"
style="text-align:left;">
<p:outputLabel value="Nombre:" for="nombre" />
<p:outputLabel id="nombre"
value="#{segPerfilBean.currentObject.segPerNombre}"
title="Nombre" />
</p:panelGrid>
</p:layoutUnit>
<p:layoutUnit position="center">
<h:panelGrid id="catalogContent" style="width: 100%;">
<p:tree value="#{segPerfilBean.rootOpciones}" var="doc"
disabled="true" readOnly="true" selectionMode="checkbox"
selection="#{segPerfilBean.selectedNodes}"
style="width:100%;height:100%;">
<p:treeNode type="perfil">
<h:outputText value="#{doc.segPerNombre}" />
</p:treeNode>
<p:treeNode type="modulo">
<h:outputText value="#{doc.segModNombre}" />
</p:treeNode>
<p:treeNode type="opcion">
<h:outputText value="#{doc.segOpcNombre}" />
</p:treeNode>
</p:tree>
</h:panelGrid>
</p:layoutUnit>
</p:layout>

<p:tree value="#{bean.root}"
style="width: 100%;height: 100px;overflow: auto;display: block">
<p:treeNode>
<h:outputText value="#{doc}" />
</p:treeNode>
</p:tree>`

So I found a way to make this work. However, I will admit upfront it was not my dream solution. But then I have only so much time to play around as this is a bit of a pet project for me:
I created two instances of the table with the same definitions and used fixed header widths. I then placed each table one after the other in individual divs. I then style those divs:
#header {
height: 24px;
}
#body thead {
display: none;
}
and then the I have a sample of simple tables and divs below:
<div id="header">
<p-treeTable [value]="[]">
<p-column field="key" header="Key" [style]="{'width':'30%'}">
<ng-template let-row="rowData" pTemplate type="body">
{{ row.data.key }}
</ng-template>
</p-column>
<p-column field="key" header="Key" [style]="{'width':'70%'}">
<ng-template let-row="rowData" pTemplate type="body">
{{ row.data.big }}
</ng-template>
</p-column>
</p-treetable>
</div>
<div id="body">
<p-treeTable [value]="treedata">
<p-column field="key" header="Key" [style]="{'width':'30%'}">
<ng-template let-row="rowData" pTemplate type="body">
{{ row.data.key }}
</ng-template>
</p-column>
<p-column field="key" header="Key" [style]="{'width':'70%'}">
<ng-template let-row="rowData" pTemplate type="body">
{{ row.data.big }}
</ng-template>
</p-column>
</p-treetable>
</div>
What I think helped is ensuring I set the width on each column so I could ensure I got the same column width during display. I also set the treedata to [] or empty for the header so I do not process the data two times. This is a bit inelegant. And I would sure have liked to add scrolling directly to the treetable but time is not available.
Also to have the table itself scroll. use something like:
.ui-treetable-tablewrapper {
overflow-y: scroll;
height: 290px;
}
NOTE: I have no idea how to get the height so a row is not a bit clipped. As it seems the row height for expanded rows is not identical to that of unexpanded rows.
If you place this in a bootstrap panel with a footer and no padding it looks good, albeit not perfect:
<div class="panel panel-default">
<div class="panel">
<div class="panel-heading">
...header...
</div>
<div class="panel-body" style="{ padding: '0' }">
...Table...
</div>
<div class="panel-footer">
<div class="row">
....footer...
</div>
<div>
</div>

Related

Primefaces LayoutUnit does not expand when browser window is maximised

I have a Layout consisting of a north LayoutUnit containing a banner, a west LayoutUnit containing a vertical menu, and a central Layoutunit containing the main page content.
When I open a page with the browser minimised (e.g. browser width is half of the pc screen width) then it displays as much as it can in the view. However, if I then maximise the browser, it doesn't expand the content in the central LayoutUnit (see attached picture).
The code for the Layout is as follows:
<h:body>
<p:layout style="margin: 0px; gutter: 0px !important!" fullPage="false" >
<p:layoutUnit position="north" size="80" resizable="false" closable="false" collapsible="true" gutter="0" >
<div style="background-image: url('../resources/images/veges.jpg'); height: 80px; "> </div>
</p:layoutUnit>
<p:layoutUnit position="west" size="210" resizable="false" closable="false" collapsible="false" gutter="0">
<h:form id="menuForm">
<p:menu style="width:180px">
<p:menuitem value="Home" outcome="WelcomeMember" icon="fa fa-home" />
</p:menu>
<p:menu style="width:180px" toggleable="true">
<ui:include src="menu.xhtml" />
</p:menu>
<p:menu style="width:180px">
<p:menuitem value="Sign Out" action="#{loginBean.doLogout()}" icon="fa fa-sign-out" />
</p:menu>
</h:form>
</p:layoutUnit>
<p:layoutUnit position="center" collapsible="false" resizable="true" gutter="0" >
<ui:insert name="pageContent" >
This is the default page content
</ui:insert>
</p:layoutUnit>
</p:layout>
</h:body>
Does anyone know why this is happening and what I need to do to correct it?

Page layout, CSS

I would like next to my dataGrid to have another table, floating left to it. Like this, located in the main div:
| | |
| A | B |
| | |
, where A is the current dataGrid, containing all user and B will be the new content. I tried with creating a table inside the main div and putting left and right part in 2 columns inside a row, but B go out of the field of main div. I tried putting CSS for left and right col and adding two extra div but it still does not look in this way. B goes below A. Please, give me an advice how can this be done. Here is the source of the page.
The code of my page is this:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:p="http://primefaces.org/ui"
xmlns:c="http://java.sun.com/jsp/jstl/core">
<ui:composition template="/WEB-INF/templates/BasicTemplate.xhtml">
<ui:define name="content">
<div id="container" style="min-height: 100%; position: relative;">
<div id="left"
style="background-image: url('#{resource['images/left.png']}'); background-repeat: repeat-y; height: 1800px; width: 163px; float: left;">
<br />
</div>
<div id="main" style="width: 920px; float: left;">
<f:view>
<h:form rendered="#{not empty loginBean.name}">
<h:outputStylesheet library="css" name="css.css" />
<center>
<h2>My Profile</h2>
</center>
<p:dataGrid var="user" value="#{profileBean.userList}">
<p:panelGrid columns="2">
<f:facet name="header">
<p:graphicImage value="#{profileBean.image}" alt="${user.name}"
width="150px" height="150px">
<f:param name="userId" value="#{user.id}" />
</p:graphicImage>
</f:facet>
<h:outputText value="Name: " />
<h:inputText value="#{user.name}" />
<h:outputText value="Phone: " />
<h:inputText value="#{user.phone}" required="true">
<f:validateRegex pattern="[0-9]+" />
</h:inputText>
<h:outputText value="Role: " />
<h:outputText value="#{user.userRole.roleName}">
</h:outputText>
<f:facet name="footer">
<h:panelGroup style="display:block; text-align:center">
<p:commandButton id="submit" value="Save changes"
actionListener="#{profileBean.editUser()}" >
<f:attribute name="profileBean.selectedUser" value="#{user}" />
</p:commandButton>
</h:panelGroup>
</f:facet>
</p:panelGrid>
</p:dataGrid>
<hr />
</h:form>
</f:view>
</div>
</div>
<div id="right"
style="background-image: url('#{resource['images/right.png']}'); background-repeat: repeat-y; height: 1800px; width: 150px; float: right;">
<br />
</div>
</ui:define>
</ui:composition>
</html>
may be using display:table and display:table-cell will help you
here is a DEMO
Mark UP
<div class="container">
<div class="left"></div>
<div class="right"></div>
</div>
CSS
.container {
display:table;
border:1px solid #000;
}
.left {
display:table-cell;
width:100px;
height:100px;
background-color:green;
}
.right {
display:table-cell;
width:100px;
height:100px;
background-color:Blue;
}
Result:
You need to set the width of "right" and "left" to fit in the width of the screen. You can do this by setting the divs width percentage wise.
e.g width=25%

Center component on jsf page

I was trying to center the component in jsf page, it looks sth like this:
<p:panel header="Enter your credentials:" style="vertical-align:middle;">
<h:panelGrid columns="2" styleClass="panelGridCenter">
<h:outputText value="Login: " />
<p:inplace id="Login">
<p:inputText value="Enter login" />
</p:inplace>
</h:panelGrid>
</p:panel>
I've tried to enter sth like this:
style="vertical-align:middle;"
I've tried to use a css class (I've had almost no experience with css):
.panelGridCenter {
margin: 0 auto;
vertical-align:middle;
}
But it doesn't work.
Can you give me any examples or hints how to position this component (panel) in the center of the jsf page?
p - primefaces
thx in advance
Try below code I will hope this answer be your question
<h:form>
<table width="100%" cellpadding="0" cellspacing="0" border="0" align="center" class="outer_table">
<tr>
<td>
<table width="500" height="300" cellpadding="0" cellspacing="0" border="0" align="center">
<tr>
<td align="center">
<p:panel header="Login">
<h:panelGrid columns="2" cellpadding="5">
<h:outputLabel for="username" value="username" />
<p:inputText id="username" value="#{loginBean.uname}" required="true" label="username"/>
<h:outputLabel for="password" value="password" />
<p:password id="password" value="#{loginBean.password}" required="true" label="password" />
<p:commandButton value="Login" action="#{loginBean.loginProject}" update=":growl"/>
</h:panelGrid>
</p:panel>
</td>
</tr>
</table>
</td>
</tr>
</table>
</h:form>
css
<script type="text/css">
html, body
{
margin:0px;
padding:0px;
width:100%;
min-height:100%;
height:100%;
}
.outer_table
{
width:100%;
height:100%;
}
</script>
This may be irrelevant as I cannot answer your question, but a dialog (centered by default) looks pretty cool for a login-page:
<h:body>
<p:growl id="growl" life="5000" autoUpdate="true" showDetail="true" escape="false"/>
<h:form>
<p:dialog id="dialog" header="Login" footer="..." width="400" widgetVar="dlg" visible="true" closable="false" showEffect="clip" draggable="false" resizable="false" style="box-shadow: 7px 10px 5px #303030;">
<p:panelGrid columns="2" style="margin: 0 auto">
<h:outputText value="username:"/>
<h:inputText value="#{loginBean.username}" id="username"/>
<h:outputText value="password:"/>
<h:inputSecret value="#{loginBean.password}" id="password"/>
</p:panelGrid>
<p:commandButton id="button" value="Login" action="#{loginBean.doLogin}" style="float:right"/>
</p:dialog>
</h:form>
</h:body>
visible="true" makes the dialog show automatically after load.
Inspired by this article, also showing how to secure parts of the application.
I am not an expert but sharing my own experience. After putting the panel into form, try putting the form into div with style as below:
<div style="width:360px; margin: 10% auto 10% auto;">
<h:form>
....
</h:form>
</div>

How can I center this checkbox

How can I center/align this checkbox and text horizontally?
<h:panelGroup>
<div>
<h:selectBooleanCheckbox id="deactivate" title="select to deactivate" />
<h:outputText value="${msg['deactivate/confirm']}" for="deactivate" />
</div>
</h:panelGroup>
You simply have to apply style="width: 500px;text-align: center;" like this :
<h:panelGroup layout="block" style="width: 500px;text-align: center;">
<h:selectBooleanCheckbox id="deactivate" title="select to deactivate" style="vertical-align: middle;" />
<h:outputText value="${msg['deactivate/confirm']}" for="deactivate" />
</h:panelGroup>
Of course, you must have a width in order to see a difference. Your div is not needed so I removed it.

Primefaces enter key closes dialog

When the below dialog is opened and the user hits enter it closes. I'm assuming that I need to somehow add some attribute to the below commandButton to not allow it to submit when the user hits enter. Any idea?
<p:dialog header="#{bundle['dreamSearch.HEADER']}"
widgetVar="webSearchDlg" modal="true" styleClass="dialog dialog2"
draggable="false" resizable="false" showEffect="fade"
hideEffect="fade">
<h:form id="dreamWebSearchFrm">
<div class="dialog-top-reg"></div>
<div class="dialog-middle-reg">
<div><p:commandButton styleClass="close zoom3" onclick="webSearchDlg.hide()" /></div>
<div class="dialog-content dialog-content2">
<h1 class="dream-search">
<h:outputText value="#{bundle['dreamSearch.HEADER']}" />
</h1>
<p class="dream-search">
<h:outputText value="#{bundle['dreamSearch.SUBHEADER']}" />
</p>
<p:panel id="searchTextPnl">
<div class="dream-search-wrap">
<fieldset>
<p:inputText id="searchText" value="#{dreamSearchBean.searchText}"/>
<p:commandButton tabindex="-1" styleClass="form-btn1" value="#{bundle['dreamSearch.search.button.TEXT']}"
actionListener="#{dreamSearch.search}" update=":dreamWebSearchFrm:resultsPnl"/>
</fieldset>
</div>
</p:panel>
<p:panel id="resultsPnl">
<div class="data-grid-wrap">
<h:outputFormat escape="false" value="#{bundle['dreamSearch.imageResults.TEXT']}" rendered="#{dreamSearchBean.shouldRender}">
<f:param value="#{dreamSearchBean.searchText}" />
</h:outputFormat>
<p:dataGrid var="dream" value="#{dreamSearchBean.dreams}" rendered="#{dreamSearchBean.shouldRender}" columns="5"
rows="10" paginator="true" effect="true"
styleClass="ui-header-visibility"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="10,15,20" paginatorPosition="bottom">
<p:column>
<h:panelGrid columns="1" style="width:100%">
<p:commandLink onclick="webSearchDlg.hide();dreamEditDlg.show();" update=":dreamEditFrm:display">
<f:setPropertyActionListener value="#{dream}" target="#{dreamModifyBean.selectedDream}"/>
<f:setPropertyActionListener value="false" target="#{dreamModifyBean.editLink}"/>
<p:graphicImage value="#{dream.imageThumb}" width="100" height="100" />
</p:commandLink>
</h:panelGrid>
</p:column>
</p:dataGrid>
</div>
</p:panel>
</div>
</div>
<div class="dialog-bottom-reg"></div>
</h:form>
</p:dialog>
You could do it with Javascript. A similiar question with a variety of answers has been asked some time ago.
Primefaces has it's own (or some adapted JQuery / YUI) javascript bundled. Don't know how it interacts with self-made js. Give it a try!
In order to solve this, I had to ensure that the close button was the very last button within the form.