Skip to content

Commit

Permalink
Work in progress
Browse files Browse the repository at this point in the history
  • Loading branch information
miohtama committed Nov 2, 2012
1 parent e8cf618 commit 268c39b
Show file tree
Hide file tree
Showing 4 changed files with 410 additions and 264 deletions.
2 changes: 2 additions & 0 deletions README.rst
Expand Up @@ -9,6 +9,8 @@ It is a helper library for building complex conditional forms.

* Handle nested decision trees

* Handle list values and multi-value comparisons

* Based on jQuery, compatible down to version jQuery 1.4

How it works
Expand Down
47 changes: 40 additions & 7 deletions demo.js
Expand Up @@ -7,30 +7,63 @@
// Start creating a new ruleset
var ruleset = $.deps.createRuleset();

var masterSwitch = ruleset.createRule("#mechanicalThrombectomyDevice", "!=", "--NOVALUE--");
var masterSwitch = ruleset.createRule("#mechanicalThrombectomyDevice",
"not-any",
["--NOVALUE--", "noDevice", "notApplicable"]);

// Make this controls to be slave for the master rule
masterSwitch.include("#dac");
masterSwitch.include("#numberOfAttemps");
masterSwitch.include(".datagridwidget-block-dac");
masterSwitch.include(".datagridwidget-block-numberOfAttempts");

// Some sample pop-ups based on number input value

var twoAttempts = masterSwitch.createRule("#numberOfAttemps", "==", 2);
twoAttempts.include("#two-attemps-test");
var twoAttempts = masterSwitch.createRule("#numberOfAttempts", "==", 2);
twoAttempts.include("#two-attempts-test");

var threeAttempts = masterSwitch.createRule("#numberOfAttemps", "==", 3);
var threeAttempts = masterSwitch.createRule("#numberOfAttempts", "==", 3);
threeAttempts.include("#three-attempts-test");

// Some more selection dropdowns under master rule

masterSwitch.include(".datagridwidget-block-balloonGuide");
masterSwitch.include(".datagridwidget-block-aspirationInGuideDuringThrombectomy");
masterSwitch.include(".datagridwidget-block-incubationOfDevice");
masterSwitch.include(".datagridwidget-block-delayedReocclusion");
masterSwitch.include(".datagridwidget-block-angioplasty");

// Check that <select> value equals our choice "yes"
var angioplasty = masterSwitch.createRule("#angioplasty", "==", "yes");
angioplasty.include(".datagridwidget-block-angioplastyExtraCranial");
angioplasty.include(".datagridwidget-block-angioplastyIntraCranial");

// Another <select> with nested options
masterSwitch.include(".datagridwidget-block-adjunctiveStenting");
var adjunctiveStenting = masterSwitch.createRule("#adjunctiveStenting", "==", "yes");
adjunctiveStenting.include(".datagridwidget-block-adjunctiveStentingExtraCranial");
adjunctiveStenting.include(".datagridwidget-block-adjunctiveStentingIntraCranial");

// Then add some third level options which check against checboxes
var adjunctiveStentingExtraCranial = adjunctiveStenting.createRule("#adjunctiveStentingExtraCranial", "==", true);
adjunctiveStentingExtraCranial.include(".datagridwidget-block-adjunctiveStentingExtraCranialType");

var adjunctiveStentingIntraCranial = adjunctiveStenting.createRule("#adjunctiveStentingIntraCranial", "==", true);
adjunctiveStentingIntraCranial.include(".datagridwidget-block-adjunctiveStentingIntraCranialType");


return ruleset;
}

$(document).ready(function() {

var ruleset = buildRuleset();

var cfg = {
log : true
};

// Make ruleset effective on a selection
// and start following changes in its inputs
$.deps.enable($("#demo-content"), ruleset);
$.deps.enable($("#demo-content"), ruleset, cfg);

});

Expand Down
110 changes: 99 additions & 11 deletions deps.js
@@ -1,7 +1,42 @@
/*global console, window*/

(function($) {

"use strict";

/**
* Microsoft wrapper
*/
function log(msg) {
if(console && console.log) {
console.log(msg);
}
}

/**
* Sample configuration object
*/
var cfg = {

/**
* @cfg show Callback function show(elem) for showing elements
* @type {Function}
*/
show : null,

/**
* @cfg hide Callback function hide(elem) for hiding elements
* @type {Functoin}
*/
hide : null,

/**
* @cfg log Write log output of rule applying
* @type {Boolean}
*/
log : false
};

/**
* Define one field inter-dependency rule.
*
Expand All @@ -10,6 +45,8 @@
*
* Possible conditions:
* "==" Widget value must be equal to given value
* "any" Widget value must be any of the values in the given value array
* "non-any" Widget value must not be any of the values in the given value array
* "!=" Widget value must not be qual to given value
* "()" Call value as a function(context, controller, ourWidgetValue) and if it's true then the condition is true
* null This input does not have any sub-conditions
Expand Down Expand Up @@ -37,6 +74,32 @@

$.extend(Rule.prototype, {

/**
* Evaluation engine
*
* @param {String} condition Any of given conditions in Rule class description
* @param {Object} val1 The base value we compare against
* @param {Object} val2 Something we got out of input
* @return {Boolean} true or false
*/
evalCondition : function(control, context, condition, val1, val2) {

if(this.condition == "==") {
return val1 == val2;
} else if(condition == "!=") {
return val1 != val2;
} else if(condition == "()") {
return val1(context, control, val2);
} else if(condition == "any") {
return val1.indexOf(val2) >= 0;
} else if(condition == "not-any") {
return val1.indexOf(val2) < 0;
} else {
throw new Error("Unknown condition:" + condition);
}

},

/**
* Evaluate the condition of this rule in given jQuery context.
*
Expand All @@ -45,26 +108,44 @@
* @param {jQuery} context The jQuery selection in which this rule is evaluated.
*
*/
evalCondition : function(context) {
checkCondition : function(context, cfg) {

// We do not have condition set, we are always true
if(!this.condition) {
return true;
}

var control = context.find(this.controller);
if(control.size() === 0 && cfg.log) {
log("Evaling condition: Could not find controller input " + this.controller);
}

var val = this.getControlValue(context, control);
if(cfg.log && val === undefined) {
log("Evaling condition: Could not exctract value from input " + this.controller);
}

if(this.condition == "==") {
return val == this.value;
} else if(this.condition == "!=") {
return val != this.value;
} else if(this.condition == "()") {
return this.value(context, this.control, val);
} else {
throw new Error("Unknown condition:" + this.condition);
if(val === undefined) {
return false;
}

val = this.normalizeValue(control, this.value, val);

return this.evalCondition(context, this.control, this.condition, this.value, val);
},

/**
* Make sure that what we read from input field is comparable against Javascript primitives
*
*/
normalizeValue : function(control, baseValue, val) {

if(typeof baseValue == "number") {
// Make sure we compare numbers against numbers
return parseFloat(val);
}

return val;
},

/**
Expand All @@ -85,7 +166,9 @@
},

/**
* Create a sub-rule
* Create a sub-rule.
*
* @return Rule instance
*/
createRule : function(controller, condition, value) {
var rule = new Rule(controller, condition, value);
Expand Down Expand Up @@ -117,11 +200,16 @@
var result;

if(enforced === undefined) {
result = this.evalCondition(context);
result = this.checkCondition(context, cfg);
} else {
result = enforced;
}


if(cfg.log) {
log("Applying rule on " + this.controller + "==" + this.value + " enforced:" + enforced + " result:" + result);
}

// Get show/hide callback functions

var show = cfg.show || function(control) {
Expand Down

0 comments on commit 268c39b

Please sign in to comment.