0

Autocomplete Combobox with huge data in MVVM

asked 2012-01-23 14:08:34 +0800

jaan gravatar image jaan
88 3

Hi,

I want to implement a combobox with autocomplete function in ZK6.
I have a generic class wich extends SimpleListModel. In this class I override getSubModel(Object value, int nRows) to get some rows from database.
This is a relevant part of the class:

public class AutocompleteListModel<T> extends SimpleListModel<T> {
	private static final long serialVersionUID = -6237906046041054025L;

	private final WeakHashMap<String, WeakReference<ListModel<T>>> CUSTOM_DATA = new WeakHashMap<String, WeakReference<ListModel<T>>>();
	private DAO<T> _dao;
	private Object _parameter = null;
	private int _maxRows = 15;

        public SimpleListModel<T> getSubModel(Object value, int nRows) {
		if(value == null || "".equals(value.toString())) return new SimpleListModel<T>((List<T>)Collections.emptyList());
		
		String customKey = (_parameter!= null ? _parameter.toString() : "") + value.toString();
		if(!CUSTOM_DATA.containsKey(customKey)) {
			SimpleListModel<T> lm = new SimpleListModel<T>(_dao.StartsWith(value.toString(), _maxRows, _parameter));
			CUSTOM_DATA.put(customKey, new WeakReference<ListModel<T>>(lm));
		}
		return (SimpleListModel<T>) CUSTOM_DATA.get(customKey).get();
	}
}

Here's a part of my ViewModel:

private AutocompleteListModel<Country> _countries;
public AutocompleteListModel<Country> getCountries() {
		if(_countries == null) {
			_countries = new AutocompleteListModel<Country>(new DAO<Country>(MyBatisConnectionResource.jSchool, "Country"));
		}
		return _countries;
	}

And this is the ZUL part:

<combobox model="@load(vm.countries)" autodrop="true" selectedItem="@bind(vm.selectedCountry)" >
  <template name="model" var="country">
    <comboitem label="@load(country.name)" />
  </template>
</combobox>

This part works very nice for once. When I have selected a value in the combobox, I cannot select another one.
This is the error output:

SEVERE: >><b >org.zkoss.zk.ui.UiException: model of the databind combobox <Combobox sNEQu0> must be an instanceof of org.zkoss.zkplus.datab[email protected]6982237d</b>
>>	at org.zkoss.zkplus.databind.SelectedComboitemConverter.coerceToUi(SelectedComboitemConverter.java:116)
>>	at org.zkoss.zkplus.databind.Binding.myLoadAttribute(Binding.java:387)
>>	at org.zkoss.zkplus.databind.Binding.loadAttribute(Binding.java:340)
>>	at org.zkoss.zkplus.databind.Binding$BaseLoadEventListener.handleEvent(Binding.java:637)
>>	at org.zkoss.zkplus.databind.Binding$LoadEventListener.onEvent(Binding.java:653)
>>	at org.zkoss.zk.ui.AbstractComponent.onEvent(AbstractComponent.java:2706)
>>	at org.zkoss.zk.ui.AbstractComponent.service(AbstractComponent.java:2653)
>>	at org.zkoss.zk.ui.impl.EventProcessor.process(EventProcessor.java:143)
>>	at org.zkoss.zk.ui.impl.UiEngineImpl.processEvent(UiEngineImpl.java:1704)
>>	at org.zkoss.zk.ui.impl.UiEngineImpl.process(UiEngineImpl.java:1489)
>>	at org.zkoss.zk.ui.impl.UiEngineImpl.execUpdate(UiEngineImpl.java:1206)
>>	at org.zkoss.zk.au.http.DHtmlUpdateServlet.process(DHtmlUpdateServlet.java:562)
>>	at org.zkoss.zk.au.http.DHtmlUpdateServlet.doGet(DHtmlUpdateServlet.java:460)
>>	at org.zkoss.zk.au.http.DHtmlUpdateServlet.doPost(DHtmlUpdateServlet.java:468)
>>	at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
>>	at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
>>	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
>>	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
>>	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
>>	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
>>	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
>>	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
>>	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
>>	at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:928)
>>	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
>>	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
>>	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:987)
>>	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:539)
>>	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:300)
>>	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
>>	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
>>	at java.lang.Thread.run(Thread.java:680)

What am I doing wrong? How can I fix this?
jaan

delete flag offensive retag edit

14 Replies

Sort by ยป oldest newest

answered 2012-01-23 15:06:53 +0800

Matze2 gravatar image Matze2
773 7

The stack trace contains ZK5 databinding packages ("org.zkoss.zkplus.databind"), but it should contain ZK6 packages ("org.zkoss.bind").
Which ZK6 version do you use? Do you use BindComposer in your ZUL file?

link publish delete flag offensive edit

answered 2012-01-23 15:20:49 +0800

jaan gravatar image jaan
88 3

I'm using zk-bin-6.0.0-RC2.
In ZUL file I have:

<borderlayout id="main" apply="org.zkoss.bind.BindComposer"
		viewModel="@id('vm') @init('be.jschool.view.users.UsersDirectoryViewModel')">

link publish delete flag offensive edit

answered 2012-01-23 16:15:12 +0800

Matze2 gravatar image Matze2
773 7

Try with the latest "Freshly Build". There were soo many changes and fixes in between.
I have similar combobox definitions and they work.

link publish delete flag offensive edit

answered 2012-01-24 09:08:52 +0800

jaan gravatar image jaan
88 3

updated 2012-01-24 09:09:20 +0800

Thanks for the help!

I've downloaded the latest Freshly Build. But now I get this error "Property '0' not found on type be.jschool.listmodel.AutocompleteListModel"

This is the stack trace:

SEVERE: >>org.zkoss.zel.PropertyNotFoundException: Property '0' not found on type be.jschool.listmodel.AutocompleteListModel
>>	at org.zkoss.zel.BeanELResolver$BeanProperties.get(BeanELResolver.java:258)
>>	at org.zkoss.zel.BeanELResolver$BeanProperties.access$400(BeanELResolver.java:209)
>>	at org.zkoss.zel.BeanELResolver.property(BeanELResolver.java:368)
>>	at org.zkoss.zel.BeanELResolver.getValue(BeanELResolver.java:85)
>>	at org.zkoss.zel.CompositeELResolver.getValue(CompositeELResolver.java:67)
>>	at org.zkoss.zel.CompositeELResolver.getValue(CompositeELResolver.java:67)
>>	at org.zkoss.xel.zel.XelELResolver.getValue(XelELResolver.java:71)
>>	at org.zkoss.bind.xel.zel.BindELResolver.getValue(BindELResolver.java:64)
>>	at org.zkoss.zel.impl.parser.AstValue.getValue(AstValue.java:179)
>>	at org.zkoss.zel.impl.ValueExpressionImpl.getValue(ValueExpressionImpl.java:189)
>>	at org.zkoss.xel.zel.ELXelExpression.evaluate(ELXelExpression.java:40)
>>	at org.zkoss.bind.impl.BindEvaluatorXImpl.getValue(BindEvaluatorXImpl.java:44)
>>	at org.zkoss.bind.impl.ReferenceImpl.getValue(ReferenceImpl.java:44)
>>	at org.zkoss.bind.xel.zel.BindELResolver.getValue(BindELResolver.java:66)
>>	at org.zkoss.zel.impl.parser.AstIdentifier.getValue(AstIdentifier.java:75)
>>	at org.zkoss.zel.impl.parser.AstValue.getValue(AstValue.java:155)
>>	at org.zkoss.zel.impl.ValueExpressionImpl.getValue(ValueExpressionImpl.java:189)
>>	at org.zkoss.xel.zel.ELXelExpression.evaluate(ELXelExpression.java:40)
>>	at org.zkoss.bind.impl.BindEvaluatorXImpl.getValue(BindEvaluatorXImpl.java:44)
>>	at org.zkoss.bind.impl.LoadPropertyBindingImpl.load(LoadPropertyBindingImpl.java:55)
>>	at org.zkoss.bind.impl.PropertyBindingHandler.doLoadBinding(PropertyBindingHandler.java:172)
>>	at org.zkoss.bind.impl.PropertyBindingHandler.doLoad(PropertyBindingHandler.java:383)
>>	at org.zkoss.bind.impl.BinderImpl.loadComponentProperties(BinderImpl.java:1660)
>>	at org.zkoss.bind.impl.BinderImpl.loadComponent(BinderImpl.java:1642)
>>	at org.zkoss.bind.tracker.impl.BindUiLifeCycle$1.onEvent(BindUiLifeCycle.java:63)
>>	at org.zkoss.zk.ui.AbstractComponent.onEvent(AbstractComponent.java:2739)
>>	at org.zkoss.zk.ui.AbstractComponent.service(AbstractComponent.java:2688)
>>	at org.zkoss.zk.ui.AbstractComponent.service(AbstractComponent.java:2651)
>>	at org.zkoss.zk.ui.impl.EventProcessor.process(EventProcessor.java:136)
>>	at org.zkoss.zk.ui.event.Events.sendEvent(Events.java:308)
>>	at org.zkoss.zk.ui.event.Events.sendEvent(Events.java:331)
>>	at org.zkoss.bind.impl.BindComboitemRenderer.render(BindComboitemRenderer.java:102)
>>	at org.zkoss.zul.Combobox$Renderer.render(Combobox.java:402)
>>	at org.zkoss.zul.Combobox$Renderer.access$300(Combobox.java:385)
>>	at org.zkoss.zul.Combobox.onInitRender(Combobox.java:299)
>>	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
>>	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
>>	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
>>	at java.lang.reflect.Method.invoke(Method.java:597)
>>	at org.zkoss.zk.ui.AbstractComponent.service(AbstractComponent.java:2723)
>>	at org.zkoss.zk.ui.AbstractComponent.service(AbstractComponent.java:2651)
>>	at org.zkoss.zk.ui.impl.EventProcessor.process(EventProcessor.java:136)
>>	at org.zkoss.zk.ui.impl.UiEngineImpl.processEvent(UiEngineImpl.java:1696)
>>	at org.zkoss.zk.ui.impl.UiEngineImpl.process(UiEngineImpl.java:1481)
>>	at org.zkoss.zk.ui.impl.UiEngineImpl.execUpdate(UiEngineImpl.java:1198)
>>	at org.zkoss.zk.au.http.DHtmlUpdateServlet.process(DHtmlUpdateServlet.java:558)
>>	at org.zkoss.zk.au.http.DHtmlUpdateServlet.doGet(DHtmlUpdateServlet.java:456)
>>	at org.zkoss.zk.au.http.DHtmlUpdateServlet.doPost(DHtmlUpdateServlet.java:464)
>>	at javax.servlet.http.HttpServlet.service(HttpServlet.java:641)
>>	at javax.servlet.http.HttpServlet.service(HttpServlet.java:722)
>>	at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
>>	at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
>>	at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:224)
>>	at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
>>	at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
>>	at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
>>	at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
>>	at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:928)
>>	at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
>>	at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
>>	at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:987)
>>	at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:539)
>>	at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:300)
>>	at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
>>	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
>>	at java.lang.Thread.run(Thread.java:680)

link publish delete flag offensive edit

answered 2012-01-24 17:31:22 +0800

mgvv gravatar image mgvv
127 2

Hi,

I had a similar problem.
You need to declare a method in AutocompleteListModel class :

public Converter getConverter(final String name)
            throws InstantiationException, IllegalAccessException,
            ClassNotFoundException {
        System.out.println("BaseService.getConverter() " + name);

        return (Converter) Class.forName(name).newInstance();
    }

This solve my problem.

Miguel Goncalves

link publish delete flag offensive edit

answered 2012-01-25 06:37:17 +0800

jaan gravatar image jaan
88 3

thank you Miguel,

But that does not solve my problem for the error: Property '0' not found on type be.jschool.listmodel.AutocompleteListModel"

Any thoughts on that?
jaan

link publish delete flag offensive edit

answered 2012-01-25 08:08:43 +0800

RichardL gravatar image RichardL
768 4

Hi jaan,

Maybe it's related to my issue here: http://www.zkoss.org/forum/listComment/18519-Setter-for-data-in-SimpleListModel. I see you're binding the selected item, but the index of the selected item won't correspond to anything in the underlying data because the listmodel data hasn't been set.

link publish delete flag offensive edit

answered 2012-01-25 09:54:52 +0800

jaan gravatar image jaan
88 3

Hi Richard,

The error occurs after getSubModel is invoked. So when I type some value in the combobox, it invokes getSubModel perfectly (it fills/returns my CUSTOM_DATA as expected), but then the PropertyNotFoundException occurs.
I don't see how or where I should implement a setter for listmodel data.

link publish delete flag offensive edit

answered 2012-01-25 10:25:43 +0800

RichardL gravatar image RichardL
768 4

Yes, as you say, the getSubModel is invoked perfectly, but when a comboitem is selected, the model has no data to select from. Regarding your point about not seeing where to implement a setter for listmodel data, this is what I'm addressing in the other thread - there is no setter in SimpleListModel, but for cases like this there should be.

link publish delete flag offensive edit

answered 2012-01-26 03:52:17 +0800

RichardL gravatar image RichardL
768 4

Hi jaan,
I've made a feature request for the setter. One question: Is the value you need for fetching from the DB the same as the label in the comboitem? If so, maybe you could have an onChange listener on the combobox and get the value of the combobox itself for processing instead of the selected item (this gets an index to correspond with the listmodel list, which hasn't been reset). In my case, I need to get the value of the selected item instead because it is not the same as the label, so I need the setter in SimpleListModel.

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: 2012-01-23 14:08:34 +0800

Seen: 2,079 times

Last updated: Jun 12 '12

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