예제 #1
0
  /** {@inheritDoc} */
  public boolean render(Context context, Object focus) {
    PrintWriter response = context.getResponseWriter();
    // included?
    if (!isIncluded(context, focus)) return false;

    // read only?
    boolean readOnly = false;
    if (this.readOnly != null) {
      readOnly = this.readOnly.decide(context, focus);
    }

    // read only collapsed?
    boolean readOnlyCollapsed = false;
    if (this.readOnlyCollapsed != null) {
      readOnlyCollapsed = this.readOnlyCollapsed.decide(context, focus);
      if (readOnlyCollapsed) readOnly = true;
    }

    // single select?
    boolean single = true;
    if (this.singleSelectDecision != null) {
      single = this.singleSelectDecision.decide(context, focus);
    }

    // alert if empty at submit?
    boolean onEmptyAlert = false;
    if (this.onEmptyAlertMsg != null) {
      onEmptyAlert = true;
      if (this.onEmptyAlertDecision != null) {
        onEmptyAlert = this.onEmptyAlertDecision.decide(context, focus);
      }
    }

    // find values and display text
    List<String> values = new ArrayList<String>();
    if (!this.selectionValues.isEmpty()) {
      for (Message msg : this.selectionValues) {
        if (msg != null) {
          values.add(msg.getMessage(context, focus));
        } else {
          values.add("");
        }
      }
    }

    List<String> display = new ArrayList<String>();
    if (!this.selectionMessages.isEmpty()) {
      for (Message msg : this.selectionMessages) {
        if (msg != null) {
          display.add(msg.getMessage(context, focus));
        } else {
          display.add("");
        }
      }
    }

    if (this.noprintflag) response.println("<div class=\"noprint\">");

    // add in any from the model
    boolean fromModel = false;
    if ((this.selectionValueMessage != null)
        && (this.selectionDisplayMessage != null)
        && (this.selectionReference != null)) {
      // get the main collection
      Collection collection = null;
      Object obj = this.selectionReference.readObject(context, focus);
      if (obj != null) {
        if (obj instanceof Collection) {
          collection = (Collection) obj;
        } else if (obj.getClass().isArray()) {
          Object[] array = (Object[]) obj;
          collection = new ArrayList(array.length);
          for (Object o : array) {
            collection.add(o);
          }
        }
      }

      // if we got something
      if (collection != null) {
        // like iteration, make each object available then get the value and display
        int index = -1;
        for (Object o : collection) {
          index++;

          // place the item
          if (this.iteratorName != null) {
            context.put(
                this.iteratorName, o, this.selectionReference.getEncoding(context, o, index));
          }

          values.add(this.selectionValueMessage.getMessage(context, o));
          display.add(this.selectionDisplayMessage.getMessage(context, o));
          fromModel = true;

          // remove item
          if (this.iteratorName != null) {
            context.remove(this.iteratorName);
          }
        }
      }
    }

    // read the current value(s)
    Set<String> value = new HashSet<String>();
    if (this.propertyReference != null) {
      Object obj = this.propertyReference.readObject(context, focus);
      if (obj != null) {
        // any sort of collection
        if (obj instanceof Collection) {
          for (Object o : ((Collection) obj)) {
            value.add(o.toString());
          }
        }

        // any sort of array
        if (obj.getClass().isArray()) {
          for (Object o : ((Object[]) obj)) {
            value.add(o.toString());
          }
        }

        // otherwise take it as a string
        else {
          value.add(obj.toString());
        }
      }
    }

    if (this.orientation == Orientation.dropdown) {
      renderDropdown(context, focus, readOnly, single, values, display, value);
      return true;
    }

    // generate some ids
    int idRoot = context.getUniqueId();
    String id = getId();
    if (id == null) id = this.getClass().getSimpleName() + "_" + idRoot;
    String decodeId = "decode_" + idRoot;
    String dependencyId = id + "_dependencies";

    // read the "correct" value
    String correctValue = null;
    boolean includeCorrectMarkers = false;
    if ((this.correctReference != null)
        && ((this.correctDecision == null) || (this.correctDecision.decide(context, focus)))) {
      correctValue = this.correctReference.read(context, focus);
      if (correctValue != null) {
        includeCorrectMarkers = true;
      }
    }

    if (onEmptyAlert) {
      // this will become visible if a submit happens and the validation fails
      response.println(
          "<div class=\"ambrosiaAlert\" style=\"display:none\" id=\"alert_"
              + id
              + "\">"
              + this.onEmptyAlertMsg.getMessage(context, focus)
              + "</div>");
    }

    boolean includeSelectAll = this.selectAll && (!single);

    // title if we are doing select all
    if (includeSelectAll) {
      response.print(
          "<input type=\"checkbox\" id=\"all_"
              + id
              + "\""
              + " onclick=\"ambrosiaSelectGroup(this, ids_"
              + id
              + ");\""
              + " />");
      if (this.titleMessage != null) {
        response.print("<label for=\"all_" + id + "\">");
        response.print(this.titleMessage.getMessage(context, focus));
        response.println("</label><br /><br />");
      }
    }

    // title otherwise
    else if (this.titleMessage != null) {
      response.print("<div class=\"ambrosiaComponentTitle\">");
      response.print(this.titleMessage.getMessage(context, focus));
      response.println("</div>");
    }

    // for a single option (unless we are using values from the model, even just one)
    if ((values.size() == 1) && !fromModel) {
      final StringBuffer dependency = new StringBuffer();
      dependency.append("var " + dependencyId + "=[");
      String startingValue = null;
      boolean needDependencies = false;
      String onclick = "";

      boolean hasContained = false;
      for (ContainerRef cr : this.selectionContainers) {
        if ((cr.container != null) && (!cr.container.getContained().isEmpty())) {
          hasContained = true;
          break;
        }
      }

      if (this.submitDestination != null) {
        onclick = "onclick=\"";
        if (hasContained) {
          // onclick += "ambrosiaSelectDependencies(this.value, " + dependencyId + ");";
          onclick +=
              "ambrosiaSelectDependencies(document.getElementById(\'"
                  + id
                  + "\').checked, "
                  + dependencyId
                  + ");";
        }

        String destination = this.submitDestination.getDestination(context, focus);
        onclick += "ambrosiaSubmit('" + destination + "')\" ";
      } else if (this.submitValue) {
        onclick = "onclick=\"";
        if (hasContained) {
          // onclick += "ambrosiaSelectDependencies(this.value, " + dependencyId + ");";
          onclick +=
              "ambrosiaSelectDependencies(document.getElementById(\'"
                  + id
                  + "\').checked, "
                  + dependencyId
                  + ");";
        }

        onclick += "ambrosiaSubmit(this.value)\" ";
      } else if (hasContained) {
        // onclick = "onclick=\"ambrosiaSelectDependencies(this.value, " + dependencyId + ")\" ";
        onclick =
            "onclick=\"ambrosiaSelectDependencies(document.getElementById(\'"
                + id
                + "\').checked, "
                + dependencyId
                + ")\" ";
      }
      /*
       * if (this.submitDestination != null) { String destination = this.submitDestination.getDestination(context, focus); onclick = "onclick=\"ambrosiaSubmit('" + destination + "')\" "; } else if (this.submitValue) { onclick =
       * "onclick=\"ambrosiaSubmit(this.value)\" "; }
       */

      // convert to boolean
      boolean checked = value.contains("true");

      // if we are doing correct marking
      if (includeCorrectMarkers) {
        // if checked, mark as correct or not
        if (checked) {
          // is the value correct?
          boolean correct =
              (correctValue == null) ? false : Boolean.parseBoolean(correctValue) == checked;

          if (correct) {
            response.print(
                "<img src=\""
                    + context.getUrl(this.correctIcon)
                    + "\" style=\"border-style: none;\" alt=\""
                    + this.correctMessage.getMessage(context, focus)
                    + "\" title=\""
                    + this.correctMessage.getMessage(context, focus)
                    + "\"/>");
          } else {
            response.print(
                "<img src=\""
                    + context.getUrl(this.incorrectIcon)
                    + "\" style=\"border-style: none;\" alt=\""
                    + this.incorrectMessage.getMessage(context, focus)
                    + "\" title=\""
                    + this.incorrectMessage.getMessage(context, focus)
                    + "\"/>");
          }
        }

        // else leave a placeholder
        else {
          response.println("<div style=\"float:left;width:16px\">&nbsp;</div>");
        }
      }

      // the check box
      response.println(
          "<input "
              + onclick
              + "type=\"checkbox\" name=\""
              + id
              + "\" id=\""
              + id
              + "\" value=\""
              + values.get(0)
              + "\" "
              + (checked ? "CHECKED" : "")
              + (readOnly ? " disabled=\"disabled\"" : "")
              + " />");

      context.editComponentRendered(id);

      // the decode directive
      if ((this.propertyReference != null) && (!readOnly)) {
        response.println(
            "<input type=\"hidden\" name=\""
                + decodeId
                + "\" value =\""
                + id
                + "\" />"
                + "<input type=\"hidden\" name=\""
                + "prop_"
                + decodeId
                + "\" value=\""
                + this.propertyReference.getFullReference(context)
                + "\" />"
                + "<input type=\"hidden\" name=\""
                + "null_"
                + decodeId
                + "\" value=\""
                + this.notSelectedValue
                + "\" />");
      }

      // title after (right) for the single check box version
      if ((display.size() > 0) && (display.get(0) != null)) {
        response.print("<label for=\"" + id + "\">");
        response.print(display.get(0));
        response.println("</label>");
      }

      String fragment = "";
      String val = null;
      ContainerRef containerRef = this.selectionContainers.get(0);
      // container of dependent components
      if ((containerRef != null)
          && (containerRef.container != null)
          && (!containerRef.container.getContained().isEmpty())) {
        needDependencies = true;
        val = values.get(0);
        dependency.append("[\"" + val + "\",");
        // dependency.append(Boolean.toString(true) + ",");
        dependency.append(Boolean.toString(containerRef.reversed) + ",");
        RenderListener listener =
            new RenderListener() {
              public void componentRendered(String id) {
                dependency.append("\"" + id + "\",");
              }
            };

        // listen for any dependent edit components being rendered
        context.addEditComponentRenderListener(listener);

        // ContainerRef containerRef = this.selectionContainers.get(0);
        if (containerRef.separate) {
          context.setCollecting();
          response = context.getResponseWriter();
        }

        // render the dependent components
        for (Component c : containerRef.container.getContained()) {
          if (containerRef.separate) {
            if (containerRef.indented) {
              response.println("<div class=\"ambrosiaContainerComponentIndented\">");
            } else {
              response.println("<div class=\"ambrosiaContainerComponent\">");
            }
          }
          c.render(context, focus);
          if (containerRef.separate) response.println("</div>");
        }

        if (containerRef.separate) {
          fragment += context.getCollected();
          response = context.getResponseWriter();
        }

        // stop listening
        context.removeEditComponentRenderListener(listener);

        dependency.setLength(dependency.length() - 1);
        dependency.append("],");
      }

      /*
       * boolean selected = value.contains(val);
       *
       * if (selected) { startingValue = val; }
       */
      if (needDependencies) {
        dependency.setLength(dependency.length() - 1);
        dependency.append("];\n");
        context.addScript(dependency.toString());

        // if read only, skip the initial setting
        if (!readOnly) {
          startingValue = String.valueOf(checked);

          // context.addScript("ambrosiaSelectDependencies(\"" + startingValue + "\", " +
          // dependencyId + ");\n");
          context.addScript(
              "ambrosiaSelectDependencies(document.getElementById(\'"
                  + id
                  + "\').checked, "
                  + dependencyId
                  + ");\n");

          // context.addScript("ambrosiaSelectDependencies(document.getElementById(" + id +
          // ").value, " + dependencyId + ");\n");
        }
      }

      // the decode directive
      /*
       * if ((this.propertyReference != null) && (!readOnly)) { response.println("<input type=\"hidden\" name=\"" + decodeId + "\" value =\"" + id + "\" />" + "<input type=\"hidden\" name=\"" + "prop_" + decodeId + "\" value=\"" +
       * this.propertyReference.getFullReference(context) + "\" />"); }
       */

      // for onEmptyAlert, add some client-side validation
      if ((onEmptyAlert) && (!readOnly) && single) {
        StringBuffer buf = new StringBuffer();
        for (int i = 0; i < values.size(); i++) {
          buf.append(
              "!document.getElementById('" + id + "_" + Integer.toString(i) + "').checked &&");
        }
        buf.setLength(buf.length() - 3);

        context.addValidation(
            "	if ("
                + buf.toString()
                + ")\n"
                + "	{\n"
                + "		if (document.getElementById('alert_"
                + id
                + "').style.display == \"none\")\n"
                + "		{\n"
                + "			document.getElementById('alert_"
                + id
                + "').style.display = \"\";\n"
                + "			rv=false;\n"
                + "		}\n"
                + "	}\n");
      }

      if (fragment.length() > 0) {
        response.print(fragment);
      }
    } else {
      final StringBuffer dependency = new StringBuffer();
      dependency.append("var " + dependencyId + "=[");
      String startingValue = null;
      boolean needDependencies = false;
      String onclick = "";

      boolean hasContained = false;
      for (ContainerRef cr : this.selectionContainers) {
        if ((cr.container != null) && (!cr.container.getContained().isEmpty())) {
          hasContained = true;
          break;
        }
      }

      if (this.submitDestination != null) {
        onclick = "onclick=\"";
        if (hasContained) {
          onclick += "ambrosiaSelectDependencies(this.value, " + dependencyId + ");";
        }

        String destination = this.submitDestination.getDestination(context, focus);
        onclick += "ambrosiaSubmit('" + destination + "')\" ";
      } else if (this.submitValue) {
        onclick = "onclick=\"";
        if (hasContained) {
          onclick += "ambrosiaSelectDependencies(this.value, " + dependencyId + ");";
        }

        onclick += "ambrosiaSubmit(this.value)\" ";
      } else if (hasContained) {
        onclick = "onclick=\"ambrosiaSelectDependencies(this.value, " + dependencyId + ")\" ";
      } else if (includeSelectAll) {
        onclick = "onclick=\"ambrosiaSelectChange(this, ids_" + id + ", 'all_" + id + "');\" ";
      }

      // collect the rendered ids
      List<String> ids = new ArrayList<String>();

      // collected dependent components marked separate
      String fragment = "";

      for (int i = 0; i < values.size(); i++) {
        String val = values.get(i);
        String message = "";
        if (i < display.size()) {
          message = display.get(i);
        }
        ContainerRef containerRef = null;
        if (i < this.selectionContainers.size()) {
          containerRef = this.selectionContainers.get(i);
        }

        boolean selected = value.contains(val);

        if ((!selected) && readOnlyCollapsed) continue;

        if (selected) {
          startingValue = val;
        }

        // if we are doing correct marking
        if (includeCorrectMarkers) {
          // if checked, mark as correct or not
          if (selected) {
            // is this one the correct one?
            boolean correct = (correctValue == null) ? false : correctValue.equals(val);

            if (correct) {
              response.print(
                  "<img src=\""
                      + context.getUrl(this.correctIcon)
                      + "\" style=\"border-style: none;\" alt=\""
                      + this.correctMessage.getMessage(context, focus)
                      + "\" title=\""
                      + this.correctMessage.getMessage(context, focus)
                      + "\"/>");
            } else {
              response.print(
                  "<img src=\""
                      + context.getUrl(this.incorrectIcon)
                      + "\" style=\"border-style: none;\" alt=\""
                      + this.incorrectMessage.getMessage(context, focus)
                      + "\" title=\""
                      + this.incorrectMessage.getMessage(context, focus)
                      + "\"/>");
            }
          }

          // else leave a placeholder
          else {
            response.println("<div style=\"float:left;width:16px\">&nbsp;</div>");
          }
        }

        // use a radio for single select
        String thisId = id + "_" + i;
        if (single) {
          // the radio button
          response.println(
              "<input "
                  + onclick
                  + "type=\"radio\" name=\""
                  + id
                  + "\" id=\""
                  + thisId
                  + "\" value=\""
                  + val
                  + "\" "
                  + (selected ? "CHECKED" : "")
                  + (readOnly ? " disabled=\"disabled\"" : "")
                  + " />");
        }

        // for multiple selection, use a checkbox set
        else {
          response.println(
              "<input "
                  + onclick
                  + "type=\"checkbox\" name=\""
                  + id
                  + "\" id=\""
                  + thisId
                  + "\" value=\""
                  + val
                  + "\" "
                  + (selected ? "CHECKED" : "")
                  + (readOnly ? " disabled=\"disabled\"" : "")
                  + " />");
        }
        ids.add(thisId);

        // message
        response.print("<label for=\"" + thisId + "\">");
        response.print(message);
        response.println("</label>");

        // container of dependent components
        if ((containerRef != null)
            && (containerRef.container != null)
            && (!containerRef.container.getContained().isEmpty())) {
          needDependencies = true;

          dependency.append("[\"" + val + "\",");
          dependency.append(Boolean.toString(containerRef.reversed) + ",");
          RenderListener listener =
              new RenderListener() {
                public void componentRendered(String id) {
                  dependency.append("\"" + id + "\",");
                }
              };

          // listen for any dependent edit components being rendered
          context.addEditComponentRenderListener(listener);

          if (containerRef.separate) {
            context.setCollecting();
            response = context.getResponseWriter();
          }

          // render the dependent components
          for (Component c : containerRef.container.getContained()) {
            if (containerRef.separate) {
              if (containerRef.indented) {
                response.println("<div class=\"ambrosiaContainerComponentIndented\">");
              } else {
                response.println("<div class=\"ambrosiaContainerComponent\">");
              }
            }
            c.render(context, focus);
            if (containerRef.separate) response.println("</div>");
          }

          if (containerRef.separate) {
            fragment += context.getCollected();
            response = context.getResponseWriter();
          }

          // stop listening
          context.removeEditComponentRenderListener(listener);

          dependency.setLength(dependency.length() - 1);
          dependency.append("],");
        }

        if (this.orientation == Orientation.vertical) {
          response.println("<br />");
        }
      }

      // register the ids in reverse order
      // Note: reverse order so that the first choice gets processed last, as in when this is a
      // dependent component to another selection
      Collections.reverse(ids);
      for (String thisId : ids) {
        context.editComponentRendered(thisId);
      }

      // record the group of checkbox element ids
      if (includeSelectAll) {
        StringBuilder buf = new StringBuilder();
        buf.append("var ids_" + id + "=[");
        for (String oneId : ids) {
          buf.append("\"" + oneId + "\",");
        }
        buf.setLength(buf.length() - 1);
        buf.append("];\n");
        context.addScript(buf.toString());
      }

      if (needDependencies) {
        dependency.setLength(dependency.length() - 1);
        dependency.append("];\n");
        context.addScript(dependency.toString());

        // if read only, skip the initial setting
        if (!readOnly) {
          context.addScript(
              "ambrosiaSelectDependencies(\"" + startingValue + "\", " + dependencyId + ");\n");
        }
      }

      // the decode directive
      if ((this.propertyReference != null) && (!readOnly)) {
        response.println(
            "<input type=\"hidden\" name=\""
                + decodeId
                + "\" value =\""
                + id
                + "\" />"
                + "<input type=\"hidden\" name=\""
                + "prop_"
                + decodeId
                + "\" value=\""
                + this.propertyReference.getFullReference(context)
                + "\" />");
      }

      // for onEmptyAlert, add some client-side validation
      if ((onEmptyAlert) && (!readOnly) && single) {
        StringBuffer buf = new StringBuffer();
        for (int i = 0; i < values.size(); i++) {
          buf.append(
              "!document.getElementById('" + id + "_" + Integer.toString(i) + "').checked &&");
        }
        buf.setLength(buf.length() - 3);

        context.addValidation(
            "	if ("
                + buf.toString()
                + ")\n"
                + "	{\n"
                + "		if (document.getElementById('alert_"
                + id
                + "').style.display == \"none\")\n"
                + "		{\n"
                + "			document.getElementById('alert_"
                + id
                + "').style.display = \"\";\n"
                + "			rv=false;\n"
                + "		}\n"
                + "	}\n");
      }

      if (fragment.length() > 0) {
        response.print(fragment);
      }
    }
    if (this.noprintflag) response.println("</div>");

    return true;
  }
예제 #2
0
  /** {@inheritDoc} */
  protected void renderDropdown(
      Context context,
      Object focus,
      boolean readOnly,
      boolean single,
      List<String> values,
      List<String> display,
      Set<String> value) {
    // generate some ids
    int idRoot = context.getUniqueId();
    String id = this.getClass().getSimpleName() + "_" + idRoot;
    String decodeId = "decode_" + idRoot;

    PrintWriter response = context.getResponseWriter();

    // Note: correct / incorrect markings not supported for dropdown

    // title
    if (this.titleMessage != null) {
      response.print("<label class=\"ambrosiaComponentTitle\" for=\"" + id + "\">");
      response.print(this.titleMessage.getMessage(context, focus));
      response.println("</label>");
    }

    String onchange = "";
    if (this.submitDestination != null) {
      String destination = this.submitDestination.getDestination(context, focus);
      onchange = " onchange=\"ambrosiaSubmit('" + destination + "');\" ";
    } else if (this.submitValue) {
      onchange = " onchange=\"ambrosiaSubmit(this.value);\" ";
    }

    response.println(
        "<select size=\""
            + Integer.toString(this.height)
            + "\" "
            + (single ? "" : "multiple ")
            + "name=\""
            + id
            + "\" id=\""
            + id
            + "\""
            + (readOnly ? " disabled=\"disabled\"" : "")
            + onchange
            + ">");

    // TODO: must have selection values

    // TODO: selectionContainers not supported

    for (int i = 0; i < values.size(); i++) {
      String val = values.get(i);
      String message = "";
      if (i < display.size()) {
        message = display.get(i);
      }

      boolean selected = value.contains(val);

      // the option
      response.println(
          "<option "
              + "value=\""
              + val
              + "\" "
              + (selected ? "selected=\"selected\"" : "")
              + ">"
              + message
              + "</option>");
    }

    response.println("</select>");

    // the decode directive
    if ((this.propertyReference != null) && (!readOnly)) {
      response.println(
          "<input type=\"hidden\" name=\""
              + decodeId
              + "\" value =\""
              + id
              + "\" />"
              + "<input type=\"hidden\" name=\""
              + "prop_"
              + decodeId
              + "\" value=\""
              + this.propertyReference.getFullReference(context)
              + "\" />");
    }
  }