This is my class as model which have 2 lists as key value pairs. One sample consists of many key value pairs. And I want to iterate this sample's list on view of the same bean class.
public class Sample {
List<String> sampleKey;
List<String> sampleValue;
boolean editable;
public Sample(List<String> sampleKey, List<String> sampleValue) {
this.sampleKey = sampleKey;
this.sampleValue = sampleValue;
}
public boolean isEditable() {
return editable;
}
public void setEditable(boolean editable) {
this.editable = editable;
}
public List<String> getsampleKey() {
return sampleKey;
}
public void setsampleKey(List<String> sampleKey) {
this.sampleKey = sampleKey;
}
public List<String> getsampleValue() {
return sampleValue;
}
public void setsampleValuee(List<String> sampleValue) {
this.sampleValue = sampleValue;
}
}
public ArrayList<Sample> sampleList;
Sample sam = null;
sampleList = new ArrayList<Sample>();
List<Map.Entry<String, List<String>>> entryList = new ArrayList<>(records.entrySet());
for (int j = 0; j < maxSamples; j++) {
ArrayList<String> sampleKey = new ArrayList<>();
ArrayList<String> sampleValue = new ArrayList<>();
for (int i = 7; i < records.size(); i++) {
List<String> sample = entryList.get(i).getValue();
if (!sample.isEmpty()) {
sampleKey.add(keyList.get(i));
if (!sample.get(j).isEmpty()) {
sampleValue.add(sample.get(j));
}
}
}
sam = new Sample(sampleKey, sampleValue);
sampleList.add(sam);
}
Now here is my view of same bean class:
<ui:repeat value="#{dataEntryFormController.sampleList}"
var="key" varStatus="recordMetadata">
<h:dataTable
value="#{dataEntryFormController.sampleList[recordMetadata.index]}"
var="o" binding="#{table}">
<h:column>
<h:inputText value="#{o.sampleKey[table.rowIndex]}" size="10" rendered="#{o.editable}" />
<h:outputText value="#{o.sampleKey[table.rowIndex]}" rendered="#{not o.editable}" />
</h:column>
<h:column>
<h:inputText value="#{o.sampleValue[table.rowIndex]}" size="20"rendered="#{o.editable}" />
<h:outputText value="#{o.sampleValue[table.rowIndex]}" rendered="#{not o.editable}" />
</h:column>
</h:dataTable>
</ui:repeat>
In my JSF page, I want to bind that list of list to view for iterating over a number of samples and each sample may have many key value pairs. With the above code, I can only print 1 key value pair at a time.
I am having issue in binding.
Related
I'm trying to get a list to show in datatable from managed bean to JSF page but it doesn't work.
it's telling me " not records found " .
JSF managed bean :
#ManagedBean
#RequestScoped
public class TestController {
private List<Rhnom> list = new ArrayList<Rhnom>();
#SuppressWarnings("serial")
private List<String> list2 = new ArrayList<String>() {{
add("s1");
add("s2");
add("s3");
}};
//getters and setters
JSF page :
<p:dataTable value="#{tesController.list2}" var="type">
<p:column headerText="Lib">
<h:outputText value="#{type}">
</h:outputText>
</p:column>
</p:dataTable>
I consider that you have problems with the implementation
Link
https://www.primefaces.org/showcase/ui/data/datatable/basic.xhtml
Example
<p:dataTable var="car" value="#{dtBasicView.cars}">
<p:column headerText="Id">
<h:outputText value="#{car.id}" />
</p:column>
<p:column headerText="Year">
<h:outputText value="#{car.year}" />
</p:column>
<p:column headerText="Brand">
<h:outputText value="#{car.brand}" />
</p:column>
<p:column headerText="Color">
<h:outputText value="#{car.color}" />
</p:column>
</p:dataTable>
Managebean
#Named("dtBasicView")
#ViewScoped
public class BasicView implements Serializable {
private List<Car> cars;
#Inject
private CarService service;
#PostConstruct
public void init() {
cars = service.createCars(10);
}
public List<Car> getCars() {
return cars;
}
public void setService(CarService service) {
this.service = service;
}
}
Java Class
#Named
#ApplicationScoped
public class CarService {
private final static String[] colors;
private final static String[] brands;
static {
colors = new String[10];
colors[0] = "Black";
colors[1] = "White";
colors[2] = "Green";
colors[3] = "Red";
colors[4] = "Blue";
colors[5] = "Orange";
colors[6] = "Silver";
colors[7] = "Yellow";
colors[8] = "Brown";
colors[9] = "Maroon";
brands = new String[10];
brands[0] = "BMW";
brands[1] = "Mercedes";
brands[2] = "Volvo";
brands[3] = "Audi";
brands[4] = "Renault";
brands[5] = "Fiat";
brands[6] = "Volkswagen";
brands[7] = "Honda";
brands[8] = "Jaguar";
brands[9] = "Ford";
}
public List<Car> createCars(int size) {
List<Car> list = new ArrayList<Car>();
for(int i = 0 ; i < size ; i++) {
list.add(new Car(getRandomId(), getRandomBrand(), getRandomYear(), getRandomColor(), getRandomPrice(), getRandomSoldState()));
}
return list;
}
private String getRandomId() {
return UUID.randomUUID().toString().substring(0, 8);
}
private int getRandomYear() {
return (int) (Math.random() * 50 + 1960);
}
private String getRandomColor() {
return colors[(int) (Math.random() * 10)];
}
private String getRandomBrand() {
return brands[(int) (Math.random() * 10)];
}
private int getRandomPrice() {
return (int) (Math.random() * 100000);
}
private boolean getRandomSoldState() {
return (Math.random() > 0.5) ? true: false;
}
public List<String> getColors() {
return Arrays.asList(colors);
}
public List<String> getBrands() {
return Arrays.asList(brands);
}
}
This question already has an answer here:
How and when should I load the model from database for JSF dataTable
(1 answer)
Closed 3 years ago.
I have developed a dynamic table which should refill table at every request, the same function is being performed by the code as follows:-
html
<h:form id="form">
<p:outputLabel value="Client: " />
<p:inputText id="inp" value="#{test.id}" />
<p:inputText id="inp1" value="#{test.title}" />
<p:commandButton value="Call List" action = "#{liveRangeService.LiveRangeServicesss(10)}"/>
<p:commandButton value="Call List" action = "#{liveRangeService.LiveRangeServicesss(20)}"/>
<p:dataTable var="result" id="tbl" widgetVar="dtlTBL"
value="#{liveRangeService.tableData}"
filteredValue="#{liveRangeService.filteredData}"
paginator="false"
scrollable="true" rowIndexVar="rowindex" scrollHeight="500"
scrollRows="50" liveScroll="true"
filterDelay="1100"
>
<p:ajax event="rowSelect" listener="#{test.onRowSelect(rowindex)}" />
<f:facet name="header">
<p:outputPanel layout="inline" styleClass="tabSpacer">
<h:outputText value="Global Filter:" />
<p:inputText id="globalFilter" onkeyup="PF('dtlTBL').filter()" style="width:150px;margin-left:10px;"/>
</p:outputPanel>
</f:facet>
<p:column width="50">
<f:facet name="header">
<h:outputText value="Sr." />
</f:facet>
<p:commandButton value="#{rowindex}" style="width: 49px" action="#{test.onRowSelect(rowindex)}"/>
</p:column>
<p:columns value="#{liveRangeService.tableHeaderNames}"
var="mycolHeader"
width="#{colIndex==0?'10%':colIndex==1?'70%':colIndex==2?'10%':colIndex==3?'10%':'0'}"
columnIndexVar="colIndex"
sortBy="#{result[mycolHeader]}"
filterBy="#{result[mycolHeader]}"
filterMatchMode="contains"
>
<f:facet name="header">
<h:outputText value="#{mycolHeader}" />
</f:facet>
<h:outputText value="#{result[mycolHeader]}" />
<br />
</p:columns>
</p:dataTable>
</h:form>
#ManagedBean(name="liveRangeService", eager = true)
#Dependent
public class LiveRangeService implements Serializable {
private static List< Map<String, String> > tableData;
public static List< Map<String, String> > filteredData;
private static List<String> tableHeaderNames;
private String tableColWidths;
public List<Map<String, String>> getTableData() {
return tableData;
}
public List<String> getTableHeaderNames() {
return tableHeaderNames;
}
public LiveRangeService() {
}
public static void LiveRangeServicesss(int noOfRows) {
tableData = new ArrayList< Map<String, String> >();
filteredData = new ArrayList< Map<String, String> >();
tableHeaderNames = new ArrayList<String>();
tableHeaderNames.add("ID");
tableHeaderNames.add("Title");
tableHeaderNames.add("Opn_Amt");
tableHeaderNames.add("Smr_Amt");
for (int i = 0; i < noOfRows; i++) {
Map<String, String> playlist = new HashMap<String, String>();
playlist.put("ID", "101000" + i);
playlist.put("Title", "Share Capital - Mr. " + i);
playlist.put("Opn_Amt", "0");
playlist.put("Smr_Amt", "0");
tableData.add(playlist);
}
filteredData=tableData;
System.out.println("Filled " + filteredData.size() + ", " + noOfRows);
String dlgTBL="form:tbl";
PrimeFaces.current().ajax().update(dlgTBL);
}
public String getTableColWidths() {
return tableColWidths;
}
public void setTableColWidths(String tableColWidths) {
this.tableColWidths = tableColWidths;
}
public List<Map<String, String>> getFilteredData() {
return filteredData;
}
public void setFilteredData(List<Map<String, String>> filteredData) {
this.filteredData = filteredData;
}
}
#ManagedBean(name="test")
#SessionScoped
public class Test implements Serializable {
public String id;
public String title;
public Test() {
id="1";
title="Testing";
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public void onRowSelect(int row) {
try {
String i="ID";
String t="Title";
String ci="id";
String ct="title";
this.getClass().getDeclaredField(ci).set(this, LiveRangeService.filteredData.get(row).get(i));
this.getClass().getDeclaredField(ct).set(this, LiveRangeService.filteredData.get(row).get(t));
PrimeFaces.current().ajax().update("form:inp");
PrimeFaces.current().ajax().update("form:inp1");
PrimeFaces.current().executeScript("PF('dlg').hide();");
} catch (Exception e) {
System.out.println("Error! " + e.getMessage() );
}
}
}
but the problem is that when the table is needed to be updated for other query, the call of function has to be done 2 times ie. i have placed two buttons, one pressing button 1, the table is populated with 10 rows and on pressing button 2, the table is populated with 20 rows. Each button is needed to be pressed two times to update the table.
Please advice.
i have just initialized the tables in Constructor, and all worked same as required.
#ManagedBean(name="liveRangeService")
#SessionScoped
public class LiveRangeService implements Serializable {
private List< Map<String, String> > tableData;
public List< Map<String, String> > filteredData;
private List<String> tableHeaderNames;
private String tableColWidths;
public List<Map<String, String>> getTableData() {
return tableData;
}
public List<String> getTableHeaderNames() {
return tableHeaderNames;
}
public LiveRangeService() {
tableData = new ArrayList< Map<String, String> >();
filteredData = new ArrayList< Map<String, String> >();
tableHeaderNames = new ArrayList<String>();
LiveRangeServicesss (-1, false);
System.out.println("in Constructor:");
}
public LiveRangeService(int noOfRows, boolean showDialogue) {
}
public void LiveRangeServicesss(int noOfRows, boolean showDialogue) {
tableData.clear();
tableHeaderNames.clear();
filteredData.clear();
tableHeaderNames.add("ID");
tableHeaderNames.add("Title");
tableHeaderNames.add("Opn_Amt");
tableHeaderNames.add("Smr_Amt");
for (int i = 0; i < noOfRows; i++) {
Map<String, String> playlist = new HashMap<String, String>();
playlist.put("ID", "101000" + noOfRows + i);
playlist.put("Title", "Share Capital - Mr. " + noOfRows + " - " + i);
playlist.put("Opn_Amt", "0");
playlist.put("Smr_Amt", "0");
tableData.add(playlist);
}
filteredData=tableData;
System.out.println("table size: " + tableData.size() + ", " + filteredData.size());
}
I'm starting with primefaces and I try use LazyModel in p:dataTable.
I already implemented the LazyModel, bean and jsf. The call's to bean and model occur's correctly and my bean return a list with elements, but my jsf show nothing.
Please, somebody know whats happen?
Bellow is my code:
JSF:
<ui:composition template="./newTemplate.xhtml">
<ui:define name="content">
content
<h:form>
<p:panel id="formFiltro">
<p:messages id="messages"/>
<h:panelGrid>
<h:outputLabel for="fieldConta" value="Número da Conta:"/>
<p:inputText id="fieldConta" value="#{log.nrConta}" label="Número da Conta">
<f:convertNumber integerOnly="true" type="number"/>
</p:inputText>
<!--<p:message for="fieldConta" />-->
<h:outputLabel for="fieldAgencia" value="Código da Agência:"/>
<p:inputText id="fieldAgencia" value="#{log.nrAgencia}" label="Código da Agência">
<f:convertNumber integerOnly="true" type="number"/>
</p:inputText>
<!--<p:message for="fieldAgencia" />-->
<center>
<p:commandButton ajax="false" value="Pesquisar" action="#{log.search}" />
</center>
</h:panelGrid>
</p:panel>
<p:dataTable var="l" value="#{log.lazyLogModel}" paginator="true" rows="5"
paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"
rowsPerPageTemplate="5,10,15" id="logTable" lazy="true">
<p:column headerText="ID">
<h:outputText value="#{l.logId}" />
</p:column>
<p:column headerText="Agência">
<h:outputText value="#{l.logAgencia}" />
</p:column>
<p:column headerText="Conta">
<h:outputText value="#{l.logConta}" />
</p:column>
<p:column headerText="SO">
<h:outputText value="#{l.logSo}" />
</p:column>
<p:column headerText="Plugin">
<h:outputText value="#{l.logVersaoPlugin}" />
</p:column>
<p:column headerText="Tam F10">
<h:outputText value="#{l.logTamF10}" />
</p:column>
</p:dataTable>
</h:form>
</ui:define>
</ui:composition>
My bean:
#ManagedBean(name="log")
#RequestScoped
public class consultaJsf implements Serializable {
private static final long serialVersionUID = 1L;
/**
* Creates a new instance of consultaJsf
*/
private List<TbLogLog> listaLog;
private LazyLogModel lazyLogModel;
private int nrConta;
private int nrAgencia;
public consultaJsf() {
try{
//this.listaLog = new ConsultarDados().getListLogAll();
}catch(Exception e){
e.printStackTrace();
}
}
#PostConstruct
public void init()
{
this.lazyLogModel = new LazyLogModel();
}
public List<TbLogLog> getListaLog()
{
return listaLog;
}
public int getNrConta()
{
return nrConta;
}
public void setNrConta(int nrConta)
{
this.nrConta = nrConta;
}
public int getNrAgencia()
{
return nrAgencia;
}
public void setNrAgencia(int nrAgencia)
{
this.nrAgencia = nrAgencia;
}
public LazyLogModel getLazyLogModel()
{
return this.lazyLogModel;
}
public String search() throws Exception
{
if(nrConta != 0)
this.listaLog = new ConsultarDados().getListLogByConta(nrConta);
else if(nrAgencia != 0)
this.listaLog = new ConsultarDados().getListLogByAgencia(nrAgencia);
return null;
}
}
My LazyModel:
public class LazyLogModel extends LazyDataModel<TbLogLog> {
private String nrConta;
private String cdAgencia;
#Override
public List<TbLogLog> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) {
List<TbLogLog> listaLog = null;
try{
listaLog = new ConsultarDados().getListLogAll(first, pageSize);
}catch(Exception e){
return null;
}
return listaLog;
}
/**
* #return the nrConta
*/
public String getNrConta() {
return nrConta;
}
/**
* #param nrConta the nrConta to set
*/
public void setNrConta(String nrConta) {
this.nrConta = nrConta;
}
/**
* #return the cdAgencia
*/
public String getCdAgencia() {
return cdAgencia;
}
/**
* #param cdAgencia the cdAgencia to set
*/
public void setCdAgencia(String cdAgencia) {
this.cdAgencia = cdAgencia;
}
}
Consult Method called by LazyModel:
private List<TbLogLog> getListLog(String hql, int firstResult, int sizePage) throws Exception {
List resultList = null;
try {
Session session = HubernateUtil.getSessionFactory().openSession();
if ((hql == null) || (hql.trim().length() == 0)) {
hql = QUERY_PESQUISAR_TODOS;
}
Query q = session.createQuery(hql);
if(firstResult > 0 )
q.setFirstResult(firstResult);
if(sizePage > 0)
q.setMaxResults(sizePage);
resultList = q.list();
} catch (HibernateException he) {
he.printStackTrace();
}
return resultList;
}
Everything work's fine, but my jsf don't show any result.
Thanks in advance.
Remove the init() in consultaJsf Class and update the getLazyLogModel() as follows
#ManagedBean(name="log")
#RequestScoped
public class consultaJsf implements Serializable {
private static final long serialVersionUID = 1L;
/**
* Creates a new instance of consultaJsf
*/
private List<TbLogLog> listaLog;
private LazyLogModel<TbLogLog> lazyLogModel;
private int nrConta;
private int nrAgencia;
public consultaJsf() {
try{
//this.listaLog = new ConsultarDados().getListLogAll();
}catch(Exception e){
e.printStackTrace();
}
}
public List<TbLogLog> getListaLog()
{
return listaLog;
}
public int getNrConta()
{
return nrConta;
}
public void setNrConta(int nrConta)
{
this.nrConta = nrConta;
}
public int getNrAgencia()
{
return nrAgencia;
}
public void setNrAgencia(int nrAgencia)
{
this.nrAgencia = nrAgencia;
}
public LazyLogModel<TbLogLog> getLazyLogModel()
{
if (lazyLogModel== null) {
lazyLogModel= new LazyDataModel<TbLogLog>() {
#Override
public List<TbLogLog> load(int first, int pageSize, String sortField,
SortOrder sortOrder, Map<String, String> filters) {
List<TbLogLog> listaLog = null;
try{
listaLog = new ConsultarDados().getListLogAll(first, pageSize);
}catch(Exception e){
return null;
}
return listaLog;
}
};
}
return listaLog;
}
public String search() throws Exception
{
if(nrConta != 0)
this.listaLog = new ConsultarDados().getListLogByConta(nrConta);
else if(nrAgencia != 0)
this.listaLog = new ConsultarDados().getListLogByAgencia(nrAgencia);
return null;
}
}
I have two pages - search and result and one bean. If I use ViewScoped, my results do not show. If I use RequestScoped, my page links do not work. How can I fix it? If I place the submit into init with Viewscoped, everything is working fine, but if I do that, how should I get the variables from the form?
My bean:
#Named
#ViewScoped
public class Result implements Serializable {
private static final long serialVersionUID = 1L;
private DAOFactory javabase = DAOFactory.getInstance("javabase.jdbc");
private RecipeDAO recipeDAO = javabase.getRecipeDAO();
private ResourceBundle messages;
#Inject
LocaleBean locale;
private List<Recipe> recipes;
private List<Recipe> recipesView;
private String language;
private List<Page> pagesArray;
private Integer currentPage;
public void init() {
System.out.println("Language is: " + language);
String language1 = "en";
recipes = new ArrayList<>();
recipes = recipeDAO.searchRecipe(language1);
int showValue = 5; //split value
int pages = recipes.size() / showValue; //pages value
if (recipes.size() % showValue != 0) {
pages = pages + 1;
}
for (int i = 0; i < recipes.size(); i++) {
int a = i + 1;
//System.out.println("i is: " + i + " recipe number is: " + a);
}
//System.out.println("pages is: " + pages + " size is: " + recipes.size());
pagesArray = new ArrayList<>();
Page page;
for (int i = 0; i < recipes.size(); i = i + showValue) {
page = new Page();
page.setPageDisabled(false);
page.setFirstItem(i);
page.setLastItem(i + showValue - 1);
pagesArray.add(page);
}
for (int i = 0; i < pagesArray.size(); i++) {
pagesArray.get(i).setPageNumber(i + 1);
}
pagesArray.get(pagesArray.size() - 1).setLastItem(recipes.size() - 1);
/* for (int i = 0; i < pagesArray.size(); i++) {
System.out.println(pagesArray.get(i).getPageNumber() + " " + pagesArray.get(i).getFirstItem() + " " + pagesArray.get(i).getLastItem() + " " + pagesArray.get(i).isPageDisabled());
}*/
recipesView = new ArrayList<>();
Recipe recipe;
for (int i = pagesArray.get(0).getFirstItem(); i <= pagesArray.get(0).getLastItem(); i++) {
recipe = new Recipe();
recipe.setAuthor(recipes.get(i).getAuthor());
recipe.setId(recipes.get(i).getId());
recipe.setCreateDate(recipes.get(i).getCreateDate());
recipe.setTitle(recipes.get(i).getTitle());
recipesView.add(recipe);
}
pagesArray.get(0).setPageDisabled(true);
}
public void doPages() {
FacesContext fc = FacesContext.getCurrentInstance();
this.currentPage = Integer.parseInt(getCountryParam(fc));
System.out.println(currentPage);
recipesView = new ArrayList<>();
Recipe recipe;
for (int i = pagesArray.get(currentPage - 1).getFirstItem(); i <= pagesArray.get(currentPage - 1).getLastItem(); i++) {
System.out.println(i);
recipe = new Recipe();
recipe.setAuthor(recipes.get(i).getAuthor());
recipe.setId(recipes.get(i).getId());
recipe.setCreateDate(recipes.get(i).getCreateDate());
recipe.setTitle(recipes.get(i).getTitle());
recipesView.add(recipe);
}
for (int i = 0; i < pagesArray.size(); i++) {
pagesArray.get(i).setPageDisabled(false);
}
pagesArray.get(currentPage - 1).setPageDisabled(true);
}
public String getCountryParam(FacesContext fc) {
Map<String, String> params = fc.getExternalContext().getRequestParameterMap();
return params.get("currentPage");
}
//setters&getters
}
My search view:
<h:form>
<h:selectOneMenu value="#{search.language}">
<f:selectItem itemLabel="English" itemValue="en"/>
<f:selectItem itemLabel="Select" itemValue=""/>
<f:selectItem itemLabel="Bulgarian" itemValue="bg"/>
</h:selectOneMenu>
<h:commandButton value="Submit" type="submit" action="#{search.submit()}">
<f:param name="lang" value ="#{search.language}"/>
</h:commandButton>
</h:form>
My result view:
<f:metadata>
<f:viewParam name="lang" value="#{result.language}" />
<f:viewAction action="#{result.init()}" />
</f:metadata>
<h:form>
<ui:repeat value="#{result.recipesView}" var="rec">
<h:link value="#{rec.title}" outcome="recipeshow">
<f:param name="id" value="#{rec.id}" />
</h:link>
<br/>
<h:outputText value="#{rec.id}"/><br/>
<h:outputText value="#{rec.author}"/><br/>
<h:outputText value="#{rec.createDate}"/><br/>
<br/>
</ui:repeat>
<br/>
<ui:repeat value="#{result.pagesArray}" var="page">
<h:commandLink value="#{page.pageNumber}" disabled="#{page.pageDisabled}">
<f:ajax listener="#{result.doPages()}" render="#form"/>
<f:param name="currentPage" value="#{page.pageNumber}"/>
</h:commandLink>
</ui:repeat>
</h:form>
My page.java
public class Page {
private int pageNumber;
private boolean pageDisabled;
private int firstItem;
private int lastItem;
public int getPageNumber() {
return pageNumber;
}
public void setPageNumber(int pageNumber) {
this.pageNumber = pageNumber;
}
public boolean isPageDisabled() {
return pageDisabled;
}
public void setPageDisabled(boolean pageDisabled) {
this.pageDisabled = pageDisabled;
}
public int getFirstItem() {
return firstItem;
}
public void setFirstItem(int firstItem) {
this.firstItem = firstItem;
}
public int getLastItem() {
return lastItem;
}
public void setLastItem(int lastItem) {
this.lastItem = lastItem;
}
}
You returned a navigation case outcome from an action method, so your view scoped bean will be recreated, that's why you don't see your results. On the other hand, as you seem to be doing a pagination basing on the information held in the view scope, thus your request scoped beans do not allow for proper pagination.
As to the solution, you should either be doing a postback from your action method, thus returning null or void, or pass the necessary information to the result view using get parameters.
It is also worth noting that you're preloading too much information in recipes = recipeDAO.searchRecipe(language);: you should be loading as much information as is shown in your view, like in: recipes = recipeDAO.searchRecipe(language, min, max);.
I am getting the following error :
Unable to find matching navigation case with from-view-id '/index.xhtml' for action '#{medcontroller.getMedGeneric}' with outcome 'javax.faces.model.ListDataModel#7a652236'
I am new to jsf and I'm really clueless about solving this error. I have a ManagedBean with the following code:
MedController.java
#ManagedBean(name = "medcontroller")
#SessionScoped
public class MedController implements Serializable {
int startId;
String gName;
int endId;
DataModel medNames;
//DataModel medGeneric;
MedicineHelper helper;
private int recordCount = 1000;
private int pageSize = 10;
private Medicine current;
private int selectedItemIndex;
public MedController() {
helper = new MedicineHelper();
startId = 1;
endId = 10;
}
public MedController(int startId, int endId) {
helper = new MedicineHelper();
this.startId = startId;
this.endId = endId;
}
public Medicine getSelected() {
if (current == null) {
current = new Medicine();
selectedItemIndex = -1;
}
return current;
}
public DataModel getMedNames() {
if (medNames == null) {
medNames = new ListDataModel(helper.getMedNames(startId, endId));
}
return medNames;
}
public String getgName()
{
return gName;
}
public void setgName(String gName)
{
this.gName = gName;
}
public DataModel getMedGeneric() {
if (medNames == null) {
medNames= new ListDataModel(helper.getMedGeneric(gName));
}
return medNames;
}
void recreateModel() {
medNames = null;
}
public boolean isHasNextPage() {
if (endId + pageSize <= recordCount) {
return true;
}
return false;
}
public boolean isHasPreviousPage() {
if (startId-pageSize > 0) {
return true;
}
return false;
}
public String next() {
startId = endId+1;
endId = endId + pageSize;
recreateModel();
return "index";
}
public String previous() {
startId = startId - pageSize;
endId = endId - pageSize;
recreateModel();
return "index";
}
public int getPageSize() {
return pageSize;
}
public String prepareView(){
current = (Medicine) getMedNames().getRowData();
return "browse";
}
public String prepareList(){
recreateModel();
return "index";
}
}
And here is my JSF file
index.xhtml
<ui:define name="body">
<h:form styleClass="jsfcrud_list_form">
<h:commandLink action="#{medcontroller.previous}" value="Previous #{medcontroller.pageSize}" rendered="#{medcontroller.hasPreviousPage}"/>
<h:commandLink action="#{medcontroller.next}" value="Next #{medcontroller.pageSize}" rendered="#{medcontroller.hasNextPage}"/>
<h:dataTable value="#{medcontroller.medNames}" var="item" border="1" cellpadding="15" cellspacing="10" rowClasses="jsfcrud_odd_row,jsfcrud_even_row" rules="all" style="border:solid 1px">
<h:column>
<f:facet name="header">
<h:outputText value="BrandName"/>
</f:facet>
<h:outputText value="#{item.brandName}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value="Generic"/>
</f:facet>
<h:outputText value="#{item.generic}"/>
</h:column>
<h:column>
<f:facet name="header">
<h:outputText value=" "/>
</f:facet>
<h:commandLink action="#{medcontroller.prepareView}" value="View"/>
</h:column>
</h:dataTable>
<h:inputText value="#{medcontroller.gName}" />
<h:commandButton value="Submit" action="#{medcontroller.getMedGeneric}" />
</h:form>
</ui:define>
Please help me solve the error.
Also, I do not have a faces-config.xml file. I am using netbeans ide 7.1.2 web application with jsf and hibernate framework.
Thank you in advance.
The <h:commandButton action> must point to a method which invokes some business logic and returns either void or a String representing the target page you'd like to (re)display. However you returned a whole ListDataModel which isn't making any sense to JSF navigation handler and hence this error.
Something like this should do:
public String getMedGeneric(){
// Do your business logic here.
return "someViewId";
}
This will navigate to someViewId.xhtml. However, if you intend to stick on the same view, just let it return void (or null) and it will redisplay the same view.
public void getMedGeneric(){
// Do your business logic here.
}
By the way, it's really a poor naming convention to prefix action method names with get. This is confusing and makes your code not self-documenting. Rather name it loadMedGeneric() or so. I'm merely guessing as you didn't tell anywhere about the concrete functional requirement, what exactly that button should be doing.
getMedGeneric should return java.lang.String which represent navigation to another page described in faces-config.xml. In your case it return some model so it will not work unfortunatell. Let try to put getMedGeneric() action to actionListener and then in action put navigation String. i.e:
action="navString" actionListener="#{medcontroller.getMedGeneric}"
you should try just
actionListener="#{medcontroller.getMedGeneric}"