Silverlight XAML Attribute Definition Order Matters - silverlight-3.0

I was working with the ComboBox control and couldn't get the SelectedItem to be set from the property on my viewmodel. Here is the control definition:
<ComboBox x:Name="jobEmployee" Grid.Column="1" Grid.Row="2"
Margin="4" HorizontalAlignment="Left" Width="150"
SelectedItem="{Binding Path=EditingJob.Employee, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}"
ItemsSource="{Binding Path=Employees, Mode=OneWay}"
DisplayMemberPath="FullName"/>
I had another Combobox control that worked jut fine. The difference between one that would set the SelectedItem and the one that wouldn't was the order of the attribute definition. Here is the working control definition:
<ComboBox x:Name="jobEmployee" Grid.Column="1" Grid.Row="2"
Margin="4" HorizontalAlignment="Left" Width="150"
ItemsSource="{Binding Path=Employees, Mode=OneWay}"
SelectedItem="{Binding Path=EditingJob.Employee, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}"
DisplayMemberPath="FullName"/>
The difference between the 2 is that the ItemsSource is defined before the SelectedItem on the working one which leads me to believe that in this case at least, the attribute definition order matters. Am I missing something or have others found this to be true? Has it been documented anywhere?

Yes order can matter. Consider that XAML reading involves the creation of objects and the assignment of values to the properties of these objects. Its not possible to assign property values at the same time, clearly one property is going to be assigned followed by another and then another until all properties are assigned.
Since assigning properties in some objects results in side-effects and other code running the order of assigning those properties can impact the result. This of course is a bad thing.

In any circumstance in which the order that properties are set is important, you should use element syntax, not attribute syntax, to represent those properties in your XAML:
<ComboBox x:Name="jobEmployee" Grid.Column="1" Grid.Row="2"
Margin="4" HorizontalAlignment="Left" Width="150" DisplayMemberPath="FullName">
<ComboBox.ItemsSource>
<Binding Path="Employees" Mode="OneWay"/>
<ComboBox.ItemsSource>
<ComboBox.SelectedItem>
<Binding Path="EditingJob.Employee" Mode="TwoWay"
ValidatesOnExceptions="true" NotifyOnValidationError="true"/>
</ComboBox.SelectedItem>
</ComboBox>
According to the XML recommendation, the ordering of attributes on an element is not significant. XML tools aren't required to retain the order they appear in. So if, for instance, you processed this ComboBox element with an XSLT transform (not a crazy idea in some circumstances), the transform might change the ordering of your attributes, even if it's doing <xsl:copy-of>. The XSLT processor probably won't do this, but it's not required not to.
What effect would randomizing the order of the attributes on every element in your XAML do to the behavior of your application? The answer to that question ought to be "nothing."
This is an aspect of XAML that makes me very nervous.

The next time you have a problem similar to this and you suspect the binding might be failing because of the order.
Check your output window, it displays all binding errors, So from that error you could have deduced that the ItemSource was null at time of binding the SelectedItem property

Related

What are the downsides of using binding in order to update a JSF component?

Consider this xhtml piece.
<p:dialog id="consumerDialog"
widgetVar="dealerDialog" modal="true">
<h:panelGroup binding="#{cdContent}">
</h:panelGroup>
</p:dialog>
<p:dialog id="dealerDialog"
widgetVar="dealerDialog" modal="true">
<h:form>
<p:commandButton value="Close"
onclick="PF('dealerDialog').hide()"
update=":#{cdContent.clientId}"/>
</h:form>
</p:dialog>
In the dealerDialog component is a p:commandButton which updates the h:panelGroup component inside the consumerDialog where the id of the updated component is obtained through binding. I sometimes do this to save pains figuring out the actual id of the target component (especially for complex views).
Are there any downsides or risks if I do it this way?
Are there any downsides or risks if I do it this way?
Only if the EL variable represented in binding, which is in your case #{cdContent}, is shared by multiple components in the same view. E.g. when the given code snippet is included multiple times in the same template via <ui:include>, tagfile or composite. Or even when there's a managed bean on that name. It doesn't apply in your case, but it would for sure fail if the binding attribtue references a session scoped bean property.
There are no risks if you make absolutely sure that #{cdContent} is exclusively used by only one component in the entire view.
See also:
How does the 'binding' attribute work in JSF? When and how should it be used?

How do you pass a Managed Bean of different type to a composite for reuse?

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?

How to refer to a bound component in a DataTable with EL?

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.

OmniFaces o:validateAllOrNone in ui:repeat or h:dataTable

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.

JSF 2.0 - how to get the property path of a jsf component?

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.

Resources