add only one value to a picklist target (PrimeFaces) - jsf-2

I have a search function which searches the system. After performing search I am updating the search result in to pick List. Each Time I search I will update pickList source. Now My problem is I want to validate in such a way that if more than 1 value is added to the pick list target It should give me error message and also check about the duplicate entries in picklist target.
Below is the code of picklist in xhmtl
<p:pickList id="primaryContactBean" value="#{addSystemManagedBean.primaryContactList}" var="contact" itemLabel="#{contact.firstName}" itemValue="#{contact}" converter="contactConverter" >
<p:ajax event="transfer" listener="#{addSystemManagedBean.onTransfer}" process="#this" update="sysMsg3" />
<p:column>
#{contact.firstName} #{contact.lastName}
</p:column>
</p:pickList>
and onTransfer the following method gets called
public int primaryOwnerCount = 0;
public void onTransfer(TransferEvent event) {
PickList picklist = (PickList) event.getComponent();
for(Object item : event.getItems()) {
ContactBean cb = (ContactBean)item;
if(picklist.getId().equals("primaryContactBean")){
if(event.isAdd())
primaryOwnerCount++;
if(primaryOwnerCount>1){
FacesContext.getCurrentInstance().addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,"Only one primary owner can exist!!","If you want to add owner, please remove from the list and then proceed.."));
for (Iterator iterator = primaryContactList.getTarget().iterator(); iterator
.hasNext();) {
ContactBean type = (ContactBean) iterator.next();
System.out.println("target:"+type.getFirstName());
}
}
else
primaryContactTarget.add(cb);
}

Related

Is it possible to have a richfaces:pickList with a search box?

I have a use case where I plan to have a rich:pickList so that a user can pick multiple items from a list. But, in few cases the number of items in pickList are too large(in hunderds and sometimes in thousands) and it is not practical for the user to scroll the whole length down. So, is there a way i can have a search box above the lefthand side list of the pickList? It should be similar to that of the autoComplete component so that there are always 10 items in the pickList, which are the closest matches of the keywords entered in the search box.
I use richfaces 4 and JSF 2.0.
What about this?
Page:
<h:inputText value="#{bean.prefix}">
<a4j:ajax event="keyup" render="list" />
<a4j:ajax event="focus" oncomplete="saveList()" />
</h:inputText>
<a4j:region>
<rich:pickList id="list" value="#{bean.selectedList}">
<f:selectItems value="#{bean.filteredList}" var="str" itemLabel="#{str}" itemValue="#{str}" />
</rich:pickList>
</a4j:region>
<a4j:jsFunction name="saveList" execute="list" />
Bean:
// fullList - contains everything
public List<String> getFilteredList() {
List<String> filteredList = new ArrayList<String>();
Set<String> filteredSet = new TreeSet<String>();
for (String s : fullList) {
if (s.startsWith(getPrefix())) {
filteredSet.add(s);
}
if (filterSet.size() > 9) {
break;
}
}
filteredSet.addAll(selectedList);
// we need to add the selected items so they would be rendered
// target list needs to be a subset of the source list
filteredList.addAll(filteredSet);
return filteredList;
}

PrimeFaces DataTable Enum filtering

I am using PF 3.4 and trying to filter a column which has enum value. I am using jsf 2.0's enum converter. But filtering does not work for me here is the sample code :
<p:dataTable id="projeTeklifiListesiDataTable"
value="#{controller.model.projeTeklifiListesi}"
var="proje" paginator="true" rowKey="#{proje.id}"
rows="50"
selection="#{controller.model.secilenProjeTeklifi}"
selectionMode="single" styleClass="defaultList">
<p:column headerText="#{etiket['pfdy_hzrl_vt013']}"
filterBy="#{projeTeklifi.projeTeklifiDurumu}"
filterOptions="#{controller.model.projeTeklifiDurumuListesi}"
sortBy="#{projeTeklifi.projeTeklifiDurumu.toString()}">
#{proje.projeTeklifiDurumu.toString()}
</p:column>
<p:column headerText="#{etiket['pfdy_dkd_vt010']}" filterBy="#{projeTeklifi.basariDurumu}"
filterOptions="#{controller.model.basariDurumuListesi}"
sortBy="#{projeTeklifi.basariDurumu.toString()}">
#{proje.basariDurumu.toString()}
</p:column>
</p:dataTable>
this are the lists for the filter options
public SelectItem[] getProjeTeklifiDurumuListesi()
{
final ProjeTeklifiDurumu[] durumListesi = ProjeTeklifiDurumu.values();
final SelectItem[] projeTeklifiDurumListesi = new SelectItem[durumListesi.length+1];
projeTeklifiDurumListesi[0] = new SelectItem("", "Seçiniz");
for(int i =0;i<durumListesi.length;i++)
{
final SelectItem select = new SelectItem(ProjeTeklifiDurumu.valueOf(durumListesi[i].name()),durumListesi[i].toString());
projeTeklifiDurumListesi[i+1]=select;
}
return projeTeklifiDurumListesi;
}
public SelectItem[] getBasariDurumuListesi()
{
final BasariDurumu[] durumListesi = BasariDurumu.values();
final SelectItem[] projeTeklifiDurumListesi = new SelectItem[durumListesi.length+1];
projeTeklifiDurumListesi[0] = new SelectItem("", "Seçiniz");
for(int i =0;i<durumListesi.length;i++)
{
final SelectItem select = new SelectItem(durumListesi[i],durumListesi[i].toString());
projeTeklifiDurumListesi[i+1]=select;
}
return projeTeklifiDurumListesi;
}
I have tried with different value bindings for SelectedItem class bind the enum itself, bind the name of the enum, called toString() method but it does not filter. I can see that my value binding of the filter option is posted correctly but does not filters the data.
Any clue would be helpful.
Thank you.
Look at org.primefaces.component.datatable.DataHelper
void decodeFilters(FacesContext context, DataTable table) {
...
String columnValue = String.valueOf(column.getValueExpression("filterBy").getValue(context.getELContext()));
...
}
They are decoding the value as is, so no converter will be used i think.

h:SelectOneMenu onchange event not working

i have two oneSelectMenu loaded with default values based on login Details,then second selectonemenu should load value based on first selectonemenu's onchangeEvent menu.i tried to clear the default value before onchange event but the value remains and doesn't work with onchange event.
<h:selectOneMenu id="blS" value="#{BoardAction.serviceAreaId}" >
<f:ajax event="valueChange" render="blSearchFacilityInput" listener="#{BoardAction.svaValueChangeEvent}"/>
<f:selectItems value="#{BoardAction.serviceAreaList}" var="c" itemLabel="#{c.svaCode}" itemValue="#{c.id}"/> </h:selectOneMenu>
<h:selectOneMenu id="blSearchFacilityInput" value="#{BoardAction.facilityId}"> <f:ajax event="valueChange" render="blSearchSectorInput" listener="#{BoardAction.facValueChangeEvent}"/>
<f:selectItems value="#{BoardAction.svaFaciltyList}" var="c" itemLabel="#{c.facCode}" itemValue="#{c.id}"/></h:selectOneMenu>
ActionBean :
private List<FacilityEBean> svaFaciltyList=null;
public List<FacilityEBean> getSvaFaciltyList() {
svaFaciltyList = facilityBusServ.getFacilityListBySVAId(session.getLoginUser());
return svaFaciltyList;
}
public List<FacilityEBean> svaValueChangeEvent(){
if(svaFaciltyList!=null){
svaFaciltyList.clear();
svaFaciltyList=null;
}
svaFaciltyList = facilityBusServ.getFacilityList(Integer.parseInt(serviceAreaId));
return svaFaciltyList;
}
Your code logic flow is wrong. You seem to expect that input components are in some way directly bound to properties and that the ajax action listener methods can return (changed) property values. This is thus actually not true.
For example, the EL expression #{BoardAction.serviceAreaList} actually invokes the getter method for the property. In your particular case, the getter method fills the list with the results from the DB everytime. So whatever you're setting in the ajax listener method is overridden everytime by the business logic in the getter method.
Those getter methods should not contain business logic at all. You need to rewrite your code as follows:
private List<FacilityEBean> svaFaciltyList;
#PostConstruct
public void init() {
svaFaciltyList = facilityBusServ.getFacilityListBySVAId(session.getLoginUser());
}
public void svaValueChangeEvent() {
svaFaciltyList = facilityBusServ.getFacilityList(Integer.parseInt(serviceAreaId));
}
public List<FacilityEBean> getSvaFaciltyList() {
return svaFaciltyList;
}

ValueChangeListener not working with <selectOneMenu> containing a null value

I've got a <selectOneMenu> with a list of objects, the first one is null (to allow "no selection" option), the problem is that when the "no selection" option is chosen, the valueChangeListener set in the is not fired.
I would like this to be able to clear a dataTable from it's content:
1) 1 object, not null, is selected -> display relevant data in the
2) the "no selection" option is selected, clear the table.
here is my code:
<h:selectOneMenu id="flowSelectionFilter"
value="#{errorController.flowSelectionFilter}" onchange="submit()"
valueChangeListener="#{errorController.changeFlow}">
<f:selectItems
value="#{errorController.flowSelectionFilterValues}"
var="flowFilter" itemLabel="#{flowFilter}" />
</h:selectOneMenu>
public String changeFlow(ValueChangeEvent event) throws Glossat2Exception {
if (glossaryVersionSelectionFilter == null) {
glossaryVersionSelectionFilter = new GlossaryVersionSelectionFilter(this.errorBean.getSelectedGlossaryVersion());
}
flowSelectionFilter = flowSelectionFilterMap.get(event.getNewValue());
errorBean.setSelectedFlow(flowSelectionFilter.getFlowWithAction());
return loadErrorsList(glossaryVersionSelectionFilter.getGlossaryVersion(), flowSelectionFilter.getFlowWithAction(), errorBean.getSelectedData());
}
the method is fired when any other object than null is selected.
thanks for your help

ZK set selected item after AnnotateDataBinder loadAll()

I'm new to ZK. I have a Listbox with a List as model. When I receive an update event I update the information in the model and then I update the UI using
AnnotateDataBinder binder = (AnnotateDataBinder) vesselsList.getPage().getAttribute("binder");
if (binder != null) {
binder.loadAll();
}
The problem is that after the update, in the following code
List updatedObjects = object.getItems();
for (Object obj : updatedObjects) {
Listitem data = (Listitem) obj;
Object ob = data.getValue();
The data.getValue() is always null.
I have search the internet for many days and I found that the binder launches an onInitRenderLater event after load everything but I can't manage to make it work.
My intent is if I have an item selected before the update,I want it to remain selected and the binder.loadAll().
Did you setValue to your items with annotated databinding ?
<listitem value="#{bean.data}" > .... </listitem>
In zul I made
<listbox model="#{objects_model}" id="objectsList"
and in Java I call the method
public void onAfterRender$objectsList(Event event) {
// select item here after the listbox has been rendered
}
it did the trick

Resources