how to use zk annotations - annotations

I am using zk 5.0.3. I want to use the following annotation binding as the title of a "center" region of a borderlayout:
<a:bind content="entrydisplay.activeEntryCaption" /> <html />
I want to do the following:
<borderlayout>
<north title="use the above binding here">
this is north
</north>
</borderlayout>
How do I achieve the functionality such that I can wrap this binding as the value of the title?
Thanks,
Sony

You are using an outdated version of ZK data binding. It is highly recommended that you make use of the latest methodology.
The following link is the databinding section of the ZK Essential guide & Developer's Reference:
Developer's Reference Databinding
ZK Essential's Databinding
Our basic databinding consists of a POJO which follows the Java bean conventions being access from an XML based interface using annotations in attributes. For example:
Person POJO:
public class Person {
private String _firstName = "";
private String _lastName = "";
private Boolean _married = true;
public Person(){
}
public Person(String firstName, String lastName, Boolean married){
_firstName = firstName;
_lastName = lastName;
_married = married;
}
// getter and setters
public void setFullName(String f) {
// do nothing
}
public String getFullName() {
return _firstName + " " + _lastName;
}
//add more here
}
The UI file:
<?init class="org.zkoss.zkplus.databind.AnnotateDataBinderInit" ?>
<window>
<zscript><![CDATA[
//prepare the person object
import bean.Person;
Person person = new Person();
person.setFirstName("Max");
person.setLastName("Planck");
]]>
</zscript>
<grid width="400px">
<rows>
<row> First Name: <textbox value="#{person.firstName}"/></row>
<row> Last Name: <textbox value="#{person.lastName}"/></row>
<row> Full Name: <label value="#{person.fullName}"/></row>
</rows>
</grid>
</window>
The theory is described here.

i think the old way is done it like this
<borderlayout>
<north>
<attribute name="label">
<a:bind value="entrydisplay.activeEntryCaption" />
</attribute>
</north>
</borderlayout>
The new doc
The doc of [http://docs.zkoss.org/wiki/Data_binding][Data Binding]

For your specific question, annotate your component like following:
<borderlayout>
<north id="mynorth" title="#{entrydisplay.activeEntryCaption}">
this is north
</north>
</borderlayout>
Data binder will read such annotation and call the getter and setter methods to set the title of the north component for you. It will do something like:
mynorth.setTitle(entrydisplay.getActiveEntryCaption());

Related

How to solve "Conversion Error setting value '2013-10-26' for 'null Converter'" in h:inputText with Date value?

when I press the insert button, I get the error indicated on the title
Conversion Error setting value '2013-10-26' for 'null Converter'
<h:form id="formulario">
<h:outputLabel for="date">Plazo</h:outputLabel>
<h:inputText id="date" required="true" requiredMessage="Campo Obligatorio" value="#{aaaNewDetalles.criterioAaa.plazo}"/>
<h:message for="date" style="color: red;"/>
<h:commandButton actionListener="#{aaaNewDetalles.add()}" value="Ingresar"/>
</h:form>
the form is managed by this class:
#ManagedBean(name = "aaaNewDetalles")
#ViewScoped
public class aaaNewDetallesBean {
private CriterioAaaController controller;
private CriterioAaa criterioAaa;
#PostConstruct
public void init(){
controller= new CriterioAaaController();
criterioAaa= new CriterioAaa();
}
public void add(){
controller.save(criterioAaa);
}
public CriterioAaa getCriterioAaa() {
return criterioAaa;
}
public void setCriterioAaa(CriterioAaa criterioAaa) {
this.criterioAaa = criterioAaa;
}
}
The object CriterioAaa:
import java.sql.Date;
#Table(name = "criterio_aaa", schema = "", catalog = "ciclos_calidad")
#Entity
public class CriterioAaa extends Entidad implements Serializable {
private Date plazo;
public Date getPlazo() {
return plazo;
}
public void setPlazo(Date plazo) {
this.plazo = plazo;
}
}
There are two problems in your current approach:
You should use java.util.Date instead java.sql.Date. JSF and other frameworks work with this type. Also, java.sql.Date extends java.util.Date but its purpose is basically for JDBC usage. More info about this: Date vs TimeStamp vs calendar?
<h:inputText> expects a String as value, and when sending the data to the managed bean, it also expects the class field is from String type as well. In cases like this, you need to use a converter to tell JSF that this String in fact represents a Date. For this, you may use <f:convertDateTime> tag component.
<h:inputText id="date" required="true" requiredMessage="Campo Obligatorio"
value="#{aaaNewDetalles.criterioAaa.plazo}">
<f:convertDateTime pattern="yyyy-MM-dd" />
</h:inputText>
As a recommendation, you may use a calendar component from third party libraries like PrimeFaces or RichFaces whose provide <p:calendar> and <rich:calendar> component respectively.
You should import the appropriate Date package :
import java.util.Date;
In Managed Bean You should use java.util.Date. and specify the converter.
e.g.
<h:inputText id="date" required="true" requiredMessage="Hire Date"
value="#{empBean.empDetail.hireDate}">
<f:convertDateTime pattern="yyyy-MM-dd" />
</h:inputText>
you can specify the pattern for DateTimeConverter also you can use dateStyle,timeStyle, type.

MvvmCross passing configuration to configurable plugin loader

I am creating a portable MockGeoLocationWatcher that one can substitute in place of the concrete implementations of IMvxGeoLocationWatcher until one has an actual device. This should facilitate development and testing of applications that require geo location.
The PluginLoader class for this plugin currently looks like this:
namespace Pidac.MvvmCross.Plugins.Location
{
public class PluginLoader : IMvxConfigurablePluginLoader
{
private bool _loaded;
public static readonly PluginLoader Instance = new PluginLoader();
public void EnsureLoaded()
{
if (_loaded)
return;
_loaded = true;
var locationWatcher = new MockGeoLocationWatcher();
var data = #"<?xml version='1.0' encoding='utf-8'?>
<WindowsPhoneEmulator xmlns='http://schemas.microsoft.com/WindowsPhoneEmulator/2009/08/SensorData'>
<SensorData>
<Header version='1' />
<GpsData latitude='48.619934106826' longitude='-84.5247359841114' />
<GpsData latitude='48.6852544862377' longitude='-83.9864059059864' />
<GpsData latitude='48.8445703681025' longitude='-83.7337203591114' />
<GpsData latitude='48.8662561090809' longitude='-83.2393355934864' />
<GpsData latitude='49.0825970371386' longitude='-83.0415816872364' />
<GpsData latitude='49.2621642999055' longitude='-82.7229781716114' />
<GpsData latitude='49.2621642999055' longitude='-82.6021285622364' />
<GpsData latitude='49.2047736379815' longitude='-82.3054977028614' />
</SensorData>
</WindowsPhoneEmulator>";
locationWatcher.SensorLocationData = data;
Mvx.RegisterSingleton(typeof(IMvxGeoLocationWatcher), locationWatcher);
}
public void Configure(IMvxPluginConfiguration configuration)
{
}
}
public class MockLocationWatcherConfiguration : IMvxPluginConfiguration
{
public static readonly MockLocationWatcherConfiguration Default = new MockLocationWatcherConfiguration();
// ideally, we should use this property to point to a file or string containing location data
// this should be configurable outside of code base.
public string SensorLocationData { get; set; }
}
}
I will like to pass the sensor data, currently hardcoded into the variable called "data" through an instance of MockLocationWatcherConfiguration but do not know where the MvvmCross framework is expecting to load the configuration for this plugin before IMvxConfigurablePluginLoader.Configure(configuration) is invoked. Ideally, I should specify this through configuration.
I looked at the Json plugin's implementation of PluginLoaded but still could not figure out where the configuration was retrieved before a cast was attempted in IMvxConfigurablePluginLoader.Configure.
Any ideas or pointers will be greatly appreciated.
TIA.
This is covered in the draft wiki page https://github.com/slodge/MvvmCross/wiki/MvvmCross-plugins - see "writing a configurable plugin"

Aliased Form Names with HtmlHelpers

tl;dr
How do I modify form element names that are generated to use aliased names that come from ModelMetadata.AdditionalValues instead? Preferably with a custom (or not custom) html helper.
I have a search view model with some custom object properties. Each property goes two more properties deep in my view. I also use editor templates in my view. My form ends up with elements like the following:
HTML
<input name="Field1.Field.Id" id="..." type="..." />
<input name="Field1.Field.Label" id="..." type="..." />
<input name="Field2.Field.Id" id="..." type="..." />
<input name="Field2.Field.Label" id="..." type="..." />
Search.spark (.aspx)
${ Html.EditorFor(m => m.Field1) } // Field1 is of type SearchField
${ Html.EditorFor(m => m.Field2) } // Field2 is of type SearchField
etc...
SearchField.spark (.ascx)
<viewdata model="SearchField" />
// *snip*
${ Html.EditorFor(m => m.Field) } // Field is of type SpecialField
SpecialField.spark (.ascx)
<viewdata model="SpecialField" />
${ Html.HiddenFor(m => m.Id) } // Id is of type int?
${ Html.TextBoxFor(m => m.Label } // Label is of type string
Because the form uses GET, I end up with very long query strings. What I'd like to do is provide aliases for the properties. I already have an attribute, a model metadata provider to populate AdditionalValues and a custom model binder to take care of the aliases, but I'm stuck on generating the proper html.
I thought I'd just write a custom html helper, but got stuck pretty fast.
public static MvcHtmlString HiddenForA<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
{
var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
if (metadata.AdditionalValues.ContainsKey("Alias"))
{
string alias = (string)metadata.AdditionalValues["Alias"];
// what to do now?
}
}
You have the alias that you want to use, the value is available from metadata.Model then all you need to do is generate your HTML. You could use a tag builder, string.format or what ever you prefer, for the sake of readability I'll use string.format and have the properties in ' rather than ".
public static MvcHtmlString HiddenForA<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression)
{
var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
if (metadata.AdditionalValues.ContainsKey("Alias"))
{
string alias = (string)metadata.AdditionalValues["Alias"];
string value = Convert.ToString(value, metadata.Model);
string html = string.Format(#"<input type='hidden' name='{0}' value='{1}' >", alias, value);
return MvcHtmlString.Create(html);
}
}
However, this will only handle the issue of your long URLs, this will mean that your model binding will not properly bind these on your action. To do this you'll need to either create a custom model binder or have your action take a viewmodel with properties of these names then either create a new object of your desired model and fill in its properties or use the viewmodel as is.

What's the Struts 2 equivalent of ASP.NET's Request.Form (or FormCollection)?

I'm dynamically adding textboxes to a form on my jsp page using Javascript. When that form is submitted to an action, how does my action get the values of those textboxes? (I'm using Struts 2, btw.) In ASP.NET, I was able to find them in Form.Request/FormCollection. Is there a Struts 2 equivalent? Thanks a million.
In Struts2, you create beans in the form to do submit values. In order to create the input text-box, use the <s> tag. For example :
<s:textfield name="loginBean.userName" label="UserName" required="true" />
Here loginBean is the bean passed to the jsp page when.
Bean consists of variable declarations and getters-setters for the variable.
Then in the back-end Java where the form is submitted to, you can access the same bean.
Declare getter-setter in Java and then you can access the properties of the bean.
public LoginBean getLoginBean() {
return loginBean;
}
public void setLoginBean(LoginBean loginBean) {
this.loginBean = loginBean;
}
public String authenticate() {
String username = loginBean.getUserName();
I would recommend looking at source codes of open-source Struts projects.
It sounds like you're trying to populate a dynamic list. To do that, you just have to use the [n] index syntax at the end of your Action class property name:
HTML:
<input type="text" name="yourCollection[0]" value="first value" />
<input type="text" name="yourCollection[1]" value="second value" />
<input type="text" name="yourCollection[2]" value="third value" />
Action Class:
public class YourAction extends Action {
public List<String> yourCollection;
public List<String> getYourCollection(){
return yourCollection;
}
public void setYourCollection(List<String> aCollection){
this.yourCollection = aCollection;
}
}

Can't get JSF input field value on JAVA backend

I have following UI part on JSF - it's simple search form with input field and submit:
<h:form>
<h:commandButton action="#{operation.found}" value="#{msg.search}" />
<h:inputText name="searchParam"/>
</h:form>
And correspondingly, on backend, i attempt to get value of input field next way:
public List<Store> getFound() {
String name = (String) FacesContext.getCurrentInstance()
.getExternalContext().getRequestParameterMap().get(
"searchParam");
SessionFactory sessionFactory = new Configuration().configure()
.buildSessionFactory();
HibernateTemplate hbt = new HibernateTemplate();
hbt.setSessionFactory(sessionFactory);
foundStores = hbt.find(BEAN_PATH + " WHERE name = ?",
new Object[] { name });
return foundStores;
}
And null name is passed to backend.
It seems that problem in .jsf part, but from first glance looks ok...
You must point the <h:inputText> to a managed-bean property:
<h:inputText name="searchParam" value="#{searchBean.searchParam}" />
and define in your bean:
private String searchParam;
public String getSearchParam() {..}
public void setSearchParam(String searchParam) {..}
and then use the searchParam in your getFound() method;
Of course, you need to have the bean defined as managed bean, but I assume you have done it:
<managed-bean>
<managed-bean-name>searchBean</managed-bean-name>
<managed-bean-class>mypackage.SearchBean</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
</managed-bean>
You can check a JSF tutorial (like this, for example)