Implement serverside and client side validatation

This commit is contained in:
YNH Webdev
2013-09-06 18:06:43 +02:00
parent 9f40c6355c
commit bbd48d24e4
19 changed files with 492 additions and 84 deletions

View File

@@ -0,0 +1,31 @@
note
description: "Summary description for {OWN_VALIDATOR}."
author: ""
date: "$Date$"
revision: "$Revision$"
class
OWN_VALIDATOR
inherit
WSF_VALIDATOR [STRING]
create
make_own
feature {NONE}
make_own
do
error := "Input to long"
end
feature
is_valid (input: STRING): BOOLEAN
do
Result := input.count < 5
end
end

View File

@@ -23,36 +23,49 @@ feature
initialize_controls
local
form: WSF_FORM_CONTROL
n1_container: WSF_FORM_ELEMENT_CONTROL [STRING]
n2_container: WSF_FORM_ELEMENT_CONTROL [STRING]
do
create textbox1.make_text ("txtBox1", "1")
create textbox2.make_text ("txtBox2", "2")
create textbox1.make_input ("txtBox1", "1")
create textbox2.make_input ("txtBox2", "2")
create button1.make_button ("sample_button1", "SUM")
create textbox_result.make_textarea ("txtBox3", "")
button1.set_click_event (agent handle_click)
button1.add_class ("col-lg-offset-2")
create form.make_form_control ("panel")
form.add_class ("form-horizontal")
create cklist.make_checkbox_list_control("categories")
cklist.add_control (create {WSF_CHECKBOX_CONTROL}.make_checkbox("net","Network","net"))
cklist.add_control (create {WSF_CHECKBOX_CONTROL}.make_checkbox("os","Operating Systems","os"))
form.add_control (create {WSF_FORM_ELEMENT_CONTROL[STRING]}.make_form_element("Number1",textbox1))
form.add_control (create {WSF_FORM_ELEMENT_CONTROL[STRING]}.make_form_element("Number2",textbox2))
form.add_control (create {WSF_FORM_ELEMENT_CONTROL[LIST[STRING]]}.make_form_element("Categories",cklist))
create cklist.make_checkbox_list_control ("categories")
cklist.add_control (create {WSF_CHECKBOX_CONTROL}.make_checkbox ("net", "Network", "net"))
cklist.add_control (create {WSF_CHECKBOX_CONTROL}.make_checkbox ("os", "Operating Systems", "os"))
create n1_container.make_form_element ("Number1", textbox1)
n1_container.add_validator (create {WSF_DECIMAL_VALIDATOR}.make_decimal_validator ("Invalid Number"))
n1_container.add_validator (create {OWN_VALIDATOR}.make_own)
create n2_container.make_form_element ("Number2", textbox2)
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))
form.add_control (button1)
form.add_control (create {WSF_FORM_ELEMENT_CONTROL[STRING]}.make_form_element("Result",textbox_result))
form.add_control (create {WSF_FORM_ELEMENT_CONTROL [STRING]}.make_form_element ("Result", textbox_result))
control := form
end
handle_click
local
text:STRING
text: STRING
do
text := textbox1.text + " + " + textbox2.text + " = " + (textbox1.text.to_integer_16 + textbox2.text.to_integer_16).out
across
cklist.value as s
loop
text.append ("%N-"+s.item)
if attached {WSF_FORM_CONTROL} control as form then
form.validate
if form.is_valid then
text := textbox1.text + " + " + textbox2.text + " = " + (textbox1.text.to_integer_64 + textbox2.text.to_integer_64).out
across
cklist.value as s
loop
text.append ("%N-" + s.item)
end
textbox_result.set_text (text)
end
end
textbox_result.set_text (text)
end
process
@@ -61,9 +74,9 @@ feature
button1: WSF_BUTTON_CONTROL
textbox1: WSF_TEXT_CONTROL
textbox1: WSF_INPUT_CONTROL
textbox2: WSF_TEXT_CONTROL
textbox2: WSF_INPUT_CONTROL
cklist: WSF_CHECKBOX_LIST_CONTROL

View File

@@ -10,17 +10,53 @@ trigger_callback = (control_name,event)->
for name,state of new_states
controls[name]?.update(state)
return
class WSF_VALIDATOR
constructor: (@parent_control, @settings)->
@error = @settings.error
return
validate: ()->
return true
class WSF_REGEXP_VALIDATOR extends WSF_VALIDATOR
constructor: ()->
super
@pattern = new RegExp(@settings.expression,'g')
validate: ()->
val = @parent_control.value()
res = val.match(@pattern)
return (res!=null)
validatormap =
"WSF_REGEXP_VALIDATOR":WSF_REGEXP_VALIDATOR
class WSF_CONTROL
constructor: (@control_name, @$el)->
@attach_events()
return
attach_events: ()->
return
update: (state)->
return
return
#Simple event listener
on: (name, callback, context)->
if not @_events?
@_events = {}
if not @_events[name]?
@_events[name] = []
@_events[name].push({callback:callback,context:context})
return @
trigger: (name)->
if not @_events?[name]?
return @
for ev in @_events[name]
ev.callback.call(ev.context)
return @
controls = {}
@@ -39,16 +75,21 @@ class WSF_BUTTON_CONTROL extends WSF_CONTROL
window.states[@control_name]['text'] = state.text
@$el.text(state.text)
class WSF_TEXT_CONTROL extends WSF_CONTROL
class WSF_INPUT_CONTROL extends WSF_CONTROL
attach_events: ()->
self = @
@$el.change ()->
self.change()
change: ()->
#update local state
window.states[@control_name]['text'] = @$el.val()
if window.states[@control_name]['callback_change']
trigger_callback(@control_name, 'change')
@trigger('change')
value:()->
return @$el.val()
update: (state) ->
if state.text?
@@ -65,6 +106,10 @@ class WSF_TEXTAREA_CONTROL extends WSF_CONTROL
window.states[@control_name]['text'] = @$el.val()
if window.states[@control_name]['callback_change']
trigger_callback(@control_name, 'change')
@trigger('change')
value:()->
return @$el.val()
update: (state) ->
if state.text?
@@ -76,23 +121,70 @@ class WSF_CHECKBOX_CONTROL extends WSF_CONTROL
self = @
@$el.change ()->
self.change()
change: ()->
#update local state
window.states[@control_name]['checked'] = @$el.is(':checked')
if window.states[@control_name]['callback_change']
trigger_callback(@control_name, 'change')
@trigger('change')
value:()->
return @$el.is(':checked')
update: (state) ->
if state.text?
window.states[@control_name]['checked'] = state.checked
@$el.prop('checked',state.checked)
class WSF_FORM_ELEMENT_CONTROL extends WSF_CONTROL
attach_events: ()->
self = @
@value_control = controls[window.states[@control_name]['value_control']]
if @value_control?
@value_control.on('change',@change,@)
@serverside_validator = false
@validators = []
for validator in window.states[@control_name]['validators']
if validatormap[validator.name]?
@validators.push new validatormap[validator.name](@,validator)
else
#Use serverside validator if no js implementation
@serverside_validator = true
return
change: ()->
for validator in @validators
if not validator.validate()
@showerror(validator.error)
return
@showerror("")
if @serverside_validator
trigger_callback(@control_name, 'validate')
return
showerror: (message)->
@$el.removeClass("has-error")
@$el.find(".validation").remove()
if message.length>0
@$el.addClass("has-error")
errordiv = $("<div />").addClass('help-block').addClass('validation').text(message)
@$el.find(".col-lg-10").append(errordiv)
update: (state) ->
if state.error?
@showerror(state.error)
value: ()->
@value_control.value()
#map class name to effective class
typemap =
"WSF_BUTTON_CONTROL":WSF_BUTTON_CONTROL
"WSF_TEXT_CONTROL":WSF_TEXT_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
#create a js class for each control
for name,state of window.states
@@ -103,4 +195,6 @@ for name,state of window.states
#create class
if type? and typemap[type]?
controls[name]=new typemap[type](name,$el)
for name,state of window.states
controls[name]?.attach_events()

View File

@@ -1,6 +1,6 @@
// Generated by CoffeeScript 1.6.1
(function() {
var $el, WSF_BUTTON_CONTROL, WSF_CHECKBOX_CONTROL, WSF_CONTROL, WSF_TEXTAREA_CONTROL, WSF_TEXT_CONTROL, controls, name, state, trigger_callback, type, typemap, _ref,
var $el, WSF_BUTTON_CONTROL, WSF_CHECKBOX_CONTROL, WSF_CONTROL, WSF_FORM_ELEMENT_CONTROL, WSF_INPUT_CONTROL, 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; };
@@ -23,12 +23,52 @@
});
};
WSF_VALIDATOR = (function() {
function WSF_VALIDATOR(parent_control, settings) {
this.parent_control = parent_control;
this.settings = settings;
this.error = this.settings.error;
return;
}
WSF_VALIDATOR.prototype.validate = function() {
return true;
};
return WSF_VALIDATOR;
})();
WSF_REGEXP_VALIDATOR = (function(_super) {
__extends(WSF_REGEXP_VALIDATOR, _super);
function WSF_REGEXP_VALIDATOR() {
WSF_REGEXP_VALIDATOR.__super__.constructor.apply(this, arguments);
this.pattern = new RegExp(this.settings.expression, 'g');
}
WSF_REGEXP_VALIDATOR.prototype.validate = function() {
var res, val;
val = this.parent_control.value();
res = val.match(this.pattern);
return res !== null;
};
return WSF_REGEXP_VALIDATOR;
})(WSF_VALIDATOR);
validatormap = {
"WSF_REGEXP_VALIDATOR": WSF_REGEXP_VALIDATOR
};
WSF_CONTROL = (function() {
function WSF_CONTROL(control_name, $el) {
this.control_name = control_name;
this.$el = $el;
this.attach_events();
return;
}
@@ -36,6 +76,33 @@
WSF_CONTROL.prototype.update = function(state) {};
WSF_CONTROL.prototype.on = function(name, callback, context) {
if (this._events == null) {
this._events = {};
}
if (this._events[name] == null) {
this._events[name] = [];
}
this._events[name].push({
callback: callback,
context: context
});
return this;
};
WSF_CONTROL.prototype.trigger = function(name) {
var ev, _i, _len, _ref, _ref1;
if (((_ref = this._events) != null ? _ref[name] : void 0) == null) {
return this;
}
_ref1 = this._events[name];
for (_i = 0, _len = _ref1.length; _i < _len; _i++) {
ev = _ref1[_i];
ev.callback.call(ev.context);
}
return this;
};
return WSF_CONTROL;
})();
@@ -76,15 +143,15 @@
})(WSF_CONTROL);
WSF_TEXT_CONTROL = (function(_super) {
WSF_INPUT_CONTROL = (function(_super) {
__extends(WSF_TEXT_CONTROL, _super);
__extends(WSF_INPUT_CONTROL, _super);
function WSF_TEXT_CONTROL() {
return WSF_TEXT_CONTROL.__super__.constructor.apply(this, arguments);
function WSF_INPUT_CONTROL() {
return WSF_INPUT_CONTROL.__super__.constructor.apply(this, arguments);
}
WSF_TEXT_CONTROL.prototype.attach_events = function() {
WSF_INPUT_CONTROL.prototype.attach_events = function() {
var self;
self = this;
return this.$el.change(function() {
@@ -92,21 +159,26 @@
});
};
WSF_TEXT_CONTROL.prototype.change = function() {
WSF_INPUT_CONTROL.prototype.change = function() {
window.states[this.control_name]['text'] = this.$el.val();
if (window.states[this.control_name]['callback_change']) {
return trigger_callback(this.control_name, 'change');
trigger_callback(this.control_name, 'change');
}
return this.trigger('change');
};
WSF_TEXT_CONTROL.prototype.update = function(state) {
WSF_INPUT_CONTROL.prototype.value = function() {
return this.$el.val();
};
WSF_INPUT_CONTROL.prototype.update = function(state) {
if (state.text != null) {
window.states[this.control_name]['text'] = state.text;
return this.$el.val(state.text);
}
};
return WSF_TEXT_CONTROL;
return WSF_INPUT_CONTROL;
})(WSF_CONTROL);
@@ -129,8 +201,13 @@
WSF_TEXTAREA_CONTROL.prototype.change = function() {
window.states[this.control_name]['text'] = this.$el.val();
if (window.states[this.control_name]['callback_change']) {
return trigger_callback(this.control_name, 'change');
trigger_callback(this.control_name, 'change');
}
return this.trigger('change');
};
WSF_TEXTAREA_CONTROL.prototype.value = function() {
return this.$el.val();
};
WSF_TEXTAREA_CONTROL.prototype.update = function(state) {
@@ -163,8 +240,13 @@
WSF_CHECKBOX_CONTROL.prototype.change = function() {
window.states[this.control_name]['checked'] = this.$el.is(':checked');
if (window.states[this.control_name]['callback_change']) {
return trigger_callback(this.control_name, 'change');
trigger_callback(this.control_name, 'change');
}
return this.trigger('change');
};
WSF_CHECKBOX_CONTROL.prototype.value = function() {
return this.$el.is(':checked');
};
WSF_CHECKBOX_CONTROL.prototype.update = function(state) {
@@ -178,11 +260,81 @@
})(WSF_CONTROL);
WSF_FORM_ELEMENT_CONTROL = (function(_super) {
__extends(WSF_FORM_ELEMENT_CONTROL, _super);
function WSF_FORM_ELEMENT_CONTROL() {
return WSF_FORM_ELEMENT_CONTROL.__super__.constructor.apply(this, arguments);
}
WSF_FORM_ELEMENT_CONTROL.prototype.attach_events = function() {
var self, validator, _i, _len, _ref;
self = this;
this.value_control = controls[window.states[this.control_name]['value_control']];
if (this.value_control != null) {
this.value_control.on('change', this.change, this);
}
this.serverside_validator = false;
this.validators = [];
_ref = window.states[this.control_name]['validators'];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
validator = _ref[_i];
if (validatormap[validator.name] != null) {
this.validators.push(new validatormap[validator.name](this, validator));
} else {
this.serverside_validator = true;
}
}
};
WSF_FORM_ELEMENT_CONTROL.prototype.change = function() {
var validator, _i, _len, _ref;
_ref = this.validators;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
validator = _ref[_i];
if (!validator.validate()) {
this.showerror(validator.error);
return;
}
}
this.showerror("");
if (this.serverside_validator) {
trigger_callback(this.control_name, 'validate');
}
};
WSF_FORM_ELEMENT_CONTROL.prototype.showerror = function(message) {
var errordiv;
this.$el.removeClass("has-error");
this.$el.find(".validation").remove();
if (message.length > 0) {
this.$el.addClass("has-error");
errordiv = $("<div />").addClass('help-block').addClass('validation').text(message);
return this.$el.find(".col-lg-10").append(errordiv);
}
};
WSF_FORM_ELEMENT_CONTROL.prototype.update = function(state) {
if (state.error != null) {
return this.showerror(state.error);
}
};
WSF_FORM_ELEMENT_CONTROL.prototype.value = function() {
return this.value_control.value();
};
return WSF_FORM_ELEMENT_CONTROL;
})(WSF_CONTROL);
typemap = {
"WSF_BUTTON_CONTROL": WSF_BUTTON_CONTROL,
"WSF_TEXT_CONTROL": WSF_TEXT_CONTROL,
"WSF_INPUT_CONTROL": WSF_INPUT_CONTROL,
"WSF_TEXTAREA_CONTROL": WSF_TEXTAREA_CONTROL,
"WSF_CHECKBOX_CONTROL": WSF_CHECKBOX_CONTROL
"WSF_CHECKBOX_CONTROL": WSF_CHECKBOX_CONTROL,
"WSF_FORM_ELEMENT_CONTROL": WSF_FORM_ELEMENT_CONTROL
};
_ref = window.states;
@@ -195,4 +347,12 @@
}
}
_ref1 = window.states;
for (name in _ref1) {
state = _ref1[name];
if ((_ref2 = controls[name]) != null) {
_ref2.attach_events();
}
}
}).call(this);