primefaces charts not updating when submit a new request - jsf

I submit data and a chart has been displayed But again when I submit it by inserting new values in form,chart doesn't update itself.Another thing I saw is when I refresh the page then it update the chart and chart with new values get display.
For instance If I give values Wheat=40 and Sugar=60and submit , It will display the chart.Now when I submit Wheat=90 and Sugar=10 , it displays nothing but the old chart remain present on the page.Now If I refresh the page , The chart with updated values will be availabe.How can I get rid of that problem :( Please suggest a solution if any one have.
Here is my code
Chart Code
<p:barChart id="horizontal"
value="#{reportingCharts.categoryModel}" legendPosition="se"
style="width:635px;height:500px" title="Horizontal Bar Chart"
orientation="horizontal" min="0" max="150" animate="true"
zoom="true" barMargin="90"
rendered="#{chartsRendering.barCharts}" showDatatip="true" shadow="true" />
Button Code
<h:commandButton id="btnLanguage" action="#{reportingCharts.getGraphValuesOnLanguageBasis}"
value="Plot Chart Language">
</h:commandButton>
getGraphValuesOnLanbguageBasis method
public void getGraphValuesOnLanguageBasis() {
categoryModel = null;
resList = (ArrayList<ChartResult>) serviceObj
.getChartByLanguage(ranks, language);
if (chartType.equalsIgnoreCase("bar")
|| chartType.equalsIgnoreCase("line")
|| chartType.equalsIgnoreCase("column")) {
categoryModel = new CartesianChartModel();
ChartSeries langChart = null;
for (int a = 0; a < ranks.length; a++) {
langChart = new ChartSeries();
if(a == 0){
for(int z=0;z<language.length;z++){
langChart.set(languageMap.get(Integer.parseInt(language[z])),0);
}
}
String rank = "";
boolean rankAvailable = false;
for (int x = 0; x < resList.size(); x++) {
if(Integer.parseInt(resList.get(x).getRankId()) == Integer.parseInt(ranks[a])){
rank = resList.get(x).getRankName();
x = resList.size();
rankAvailable = true;
}
}
if(rankAvailable == false){
langChart.setLabel(rankMap.get(Integer.parseInt(ranks[a])));
}
else{
langChart.setLabel(rank);
}
for (int x = 0; x < resList.size(); x++) {
if (Integer.parseInt(resList.get(x).getRankId()) == Integer
.parseInt(ranks[a]) && rankAvailable == true) {
langChart.set(languageMap.get(Integer.parseInt(resList.get(x).getCriteria())), Integer
.parseInt(resList.get(x).getNoOfPersons()));
}
}
categoryModel.addSeries(langChart);
}
} else if (chartType.equalsIgnoreCase("pie")) {
pieModel = new PieChartModel();
for (int x = 0; x < resList.size(); x++) {
pieModel.set(languageMap.get(Integer.parseInt(resList.get(x).getCriteria())), Integer
.parseInt(resList.get(x).getNoOfPersons()));
}
}
ChartsRendering chartRenderer1 = (ChartsRendering) FacesContext
.getCurrentInstance().getExternalContext().getSessionMap()
.get("chartsRendering");
if (chartType.equalsIgnoreCase("bar")) {
chartRenderer1.showBarChart();
} else if (chartType.equalsIgnoreCase("line"))
chartRenderer1.showLineChart();
else if (chartType.equalsIgnoreCase("column"))
chartRenderer1.showColumnChart();
else if (chartType.equalsIgnoreCase("pie"))
chartRenderer1.showPieChart();
}

The chart won't update itself after you change the model values but you can update it through ajax. For example if you have a chart:
<p:barChart id="myBarChart" value=#{yourChartBean.chartModel} ..../>
and a selecteOneMenu which sends new values to your backing bean, define a method which will update the model in your backing bean:
<p:selectOneMenu id="aMenu" value="#{yourChartBean.menuValue}">
<p:ajax event="change" update="myBarChart" listener="#{yourChartBean.refreshChart()}"/>
<f:selectItem itemLabel="This value" itemValue="tv"/>
<f:selectItem itemLabel="Another value" itemValue="av"/>
</p:selectOneMenu>
in this case the refreshChart() method is intended to update your chart model:
public void refreshChart() {
buildChart();
}
private void buildChart() {
chartModel = new CartesianChartModel();
ChartSeries series1 = new ChartSeries();
...
ChartSeries series2 = new ChartSeries();
...
categoryModel.addSeries(series1);
categoryModel.addSeries(series2);
}

Chart should be visible when page loads...after that all ajax request properly renders your chart.
To do that just provide a dummy series data like (0,0) for series 1 and (0,0) for series 2 when page loads, after that everything works fine

Related

draw horizontal line in primeFaces chart

i am trying to draw horizontal line for show max and min trend in my primeFaces line chart but cannot understand ho to do there is my xhtml code:
<div align="center">
<p:outputPanel id="fuelAnalysisPanel">
<p:chart type="line" model="#{generatorDataLogReportBean.animatedModel2}" style="width:95%;" widgetVar="fuelChart"/>
<br/>
</p:outputPanel>
</div>
and my java class code is:
private void createAnimatedModelsForFuel(ArrayList<Param> dataLog) {
animatedModel2 = initLinearModelForFuel(dataLog);
animatedModel2.setTitle("Fuel Graph (%)");
animatedModel2.setAnimate(true);
animatedModel2.setLegendPosition("se");
animatedModel2.setSeriesColors("D42F36");
Axis yAxis = animatedModel2.getAxis(AxisType.Y);
yAxis.setMin(0);
yAxis.setMax(100);
yAxis.setLabel("Percentage %");
}
private LineChartModel initLinearModelForFuel(ArrayList<Param> dataLog) {
LineChartModel model = new LineChartModel();
LineChartSeries series1 = new LineChartSeries();
series1.setLabel("Fuel%");
int i = 1;
String dt = "";
//int size = dataLog.size()-1 ;
/* for (; size >= 0; size--) {
if (dataLog.get(size) instanceof VT12Param) {
series1.set(i++, ((VT12Param) dataLog.get(size)).getActualFuelPercent());
}
}
*/
for (Param p : dataLog) {
if (p instanceof VT12Param) {
dt = sdf2.format(((VT12Param) p).getDateTime().getTime());
series1.set(dt, ((VT12Param) p).getActualFuelPercent());
} else if (p instanceof T20Param) {
dt = sdf2.format(((T20Param) p).getDateTime().getTime());
series1.set(dt, ((T20Param) p).getActualFuelPercent());
}
}
//model.setDatatipFormat("%s, %s");
model.addSeries(series1);
DateAxis axis = new DateAxis("Dates");
axis.setTickAngle(-30);
model.getAxes().put(AxisType.X, axis);
//axis.setMax(sdf.format(toDate.getTime()));
axis.setTickFormat("%b %#d, %H:%M"); //%b %#d, %#I %p // %b %#d, %#I:%M %p
if(dataLog.size() < 500){
axis.setTickInterval(dataLog.size()+"00000");
}
else{
axis.setTickInterval(dataLog.size()+"0000");
}
model.setLegendCols(15);
model.getAxes().put(AxisType.X, axis);
// model.setZoom(true);
return model;
}
and i want horizontal line like this these blue lines:

JSF Target Unreachable, ''0'' returned null: javax.el.PropertyNotFoundException

a list of Objects :
private ArrayList<LegBeanForInsert> listOfLegs;
I show this array by using the notation with arrays: 0 , 1 , .... positional for example:
<p:selectOneMenu value="#{otcdEventsBean.listOfLegs[0].fixvar}"
effect="fade" style="width:100px; height:25px"
panelStyle="width:80px" >
<f:selectItem itemLabel="Select" itemValue="" />
<f:selectItems value="#{otcdEventsBean.fixedVariableCodes}"
itemValue="#{otcdEventsBean.listOfLegs[0].fixvar}" />
<p:ajax listener="#{otcdEventsBean.fixvarchange}" event="change" update="panelUpdate"/>
</p:selectOneMenu>
ERROR:
value="#{otcdEventsBean.listOfLegs[0].fixvar}": Target Unreachable, ''0'' returned null: javax.el.PropertyNotFoundException
in the constructor of the bean i do:
public void initLeg(){
for(int i=0;i<8;i++){
LegBeanForInsert beanLeg = new LegBeanForInsert();
beanLeg.setCallamount(new BigDecimal(0));
beanLeg.setFixvar("");
this.listOfLegs.add(beanLeg);
}
}
this method is called by another page and when the page is renderd dose not have problem the page:
public void setProduct(Object product1, Object product2) {
System.out.println("BEGIN::setProduct: " + (String) product2);
if (product1 instanceof EqdProduct) {
this.eqdProdToedit = (EqdProduct) product1;
} else if (product1 instanceof CURROPTRBTProduct) {
this.rbtProdType = (CURROPTRBTProduct) product1;
} else if (product1 instanceof COMAsianProduct) {
this.comAsianProd = (COMAsianProduct) product1;
} else if (product1 instanceof CRDProductType) {
this.crdProduct = (CRDProductType) product1;
} else if (product1 instanceof ComSwapProduct) {
firstLegComSw = (ComSwapProduct) product1;
if (product2 instanceof ComSwapProduct) {
System.out.println("Com Sawp second prod");
secondLegComSw = (ComSwapProduct) product2;
}
} else if (product1 instanceof List) {
// bisogna settare LegBeanForInsert, LE GAMBE SONO 8 !!
List<?> legs = (List<?>) product1;
String s = (String) product2;
System.out.println("setProduct 2nd arg: " + product2);
if (s.equals("Legs")) {
for (int i = 0; i < legs.size(); i++) {
Leg leg = (Leg) legs.get(i);
LegBeanForInsert beanLeg = new LegBeanForInsert();
beanLeg.setCallamount(new BigDecimal(leg.getCallamount()));
beanLeg.setCallcurrency(leg.getCallcurrency());
beanLeg.setCallmaturity(leg.getCallmaturityNumber());
beanLeg.setCodintord(leg.getCodintord());
beanLeg.setDayconvention(leg.getDayconvention());
beanLeg.setEnddate(leg.getEnddate());
beanLeg.setEventcode(leg.getEventcode());
beanLeg.setEventtype(leg.getEventtype());
beanLeg.setExercisemode(leg.getExercisemode());
beanLeg.setFixvar(leg.getFixvar());
beanLeg.setEndDate(leg.getFmtenddate());
beanLeg.setStartDate(leg.getFmtstartdate());
beanLeg.setFrequency(leg.getFrequency());
beanLeg.setFrequencymultiplier(leg.getFrequencymultiplier());
beanLeg.setFrequencyunit(leg.getFrequencyunit());
beanLeg.setInareas(leg.getInareas());
beanLeg.setIndexname(leg.getIndexname());
beanLeg.setMargin(leg.getMargin());
beanLeg.setNotional(leg.getNotional());
beanLeg.setNumber(leg.getNumber());
beanLeg.setOptioncashdelivery(leg.getOptioncashdelivery());
beanLeg.setOptionmaturity(leg.getOptionMatirityNumber());
beanLeg.setOptiontype(leg.getOptiontype());
beanLeg.setPaycurrency(leg.getPaycurrency());
beanLeg.setPutamount(leg.getPutamount());
beanLeg.setPutcurrency(leg.getPutcurrency());
beanLeg.setPutmaturity(leg.getPutMatirityNumber());
beanLeg.setQuantityunit(leg.getQuantityunit());
beanLeg.setRate(leg.getRate());
beanLeg.setRateconvention(leg.getRateconvention());
beanLeg.setSign(leg.getSign());
beanLeg.setStartdate(leg.getStartdate());
beanLeg.setStrike(leg.getStrike());
this.listOfLegs.add(beanLeg);
}
} else {
System.out.println("MoneyD 2nd arg: " + product2);
for (int i = 0; i < legs.size(); i++) {
LegMoneyDeal leg = (LegMoneyDeal) legs.get(i);
this.legMoneyD.add(leg);
}
}
} else {
// non nè nessuno di quelli bisogna settare a null tutto quanto
otcdEvents = new OtcdEvents();
crdProduct = new CRDProductType();
firstLegComSw = new ComSwapProduct();
secondLegComSw = new ComSwapProduct();
comAsianProd = new COMAsianProduct();
rbtProdType = new CURROPTRBTProduct();
listOfLegs = new ArrayList<LegBeanForInsert>();
legMoneyD = new ArrayList<LegMoneyDeal>();
eqdProdToedit = new EqdProduct();
}
}
the constructor :
public OtcdEventsBean() {
try {
Context ctx = new InitialContext();
otcdEvents = new OtcdEvents();
crdProduct = new CRDProductType();
firstLegComSw = new ComSwapProduct();
secondLegComSw = new ComSwapProduct();
comAsianProd = new COMAsianProduct();
rbtProdType = new CURROPTRBTProduct();
ds = (DataSource) ctx.lookup("java:comp/env/jdbc/myoracleDS");
rederField = true;
listOfLegs = new ArrayList<LegBeanForInsert>();
initLeg();
eqdProdToedit = new EqdProduct();
legMoneyD = new ArrayList<LegMoneyDeal>();
legMoneyD.add(new LegMoneyDeal());
legMoneyD.add(new LegMoneyDeal());
fieldsEditingDisabled = false;
loginBean = (LoginBean) FacesContext.getCurrentInstance().getApplication().evaluateExpressionGet(FacesContext.getCurrentInstance(), "#{loginBean}", LoginBean.class);
setFixedVariableCodes(new String[2]);
getFixedVariableCodes()[0] = "Fixed";
getFixedVariableCodes()[1] = "Variable";
setSignPremiumCodes(new String[2]);
signPremiumCodes[0] = "Pay";
signPremiumCodes[1] = "Receive";
setFrequencyUnitCodes(new String[4]);
frequencyUnitCodes[0] = "day";
frequencyUnitCodes[1] = "week";
frequencyUnitCodes[2] = "month";
frequencyUnitCodes[3] = "year";
setCashDeliveryCodes(new String[2]);
cashDeliveryCodes[0] = "C";
cashDeliveryCodes[1] = "D";
setOptionTypeCodes(new String[2]);
optionTypeCodes[0] = "CALL";
optionTypeCodes[1] = "PUT";
} catch (NamingException e) {
e.printStackTrace();
}
}
full bean code:
http://pastebin.com/EbfuSwHN
How is the init method called. Maybe that is not getting called? I do not see a new ArrayList on the definition. When do you call new on ArrayList? You should be getting a null pointer exception in the init method. You could add the new ArrayList to the beginning of the init method before the loop. Remember also that set methods get called multiple times in JSF so you should limit the code in the set method.

Read Check Box, Radio Button Name and values from PDF using iText Sharp

I have a fillable PDF contains CheckBoxes and RadioButtons and TextBox.
How do i get the CheckBox Name and its value also how do we know that it is a checkbox / Radio Button?
i'm using iTextSharp and have look at my below code
PdfReader pdfReader = new PdfReader(FileName);
pdfReader.SelectPages("37");
MemoryStream oStream = new MemoryStream();
PdfStamper stamper = new PdfStamper(pdfReader, oStream);
AcroFields form = stamper.AcroFields;
if (form.Fields.Count() > 0)
{
IDictionary<string,AcroFields.Item> oDic= form.Fields;
foreach (string FieldName in oDic.Keys)
{
//FieldName - CheckBox name; i need to confirm that is a Checkbox...
}
foreach (AcroFields.Item oItem in oDic.Values)
{
// how do we get check box values
}
}
The following code may help you out, if you still need it. It only works for AcroForms
int BUTTON = 1;
int CHECK_BOX = 2;
int RADIO_BUTTON = 3;
int TEXT_FIELD = 4;
int LIST_BOX = 5;
int COMBO_BOX = 6;
PdfReader pdfReader = new PdfReader(path);
AcroFields af = pdfReader.AcroFields;
foreach (var field in af.Fields)
{
bool isRadio = RADIO_BUTTON == af.GetFieldType(field.Key));
}
Edit:
Also, field.Key is the name of the field and field.Value is the value at it.
For checkboxes, if(field.Value == "Yes") then it is selected... if it is anything else, it is not selected.
Edit:
And I just found how tro get Radio Button options, if you are needing them.
myKey k = new myKey(field.Key, af.GetField(field.Key), af.GetFieldType(field.Key));
if (k.isRadio())
{
try { k.options.AddRange(af.GetAppearanceStates(k.key)); }
catch { }
}
Keys.Add(k);
Radio buttons, checkbox and buttons are all actually the same type of field but with different flags set. You can see the flags in the PDF Spec section 12.7.4.2.1 Table 226.
int ffRadio = 1 << 15; //Per spec, 16th bit is radio button
int ffPushbutton = 1 << 16; //17th bit is push button
For a given Field you want to get the Widgets associated with it. Usually this is just one but can be more so you should account for this.
PdfDictionary w = f.Value.GetWidget(0);
Button fields will have their field type (/Ft) set to /Btn so check for that
if (!w.Contains(PdfName.FT) || !w.Get(PdfName.FT).Equals(PdfName.BTN)) {continue;/*Skipping non-buttons*/ }
For the current Widget get the optional field flags (/Ff) value or use zero if it doesn't exist.
int ff = (w.Contains(PdfName.FF) ? w.GetAsNumber(PdfName.FF).IntValue : 0);
Then just some simple math:
if ((ff & ffRadio) == ffRadio) {
//Is Radio
} else if (((ff & ffRadio) != ffRadio) && ((ff & ffPushbutton) != ffPushbutton)) {
//Is Checkbox
} else {
//Regular button
}
Below is a full-working C# WinForm 2011 app targeting iTextSharp 5.2.0 that shows off all of the above looking at a file called Test.pdf living on your desktop. Just add some logic to the conditionals to handle each button type.
using System;
using System.IO;
using System.Windows.Forms;
using iTextSharp.text.pdf;
namespace WindowsFormsApplication3 {
public partial class Form1 : Form {
public Form1() {
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e) {
var testFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop), "Test.pdf");
PdfReader reader = new PdfReader(testFile);
var fields = reader.AcroFields;
int ffRadio = 1 << 15; //Per spec, 16th bit is radio button
int ffPushbutton = 1 << 16; //17th bit is push button
int ff;
//Loop through each field
foreach (var f in fields.Fields) {
//Get the widgets for the field (note, this could return more than 1, this should be checked)
PdfDictionary w = f.Value.GetWidget(0);
//See if it is a button-like object (/Ft == /Btn)
if (!w.Contains(PdfName.FT) || !w.Get(PdfName.FT).Equals(PdfName.BTN)) { continue;/*Skipping non-buttons*/ }
//Get the optional field flags, if they don't exist then just use zero
ff = (w.Contains(PdfName.FF) ? w.GetAsNumber(PdfName.FF).IntValue : 0);
if ((ff & ffRadio) == ffRadio) {
//Is Radio
} else if (((ff & ffRadio) != ffRadio) && ((ff & ffPushbutton) != ffPushbutton)) {
//Is Checkbox
} else {
//Regular button
}
}
this.Close();
}
}
}
C# with System.Linq included
for radio buttons , get which option is selected from all the options in radio form, print also all the choice options by their specified name in Adobe Acrobat Pro
AcroFields fields = reader.AcroFields;
List<string> fldNames = new List<string>(fields.Fields.Keys);
if (fldNames.Count > 0) //am gasit cel putin un acroform
{
foreach (string fldname in fldNames)
{
int tip = fields.GetFieldType(fldname);
if (tip == 3) //choice / radio
{
Console.WriteLine("radio form");
string[] valori = fields.GetListSelection(fldname);
foreach (string s in valori)
Console.WriteLine(s + " ");
Console.WriteLine("selected from radio form options");
string[] valori2 = fields.GetAppearanceStates(fldname);
//Console.WriteLine(valori2.Length);
var val2 = (from string c in valori2
where (c.ToLower().CompareTo("off") != 0)
select c).ToList();
if (val2.Count > 0)
foreach (string s2 in val2)
Console.WriteLine(s2 + " ");
}
}
}

How to do filter in jsf datatable?

I need to do the filter in the datatable.
I have two dropdown and first is just static values..like filter by name,dob,age.Based on that open second dropdown and do the filter display the values.
<ice:selectOneMenu size="12" onchange="this.form.submit()"
partialSubmit="true" id="filterByPastDue"
valueChangeListener="#{details.filterByListener}">
<f:selectItem itemLabel="None" itemValue="1" />
<f:selectItem itemLabel="Name" itemValue="2" />
<f:selectItem itemLabel="Age" itemValue="3" />
<f:selectItem itemLabel="DOB" itemValue="4" />
<ice:selectOneMenu binding="#{person.selectFilterItems}" size="12" id="OpenFilterMenu" rendered="false">
In my mangebean have logic to get values in second drop down values.
public void filterByListener(ValueChangeEvent valueChangeEvent) {
int filterBy = Integer
.parseInt((String) valueChangeEvent.getNewValue());
switch (filterBy) {
case 1: {
filterItems = null;
filterItems = new HashSet<SelectItem>();
filterOptions = null;
filterOptions = new HashSet<String>();
outputTextFor = false;
selectFilterItems.setRendered(false);
break;
}
case 2: {
// clearing arraylist
filterItems = null;
filterItems = new HashSet<SelectItem>();
filterOptions = null;
filterOptions = new HashSet<String>();
// loading arrayList
for (int i = 0; i < person.size(); i++) {
filterOptions.add(person.get(i).getName()
.toString());
}
Iterator it = filterOptions.iterator();
while (it.hasNext()) {
String s = (String) it.next();
filterItems.add(new SelectItem(s, s));
}
// rendering components
outputTextFor = true;
selectFilterItems.setRendered(true);
break;
}
case 3: {
// clearing arraylist
filterItems = null;
filterItems = new HashSet<SelectItem>();
filterOptions = null;
filterOptions = new HashSet<String>();
// loading arrayList
for (int i = 0; i < person.size(); i++) {
filterOptions.add(person.get(i).getAge());
}
Iterator it = filterOptions.iterator();
while (it.hasNext()) {
String s = (String) it.next();
filterItems.add(new SelectItem(s, s));
}
// rendering components
outputTextFor = true;
selectFilterItems.setRendered(true);
break;
}
case 4: {
// clearing arraylist
filterItems = null;
filterItems = new HashSet<SelectItem>();
filterOptions = null;
filterOptions = new HashSet<String>();
// loading arrayList
for (int i = 0; i < person.size(); i++) {
filterOptions.add(person.get(i).getDOB());
}
Iterator it = filterOptions.iterator();
while (it.hasNext()) {
String s = (String) it.next();
filterItems.add(new SelectItem(s, s));
}
// rendering components
outputTextFor = true;
selectFilterItems.setRendered(true);
break;
}
default: {
// clearing arrayList
filterItems = null;
filterItems = new HashSet<SelectItem>();
filterOptions = null;
filterOptions = new HashSet<String>();
outputTextFor = false;
selectFilterItems.setRendered(false);
break;
}
}
}
Now i got the second drop down values what in my datatable.
Now, how to get the filter values display in the datatable.I having person object and need to display the datatables which ever selected in the second drop down.
You need to preset the property associated the value attribute of the h:dataTable with the desired datamodel. You could do that in the action method of the submit button or valueChangeListener method of the second dropdown. E.g.
public void submit() {
this.dataModel = getDataModelSomehow(filterBy, filterOption);
}

Conditionally display row using JSF Datatable

I have some JSF code that currently works (as shown below), and I need to modify it to conditionally suppress the display of certain rows of the table. I know how to conditionally suppress the display of a particular cell, but that seems to create an empty cell, while what I'm trying to do is to not display the row at all.
Any suggestions?
<h:dataTable styleClass="resultsTable" id="t1" value="#{r.common}" var="com" headerClass="headerBackgrnd" rowClasses="rowOdd, rowEven" columnClasses="leftAlign, rightAlign, leftAlign">
<h:column>
<h:outputText rendered="#{com.rendered}" styleClass="inputText" value="#{com.description}: " />
</h:column>
<h:column>
<h:outputText styleClass="outputText" value="#{com.v1}" />
</h:column>
<h:column>
<h:inputText styleClass="inputText" value="#{com.v2}" />
</h:column>
</h:dataTable>
Basically, the line that says #{com.rendered} will conditionally display the contents of a single cell, producing an empty cell when com.rendered is false. But I want to skip an entire row of the display under certain conditions - how would I go about doing that?
Rows correspond to data objects in the collection of your table. If you don't want the row, don't put the object in the collection.
Alternatively, you can use the rowClasses parameter for dataTable.
Bean code:
public String getRowClasses() {
StringBuilder sb = new StringBuilder();
for (Data data : myData) {
sb.append(data.hide ? 'hide,' : 'show,');
}
return sb.toString();
}
CSS:
tr.hide {display:none;}
For people using richFaces, you can use rich:column's filterExpression attribute.
<rich:column filterExpression="#{put your expression here}">
...
</rich>
If the condition is not met, the complete row is filtered out.
Example is using seam EL!
extension to Brian's solution.
To display the column names I did the following in primefaces
<p:dataTable value="#{eiBean.dce.ilDbConns}" var="c">
<p:columnGroup type="header">
<p:row>
<p:column colspan="1" />
<p:column colspan="1" />
</p:row>
<p:row>
<p:column headerText="DataBase Type" width="auto" />
<p:column headerText="URL" width="400" />
</p:row>
</p:columnGroup>
<p:column rendered='#{c.conType == "TARGET"}'>
<p:outputLabel value="#{c.dbType}" />
</p:column>
<p:column rendered='#{c.conType == "TARGET"}'>
<p:outputLabel value="#{c.dbUrl}" />
</p:column>
</p:dataTable>
I extend HtmlTableRenderer default renderer and overwrite renderRowStart method to achieve this by giving style attribute into table->tr element with value display:none.
The item inside binding list needs to implement TableRow interface which only has one method of isHide. In the concrete class you can put any logic you like to give a boolean value.
BTW, in this custom renderer also has PrimeFaces implementation like function which gives the message when table is empty and the table->tr will automatically calculate how many columns in the table and give proper value to colspan attribute.
public class MyDataTableRenderer extends HtmlTableRenderer {
private static final Integer[] ZERO_INT_ARRAY = new Integer[] { 0 };
private static final String NO_RESULT_MESSAGE_ATTR_NAME = "noResultMessage";
private static final String defaultEmptyMessage = "No records found";
private static final Logger log = Logger.getLogger(DHSDataTableRenderer.class.getName());
#Override
public void encodeInnerHtml(FacesContext facesContext, UIComponent component) throws IOException {
UIData uiData = (UIData) component;
String message = (String) uiData.getAttributes().get(NO_RESULT_MESSAGE_ATTR_NAME);
if (message == null || "".equals(message.trim())) {
message = defaultEmptyMessage;
}
ResponseWriter writer = facesContext.getResponseWriter();
int rowCount = uiData.getRowCount();
int newspaperColumns = getNewspaperColumns(component);
int columnNumber = getChildCount(component);
if (rowCount == -1 && newspaperColumns == 1) {
encodeInnerHtmlUnknownRowCount(facesContext, component);
return;
}
if (rowCount == 0) {
// nothing to render, to get valid xhtml we render an empty dummy
// row
writer.startElement(HTML.TBODY_ELEM, uiData);
writer.writeAttribute(HTML.ID_ATTR, component.getClientId(facesContext) + ":tbody_element", null);
writer.startElement(HTML.TR_ELEM, uiData);
writer.startElement(HTML.TD_ELEM, uiData);
writer.writeAttribute(HTML.COLSPAN_ATTR, columnNumber, null);
writer.writeAttribute(HTML.CLASS_ATTR, "dhs-empty-table", null);
writer.write(message);
writer.endElement(HTML.TD_ELEM);
writer.endElement(HTML.TR_ELEM);
writer.endElement(HTML.TBODY_ELEM);
return;
}
// begin the table
// get the CSS styles
Styles styles = getStyles(uiData);
int first = uiData.getFirst();
int rows = uiData.getRows();
int last;
if (rows <= 0) {
last = rowCount;
} else {
last = first + rows;
if (last > rowCount) {
last = rowCount;
}
}
int newspaperRows;
if ((last - first) % newspaperColumns == 0) {
newspaperRows = (last - first) / newspaperColumns;
} else {
newspaperRows = ((last - first) / newspaperColumns) + 1;
}
boolean newspaperHorizontalOrientation = isNewspaperHorizontalOrientation(component);
// get the row indizes for which a new TBODY element should be created
Integer[] bodyrows = getBodyRows(facesContext, component);
int bodyrowsCount = 0;
// walk through the newspaper rows
for (int nr = 0; nr < newspaperRows; nr++) {
boolean rowStartRendered = false;
// walk through the newspaper columns
for (int nc = 0; nc < newspaperColumns; nc++) {
// the current row in the 'real' table
int currentRow;
if (newspaperHorizontalOrientation) {
currentRow = nr * newspaperColumns + nc + first;
} else {
currentRow = nc * newspaperRows + nr + first;
}
// if this row is not to be rendered
if (currentRow >= last) {
continue;
}
// bail if any row does not exist
uiData.setRowIndex(currentRow);
if (!uiData.isRowAvailable()) {
log.severe("Row is not available. Rowindex = " + currentRow);
break;
}
if (nc == 0) {
// first column in table, start new row
beforeRow(facesContext, uiData);
// is the current row listed in the bodyrows attribute
if (ArrayUtils.contains(bodyrows, currentRow)) {
// close any preopened TBODY element first
if (bodyrowsCount != 0) {
HtmlRendererUtils.writePrettyLineSeparator(facesContext);
writer.endElement(HTML.TBODY_ELEM);
}
HtmlRendererUtils.writePrettyLineSeparator(facesContext);
writer.startElement(HTML.TBODY_ELEM, uiData);
// Do not attach bodyrowsCount to the first TBODY
// element, because of backward compatibility
writer.writeAttribute(HTML.ID_ATTR, component.getClientId(facesContext) + ":tbody_element" + (bodyrowsCount == 0 ? "" : bodyrowsCount),
null);
bodyrowsCount++;
}
HtmlRendererUtils.writePrettyLineSeparator(facesContext);
renderRowStart(facesContext, writer, uiData, styles, nr);
rowStartRendered = true;
}
List<UIComponent> children = null;
for (int j = 0, size = getChildCount(component); j < size; j++) {
if (children == null) {
children = getChildren(component);
}
UIComponent child = children.get(j);
if (child.isRendered()) {
boolean columnRendering = child instanceof UIColumn;
if (columnRendering) {
beforeColumn(facesContext, uiData, j);
}
encodeColumnChild(facesContext, writer, uiData, child, styles, nc * uiData.getChildCount() + j);
if (columnRendering) {
afterColumn(facesContext, uiData, j);
}
}
}
if (hasNewspaperTableSpacer(uiData)) {
// draw the spacer facet
if (nc < newspaperColumns - 1) {
renderSpacerCell(facesContext, writer, uiData);
}
}
}
if (rowStartRendered) {
renderRowEnd(facesContext, writer, uiData);
afterRow(facesContext, uiData);
}
}
if (bodyrowsCount != 0) {
// close the last TBODY element
HtmlRendererUtils.writePrettyLineSeparator(facesContext);
writer.endElement(HTML.TBODY_ELEM);
}
}
#Override
protected void renderRowStart(FacesContext facesContext, ResponseWriter writer, UIData uiData, Styles styles, int rowStyleIndex) throws IOException {
writer.startElement(HTML.TR_ELEM, null); // uiData);
renderRowStyle(facesContext, writer, uiData, styles, rowStyleIndex);
Object obj = uiData.getRowData();
boolean isHide = false;
if (obj instanceof TableRow) {
isHide = ((TableRow) obj).isHide();
}
if (isHide) {
writer.writeAttribute("style", "display: none;", null);
}
Object rowId = uiData.getAttributes().get(org.apache.myfaces.shared.renderkit.JSFAttr.ROW_ID);
if (rowId != null) {
writer.writeAttribute(HTML.ID_ATTR, rowId.toString(), null);
}
}
private void encodeInnerHtmlUnknownRowCount(FacesContext facesContext, UIComponent component) throws IOException {
UIData uiData = (UIData) component;
ResponseWriter writer = facesContext.getResponseWriter();
Styles styles = getStyles(uiData);
Integer[] bodyrows = getBodyRows(facesContext, component);
int bodyrowsCount = 0;
int first = uiData.getFirst();
int rows = uiData.getRows();
int currentRow = first;
boolean isRowRendered = false;
while (true) {
uiData.setRowIndex(currentRow);
if (!uiData.isRowAvailable()) {
break;
}
isRowRendered = true;
// first column in table, start new row
beforeRow(facesContext, uiData);
// is the current row listed in the bodyrows attribute
if (ArrayUtils.contains(bodyrows, currentRow)) {
// close any preopened TBODY element first
if (bodyrowsCount != 0) {
HtmlRendererUtils.writePrettyLineSeparator(facesContext);
writer.endElement(HTML.TBODY_ELEM);
}
HtmlRendererUtils.writePrettyLineSeparator(facesContext);
writer.startElement(HTML.TBODY_ELEM, uiData);
// Do not attach bodyrowsCount to the first TBODY element,
// because of backward compatibility
writer.writeAttribute(HTML.ID_ATTR, component.getClientId(facesContext) + ":tbody_element" + (bodyrowsCount == 0 ? "" : bodyrowsCount), null);
bodyrowsCount++;
}
HtmlRendererUtils.writePrettyLineSeparator(facesContext);
renderRowStart(facesContext, writer, uiData, styles, currentRow);
List<UIComponent> children = null;
for (int j = 0, size = getChildCount(component); j < size; j++) {
if (children == null) {
children = getChildren(component);
}
UIComponent child = children.get(j);
if (child.isRendered()) {
boolean columnRendering = child instanceof UIColumn;
if (columnRendering) {
beforeColumn(facesContext, uiData, j);
}
encodeColumnChild(facesContext, writer, uiData, child, styles, j);
if (columnRendering) {
afterColumn(facesContext, uiData, j);
}
}
}
renderRowEnd(facesContext, writer, uiData);
afterRow(facesContext, uiData);
currentRow++;
if (rows > 0 && currentRow - first > rows) {
break;
}
}
if (!isRowRendered) {
// nothing to render, to get valid xhtml we render an empty dummy
// row
writer.startElement(HTML.TBODY_ELEM, uiData);
writer.writeAttribute(HTML.ID_ATTR, component.getClientId(facesContext) + ":tbody_element", null);
writer.startElement(HTML.TR_ELEM, uiData);
writer.startElement(HTML.TD_ELEM, uiData);
writer.endElement(HTML.TD_ELEM);
writer.endElement(HTML.TR_ELEM);
writer.endElement(HTML.TBODY_ELEM);
return;
}
if (bodyrowsCount != 0) {
// close the last TBODY element
HtmlRendererUtils.writePrettyLineSeparator(facesContext);
writer.endElement(HTML.TBODY_ELEM);
}
}
private Integer[] getBodyRows(FacesContext facesContext, UIComponent component) {
Integer[] bodyrows = null;
String bodyrowsAttr = (String) component.getAttributes().get(JSFAttr.BODYROWS_ATTR);
if (bodyrowsAttr != null && !"".equals(bodyrowsAttr)) {
String[] bodyrowsString = StringUtils.trim(StringUtils.splitShortString(bodyrowsAttr, ','));
// parsing with no exception handling, because of JSF-spec:
// "If present, this must be a comma separated list of integers."
bodyrows = new Integer[bodyrowsString.length];
for (int i = 0; i < bodyrowsString.length; i++) {
bodyrows[i] = new Integer(bodyrowsString[i]);
}
} else {
bodyrows = ZERO_INT_ARRAY;
}
return bodyrows;
}
}
Use the empty css selector as suggested here, but with tr instead of td. This worked for me.
https://stackoverflow.com/a/19177424
As described here: https://developer.mozilla.org/en-US/docs/Web/CSS/:empty
This selector works on all current browsers.
<style>
tr:empty {
display: none;
}
</style>
I've successfully hidden rows by putting a rendered attribute in all the <h:column> tags. The problem is that it suppresses the table headers. If your table has no table headers (they are <f:facet name="header"> tags embedded in the <h:column>), this approach might work for you.
I ended up using multiple lists in the backing bean, as I needed the table headers.

Resources