0

Converter does not work with [custom attributes] in Textbox component

asked 2010-08-24 22:51:07 +0800

enix0907 gravatar image enix0907
129 1
http://sites.google.com/s...

updated 2010-08-24 22:52:55 +0800

I was glad to find this new feature in ZK 5.0.2: add data binding support for custom attribute tag - ID: 2855116

However, it is not working when I apply events to annotation:

<textbox rows="3" width="90%" maxlength="500">
  <custom-attributes CriNo="@{textCri.Criteria_No, converter='sas.application.TextCriAnsConverter', save-when='self.onChange'}" />
</textbox>



After my testing, save-when='self.onChange' can not trigger my code in coerceToBean(Object val, Component comp) method, even if onChange event occurs in this textbox.
However, it is working when I use <textbox value="@{textCri.Criteria_No, converter='sas.application.TextCriAnsConverter', save-when='self.onChange'}" instead of this custom-attributes.

Here is my complete code:
code: null
<listbox id="textCriList" model="@{mainWin$composer.App.Scho.TextCriteria, load-after='mainWin.onDisplay'}" sizedByContent="false"> <listhead sizable="true"> <listheader label="Criteria" sort="auto" /> <listheader label="Reasons" /> </listhead> <listitem self="@{each='textCri'}" value="@{textCri}" height="25px"> <listcell label="@{textCri.Statement}" /> <listcell> <textbox rows="3" width="90%" maxlength="500"> <custom-attributes CriNo="@{textCri.Criteria_No, converter='sas.application.TextCriAnsConverter', save-when='self.onChange'}" /> </textbox> </listcell> </listitem> </listbox>
<br/>
<br/>My converter:
<div style="class=code" class="code"><pre><div class="error">code: null</div>
public class TextCriAnsConverter implements TypeConverter {

	@Override
	public Object coerceToBean(Object val, Component comp) {
		if (val != null) {
			if (val instanceof Textbox) {
				Textbox ansField = (Textbox) val;

				int cri_No = (Integer) ansField.getAttribute("CriNo");
				String Ans = ansField.getValue();

				if (Ans.trim().length() > 0) {
					// get the application bound with textCriList
					Application binding_app = (Application) ((Listcell) ansField
							.getParent()).getListbox().getAttribute(
							"binding_app");

					AppTextCriteria item = new AppTextCriteria(cri_No, Ans);
					binding_app.addTextCriteriaAns(item);
				}
			}
		}

		return null;
	}

	@Override
	public Object coerceToUi(Object val, Component comp) {
		if (val != null) {
			if (val instanceof Integer && comp instanceof Textbox) {
				int cri_No = (Integer) val;
				Textbox ansField = (Textbox) comp;
				// get the application bound with textCriList
				Application binding_app = (Application) ((Listcell) ansField
						.getParent()).getListbox().getAttribute("binding_app");

				if (binding_app != null) {
					AppTextCriteria TextCriAns = binding_app
							.findTextCriteriaAns(cri_No);
					if (TextCriAns != null) {
						ansField.setValue(TextCriAns.getReason());
					}
				}
			}
		}
		return null;
	}

}


Thank you for your help in advance!

delete flag offensive retag edit

9 Replies

Sort by ยป oldest newest

answered 2010-08-25 12:01:11 +0800

enix0907 gravatar image enix0907
129 1
http://sites.google.com/s...

Here is my solution but.... it's just to avoid that problem. I still hope someone could tell me whether or not custom attributes support data binding annotation with events trigger like save-when, thank you a lot!

<listbox id="textCriList"
model="@{mainWin$composer.App.Scho.TextCriteria, load-after='mainWin.onDisplay'}"
sizedByContent="false">
	<listhead sizable="true">
		<listheader label="Criteria" sort="auto" />
		<listheader label="Reasons" />
	</listhead>

	<listitem self="@{each='textCri'}" value="@{textCri}"
		height="25px">
		<listcell label="@{textCri.Statement}" />
		<listcell>
			<custom-attributes CriNo="@{textCri.Criteria_No}" />
			<textbox
				value="@{textCri.Criteria_No, converter='sas.application.TextCriAnsConverter', save-after='self.onBlur'}"
				rows="3" width="90%" maxlength="500">
			</textbox>
		</listcell>
	</listitem>
</listbox>

public class TextCriAnsConverter implements TypeConverter {

	@Override
	public Object coerceToBean(Object val, Component comp) {
		if (val != null) {
			if (val instanceof String) {
				// object val is extracted from the attribute which is bound
				// with annotation by its getter method
				String Ans = (String) val;
				Textbox ansField = (Textbox) comp;
				int cri_No = (Integer) ansField.getParent().getAttribute(
						"CriNo");

				// get the application bound with textCriList
				Application binding_app = (Application) ((Listcell) ansField
						.getParent()).getListbox().getAttribute("binding_app");

				AppTextCriteria item = new AppTextCriteria(cri_No, Ans);

				if (Ans.trim().length() > 0) {
					binding_app.addTextCriteriaAns(item);
				} else {
					binding_app.removeTextCriteriaAns(item);
				}
			}
		}

		// can NOT return null; because the receiving bean is int data type by
		// calling setCriteria_No(int criteriaNo)
		return TypeConverter.IGNORE;
	}

	@Override
	public Object coerceToUi(Object val, Component comp) {
		if (val != null) {
			if (comp instanceof Textbox) {
				Textbox ansField = (Textbox) comp;
				// wish to be get from val... :(
				int cri_No = (Integer) ansField.getParent().getAttribute(
						"CriNo");
				// get the application bound with textCriList
				Application binding_app = (Application) ((Listcell) ansField
						.getParent()).getListbox().getAttribute("binding_app");

				if (binding_app != null) {
					AppTextCriteria TextCriAns = binding_app
							.findTextCriteriaAns(cri_No);
					if (TextCriAns != null) {
						// indicate setValue(TextCriAns.getReason())
						return cri_No+": "+TextCriAns.getReason();
					}
				}
			}
		}
		return null;
	}

}

link publish delete flag offensive edit

answered 2010-08-25 15:45:17 +0800

robertpic71 gravatar image robertpic71
1275 1

Just an idea (not tested):

<textbox rows="3" width="90%" maxlength="500">
<custom-attributes CriNo="@{textCri.Criteria_No, converter='sas.application.TextCriAnsConverter', save-when='self.onChange'}" />
</textbox>

Maybe self don't work in the custom-attribute, try

<textbox id="tbid" ...
<ustom-attributes .....save-when='tbid.onChange'}"/>

/Robert

link publish delete flag offensive edit

answered 2010-08-25 20:30:25 +0800

enix0907 gravatar image enix0907
129 1
http://sites.google.com/s...

updated 2010-08-25 20:30:54 +0800

Thank you for this good idea. However, before trying it, could you tell me how to set distinct ID for each of my dynamically-generated textboxes component in ZUL? Can I use <textbox id="tbid_${textCriList.ItemCount}"... ? Or I have to set their IDs programmically?
because they are created depending on my listbox setModel() as you can see on my above code.

code: null
<listbox id="textCriList" model="@{mainWin$composer.App.Scho.TextCriteria, load-after='mainWin.onDisplay'}" sizedByContent="false"> <listhead sizable="true"> <listheader label="Criteria" sort="auto" /> <listheader label="Reasons" /> </listhead> <listitem self="@{each='textCri'}" value="@{textCri}" height="25px"> <listcell label="@{textCri.Statement}" /> <listcell> <custom-attributes CriNo="@{textCri.Criteria_No}" /> <textbox id="tbid_${textCriList.ItemCount}" value="@{textCri.Criteria_No, converter='sas.application.TextCriAnsConverter', save-after='self.onBlur'}" rows="3" width="90%" maxlength="500"> </textbox> </listcell> </listitem> </listbox>
code: null

link publish delete flag offensive edit

answered 2010-08-25 22:25:37 +0800

SimonPai gravatar image SimonPai
1696 1

Hi enix0907,

Would you post the issue to the bugtracker? And then we will take a look at the issue and see what to do about it.

Thanks,
Simon

link publish delete flag offensive edit

answered 2010-08-26 00:32:50 +0800

enix0907 gravatar image enix0907
129 1
http://sites.google.com/s...

Thanks for your concern, I have posted this issue on bug tracker.

link publish delete flag offensive edit

answered 2010-08-26 05:59:31 +0800

robertpic71 gravatar image robertpic71
1275 1

I'm not sure about your case, custom-attributes seems to work for me. Maybe this is an special case (custom-attribute without binding for the value...).

About your question:
>> However, before trying it, could you tell me how to set distinct ID for each of my dynamically-generated textboxes

There is no need for an distinct ID. Databinding creates a template (including the eventlisteners) and copy the template
for each record (including the eventlisteners).

/Robert

link publish delete flag offensive edit

answered 2010-08-26 13:40:06 +0800

enix0907 gravatar image enix0907
129 1
http://sites.google.com/s...

As for my Textbox component,



<textbox rows="3" width="90%" maxlength="500">
<custom-attributes
CriNo="@{textCri.Criteria_No, converter='sas.application.TextCriAnsConverter', save-when='self.onChange'}" />
</textbox>


this custom attribute is binding with my bean property (textCri.Criteria_No) and also applying to a converter. The only problem is save-when is not effective. I tried another type of event like onBlur, it does not work either.
Thank you for your idea anyway :-)

link publish delete flag offensive edit

answered 2010-08-30 02:18:41 +0800

henrichen gravatar image henrichen
3869 2
ZK Team

@enix0907,

Have to specify the access to 'both'

----
<textbox rows="3" width="90%" maxlength="500">
<custom-attributes
CriNo="@{textCri.Criteria_No, converter='sas.application.TextCriAnsConverter', save-when='self.onChange', access='both'}" />
</textbox>
----

Which tells the data binder that the attribute CriNo is both "loadable" and "savable".

Search 'access' in JavaDoc for details.
http://www.zkoss.org/javadoc/5.0.0/zk/org/zkoss/zkplus/databind/AnnotateDataBinder.html

link publish delete flag offensive edit

answered 2010-08-30 15:29:34 +0800

enix0907 gravatar image enix0907
129 1
http://sites.google.com/s...

@henrichen,

Thank you for your assistance, now it is working correctly! :=) this attribute access controls whether or not to execute my converter when events assign to save/load attribute.

link publish delete flag offensive edit
Your reply
Please start posting your answer anonymously - your answer will be saved within the current session and published after you log in or create a new account. Please try to give a substantial answer, for discussions, please use comments and please do remember to vote (after you log in)!

[hide preview]

Question tools

Follow

RSS

Stats

Asked: 2010-08-24 22:51:07 +0800

Seen: 723 times

Last updated: Aug 30 '10

Support Options
  • Email Support
  • Training
  • Consulting
  • Outsourcing
Learn More