diff --git a/examples/widgetapp/sample_page.e b/examples/widgetapp/sample_page.e
index 91aa91de..d88c95a8 100644
--- a/examples/widgetapp/sample_page.e
+++ b/examples/widgetapp/sample_page.e
@@ -21,6 +21,7 @@ feature
form: WSF_FORM_CONTROL
n1_container: WSF_FORM_ELEMENT_CONTROL [STRING]
n2_container: WSF_FORM_ELEMENT_CONTROL [STRING]
+ cats_container: WSF_FORM_ELEMENT_CONTROL [LIST [STRING]]
do
create textbox1.make_input ("txtBox1", "1")
create textbox2.make_input ("txtBox2", "2")
@@ -40,8 +41,13 @@ feature
n2_container.add_validator (create {WSF_DECIMAL_VALIDATOR}.make_decimal_validator ("Invalid Number"))
form.add_control (n1_container)
form.add_control (n2_container)
- form.add_control (create {WSF_FORM_ELEMENT_CONTROL [LIST [STRING]]}.make_form_element ("Categories", cklist))
+ create cats_container.make_form_element ("Categories", cklist)
+ cats_container.add_validator (create {WSF_MIN_VALIDATOR[STRING]}.make_min_validator (1,"Choose at least one category"))
+ cats_container.add_validator (create {WSF_MAX_VALIDATOR[STRING]}.make_max_validator (1,"Choose at most one category"))
+
+ form.add_control (cats_container)
form.add_control (button1)
+
form.add_control (create {WSF_FORM_ELEMENT_CONTROL [STRING]}.make_form_element ("Result", textbox_result))
control := form
end
@@ -54,11 +60,13 @@ feature
form.validate
if form.is_valid then
text := textbox1.text + " + " + textbox2.text + " = " + (textbox1.text.to_integer_64 + textbox2.text.to_integer_64).out
+ text.append ("
")
across
cklist.value as s
loop
- text.append ("
-" + s.item)
+ text.append ("- " + s.item + "
")
end
+ text.append ("
")
textbox_result.set_html (text)
else
textbox_result.set_html ("VALIDATION ERROR")
diff --git a/examples/widgetapp/widget.coffee b/examples/widgetapp/widget.coffee
index 417c5eb9..58e81af6 100644
--- a/examples/widgetapp/widget.coffee
+++ b/examples/widgetapp/widget.coffee
@@ -28,8 +28,22 @@ class WSF_REGEXP_VALIDATOR extends WSF_VALIDATOR
res = val.match(@pattern)
return (res!=null)
+class WSF_MIN_VALIDATOR extends WSF_VALIDATOR
+
+ validate: ()->
+ val = @parent_control.value()
+ return (val.length>=@settings.min)
+
+class WSF_MAX_VALIDATOR extends WSF_VALIDATOR
+
+ validate: ()->
+ val = @parent_control.value()
+ return (val.length<=@settings.max)
+
validatormap =
"WSF_REGEXP_VALIDATOR":WSF_REGEXP_VALIDATOR
+ "WSF_MIN_VALIDATOR":WSF_MIN_VALIDATOR
+ "WSF_MAX_VALIDATOR":WSF_MAX_VALIDATOR
class WSF_CONTROL
constructor: (@control_name, @$el)->
@@ -142,6 +156,7 @@ class WSF_TEXTAREA_CONTROL extends WSF_CONTROL
class WSF_CHECKBOX_CONTROL extends WSF_CONTROL
attach_events: ()->
self = @
+ @checked_value = window.states[@control_name]['checked_value']
@$el.change ()->
self.change()
@@ -215,6 +230,28 @@ class WSF_HTML_CONTROL extends WSF_CONTROL
window.states[@control_name]['html'] = state.html
@$el.html(state.html)
+class WSF_CHECKBOX_LIST_CONTROL extends WSF_CONTROL
+
+ attach_events: ()->
+ self = @
+ @subcontrols = []
+ #Listen to events of subelements and forward them
+ for name,control of controls
+ if @$el.has(control.$el).length > 0
+ @subcontrols.push(control)
+ control.on('change',@change,@)
+ return
+
+ change:()->
+ @trigger("change")
+
+ value:()->
+ result = []
+ for subc in @subcontrols
+ if subc.value()
+ result.push(subc.checked_value)
+ return result
+
#map class name to effective class
typemap =
"WSF_BUTTON_CONTROL":WSF_BUTTON_CONTROL
@@ -223,6 +260,7 @@ typemap =
"WSF_CHECKBOX_CONTROL":WSF_CHECKBOX_CONTROL
"WSF_FORM_ELEMENT_CONTROL": WSF_FORM_ELEMENT_CONTROL
"WSF_HTML_CONTROL": WSF_HTML_CONTROL
+ "WSF_CHECKBOX_LIST_CONTROL": WSF_CHECKBOX_LIST_CONTROL
#create a js class for each control
for name,state of window.states
diff --git a/examples/widgetapp/widget.js b/examples/widgetapp/widget.js
index cab1a948..1df3d11b 100644
--- a/examples/widgetapp/widget.js
+++ b/examples/widgetapp/widget.js
@@ -1,6 +1,6 @@
// Generated by CoffeeScript 1.6.1
(function() {
- var $el, WSF_BUTTON_CONTROL, WSF_CHECKBOX_CONTROL, WSF_CONTROL, WSF_FORM_ELEMENT_CONTROL, WSF_HTML_CONTROL, WSF_INPUT_CONTROL, WSF_REGEXP_VALIDATOR, WSF_TEXTAREA_CONTROL, WSF_VALIDATOR, controls, name, state, trigger_callback, type, typemap, validatormap, _ref, _ref1, _ref2,
+ var $el, WSF_BUTTON_CONTROL, WSF_CHECKBOX_CONTROL, WSF_CHECKBOX_LIST_CONTROL, WSF_CONTROL, WSF_FORM_ELEMENT_CONTROL, WSF_HTML_CONTROL, WSF_INPUT_CONTROL, WSF_MAX_VALIDATOR, WSF_MIN_VALIDATOR, WSF_REGEXP_VALIDATOR, WSF_TEXTAREA_CONTROL, WSF_VALIDATOR, controls, name, state, trigger_callback, type, typemap, validatormap, _ref, _ref1, _ref2,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
@@ -60,8 +60,46 @@
})(WSF_VALIDATOR);
+ WSF_MIN_VALIDATOR = (function(_super) {
+
+ __extends(WSF_MIN_VALIDATOR, _super);
+
+ function WSF_MIN_VALIDATOR() {
+ return WSF_MIN_VALIDATOR.__super__.constructor.apply(this, arguments);
+ }
+
+ WSF_MIN_VALIDATOR.prototype.validate = function() {
+ var val;
+ val = this.parent_control.value();
+ return val.length >= this.settings.min;
+ };
+
+ return WSF_MIN_VALIDATOR;
+
+ })(WSF_VALIDATOR);
+
+ WSF_MAX_VALIDATOR = (function(_super) {
+
+ __extends(WSF_MAX_VALIDATOR, _super);
+
+ function WSF_MAX_VALIDATOR() {
+ return WSF_MAX_VALIDATOR.__super__.constructor.apply(this, arguments);
+ }
+
+ WSF_MAX_VALIDATOR.prototype.validate = function() {
+ var val;
+ val = this.parent_control.value();
+ return val.length <= this.settings.max;
+ };
+
+ return WSF_MAX_VALIDATOR;
+
+ })(WSF_VALIDATOR);
+
validatormap = {
- "WSF_REGEXP_VALIDATOR": WSF_REGEXP_VALIDATOR
+ "WSF_REGEXP_VALIDATOR": WSF_REGEXP_VALIDATOR,
+ "WSF_MIN_VALIDATOR": WSF_MIN_VALIDATOR,
+ "WSF_MAX_VALIDATOR": WSF_MAX_VALIDATOR
};
WSF_CONTROL = (function() {
@@ -271,6 +309,7 @@
WSF_CHECKBOX_CONTROL.prototype.attach_events = function() {
var self;
self = this;
+ this.checked_value = window.states[this.control_name]['checked_value'];
return this.$el.change(function() {
return self.change();
});
@@ -391,13 +430,56 @@
})(WSF_CONTROL);
+ WSF_CHECKBOX_LIST_CONTROL = (function(_super) {
+
+ __extends(WSF_CHECKBOX_LIST_CONTROL, _super);
+
+ function WSF_CHECKBOX_LIST_CONTROL() {
+ return WSF_CHECKBOX_LIST_CONTROL.__super__.constructor.apply(this, arguments);
+ }
+
+ WSF_CHECKBOX_LIST_CONTROL.prototype.attach_events = function() {
+ var control, name, self;
+ self = this;
+ this.subcontrols = [];
+ for (name in controls) {
+ control = controls[name];
+ if (this.$el.has(control.$el).length > 0) {
+ this.subcontrols.push(control);
+ control.on('change', this.change, this);
+ }
+ }
+ };
+
+ WSF_CHECKBOX_LIST_CONTROL.prototype.change = function() {
+ return this.trigger("change");
+ };
+
+ WSF_CHECKBOX_LIST_CONTROL.prototype.value = function() {
+ var result, subc, _i, _len, _ref;
+ result = [];
+ _ref = this.subcontrols;
+ for (_i = 0, _len = _ref.length; _i < _len; _i++) {
+ subc = _ref[_i];
+ if (subc.value()) {
+ result.push(subc.checked_value);
+ }
+ }
+ return result;
+ };
+
+ return WSF_CHECKBOX_LIST_CONTROL;
+
+ })(WSF_CONTROL);
+
typemap = {
"WSF_BUTTON_CONTROL": WSF_BUTTON_CONTROL,
"WSF_INPUT_CONTROL": WSF_INPUT_CONTROL,
"WSF_TEXTAREA_CONTROL": WSF_TEXTAREA_CONTROL,
"WSF_CHECKBOX_CONTROL": WSF_CHECKBOX_CONTROL,
"WSF_FORM_ELEMENT_CONTROL": WSF_FORM_ELEMENT_CONTROL,
- "WSF_HTML_CONTROL": WSF_HTML_CONTROL
+ "WSF_HTML_CONTROL": WSF_HTML_CONTROL,
+ "WSF_CHECKBOX_LIST_CONTROL": WSF_CHECKBOX_LIST_CONTROL
};
_ref = window.states;
diff --git a/library/server/wsf_html/webcontrol/validators/wsf_max_validator.e b/library/server/wsf_html/webcontrol/validators/wsf_max_validator.e
new file mode 100644
index 00000000..a46c2eec
--- /dev/null
+++ b/library/server/wsf_html/webcontrol/validators/wsf_max_validator.e
@@ -0,0 +1,45 @@
+note
+ description: "Summary description for {WSF_MAX_VALIDATOR}."
+ author: ""
+ date: "$Date$"
+ revision: "$Revision$"
+
+class
+ WSF_max_VALIDATOR[G]
+
+inherit
+ WSF_VALIDATOR [LIST[G]]
+ redefine
+ state
+ end
+
+create
+ make_max_validator
+
+feature {NONE}
+
+ make_max_validator (m:INTEGER; e: STRING)
+ do
+ make (e)
+ max := m
+ end
+
+feature -- Implementation
+
+ is_valid (input:LIST[G]): BOOLEAN
+ do
+ Result:= input.count < max or input.count = max
+
+ end
+
+feature
+
+ state: JSON_OBJECT
+ do
+ Result := Precursor
+ Result.put (create {JSON_NUMBER}.make_integer (max), create {JSON_STRING}.make_json ("max"))
+ end
+
+ max: INTEGER
+
+end
diff --git a/library/server/wsf_html/webcontrol/validators/wsf_min_validator.e b/library/server/wsf_html/webcontrol/validators/wsf_min_validator.e
new file mode 100644
index 00000000..6e225aa1
--- /dev/null
+++ b/library/server/wsf_html/webcontrol/validators/wsf_min_validator.e
@@ -0,0 +1,45 @@
+note
+ description: "Summary description for {WSF_MIN_VALIDATOR}."
+ author: ""
+ date: "$Date$"
+ revision: "$Revision$"
+
+class
+ WSF_MIN_VALIDATOR[G]
+
+inherit
+ WSF_VALIDATOR [LIST[G]]
+ redefine
+ state
+ end
+
+create
+ make_min_validator
+
+feature {NONE}
+
+ make_min_validator (m:INTEGER; e: STRING)
+ do
+ make (e)
+ min := m
+ end
+
+feature -- Implementation
+
+ is_valid (input:LIST[G]): BOOLEAN
+ do
+ Result:= input.count > min or input.count = min
+
+ end
+
+feature
+
+ state: JSON_OBJECT
+ do
+ Result := Precursor
+ Result.put (create {JSON_NUMBER}.make_integer (min), create {JSON_STRING}.make_json ("min"))
+ end
+
+ min: INTEGER
+
+end
diff --git a/library/server/wsf_html/webcontrol/wsf_checkbox_control.e b/library/server/wsf_html/webcontrol/wsf_checkbox_control.e
index 42233d74..cf8957c9 100644
--- a/library/server/wsf_html/webcontrol/wsf_checkbox_control.e
+++ b/library/server/wsf_html/webcontrol/wsf_checkbox_control.e
@@ -38,6 +38,7 @@ feature {WSF_PAGE_CONTROL, WSF_CONTROL} -- STATE MANAGEMENT
do
create Result.make
Result.put (create {JSON_BOOLEAN}.make_boolean (checked), create {JSON_STRING}.make_json ("checked"))
+ Result.put (create {JSON_STRING}.make_json (checked_value), create {JSON_STRING}.make_json ("checked_value"))
Result.put (create {JSON_BOOLEAN}.make_boolean (attached change_event), create {JSON_STRING}.make_json ("callback_change"))
end