I have a doubt. How can we create an attribute and store that attribute value in a variable so that the value can be re-used. And mainly the attribute must be created within a template.
<xsl:template name="test">
<xsl:attribute name="id" select="generate-id()"/>
</xsl:template>
I want to use the value of "id" at multiple locations of my xslt file.
Variables are immutable and a variable declared within a template is not visible outside that template. You're clearly trying to use the language in a way it isn't designed to be used; if you show us your problem, rather than your wrong approach to a solution, then we can help show you the right way to address it.
You use the phrase "at the time" in your comment - that's a clear indication that you're thinking in procedural rather than functional terms. There's no time axis in XSLT processing; things happen when the processor chooses to make them happen.
Related
I'm creating an inline text editor. I've written the code to edit one single h:ouputText field (h:inputHidden). Works. Thus, I thought I create a composite (widget), that I can call for every field I want to update. Of course, those fields refer to a managed bean in my case, that is the PubController MB.
<composite:interface name="inlineEditor">
<composite:attribute name="attrOfMb" required="true"
type="java.lang.String" />
<composite:attribute name="pubController" required="true" type="com.playground.webapp.controller.PubController"/>
</composite:interface>
Now, I have the following tasks to accomplish:
pass the MB to the composite (done).
in the composite, create the div and the hidden input field with id of the MB attribute.
Challenge where I struggle:
How do I "bind" an attribute of the passed PubController to the hidden input field? #{cc.attrs.pubController.title}? Well, it should not always be the same attribute. The attribute should be chosen by what has been passed in the interface attribute attrOfMb.
In other cases, its not necessariley PubController. Might be another MB. My initial thought was to define the interface type to javax.faces.bean.ManagedBean. On the other hand, how could you then "bind" the passed MB to the input hidden field (respectively vice-versa).
Is there a JSF-Pattern on how you accomplish these things?
You're going in the wrong path as to designing the composite. You should bind a bean property, not a whole bean.
I.e. you should not have
<my:composite bean="#{bean}" />
but you should have
<my:composite value="#{bean.value}" title="#{bean.title}" />
Once you fix that problem, then you can easily reuse it on any backing bean. Please note that this is also the way how standard JSF <h:xxx> components work. If you worry about about "too many" attributes for some unclear reason, then just create a reusable model class which in turn can be a property of the backing bean.
<my:composite data="#{bean.data}" />
This way you can use it further in the composite as #{cc.attrs.data.value}, #{cc.attrs.data.title}, etc.
If you really, really need to bind a whole bean, then I'd question if a tag file or maybe an include file isn't a better solution for whatever functional requirement you've had in mind. A composite component should really represent a component with a single responsibility and a single point of model value binding.
See also:
When to use <ui:include>, tag files, composite components and/or custom components?
Using expression language, how can I access a component that is bound and repeated in a datatable?
<h:dataTable value="#{bean.items}" var="item" id="table">
<h:column>
<h:inputText value="#{item.name}" id="name" binding="#{mybinding}"/>
</h:column>
</h:dataTable>
Should I give each binding a generated name with a concatenation of a literal and the row index, for instance ('mybinding_1', 'mybinding_2', and so forth), and if so, how?
Or instead is there a way to get a particuliar element with #{mybinding} plus some kind of brace notation ([])?
There's a misconception going here. There are definitely not physically multiple <h:inputText> components in the component tree. There's only one component whose HTML representation is generated multiple times depending on the current state of the parent table component. You can confirm this by walking through the component tree starting at FacesContext#getViewRoot(), you'll ultimately find only one <h:inputText> component.
So, binding="#{mybinding}" is perfectly fine.
If you're having problems with it, it's caused elsewhere and needs to be solved differently. Only and only if you're using a view build time tag to generate physically multiple components in a loop, such as JSTL <c:forEach>, then there would indeed be physically multiple <h:inputText> components in the component tree and you'd need to bind them to an array or map. But this is currently clearly not the case.
Is it possible to use OmniFaces <o:validateAllOrNone> (which is pretty cool ;)) within an <ui:repeat> or <h:dataTable>?
I need a table with each row having an input field column. You could either fill in none of these values or all of them.
If I put the <o:validateAllOrNone> within the <ui:repeat> or <h:dataTable> and use the id of the input field in components attribute, then the validator also gets triggered, if all fields are empty.
No, that's not possible. The components attribute must refer physically multiple components, not a single component which is rendered multiple times. It can however be used on physically multiple components which are rendered during same iteration round. The <o:validateXxx> multi field validator is not designed to reference a single component which is rendered multiple times. The only OmniFaces validator which does that is <o:validateUniqueColumn>.
If you want to use the <o:validateXxx> multi field validator on dynamic inputs based on a collection, then your best bet is to use JSTL <c:forEach>. It will build physically multiple components.
E.g.
<c:forEach items="#{bean.items}" var="item" varStatus="loop">
<h:inputText id="input_#{loop.index}" value="#{item.value}" />
</c:forEach>
Assuming that there are 3 items, this will dynamically create JSF components with IDs of input_0, input_1 and input_2. Then you can just use <o:validateXxx> as follows (put it outside the loop!)
<o:validateAllOrNone components="input_0 input_1 input_2" />
You can replace the hardcoded string in the above example by an EL expression which returns the desired space separated string of component IDs from a backing bean.
<o:validateAllOrNone components="#{bean.inputIds}" />
An alternative would be to create a <x:validateAllOrNoneColumn> yourself or to post an enhancement request at OmniFaces issue tracker. It would be not exactly trivial to alter the existing <o:validateAllOrNone> that a completely separate component is desired.
Is it best to NOT label a form component (or any other component for that matter) unless you have a need to do so e.g. if you want to be able to reliably distinguish one component from another?
When I see examples of reference components I am always seeing them with a preceding colon e.g. ":dialog" rather than "dialog" or "form:dialog". Is not naming the form and then specifying the component using a preceding colon the best practice?
If you don't specify the id of the form because you don't need to reference it by a client ID right now, then it will technically not harm to omit it, because JSF will autogenerate one in any way.
From inside an ID-less form, for example, you can always reference the parent form as #form in execute and render attributes of <f:ajax> to signal that you want to submit and/or render the entire parent form.
<f:ajax execute="#form" render="#form" />
But if you need to reference for example another form or one of its child components on ajax render, then you should give that form a fixed ID, so that you will be able to reference it by client ID.
Another reason which we're experiencing in real world projects is that automated web unit testing software such as Selenium really requires a form with a fixed ID, because it needs to find the input fields and submit buttons by their name attribute which is also composed based on the JSF form ID. If the JSF form ID is not specified, then the input field name is unpredictable on every deploy/request and thus untestable.
All with all, the "best practice" is basically: "only if you need it". I myself am just getting used to always specify the ID of NamingContainer, UIInput and UICommand components. "You never know".
Your component ID would look something like,
:namingContainer:myComponent. Where the first “:” tells JSF that you
want to start looking for the component at the UIViewRoot instance, or
the very top level of the component tree
Read http://ocpsoft.org/java/jsf2-java/how-to-jsf-2-0-render-components-outside-of-the-form/
is there a way to get from a JSF component the property path which is obviously used for updating the model?
I am asking cause we have a concept where the backend validates the whole stuff. Don't ask why but I am not allowed to use JSF build-in validation.
The backend provides ValidationException if for example a property is null but should not be null and the ValidationException contains a list of ValidationInfos containing the full property path for the property the validation info belongs to.
My task is to find a way to map back this info to the corresponding JSF component to be able to show the message for the correct JSF component.
It is allowed for me to register/attach some kind of little helpers to the component to make it easier for mapping back the infos.
My first approach was to write a tag handler and in the tag handler to find out the property path and the root bean. But I am lost there cause we are also using JSF 2.0 components with deferred value expression so I see at the moment a value expression like vor example #{cc.attrs.value} but I am interested in the "caller" expression like for example #{aBean.street} which is obiously the property path for updating the model.
<composite:interface>
<composite:attribute name="value" required="true"/>
</composite:interface>
<composite:implementation>
<h:inputText value="#{cc.attrs.value}" styleClass="#{!component.valid ? 'col2 error' : 'col2'}">
<my-components:registerTagHandler value="#{cc.attrs.value}"/>
</h:inputText>
</composite:implementation>
Maybe there are other approaches or other ideas out there. It would be helpful for me to get some hints/ideas.
Best Regards,
Walter
PS: sorry for my crude english cause I am not a native english speaker.