Beispiel #1
0
  /**
   * Identify the itemset in the backend model, and create a set of SelectChoice objects at the
   * current question reference based on the data in the model.
   *
   * <p>Will modify the itemset binding to contain the relevant choices
   *
   * @param itemset The binding for an itemset, where the choices will be populated
   * @param curQRef A reference to the current question's element, which will be used to determine
   *     the values to be chosen from.
   */
  public void populateDynamicChoices(ItemsetBinding itemset, TreeReference curQRef) {
    Vector<SelectChoice> choices = new Vector<SelectChoice>();

    Vector<TreeReference> matches =
        itemset.nodesetExpr.evalNodeset(
            this.getInstance(),
            new EvaluationContext(exprEvalContext, itemset.contextRef.contextualize(curQRef)));

    for (int i = 0; i < matches.size(); i++) {
      TreeReference item = matches.elementAt(i);

      String label =
          itemset.labelExpr.evalReadable(
              this.getInstance(), new EvaluationContext(exprEvalContext, item));
      String value = null;
      TreeElement copyNode = null;

      if (itemset.copyMode) {
        copyNode = this.getInstance().resolveReference(itemset.copyRef.contextualize(item));
      }
      if (itemset.valueRef != null) {
        value =
            itemset.valueExpr.evalReadable(
                this.getInstance(), new EvaluationContext(exprEvalContext, item));
      }
      //			SelectChoice choice = new SelectChoice(labelID,labelInnerText,value,isLocalizable);
      SelectChoice choice =
          new SelectChoice(label, value != null ? value : "dynamic:" + i, itemset.labelIsItext);
      choice.setIndex(i);
      if (itemset.copyMode) choice.copyNode = copyNode;

      choices.addElement(choice);
    }

    if (choices.size() == 0) {
      throw new RuntimeException(
          "dynamic select question has no choices! [" + itemset.nodesetRef + "]");
    }

    itemset.setChoices(choices, this.getLocalizer());
  }
Beispiel #2
0
  public void copyItemsetAnswer(QuestionDef q, TreeElement targetNode, IAnswerData data)
      throws InvalidReferenceException {
    ItemsetBinding itemset = q.getDynamicChoices();
    TreeReference targetRef = targetNode.getRef();
    TreeReference destRef = itemset.getDestRef().contextualize(targetRef);

    Vector<Selection> selections = null;
    Vector<String> selectedValues = new Vector<String>();
    if (data instanceof SelectMultiData) {
      selections = (Vector<Selection>) data.getValue();
    } else if (data instanceof SelectOneData) {
      selections = new Vector<Selection>();
      selections.addElement((Selection) data.getValue());
    }
    if (itemset.valueRef != null) {
      for (int i = 0; i < selections.size(); i++) {
        selectedValues.addElement(selections.elementAt(i).choice.getValue());
      }
    }

    // delete existing dest nodes that are not in the answer selection
    Hashtable<String, TreeElement> existingValues = new Hashtable<String, TreeElement>();
    Vector<TreeReference> existingNodes = getInstance().expandReference(destRef);
    for (int i = 0; i < existingNodes.size(); i++) {
      TreeElement node = getInstance().resolveReference(existingNodes.elementAt(i));

      if (itemset.valueRef != null) {
        String value =
            itemset
                .getRelativeValue()
                .evalReadable(
                    this.getInstance(), new EvaluationContext(exprEvalContext, node.getRef()));
        if (selectedValues.contains(value)) {
          existingValues.put(value, node); // cache node if in selection and already exists
        }
      }

      // delete from target
      targetNode.removeChild(node);
    }

    // copy in nodes for new answer; preserve ordering in answer
    for (int i = 0; i < selections.size(); i++) {
      Selection s = selections.elementAt(i);
      SelectChoice ch = s.choice;

      TreeElement cachedNode = null;
      if (itemset.valueRef != null) {
        String value = ch.getValue();
        if (existingValues.containsKey(value)) {
          cachedNode = existingValues.get(value);
        }
      }

      if (cachedNode != null) {
        cachedNode.setMult(i);
        targetNode.addChild(cachedNode);
      } else {
        getInstance().copyItemsetNode(ch.copyNode, destRef, this);
      }
    }

    triggerTriggerables(
        destRef); // trigger conditions that depend on the creation of these new nodes
    initializeTriggerables(destRef); // initialize conditions for the node (and sub-nodes)
    // not 100% sure this will work since destRef is ambiguous as the last step, but i think it's
    // supposed to work
  }