From 8f148f2a5e7ce7317328ce554e206d5dcf502bfd Mon Sep 17 00:00:00 2001 From: YNH Webdev Date: Sun, 26 Jan 2014 15:02:06 +0100 Subject: [PATCH] Add dynamic multicontrol --- .../kernel/webcontrol/wsf_control.e | 11 +- .../webcontrol/wsf_dynamic_multi_control.e | 121 ++++++++++++++++++ .../kernel/webcontrol/wsf_page_control.e | 2 +- .../webcontrol/wsf_stateless_multi_control.e | 9 +- examples/widgetapp/assets/widget.coffee | 20 ++- examples/widgetapp/assets/widget.js | 49 ++++++- .../wsf/src/request/value/wsf_uploaded_file.e | 2 +- 7 files changed, 196 insertions(+), 18 deletions(-) create mode 100644 draft/library/wsf_js_widget/kernel/webcontrol/wsf_dynamic_multi_control.e diff --git a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_control.e b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_control.e index 1b3d303b..b6808e35 100644 --- a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_control.e +++ b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_control.e @@ -96,9 +96,6 @@ feature {WSF_PAGE_CONTROL, WSF_CONTROL} -- State management read_state_changes (states: WSF_JSON_OBJECT) -- Add a new entry in the `states_changes` JSON object with the `control_name` as key and the `state` as value do - if state_changes.count > 0 then - states.put (state_changes, control_name) - end if actions.count > 0 then if not attached states.item ("actions") then states.put (create {JSON_ARRAY}.make_array, "actions") @@ -127,7 +124,7 @@ feature -- Rendering render_tag (body: STRING; attrs: detachable STRING): STRING -- Render this control with the specified body and attributes do - Result := render_tag_with_generator_name (generator, body, attrs) + Result := render_tag_with_generator_name (js_class, body, attrs) end render_tag_with_generator_name (a_generator, body: STRING; attrs: detachable STRING): STRING @@ -152,6 +149,11 @@ feature -- Rendering Result := render_tag_with_tagname (tag_name, body, l_attributes, css_classes_string) end + js_class: STRING + do + Result := generator + end + feature -- Event handling handle_callback (cname: LIST [STRING]; event: STRING; event_parameter: detachable ANY) @@ -186,7 +188,6 @@ feature -- Properties control_name_prefix: STRING assign set_control_name_prefix - set_control_name_prefix (p: STRING) do control_name_prefix := p diff --git a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_dynamic_multi_control.e b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_dynamic_multi_control.e new file mode 100644 index 00000000..5050d7f8 --- /dev/null +++ b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_dynamic_multi_control.e @@ -0,0 +1,121 @@ +note + description: "Summary description for {WSF_DYNAMIC_MULTI_CONTROL}." + author: "" + date: "$Date$" + revision: "$Revision$" + +deferred class + WSF_DYNAMIC_MULTI_CONTROL [G -> WSF_CONTROL] + +inherit + + WSF_MULTI_CONTROL [G] + rename + add_control as add_control_internal + redefine + make_with_tag_name, + set_state, + state, + read_state_changes, + js_class + end + +feature {NONE} -- Initialization + + make_with_tag_name (tag: STRING) + do + Precursor (tag) + create items.make_array + end + +feature {WSF_DYNAMIC_MULTI_CONTROL} -- Iternal functions + + add_control (c: G; id: INTEGER_32) + -- Add a control to this multi control + do + controls.extend (c) + if attached {WSF_CONTROL} c as d then + d.control_id := id + max_id := id.max (max_id) + end + items_changed := True + end + +feature {WSF_PAGE_CONTROL, WSF_CONTROL} -- State management + + set_state (new_state: JSON_OBJECT) + -- Before we process the callback. We restore the subcontrols + do + if attached {JSON_ARRAY} new_state.item ("items") as new_items then + items := new_items + create controls.make (items.count) + across + new_items.array_representation as n + loop + if attached {JSON_OBJECT} n.item as record and then attached {JSON_NUMBER} record.item ("id") as id and then attached {JSON_STRING} record.item ("tag") as tag then + if attached create_control_from_tag (tag.item) as control then + add_control (control, id.item.to_integer_32) + end + end + end + items_changed := False + end + end + + state: WSF_JSON_OBJECT + -- Return state which contains the current text and if there is an event handle attached + local + do + create Result.make + Result.put (items, "items") + end + +feature + + create_control_from_tag (tag: STRING): detachable G + deferred + end + + add_control_from_tag (tag: STRING) + local + item: WSF_JSON_OBJECT + do + if attached create_control_from_tag (tag) as control then + add_control (control, max_id + 1) + create item.make + item.put_integer (max_id, "id") + item.put_string (tag, "tag") + items.add (item) + end + end + + read_state_changes (states: WSF_JSON_OBJECT) + local + new_state: WSF_JSON_OBJECT + sub_state: WSF_JSON_OBJECT + do + Precursor (states) + if items_changed then + new_state := state + create sub_state.make + read_subcontrol_state (sub_state) + new_state.put (sub_state, "newstate") + new_state.put_string (render, "render") + states.put (new_state, control_name) + end + end + + js_class: STRING + do + Result := "WSF_DYNAMIC_MULTI_CONTROL" + end + +feature + + items: JSON_ARRAY + + items_changed: BOOLEAN + + max_id: INTEGER + +end diff --git a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_page_control.e b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_page_control.e index 4b49e234..d5621f21 100644 --- a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_page_control.e +++ b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_page_control.e @@ -83,7 +83,7 @@ feature -- Implementation set_state (sp) end end - event_parameter:=request.uploaded_files + event_parameter := request.uploaded_files end handle_callback (event_control_name.split ('-'), event, event_parameter) create states_changes.make diff --git a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_stateless_multi_control.e b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_stateless_multi_control.e index 18a192ce..11821cb3 100644 --- a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_stateless_multi_control.e +++ b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_stateless_multi_control.e @@ -10,8 +10,6 @@ class inherit WSF_MULTI_CONTROL [G] - rename - make_with_tag_name as make_with_tag_name_and_name redefine add_control, set_control_name_prefix, @@ -24,14 +22,9 @@ create feature {NONE} -- Initialization - make_with_tag_name (t: STRING) - do - make_with_tag_name_and_name (t) - end - make_tag_less do - make_with_tag_name_and_name ("") + make_with_tag_name ("") stateless := True end diff --git a/examples/widgetapp/assets/widget.coffee b/examples/widgetapp/assets/widget.coffee index fc29c516..a62f7d48 100644 --- a/examples/widgetapp/assets/widget.coffee +++ b/examples/widgetapp/assets/widget.coffee @@ -280,6 +280,8 @@ class WSF_CONTROL return @ remove:()-> + for control in @controls + control.remove() console.log "Removed #{@control_name}" @$el.remove() @@ -310,6 +312,8 @@ class WSF_PAGE_CONTROL extends WSF_CONTROL state remove:()-> + for control in @controls + control.remove() console.log "Removed #{@control_name}" @$el.remove() @@ -476,7 +480,7 @@ class WSF_FILE_CONTROL extends WSF_CONTROL return @progressbar?.remove() @$el.parent().find("p, img").remove() - if @state['file_id'] != null + if @state['file_id']? @$el.hide() fname = $("""

""").addClass("form-control-static").text(@state['file_name']) @$el.parent().append(fname) @@ -499,6 +503,20 @@ class WSF_FILE_CONTROL extends WSF_CONTROL @$el.val('') @change() +class WSF_DYNAMIC_MULTI_CONTROL extends WSF_CONTROL + + update: (state)-> + console.log state + if state.items? and state.render? and state.newstate? + @state['items'] = state.items + for control in @controls + control.remove() + @$el.html($(state.render).html()) + @fullstate.controls = state.newstate + @load_subcontrols() + for control in @controls + control.initialize() + return class WSF_PASSWORD_CONTROL extends WSF_INPUT_CONTROL diff --git a/examples/widgetapp/assets/widget.js b/examples/widgetapp/assets/widget.js index 632e58ff..359d0f76 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_DATE_PICKER_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, +var Mini, WSF_AUTOCOMPLETE_CONTROL, WSF_BUTTON_CONTROL, WSF_CHECKBOX_CONTROL, WSF_CHECKBOX_LIST_CONTROL, WSF_CODEVIEW_CONTROL, WSF_CONTROL, WSF_DATE_PICKER_CONTROL, WSF_DROPDOWN_CONTROL, WSF_DYNAMIC_MULTI_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; }; @@ -433,6 +433,12 @@ WSF_CONTROL = (function() { }; WSF_CONTROL.prototype.remove = function() { + var control, _i, _len, _ref; + _ref = this.controls; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + control = _ref[_i]; + control.remove(); + } console.log("Removed " + this.control_name); return this.$el.remove(); }; @@ -478,6 +484,12 @@ WSF_PAGE_CONTROL = (function(_super) { }; WSF_PAGE_CONTROL.prototype.remove = function() { + var control, _i, _len, _ref; + _ref = this.controls; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + control = _ref[_i]; + control.remove(); + } console.log("Removed " + this.control_name); return this.$el.remove(); }; @@ -747,7 +759,7 @@ WSF_FILE_CONTROL = (function(_super) { _ref.remove(); } this.$el.parent().find("p, img").remove(); - if (this.state['file_id'] !== null) { + if (this.state['file_id'] != null) { this.$el.hide(); fname = $("

").addClass("form-control-static").text(this.state['file_name']); this.$el.parent().append(fname); @@ -782,6 +794,39 @@ WSF_FILE_CONTROL = (function(_super) { })(WSF_CONTROL); +WSF_DYNAMIC_MULTI_CONTROL = (function(_super) { + + __extends(WSF_DYNAMIC_MULTI_CONTROL, _super); + + function WSF_DYNAMIC_MULTI_CONTROL() { + return WSF_DYNAMIC_MULTI_CONTROL.__super__.constructor.apply(this, arguments); + } + + WSF_DYNAMIC_MULTI_CONTROL.prototype.update = function(state) { + var control, _i, _j, _len, _len1, _ref, _ref1; + console.log(state); + if ((state.items != null) && (state.render != null) && (state.newstate != null)) { + this.state['items'] = state.items; + _ref = this.controls; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + control = _ref[_i]; + control.remove(); + } + this.$el.html($(state.render).html()); + this.fullstate.controls = state.newstate; + this.load_subcontrols(); + _ref1 = this.controls; + for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) { + control = _ref1[_j]; + control.initialize(); + } + } + }; + + return WSF_DYNAMIC_MULTI_CONTROL; + +})(WSF_CONTROL); + WSF_PASSWORD_CONTROL = (function(_super) { __extends(WSF_PASSWORD_CONTROL, _super); diff --git a/library/server/wsf/src/request/value/wsf_uploaded_file.e b/library/server/wsf/src/request/value/wsf_uploaded_file.e index b194f9b0..16de47aa 100644 --- a/library/server/wsf/src/request/value/wsf_uploaded_file.e +++ b/library/server/wsf/src/request/value/wsf_uploaded_file.e @@ -258,7 +258,7 @@ feature -- Basic operation if f.exists then f.rename_file (a_destination) Result := True - end + end end ensure removed: not exists