public void createNewRepeat(FormIndex index) throws InvalidReferenceException { TreeReference destRef = getChildInstanceRef(index); TreeElement template = instance.getTemplate(destRef); instance.copyNode(template, destRef); preloadInstance(instance.resolveReference(destRef)); triggerTriggerables(destRef); // trigger conditions that depend on the creation of this new node initializeTriggerables(destRef); // initialize conditions for the node (and sub-nodes) }
/** * Deletes the inner-most repeat that this node belongs to and returns the corresponding * FormIndex. Behavior is currently undefined if you call this method on a node that is not * contained within a repeat. * * @param index * @return */ public FormIndex deleteRepeat(FormIndex index) { Vector indexes = new Vector(); Vector multiplicities = new Vector(); Vector elements = new Vector(); collapseIndex(index, indexes, multiplicities, elements); // loop backwards through the elements, removing objects from each // vector, until we find a repeat // TODO: should probably check to make sure size > 0 for (int i = elements.size() - 1; i >= 0; i--) { IFormElement e = (IFormElement) elements.elementAt(i); if (e instanceof GroupDef && ((GroupDef) e).getRepeat()) { break; } else { indexes.removeElementAt(i); multiplicities.removeElementAt(i); elements.removeElementAt(i); } } // build new formIndex which includes everything // up to the node we're going to remove FormIndex newIndex = buildIndex(indexes, multiplicities, elements); TreeReference deleteRef = getChildInstanceRef(newIndex); TreeElement deleteElement = instance.resolveReference(deleteRef); TreeReference parentRef = deleteRef.getParentRef(); TreeElement parentElement = instance.resolveReference(parentRef); int childMult = deleteElement.getMult(); parentElement.removeChild(deleteElement); // update multiplicities of other child nodes for (int i = 0; i < parentElement.getNumChildren(); i++) { TreeElement child = parentElement.getChildAt(i); if (child.getMult() > childMult) { child.setMult(child.getMult() - 1); } } triggerTriggerables(deleteRef); return newIndex; }
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 }
public void setValue(IAnswerData data, TreeReference ref, TreeElement node) { setAnswer(data, node); triggerTriggerables(ref); // TODO: pre-populate fix-count repeats here? }