0 votes
1.2k views
in Coach Views by

1 Answer

0 votes
by (30.6k points)

A coach view validation framework = one way to declare rules, one place to run them, one way to show results - implemented as a small JavaScript library (managed asset) plus a convention in the coaches. A compact working version:

// validation.js (managed web asset, included by the house-style header view)
window.myco = window.myco || {};
myco.validate = (function () {
  var rules = {
    required: function (v) { return v !== null && v !== undefined && String(v).trim() !== ""; },
    email:    function (v) { return !v || /^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(v); },
    min:      function (v, p) { return v === null || v === "" || Number(v) >= p; },
    max:      function (v, p) { return v === null || v === "" || Number(v) <= p; },
    pattern:  function (v, p) { return !v || new RegExp(p).test(v); },
    future:   function (v) { return !v || new Date(v) >= new Date(new Date().setHours(0,0,0,0)); }
  };
  var messages = { required: "Required", email: "Invalid e-mail", min: "Minimum is {p}", max: "Maximum is {p}", pattern: "Invalid format", future: "Date must not be in the past" };
  // spec: { "Email": ["required", "email"], "Amount": ["required", {"min": 1}, {"max": 10000}], "Due": ["future"] }
  return function (spec, summaryControl) {
    var errors = [];
    Object.keys(spec).forEach(function (id) {
      var ctl = bpmext.ui.getView(id); if (!ctl) return;
      var value = ctl.getData ? ctl.getData() : null, msg = null;
      spec[id].forEach(function (r) {
        if (msg) return;
        var name = typeof r === "string" ? r : Object.keys(r)[0], p = typeof r === "string" ? undefined : r[name];
        if (!rules[name](value, p)) msg = messages[name].replace("{p}", p);
      });
      ctl.setValid(!msg, msg || ""); if (msg) errors.push((ctl.context.options["@label"] ? ctl.context.options["@label"].get("value") : id) + ": " + msg);
    });
    if (summaryControl) { summaryControl.setText(errors.join("<br>")); summaryControl.setVisible(errors.length > 0); }
    return errors.length === 0;
  };
})();
// coach: Submit button > On click
if (!myco.validate({ "Email": ["required", "email"], "Amount": ["required", {"min": 1}, {"max": 10000}], "Due": ["future"] }, ${Errors})) return;
${SubmitHidden}.click();      // hidden button with the boundary event

Extend it with cross-field rules (a function in the spec), server-side re-validation in the CSHS validation script for the rules that matter (the server never trusts the browser), and a "validate on change" mode (call the same function from each control's On change with a one-control spec). Keep the messages in a resource bundle for localization. The framework stays small because the UI Toolkit already does the display part (setValid).

References

Related questions

0 votes
1 answer 782 views
0 votes
1 answer 1.2k views
0 votes
1 answer 901 views
0 votes
1 answer 1.7k views
0 votes
1 answer 1.9k views
0 votes
1 answer 861 views
+1 vote
1 answer 2.5k views
+1 vote
1 answer 921 views
0 votes
1 answer 2.4k views
0 votes
1 answer 2.5k views
0 votes
1 answer 4.0k views
0 votes
1 answer 3.1k views

723 questions

807 answers

98 comments

4.9k users

Join BPM Community Discord Channel

Welcome to BPM Tips Q&A, Community wiki/forum where you can ask questions and receive answers from other IBM BPM experts and members of the community. Users with 2000 points will automatically be promoted to expert level.
Created by Dosvak LLC
Our Youtube Channel
...