Displaying command button with image only - jsf

I am trying to display a button with image only on my page but all I see is the button with ^. Following is the code for my button:
<p:commandButton onclick="lineSearch.show();" image="backgroung-image:url(/images/title_logo.jpg)"/>
<p:dialog header="Modal Dialog" widgetVar="lineSearch" modal="true" onCloseUpdate="lineIdField" showEffect="scale" hideEffect="explode">
<ui:include src="lineSearch.xhtml"/>
</p:dialog>
The image does exist in the images folder. The button is rendered as following in the page:
<button id="j_idt23:j_idt27" class="ui-button ui-widget ui-state-default ui-corner-all ui-button-icon-only" type="submit" onclick="lineSearch.show();;PrimeFaces.ab({formId:'j_idt23',source:'j_idt23:j_idt27',process:'#all'});return false;" name="j_idt23:j_idt27" role="button" aria-disabled="false">
<span class="ui-button-icon-primary ui-icon backgroung-image:url(/images/title_logo.jpg)"></span>
<span class="ui-button-text">ui-button</span>
</button>
<script type="text/javascript">
widget_j_idt23_j_idt27 = new PrimeFaces.widget.CommandButton('j_idt23:j_idt27', {text:false,icons:{primary:'backgroung-image:url(/images/title_logo.jpg)'}});
</script>
Thanks!!!

The image attribute has to refer a CSS class name, not a plain CSS property. So, this should do:
<p:commandButton image="someCssClassName" />
with the following in your CSS:
.someCssClassName {
background-image: url(images/title_logo.jpg)
}
Please note that I fixed the major typo in property name and also removed the leading slash from the image URL, it would otherwise be resolved relative to the site's domain root; the above expects the title_logo.jpg to be inside an /image folder which in turn is in the folder where the CSS file resides.
However, this one is less clumsy, I think:
<p:commandLink action="#{bean.submit}">
<h:graphicImage name="images/title_logo.jpg" />
</p:commandLink>

I suggest to use "P:coomandLink" and "P:graphicImage" at the same time.
I have created a folder under webapps, and put my jpg file under this folder.
This code works fine for me.
good luck.
<p:commandLink action="#{MyClass.myMethod}">
<p:graphicImage value="images/Max-Burger.jpg" />
</p:commandLink>

Put this on your css style:
.dolar-icon {
background-image: url("#{facesContext.externalContext.request.contextPath}/resources/imagenes/dolar.png") !important;}
Now you can use the icon "dolar-icon" that you defined in your css.
<p:commandButton action="#{as.fe}" icon="dolar-icon"/>

Even easier:
<p:commandButton icon="ui-icon-XXXXX">
Diferent icons you can choose: https://api.jqueryui.com/theming/icons/ and http://www.primefaces.org/showcase/ui/misc/fa.xhtml

Related

How to open multiple component in p:inplace at once

i need to make all component editable when i clicked on h:commandLink
This my code
<p:dataTable styleClass="borderless" id="projectsTable" var="o" value="#{order.orderList}">
<p:column>
<div class="tasks">
<div class="task-item task-success">
<h:form>
<div class="task-text">
<div class="form-group">
<h:outputLabel for="projectName" value="Project Name:" />
<p:inplace effectSpeed="fast" editor="true">
<p:inputText styleClass="form-control" value="#{o.productName}" required="true" label="text" />
</p:inplace>
</div>
<div class="form-group">
<h:outputLabel for="projectURL" value="Project URL:" />
<p:inplace effectSpeed="fast" editor="true">
<p:inputText styleClass="form-control" value="#{o.price}" required="true" label="text" />
</p:inplace>
</div>
</div>
<div class="task-footer">
<div class="pull-left">
<h:commandLink >
<span class="glyphicon glyphicon-ok-circle" aria-hidden="true"></span> EDIT
</h:commandLink>
</div>
<div class="pull-right">
<h:commandLink action="#{order.deleteAction(o)}" >
<span class="glyphicon glyphicon-remove-circle" aria-hidden="true"></span> Delete
</h:commandLink>
</div>
</div>
</h:form>
</div>
</div>
that's link i need to click on it and open all h:inputText
<h:commandLink action="#{order.update(o)}">
<span class="glyphicon glyphicon-ok-circle" aria-hidden="true">
</span> EDIT
</h:commandLink>
Such as linkedIn in editProfile page when click on button appear all editable components
Examples:
Befor click button
After clicked button
First of all, every PrimeFaces component has a javascript representation which is acessible through the widgetVar.
The Inplace's widget has a method called show() that you can use to show the input field for it. Check this code out:
<p:inplace ... widgetVar="myinplace">
<p:inputText ... />
</p:inplace>
<!-- this button's click will show the input -->
<button onclick="myinplace.show()">Click Me</button>
I suggest you to set the widgetVar attribute for the inplace components and call the show method on each one of them inside a function that you can use everywhere you want:
<script>
function showInplaces() {
myinplace1.show();
myinplace2.show();
...
}
Cheers
During my lunchbreak I was curious, so I did have a quick look.
I looked at the generated source in the showcase of the first item:
<span id="j_idt88:basic" class="ui-inplace ui-hidden-container" data-widget="widget_j_idt88_basic">
<span id="j_idt88:basic_display" class="ui-inplace-display" style="display:inline">Edit Me</span>
<span id="j_idt88:basic_content" class="ui-inplace-content" style="display:none">
<input id="j_idt88:j_idt91" name="j_idt88:j_idt91" value="Edit Me" class="ui-inputfield ui-inputtext ui-widget ui-state-default ui-corner-all" role="textbox" aria-disabled="false" aria-readonly="false" type="text" />
</span>
</span>
I noticed the class='ui-inplace-display' class which is on each 'component. The following jquery code selects all inplace components that can be clicked:
$('.ui-inplace-display')
I tried this in the FireFox developer console resulting in the following output:
Object { length: 5, prevObject: Object, context: HTMLDocument → inplace.xhtml, selector: ".ui-inplace-display", 5 more… }
I know you can enable the editing by clicking on an item and so I had to find a way to click on each one. Fortunately, you can give each of them a click by just appending .click() to the selector. It will be applied to each of the components:
$('.ui-inplace-display').click()
And like mentioned, you do not need any jsf button for this, just a plain html one to execute the javascript in an onlclick:
<input onclick="$('.ui-inplace-display').click()" value="Click to edit" type="button">
works perfectly.
As you can see, it pays to learn the basics of webdevelopment before diving into using more complex frameworks since no framework ever solves all of your problems and from time to time (more often then you think), you do need a little low-level javascript

How to prevent a4j:status from flickering when polled by a4j:poll

I am working on a project that uses a rich:tree element that, when expanded, should display a processing animation nearby using a4j:status. The problem that I am running into is that the tree is rerendered by multiple other elements. The one that I believe to be causing the most trouble is an a4j:push element that rerenders the tree every second. This rerendering is causing the status element to change states when it shouldn't, causing a flickering on screen.
My status element:
<a:outputPanel id="working_animation" style="display: block; height: 1px">
<!-- Working animation -->
<a:status stopText=" " id="header_progress">
<a:facet name="start">
<a:outputPanel id="header_working" rendered="#{rich:element('tree_state.value').value}" style="padding-left: 16.5em;">
<span id="l-1"></span>
<span id="l-2"></span>
<span id="l-3"></span>
<span id="l-4"></span>
<span id="l-5"></span>
<span id="l-6"></span>
</a:outputPanel>
</a:facet>
</a:status>
</a:outputPanel>
Part of the tree element:
<rich:tree
id="sectionTree"
switchType="ajax"
value="#{sectionAction.sectionNodes}"
var="node"
nodeFace="#{node.nodeType}"
rightClickSelection="true"
ajaxSubmitSelection="true"
iconCollapsed="/img/treenode/collapsed.png"
iconExpanded="/img/treenode/expanded.png"
componentState="#{sectionAction.treeState}">
<rich:changeExpandListener binding="#{sectionAction}" />
<rich:nodeSelectListener binding="#{sectionAction}" />
beyond that are node definitions
The push element:
<h:form>
<a:push
eventProducer="#{loggedUser.registerLoginListener}"
interval="1000"
reRender="sectionTree">
</a:push>
<a:push
eventProducer="#{loggedUser.registerStudentListener}"
interval="2000"
reRender="sectionTree">
</a:push>
</h:form>
There are two options how to disable status:
Wrap a:push tags by a:region.
Specify status="none" attribute for a:push.
Refer to the livedemo for more details: http://livedemo.exadel.com/richfaces-demo/richfaces/status.jsf?c=status&tab=usage

Validation failed javascript callback in JSF

I have a template in which I can add a CSS error class to a div when the validation of a component has failed and it renders a pretty nice effect on the browser.
Now, I don't need to add a css class to a component (this won't help me), but rather I need to change the css of the html that surrounds it, this is pretty simple with jQuery, however I can't seem to find a javascript callback for failed validation, is this possible? I'm also using primefaces (in case they provide such capabilities).
Markup:
<div class="control-group ERROR_CLASS_GOES_HERE_IF_VALIDATION_FAILED">
<label class="control-label">Input value:</label>
<div class="controls">
<h:inputText class=" inputbox" type="text" required="true" /> <!--Component that can fail -->
</div>
</div>
if the input text is empty, I need the div that wraps the "control group" to have an extra class. I can turn it into a <h:panelGroup> so it is a JSF component but still I wouldn't know how to do it. Javascript seems easier as I can do a:
jQuery("#ID_OF_DIV").addClass("error_class")
Just let JSF/EL conditionally print the class based on FacesContext#isValidationFailed().
<div class="control-group #{facesContext.validationFailed ? 'error_class' : ''}">
You only need to ensure that this element is covered by ajax update/render.
Another way would be hooking on the oncomplete event of an arbitrary PrimeFaces ajax based component. There's an args object available in the scope which in turn has a validationFailed property. E.g. <p:commandButton oncomplete> or even <p:ajaxStatus oncomplete>.
<p:ajaxStatus ... oncomplete="if (args && args.validationFailed) $('#ID_OF_DIV').addClass('error_class')">
If you want to do everything on the client side.
<h:outputText class="samplecls" rendered="#{facesContext.validationFailed}"
value="Please enter all the required fields">
</h:outputText>
<div class="control-group ERROR_CLASS_GOES_HERE_IF_VALIDATION_FAILED">
<label class="control-label">Input value:</label>
<div class="controls">
<h:inputText class=" inputbox" type="text" required="true" /> <!--Component that can fail -->
</div>
</div>
Javascript/Jquery
This class will exist in DOM only validation fails by rendered="#{facesContext.validationFailed}"
$(window).load(function(){
if($('.samplecls').length>0){
$("#ID_OF_DIV").addClass("error_class");
}
});

Inconsistent behavior between <p:commandLink> and <p:commandButton>

I have a delete confirmation dialog:
<p:confirmDialog id="deleteConfirmDialog"
header="#{i18n['confirm-deletion']}"
widgetVar="pnp_delete_confirmDialog" closeable="false"
appendToBody="true">
<f:facet name="message">
<h:outputFormat id="deleteConfirmMessage"
value="#{i18n['confirm-subscription-deletion']}">
<f:param value="#{subscriptions.deleteSelected.title}" />
</h:outputFormat>
</f:facet>
<h:form id="pnpConfirmDeleteForm">
<p:commandButton id="deleteActionConfirmed"
action="#{subscriptions.delete}" value="#{i18n['delete']}"
type="button" process="#this" update=":pnpEditForm :pnpExistingForm"
oncomplete="pnp_delete_confirmDialog.hide()" />
<p:commandLink id="deleteActionConfirmedLink"
action="#{subscriptions.delete}" process="#this"
update=":pnpEditForm :pnpExistingForm"
oncomplete="pnp_delete_confirmDialog.hide()">#{i18n['delete']}</p:commandLink>
<p:commandButton id="deleteActionCancelled" value="#{i18n['cancel']}"
type="button" onclick="pnp_delete_confirmDialog.hide()" />
</h:form>
</p:confirmDialog>
You will notice that the deleteActionConfirmed button and the deleteActionConfirmedLink link have the exact same action, process, update, and oncomplete attributes. However, the link works as expected and the button does nothing. Looking at the generated markup:
<form enctype="application/x-www-form-urlencoded"
action="/primefaces-quickstart/xhtml/pnp-configuration.xhtml" method="post"
name="pnpConfirmDeleteForm" id="pnpConfirmDeleteForm">
<input type="hidden" value="pnpConfirmDeleteForm" name="pnpConfirmDeleteForm">
<button type="button"
class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only"
name="pnpConfirmDeleteForm:deleteActionConfirmed"
id="pnpConfirmDeleteForm:deleteActionConfirmed" role="button"
aria-disabled="false">
<span class="ui-button-text">Delete</span>
</button>
<a
onclick="PrimeFaces.ab({source:'pnpConfirmDeleteForm:deleteActionConfirmedLink',process:'pnpConfirmDeleteForm:deleteActionConfirmedLink',update:'pnpEditForm pnpExistingForm',oncomplete:function(xhr,status,args){pnp_delete_confirmDialog.hide();}});return false;"
class="ui-commandlink" href="#"
id="pnpConfirmDeleteForm:deleteActionConfirmedLink">Delete</a>
<button type="button" onclick="pnp_delete_confirmDialog.hide();"
class="ui-button ui-widget ui-state-default ui-corner-all ui-button-text-only"
name="pnpConfirmDeleteForm:deleteActionCancelled"
id="pnpConfirmDeleteForm:deleteActionCancelled" role="button"
aria-disabled="false">
<span class="ui-button-text">Cancel</span>
</button>
<input type="hidden" autocomplete="off"
value="7076449462381240234:-2976764560029615800" id="javax.faces.ViewState"
name="javax.faces.ViewState">
</form>
You can see that there is no onclick generated for the button, where there is for the link. Am I missing something or is this a bug in primefaces? If a bug, is there a workaround other than using links with styles to make them look like buttons?
I am using mojarra 2.1.14 with primefaces 3.4.2 on tomcat 6.0.32 (servlet 2.5, el 2.1).
ARGH... Simple mistake. The type attribute of the p:commandButton determines the behavior. It appears that by setting type='button' I have turned it into a (taken from the primefaces user guide):
Push Buttons
Push buttons are used to execute custom javascript
without causing an ajax/non-ajax request. To create a push button set
type as "button".
<p:commandButton type="button" value="Alert"
onclick="alert(‘Prime’)" />
Switching type to submit fixed this issue. Lesson learned... If using buttons, type='button' causes the component to ignore any server side action.

How to make an image button in JSF

I want to have a component that looks like a button, but instead of text it should contain an image.
Because the standard button does not offer this functionality, I tried to use a <h:commandLink>:
<h:commandLink action="#{some_action}">
<p:panel styleClass="some_style">
<h:graphicImage value="#{some_image}">
</p:panel>
</h:commandLink>
This doesn't work. The <h:commandLink> is translated into an <a> tag, and the <p:panel> into a <div>. <a>-tags may not contain <div>-tags, so the <div>-tag is automatically placed outside the <a>-tag.
The result is that only the image is clickable, not the surrounding panel which is styled to look like a button. Is there a way to make the surrounding panel part of the link, or to put an image inside a button?
My project uses JSF and the Primefaces library:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:composite="http://java.sun.com/jsf/composite"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.prime.com.tr/ui">
There are a couple ways you can add an image to a commandButton:
Using the image attribute
<h:commandButton action="#{some_action}" image="button.gif" />
Absolute or relative URL of the image
to be displayed for this button. If
specified, this "input" element will
be of type "image". Otherwise, it will
be of the type specified by the "type"
property with a label specified by the
"value" property.
Use CSS
<h:commandButton action="#{some_action}" styleClass="button" />
.button {
background: white url('button.gif') no-repeat top;
}
You could just move the div outside e.g.
<div class="myButton">
<h:commandLink action="#{some_action}" styleClass="clickAll">
<h:graphicImage value="#{some_image}">
</h:commandLink>
</div>
And style the div that way. Just make the anchor (a tag) display as a block and it should fill the whole div so it's all clickable. For example in your CSS go:
.clickAll{
display:block;
}
If you can use an icon from PrimeFaces/JSF, then there is a simple and sound solution is
<p:column>
<p:commandButton icon="ui-icon-wrench"
style="border-width:0;background:none;"/>
</p:column>
It may help to avoid JavaScript code in JSF.
If the image does not fit then add properties to a сss class:
.button {
background: white url('button.gif') no-repeat top;
width: 32px; // button width
height: 32px; // button height
background-size: contain;
border: none; // hide border of button
}

Resources