I have a little trouble with tag h:selectOneMenu, I just want to add some background image to option, such as avatar of user.
Follow styling options in h:selectOneMenu - by balusC
I had tried to render options with its own style css.
<h:selectOneMenu id="dropListUser"
value="#{myController.myUserObject.userid}">
<f:attribute name="avatar" value="#{true}"></f:attribute>
<f:attribute name="key" value="somthing"></f:attribute>
<f:attribute name="height" value="32"></f:attribute>
<f:attribute name="width" value="32"></f:attribute>
<f:selectItems value="#{myController.listOfUsers}" var="item" itemLabel="#{item.username}" itemValue="#{item.userid}"/>
</h:selectOneMenu>
It work great with height, width and key, but with avatar(or any attribute contains value with #{} expression) server bean could not get it.
Try to printout all key name:
Iterator itr = component.getAttributes().keySet().iterator();
while(itr.hasNext()){
System.out.println(itr.next().toString());
}
there is no key with name avatar :
--------------------------------
height
javax.faces.component.VIEW_LOCATION_KEY
com.sun.faces.facelets.MARK_ID
key
width
width: 32 height: 32 style null?: true
--------------------------------
ps: by the way,Is there any one know how to create custom taglib that extends h:selectOneMenu :-?
ps2: In the fact, If I could get myController.listOfUsers
in <f:selectItems value="#{myController.listOfUsers}" var="item" itemLabel="#{item.username}" itemValue="#{item.userid}"/> in my custom render bean, it could be better
Woof, I don't know why or how, but when try print out all of key names from component.getAttributes() also component.getAttributes().containsKey("avatar") return that avatar is not exist, BUT I really can get avatar value, my trouble was solved ^^" just remove code that check the key exist or not
Related
I have a datatable with primefaces:
<p:dataTable var="wapsoplandtl" id="wapsoplandtlList" widgetVar="wapsoplandtlList" value="#{exportController.wapsoplandtls}"
paginator="true" rows="50" scrollable="true" scrollWidth="2500px;" styleClass="borderless"
paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {CurrentPageReport}"
currentPageReportTemplate="{startRecord} - {endRecord} of {totalRecords}" paginatorPosition="bottom"
rowsPerPageTemplate="10,25,50" rowKey="#{wapsoplandtl.dtlsys}">
and produce something like this:
As you can see, it has scrollwidth attribute, but the header got scrolled to the far right. I want only scroll the content of datatable, not the header and footer (paging). Can anyone help me?
This can be done by CSS only, forget about the scrollable attribute of the <p:datatable> component, apparently it will always overflow the whole table, and not just the content.
In this case, do the following:
Remove the scrollable and scrollWidth attribute from your <p:datatable> component;
Include another CSS class (any name, but keep this name to be used later, in this case I will use the name 'overflow-content') in the styleClass attribute from <p:datatable>;
Include the following CSS rule in your page:
-
.overflow-content .ui-datatable-tablewrapper table {
overflow: auto;
width: 2500px;
}
The result will be something like this:
For this you need to first add the option scrollX: true and should add css to table width:100% inline.
$('#example').dataTable( {
"scrollX": true
} );
and you are done.
I am using PF v. 5.3.5 and JSF v. 2.2.8.
<p:tree value="#{userFiltersBean.objectsTreeModel}" var="node" hideRootNode="true" styleClass="filtersTree">
<p:treeNode icon="">
My CSS class is below:
.ui-treenode-icon{
background: url("#{node.leafIcon}") no-repeat top !important;
}
I see the same icon in each treeNode that it is not desired. This icon is for the final treeNode in the tree.
However, I want to iterate trough them that each treeNode has his own icon.
NOTE The size of tree is different on each environment and it is created dynamically.
How can I do this, please?
Please, see current PF version here.
The desired Icefaces version is here.
Thanks in advance.
In the Api-Documentation (http://www.primefaces.org/showcase/ui/data/tree/basic.xhtml -> Documentation Tab) it says you could do it like this:
<p: tree value="#{bean.root}" var="doc">
<p:treeNode type="mp3" icon="ui-icon ui-icon-video">
<h:outputText value="#{doc.name}" />
</p:treeNode>
<p:treeNode type="document" icon="ui-icon ui-icon-image-document">
<h:outputText value="#{doc.name}" />
</p:treeNode>
</p:Tree>
So in the backing Bean you have to give the Node a name, which will be the p:treeNode type. So as far as I understand
TreeNode mp3 = new TreeNode("mp3", "some music");
would do the linking for
<p:treeNode type="mp3" ... />
Let me know if it helped.
Cheers
kyhu :)
SOLVED without css
I solved by inserting a h:graphicImage inside treeNode without facet. it now as I needed and how it was done in the previous version.
<p:tree value="#{userFiltersBean.objectsTreeModel}" var="node" hideRootNode="true" styleClass="filtersTree"
selectionMode="checkbox">
<p:treeNode>
<h:graphicImage value="#{node.leafIcon}" />
<h:outputText value="#{node.text}" />
</p:treeNode>
</p:tree>
Having different values for each element with one CSS class is not possible. You would have to create a class for each icon, like so:
my-treenode-icon-1 {
background: url("/resources/img/treenode/icon-1.jpg") no-repeat top !important;
}
my-treenode-icon-2 {
background: url("/resources/img/treenode/icon-2.jpg") no-repeat top !important;
}
and then in iteration use icon name instead of path (if you have a path in database you can slice last part of it and take only the image name which will be class name).
<p:tree value="#{userFiltersBean.objectsTreeModel}" var="node" hideRootNode="true" styleClass="filtersTree">
<p:treeNode icon="my-treenode-#{node.iconName}">
I want to add a custom style to a selectManyButton in primefaces 5.1. The style I want to change is bound to the .ui-state-active class. When I change this class, I get my custom style for the selectManyButton, but all other elements which refer to this styleclass, changed, too. How can I make that just one certain element change to the defined style?
<p:selectManyButton value="#{projektCriteriaBean.selectedOptions}" >
<f:selectItems value="#{projektCriteriaBean.yearSelection}" />
<p:ajax listener="#{projektCriteriaBean.changeDate}" update=":form:startDate,:form:endDate" />
</p:selectManyButton>
You need to specify an id or styleClass for your button.
<h:form id="my_form">
<p:selectManyButton id="my_unique_selector" styleClass="generic-selector"
value="#{projektCriteriaBean.selectedOptions}">
<!-- ... -->
</p:selectManyButton>
</h:form>
The difference between id and class is a HTML matter, that is explained here.
I've included the h:form because the parent naming containers affect the resulting client id. More on that here.
Now you can stylize your button by class:
.generic-selector .ui-state-active {
background-color: red;
}
Or by id:
#my_form\:my_unique_selector .ui-state-active {
background-color: red;
}
The colon is a JSF naming container default separator char. It needs to be escaped with a backslash, because : has a special meaning in CSS. More on that here.
I want p:selectOneMenu width to be auto regarding to the parent cell not regarding to the values it has.
<p:panelGrid>
<p:row>
<p:column><p:outputLabel value="Value01" for="idInput01"/></p:column>
<p:column><p:inputText value="#{bean.input01}" id="idInput01" /></p:column>
<p:column><p:outputLabel value="Value02" for="idSelect" /></p:column>
<p:column>
<p:selectOneMenu value="#{bean.selectedObject}" id="idSelect" converter="objectConverter">
<f:selectItems value="#{bean.objectsList}" var="varObject" itemLabel="#{varObject.label}" itemValue="#{varObject}" />
</p:selectOneMenu>
</p:column>
</p:row>
</p:panelGrid>
What I've got :
What I'm expecting :
Note: I don't want to specify a fixed width.
My solution: autoWidth="false"
i overrode .ui-selectonemenu, .ui-selectonemenu-label to:
.ui-selectonemenu{
width: 100% !important;
}
.ui-selectonemenu-label{
width: 100% !important;
}
The only way I found is to use jQuery to initialize width at load time.
You can create simply a CSS class like this (just to be used as a futur selector) :
.full-width
{
}
And add it to your component :
<p:selectOneMenu value="#{bean.selectedObject}" id="idSelect" converter="objectConverter" styleClass="full-width">
<f:selectItems value="#{bean.objectsList}" var="varObject" itemLabel="{varObject.label}" itemValue="#{varObject}" />
</p:selectOneMenu>
Since you will need jQuery, you should add this inside your h:head if you are not already using PrimeFaces components that use it.
<h:outputScript library="primefaces" name="jquery/jquery.js" />
Here is the small script that initialize all p:selectOneMenu in the selector :
<script>
$(document).ready(
function()
{
$("div.ui-selectonemenu.full-width").each(
function()
{
$(this).css("width",$(this).parent().width());
}
);
}
);
</script>
you can add the value of width directly in the component to modify it, to avoid impacting other p: selectOneMenu existing in the page.
<p:selectOneMenu style="width: 100% !important">
...
</p:selectOneMenu>
I now have a proper fix for this.
Primefaces 6.0 now has a new field called autoWidth that by default is set to true, and you can set to false.
IF you do as some of the above responses say and set it to false, all you are doing is playing roulette with you app css.
By setting it to false, primefaces will leave it up to you to manage the width.
You can either have the width set on the selectOneMeny expliclitly by style attribute, or some css class in your application.
But this is not what this issue is about, this issue is about the fact that the default behaivor of not specifying any width to a drop down makes leads our drop downs to normally be way too small for the labels in there.
So what we actually want is for the autoWidth to work proplerly.
FInally, I looked at the component and at the renderer, and it is obvious the auto-width mechanism does not work in the backend side.
The backend side only builds some JSON like data that the primefaces javascript builder can use to properly tune on the browser the behavior of the widget.
If you loook at primefaces 6.0 source code, the bug is in META-INF\resources\primefaces\forms
Search for the code that says the following:
PrimeFaces SelectOneMenu Widget
In this javascript function hunt for the code chunk that says:
_render: function() {
if(this.cfg.autoWidth) {
In this section of code your bug is the following line:
this.jq.css('min-width', this.input.outerWidth());
Here, I applied the following patch that hopefully should work in geting the drop down box to be as fat as the largest label:
_render: function() {
if(this.cfg.autoWidth) {
// BEGIN: PATCHING
// ORIGINAL CODE:
// this.jq.css('min-width', this.input.outerWidth());
// BUGFIX:
// (a) compute the original min-with primefaces 6.0 would put on the root div
var primefacesBugWidth = this.input.outerWidth();
// (b) compute the length of the hidden select element with all the labels inside of it
var widthOfHiddenDivWithSelectLabels = this.jq.find('div select').width();
var widthOfTheDropDownTriangle = this.jq.find('.ui-selectonemenu-trigger.ui-state-default.ui-corner-right').width();
var widthOfLabelPlusTraingle = widthOfHiddenDivWithSelectLabels + widthOfTheDropDownTriangle;
// (c) we will use whichever length is longer
// in bug-fixed primefaces version the outerWidth should be computed correctly
// but this seems not to be the case
var maxWidthOfTwoPossibleOptions = primefacesBugWidth > widthOfLabelPlusTraingle ? primefacesBugWidth : widthOfLabelPlusTraingle;
this.jq.css('min-width', maxWidthOfTwoPossibleOptions);
// END: PATCHING
}
}
The idea of the code above is:
(a) look at the hidden div with all labels and get the width of that div
(b) add to that length the width needed for the primefaces triangle facing down
(c) compare the width we have computed to that that is suggested by primefaces and that seems to be way too small
NOTE:
To install the patch you have to copy all of the Primaces code for the SelectOneWidget.
Add it to a javascript file under your control.
Make sure you only run the compilation of your javascript file after the primefaces javascript file has been loaded.
Normally primefaces is being rendered at the HEAD.
So if you have you jasvacript as the last ement in the body you should be fine.
The patching is working fine for me.
THis is code I do not like to maintain however.
You can ID the element and change the style width through CSS. Make it 100% of its container.
If your p:selectOneMenu is in a DIV with an assigned width, I find setting style="width:100%;" on the p:selectOneMenu seems to work in my case.
The problem might be min-width, which is set in the rendered HTML. If that is your case, use a CSS selector fixed-width like this:
<p:selectOneMenu styleClass="fixed-width" ...
then define CSS
.fixed-width { min-width: 100% !important; }
That sets the width of the selectOneMenu widget to the width of the parent element. To have it work, parent elements's width should not be 'auto'.
Those who still got problem with selectonemenu may try this
.ui-selectonemenu {
min-width: 0 !important;
}
Perfectly worked for me.
You can use something like
style="min-width: 12rem"
I want to implement JSF button with image and custom label. I tested this code:
<h:commandButton id="savesettings" styleClass="avesettings" value=" Save Settings " action="#{GeneralController.updateDBSettings}" rendered="true" update="growl">
<f:ajax render="#form" execute="#form"></f:ajax>
</h:commandButton>
.avesettings {
background-image: url('../images/small.png');
}
This is the result:
I also tested this second code:
<h:commandButton id="savesettings" image="resources/images/first.png" value=" Save Settings " action="#{GeneralController.updateDBSettings}" rendered="true" update="growl">
<f:ajax render="#form" execute="#form"></f:ajax>
</h:commandButton>
I get this result with no label:
Can you help me to create JSF button with background image and custom label defined as button attribute?
The first method that you have used styleClass="avesettings" i.e., using CSS style is the only possible way to do it since if you specify the image attribute, the input element will become an image.
See also documentation
So your best bet would be to use advanced styling techniques for the buttons, refer to these articles for that:
http://coding.smashingmagazine.com/2009/11/18/designing-css-buttons-techniques-and-resources/
http://www.tyssendesign.com.au/articles/css/styling-form-buttons/
The following JSF/CSS should solve your problem:
JSF (the same as in your first example):
<h:commandButton id="savesettings" styleClass="avesettings" value="Save Settings" action="#{GeneralController.updateDBSettings}" rendered="true" update="growl">
<f:ajax render="#form" execute="#form"></f:ajax>
</h:commandButton>
CSS (adapted):
.avesettings {
background: url('../images/small.png') no-repeat;
cursor: pointer;
width: 126px;
height: 41px;
border: none;
}
Width and height of the css must be the width and height of your image. I also have the css in an external css file, not direct in the JSF template.
Did you try the "image" attribute of he commandButton tag?
One way to implement this is to load the image as jsf resource in your style sheet:
<style type="text/css">
.imageButton
{
background-image:url(#{resource['images/button.png']});
}
</style>
Then set the relevant commandButton styleClass in the xhtml:
<h:commandButton value="Submit" styleClass="imageButton" action="#{...}"/>
Put the file button.png under your resources folder i.e. resources/images/button.png and make sure your resources folder is located next to your WEB-INF folder
Or if you want the image to display as an icon next to the text in the commandButton then you can play around with css a little:
.imageButton
{
padding: ...
border: ...
color: ...
background: [<'background-color'> || <'background-image'> || <'background-repeat'> || <'background-attachment'> || <'background-position'>]
}