accessing var outside ui:repeat JSF2 - jsf

I want to access a variable through out my page. The var is declared inside a ui:repeat element. Heard that the scope of the variable in only inside the repeat tag. I want to load another div on the same page which need the details inside this var. How can I achieve this.
<ui:repeat var="errorDetails"
value="#{adminDashboardController.errorDetails}" varStatus="status">
<tr>
<td>#{errorDetails.issueName}</td>
<td>#{errorDetails.priority}</td>
<td>#{errorDetails.comments}</td>
<td><h:commandButton class="btn btn-primary btn-xs view-issue"
value="View" /></td>
</tr>
</ui:repeat>
<h4 class="modal-title" id="myModalLabel">#{errorDetails.issueName}</h4>

The errorDetails variable is only available in the scope of the ui:repeat.
You have here two options:
HTML/JS solution: Generate HTML code which contains one <h4...>#{errorDetails.issueName}</h4> for each line of your table and use JavaScript to display the right block when pressing on the command button.
I think that this option should be only used for performance reason, because you will generate lot of HTML and because as a JSF developer you usually prefer to avoid coding custom things in JavaScript.
JSF solution (my preferred one): use a backing bean to hold the currently viewed error detail. That would be something like this:
<ui:repeat var="errorDetails" value="#{adminDashboardController.errorDetails}" varStatus="status">
...
<h:commandButton ... action="#{adminDashboardController.showDetails(errorDetails)" update="myModalLabel" />
...
</ui:repeat>
...
<h:panelGroup rendered="#{adminDashboardController.currentDetail != null}">
<h4 class="modal-title" id="myModalLabel">#{adminDashboardController.currentDetail.issueName}</h4>
</h:panelGroup>
The AdminDashboardController.showDetails methods would save the given error detail in a the field currentDetail.

Related

Bootsfaces modal not working inside <h:form>

I am new to JSF and I am currently building a web-auction type of application, based on it. I have also used multiple elements from Bootsfaces. What I would like to do is have an inputText where bidders can type their bids and then press a button that will trigger a Bootsfaces modal. Inside the modal, the bidder will have to confirm that he actually wants to bid, by pressing a commandButton that will eventually "submit" his bid. In order for this to work (if I have understood correctly how JSF works), I need the inputText and the commandButton inside the same h:form element. The only problem is that, whenever I put the code of the modal inside the form, the modal doesn't show up when I press the button that triggers it. My code is the following:
<h:form>
<b:inputText class="bid1" value="#{detailedViewBean.current}" placeholder="Type the amount you would like to bid..." style="width: 90%" onfocus="enableButton('atrigger1')" onblur="bidAmount(this.value, '#{detailedViewBean.previous}')"> <!--current highest bid-->
<f:facet name="prepend">
<h:outputText value="$" />
</f:facet>
<f:facet name="append">
<b:buttonGroup>
<a id="atrigger1" class="btn btn-primary" href="#amodal1" data-toggle="modal">Bid!</a>
</b:buttonGroup>
</f:facet>
</b:inputText>
<b:modal id="amodal1" title="Warning!" styleClass="modalPseudoClass">
<p id="amodal1body"> Are you sure ?</p>
<f:facet name="footer">
<b:button value="Close" dismiss="modal" onclick="return false;"/>
<b:commandButton value="Yes, submit my bid!" id="modalbidbutton" type="button" class="btn btn-primary" data-dismiss="modal" data-toggle="modal" data-target="#amodal2"/>
</f:facet>
</b:modal>
<h:form>
Does anyone know why this might happen or how I can correct it?
Moving the <b:modal /> into a form modifies its id. That's an annoying property of the JSF framework: it sees to it that ids are always unique - and of of the measures to achieve that goal is to prepend the form's id to the id of <b:modal >. Most of the time, this works just great, but sometimes you need the HTML id. Your button uses a jQuery expression, so this is one of those times. Adding insult to injury, JSF uses the colon as a separator, and jQuery doesn't cope well with the colon.
Cutting a long story short, I suggest to use the CSS class of the modal dialog instead of the id. You already gave it a pseudo CSS class. This class doesn't bear any layout information. Instead, you can use it in the button:
<a id="atrigger1" class="btn btn-primary disabled"
href=".modalPseudoClass" data-toggle="modal">Bid!</a>
TL;DR: If you run into trouble with id, replace your jQuery expression ("#id") with a CSS pseudo class expression (".pseudoClass").

Access JSF Custom Tag's id

TL;DR
Is there something like composite's cc.clientId that will give me the id of a custom tag?
Details:
I'd like a custom tag that will render a label, a value, and an icon. When the icon is clicked, a Bootstrap modal is supposed to open up that will edit the value.
<ui:composition>
<div> #{field.label}: #{field.value}
<a class="icon-pencil" data-target="#editForm" data-toggle="modal">
</div>
<h:form id="editForm" class="modal hide fade" role="dialog" ...>
... there's an input here linked to field.value ...
</h:form>
</ui:composition>
I can use the tag with <my:editor />. When I do so within a ui:repeat, an id is prepended to the editForm so that it renders with id j_idt104:editForm. So I need to modify the data-target to include the id.
This would be really easy with a composite component because I have access to the id via cc.clientId:
data-target="\##{cc.clientId}\:editForm"
However, I can't get it to work with a custom tag because I don't know of an EL expression (or something) that will give me access to the id. I could probably wait until after the page is loaded, then use jQuery to inspect the id and set the data-target after the fact, but I was hoping for a more pure-JSF solution.
I'm using JSF 2.1 and Bootstrap 2.3, at the moment.
Answer seems to be no. BalusC says you should replace things like custom tags with "normal" JSF components. In this case, that would mean using the composite component.
If you're deadset on using custom tag, I worked around the issue (with lots of help from the answer here) by using an index in the form's id:
I replaced the ui:repeat with a c:forEach that has access to the item's index:
<table>
<c:forEach items="#{bean.items}" var="item" varStatus="status">
<my:editor index="#{status.index}" ... />
</c:forEach>
</table>
And in the custom tag, I used the index in the data-target:
<tr>
<td>#{label}: #{value}</td>
<td>
<a data-target="\#editForm-#{index}" ... ></a>
<h:form id="editForm-#{index}" ... >
...
</h:form>
</td>
</tr>
The only catch is that c:forEach is a build-time construct (see details in this answer), which is a problem if you need any render-time data (like if you build information up in preRenderView). If you do, then you're better off using ui:repeat with a custom component, and relying on the cc.clientId.

Show some contents inside p:lightBox

How to show some content inside light-box of primefaces as I have to show some information about the image as no. of likes,no. of comments,and also have to provide option to post comments so on and so forth?
On xhtml page I have written this:
<p:lightBox styleClass="imagebox">
<c:forEach var="event1" items="#{event.files}" varStatus="cnt">
<h:outputLink value="#{listOfFilesForEventBean.getImage854By480ProfileUrl(event1)}" title="#{event1.location.locationName}">
<h:graphicImage value="#{listOfFilesForEventBean.getImageIconProfileUrl(event1)}"/>
</h:outputLink>
</c:forEach>
</p:lightBox>
Where files is list of image profiles that I am iterating.
And I want along with the image which is displayed on lightbox some information about the image should be displayed.
I had similar problem. If somebody is still looking for the answer here is my solution.
I did not find easy way to have some additional controls inside p:lightBox item.
Guess it assigns own JavaScript handlers to all its children and that makes a problem.
Also I had the problems with using commandButton inside ui:repeat. So I'm using my own implementation of p:lightBox and p:remoteCommand to call other actions(like post comments, delete image etc). Something like that:
<p:remoteCommand name="deleteImage" update="imagesGrid"
actionListener="#{imageBean.deleteImage}" />
<h:panelGroup id="imagesGrid">
<ui:repeat var="item" value="#{imageBean.list}">
<div class="docThumbContainer">
<div class="docPlaceholder"></div>
<div class="docThumbImage">
<h:outputLink value="/images?id=#{item.imageId}">
<h:graphicImage value="data:image/jpg;base64,#{item.thumbnail}"
alt="" />
</h:outputLink>
</div>
<div class="docThumbButtons">
<p:commandButton type="button" value="Delete"
onclick="deleteImage([{name:'imageId', value:#{item.imageId}}]);" />
</div>
</div>
</ui:repeat>
</h:panelGroup>
ImageBean:
public void deleteImage(ActionEvent event) {
ImageManager manager = getManager();
manager.deleteImage(StringUtil.parseInt(getUrlParameter("imageId"), -1));
}
Of course it is simplified replacement for p:lightBox. To show the full image in the overlay with prev/next buttons you need additional work. E.g. using p:dialog etc

Disabling items in JavaServer Faces

I’m new in JavaServer Faces.
I have a simply form:
<div id="respond" class="comment-respond">
<h3 id="reply-title" class="comment-reply-title">#{msgs.leavereply}</h3>
<h1>#{!forumsBean.activeWithProject}</h1>
<h:form>
<h:inputTextarea value="#{forumpostsBean.text}" style="resize:none"/>
<h:commandButton value="#{msgs.add}" action="#{forumpostsBean.addForumpost}"/>
</h:form>
</div>
By clicking command button all it’s fine, executes method forumpostsBean.addForumpost.
But when I modify code to this:
<div id="respond" class="comment-respond">
<h3 id="reply-title" class="comment-reply-title">#{msgs.leavereply}</h3>
<h1>#{!forumsBean.activeWithProject}</h1>
<h:form>
<h:inputTextarea value="#{forumpostsBean.text}" style="resize:none" disabled="#{not forumsBean.active}"/>
<h:commandButton value="#{msgs.add}" action="#{forumpostsBean.addForumpost}" disabled="#{not forumsBean.active}"/>
</h:form>
</div>
When items not disabled, current page only have refreshed, but method forumpostsBean.addForumpost don’t executes.
In both variants, <h1>#{!forumsBean.activeWithProject}</h1> shows correct value.
You have 2 beans? one called forumpostsBean and another just forumsBean? I can't see if you've got them both but maybe its the main error? as the comment above says, maybe your logic is out of place.
You may want to use rendered="" on the button rather that just disabling it so its not part of the dom at all upon page load and then use an ajax call when you type data in your input field to do partial ajax render the div again and show it. good for testing.

Assign unique ids to <div> inside <c:forEach>

I want to assign a unique id for the <div> enclosed in the <c:forEach>. Whenever the page is rendered all the <div>s generated by the <c:forEach> have the same id. Is there any way to assign unique id for all the divs generated by the <c:forEach>? I have tried using <ui:repeat> but I was having issues with it so I decided to stick with <c:forEach>.
Facelet:
<c:forEach var="p" items="#{statusBean.statusList}">
<h:form>
<div class="status">
// Content
</div>
</h:form>
</c:forEach>
Use the c:forEach attribute varStatus to define a variable that will contain the status of the loop. Then you can use it in your template like this:
<c:forEach var="p" items="#{statusBean.statusList}" varStatus="loop">
<h:form>
<div class="status_#{loop.count}">
// Content
</div>
</h:form>
</c:forEach>
You can also use #{loop.index} if you want it initiated with 0.
Try using a <h:panelGroup> or another JSF component to render your divs.
http://docs.oracle.com/javaee/5/javaserverfaces/1.2/docs/tlddocs/
This will cause unique IDs to get generated for you.

Resources