Esempio n. 1
0
  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;
  }
  public void render(final Comboitem item, final Object data, final int index) throws Exception {
    final Combobox cb = (Combobox) item.getParent();
    final ListModel<?> model = cb.getModel();
    final int size = model.getSize();
    final Template tm = resoloveTemplate(cb, item, data, index, size, "model");
    if (tm == null) {
      item.setLabel(Objects.toString(data));
      item.setValue(data);
    } else {
      final ForEachStatus iterStatus =
          new AbstractForEachStatus() { // provide iteration status in this context
            private static final long serialVersionUID = 1L;

            public int getIndex() {
              return index;
            }

            public Object getEach() {
              return data;
            }

            public Integer getEnd() {
              return size;
            }
          };

      final String var = (String) tm.getParameters().get(EACH_ATTR);
      final String varnm = var == null ? EACH_VAR : var; // var is not specified, default to "each"
      final String itervar = (String) tm.getParameters().get(STATUS_ATTR);
      final String itervarnm =
          itervar == null
              ? (var == null ? EACH_STATUS_VAR : varnm + STATUS_POST_VAR)
              : itervar; // provide default value if not specified

      // bug 1188, EL when nested var and itervar
      Object oldVar = cb.getAttribute(varnm);
      Object oldIter = cb.getAttribute(itervarnm);
      cb.setAttribute(varnm, data);
      cb.setAttribute(itervarnm, iterStatus);

      final Component[] items = tm.create(cb, item, null, null);

      cb.setAttribute(varnm, oldVar);
      cb.setAttribute(itervarnm, oldIter);

      if (items.length != 1)
        throw new UiException("The model template must have exactly one item, not " + items.length);

      final Comboitem nci = (Comboitem) items[0];
      nci.setAttribute(BinderImpl.VAR, varnm); // for the converter to get the value

      if (model instanceof ListSubModel) {
        // ZK-992 wrong item when binding to combbox with submodel implementation
        // combobox has a internal model as the submodel,
        // I don't have way to access the submodel, and user doesn't has info to notify model[index]
        // changed.
        // so I set the value directly.
        nci.setAttribute(varnm, data);
      } else {
        addItemReference(
            cb, nci, index, varnm); // kept the reference to the data, before ON_BIND_INIT
      }

      nci.setAttribute(itervarnm, iterStatus);

      // add template dependency
      addTemplateTracking(cb, nci, data, index, size);

      if (nci.getValue() == null) // template might set it
      nci.setValue(data);
      item.setAttribute("org.zkoss.zul.model.renderAs", nci);
      // indicate a new item is created to replace the existent one
      item.detach();

      // bug #ZK-677: combobox selection is lost after reload model
      // binding Comboitem immediately, @see BindUiLifeCycle#afterComponentAttached
      Events.sendEvent(new Event(BinderImpl.ON_BIND_INIT, nci));
    }
  }