Primefaces conditional logic within <p:dataGrid> - jsf-2

I have a data table which has two images per column, one that is displayed and also a hidden image that is not. The idea is to dislpay the hidden image on top of the other image if an attribute #{person.isLocked} result set is set to 'T'. My code has a div and within that div has two div's, one for the main image and then one for the image that will be overlayed. (Code below) The image that is to be overlayed has a style attribute display: none; . I need somehow to check to see if the #{person.isLocked} equals 'T', if so then I need to change the css to display:block; else leave it be.
<p:dataGrid var="person" value="myBean.people">
<p:column>
<h:panelGird style="margin-left:auto; margin-right:auto;">
<div>
<div style="position:absolute; z-index:1;">
<p:graphicImage value="image?id=#{person.id}" cache="false"/>
</div>
<div style="position:absolute; z-index:100; display: none;">
<p:graphicImage value="./images/lock.png" cache="true"/>
</div>
</div>
</h:panelGrad>
</p:column>
</p:dataGrid>
The only solution I have come up with is instead of storing 'T' or 'F' in the database as #{person.isLocked}, store the css attribute instead, so I would store 'block' or 'none' and then call the person attribute in the style like so.
<div style="position:absolute: z-index:100; display: #{person.isLocked}">
<p:graphicImage value="./images/lock.png" cache="true"/>
</div>
This seems like a bad design though. I don't want to manipulate the data in my database just for display purposes. Has anyone found a different way of doing this?

I've never used Primefaces, but you could try
<ui:fragment rendered="#{person.isLocked}">
<!-- your div here -->
</ui fragment>

Related

How to disable field's auoifilling in Chrome with Vaadin?

In all input fields in Chrome appear nonsens texts - some texts, that were written in other text field. It seems, that it is connected with default IDs. It can be probably resolved for text fields with setting custom id with setId(..) method. But it doesn't work for datefields, comboboxes etc. while the id is set for the parent div not the input itself eg.:
<div role="combobox" class="v-filterselect v-widget small v-filterselect-small v-has-width" id="Field-1553856663994" style="width: 100%;" autocomplete="off">
<input type="text" class="v-filterselect-input" autocomplete="nope" id="gwt-uid-134" aria-labelledby="gwt-uid-133" style="width: 100%;" tabindex="0" dir="">
<div class="v-filterselect-button" aria-hidden="true" role="button"></div></div>
Is the way in Vaadin to set id for inner element or to disable completion in Chrome?
Chrome the behavior on autocomplete attribute changed a while ago, but it has been until recently we made a change in our implementation according to that in Vaadin 8.
There is lengthy discssion about this in our issue tracker;:: https://github.com/vaadin/framework/issues/11437

Voiceover reading pseudo-elements despite aria-hidden attributes within <label />

I'm creating custom radio / checkbox icons by adding a pseudo-element on a label element with the :before css rule. I've added aria-hidden to the label element, but VO on iOS is still reading the pseudo-element.
I understand that some screen readers will ignore an aria-hidden attribute if the element is providing additional context (this is the case for label elements, since they provide additional information about a connected input element). To get around this I've added a aria-label attribute, but again, this is ignore by VO on iOS. This seems to fix the same problem for other screen reader, browser, and device combinations (Narrator and IE / Edge for example).
I've also tried to add a child span or i element to the label and add the :before css rule and aria-hidden attribute to that, but VO on iOS is still reading the pseudo-element.
Does anyone have any advice for having the screen reader read the correct content?
My basic approach is below (note: won't work in a jsfiddle since I'm not loading my font-face).
You can also view the first example here:
http://uatwww.surveygizmo.com/s3/4102902/Basic-Radio
<input type="radio" id="radio1" value="1" name="example" />
<label for="radio1" class="custom-icon" aria-hidden="true" aria-label="example 1">Example 1</label>
<input type="radio" id="radio2" value="2" name="example" />
<label for="radio2">
<span class="custom-icon" aria-hidden="true" aria-label="example 2"></span>
Example 2
</label>
<input type="radio" id="radio3" value="3" name="example" />
<label for="radio3">
<i class="custom-icon" aria-hidden="true" aria-label="example 3"></i>
Example 3
</label>
<style>
input[type=radio] {
opacity: 0;
position: absolute;
border: 0;
height: 0;
margin: 0;
overflow: hidden;
padding: 0;
}
input[type=radio] + .custom-icon:before,
input[type=radio] + label .custom-icon:before {
content: "\26aa";
}
input[type=radio]:checked + .custom-icon:before,
input[type=radio]:checked + label .custom-icon:before {
content: "\26ab";
}
</style>
I think the problem is that you are giving confusing instructions to both the browser and screenreader. You have an invisible input with CSS content attached to it, which is then associated to a label which is aria-hidden but also has an aria-label. You’re definitely going to get inconsistent interpretations of that markup across different browser/screenreader combinations.
I’ve used Heydon Pickering’s custom control method successfully on a bunch of sites with no problems. It seems like a simpler version of what you’re aiming for. It accessibly hides the input from everyone except screenreader software, puts the CSS content on a span instead of the label or input. He doesn’t use any ARIA, but if more recent versions of VoiceOver announce the CSS content you can just put aria-hidden on the span and let screenreaders treat the label and input as normal.
Concerning radio1, the W3C says:
If the current node is hidden and is not referenced by aria-labelledby or aria-describedby, nor referenced by a native host language text alternative element or attribute, return the empty string.
So as long as you reference an element even though it has the aria-hidden attribute, it will be spoken out.
If you want to give an alternative text for an element, you have to set the aria-label attribute on the element:
<input type="radio" id="radio1" value="1" name="example" aria-label="example 1" />
<label for="radio1" class="custom-icon" aria-hidden="true">Example 1</label>
Pseudo elements have different beheviours on browsers, and as you can see the alternative text for :before elements will be given even though the associated element is marked with the aria-hidden attribute.

Row rendering on extendedDataTable doesnt work

Question (short version)
I have an issue with richfaces(4.3.2-final).
I'm trying to rerender a row/cells inside a rich:extendedDataTable. I can't get it to work.
The only thing that works is to rerender the whole table.
All examples/tutorials i can find are for version 3.3. Those solutions dont work for me.
I hope you can help me with a solution or a 4.2+ example/tutorial.
Long version of the question
Not selected row cells:
<a4j:outputPanel layout="block" rendered="#{inactive}">
<h:outputText
value="#{cc.attrs.rowItem.getValue(cc.attrs.id)}"
styleClass="outputField"
style="#{cc.attrs.style}">
</h:outputText>
</a4j:outputPanel>
Selected Row cells:
<a4j:outputPanel layout="block" rendered="#{active and field.echoed}">
<h:inputText
value="#{field.value}"
id="#{cc.attrs.id}ID"
disabled="#{field.disabled}"
readonly="#{field.readonly}"
rendered="true"
title="#{field.title}"/>
....
</a4j:outputPanel>
On selection of other rows:
<a4j:ajax event="selectionchange"
listener="#{crudBean.actionForm.selectionListener}"
render="messages,saveButton,deleteButton,multiOccurenceTable"
/>
HTML code, not selected row cell:
<td class="rf-edt-td-j_idt230">
<div class="rf-edt-c rf-edt-c-j_idt230">
<div class="rf-edt-c-cnt">
<div id="multiOccurenceTable:0:soort:soort">
<div id="multiOccurenceTable:0:soort:j_idt140">
<span class=" outputField" style="">VO</span>
</div>
</div>
</div>
</div>
</td>
Selected row cell HTML:
<td class="rf-edt-td-j_idt230">
<div class="rf-edt-c rf-edt-c-j_idt230">
<div class="rf-edt-c-cnt">
<div id="multiOccurenceTable:1:soort:soort">
<div id="multiOccurenceTable:1:soort:j_idt240">
<input id="multiOccurenceTable:1:soort:soortID" name="multiOccurenceTable:1:soort:soortID" value="VO" type="text">
</div>
</div>
</div>
</div>
</td>
My attempts:
The on selectionchange rerender is now put on the table:"multiOccurenceTable".
This works, on every selection change the whole table gets rerendered.
For performance i try to update the table on row or cell level. I can't get get this to work. I tried simple and more complex solutions, none worked. What am i doing wrong?
(most examples/tutorials are for richfaces 3.3 on the internet which could be a reason)
Try 1, manually updating the rows/cells:
all 3 rows: nothing happened when i pressed the 'save' button
<a4j:commandLink actionListener="#{crudBean.actionForm.save}"
render="multiOccurenceTable:0,multiOccurenceTable:1,multiOccurenceTable:2"
reRender="multiOccurenceTable:0,multiOccurenceTable:1,multiOccurenceTable:2">Save
</a4j:commandLink>
One cell: nothing happened when i pressed the 'save1' button
<a4j:commandLink actionListener="#{crudBean.actionForm.save}"
render="multiOccurenceTable:#rows(crudBean.actionForm.rowsToUpdate):soort"
reRender="multiOccurenceTable:#rows(crudBean.actionForm.rowsToUpdate):soort">Save1
</a4j:commandLink>
I've also tried with ajaxKeys with no succes according to this tutorial rich 3.x and this example (rich 3.3)
If you got any possible solutions, please let me know.
My error is fixed. The error was not the rendering. but that the condition for rendering was set outside the component that was rendered. This resulted in rerendering the component with not updated values, which led to no change on the screen.
Lessons learned: If you have render conditions make sure the condition values are inside the rerendered component.
I'm not familiar enough with richfaces 4 to know the details of the extendedDatatable. A quick search led me to believe that it is not possible to automagically render a row since a row isn't a component.
So you seems to be stuck having to render the individual cells.
Rendering works based on the clientId's of the components. You can find the exact ID's in your html code. Because it works on those clientId's the component you want to render already needs to be rendered.
In other words, you need to wrap your components with a panel that has an id and is rendered per default:
<h:outputPanel layout="block" id="soortPanel">
<h:outputText
value="#{cc.attrs.rowItem.getValue(cc.attrs.id)}"
rendered="#{inactive}">
</h:outputText>
<h:inputText
value="#{field.value}"
rendered="#{active}"/>
</h:outputPanel>
The outputpanel should get an id like: multiOccurenceTable:1:soortPanel and you should be able to render that id.

jsf2 ui:repeat alternate row color

Using varStatus of ui:repeat is helpful to identify the odd and even rows if I display all the records in the list that is mapped to ui:repeat.
However, how do I handle a situation if I choose to display only specific records in the arraylist mapped to ui:repeat ? i.e. say for example that I display a table of students who have only scored more than 75% but my list that is mapped to ui:repeat contains the entire list of students. In this case, alternate row coloring does not work as some times consecutive rows have the same row color assigned to them. Is there an efficient workaround for this ?
Is there a similar feature like rowClasses that h:dataTable uses for ui:repeat?
You can do this by using css condition:
<style type="text/css">
.test1{
display:none;
}
.test2{
display:block;
}
</style>
<ui:repeat value="#{tabview.students}" var="dt">
<div class="#{(dt.scored gt 75) ?'test1':'test2'}">#{dt.model}</div>
</ui:repeat>
For the Odd/Even, you can use the varStatus
<ui:repeat var="item" value="#{myBean.myList}" varStatus="status">
<div class="some-class ${status.even ? 'row-even' : 'row-odd'}"> ... </div>
</ui:repeat>
CSS
.row-even {
background-color: floralwhite;
}
.row-odd {
background-color: gainsboro;
}

Knockout Javascript any strategies for making a foreach checkbox section with a bound observable array

Basically I'm making a repeatable section and I want to have the checked state of all checkboxes pre-supplied by an array.
<div style="height: 100%; border: 1px solid grey; overflow-y: scroll;" id="AssociatedUsers" data-bind="foreach: AllUserList">
<input type='checkbox' class='cSupUser' style="width:20px;margin:2px" value="$data" data-bind='checked: supplierUsers' /><span data-bind='text: $data.Text'></span><br />
</div>
But obviously value="$data" is just returning the string "$data". I've decided to start working on a solution where I just map the array with json strings when I save and load the related data, but this adds complication and feels like a hack, so I was wondering if there is a better way to handle this situation. I would also prefer supplierUsers could just be mapped directly to the viewModel, because I'm going to be generating the response to the server from the viewModel, but it seems like observableArrays don't work for that parameter.
I'm only 3 days into using knockout framework, any help/suggestions are appreciated.
The way i've dealt with this is to use the attr binding for each checkbox. E.G.
<input type="checkbox" data-bind="checked : supplierUsers, attr : { value : $data}" />

Resources