How to make an image button in JSF - 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
}

Related

PrimeFaces inputTextarea is not auto resizable

I want to make resizeable inputTextarea in dataTable. Written next xhtml by the Primefaces-Users-Guide and ShowCase
<p:dataTable id="valueSelection" var="value"
value="#{dtBasicView.cars}">
<p:column headerText="Test" >
<h:inputTextarea value="#{car.brand}" autoResize="true" cols="38"
style="overflow: hidden; overflow-wrap: break-word; resize: none;"/>
</p:column>
</p:dataTable>
But when the text in inputTextarea is only one row, the height is for two row.
In FireFox the element row is (without class):
<textarea id="mainform:tabPanel:valueSelection:1:j_idt132" name="mainform:tabPanel:valueSelection:1:j_idt132" cols="38" style="overflow: hidden; overflow-wrap: break-word; resize: none;" disabled="disabled">STEVE6666</textarea>
And the generated css is (without height):
element {
overflow: hidden;
overflow-wrap: break-word;
resize: none;
}
Why primefaces does not generate height in css and class attribute in html tag?
In your example you used h:inputTextarea, which is the default implementation of the component in JSF, and thus, does not support auto resize.
Try to use p:inputTextarea, which is the PrimeFaces one, and check if the desired behavior will happen.

Summarize and expand long text output in JSF

My question is similar to How to hide/show more text within a certain length (like youtube) or Readmore but for JSF. It's a very common metaphor on the web.
I have a page that displays a section with user-entered text, which may be short or it may be long. If it's long, the table height is unmanageable, so in those cases I'd like to show a portion of the text followed by a "(more)" link that will reveal the remaining text. After expansion, there would be a "(less)" link as well. (Note: My particular case has just text with newlines in it.)
Are there any pre-existing JSF components to do this? I've checked PrimeFaces and OmniFaces and ButterFaces and was surprised that I didn't see anything that jumped out at me as having this functionality. I'm sure I could make my own custom component using one of the techniques in the referenced StackOverflow question, but I'd rather not reinvent the wheel.
Maybe this is a good extension for ButterFaces. I will think about it.
But why do you need a JSF component? Just use Readmore.js.
Here's a quick composite component that uses readmore that can be used as a starting point for anyone else wanting something like this. There are a few unrelated features in it that are kind of hacked in (hard-coded style, hard-coded options to the readmore() function, etc.) that you would probably want to improve and customize. Suggestions for improvement welcome.
Parameters
value (String, Required): The text to display. Expected to be plain text with empty lines.
cols (integer, default=40): The number of columns to limit the width of the containing div to. If less than or equal to 0, then don't limit the width.
readmore (boolean, default=false): Whether to use the Readmore feature.
textonly (boolean, default=false): By default, the component assigns a "readonly" class to the containing div. Setting textonly to true does not assign the "readonly" class to the containing div.
Location: Under /resources/{samplelibrary}/readOnlyTextArea.xhtml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:composite="http://java.sun.com/jsf/composite"
>
<composite:interface>
<composite:attribute name="cols" default="40" type="java.lang.Integer"/>
<composite:attribute name="value" required="true"/>
<composite:attribute name="readmore" default="false" type="java.lang.Boolean"/>
<composite:attribute name="textonly" default="false" type="java.lang.Boolean"/>
</composite:interface>
<composite:implementation>
<h:outputScript library="samplelibrary" name="readmore.min.js" target="head"/>
<div id="#{cc.clientId}_div" class="#{cc.attrs.textonly?'':'readonly'}"
style="overflow: hidden; white-space: pre-wrap; #{cc.attrs.readmore ? '' : 'min-height: 1.3em;'} #{(cc.attrs.cols gt 0) ? 'width: '.concat(cc.attrs.cols / 2.09).concat('em; padding: 2px 2px 2px 2px;') : ''}">
<h:outputText value="#{cc.attrs.value}"
/></div>
<ui:fragment rendered="#{cc.attrs.readmore}">
<script type="text/javascript">
$(window).ready(function() {
var comps = $(document.getElementById('#{cc.clientId}_div'));
comps.readmore({speed:300,collapsedHeight:54});
});
</script>
</ui:fragment>
</composite:implementation>
</html>
Here's some CSS for the readonly CSS class:
.readonly
{
border: 1px solid #999;
background-color: #eee;
color: #333;
}

Can I show tooltip for a disabled command button in primefaces?

Is there a feature that displayable tooltip for disabled commandButton in primefaces.
If you wont find a way to show tooltip on the disabled button you can always try wrap it with some
<h:panelGroup></h:panelGroup> which will turn into span
or with
<h:panelGroup layout="block"></h:panelGroup> which will turn into div
And try to apply the tooltip to the wrapper...
In this question explains #Kukeltje why tooltips do not work on a disabled commandButton: PrimeFaces 6.2 commandButton title not working when commandbutton is disabled
The class .ui-state.disabled is added to the button if its disabled attribute is set to true:
.ui-state-disabled {
cursor: default !important;
pointer-events: none;
}
In order to display the tooltip anyways you could create something like this:
<p:commandButton id="testButton" disabled="true"
action="yourAction" styleClass="showTooltip" value="Click me!" />
In your css file add the following rule:
.ui-state-disabled.showTooltip{
pointer-events: all;
}
If an element has both classes ui-state-disabled and showTooltip the tooltip will be displayed anyways.
I would like to extend Daniel's answer. You need to insert overlay block over disabled button and apply tooltip on it. Simple wrapping button in h:panelGroup won't be so helpful.
<h:panelGroup styleClass="display: inline-block; position: relative;">
<p:commandButton disabled="#{controller.isDisabled()}" ... />
<h:panelGroup styleClass="display: block; height: 100%; width: 100%; position: absolute; top: 0px; left: 0px;"
rendered="#{controller.isDisabled()}"
id="disabledBtnOverlay" />
</h:panelGroup>
<p:tooltip for="disabledBtnOverlay" rendered="#{controller.isDisabled()}" />
A way to make a disabled button or inputtext to show a tooltip is creating a global tooltip and in the inputtext or button a title, like this:
<p:tooltip />
<p:inputText id="inputTextID" disabled="true" value="Your value"
title="TooltipMessage" />
Though it won't show any styles, dunno why

Is there any rich text editor component for JSF RI?

I am using JSF RI 1.1. How to add rich text editor component? Is there any rich text editor component available?
I am displaying set of images horizontally using the below code. Selected image is stored in database. while showing the images in edit mode, how to highlight the previously selected image?
<t:dataList
var="item"
value="#{occasionBean.messageInfo}"
layout="simple">
<h:commandLink action="#{occasionBean.selectedImage}" >
<h:graphicImage
width="100" height="100"
url="#{item.imageSnapUrl}"
onclick="return setMsgId(this.id,{item.img_id},'{item.imageUrl}');"
id="test">
</h:graphicImage>
</h:commandLink>
</t:dataList>
Richfaces has editor component.
1) Mojarra Scales has a htmlEditor component.
(source: kenai.com)
2) Add a styleClass conditionally.
styleClass="#{item.previouslySelected ? 'selected' : ''}"
with this getter
public boolean isPreviouslySelected() {
return previouslySelected;
}
and this CSS
img.selected {
border: 2px solid red; /* Use whatever highlight style here. */
}

newbie JSF question - How to achieve this layout?

I'm trying to achieve the layout shown here
Each of the panels should be linked to a backing bean from which I will later add differrent components according to context.
I tried using panelgrid but could not achieve this look.
I would prefer to use just JSF for this but if impossible or too complicated RichFaces is ok too.
Thanks!!
It's not only matter of JSF/HTML, but it's also a matter of CSS. The above layout can basically already be achieved as follows:
<h:panelGroup id="header" layout="block"></h:panelGroup>
<h:panelGroup id="leftcol" layout="block"></h:panelGroup>
<h:panelGroup id="rightcol" layout="block"></h:panelGroup>
(which generates the following HTML)
<div id="header"></div>
<div id="leftcol"></div>
<div id="rightcol"></div>
You can style/position it using CSS like as:
#header {
width: 100%;
height: 100px;
}
#leftcol {
width: 200px;
float: left;
}
#rightcol {
float: left;
}
That's all.
You can use the HTML code with which you have achieved the above layout. I.e.
<table>
<tr>..</tr>
<tr>..</tr>
</table>
However, the table-less layouts are preferred - i.e. using <div> tags. (see here)

Resources