public Comboitem newComboitem(Combobox combobox) { // clone from template final Comboitem clone = (Comboitem) _template.clone(); // TODO: see if databinder has this kind of Comboitem, if not, add new CollectionListItem // avoid duplicate id error, will set to new id when render() // Bug #1962153: Data binding generates duplicate id in some case add "_". if (clone.getId().length() > 0) { clone.setId(null); } // link cloned component with template // each Comboitem and and it descendants share the same templatemap Map<Object, Object> templatemap = new HashMap<Object, Object>(8); BindingRendererUtil.linkTemplates(clone, _template, templatemap, _binder); // link this template map to parent templatemap (Combobox in Combobox) Map parenttemplatemap = (Map) combobox.getAttribute(DataBinder.TEMPLATEMAP); if (parenttemplatemap != null) { templatemap.put(DataBinder.TEMPLATEMAP, parenttemplatemap); } // kept clone kids somewhere to avoid create too many components in browser final List<Component> kids = new ArrayList<Component>(clone.getChildren()); clone.setAttribute(KIDS, kids); clone.getChildren().clear(); return clone; }
@SuppressWarnings("unchecked") public void render(Comboitem item, Object bean, int index) throws Exception { final List<Component> kids = cast((List) item.getAttribute(KIDS)); ((List<Component>) item.getChildren()).addAll(kids); // item.removeAttribute(KIDS); // remove template mark of cloned component and its descendants _binder.setupTemplateComponent(item, null); // setup clone id BindingRendererUtil.setupCloneIds(item); // bind bean to the associated listitem and its descendants final String varname = (String) _template.getAttribute(DataBinder.VARNAME); final Map<Object, Object> templatemap = cast((Map) item.getAttribute(DataBinder.TEMPLATEMAP)); templatemap.put(varname, bean); // apply the data binding _binder.loadComponent(item); // feature# 3026221: Databinder shall fire onCreate when cloning each items DataBinder.postOnCreateEvents(item); // since 5.0.4 }