I just inherited a project implemented in JSF. I have the following code which looks fine in Chrome, but Firefox renders the borders on the "empty" list items:
<ul>
<li><a href="/home">Home</li>
<li>
<s:link view="/signup.xhtml" rendered="#{someCondition}">Sign Up</s:link>
</li>
<!-- etc... -->
</ul>
Which ends up looking like:
Is there a JSF tag to conditionally render the <li> ?
If you do it as in #CoolBeans example, you will get a <span> around your <li>. In some cases it might disrupt your layout, besides you don't really want an extra tag under <ul>. To get rid of it, use <ui:fragment rendered="#{condition}" /> around your item instead of <h:panelGroup>.
Also you can use style attribute to hide an item:
<li style="display: #{condition ? 'list-item' : 'none'};" />
No li is vanilla html, not a jsf component.
You can hack it by putting a <h:panelGroup /> around the li element and setting the rendered property on it.
ie.
<h:panelGroup rendered="#{someCondition}">
<li>
<s:link view="/signup.xhtml">Sign Up</s:link>
</li>
</h:panelGroup>
Another option is to use <f:verbatim rendered="#{someCondition}" >, but keep in mind that it has been deprecated in JSF 2.0.
You could also use the core JSTL library:
<c:if test="#{someCondition}">
<li>
<s:link view="/signup.xhtml">Sign Up</s:link>
</li>
</c:if>
I think using this core tag makes the code easier to understand than using the panelGroup tag.
Related
I am having serious trouble using the regular selenium webdriver on one page of my application which is build with Angular. I have added the dependency of ngwebdriver in my pom.xml and so far I have solved some of the issues. Only with the drop-down, I still haven't figured out how to do this. This is the drop-down I am talking about:
<d3-data-list _nghost-c8="" ng-reflect-data-source="[object Object]" ng-
reflect-html-id="documents_glossary_entityPicke" ng-reflect-allow-blank-
option="true" ng-reflect-blank-option-text="All entities" ng-reflect-default-
caption="Choose an entity"><div _ngcontent-c8="" class="dropdown d3-data-
list" id="documents_glossary_entityPicker">
<button _ngcontent-c8="" aria-expanded="true" aria-haspopup="true" class="btn btn-default dropdown-toggle" data-toggle="dropdown" type="button" id="documents_glossary_entityPicker_button">
All entities
<span _ngcontent-c8="" class="caret"
id="documents_glossary_entityPicker_caret"></span>
</button>
<ul _ngcontent-c8="" aria-labelledby="dropdownMenu1" class="dropdown-menu"
ng-reflect-infinite-scroll-handle-in-progress="false"
id="documents_glossary_entityPicker_dropdown">
<!--bindings={
"ng-reflect-ng-if": "true"
}--><li _ngcontent-c8="">
<a _ngcontent-c8=""
id="documents_glossary_entityPicker_blank_option">All entities</a>
</li>
then the options from the drop-down are like this:
</li><li _ngcontent-c8="">
<a _ngcontent-c8="" id="documents_glossary_entityPicker_option_2">Entity three</a>
</li>
The problem is that the order of the elements in my drop-down is not maintained because if an element (entity) is edited on another page then it will be at the bottom of the list. So I can never really know where exactly my element is in the drop-down list.
Is there something like browser.findElement(ByAngular.buttonText("text")) which I can use in my case? Thanks.
I guess you're looking for the filter() or .reduce() possibilities.
For .reduce() check the example here
For .filter() your code should look something like this:
element.all(by.css('ul li a')).filter(function (elm) {
return elm.getAttribute('value').then(function (text) {
return text === "TheValueYouLookFor";
});
}).first().click();
I didn't test this .filter myself, but it's pretty straight forward from the Protractor documentation.
I have, what I would assume, is a pretty common use case. We're rendering a simple "Comments" page using JSF on Wildfly 10.0. Each comment may have a parent comment, and child comments underneath it. Since there's no way to know ahead of time what the structure is, we'd like to create a JSF fragment and <ui:include /> it recursively to render the contents. It would look something like this...
Main page:
<ul class="comments>
<ui:repeat value="#{myObj.comments}" var="comment">
<ui:include src="/WEB-INF/fragments/comment.xhtml">
<ui:param name="comment" value="#{comment}" />
</ui:include>
</ui:repeat>
</ul>
Comment Fragment:
<li><h:outputText value="#{comment.text}">
<ui:fragment rendered="#{not empty comment.childComments}">
<ul class="comments">
<ui:repeat value="#{comment.childComments}" var="comment">
<ui:include src="/WEB-INF/fragments/comment.xhtml">
<ui:param name="comment" value="#{comment}" />
</ui:include>
</ui:repeat>
</ul>
</ui:fragment>
</li>
However, when I run this code, the recursion seems to cause java.lang.StackOverflowError, regardless of how many items there are. Additionally, we see a javax.servlet.ServletException saying, "Could not Resolve Variable [Overflow]"
Is there a reason why this recursive call results in this Exception? Is there a better way to accomplish this? I've tried using <c:forEach /> to iterate over the comments, however when I do this it does not appear to work in JSF. I've tried both the http://xmlns.jcp.org/jsp/jstl/core and http://java.sun.com/jsp/jstl/core namespaces for the taglib, but the <c:forEach /> tag doesn't seem to iterate over my objects. (That is, nothing is being rendered to the page)
Any help you can give would be GREATLY appreciated.
I am currently upgrading from Struts 2.0.11.1 to Struts 2.3.7, but I'm having a problem with the output of Struts tags (like <s:radio>and <s:textarea>. Before, the output of these tags were two <div>'s, one containing the label, and one containing the radiobuttons/textarea. But after I upgraded there is a <br>between the two <div>'s.
Before:
<div id="wwlbl_something_someString" class="wwlbl">
<label for="something_someString" class="desc">Some label</label>
</div>
<div id="wwctrl_something_someString" class="wwctrl">
<!--radiobuttons/textarea -->
</div>
After
<div id="wwlbl_something_someString" class="wwlbl">
<label for="something_someString" class="desc">Some label</label>
</div>
<!-- I don't want this.. -->
<br>
<!-- -->
<div id="wwctrl_something_someString" class="wwctrl">
<!--radiobuttons/textarea -->
</div>
The jsp:
<li class="wwgrp flowClear">
<h3 class="header"><s:text name="something.header"/></h3>
<ol class="nobullets">
<s:radio list="yesNoList"
label="%{getText('something.text.label')}"
name="something.someString"
value="something.some"
disabled="%{readOnly}"/>
</ol>
</li>
#Comment: There are a lot of things in this project that many have never seen before (not in a good way) ;)
Does anyone know if this is something that has changed in Struts, and if so, how to avoid creating the <br>'s?
I actually stumbled across the answer. As an answer to the last comment struts.ui.theme is set to css_xhtml.
http://depressedprogrammer.wordpress.com/2007/04/11/struts-2-form-control-templates/
One quick note, the xhtml_css theme also generates a very worthless <br/> tag between a label and the control which can throw of your entire look, do get rid of this you’ll have to do a .wwgrp br { display: none; } in your CSS stylesheeet.
So I assume doing this will solve the problem, it is something added by struts theme, probably changed when I updated Struts version.
Pointers on how this is usually set up/should be set up is welcomed, as I do not know anything about this.. :)
I'm using JSF, and I have to load a bundle called Extra.
<f:loadBundle basename="com.ni.lib.extra.delivery.ExtraBundle" var="extra" />
Inside that extra variable, there's a value called downtime_notice. Now, if that value is NOT empty, I have to show a css segment with the text contained within the downtime_notice value. Something like this (of course this doesn't work):
if(extra.donwtime_notice!=''){
<div class="pnx-msg pnx-msg-warning clearfix">
<i class="pnx-msg-icon pnx-icon-msg-warning"/>
<span class="pnx-msg-content"><h:outputText value="#{extra.downtime_notice}" escape="false"/></span>
</div>
</br>
}
I can use javascript, just in case.
Any ideas? Thanks!
You can use <ui:fragment> or <h:panelGroup> to conditionally render content. You can use the empty keyword in EL to check if a variable is not null or empty. So, all with all this should do:
<ui:fragment rendered="#{not empty extra.donwtime_notice}">
<div class="pnx-msg pnx-msg-warning clearfix">
<i class="pnx-msg-icon pnx-icon-msg-warning"/>
<span class="pnx-msg-content"><h:outputText value="#{extra.downtime_notice}" escape="false"/></span>
</div>
</ui:fragment>
Or, using <h:panelGroup layout="block"> which renders a <div> already:
<h:panelGroup layout="block" styleClass="pnx-msg pnx-msg-warning clearfix" rendered="#{not empty extra.donwtime_notice}">
<i class="pnx-msg-icon pnx-icon-msg-warning"/>
<span class="pnx-msg-content"><h:outputText value="#{extra.downtime_notice}" escape="false"/></span>
</h:panelGroup>
Note that some may opt to use <f:verbatim> for the job, but this tag is deprecated since JSF2.
See also:
Conditionally displaying JSF components
Alternative to ui:fragment in JSF
Unrelated to the concrete problem, the </br> tag is invalid HTML, so I omitted it form the examples.
I have this piece of code:
<c:if test="#{utils.getCounterOfCharOccurence(hideTypes, ';') != 0}">
<ui:repeat value="#{document.instanceList}" var="instance">
<c:set var="columnRendered" value="true"></c:set>
<c:forEach items="${hideTypes.split(';')}"
var="hideType">
<h:outputText value="#{hideType eq instance.documentInstanceType.mimeType}"/>
<c:if test="#{hideType eq instance.documentInstanceType.mimeType}">
<c:set var="columnRendered" value="false"></c:set>
<h:outputText value="#{columnRendered}|"/>
</c:if>
</c:forEach>
<a:outputPanel rendered="#{columnRendered == 'true'}">
<up:mimeTypeIcon type="#{instance.documentInstanceType.mimeType}"
icon="#{instance.documentInstanceType.iconPath}"
key="#{instance.instanceKey}" referenced="false"/>
</a:outputPanel>
</ui:repeat>
</c:if>
As you see, i render that outputPanel only when columnRendered is true.
Well, there are situations when this (used only for tests to approve what it should do):
<h:outputText value="#{hideType eq instance.documentInstanceType.mimeType}"/>
is true so it should enter in c:if and switch columnRendered to false. But it doesn't, so columnRendered is true forever...
Do you know why?
JSF and JSTL doesn't run in sync as you'd expect from the coding. JSTL runs during build time of the view (when the JSF component tree is to be populated) and JSF runs during render time of the view component tree (when HTML output is to be generated). You can visualize it as follows: JSTL runs first from top to bottom and then hands over the result to JSF which in turn runs from top to bottom again.
In your particular case, the object instance is never present in JSTL.
Instead of c:forEach, you should use ui:repeat and instead of c:if you should use JSF component's rendered attribute. I'd like to give a rewrite of the code, but the usage of hideTypes is a mess. Rather convert it to a List<String> in the model and it'll be much easier to do with pure JSF. Here's a kickoff example assuming that hideTypes is a List<String>:
<h:panelGroup rendered="#{not empty hideTypes}">
<ui:repeat value="#{document.instanceList}" var="instance">
<a:outputPanel rendered="#{!hideTypes.contains(instance.documentInstanceType.mimeType)}">
<up:mimeTypeIcon type="#{instance.documentInstanceType.mimeType}"
icon="#{instance.documentInstanceType.iconPath}"
key="#{instance.instanceKey}" referenced="false"/>
</a:outputPanel>
</ui:repeat>
<h:panelGroup>