Currently I'm trying to populate the h:selectOneListbox with values from database.
My function to fetch the data findAllCriteria()
public List<String> findAllCriteria() {
try {
List<Criteria> crits = criteriaFacade().findAllByAnmeldename(getCurrentUserName(),
getCriteriaDefinition().getName());
List<String> results = new ArrayList<>();
for (Criteria crit : crits) {
results.add(crit.getId().toString());
}
return results;
} catch (BusinessException e) {
LOG.error("failed to load criteria" + e);
messageFactory().makeAndAdd(e);
return null;
}
}
this function I'm passing to my Converter criteriaToSelectItems(meldungListController.findAllCriteria())
public static List<SelectItem> criteriaToSelectItems(List<String> elements) {
List<SelectItem> items = new ArrayList<SelectItem>(elements.size());
for (String element : elements) {
items.add(new SelectItem(element, element));
}
return items;
}
as defined here:
<function>
<function-name>criteriaToSelectItems</function-name>
<function-class>de.db.udg.diagnose.udgdiag.webui.app.facelets.functions.SelectItemsFunctions</function-class>
<function-signature>java.util.List criteriaToSelectItems(java.util.List)</function-signature>
The critial part is:
<h:selectOneListbox id="critList" size="1"
value="#{meldungListController.findCriteriaById(identifier)}">
<f:selectItems
value="#{d:criteriaToSelectItems(meldungListController.findAllCriteria())}" />
</h:selectOneListbox>
I don't understand how to retrieve the Item(String) from the selected Item and how to further process it.
public Criteria findCriteriaById(String identifier) {
if (identifier.isEmpty()) {
return querySpec.getCriteria();
}
Long id = Long.valueOf(identifier);
Criteria criteria;
try {
criteria = criteriaFacade().findById(id);
} catch (BusinessException e) {
LOG.error("failed to load criteria" + e);
messageFactory().makeAndAdd(e);
return null;
}
return criteria;
}
Both functions are nested inside of #Component("meldungListController")
)
I've read through this article on SO but this is kind of limited to JSF 2.x
Upgrading my JSF Version from 1.2 to 2.x is no option.
Question
How to dynamically populate selectOneListbox in JSF 1.2 and find the value of the selected index.
In-Depth:
Listing all selectItems works, see image, but:
javax.el.PropertyNotFoundException: /pages/meldung/meldungList.xhtml #341,72 value="#{meldungListController.findCriteriaById(identifier)}": The class 'de.db.udg.diagnose.udgdiag.webui.meldung.MeldungListController' does not have the property 'findCriteriaById'.
I hope someone remembers the good old days with JSF 1.2 and can help me.
Related
Sorry if this is a basic question, as I am quite new to AEM.
I have a cq dialog allowing multiple tags to be entered.
<tags
cq:showOnCreate="{Boolean}true"
jcr:primaryType="nt:unstructured"
sling:resourceType="/libs/cq/gui/components/coral/common/form/tagfield"
allowCreate="{Boolean}true"
fieldLabel="Tags to add"
metaType="tags"
multiple="true" <====================
name="./metaData/TAGS"/>
I am trying to retrieve the two tags above in my WorkflowProcess as below:
#Component(
//...
)
public class TagStep implements WorkflowProcess {
#Override
public void execute(WorkItem workItem, WorkflowSession workflowSession, MetaDataMap processArguments) {
try {
//...
List<String> tagslist = new ArrayList();
List<String> tags = processArguments.get("TAGS",tagslist);
// Nothing logged here <=======
for (String tag: tags) {
LOG.info(tag);
}
//...
} catch (Exception e){
LOG.info("\n ERROR {} ",e.getMessage());
}
}
}
There is no output when I try to log tag in the loop above, probably the return type of List<String> cannot be converted.
What is the proper return type when using multiple="true", and how to use processArguments.get to get the values?
Btw my code was based on the tutorial here.
Thank you,
After looking into the source implementation, it is using an Array, not a List. so here is how to retrieve the passed in data.
Node node = (Node) session.getItem(path);
String[] cars = {};
String[] tags = processArguments.get("TAGS",cars);
node.setProperty("cq:tags", tags);
I have a PrimeFaces inputSwitch:
<p:inputSwitch id="snoozeSwitch" value="#{dashBController.snooze}" valueChangeListener="#{dashBController.updateSnoozeStatus}">
<p:ajax listener="#{dashBController.updateSnoozeStatus}" update="msgSnooze" />
</p:inputSwitch>
Now I want to give this switch an initial value from my DB. I get the value with:
#PostConstruct
public void init() {
if (!FacesContext.getCurrentInstance().isPostback()) {
snooze = getSnoozeStatus();
}
}
But I have trouble to update the old value with the new one.
public void updateSnoozeStatus() {
if(snooze == true) {
DBconnector.updateSnooze("true");
} else {
DBconnector.updateSnooze("false");
}
}
The problem: My app always uses the inital value and so the switch is stucking on the state it has originally. Maybe #BalusC knows the answer :)
Unless I am missing something your solution seems complex for something very simple. Why don't you just use a getter and a setter?
The getter should load the value from the database and the setter should save it. I couldn't test the code below because I don't have PF 5.0.4 but it should be a good start.
public class DashBController {
private Boolean snooze = null;
public boolean isSnooze() {
if (snooze == null) {
snooze = getSnoozeStatus();
}
return snooze;
}
public void setSnooze(boolean snooze) {
this.snooze = snooze;
DBconnector.updateSnooze(this.snooze.toString());
}
}
and simply :
<p:inputSwitch id="snoozeSwitch" value="#{dashBController.snooze}"/>
I have a function that I derclare beans in my manager and I want to return the value in inputText but when I put the name of my function in the value attribute of inputText tag like this:
<p: inputText value = "#{ticketBean.getLastIndexTache} "/>
this error appear:
Etat HTTP 500 - /pages/test.xhtml #13,106 value="#{ticketBean.getLastIndexTache}": Property 'getLastIndexTache' not found on type com.bean.TicketBean
here is the java code
#ManagedBean(name="ticketBean")
public class TicketBean {
public int getLastIndexTache() {
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
int index = 0;
try {
session.beginTransaction();
String sql = "select MAX(t.IDTICKET) from ticket t ";
Query query = session.createSQLQuery(sql);
if( query.uniqueResult()==null){
index=0;
}else{
index=(int) query.uniqueResult();
index=index+1;
}
} catch (HibernateException e) {
// TODO: handle exception
session.getTransaction().rollback();
e.printStackTrace();
}
return index;
}
}
You should use the bean property in value like
<p:inputText value="#{ticketBean.lastIndexTache}"/>
as JSF by itself adds "get" to the property name. Currently it will look for the method getGetLastIndexTache().
Besides its very bad practice to have logic in any getter as they are called multiple times by JSF. Instead you should make an property like
private Integer lastIndexTache; // +getter/setter
and set the value in a #PostConstruct method:
#PostConstruct
public void init() {
Session session = HibernateUtil.getSessionFactory().getCurrentSession();
// etc....
lastIndexTache = index;
}
The getter would then simply be
public Integer getLastIndexTache() {
return lastIndexTache;
}
and don't forget a setter:
public void setLastIndexTache(Integer newValue) {
lastIndexTache = newValue;
}
Also you should probably put a scope on the bean (for example #ViewScoped).
I have a checkbox:
<webuijsf:checkbox immediate="true" valueChangeListenerExpression="#{user$recentreports.selectSingleCBEvent}" id="selectCB" binding="#{user$recentreports.selectCB}" toolTip="#{msg.report_select}"/>
whose valueChangeListenerExpression method is:
List<RowKey> rowsToBeRemoved=new ArrayList();
public void selectSingleCBEvent(ValueChangeEvent event) throws Exception {
RowKey rowKey = tableRowGroup.getRowKey();
System.out.println("rowKey" + rowKey);
System.out.println("tableRowGroup.getRowKey().toString()" + tableRowGroup.getRowKey().toString());
rowsToBeRemoved.add(rowKey);
FacesContext.getCurrentInstance( ).renderResponse( );
}
I have a button that must be used for deleting rows that checkbox component is selected:
<webuijsf:button actionExpression="#{user$recentreports.deleteButton_action}" id="deleteButton" text="#{msg.report_delete_selected}"/>
whose backing bean is:
public String deleteButton_action() {
for(RowKey rowToBeRemoved:rowsToBeRemoved){
try {
System.out.println("rowToBeRemoved" + rowToBeRemoved);
GeneratedReport generatedReport = (GeneratedReport) reportList.getObject(rowToBeRemoved);
Query resultQuery = queryGeneration(generatedReport.getId());
List<String> dropTableQueries = resultQuery.getResultList(); // generated the queries to drop r tables
for(int i=0; i<dropTableQueries.size(); i++){
String aDropTableQuery;
aDropTableQuery = dropTableQueries.get(i); // get single drop table query
entityManager.createNativeQuery(aDropTableQuery);
reportList.removeRow(rowToBeRemoved);
reportList.commitChanges();
}
generatedReportJpaController.delete(generatedReport);
reportList.commitChanges();
analyzerResultService.drop(generatedReport.getId().longValue());
} catch (Exception e) {
error("Cannot delete report with row key " + rowToBeRemoved + e);
}
}
return null;
}
output of this form is:
[#|2011-10-17T11:47:14.304+0300|INFO|glassfishv3.0|null|_ThreadID=25;_ThreadName=Thread-1;|rowKeyRowKey[0]|#]
[#|2011-10-17T11:47:14.304+0300|INFO|glassfishv3.0|null|_ThreadID=25;_ThreadName=Thread-1;|tableRowGroup.getRowKey().toString()RowKey[0]|#]
[#|2011-10-17T11:47:14.304+0300|INFO|glassfishv3.0|null|_ThreadID=25;_ThreadName=Thread-1;|rowKeyRowKey[1]|#]
[#|2011-10-17T11:47:14.304+0300|INFO|glassfishv3.0|null|_ThreadID=25;_ThreadName=Thread-1;|tableRowGroup.getRowKey().toString()RowKey[1]|#]
which means my deleteButtonAction is reached but is not performing the actions that I write (getting rowKey from rowsToBeRemoved and deleting them), I don't understand why. Back bean is request scoped does it have any relevance?
My impression is you short-circuit JSF lifecycle by calling FacesContext.getCurrentInstance( ).renderResponse( ) in selectSingleCBEvent and your actionListener is never reached.
ValueChangeListeners for immediate inputs are called in ApplyRequestValues phase. ActionListeners are called later in InvokeApplication phase. By calling renderResponse() you skip the rest of the cycle and proceed directly to RenderResponse phase.
I have 3 test web applications, using the same model and controllers, the difference is in JSF session managed beans.
The applications A and C use JSF DataModel to retrieve items :
A JPA Query result set returns a java LIST which is then wrapped in a ListDataModel. The value of this latter is being the items displayed by PrimeFaces dataTable.
The application B uses Java LIST to retrieve items:
A JPA Query result set returns a java List which is being the value of items displayed by PrimeFaces 2.2.1 dataTable.
Sorting and filtering in application B are fully functional and fast, while in application A and C, they are deadly not.
I just want to mention that Filtering in Sorting of other Libraries like Richfaces, OpenFaces, works out of the box using this same code.
The problem also remains in PrimeFaces 3.0.0. Is this a bug?
In App B :
Code:
private List<Customer> items = null;
// remainder of code here
public List<Customer> getCustomerItems() {
if (customerItems == null) {
getPagingInfo();
customerItems = jpaController.findCustomerEntities(pagingInfo.getBatchSize(), pagingInfo.getFirstItem());
}
return customerItems;
}
In App A:
Code:
private DataModel items = null;
public PaginationHelper getPagination() {
if (pagination == null) {
pagination = new PaginationHelper(999999) {
#Override
public int getItemsCount() {
return getJpaController().getChimioCount();
}
#Override // The list of Customers is wrapped in a JSF ListDataModel
public DataModel createPageDataModel() {
return new ListDataModel(getJpaController().findCustomerEntities(getPageSize(), getPageFirstItem()));
}
};
}
return pagination;
}
/**
* this goes for the value attribute in a datatable to list all the Customer items
*/
public DataModel getItems() {
if (items == null) {
items = getPagination().createPageDataModel();
}
return items;
}
In App C:
Code:
private DataModel<Project> items;
// remainder of code here
/**
*The ListDataModel is initialized here
*/
public void init() {
try {
setProjectList(doInTransaction(new PersistenceAction<List<Project>>() {
public List<Project> execute(EntityManager em) {
Query query = em.createNamedQuery("project.getAll");
return (List<Project>) query.getResultList();
}
}));
} catch (ManagerException ex) {
Logger.getLogger(ProjectManager.class.getName()).log(Level.SEVERE, null, ex);
}
projectItems = new LinkedList<SelectItem>();
projectItems.add(new SelectItem(new Project(), "-- Select one project --"));
if (getProjectList() != null) {
projects = new ListDataModel<Project>(getProjectList());
for (Project p : getProjectList()) {
projectItems.add(new SelectItem(p, p.getName()));
}
}
}
Thank you in advance for your help.
This might be a PrimeFaces bug. I have seen some discussion about issues with DataTable sorting when a data model is used. Here is a link to one of the PrimeFaces defects in their tracker.