I have a primafaces ring.I want to take images in xhtml codes.I have a papers library include images(paper1.jpg,paper2.jpg,..paper12.jpg). I don't want to use ringview.java.I added graphicimage tags between p:ring tags.But I don't display images.How can I do?
<h:form id="form">
<p:ring id="custom" value="#{ringView.papers}" var="paper">
<p:graphicImage id="img" name="papers/#{paper}" style="width:100%; height:100%"/>
</p:ring>
</h:form>
RingView.java
#ManagedBean
public class RingView implements Serializable {
private List<String> papers;
private String selectedPaper;
#PostConstruct
public void init() {
papers = new ArrayList<String>();
for (int i = 1; i <= 12; i++) {
papers.add("paper" + i + ".jpg");
}
}
public List<String> getPapers() {
return papers;
}
public void setPapers(List<String> papers) {
this.papers = papers;
}
public String getSelectedPaper() {
return selectedPaper;
}
public void setSelectedCar(String selectedPaper) {
this.selectedPaper = selectedPaper;
}
}
I tried something like:
<h:form id="form">
<p:ring id="custom">
<p:graphicImage id="img1" name="papers/paper1.jpg" style="width:100%; height:100%"/>
<p:graphicImage id="img2" name="papers/paper2.jpg" style="width:100%; height:100%"/>
<p:graphicImage id="img3" name="papers/paper3.jpg" style="width:100%; height:100%"/>
</p:ring>
Related
I've a dataTable within a dataTable. The initial dataTable has a list of components that appear on the page. One of these components will be a list of strings which can have elements added or deleted. When I change a string in this list, I expect the value to show up in the bean and it is not.
Below I have an example of my problem. The page renders a text input field for the first component then three text input fields to represent the second component which is a list of three input fields.
I have valueChange listener on all the input fields. The listener, is in the InnerBean class, prints out the source and the value that changed.
For the standalone input field, the listener correctly prints out the changed value and shows that the bean has been updated with this value. For any of the input fields from the list, the listener prints out the previous value of the input field and the bean has not been updated. On the ajax update of the inner datatable, the changed value is replace with the original value.
Since the valueChange listener is called, it appears that Primefaces knows that the value has changed. The code just doesn't seem to record the changed value.
Any help is appreciated.
I'm using Primefaces 8.0 and JSF 2.2.20.
Here is the xhtml:
<p:panel id="testPanel" header="#{myController.outerBean.name}" toggleable="true" collapsed="false" >
<p:dataTable id="testTable" value="#{myController.outerBean.innerBeanList}" var="bean">
<p:column >
<!-- TEXT COMPONENT-->
<h:panelGroup rendered="#{bean.type eq 'text'}" >
<p:inputText id="textfield" value="#{bean.value}" style="width:100%;" >
<p:ajax event="valueChange" listener="#{bean.textListListener}" update="testTable" />
</p:inputText>
</h:panelGroup>
<!-- LIST COMPONENT -->
<h:panelGroup rendered="#{bean.type eq 'textlist'}" >
<p:dataTable id="testListTable" styleClass="datatableWithoutBorder" style="width:320px"
var="textAddition" value="#{bean.list}" rowIndexVar="rowIndex" >
<p:column >
<p:inputText id="textAdd" value="#{textAddition}" style="width: 100%;">
<p:ajax event="valueChange" listener="#{bean.textListListener}" update="testListTable"/>
</p:inputText>
</p:column>
</p:dataTable>
</h:panelGroup>
</p:column>
</p:dataTable>
<h:panelGrid columns="1" style="width:100%;">
<h:panelGroup style="float:right">
<p:commandButton id="submitBtn" value="Submit"
action="#{dummyController.submit}"
update="messages #this"
icon="fa fa-save"/>
</h:panelGroup>
</h:panelGrid>
</p:panel>
My controller code:
public class MyController {
private OuterBean outerBean;
public MyController() {
System.out.println("MyController instantiated");
setOuterBean(new OuterBean());
}
public void submit() {
for (InnerBean ab: outerBean.getInnerBeanList()) {
System.out.println(ab.getLabel() + ": " + ab.getValue() + ":" + ab.getList() );
}
}
public void clear() {
// TODO
}
// Getter/Setter methods
public OuterBean getOuterBean() {
return outerBean;
}
public void setOuterBean(OuterBean outerBean) {
this.outerBean = outerBean;
}
}
My OuterBean with the list of components:
public class OuterBean implements Serializable {
private String name;
private String value;
private List<InnerBean> innerBeanList;
public OuterBean() {
name = "Entry Panel #1";
value = "";
innerBeanList = new ArrayList<InnerBean>();
InnerBean ab1 = new InnerBean();
ab1.setLabel("First Component");
ab1.setType("text");
ab1.setValue("Input text");
innerBeanList.add(ab1);
InnerBean ab2 = new InnerBean();
ab2.setLabel("Second Component");
ab2.setType("textlist");
ArrayList<String> list = new ArrayList<String>();
list.add("Item 1");
list.add("Item 2");
list.add("Item 3");
ab2.setList(list);
innerBeanList.add(ab2);
}
//
// Getter/Setters
//
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public List<InnerBean> getInnerBeanList() {
return innerBeanList;
}
public void setInnerBeanList(List<InnerBean> innerBeanList) {
this.innerBeanList = innerBeanList;
}
}
My InnerBean which represents a component to be render. One of which can be a list of strings:
public class InnerBean implements Serializable {
// Type of component
public static final String TEXT = "text";
public static final String TEXTLIST = "textlist";
private String label;
private String type; // If TEXT, use value; if TEXTLIST, use list.
private String value;
private List<String> list = new ArrayList<String>();
public InnerBean() {
}
public void textListListener(AjaxBehaviorEvent event) {
System.out.println("Listener called");
System.out.println(" Source: " + event.getSource().toString());
System.out.println(" Value: " + ((UIInput)event.getSource()).getValue());
System.out.println(" List: " + list.toString());
System.out.println(" Event: " + event.toString());
}
//
// Setters and getters
//
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
public List<String> getList() {
return list;
}
public void setList(List<String> list) {
this.list = list;
}
}
I am trying to filter using a Select One Menu using PrimeFaces 6.1. But the menu does not drop down to show its values. It acts as if it is disabled. I have wrapped my datable with <h:form> and checked to see if the menu is populated in the browser inspect window.
Edit:
Here is the table:
<h:form>
<p:dataTable var="left" value="#{dataFilterView.leftGrid}"
widgetVar="leftTable"
filteredValue="#{dataFilterView.filteredLeftGrid}">
<ui:debug />
<p:column headerText="Project">
<h:outputText value="#{left.projectName}" />
</p:column>
<p:column headerText="Company">
<h:outputText value="#{left.companyName}" />
</p:column>
<p:column headerText="Location" filterBy="left.projectLocation">
<h:outputText value="#{left.projectLocation}" />
</p:column>
<p:column headerText="Request Name">
<h:outputText value="#{left.requestName}" />
</p:column>
<p:column headerText="Request Type" filterBy="#{left.requestType}"
filterMatchMode="exact">
<f:facet name="filter">
<p:selectOneMenu onchange="PF('leftTable').filter()"
style="width:70%; box-sizing: border-box;">
<f:selectItem itemLabel="Select One" itemValue="#{null}"
noSelectionOption="true" />
<f:selectItems
value="#{dataFilterView.uniqueRequestTypes.entrySet()}"
var="data" itemValue="#{data.key}" itemLabel="#{data.value}" />
</p:selectOneMenu>
</f:facet>
<h:outputText value="#{left.requestType}" />
</p:column>
</p:dataTable>
</h:form>
The ManagedBean is:
#ManagedBean(name = "dataFilterView")
#SessionScoped
public class DataFilterView {
private String reqType;
private List<LeftGridBean> leftGrid;
private List<LeftGridBean> filteredLeftGrid;
private List<String> uniqueLocations;
private Map<String, String> uniqueRequestTypes;
#ManagedProperty("#{supplierRequestsService}")
private SupplierRequestsService service;
#PostConstruct
public void init() {
leftGrid = service.populateLeftGrid();
}
public void setService(SupplierRequestsService service) {
this.service = service;
}
public List<LeftGridBean> getLeftGrid() {
return leftGrid;
}
public List<LeftGridBean> getFilteredLeftGrid() {
return filteredLeftGrid;
}
public void setFilteredLeftGrid(List<LeftGridBean> filteredLeftGrid) {
this.filteredLeftGrid = filteredLeftGrid;
}
public String getReqType() {
return reqType;
}
public void setReqType(String reqType) {
this.reqType = reqType;
}
public List<String> getUniqueLocations() {
Set<String> locations = new HashSet<>();
for (LeftGridBean lg : getLeftGrid()) {
locations.add(lg.getProjectLocation());
}
uniqueLocations = new ArrayList<String>(locations);
return uniqueLocations;
}
public Map<String, String> getUniqueRequestTypes() {
Map<String, String> requestTypes = new HashMap<>();
for (LeftGridBean lg : getLeftGrid()) {
requestTypes.put(lg.getRequestType(), lg.getRequestType());
}
uniqueRequestTypes = requestTypes;
return uniqueRequestTypes;
}
}
Domain:
public class LeftGridBean {
private String projectName;
private String projectLocation;
private String requestType;
private String requestName;
private String companyName;
public String getProjectLocation() {
return projectLocation;
}
public void setProjectLocation(String projectLocation) {
this.projectLocation = projectLocation;
}
public String getRequestType() {
return requestType;
}
public void setRequestType(String requestType) {
this.requestType = requestType;
}
public String getRequestName() {
return requestName;
}
public void setRequestName(String requestName) {
this.requestName = requestName;
}
public String getProjectName() {
return projectName;
}
public void setProjectName(String projectName) {
this.projectName = projectName;
}
public String getCompanyName() {
return companyName;
}
public void setCompanyName(String companyName) {
this.companyName = companyName;
}
}
and finally the service:
#ManagedBean(name="supplierRequestsService")
#SessionScoped
public class SupplierRequestsService {
#ManagedProperty("#{userManager}")
private UserManager usr;
public List<LeftGridBean> populateLeftGrid() {
List<LeftGridBean> lgbList = usr.getSupplierLeftGridData();
return lgbList;
}
public List<RightGridBean> populateRightGrid() {
List<RightGridBean> rgbList = usr.getSupplierRightGridData();
return rgbList;
}
public void setUsr(UserManager usr) {
this.usr = usr;
}
}
Environment:
PrimeFaces 5.1
Mojarra 2.2.2
Spring 4.0.2
Problem:
I use a p:dataTable with lazy=true and I have implemented a LazyDataModel.
All works perfectly well (pagination, filtering, etc.), but it is very slow...
The load method is called, it performes the call to the DB and returns in 3sec max. But after that, it takes up to 20sec for the page to load (render?)...
For information, the page loads through ajax: a listener give informations to the LazyModel (setters), then change the page to insert (ui:insert, value stored in the controller), and finally update the form (update=":form").
After debugging it seems that I have no control on this...
Code:
<p:dataTable id="storeTable"
value="#{dashboard.stores}"
var="store"
lazy="true"
paginator="true" rows="30"
paginatorTemplate="{FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink}"
paginatorPosition="bottom">
...
<!-- Columns -->
...
<c:forEach var="date" items="#{dashboard.days}">
<c:set var="day" value="#{store.getDay(date)}"/>
<p:column styleClass="store-day open-#{store.isAmOpen(date.date)} store-day-available-#{store.isAvailable(date.date)} #{store.storeKey} #{day.date.time} am"
width="30">
<h:outputText value=" " title="#{day.amComment}" />
<h:outputText styleClass="store" value="#{store.storeKey}" style="display: none" />
<h:outputText styleClass="date" value="#{day.date.time}" style="display: none" />
<h:outputText styleClass="am_pm" value="am" style="display: none" />
</p:column>
<p:column styleClass="store-day open-#{store.isPmOpen(date.date)} store-day-available-#{store.isAvailable(date.date)} #{store.storeKey} #{day.date.time} pm"
width="30">
<h:outputText value=" " title="#{day.pmComment}" />
<h:outputText styleClass="store" value="#{store.storeKey}" style="display: none" />
<h:outputText styleClass="date" value="#{day.date.time}" style="display: none" />
<h:outputText styleClass="am_pm" value="pm" style="display: none" />
</p:column>
</c:forEach>
</p:dataTable>
Relevant code of the controller:
#Controller("dashboard")
#Scope("session")
public class DashboardController implements Serializable {
private static final long serialVersionUID = 1971543164359627877L;
private LazyStoreWebModel stores;
// Some more attributes
#PostConstruct
public void postCtr() {
stores = new LazyStoreWebModel(restit);
update();
}
private void updateGroupList() {
groupList.clear();
groupList.addAll(groupDao.findByCountry(countryFilter));
}
public void updateStoreChainTypeList() {
storeChainTypeList.clear();
storeChainTypeList.addAll(storeTypeDao.findByCountry(countryFilter));
}
public void updateStoreZoneList() {
storeZoneList.clear();
storeZoneList.addAll(storeZoneDao.findByCountryAndChainType(
countryFilter, chainTypeFilter));
}
public void updateStoreRegionList() {
storeRegionList.clear();
if (storeZoneFilter != null) {
storeRegionList.addAll(storeRegionDao.findByCountryAndZone(
countryFilter, storeZoneFilter));
}
}
public void updateDays() {
days.clear();
days.addAll(calendar.generateListDateFromMonthAndYear(
yearFilter, monthFilter.getCode()));
stores.setYear(yearFilter);
stores.setMonth(monthFilter.getCode());
Collections.sort(days);
}
public void update() {
updateGroupList();
updateStoreChainTypeList();
updateStoreZoneList();
updateStoreRegionList();
updateDays();
stores.setCountry(countryFilter);
stores.setChainType(chainTypeFilter);
stores.setRegion(storeRegionFilter);
stores.setZone(storeZoneFilter);
}
public LazyDataModel<StoreWeb> getStores() {
return stores;
}
}
The LazyDataModel
public class LazyStoreWebModel extends LazyDataModel<StoreWeb> {
private static final long serialVersionUID = -4318420518897167924L;
private RestitService restit;
private Country country;
private StoreChainType chainType;
private StoreZone zone;
private StoreRegion region;
private Integer storeIntFlagFilter;
private Integer year;
private Integer month;
public LazyStoreWebModel(RestitService restit) {
this.restit = restit;
}
#Override
public StoreWeb getRowData(String key) {
try {
return restit.visualisationStoreById(key, year, month);
} catch (CalendarException e) {
e.printStackTrace();
} catch (NotExistStoreException e) {
e.printStackTrace();
}
StoreWeb sto = new StoreWeb();
sto.setStoreDesc("Should be null");
sto.setStoreKey("NULL:" + key);
return sto;
}
#Override
public Object getRowKey(StoreWeb sto) {
return sto.getStoreKey();
}
#Override
public List<StoreWeb> load(int first, int pageSize, String sortField,
SortOrder sortOrder, Map<String, Object> fieldFilters) {
List<StoreWeb> result = new ArrayList<StoreWeb>();
Map<String, Object> mainFilters = new HashMap<String, Object>();
mainFilters.put(RestitService.COUNTRY_KEY, country);
mainFilters.put(RestitService.CHAIN_TYPE_KEY, chainType);
mainFilters.put(RestitService.ZONE_KEY, zone);
mainFilters.put(RestitService.REGION_KEY, region);
mainFilters.put(RestitService.INT_FLAG_KEY, storeIntFlagFilter);
mainFilters.put(RestitService.YEAR_KEY, year);
mainFilters.put(RestitService.MONTH_KEY, month);
try {
result.addAll(restit.load(first, pageSize, sortField, sortOrder,
mainFilters, fieldFilters));
} catch (CalendarException e) {
e.printStackTrace();
} catch (NotExistStoreException e) {
e.printStackTrace();
}
setRowCount(restit.count(mainFilters, fieldFilters));
return result;
}
}
The restit attribute do the calls to the DB.
Any idea?
Thanks.
Edits:
Added relevant code of the controller
Added code of the LazyDataModel
Added code inside the HTML: Problem seems to come from the amount of columns (60+), more precisely from the quantity of attribute access done to build those.
I do have a page, where I have a list of rich:collapsiblePanel that hold input elements. These collapsiblePanels themselves store their expanded/collapsed state within a backing bean.
Now I have the use case to Open/Close all of these collapsiblePanels at once, with one mouse click. So I have tried to achieve this with the two commandButtons over the list. These use the attached actionListener to iterate over all backing beans of the collapsiblePanels and set the expanded flag to true/false.
This seems to work, unless you Open or Close one of the collapsiblePanels on their own. As soon as that happens clicking the buttons does not do anything anymore.
<h:form prependId="false">
<a4j:commandButton value="Open All" actionListener="#{viewBean.doOpenAll}" render="c" />
<a4j:commandButton value="Close All" actionListener="#{viewBean.doCloseAll}" render="c" style="margin-left: 10px;" />
<a4j:outputPanel id="c">
<a4j:repeat id="repeat" value="#{viewBean.items}" var="item">
<rich:collapsiblePanel id="panel" expanded="#{item.expanded}">
<h:outputLabel id="text_lbl" value="text" />
<h:inputText id="text" value="#{item.text}" />
</rich:collapsiblePanel>
</a4j:repeat>
</a4j:outputPanel>
</h:form>
I have published a project on github so that you can try around with the code.
For completeness here are the two backing beans
#ViewScoped
#ManagedBean
public class ViewBean implements Serializable {
static final Logger LOG = LoggerFactory.getLogger(ViewBean.class);
private static final long serialVersionUID = -6239437588285327644L;
private List<ListItem> items;
public ViewBean() {
items = new ArrayList<ListItem>(10);
for (int i = 0; i < 10; i++) {
items.add(new ListItem("item " + i));
}
}
public void doOpenAll() {
LOG.debug("open all");
for (ListItem item : items) {
item.setExpanded(true);
}
}
public void doCloseAll() {
LOG.debug("close all");
for (ListItem item : items) {
item.setExpanded(false);
}
}
public List<ListItem> getItems() {
return items;
}
}
public class ListItem {
private boolean expanded;
private String text;
public ListItem(String text) {
super();
this.text = text;
}
public boolean isExpanded() {
return expanded;
}
public void setExpanded(boolean expanded) {
this.expanded = expanded;
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
}
}
This may be related to this RichFaces bug?!: https://issues.jboss.org/browse/RF-11546
I have table Providers.I am displaying the table contents in primefaces datatable and performing create,edit and delete operations on it using Jdbc and Tomcat 7.0.
In the edit dialog there are save and cancel buttons. When I click the cancel button and click on the edit button of another row the values of previous row are getting displayed.
I am getting the following warnings when I click on the cancel button:
com.sun.faces.application.view.FaceletPartialStateManagementStrategy saveDynamicActions
WARNING: Unable to save dynamic action with clientId 'editproviderform:btnCancelProviders' because the UIComponent cannot be found
Providers table structure:
ProviderId,
ProviderFirstName and
ProviderLastName
Providers.java
public class Providers implements Serializable {
private static final long serialVersionUID = 1L;
private Integer providerId;
private String providerFirstName;
private String providerLastName;
public Providers() {
}
public Providers(Integer providerId) {
this.providerId = providerId;
}
public Providers(Integer providerId, String providerFirstName, String providerLastName) {
this.providerId = providerId;
this.providerFirstName = providerFirstName;
this.providerLastName = providerLastName;
}
public Integer getProviderId()
{
return providerId;
}
public void setProviderId(Integer providerId)
{
this.providerId=providerId;
}
public String getProviderFirstName()
{
return providerFirstName;
}
public void setProviderFirstName(String providerFirstName)
{
this.providerFirstName=providerFirstName;
}
public String getProviderLastName()
{
return providerLastName;
}
public void setProviderLastName(String providerLastName)
{
this.providerLastName=providerLastName;
}
}
ProvidersBean.java
#ManagedBean(name = "providersBean")
#SessionScoped
public class ProvidersBean implements Serializable {
private Providers selectedProvider;
public Providers getSelectedProvider() {
return selectedProvider;
}
public void setSelectedProvider(Providers selectedProvider) {
this.selectedProvider = selectedProvider;
}
private Connection con;
#Resource(name = "jdbc/abc")
private DataSource ds;
public ProvidersBean() {
try {
Context ctx = new InitialContext();
ds = (DataSource) ctx.lookup("java:comp/env/jdbc/ClinicalStudy");
} catch (NamingException e) {
e.printStackTrace();
}
}
public void updateProvider() {
try {
con = ds.getConnection();
PreparedStatement ps = con.prepareStatement("UPDATE Providers SET
ProviderFirstName=?,ProviderLastName=? WHERE ProviderId=?");
ps.setString(1, selectedProvider.getProviderFirstName());
ps.setString(2, selectedProvider.getProviderLastName());
ps.setInt(3, selectedProvider.getProviderId());
ps.executeUpdate();
clearSelectedProvider();
ps.close();
con.close();
} catch (SQLException e) {
System.out.println("SQLException:" + e.getMessage());
}
}
#PostConstruct
public void init()
{
selectedProvider=new Providers();
}
public void clearSelectedProvider()
{
selectedProvider = null;
}
public void close(CloseEvent event)
{
event.getComponent().getChildren().clear();
clearSelectedProvider();
}
}
Edit dialog code
<p:dialog id="_EditProvider" header="Edit Provider" widgetVar="EditProvider" modal="true"
showEffect="fade" hideEffect="fade" resizable="false" position="center"
appendToBody="true">
<p:ajax event="close" listener="#{providersBean.close}"
update=":editproviderform" global="false"/>
<h:form id="editproviderform">
<p:panelGrid columns="2" rendered="#{not empty providersBean.selectedProvider}">
<h:outputLabel for="EdtProviderFirstName" value="ProviderFirstName*:"/>
<p:inputText id="EdtProviderFirstName" value="#{providersBean.selectedProvider.providerFirstName}"
required="true" requiredMessage="FirstName must be entered" maxlength="30"
validatorMessage="FirstName must be an alphanumeric value">
<f:validateRegex pattern="[a-zA-Z0-9\s]+"/>
</p:inputText>
<h:outputLabel for="EdtProviderLastName" value="ProviderLastName*:"/>
<p:inputText id="EdtProviderLastName" value="#{providersBean.selectedProvider.providerLastName}"
required="true" requiredMessage="LastName must be entered" maxlength="30"
validatorMessage="LastName must be an alphanumeric value">
<f:validateRegex pattern="[a-zA-Z0-9\s]+"/>
</p:inputText>
<p:commandButton id="btnUpdateProvider" value="Save" actionListener="#{providersBean.updateProvider()}"
update=":providersform:providersdt :providersmessages:messages" oncomplete="handleEditProviders(xhr,status,args)"/>
<p:commandButton id="btnCancelProviders" value="Cancel" actionListener="#{providersBean.clearSelectedProvider()}"
oncomplete="EditProvider.hide()"/>
</p:panelGrid>
</h:form>
</p:dialog>
Below is the code for the edit button in datatable:
<p:column style="text-align: center;">
<p:commandButton id="btneditproviders" value="Edit" update=":editproviderform" oncomplete="EditProvider.show()" title="Edit">
<f:setPropertyActionListener value="#{item[0]}" target="#{providersController.selectedProvider}"/>
</p:commandButton>
</p:column>