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 ("") 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