From 1ae44e74e79864b6780a9d94cfa2b5ac1cf62709 Mon Sep 17 00:00:00 2001 From: YNH Webdev Date: Tue, 31 Dec 2013 16:03:24 +0100 Subject: [PATCH] File upload implementation part1 --- .../kernel/input/wsf_file_control.e | 81 +++++++++++++++++++ .../kernel/input/wsf_pending_file.e | 30 +++++++ .../kernel/validator/wsf_filesize_validator.e | 54 +++++++++++++ .../webcontrol/wsf_form_element_control.e | 7 +- examples/widgetapp/assets/widget.coffee | 29 +++++++ examples/widgetapp/assets/widget.js | 51 +++++++++++- examples/widgetapp/sample_page.e | 8 ++ 7 files changed, 256 insertions(+), 4 deletions(-) create mode 100644 draft/library/wsf_js_widget/kernel/input/wsf_file_control.e create mode 100644 draft/library/wsf_js_widget/kernel/input/wsf_pending_file.e create mode 100644 draft/library/wsf_js_widget/kernel/validator/wsf_filesize_validator.e diff --git a/draft/library/wsf_js_widget/kernel/input/wsf_file_control.e b/draft/library/wsf_js_widget/kernel/input/wsf_file_control.e new file mode 100644 index 00000000..4d2449c4 --- /dev/null +++ b/draft/library/wsf_js_widget/kernel/input/wsf_file_control.e @@ -0,0 +1,81 @@ +note + description: "Summary description for {WSF_FILE_CONTROL}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + WSF_FILE_CONTROL + +inherit + + WSF_VALUE_CONTROL [detachable WSF_PENDING_FILE] + rename + make as make_value_control + end + +create + make + +feature {NONE} -- Initialization + + make + do + make_value_control ("input") + end + +feature {WSF_PAGE_CONTROL, WSF_CONTROL} -- State management + + set_state (new_state: JSON_OBJECT) + -- Restore text from json + do + if attached {JSON_STRING} new_state.item ("file") as new_name and attached {JSON_STRING} new_state.item ("type") as new_type and attached {JSON_NUMBER} new_state.item ("size") as new_size then + create file.make (new_name.unescaped_string_32, new_type.unescaped_string_32, new_size.item.to_integer_32); + end + end + + state: WSF_JSON_OBJECT + -- Return state which contains the current text and if there is an event handle attached + do + create Result.make + Result.put_boolean (attached change_event, "callback_change") + end + +feature --Event handling + + set_change_event (e: attached like change_event) + -- Set text change event handle + do + change_event := e + end + + handle_callback (cname: LIST [STRING]; event: STRING; event_parameter: detachable STRING) + do + if Current.control_name.same_string (cname [1]) and attached change_event as cevent then + if event.same_string ("change") then + cevent.call (Void) + end + end + end + +feature -- Implementation + + value: detachable WSF_PENDING_FILE + do + Result := file + end + + render: STRING + do + Result := render_tag ("", "type=%"file%" ") + end + +feature -- Properties + + file: detachable WSF_PENDING_FILE + -- Text to be displayed + + change_event: detachable PROCEDURE [ANY, TUPLE] + -- Procedure to be execued on change + +end diff --git a/draft/library/wsf_js_widget/kernel/input/wsf_pending_file.e b/draft/library/wsf_js_widget/kernel/input/wsf_pending_file.e new file mode 100644 index 00000000..759d39f3 --- /dev/null +++ b/draft/library/wsf_js_widget/kernel/input/wsf_pending_file.e @@ -0,0 +1,30 @@ +note + description: "Summary description for {WSF_PENDING_FILE}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + WSF_PENDING_FILE + +create + make + +feature {NONE} + + make (a_name, a_type: STRING; a_size: INTEGER) + do + name := a_name + type := a_type + size := a_size + end + +feature --Properties + + name: STRING + + type: STRING + + size: INTEGER + +end diff --git a/draft/library/wsf_js_widget/kernel/validator/wsf_filesize_validator.e b/draft/library/wsf_js_widget/kernel/validator/wsf_filesize_validator.e new file mode 100644 index 00000000..517decdf --- /dev/null +++ b/draft/library/wsf_js_widget/kernel/validator/wsf_filesize_validator.e @@ -0,0 +1,54 @@ +note + description: "Summary description for {WSF_FILESIZE_VALIDATOR}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + WSF_FILESIZE_VALIDATOR + +inherit + + WSF_VALIDATOR [detachable WSF_PENDING_FILE] + rename + make as make_validator + redefine + state + end + +create + make + +feature {NONE} -- Initialization + + make (m: INTEGER; e: STRING) + -- Initialize with specified maximum filesize and error message which will be displayed on validation failure + do + make_validator (e) + max := m + end + +feature -- Implementation + + is_valid (input: detachable WSF_PENDING_FILE): BOOLEAN + do + Result := True + if attached input as a_input then + Result := a_input.size < max or a_input.size = max + end + end + +feature -- State + + state: WSF_JSON_OBJECT + do + Result := Precursor + Result.put_integer (max, "max") + end + +feature -- Properties + + max: INTEGER + -- The maximal allowed value + +end diff --git a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_form_element_control.e b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_form_element_control.e index e4b860b6..acd49e18 100644 --- a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_form_element_control.e +++ b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_form_element_control.e @@ -36,12 +36,13 @@ feature {NONE} -- Initialization do make_control ("div") add_class ("form-group") - if attached {WSF_INPUT_CONTROL} c or attached {WSF_TEXTAREA_CONTROL} c then - c.add_class ("form-control") - end if attached {WSF_HTML_CONTROL} c then c.add_class ("form-control-static") + elseif not attached {WSF_VALUE_CONTROL [LIST[ANY]]} c then + + c.add_class ("form-control") end + label_width := 2 value_control := c validators := v label := a_label diff --git a/examples/widgetapp/assets/widget.coffee b/examples/widgetapp/assets/widget.coffee index aed793aa..2bbb9686 100644 --- a/examples/widgetapp/assets/widget.coffee +++ b/examples/widgetapp/assets/widget.coffee @@ -360,6 +360,35 @@ class WSF_INPUT_CONTROL extends WSF_CONTROL @state['text'] = state.text @$el.val(state.text) +class WSF_FILE_CONTROL extends WSF_CONTROL + attach_events: ()-> + super + self = @ + @$el.change ()-> + self.change() + + change: ()-> + #update local state + @state['file'] = null + @state['type'] = null + @state['size'] = null + if @$el[0].files.length>0 + file = @$el[0].files[0] + @state['file'] = file.name + @state['type'] = file.type + @state['size'] = file.size + if @state['callback_change'] + @trigger_callback(@control_name, 'change') + @trigger('change') + + value:()-> + return @$el.val() + + update: (state) -> + if state.text? + @state['text'] = state.text + @$el.val(state.text) + class WSF_PASSWORD_CONTROL extends WSF_INPUT_CONTROL class WSF_NAVLIST_ITEM_CONTROL extends WSF_BUTTON_CONTROL diff --git a/examples/widgetapp/assets/widget.js b/examples/widgetapp/assets/widget.js index a4215d29..03cbe912 100644 --- a/examples/widgetapp/assets/widget.js +++ b/examples/widgetapp/assets/widget.js @@ -1,5 +1,5 @@ // Generated by CoffeeScript 1.6.1 -var Mini, WSF_AUTOCOMPLETE_CONTROL, WSF_BUTTON_CONTROL, WSF_CHECKBOX_CONTROL, WSF_CHECKBOX_LIST_CONTROL, WSF_CODEVIEW_CONTROL, WSF_CONTROL, WSF_DROPDOWN_CONTROL, WSF_FORM_ELEMENT_CONTROL, WSF_GRID_CONTROL, WSF_HTML_CONTROL, WSF_INPUT_CONTROL, WSF_MAX_VALIDATOR, WSF_MIN_VALIDATOR, WSF_NAVLIST_ITEM_CONTROL, WSF_PAGE_CONTROL, WSF_PAGINATION_CONTROL, WSF_PASSWORD_CONTROL, WSF_PROGRESS_CONTROL, WSF_REGEXP_VALIDATOR, WSF_REPEATER_CONTROL, WSF_SLIDER_CONTROL, WSF_TEXTAREA_CONTROL, WSF_VALIDATOR, build_control, cache, controls, lazy_load, loaded, parseSuggestions, redirect, show_alert, start_modal, start_modal_big, template, tmpl, +var Mini, WSF_AUTOCOMPLETE_CONTROL, WSF_BUTTON_CONTROL, WSF_CHECKBOX_CONTROL, WSF_CHECKBOX_LIST_CONTROL, WSF_CODEVIEW_CONTROL, WSF_CONTROL, WSF_DROPDOWN_CONTROL, WSF_FILE_CONTROL, WSF_FORM_ELEMENT_CONTROL, WSF_GRID_CONTROL, WSF_HTML_CONTROL, WSF_INPUT_CONTROL, WSF_MAX_VALIDATOR, WSF_MIN_VALIDATOR, WSF_NAVLIST_ITEM_CONTROL, WSF_PAGE_CONTROL, WSF_PAGINATION_CONTROL, WSF_PASSWORD_CONTROL, WSF_PROGRESS_CONTROL, WSF_REGEXP_VALIDATOR, WSF_REPEATER_CONTROL, WSF_SLIDER_CONTROL, WSF_TEXTAREA_CONTROL, WSF_VALIDATOR, build_control, cache, controls, lazy_load, loaded, parseSuggestions, redirect, show_alert, start_modal, start_modal_big, template, tmpl, __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; }; @@ -596,6 +596,55 @@ WSF_INPUT_CONTROL = (function(_super) { })(WSF_CONTROL); +WSF_FILE_CONTROL = (function(_super) { + + __extends(WSF_FILE_CONTROL, _super); + + function WSF_FILE_CONTROL() { + return WSF_FILE_CONTROL.__super__.constructor.apply(this, arguments); + } + + WSF_FILE_CONTROL.prototype.attach_events = function() { + var self; + WSF_FILE_CONTROL.__super__.attach_events.apply(this, arguments); + self = this; + return this.$el.change(function() { + return self.change(); + }); + }; + + WSF_FILE_CONTROL.prototype.change = function() { + var file; + this.state['file'] = null; + this.state['type'] = null; + this.state['size'] = null; + if (this.$el[0].files.length > 0) { + file = this.$el[0].files[0]; + this.state['file'] = file.name; + this.state['type'] = file.type; + this.state['size'] = file.size; + } + if (this.state['callback_change']) { + this.trigger_callback(this.control_name, 'change'); + } + return this.trigger('change'); + }; + + WSF_FILE_CONTROL.prototype.value = function() { + return this.$el.val(); + }; + + WSF_FILE_CONTROL.prototype.update = function(state) { + if (state.text != null) { + this.state['text'] = state.text; + return this.$el.val(state.text); + } + }; + + return WSF_FILE_CONTROL; + +})(WSF_CONTROL); + WSF_PASSWORD_CONTROL = (function(_super) { __extends(WSF_PASSWORD_CONTROL, _super); diff --git a/examples/widgetapp/sample_page.e b/examples/widgetapp/sample_page.e index 9015dc24..688995cb 100644 --- a/examples/widgetapp/sample_page.e +++ b/examples/widgetapp/sample_page.e @@ -21,6 +21,7 @@ feature initialize_controls local + n0_container: WSF_FORM_ELEMENT_CONTROL [detachable WSF_PENDING_FILE] n1_container: WSF_FORM_ELEMENT_CONTROL [STRING] n2_container: WSF_FORM_ELEMENT_CONTROL [STRING] n3_container: WSF_FORM_ELEMENT_CONTROL [STRING] @@ -32,6 +33,11 @@ feature Precursor create form.make form.add_class ("form-horizontal") + --File + create filebox.make + create n0_container.make ("File Upload", filebox) + n0_container.add_validator (create {WSF_FILESIZE_VALIDATOR}.make (100000,"File must be smaller than 100KB")) + form.add_control (n0_container) --Number 1 create textbox1.make ("1") create n1_container.make ("Number1", textbox1) @@ -122,6 +128,8 @@ feature button2: WSF_BUTTON_CONTROL + filebox: WSF_FILE_CONTROL + textbox1: WSF_INPUT_CONTROL textbox2: WSF_INPUT_CONTROL