How do you reference a zul component with an dynamic id, like id="calendarDecorate_${vmStatus.index}"? - zk

I have method in class
public class CalendarDecorate {
public void setDays(final boolean checkDays){
//code
}}
In my zul file, i have a own component for this class:
<div>
<calendarDecorate id="calendarDecorate_${vmStatus.index}"</calendarDecorate>
<combobox onChange="calendarDecorate_${vmStatus.index}.setDays(payment.Code)"/>
</div>
Is there a notation that allows this reference calendarDecorator_${vmPaymentStatus.index}.setDays(payment.Code) to work?

If there is just one <calendarDecorate>, you can just wire by component type
#Wire("calendardecorate")
Since you append an index in id, I suppose there are multiple <calendarDecorate>. You can
Wiring a Collection and reference one of them with index, vmStatus.index.
If you develop in MVVM pattern, usually you don't need to get a component reference. Just bind the corresponding property to the attribute e.g.
<calendarDecorate days="#load(vm.payment.code">

Related

ZK: loading value/text into selectbox

I have a selectbox and want to load the value and text into the template, similar to an HTML dropdown box. I am using ZK framework with Java on the back end.
<selectbox id="buListbox" model="${$composer.buModel}" >
<template name="model">
<label value="${each}" />
</template>
</selectbox>
When using ZK, you don't need the value to identify the selected object like in HTML.
When using the MVC pattern, binding a model via model attribute, the selected item is also stored in that model and can be retrieved in java via model.getSelection().
Furthermore, a model is not restricted to lists of String, but it can hold any object type you want. In the template section, you can display any property of that object. Then the properties' toString() method is used to get the value which is displayed. This also applies to ${each} itself.
Example:
Assuming your model is a ListModelList of type ValueType:
public class ValueType {
private String value;
private String text;
public ValueType(String value, String text) {
this.value=value;
this.text=text;
}
public String getText() {
return this.text;
}
public String getValue() {
return this.value;
}
}
private ListModelList<ValueType> typesModel;
public ListModelList<ValueType> getTypesModel() {
return typesModel;
}
You than can use the selectbox's model/template to display it's text property:
<selectbox id="typesSelectbox" model="${$composer.typesModel}">
<template name="model">
${each.text}
</template>
</selectbox>
In java, you then get the selected item via typeModel.getSelection() .
Here you can find a working ZKFiddle example.

Spring form path with multiple model attributes with the same property name

The problem is that I have a spring form and 2 #ModelAttribute params with the same properties in my controller. The 'commandName' parameter of the the form is set to one of my modelAttributes names. I was surprised that the maps the property not only to the model attribute specified with 'commandName', but also to the second one.
I haven't found the exact solution here, except the similar to mine: Spring-form multiple forms with same model atribute name properties
But in my case I can't see any 'strange things', I have one form, one Model attribute to bind this form, and one model attribute to have accsess to controller scoped #SessionAttribute.
I've also tried to use form's 'modelAttribute' parameter (Actually I can't see any difference between them), but it didn't help.
My code example:
view.jsp:
<form:form name="form" action="/myAction" method="POST" commandName="model1">
<form:input path="property"/>
....
<input type="submit" value="Submit"/>
</form:form>
Controller.java
#SessionAttributes("model2")
class Controller {
#RequestMapping(value = "/myAction", method = POST)
public String submitEditSite(final #ModelAttribute(value = "model1") Model1 model1,
final #ModelAttribute(value = "model2") Model2 model2) {
....
return "redirect:/home";
}
}
Model1.java Model2.java
class Model1 {
private String property;
}
class Model2 {
private String property;
}
Where am I wrong?
If I understand you correctly you want to prevent the setting of any property on model2, right?
Then this should do:
#InitBinder("model2")
public void initBinder(WebDataBinder binder) {
binder.setDisallowedFields("*");
}

Custom sort in domaincollectionview

I'm using a DCV as a property in the View Model.
Everything works fine but what about custom sort?
Say I have a string property in my model which should be sorted alphanumerically.
How can I achieve such thing?
UPD:
Model:
public class MyModel
{
///...
public SomeProperty {get;set;}
}
xaml:
<data:DataTextColumn Binding={binding path=SomeProperty}, canusersort=true />
When sorting within the datagrid, the property gets sorted with disregard to alphanumeric order, i.e. in a regular string way. I'd like to apply my custom sort, e.g. by introducing my own IComparer. No API is available at least as I know of it.
Any clues?
The DomainCollectioView has special collection:
SortDescriptions
You could add next code in Your ViewModel:
DCV.SortDescriptions.Add(new SortDescription("SomeProperty ", ListSortDirection.Ascending));

Read DataAnnotations from a collection of models in an MCV2 view

In my MVC2 AdminArea I'd like to create an overview table for each of my domain models.
I am using DataAnnotations like the following for the properties of those domain model objects:
[DisplayName("MyPropertyName")]
public string Name { get; set; }
Now my question is: How can I access the DisplayName Attribute if my view receives a collection of my domain models? I need this to build the table headers which are defined outside of the usual
<% foreach (var item in Model) { %>
loop. Inside this loop I can write
<%: Html.LabelFor(c => item.Name) %>
but is there any way to access this information using the collection of items instead of a concrete instance?
Thanks in advance!
There is a ModelMetaData class that has a static method called FromLambdaExpression. If you call it and pass in your property, along with your ViewData, it will return an instance of ModelMetaData. That class has a DisplayName property that should give you what you need. You can also get other meta data information from this object.
For example, you can create an empty ViewDataDictionary object to get this information. It can be empty because the ModelMetaData doesn't actually use the instance, it just needs the generic class to define the type being used.
//This would typically be just your view model data.
ViewDataDictionary<IEnumerable<Person>> data = new ViewDataDictionary<IEnumerable<Person>>();
ModelMetadata result = ModelMetadata.FromLambdaExpression(p => p.First().Name, data);
string displayName = result.DisplayName;
The First() method call doesn't break even if you have no actual Person object because the lambda is simply trying to find the property you want the meta data about. Similarly, you could d this for a single Person object:
//This would typically be just your view model data.
ViewDataDictionary<Person> data = new ViewDataDictionary<Person>();
ModelMetadata result = ModelMetadata.FromLambdaExpression(p => p.Name, data);
You could clean this up significantly with a helper or extension method, but this should put you on the right path.
Alright, I followed sgriffinusa's advise (thanks again!) and created a strongly typed HtmlHelper:
public static MvcHtmlString MetaDisplayName<TModel, TProperty>(this HtmlHelper<TModel> helper, Expression<Func<TModel, TProperty>> expression) where TModel : class
{
ModelMetadata metadata = ModelMetadata.FromLambdaExpression(expression, helper.ViewData);
return MvcHtmlString.Create(metadata.GetDisplayName());
}
Of course TModel still is a collection of domain models like stated in my inital question but we can call the helper in the view like this:
<%: Html.MetaDisplayName(p => p.First().Name) %>

asp.net mvc editorfor

Is it possible to get the EditorFor method also render the label and validation for a property like the EditorForModel method does ?
Now When I use the EditorFor method for a property (for example a string), it renders only the textbox.
EDIT
Arnis I tried it out and there some problems:
The extension method should be bound on the generic HtmlHelper class. Also returning string from the helper was causing encoded html.
So I modified your code
public static MvcHtmlString EditorWithLabel<T>(this HtmlHelper<T> h,Expression<Func<T, object>> p)
{
return new MvcHtmlString(string.Format("{0}: {1}", h.LabelFor(p), h.EditorFor(p)));
}
But the main problem is it works only with if the propert is of type string.
When the property is Decimal,Int,DateTime an excetion will be thrown.
Templates can be used only with field access, property access, single-dimension array index, or single-parameter custom indexer expressions.
I would create custom html helper (code is untested):
public string EditorWithLabel<T>(this HtmlHelper h,
Expression<Func<T, object>> p){
return string.Format("{0}: {1}",h.LabelFor(p),h.EditorFor(p));
}
This can be achieved with templates too, but I think custom helper fits better.