From c9102af0aadf1b02e69ec48587033e2440e9635d Mon Sep 17 00:00:00 2001 From: YNH Webdev Date: Wed, 6 Nov 2013 15:44:31 +0100 Subject: [PATCH 01/18] Add stateless widgets --- .../kernel/dropdown/wsf_dropdown_control.e | 14 +++---- .../kernel/navbar/wsf_navbar_control.e | 8 ++-- .../kernel/slider/wsf_image_slider_control.e | 8 ++-- .../kernel/webcontrol/wsf_form_control.e | 2 +- .../kernel/webcontrol/wsf_layout_control.e | 4 +- .../kernel/webcontrol/wsf_multi_control.e | 38 ++++++++++++++----- .../webcontrol/wsf_stateless_multi_control.e | 31 +++++++++++++++ examples/widgetapp/base_page.e | 2 +- 8 files changed, 78 insertions(+), 29 deletions(-) create mode 100644 draft/library/wsf_js_widget/kernel/webcontrol/wsf_stateless_multi_control.e diff --git a/draft/library/wsf_js_widget/kernel/dropdown/wsf_dropdown_control.e b/draft/library/wsf_js_widget/kernel/dropdown/wsf_dropdown_control.e index 1b8a26e7..a12b7916 100644 --- a/draft/library/wsf_js_widget/kernel/dropdown/wsf_dropdown_control.e +++ b/draft/library/wsf_js_widget/kernel/dropdown/wsf_dropdown_control.e @@ -9,7 +9,7 @@ class inherit - WSF_MULTI_CONTROL [WSF_STATELESS_CONTROL] + WSF_STATELESS_MULTI_CONTROL [WSF_STATELESS_CONTROL] rename make as make_multi_control, make_with_tag_name as make_multi_control_with_tag_name @@ -20,19 +20,19 @@ create feature {NONE} -- Initialization - make (n, title: STRING) + make ( title: STRING) -- Make a dropdown control with div tag name and specified menu title do - make_with_tag_name (n, title, "div") + make_with_tag_name ( title, "div") end - make_with_tag_name (n, title, t: STRING) + make_with_tag_name ( title, t: STRING) -- Make a dropdown control with specified tag name and menu title (such as li) do - make_multi_control_with_tag_name (n, t) + make_multi_control_with_tag_name ( t) add_class ("dropdown") create {WSF_BASIC_CONTROL} dropdown_toggle.make_with_body_class ("a", "data-toggle=%"dropdown%" href=%"#%"", "dropdown-toggle", title + " ") - create dropdown_menu.make_with_tag_name (n + "_menu", "ul") + create dropdown_menu.make_with_tag_name ( "ul") dropdown_menu.add_class ("dropdown-menu") add_control (dropdown_toggle) add_control (dropdown_menu) @@ -66,6 +66,6 @@ feature -- Properties dropdown_toggle: WSF_STATELESS_CONTROL - dropdown_menu: WSF_MULTI_CONTROL [WSF_STATELESS_CONTROL] + dropdown_menu: WSF_STATELESS_MULTI_CONTROL [WSF_STATELESS_CONTROL] end diff --git a/draft/library/wsf_js_widget/kernel/navbar/wsf_navbar_control.e b/draft/library/wsf_js_widget/kernel/navbar/wsf_navbar_control.e index 06a70be2..302a00b4 100644 --- a/draft/library/wsf_js_widget/kernel/navbar/wsf_navbar_control.e +++ b/draft/library/wsf_js_widget/kernel/navbar/wsf_navbar_control.e @@ -27,8 +27,8 @@ feature {NONE} -- Initialization make_multi_control (n) active_set := false add_class ("navbar navbar-inverse navbar-fixed-top") - create nav.make_with_tag_name (control_name + "_nav", "ul") - create nav_right.make_with_tag_name (control_name + "_nav_right", "ul") + create nav.make_with_tag_name ("ul") + create nav_right.make_with_tag_name ( "ul") controls.extend (nav) controls.extend (nav_right) nav.add_class ("nav navbar-nav") @@ -155,10 +155,10 @@ feature -- Properties brand: detachable STRING -- Optional brand of the navbar - nav: WSF_MULTI_CONTROL [WSF_STATELESS_CONTROL] + nav: WSF_STATELESS_MULTI_CONTROL [WSF_STATELESS_CONTROL] -- Middle nav - nav_right: WSF_MULTI_CONTROL [WSF_STATELESS_CONTROL] + nav_right: WSF_STATELESS_MULTI_CONTROL [WSF_STATELESS_CONTROL] -- Right nav end diff --git a/draft/library/wsf_js_widget/kernel/slider/wsf_image_slider_control.e b/draft/library/wsf_js_widget/kernel/slider/wsf_image_slider_control.e index c34f35d5..0a9f3bbe 100644 --- a/draft/library/wsf_js_widget/kernel/slider/wsf_image_slider_control.e +++ b/draft/library/wsf_js_widget/kernel/slider/wsf_image_slider_control.e @@ -24,9 +24,9 @@ feature {NONE} -- Initialization do make_control (n, "div") add_class ("carousel slide") - create list.make_with_tag_name (control_name + "_links", "ol") + create list.make_with_tag_name ( "ol") list.add_class ("carousel-indicators") - create slide_wrapper.make (control_name + "_wrapper") + create slide_wrapper.make_with_tag_name ("div") slide_wrapper.add_class ("carousel-inner") end @@ -108,10 +108,10 @@ feature -- Change feature -- Properties - list: WSF_MULTI_CONTROL [WSF_STATELESS_CONTROL] + list: WSF_STATELESS_MULTI_CONTROL [WSF_STATELESS_CONTROL] -- List of slider links - slide_wrapper: WSF_MULTI_CONTROL [WSF_STATELESS_CONTROL] + slide_wrapper: WSF_STATELESS_MULTI_CONTROL [WSF_STATELESS_CONTROL] -- List of the single slides end diff --git a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_form_control.e b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_form_control.e index 14c094fb..3bb3c46d 100644 --- a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_form_control.e +++ b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_form_control.e @@ -9,7 +9,7 @@ class inherit - WSF_MULTI_CONTROL [WSF_CONTROL] + WSF_STATELESS_MULTI_CONTROL [WSF_CONTROL] rename make as make_multi_control end diff --git a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_layout_control.e b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_layout_control.e index d42708b0..4f7fb08d 100644 --- a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_layout_control.e +++ b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_layout_control.e @@ -9,7 +9,7 @@ class inherit - WSF_MULTI_CONTROL [WSF_STATELESS_CONTROL] + WSF_STATELESS_MULTI_CONTROL [WSF_STATELESS_CONTROL] rename make as make_multi_control, add_control as add_control_raw @@ -22,7 +22,7 @@ feature {NONE} -- Initialization make (n: STRING) do - make_with_tag_name (n, "div") + make_with_tag_name ("div") add_class ("row") end diff --git a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_multi_control.e b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_multi_control.e index 719ed911..fc6fdfaa 100644 --- a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_multi_control.e +++ b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_multi_control.e @@ -43,13 +43,20 @@ feature {WSF_PAGE_CONTROL, WSF_CONTROL} -- State management do Precursor (new_states) if attached {JSON_OBJECT} new_states.item ("controls") as ct then - across - controls as c - loop - if attached {WSF_CONTROL} c.item as cont then - if attached {JSON_OBJECT} ct.item (cont.control_name) as value_state then - cont.load_state (value_state) - end + load_subcontrol_state (ct) + end + end + + load_subcontrol_state (newstate: JSON_OBJECT) + do + across + controls as c + loop + if attached {WSF_STATELESS_MULTI_CONTROL[WSF_STATELESS_CONTROL]} c.item as cont then + cont.load_subcontrol_state (newstate) + elseif attached {WSF_CONTROL} c.item as cont then + if attached {JSON_OBJECT} newstate.item (cont.control_name) as value_state then + cont.load_state (value_state) end end end @@ -67,14 +74,21 @@ feature {WSF_PAGE_CONTROL, WSF_CONTROL} -- State management do Result := Precursor create controls_state.make + read_subcontrol_state (controls_state) + Result.put (controls_state, "controls") + end + + read_subcontrol_state (controls_state: JSON_OBJECT) + do across controls as c loop - if attached {WSF_CONTROL} c.item as cont then + if attached {WSF_STATELESS_MULTI_CONTROL[WSF_STATELESS_CONTROL]} c.item as mcont then + mcont.read_subcontrol_state (controls_state) + elseif attached {WSF_CONTROL} c.item as cont then controls_state.put (cont.full_state, cont.control_name) end end - Result.put (controls_state, "controls") end read_state_changes (states: WSF_JSON_OBJECT) @@ -124,7 +138,9 @@ feature -- Rendering loop Result := Result + c.item.render end - Result := render_tag (Result, "") + if not tag_name.is_empty then + Result := render_tag (Result, "") + end end feature -- Change @@ -137,6 +153,8 @@ feature -- Change feature -- Properties + stateless: BOOLEAN + controls: ARRAYED_LIST [G] -- List of current controls in this multi control 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 new file mode 100644 index 00000000..3425abb7 --- /dev/null +++ b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_stateless_multi_control.e @@ -0,0 +1,31 @@ +note + description: "Summary description for {WSF_STATELESS_MULTI_CONTROL}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + WSF_STATELESS_MULTI_CONTROL [G -> WSF_STATELESS_CONTROL] +inherit + WSF_MULTI_CONTROL [G] + rename + make_with_tag_name as make_with_tag_name_and_name + end + +create + make_with_tag_name, make_tag_less + +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 ("", "") + stateless := True + end + +end diff --git a/examples/widgetapp/base_page.e b/examples/widgetapp/base_page.e index 9dd713d4..4e054dad 100644 --- a/examples/widgetapp/base_page.e +++ b/examples/widgetapp/base_page.e @@ -23,7 +23,7 @@ feature do create control.make ("container") control.add_class ("container") - create dropdown.make_with_tag_name ("mydropdown", "Dropdown", "li") + create dropdown.make_with_tag_name ( "Dropdown", "li") dropdown.add_link_item ("Example link 1", "#") dropdown.add_divider dropdown.add_link_item ("Example link 2", "#") From 86339d8163f5ba73a2c7c85d33f21d1782d79055 Mon Sep 17 00:00:00 2001 From: YNH Webdev Date: Fri, 8 Nov 2013 00:03:02 +0100 Subject: [PATCH 02/18] Redesign states and implement generated control_name --- .../kernel/dropdown/wsf_dropdown_control.e | 2 +- .../kernel/grid/wsf_grid_control.e | 4 +- .../kernel/grid/wsf_pagination_control.e | 8 +- .../kernel/grid/wsf_repeater_control.e | 6 +- .../kernel/input/wsf_autocomplete_control.e | 12 +- .../kernel/input/wsf_checkbox_control.e | 8 +- .../kernel/input/wsf_checkbox_list_control.e | 4 +- .../kernel/input/wsf_input_control.e | 10 +- .../kernel/input/wsf_password_control.e | 4 +- .../kernel/input/wsf_textarea_control.e | 4 +- .../kernel/navbar/wsf_navbar_control.e | 19 ++- .../kernel/navlist/wsf_navlist_control.e | 17 ++- .../kernel/navlist/wsf_navlist_item.e | 36 +++++- .../kernel/progressbar/wsf_progress_control.e | 12 +- .../kernel/slider/wsf_image_slider_control.e | 8 +- .../kernel/webcontrol/wsf_button_control.e | 10 +- .../kernel/webcontrol/wsf_control.e | 27 ++++- .../kernel/webcontrol/wsf_form_control.e | 4 +- .../webcontrol/wsf_form_element_control.e | 9 +- .../kernel/webcontrol/wsf_html_control.e | 6 +- .../kernel/webcontrol/wsf_layout_control.e | 8 +- .../kernel/webcontrol/wsf_multi_control.e | 46 +++++-- .../kernel/webcontrol/wsf_page_control.e | 10 +- .../kernel/webcontrol/wsf_stateless_control.e | 6 + .../webcontrol/wsf_stateless_multi_control.e | 69 ++++++++++- examples/widgetapp/assets/widget.coffee | 74 ++++++++++-- examples/widgetapp/assets/widget.js | 113 +++++++++++++++--- examples/widgetapp/base_page.e | 6 +- examples/widgetapp/codeview_page.e | 2 +- examples/widgetapp/grid_page.e | 4 +- examples/widgetapp/image_slider_page.e | 6 +- examples/widgetapp/repeater_page.e | 4 +- examples/widgetapp/sample_page.e | 28 ++--- 33 files changed, 433 insertions(+), 153 deletions(-) diff --git a/draft/library/wsf_js_widget/kernel/dropdown/wsf_dropdown_control.e b/draft/library/wsf_js_widget/kernel/dropdown/wsf_dropdown_control.e index a12b7916..3693c02a 100644 --- a/draft/library/wsf_js_widget/kernel/dropdown/wsf_dropdown_control.e +++ b/draft/library/wsf_js_widget/kernel/dropdown/wsf_dropdown_control.e @@ -44,7 +44,7 @@ feature -- Change local li: WSF_MULTI_CONTROL [WSF_STATELESS_CONTROL] do - create li.make_with_tag_name (control_name + "_item" + dropdown_menu.controls.count.out, "li") + create li.make_with_tag_name ("li") li.add_control (c) dropdown_menu.add_control (li) end diff --git a/draft/library/wsf_js_widget/kernel/grid/wsf_grid_control.e b/draft/library/wsf_js_widget/kernel/grid/wsf_grid_control.e index cab1e36c..77cfae25 100644 --- a/draft/library/wsf_js_widget/kernel/grid/wsf_grid_control.e +++ b/draft/library/wsf_js_widget/kernel/grid/wsf_grid_control.e @@ -21,9 +21,9 @@ create feature {NONE} -- Initialization - make (n: STRING; a_columns: ITERABLE [WSF_GRID_COLUMN]; a_datasource: WSF_DATASOURCE [G]) + make (a_columns: ITERABLE [WSF_GRID_COLUMN]; a_datasource: WSF_DATASOURCE [G]) do - make_repeater (n, a_datasource) + make_repeater (a_datasource) columns := a_columns end diff --git a/draft/library/wsf_js_widget/kernel/grid/wsf_pagination_control.e b/draft/library/wsf_js_widget/kernel/grid/wsf_pagination_control.e index 838f2a55..1e377627 100644 --- a/draft/library/wsf_js_widget/kernel/grid/wsf_pagination_control.e +++ b/draft/library/wsf_js_widget/kernel/grid/wsf_pagination_control.e @@ -19,9 +19,9 @@ create feature {NONE} - make (n: STRING; ds: WSF_PAGABLE_DATASOURCE [G]) + make (ds: WSF_PAGABLE_DATASOURCE [G]) do - make_control (n, "ul") + make_control ( "ul") add_class ("pagination") datasource := ds datasource.set_on_update_page_agent (agent update) @@ -48,10 +48,10 @@ feature {WSF_PAGE_CONTROL, WSF_CONTROL} -- State management feature --Event handling - handle_callback (cname: STRING; event: STRING; event_parameter: detachable STRING) + handle_callback (cname: LIST[STRING]; event: STRING; event_parameter: detachable STRING) -- Handle goto/next/prev events do - if Current.control_name.same_string (cname) then + if Current.control_name.same_string (cname[1]) then if event.same_string ("next") then datasource.set_page (datasource.page + 1) elseif event.same_string ("prev") then diff --git a/draft/library/wsf_js_widget/kernel/grid/wsf_repeater_control.e b/draft/library/wsf_js_widget/kernel/grid/wsf_repeater_control.e index 88012bdd..785f8567 100644 --- a/draft/library/wsf_js_widget/kernel/grid/wsf_repeater_control.e +++ b/draft/library/wsf_js_widget/kernel/grid/wsf_repeater_control.e @@ -20,15 +20,15 @@ inherit feature {NONE} -- Initialization - make (n: STRING; a_datasource: WSF_DATASOURCE [G]) + make ( a_datasource: WSF_DATASOURCE [G]) local p: WSF_PAGINATION_CONTROL [G] do - make_multi_control (n) + make_multi_control datasource := a_datasource datasource.set_on_update_agent (agent update) if attached {WSF_PAGABLE_DATASOURCE [G]} a_datasource as ds then - create p.make (n + "_paging", ds) + create p.make ( ds) add_control (p) pagination_control := p end diff --git a/draft/library/wsf_js_widget/kernel/input/wsf_autocomplete_control.e b/draft/library/wsf_js_widget/kernel/input/wsf_autocomplete_control.e index 35b86056..f484947c 100644 --- a/draft/library/wsf_js_widget/kernel/input/wsf_autocomplete_control.e +++ b/draft/library/wsf_js_widget/kernel/input/wsf_autocomplete_control.e @@ -22,19 +22,19 @@ create feature {NONE} -- Initialization - make (n: STRING; c: WSF_AUTOCOMPLETION) + make (c: WSF_AUTOCOMPLETION) -- Initialize with specified name and autocompletion do - make_with_agent (n, agent c.autocompletion) + make_with_agent ( agent c.autocompletion) if attached c.template as t then template := t end end - make_with_agent (n: STRING; c: FUNCTION [ANY, TUPLE [STRING], JSON_ARRAY]) + make_with_agent (c: FUNCTION [ANY, TUPLE [STRING], JSON_ARRAY]) -- Initialize with specified name and autocompletion function do - make_input (n, "") + make_input ( "") create_json_list := c template := "{{=value}}" end @@ -49,10 +49,10 @@ feature -- State feature -- Callback - handle_callback (cname: STRING; event: STRING; event_parameter: detachable STRING) + handle_callback (cname: LIST[STRING]; event: STRING; event_parameter: detachable STRING) do Precursor {WSF_INPUT_CONTROL} (cname, event, event_parameter) - if cname.same_string (control_name) and event.same_string ("autocomplete") then + if cname[1].same_string (control_name) and event.same_string ("autocomplete") then state_changes.put (create_json_list.item ([text]), "suggestions") end end diff --git a/draft/library/wsf_js_widget/kernel/input/wsf_checkbox_control.e b/draft/library/wsf_js_widget/kernel/input/wsf_checkbox_control.e index 6b9d1239..6afa3e6f 100644 --- a/draft/library/wsf_js_widget/kernel/input/wsf_checkbox_control.e +++ b/draft/library/wsf_js_widget/kernel/input/wsf_checkbox_control.e @@ -19,10 +19,10 @@ create feature {NONE} -- Initialization - make (n, l, c: STRING) + make (l, c: STRING) -- Initialize with specified control name, do - make_value_control (n, "input") + make_value_control ( "input") label := l checked_value := c end @@ -54,9 +54,9 @@ feature --Event handling change_event := e end - handle_callback (cname: STRING; event: STRING; event_parameter: detachable STRING) + handle_callback (cname: LIST[STRING]; event: STRING; event_parameter: detachable STRING) do - if Current.control_name.same_string (cname) and attached change_event as cevent then + 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 diff --git a/draft/library/wsf_js_widget/kernel/input/wsf_checkbox_list_control.e b/draft/library/wsf_js_widget/kernel/input/wsf_checkbox_list_control.e index e99d91ee..6d9d2aff 100644 --- a/draft/library/wsf_js_widget/kernel/input/wsf_checkbox_list_control.e +++ b/draft/library/wsf_js_widget/kernel/input/wsf_checkbox_list_control.e @@ -28,10 +28,10 @@ create feature {NONE} -- Initializaton - make (n: STRING) + make -- Initialize with specified control name do - make_multi_control (n) + make_multi_control end feature -- Implementation diff --git a/draft/library/wsf_js_widget/kernel/input/wsf_input_control.e b/draft/library/wsf_js_widget/kernel/input/wsf_input_control.e index c0223e3c..e0511bb0 100644 --- a/draft/library/wsf_js_widget/kernel/input/wsf_input_control.e +++ b/draft/library/wsf_js_widget/kernel/input/wsf_input_control.e @@ -19,10 +19,10 @@ create feature {NONE} -- Initialization - make (n, v: STRING) + make (v: STRING) -- Initialize with specified name and value do - make_value_control (n, "input") + make_value_control ( "input") type := "text" text := v end @@ -53,9 +53,9 @@ feature --Event handling change_event := e end - handle_callback (cname: STRING; event: STRING; event_parameter: detachable STRING) - do - if Current.control_name.same_string (cname) and attached change_event as cevent then + 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 diff --git a/draft/library/wsf_js_widget/kernel/input/wsf_password_control.e b/draft/library/wsf_js_widget/kernel/input/wsf_password_control.e index 536f1b26..4bd84b97 100644 --- a/draft/library/wsf_js_widget/kernel/input/wsf_password_control.e +++ b/draft/library/wsf_js_widget/kernel/input/wsf_password_control.e @@ -19,10 +19,10 @@ create feature {NONE} -- Initialization - make (n, v: STRING) + make (v: STRING) -- Initialize with specified control name and text do - make_input (n, v) + make_input (v) type := "password" end diff --git a/draft/library/wsf_js_widget/kernel/input/wsf_textarea_control.e b/draft/library/wsf_js_widget/kernel/input/wsf_textarea_control.e index 440b8795..2b0318b4 100644 --- a/draft/library/wsf_js_widget/kernel/input/wsf_textarea_control.e +++ b/draft/library/wsf_js_widget/kernel/input/wsf_textarea_control.e @@ -21,10 +21,10 @@ create feature {NONE} -- Initialization - make (n, t: STRING) + make (t: STRING) -- Initialize with specified control name and text to be displayed in this textarea do - make_input (n, t) + make_input ( t) tag_name := "textarea" end diff --git a/draft/library/wsf_js_widget/kernel/navbar/wsf_navbar_control.e b/draft/library/wsf_js_widget/kernel/navbar/wsf_navbar_control.e index 302a00b4..4c7b69b9 100644 --- a/draft/library/wsf_js_widget/kernel/navbar/wsf_navbar_control.e +++ b/draft/library/wsf_js_widget/kernel/navbar/wsf_navbar_control.e @@ -21,10 +21,10 @@ create feature {NONE} -- Initialization - make (n: STRING) + make --Initialize do - make_multi_control (n) + make_multi_control active_set := false add_class ("navbar navbar-inverse navbar-fixed-top") create nav.make_with_tag_name ("ul") @@ -35,10 +35,10 @@ feature {NONE} -- Initialization nav_right.add_class ("nav navbar-nav navbar-right") end - make_with_brand (n, b: STRING) + make_with_brand ( b: STRING) -- Initialize with specified brand string do - make (n) + make brand := b end @@ -85,7 +85,7 @@ feature -- Change local li: WSF_MULTI_CONTROL [WSF_STATELESS_CONTROL] do - create li.make_with_tag_name (control_name + "_link" + nav.controls.count.out, "li") + create li.make_with_tag_name ("li") li.add_class ("dropdown") li.add_control (l) li.add_control (d) @@ -97,7 +97,7 @@ feature -- Change local li: WSF_MULTI_CONTROL [WSF_STATELESS_CONTROL] do - create li.make_with_tag_name (control_name + "_link" + nav.controls.count.out, "li") + create li.make_with_tag_name ("li") li.add_class ("dropdown") li.add_control (l) li.add_control (d) @@ -107,12 +107,9 @@ feature -- Change add_list_element_right (l: WSF_STATELESS_CONTROL) -- Add element in li tag to right aligned part of navbar local - name: STRING li: WSF_MULTI_CONTROL [WSF_STATELESS_CONTROL] do - name := control_name + "_rightlink"; - name := name + nav_right.controls.count.out - create li.make_with_tag_name (name, "li") + create li.make_with_tag_name ("li") li.add_control (l) add_element_right (li) end @@ -122,7 +119,7 @@ feature -- Change local li: WSF_MULTI_CONTROL [WSF_STATELESS_CONTROL] do - create li.make_with_tag_name (control_name + "_link" + nav.controls.count.out, "li") + create li.make_with_tag_name ("li") li.add_control (l) add_element (li) end diff --git a/draft/library/wsf_js_widget/kernel/navlist/wsf_navlist_control.e b/draft/library/wsf_js_widget/kernel/navlist/wsf_navlist_control.e index 0cb3f015..e2558c53 100644 --- a/draft/library/wsf_js_widget/kernel/navlist/wsf_navlist_control.e +++ b/draft/library/wsf_js_widget/kernel/navlist/wsf_navlist_control.e @@ -9,7 +9,7 @@ class inherit - WSF_MULTI_CONTROL [WSF_STATELESS_CONTROL] + WSF_MULTI_CONTROL [WSF_NAVLIST_ITEM_CONTROL] rename make as make_multi_control end @@ -19,9 +19,9 @@ create feature {NONE} -- Initialization - make (n: STRING) + make do - make_multi_control (n) + make_multi_control add_class ("list-group") end @@ -31,7 +31,16 @@ feature -- Change local c: WSF_NAVLIST_ITEM_CONTROL do - create c.make (control_name + "_item_" + controls.count.out, link, text) + create c.make (link, text) + add_control(c) + end + + add_button (event:attached like {WSF_BUTTON_CONTROL}.click_event; text: STRING) + local + c: WSF_NAVLIST_ITEM_CONTROL + do + create c.make ("", text) + c.set_click_event(event) add_control(c) end diff --git a/draft/library/wsf_js_widget/kernel/navlist/wsf_navlist_item.e b/draft/library/wsf_js_widget/kernel/navlist/wsf_navlist_item.e index a2b338a9..f589313e 100644 --- a/draft/library/wsf_js_widget/kernel/navlist/wsf_navlist_item.e +++ b/draft/library/wsf_js_widget/kernel/navlist/wsf_navlist_item.e @@ -12,6 +12,9 @@ inherit WSF_BUTTON_CONTROL rename make as make_button + redefine + set_state, + state end create @@ -19,12 +22,41 @@ create feature {NONE} -- Initialization - make (n, link, t: STRING) + make ( link, t: STRING) do - make_control (n, "a") + make_control ("a") text := t attributes := "href=%"" + link + "%""; add_class ("list-group-item") end +feature {WSF_PAGE_CONTROL, WSF_CONTROL} -- State management + + set_state (new_state: JSON_OBJECT) + -- Restore text from json + do + Precursor {WSF_BUTTON_CONTROL}(new_state) + if attached {JSON_BOOLEAN} new_state.item ("active") as new_active then + active := new_active.item + end + end + + state: WSF_JSON_OBJECT + -- Return state which contains the current text and if there is an event handle attached + do + Result := Precursor {WSF_BUTTON_CONTROL} + Result.put_boolean (true, "active") + end + +feature -- Change + + set_active (a: BOOLEAN) + -- Set text of that button + do + active := a + state_changes.replace (create {JSON_BOOLEAN}.make_boolean (a), "active") + end +feature -- Properties + + active: BOOLEAN end diff --git a/draft/library/wsf_js_widget/kernel/progressbar/wsf_progress_control.e b/draft/library/wsf_js_widget/kernel/progressbar/wsf_progress_control.e index 5e2ea58c..2f772db6 100644 --- a/draft/library/wsf_js_widget/kernel/progressbar/wsf_progress_control.e +++ b/draft/library/wsf_js_widget/kernel/progressbar/wsf_progress_control.e @@ -19,18 +19,18 @@ create feature {NONE} -- Initialization - make (n: STRING) + make -- Initialize with specified control name do - make_control (n, "div") + make_control ("div") add_class ("progress") progress := 0 end - make_with_source (n: STRING; p: WSF_PROGRESSSOURCE) + make_with_source ( p: WSF_PROGRESSSOURCE) -- Initialize with specified control name and progresssource do - make (n) + make progress_source := p end @@ -51,9 +51,9 @@ feature -- State handling feature -- Event handling - handle_callback (cname: STRING; event: STRING; event_parameter: detachable STRING) + handle_callback (cname: LIST[STRING]; event: STRING; event_parameter: detachable STRING) do - if cname.same_string (control_name) and event.same_string ("progress_fetch") then + if cname[1].same_string (control_name) and event.same_string ("progress_fetch") then state_changes.put_integer (progress_value, "progress") end end diff --git a/draft/library/wsf_js_widget/kernel/slider/wsf_image_slider_control.e b/draft/library/wsf_js_widget/kernel/slider/wsf_image_slider_control.e index 0a9f3bbe..f7200e23 100644 --- a/draft/library/wsf_js_widget/kernel/slider/wsf_image_slider_control.e +++ b/draft/library/wsf_js_widget/kernel/slider/wsf_image_slider_control.e @@ -19,10 +19,10 @@ create feature {NONE} -- Initialization - make (n: STRING) + make -- Initialize with specified name do - make_control (n, "div") + make_control ( "div") add_class ("carousel slide") create list.make_with_tag_name ( "ol") list.add_class ("carousel-indicators") @@ -43,7 +43,7 @@ feature -- State handling feature -- Callback - handle_callback (cname, event: STRING; event_parameter: detachable STRING) + handle_callback (cname: LIST[STRING]; event: STRING; event_parameter: detachable STRING) do -- Do nothing here end @@ -91,7 +91,7 @@ feature -- Change cl: STRING item: WSF_MULTI_CONTROL [WSF_STATELESS_CONTROL] do - create item.make (control_name + "_item" + slide_wrapper.controls.count.out) + create item.make () item.add_class ("item") item.add_control (c) if attached caption as capt then diff --git a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_button_control.e b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_button_control.e index 841537af..dd06596f 100644 --- a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_button_control.e +++ b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_button_control.e @@ -19,13 +19,13 @@ create feature {NONE} -- Initialization - make (n: STRING; t: STRING) + make (a_text: STRING) -- Initialize with specified control name and text do - make_control (n, "button") + make_control ("button") add_class ("btn") add_class ("btn-default") - text := t + text := a_text end feature {WSF_PAGE_CONTROL, WSF_CONTROL} -- State management @@ -54,9 +54,9 @@ feature --Event handling click_event := e end - handle_callback (cname: STRING; event: STRING; event_parameter: detachable STRING) + handle_callback (cname: LIST[STRING]; event: STRING; event_parameter: detachable STRING) do - if Current.control_name.same_string (cname) and attached click_event as cevent then + if Current.control_name.same_string (cname[1]) and attached click_event as cevent then cevent.call (Void) end end 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 f3ee1f54..c65d7d9b 100644 --- a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_control.e +++ b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_control.e @@ -18,14 +18,13 @@ inherit feature {NONE} -- Initialization - make (n, a_tag_name: STRING) + make (a_tag_name: STRING) -- Initialize with specified control name and tag require - not n.is_empty not a_tag_name.is_empty do make_stateless_control (a_tag_name) - control_name := n + create control_name_prefix.make_empty create state_changes.make create actions.make_array ensure @@ -140,7 +139,7 @@ feature -- Rendering loop css_classes_string := css_classes_string + " " + c.item end - l_attributes := "id=%"" + control_name + "%" data-name=%"" + control_name + "%" data-type=%"" + a_generator + "%" " + l_attributes := " data-name=%"" + control_name + "%" data-type=%"" + a_generator + "%" " if attached attrs as a then l_attributes := l_attributes + a end @@ -152,7 +151,7 @@ feature -- Rendering feature -- Event handling - handle_callback (cname: STRING; event: STRING; event_parameter: detachable STRING) + handle_callback (cname: LIST [STRING]; event: STRING; event_parameter: detachable STRING) -- Method called if any callback received. In this method you can route the callback to the event handler deferred end @@ -170,6 +169,24 @@ feature -- Properties actions: JSON_ARRAY + control_id: INTEGER assign set_control_id + + set_control_id (d: INTEGER) + do + control_id := d + end + control_name: STRING + do + Result := control_name_prefix + control_id.out + end + + control_name_prefix: STRING assign set_control_name_prefix + + + set_control_name_prefix (p: STRING) + do + control_name_prefix := p + end end diff --git a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_form_control.e b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_form_control.e index 3bb3c46d..42bb258a 100644 --- a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_form_control.e +++ b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_form_control.e @@ -21,10 +21,10 @@ create feature {NONE} -- Initialization - make (n: STRING) + make -- Initialize do - make_multi_control (n) + make_multi_control tag_name := "form" 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 b8fd1d9f..5a9e9e2d 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 @@ -34,7 +34,7 @@ feature {NONE} -- Initialization make_with_validators (a_label: STRING; c: WSF_VALUE_CONTROL [G]; v: LIST [WSF_VALIDATOR [G]]) -- Initialize form element control with a specific label, value control and list of validators do - make_control (c.control_name + "_container", "div") + 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") @@ -100,14 +100,15 @@ feature {WSF_PAGE_CONTROL, WSF_CONTROL} -- State management feature -- Event handling - handle_callback (cname: STRING; event: STRING; event_parameter: detachable STRING) + handle_callback (cname: LIST[STRING]; event: STRING; event_parameter: detachable STRING) -- Pass callback to subcontrols do - if cname.same_string (control_name) then + if cname[1].same_string (control_name) then + cname.go_i_th (1) + cname.remove if event.same_string ("validate") then validate end - else value_control.handle_callback (cname, event, event_parameter) end end diff --git a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_html_control.e b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_html_control.e index 7d6a6f4c..11335fd4 100644 --- a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_html_control.e +++ b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_html_control.e @@ -17,10 +17,10 @@ create feature {NONE} -- Initialization - make (n, t, v: STRING) + make (t, v: STRING) -- Initialize do - make_value_control (n, t) + make_value_control ( t) html := v end @@ -43,7 +43,7 @@ feature {WSF_PAGE_CONTROL, WSF_CONTROL} -- State management feature --Event handling - handle_callback (cname: STRING; event: STRING; event_parameter: detachable STRING) + handle_callback (cname: LIST[STRING]; event: STRING; event_parameter: detachable STRING) do end diff --git a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_layout_control.e b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_layout_control.e index 4f7fb08d..1ff8c24c 100644 --- a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_layout_control.e +++ b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_layout_control.e @@ -30,9 +30,9 @@ feature -- Add control add_control_with_offset (c: WSF_STATELESS_CONTROL; span, offset: INTEGER) local - div: WSF_MULTI_CONTROL [WSF_STATELESS_CONTROL] + div: WSF_STATELESS_MULTI_CONTROL [WSF_STATELESS_CONTROL] do - create div.make (control_name + "_item_" + controls.count.out) + create div.make_with_tag_name ("div") div.add_class ("col-md-" + span.out + " col-md-offset-" + offset.out) div.add_control (c) add_control_raw (div) @@ -40,9 +40,9 @@ feature -- Add control add_control (c: WSF_STATELESS_CONTROL; span: INTEGER) local - div: WSF_MULTI_CONTROL [WSF_STATELESS_CONTROL] + div: WSF_STATELESS_MULTI_CONTROL [WSF_STATELESS_CONTROL] do - create div.make (control_name + "_item_" + controls.count.out) + create div.make_with_tag_name ("div") div.add_class ("col-md-" + span.out) div.add_control (c) add_control_raw (div) diff --git a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_multi_control.e b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_multi_control.e index fc6fdfaa..33aec384 100644 --- a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_multi_control.e +++ b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_multi_control.e @@ -23,16 +23,16 @@ create feature {NONE} -- Initialization - make (n: STRING) + make -- Initialize with specified control name and default tag "div" do - make_with_tag_name (n, "div") + make_with_tag_name ("div") end - make_with_tag_name (n, t: STRING) + make_with_tag_name (t: STRING) -- Initialize with specified control name and tag do - make_control (n, t) + make_control (t) controls := create {ARRAYED_LIST [G]}.make (5); end @@ -52,7 +52,7 @@ feature {WSF_PAGE_CONTROL, WSF_CONTROL} -- State management across controls as c loop - if attached {WSF_STATELESS_MULTI_CONTROL[WSF_STATELESS_CONTROL]} c.item as cont then + if attached {WSF_STATELESS_MULTI_CONTROL [WSF_STATELESS_CONTROL]} c.item as cont then cont.load_subcontrol_state (newstate) elseif attached {WSF_CONTROL} c.item as cont then if attached {JSON_OBJECT} newstate.item (cont.control_name) as value_state then @@ -83,7 +83,7 @@ feature {WSF_PAGE_CONTROL, WSF_CONTROL} -- State management across controls as c loop - if attached {WSF_STATELESS_MULTI_CONTROL[WSF_STATELESS_CONTROL]} c.item as mcont then + if attached {WSF_STATELESS_MULTI_CONTROL [WSF_STATELESS_CONTROL]} c.item as mcont then mcont.read_subcontrol_state (controls_state) elseif attached {WSF_CONTROL} c.item as cont then controls_state.put (cont.full_state, cont.control_name) @@ -93,12 +93,32 @@ feature {WSF_PAGE_CONTROL, WSF_CONTROL} -- State management read_state_changes (states: WSF_JSON_OBJECT) -- Read states_changes in subcontrols + local + sub_states: WSF_JSON_OBJECT + control_state: WSF_JSON_OBJECT do Precursor (states) + create sub_states.make + read_subcontrol_state_changes (sub_states) + if sub_states.count>0 then + if attached {JSON_OBJECT}states.item (control_name) as changes then + changes.put (sub_states, "controls") + else + create control_state.make + control_state.put (sub_states, "controls") + states.put (control_state, control_name) + end + end + end + + read_subcontrol_state_changes (states: WSF_JSON_OBJECT) + do across controls as c loop - if attached {WSF_CONTROL} c.item as cont then + if attached {WSF_STATELESS_MULTI_CONTROL [WSF_STATELESS_CONTROL]} c.item as cont then + cont.read_subcontrol_state_changes (states) + elseif attached {WSF_CONTROL} c.item as cont then cont.read_state_changes (states) end end @@ -112,11 +132,12 @@ feature {WSF_PAGE_CONTROL, WSF_CONTROL} -- State management feature -- Event handling - handle_callback (cname: STRING; event: STRING; event_parameter: detachable STRING) + handle_callback (cname: LIST [STRING]; event: STRING; event_parameter: detachable STRING) -- Pass callback to subcontrols do - if equal (cname, control_name) then - else + if equal (cname [1], control_name) then + cname.go_i_th (1) + cname.remove across controls as c loop @@ -143,12 +164,15 @@ feature -- Rendering end end -feature -- Change +feature add_control (c: G) -- Add a control to this multi control do controls.extend (c) + if attached {WSF_CONTROL} c as d then + d.control_id := controls.count + end end feature -- Properties 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 1484eeb9..e9e8fa23 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 @@ -13,6 +13,7 @@ inherit rename make as make_control redefine + control_name, full_state, read_state_changes end @@ -22,7 +23,8 @@ feature {NONE} -- Initialization make (req: WSF_REQUEST; res: WSF_RESPONSE) -- Initialize do - make_control (req.request_time_stamp.out, "body") + control_name:=req.request_time_stamp.out + make_control ( "body") request := req response := res initialize_controls @@ -73,7 +75,7 @@ feature -- Implementation if attached {JSON_OBJECT} json_parser.parse_json as sp then set_state (sp) end - handle_callback (event_control_name, event, event_parameter) + handle_callback (event_control_name.split ('-'), event, event_parameter) create states_changes.make read_state_changes (states_changes) response.put_header ({HTTP_STATUS_CODE}.ok, <<["Content-Type", "application/json; charset=ISO-8859-1"]>>) @@ -145,7 +147,7 @@ feature -- Implementation feature -- Event handling - handle_callback (cname: STRING; event: STRING; event_parameter: detachable STRING) + handle_callback (cname: LIST[STRING]; event: STRING; event_parameter: detachable STRING) -- Forward callback to control do control.handle_callback (cname, event, event_parameter) @@ -178,6 +180,8 @@ feature {WSF_PAGE_CONTROL, WSF_CONTROL} -- State management Result.put (controls_state, "controls") Result.put (state, "state") end +feature + control_name:STRING feature {NONE} -- Root control diff --git a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_stateless_control.e b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_stateless_control.e index 6bfbd7be..ab70a7de 100644 --- a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_stateless_control.e +++ b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_stateless_control.e @@ -37,6 +37,12 @@ feature -- Change css_classes.force (c) end + remove_class (cla: STRING) + -- Add a css class to this control + do + css_classes.prune (cla) + end + feature -- Rendering render_tag (body: STRING; attrs: detachable STRING): STRING 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 3425abb7..8ce9321e 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 @@ -6,10 +6,17 @@ note class WSF_STATELESS_MULTI_CONTROL [G -> WSF_STATELESS_CONTROL] + inherit + WSF_MULTI_CONTROL [G] rename make_with_tag_name as make_with_tag_name_and_name + redefine + add_control, + set_control_name_prefix, + handle_callback, + set_control_id end create @@ -17,15 +24,67 @@ create feature {NONE} -- Initialization - make_with_tag_name(t:STRING) - do - make_with_tag_name_and_name("",t) - end + 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_and_name ("") stateless := True end +feature + + + + set_control_id (d: INTEGER) + do + control_id := d + set_subcontrol_prefixes + end + + set_control_name_prefix (p: STRING) + do + control_name_prefix := p + set_subcontrol_prefixes + end + + set_subcontrol_prefixes + do + across + controls as e + loop + if attached {WSF_CONTROL} e.item as el then + el.control_name_prefix := control_name_prefix + control_id.out + "_" + end + end + end + +feature + + add_control (c: G) + -- Add a control to this multi control + do + controls.extend (c) + if attached {WSF_CONTROL} c as d then + d.control_id := controls.count + d.control_name_prefix := control_name_prefix + control_id.out + "_" + end + end +feature -- Event handling + + handle_callback (cname: LIST [STRING]; event: STRING; event_parameter: detachable STRING) + -- Pass callback to subcontrols + do + across + controls as c + loop + if attached {WSF_CONTROL} c.item as cont then + cont.handle_callback (cname, event, event_parameter) + end + end + end + end diff --git a/examples/widgetapp/assets/widget.coffee b/examples/widgetapp/assets/widget.coffee index 323faf89..f2493c01 100644 --- a/examples/widgetapp/assets/widget.coffee +++ b/examples/widgetapp/assets/widget.coffee @@ -69,6 +69,15 @@ Mini = { render:template(t) } +parseSuggestions = (data)-> + for a of data + if a == 'suggestions' + return data[a] + else + d = parseSuggestions(data[a]) + if d? + return d + return null loaded = {} lazy_load = (requirements,fn,that)-> if requirements.length == 0 @@ -97,7 +106,7 @@ lazy_load = (requirements,fn,that)-> done() build_control = (control_name, state, control)-> - $el = control.$el.find('[data-name='+control_name+']') + $el = control.$el.find('[data-name='+control_name+']').first() #get control type type = $el.data('type') #create class @@ -176,16 +185,31 @@ class WSF_CONTROL console.log "Failed preforming action #{action.type}" process_update: (new_states)-> - if new_states[@control_name]? - @update(new_states[@control_name]) - for control in @controls - if control? - control.process_update(new_states) + try + if new_states[@control_name]? + @update(new_states[@control_name]) + for control in @controls + if control? + control.process_update(new_states[this.control_name]['controls']) + catch e + return + return + + get_context_state : ()-> if @parent_control? and not @isolation return @parent_control.get_context_state() return @wrap(@control_name,@fullstate) + + get_full_control_name: ()-> + if @parent_control? + val = @parent_control.get_full_control_name() + if val != "" + val = val + "-" + return val+@control_name + return @control_name + wrap : (cname,state)-> ctrs = {} ctrs[cname] = state @@ -201,10 +225,18 @@ class WSF_CONTROL @url + '?' + $.param(params) trigger_callback: (control_name,event,event_parameter)-> + @run_trigger_callback(@get_full_control_name(),event,event_parameter) + + get_page:()-> + if @parent_control? + return @parent_control.get_page() + return @ + + run_trigger_callback: (control_name,event,event_parameter)-> if @parent_control? and not @isolation - return @parent_control.trigger_callback(control_name,event,event_parameter) + return @parent_control.run_trigger_callback(control_name,event,event_parameter) self = @ - $.ajax + return $.ajax type: 'POST', url: @callback_url control_name: control_name @@ -219,7 +251,7 @@ class WSF_CONTROL #Update all classes if new_states.actions? self.process_actions(new_states.actions) - self.process_update(new_states) + self.get_page().process_update(new_states) #Simple event listener @@ -257,6 +289,17 @@ class WSF_PAGE_CONTROL extends WSF_CONTROL @initialize = lazy_load @requirements, @attach_events, @ @load_subcontrols() + process_update: (new_states)-> + for control in @controls + if control? + control.process_update(new_states) + + return + + + get_full_control_name: ()-> + "" + wrap : (cname,state)-> state @@ -310,6 +353,16 @@ class WSF_INPUT_CONTROL extends WSF_CONTROL if state.text? @state['text'] = state.text @$el.val(state.text) + +class WSF_NAVLIST_ITEM_CONTROL extends WSF_BUTTON_CONTROL + update: (state) -> + super + if state.active? + if state.active + @$el.addClass("active") + else + @$el.removeClass("active") + class WSF_TEXTAREA_CONTROL extends WSF_INPUT_CONTROL @@ -341,6 +394,7 @@ class WSF_AUTOCOMPLETE_CONTROL extends WSF_INPUT_CONTROL attach_events: () -> super self = @ + console.log @$el @$el.typeahead({ name: @control_name template: @state['template'] @@ -354,7 +408,7 @@ class WSF_AUTOCOMPLETE_CONTROL extends WSF_INPUT_CONTROL event: 'autocomplete' states: JSON.stringify(self.get_context_state()) filter: (parsedResponse) -> - parsedResponse[self.control_name]['suggestions'] + return parseSuggestions(parsedResponse) fn: ()-> self.trigger_callback(self.control_name, 'autocomplete') }) diff --git a/examples/widgetapp/assets/widget.js b/examples/widgetapp/assets/widget.js index 5cb134cd..e8dd864e 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_PAGE_CONTROL, WSF_PAGINATION_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, 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_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_PROGRESS_CONTROL, WSF_REGEXP_VALIDATOR, WSF_REPEATER_CONTROL, WSF_SLIDER_CONTROL, WSF_TEXTAREA_CONTROL, WSF_VALIDATOR, build_control, cache, controls, lazy_load, loaded, parseSuggestions, 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; }; @@ -101,6 +101,21 @@ Mini = { } }; +parseSuggestions = function(data) { + var a, d; + for (a in data) { + if (a === 'suggestions') { + return data[a]; + } else { + d = parseSuggestions(data[a]); + if (d != null) { + return d; + } + } + } + return null; +}; + loaded = {}; lazy_load = function(requirements, fn, that) { @@ -141,7 +156,7 @@ lazy_load = function(requirements, fn, that) { build_control = function(control_name, state, control) { var $el, type, typeclass; - $el = control.$el.find('[data-name=' + control_name + ']'); + $el = control.$el.find('[data-name=' + control_name + ']').first(); type = $el.data('type'); typeclass = null; try { @@ -293,21 +308,21 @@ WSF_CONTROL = (function() { }; WSF_CONTROL.prototype.process_update = function(new_states) { - var control, _i, _len, _ref, _results; - if (new_states[this.control_name] != null) { - this.update(new_states[this.control_name]); - } - _ref = this.controls; - _results = []; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - control = _ref[_i]; - if (control != null) { - _results.push(control.process_update(new_states)); - } else { - _results.push(void 0); + var control, _i, _len, _ref; + try { + if (new_states[this.control_name] != null) { + this.update(new_states[this.control_name]); + _ref = this.controls; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + control = _ref[_i]; + if (control != null) { + control.process_update(new_states[this.control_name]['controls']); + } + } } + } catch (e) { + return; } - return _results; }; WSF_CONTROL.prototype.get_context_state = function() { @@ -317,6 +332,18 @@ WSF_CONTROL = (function() { return this.wrap(this.control_name, this.fullstate); }; + WSF_CONTROL.prototype.get_full_control_name = function() { + var val; + if (this.parent_control != null) { + val = this.parent_control.get_full_control_name(); + if (val !== "") { + val = val + "-"; + } + return val + this.control_name; + } + return this.control_name; + }; + WSF_CONTROL.prototype.wrap = function(cname, state) { var ctrs; ctrs = {}; @@ -339,9 +366,20 @@ WSF_CONTROL = (function() { }; WSF_CONTROL.prototype.trigger_callback = function(control_name, event, event_parameter) { + return this.run_trigger_callback(this.get_full_control_name(), event, event_parameter); + }; + + WSF_CONTROL.prototype.get_page = function() { + if (this.parent_control != null) { + return this.parent_control.get_page(); + } + return this; + }; + + WSF_CONTROL.prototype.run_trigger_callback = function(control_name, event, event_parameter) { var self; if ((this.parent_control != null) && !this.isolation) { - return this.parent_control.trigger_callback(control_name, event, event_parameter); + return this.parent_control.run_trigger_callback(control_name, event, event_parameter); } self = this; return $.ajax({ @@ -359,7 +397,7 @@ WSF_CONTROL = (function() { if (new_states.actions != null) { self.process_actions(new_states.actions); } - return self.process_update(new_states); + return self.get_page().process_update(new_states); }); }; @@ -416,6 +454,21 @@ WSF_PAGE_CONTROL = (function(_super) { this.load_subcontrols(); } + WSF_PAGE_CONTROL.prototype.process_update = function(new_states) { + var control, _i, _len, _ref; + _ref = this.controls; + for (_i = 0, _len = _ref.length; _i < _len; _i++) { + control = _ref[_i]; + if (control != null) { + control.process_update(new_states); + } + } + }; + + WSF_PAGE_CONTROL.prototype.get_full_control_name = function() { + return ""; + }; + WSF_PAGE_CONTROL.prototype.wrap = function(cname, state) { return state; }; @@ -534,6 +587,29 @@ WSF_INPUT_CONTROL = (function(_super) { })(WSF_CONTROL); +WSF_NAVLIST_ITEM_CONTROL = (function(_super) { + + __extends(WSF_NAVLIST_ITEM_CONTROL, _super); + + function WSF_NAVLIST_ITEM_CONTROL() { + return WSF_NAVLIST_ITEM_CONTROL.__super__.constructor.apply(this, arguments); + } + + WSF_NAVLIST_ITEM_CONTROL.prototype.update = function(state) { + WSF_NAVLIST_ITEM_CONTROL.__super__.update.apply(this, arguments); + if (state.active != null) { + if (state.active) { + return this.$el.addClass("active"); + } else { + return this.$el.removeClass("active"); + } + } + }; + + return WSF_NAVLIST_ITEM_CONTROL; + +})(WSF_BUTTON_CONTROL); + WSF_TEXTAREA_CONTROL = (function(_super) { __extends(WSF_TEXTAREA_CONTROL, _super); @@ -590,6 +666,7 @@ WSF_AUTOCOMPLETE_CONTROL = (function(_super) { var self; WSF_AUTOCOMPLETE_CONTROL.__super__.attach_events.apply(this, arguments); self = this; + console.log(this.$el); this.$el.typeahead({ name: this.control_name, template: this.state['template'], @@ -605,7 +682,7 @@ WSF_AUTOCOMPLETE_CONTROL = (function(_super) { }); }, filter: function(parsedResponse) { - return parsedResponse[self.control_name]['suggestions']; + return parseSuggestions(parsedResponse); }, fn: function() { return self.trigger_callback(self.control_name, 'autocomplete'); diff --git a/examples/widgetapp/base_page.e b/examples/widgetapp/base_page.e index 4e054dad..6602a52e 100644 --- a/examples/widgetapp/base_page.e +++ b/examples/widgetapp/base_page.e @@ -21,20 +21,20 @@ feature btn: WSF_BUTTON_CONTROL dropdown:WSF_DROPDOWN_CONTROL do - create control.make ("container") + create control.make control.add_class ("container") create dropdown.make_with_tag_name ( "Dropdown", "li") dropdown.add_link_item ("Example link 1", "#") dropdown.add_divider dropdown.add_link_item ("Example link 2", "#") - create navbar.make_with_brand ("navbar1", "Example") + create navbar.make_with_brand ("Example") navbar.add_list_element (create {WSF_BASIC_CONTROL}.make_with_body ("a", "href=%"/%"", "Home")) navbar.add_list_element (create {WSF_BASIC_CONTROL}.make_with_body ("a", "href=%"/grid%"", "Grid")) navbar.add_list_element (create {WSF_BASIC_CONTROL}.make_with_body ("a", "href=%"/repeater%"", "Repeater")) navbar.add_list_element (create {WSF_BASIC_CONTROL}.make_with_body ("a", "href=%"/slider%"", "Slider")) navbar.add_element (dropdown) navbar.add_list_element_right (create {WSF_BASIC_CONTROL}.make_with_body ("a", "href=%"/about%"", "About")) - create btn.make ("scode", "Show Code") + create btn.make ("Show Code") btn.set_click_event (agent show_code) btn.set_isolation (true) btn.add_class ("btn-success") diff --git a/examples/widgetapp/codeview_page.e b/examples/widgetapp/codeview_page.e index 75e4e554..dd6ea7d7 100644 --- a/examples/widgetapp/codeview_page.e +++ b/examples/widgetapp/codeview_page.e @@ -20,7 +20,7 @@ feature initialize_controls do - create control.make_codeview ("textarea", "") + create control.make_codeview ("") end process diff --git a/examples/widgetapp/grid_page.e b/examples/widgetapp/grid_page.e index f68bf164..124f31ff 100644 --- a/examples/widgetapp/grid_page.e +++ b/examples/widgetapp/grid_page.e @@ -24,12 +24,12 @@ feature Precursor control.add_control (create {WSF_BASIC_CONTROL}.make_with_body ("h1", "", "Grid Demo")) create datasource.make_news - create search_query.make ("query", create {GOOGLE_AUTOCOMPLETION}.make) + create search_query.make (create {GOOGLE_AUTOCOMPLETION}.make) search_query.add_class ("form-control") search_query.set_change_event (agent change_query) control.add_control (search_query) control.add_control (create {WSF_BASIC_CONTROL}.make_with_body ("h2", "", "Results")) - create grid.make ("mygrid", <>, datasource) + create grid.make (<>, datasource) control.add_control (grid) navbar.set_active (2) end diff --git a/examples/widgetapp/image_slider_page.e b/examples/widgetapp/image_slider_page.e index caf93308..d2411873 100644 --- a/examples/widgetapp/image_slider_page.e +++ b/examples/widgetapp/image_slider_page.e @@ -24,9 +24,9 @@ feature -- Implementation form: WSF_FORM_CONTROL do Precursor - create slider.make ("myslider") - create form.make ("sliderform") - form.add_control (create {WSF_FORM_ELEMENT_CONTROL [STRING]}.make ("Input", create {WSF_INPUT_CONTROL}.make ("sliderformtext", "Test"))) + create slider.make + create form.make + form.add_control (create {WSF_FORM_ELEMENT_CONTROL [STRING]}.make ("Input", create {WSF_INPUT_CONTROL}.make ("Test"))) --slider.add_control (form, Void) --slider.add_image ("http://www.placesmustseen.com/wp-content/uploads/2013/01/paris-eiffel-tower.jpg", "Eiffel Tower") slider.add_image ("http://31.media.tumblr.com/43f3edae3fb569943047077cddf93c79/tumblr_mtw7wdX9cm1st5lhmo1_1280.jpg", "car") diff --git a/examples/widgetapp/repeater_page.e b/examples/widgetapp/repeater_page.e index c56ee8d0..3af98551 100644 --- a/examples/widgetapp/repeater_page.e +++ b/examples/widgetapp/repeater_page.e @@ -24,12 +24,12 @@ feature Precursor control.add_control (create {WSF_BASIC_CONTROL}.make_with_body ("h1", "", " Repeater Demo")) create datasource.make_news - create search_query.make ("query", create {GOOGLE_AUTOCOMPLETION}.make) + create search_query.make (create {GOOGLE_AUTOCOMPLETION}.make) search_query.add_class ("form-control") search_query.set_change_event (agent change_query) control.add_control (search_query) control.add_control (create {WSF_BASIC_CONTROL}.make_with_body ("h2", "", "Results")) - create repeater.make ("myrepeater", datasource) + create repeater.make (datasource) control.add_control (repeater) navbar.set_active (3) end diff --git a/examples/widgetapp/sample_page.e b/examples/widgetapp/sample_page.e index 9e2a9260..04d41b0c 100644 --- a/examples/widgetapp/sample_page.e +++ b/examples/widgetapp/sample_page.e @@ -30,58 +30,58 @@ feature source: INCREASING_PROGRESSSOURCE do Precursor - create form.make ("panel") + create form.make form.add_class ("form-horizontal") --Number 1 - create textbox1.make ("txtBox1", "1") + create textbox1.make ("1") create n1_container.make ("Number1", textbox1) n1_container.add_validator (create {WSF_DECIMAL_VALIDATOR}.make_decimal_validator ("Invalid Number")) n1_container.add_validator (create {OWN_VALIDATOR}.make_own) form.add_control (n1_container) --Number 2 - create textbox2.make ("txtBox2", "2") + create textbox2.make ("2") create n2_container.make ("Number2", textbox2) n2_container.add_validator (create {WSF_DECIMAL_VALIDATOR}.make_decimal_validator ("Invalid Number")) form.add_control (n2_container) --Flag autocomplete - create autocompletion1.make ("autocompletion1", create {FLAG_AUTOCOMPLETION}.make) + create autocompletion1.make (create {FLAG_AUTOCOMPLETION}.make) create n3_container.make ("Flag Autocomplete", autocompletion1) form.add_control (n3_container) --Contact autocomplete - create autocompletion2.make ("autocompletion2", create {CONTACT_AUTOCOMPLETION}.make) + create autocompletion2.make (create {CONTACT_AUTOCOMPLETION}.make) create n4_container.make ("Contact Autocomplete", autocompletion2) form.add_control (n4_container) --Google autocomplete - create autocompletion3.make ("autocompletion4", create {GOOGLE_AUTOCOMPLETION}.make) + create autocompletion3.make (create {GOOGLE_AUTOCOMPLETION}.make) create n5_container.make ("Google Autocomplete", autocompletion3) form.add_control (n5_container) --Categories - create cklist.make ("categories") - cklist.add_control (create {WSF_CHECKBOX_CONTROL}.make ("net", "Network", "net")) - cklist.add_control (create {WSF_CHECKBOX_CONTROL}.make ("os", "Operating Systems", "os")) - cklist.add_control (create {WSF_CHECKBOX_CONTROL}.make ("fmfp", "Formal Methods and Functional Programming", "fmfp")) + create cklist.make + cklist.add_control (create {WSF_CHECKBOX_CONTROL}.make ("Network", "net")) + cklist.add_control (create {WSF_CHECKBOX_CONTROL}.make ("Operating Systems", "os")) + cklist.add_control (create {WSF_CHECKBOX_CONTROL}.make ("Formal Methods and Functional Programming", "fmfp")) create cats_container.make ("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 (2, "Choose at most two category")) form.add_control (cats_container) --Button 1 - create button1.make ("sample_button1", "Update") + create button1.make ("Update") button1.set_click_event (agent handle_click) button1.add_class ("col-lg-offset-2") form.add_control (button1) --Button 2 - create button2.make ("sample_button2", "Start Modal Grid") + create button2.make ("Start Modal Grid") button2.set_click_event (agent handle_click) form.add_control (button2) --Result - create result_html.make ("txtBox3", "p", "") + create result_html.make ("p", "") form.add_control (create {WSF_FORM_ELEMENT_CONTROL [STRING]}.make ("Result", result_html)) control.add_control (form) --Progress bar control.add_control (create {WSF_BASIC_CONTROL}.make_with_body ("h4", "", "Autoincrementing progressbar")) create source.make - create progress.make_with_source ("progress1", source) + create progress.make_with_source (source) source.set_control (progress) progress.set_isolation (true) control.add_control (progress) From 0d79799a5db8fbc6e25dce5c3373ba0d0f182e5c Mon Sep 17 00:00:00 2001 From: YNH Webdev Date: Fri, 8 Nov 2013 00:09:09 +0100 Subject: [PATCH 03/18] Fix autocomplete --- examples/widgetapp/assets/widget.coffee | 2 +- examples/widgetapp/assets/widget.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/widgetapp/assets/widget.coffee b/examples/widgetapp/assets/widget.coffee index f2493c01..a4847fe4 100644 --- a/examples/widgetapp/assets/widget.coffee +++ b/examples/widgetapp/assets/widget.coffee @@ -396,7 +396,7 @@ class WSF_AUTOCOMPLETE_CONTROL extends WSF_INPUT_CONTROL self = @ console.log @$el @$el.typeahead({ - name: @control_name + name: @control_name+Math.random() template: @state['template'] engine: Mini remote: diff --git a/examples/widgetapp/assets/widget.js b/examples/widgetapp/assets/widget.js index e8dd864e..00281b07 100644 --- a/examples/widgetapp/assets/widget.js +++ b/examples/widgetapp/assets/widget.js @@ -668,7 +668,7 @@ WSF_AUTOCOMPLETE_CONTROL = (function(_super) { self = this; console.log(this.$el); this.$el.typeahead({ - name: this.control_name, + name: this.control_name + Math.random(), template: this.state['template'], engine: Mini, remote: { From 0721384b60878e42da22177aa41f3869c35a7139 Mon Sep 17 00:00:00 2001 From: YNH Webdev Date: Fri, 8 Nov 2013 09:27:56 +0100 Subject: [PATCH 04/18] Adjust layout control and fix navlist --- .../wsf_js_widget/kernel/navlist/wsf_navlist_item.e | 10 +++++++--- .../kernel/webcontrol/wsf_layout_control.e | 12 +++++++++--- examples/widgetapp/assets/widget.coffee | 1 + examples/widgetapp/assets/widget.js | 1 + 4 files changed, 18 insertions(+), 6 deletions(-) diff --git a/draft/library/wsf_js_widget/kernel/navlist/wsf_navlist_item.e b/draft/library/wsf_js_widget/kernel/navlist/wsf_navlist_item.e index f589313e..ee0d51cd 100644 --- a/draft/library/wsf_js_widget/kernel/navlist/wsf_navlist_item.e +++ b/draft/library/wsf_js_widget/kernel/navlist/wsf_navlist_item.e @@ -22,19 +22,20 @@ create feature {NONE} -- Initialization - make ( link, t: STRING) + make (link, t: STRING) do make_control ("a") text := t attributes := "href=%"" + link + "%""; add_class ("list-group-item") end + feature {WSF_PAGE_CONTROL, WSF_CONTROL} -- State management set_state (new_state: JSON_OBJECT) -- Restore text from json do - Precursor {WSF_BUTTON_CONTROL}(new_state) + Precursor {WSF_BUTTON_CONTROL} (new_state) if attached {JSON_BOOLEAN} new_state.item ("active") as new_active then active := new_active.item end @@ -44,7 +45,7 @@ feature {WSF_PAGE_CONTROL, WSF_CONTROL} -- State management -- Return state which contains the current text and if there is an event handle attached do Result := Precursor {WSF_BUTTON_CONTROL} - Result.put_boolean (true, "active") + Result.put_boolean (active, "active") end feature -- Change @@ -52,9 +53,12 @@ feature -- Change set_active (a: BOOLEAN) -- Set text of that button do + if active /= a then active := a state_changes.replace (create {JSON_BOOLEAN}.make_boolean (a), "active") + end end + feature -- Properties active: BOOLEAN diff --git a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_layout_control.e b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_layout_control.e index 1ff8c24c..0ce05128 100644 --- a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_layout_control.e +++ b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_layout_control.e @@ -12,7 +12,7 @@ inherit WSF_STATELESS_MULTI_CONTROL [WSF_STATELESS_CONTROL] rename make as make_multi_control, - add_control as add_control_raw + add_control as add_control_raw end create @@ -38,13 +38,19 @@ feature -- Add control add_control_raw (div) end - add_control (c: WSF_STATELESS_CONTROL; span: INTEGER) + add_control (col:INTEGER; c: WSF_STATELESS_CONTROL) + do + if attached {WSF_STATELESS_MULTI_CONTROL [WSF_STATELESS_CONTROL]}controls[col] as div then + div.add_control (c) + end + end + + add_column (span:INTEGER) local div: WSF_STATELESS_MULTI_CONTROL [WSF_STATELESS_CONTROL] do create div.make_with_tag_name ("div") div.add_class ("col-md-" + span.out) - div.add_control (c) add_control_raw (div) end diff --git a/examples/widgetapp/assets/widget.coffee b/examples/widgetapp/assets/widget.coffee index a4847fe4..939e7360 100644 --- a/examples/widgetapp/assets/widget.coffee +++ b/examples/widgetapp/assets/widget.coffee @@ -358,6 +358,7 @@ class WSF_NAVLIST_ITEM_CONTROL extends WSF_BUTTON_CONTROL update: (state) -> super if state.active? + @state['active'] = state.active if state.active @$el.addClass("active") else diff --git a/examples/widgetapp/assets/widget.js b/examples/widgetapp/assets/widget.js index 00281b07..a3f197e3 100644 --- a/examples/widgetapp/assets/widget.js +++ b/examples/widgetapp/assets/widget.js @@ -598,6 +598,7 @@ WSF_NAVLIST_ITEM_CONTROL = (function(_super) { WSF_NAVLIST_ITEM_CONTROL.prototype.update = function(state) { WSF_NAVLIST_ITEM_CONTROL.__super__.update.apply(this, arguments); if (state.active != null) { + this.state['active'] = state.active; if (state.active) { return this.$el.addClass("active"); } else { From 7e69fddac9efdd040a2c9b670c909b6addeb6314 Mon Sep 17 00:00:00 2001 From: YNH Webdev Date: Fri, 8 Nov 2013 23:03:30 +0100 Subject: [PATCH 05/18] Fix rendering issue. Add active class --- .../library/wsf_js_widget/kernel/navlist/wsf_navlist_item.e | 5 +++++ .../wsf_js_widget/kernel/webcontrol/wsf_stateless_control.e | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/draft/library/wsf_js_widget/kernel/navlist/wsf_navlist_item.e b/draft/library/wsf_js_widget/kernel/navlist/wsf_navlist_item.e index ee0d51cd..5dcbb5f5 100644 --- a/draft/library/wsf_js_widget/kernel/navlist/wsf_navlist_item.e +++ b/draft/library/wsf_js_widget/kernel/navlist/wsf_navlist_item.e @@ -55,6 +55,11 @@ feature -- Change do if active /= a then active := a + if a then + add_class ("active") + else + remove_class ("active") + end state_changes.replace (create {JSON_BOOLEAN}.make_boolean (a), "active") end end diff --git a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_stateless_control.e b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_stateless_control.e index ab70a7de..9294e329 100644 --- a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_stateless_control.e +++ b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_stateless_control.e @@ -75,7 +75,7 @@ feature -- Rendering l_attributes.append_character ('%"') end Result := "<" + tag + " " + l_attributes - if body.is_empty and not tag.same_string ("textarea") and not tag.same_string ("span") and not tag.same_string ("button") and not tag.same_string ("ul") then + if body.is_empty and not tag.same_string ("textarea") and not tag.same_string ("span") and not tag.same_string ("button") and not tag.same_string ("ul") and not tag.same_string ("div") then Result.append (" />") else Result.append (" >" + body + "") From 3895cf4399f405f2d51959ffc988f786c25a10cd Mon Sep 17 00:00:00 2001 From: YNH Webdev Date: Sat, 9 Nov 2013 14:42:17 +0100 Subject: [PATCH 06/18] Fix assert path --- .../wsf_js_widget/kernel/webcontrol/wsf_page_control.e | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) 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 e9e8fa23..e4848ca9 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 @@ -105,12 +105,12 @@ feature -- Implementation create Result.make_empty if not ajax then Result.append ("") - Result.append ("") - Result.append ("") + Result.append ("") + Result.append ("") Result.append ("") Result.append (control.render) - Result.append ("") - Result.append ("") + Result.append ("") + Result.append ("") Result.append ("") From 38f422896de4aee4af3543b2d4fc6235e17da593 Mon Sep 17 00:00:00 2001 From: YNH Webdev Date: Sat, 9 Nov 2013 17:14:58 +0100 Subject: [PATCH 07/18] Fix slider --- .../kernel/slider/wsf_image_slider_control.e | 6 +++--- examples/widgetapp/assets/widget.coffee | 16 +++++++++++----- examples/widgetapp/assets/widget.js | 17 +++++++++++++---- 3 files changed, 27 insertions(+), 12 deletions(-) diff --git a/draft/library/wsf_js_widget/kernel/slider/wsf_image_slider_control.e b/draft/library/wsf_js_widget/kernel/slider/wsf_image_slider_control.e index f7200e23..0e5263e1 100644 --- a/draft/library/wsf_js_widget/kernel/slider/wsf_image_slider_control.e +++ b/draft/library/wsf_js_widget/kernel/slider/wsf_image_slider_control.e @@ -56,8 +56,8 @@ feature -- Rendering do temp := list.render temp.append (slide_wrapper.render) - temp.append (render_tag_with_tagname ("a", "", "href=%"#" + control_name + "%" data-slide=%"prev%"", "left carousel-control")) - temp.append (render_tag_with_tagname ("a", "", "href=%"#" + control_name + "%" data-slide=%"next%"", "right carousel-control")) + temp.append (render_tag_with_tagname ("a", "", "data-slide=%"prev%"", "left carousel-control")) + temp.append (render_tag_with_tagname ("a", "", "data-slide=%"next%"", "right carousel-control")) Result := render_tag (temp, "") end @@ -103,7 +103,7 @@ feature -- Change item.add_class (cl) end slide_wrapper.add_control (item) - list.add_control (create {WSF_BASIC_CONTROL}.make_with_body_class ("li", "data-target=%"#" + control_name + "%" data-slide-to=%"" + list.controls.count.out + "%"", cl, "")); + list.add_control (create {WSF_BASIC_CONTROL}.make_with_body_class ("li", "data-slide-to=%"" + list.controls.count.out + "%"", cl, "")); end feature -- Properties diff --git a/examples/widgetapp/assets/widget.coffee b/examples/widgetapp/assets/widget.coffee index 939e7360..6c362ab0 100644 --- a/examples/widgetapp/assets/widget.coffee +++ b/examples/widgetapp/assets/widget.coffee @@ -308,10 +308,16 @@ class WSF_PAGE_CONTROL extends WSF_CONTROL @$el.remove() class WSF_SLIDER_CONTROL extends WSF_CONTROL - requirements: ['assets/bootstrap.min.js'] + requirements: ['/assets/bootstrap.min.js'] + attach_events: ()-> + super + id = "slider"+Math.round(Math.random()*10000) + @$el.attr("id",id) + @$el.find("ol li").attr("data-target","#"+id) + @$el.find(".carousel-control").attr("href","#"+id) class WSF_DROPDOWN_CONTROL extends WSF_CONTROL - requirements: ['assets/bootstrap.min.js'] + requirements: ['/assets/bootstrap.min.js'] controls = {} @@ -371,8 +377,8 @@ class WSF_CODEVIEW_CONTROL extends WSF_INPUT_CONTROL constructor:()-> super #load codemirror and then eiffel syntax - @initialize = lazy_load ['assets/codemirror/codemirror.js','assets/codemirror/codemirror.css','assets/codemirror/estudio.css'], - (lazy_load ['assets/codemirror/eiffel.js'], @attach_events, @), + @initialize = lazy_load ['/assets/codemirror/codemirror.js','/assets/codemirror/codemirror.css','/assets/codemirror/estudio.css'], + (lazy_load ['/assets/codemirror/eiffel.js'], @attach_events, @), @ attach_events: () -> @@ -595,7 +601,7 @@ class WSF_REPEATER_CONTROL extends WSF_CONTROL show_alert = (action)-> alert(action.message) -start_modal = lazy_load ['assets/bootstrap.min.js'], (action)-> +start_modal = lazy_load ['/assets/bootstrap.min.js'], (action)-> cssclass = "" if action.type == "start_modal_big" cssclass = " big" diff --git a/examples/widgetapp/assets/widget.js b/examples/widgetapp/assets/widget.js index a3f197e3..3eb2c515 100644 --- a/examples/widgetapp/assets/widget.js +++ b/examples/widgetapp/assets/widget.js @@ -490,7 +490,16 @@ WSF_SLIDER_CONTROL = (function(_super) { return WSF_SLIDER_CONTROL.__super__.constructor.apply(this, arguments); } - WSF_SLIDER_CONTROL.prototype.requirements = ['assets/bootstrap.min.js']; + WSF_SLIDER_CONTROL.prototype.requirements = ['/assets/bootstrap.min.js']; + + WSF_SLIDER_CONTROL.prototype.attach_events = function() { + var id; + WSF_SLIDER_CONTROL.__super__.attach_events.apply(this, arguments); + id = "slider" + Math.round(Math.random() * 10000); + this.$el.attr("id", id); + this.$el.find("ol li").attr("data-target", "#" + id); + return this.$el.find(".carousel-control").attr("href", "#" + id); + }; return WSF_SLIDER_CONTROL; @@ -504,7 +513,7 @@ WSF_DROPDOWN_CONTROL = (function(_super) { return WSF_DROPDOWN_CONTROL.__super__.constructor.apply(this, arguments); } - WSF_DROPDOWN_CONTROL.prototype.requirements = ['assets/bootstrap.min.js']; + WSF_DROPDOWN_CONTROL.prototype.requirements = ['/assets/bootstrap.min.js']; return WSF_DROPDOWN_CONTROL; @@ -629,7 +638,7 @@ WSF_CODEVIEW_CONTROL = (function(_super) { function WSF_CODEVIEW_CONTROL() { WSF_CODEVIEW_CONTROL.__super__.constructor.apply(this, arguments); - this.initialize = lazy_load(['assets/codemirror/codemirror.js', 'assets/codemirror/codemirror.css', 'assets/codemirror/estudio.css'], lazy_load(['assets/codemirror/eiffel.js'], this.attach_events, this), this); + this.initialize = lazy_load(['/assets/codemirror/codemirror.js', '/assets/codemirror/codemirror.css', '/assets/codemirror/estudio.css'], lazy_load(['/assets/codemirror/eiffel.js'], this.attach_events, this), this); } WSF_CODEVIEW_CONTROL.prototype.attach_events = function() { @@ -1012,7 +1021,7 @@ show_alert = function(action) { return alert(action.message); }; -start_modal = lazy_load(['assets/bootstrap.min.js'], function(action) { +start_modal = lazy_load(['/assets/bootstrap.min.js'], function(action) { var cssclass, modal; cssclass = ""; if (action.type === "start_modal_big") { From 1ec14ec397535a6f0a684fd761e501b9f684fa7a Mon Sep 17 00:00:00 2001 From: YNH Webdev Date: Sun, 10 Nov 2013 13:53:20 +0100 Subject: [PATCH 08/18] Fix email validation and min and max validator --- .../wsf_js_widget/kernel/validator/wsf_email_validator.e | 2 +- .../wsf_js_widget/kernel/validator/wsf_max_validator.e | 6 +++--- .../wsf_js_widget/kernel/validator/wsf_min_validator.e | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/draft/library/wsf_js_widget/kernel/validator/wsf_email_validator.e b/draft/library/wsf_js_widget/kernel/validator/wsf_email_validator.e index f3cd93b3..64dfee02 100644 --- a/draft/library/wsf_js_widget/kernel/validator/wsf_email_validator.e +++ b/draft/library/wsf_js_widget/kernel/validator/wsf_email_validator.e @@ -19,7 +19,7 @@ feature {NONE} -- Initialization make_email_validator (e: STRING) -- Initialize with specified error message which will be displayed on validation failure do - make_regexp_validator ("^[a-zA-Z0-9._%%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,6}$", e) + make_regexp_validator ("^[a-zA-Z0-9._%%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$", e) end end diff --git a/draft/library/wsf_js_widget/kernel/validator/wsf_max_validator.e b/draft/library/wsf_js_widget/kernel/validator/wsf_max_validator.e index 2dc91970..2357f93f 100644 --- a/draft/library/wsf_js_widget/kernel/validator/wsf_max_validator.e +++ b/draft/library/wsf_js_widget/kernel/validator/wsf_max_validator.e @@ -5,11 +5,11 @@ note revision: "$Revision$" class - WSF_max_VALIDATOR [G] + WSF_MAX_VALIDATOR [G->FINITE[ANY]] inherit - WSF_VALIDATOR [LIST [G]] + WSF_VALIDATOR [G] redefine state end @@ -28,7 +28,7 @@ feature {NONE} -- Initialization feature -- Implementation - is_valid (input: LIST [G]): BOOLEAN + is_valid (input: G): BOOLEAN do Result := input.count < max or input.count = max end diff --git a/draft/library/wsf_js_widget/kernel/validator/wsf_min_validator.e b/draft/library/wsf_js_widget/kernel/validator/wsf_min_validator.e index 68d299d8..a496f500 100644 --- a/draft/library/wsf_js_widget/kernel/validator/wsf_min_validator.e +++ b/draft/library/wsf_js_widget/kernel/validator/wsf_min_validator.e @@ -5,11 +5,11 @@ note revision: "$Revision$" class - WSF_MIN_VALIDATOR [G] + WSF_MIN_VALIDATOR [G->FINITE[ANY]] inherit - WSF_VALIDATOR [LIST [G]] + WSF_VALIDATOR [G] redefine state end @@ -28,7 +28,7 @@ feature {NONE} -- Initialization feature -- Implementation - is_valid (input: LIST [G]): BOOLEAN + is_valid (input: G): BOOLEAN do Result := input.count > min or input.count = min end From eb3fb7e5f78436b8a45bc74c67085b7b6753f9f8 Mon Sep 17 00:00:00 2001 From: YNH Webdev Date: Sun, 10 Nov 2013 13:58:44 +0100 Subject: [PATCH 09/18] Update sample app --- examples/widgetapp/sample_page.e | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/widgetapp/sample_page.e b/examples/widgetapp/sample_page.e index 04d41b0c..5b6d74e6 100644 --- a/examples/widgetapp/sample_page.e +++ b/examples/widgetapp/sample_page.e @@ -61,8 +61,8 @@ feature cklist.add_control (create {WSF_CHECKBOX_CONTROL}.make ("Operating Systems", "os")) cklist.add_control (create {WSF_CHECKBOX_CONTROL}.make ("Formal Methods and Functional Programming", "fmfp")) create cats_container.make ("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 (2, "Choose at most two category")) + cats_container.add_validator (create {WSF_MIN_VALIDATOR [LIST[STRING]]}.make_min_validator (1, "Choose at least one category")) + cats_container.add_validator (create {WSF_MAX_VALIDATOR [LIST[STRING]]}.make_max_validator (2, "Choose at most two category")) form.add_control (cats_container) --Button 1 create button1.make ("Update") From 6213021f4583fb559c75f84e25c618645a79cbfe Mon Sep 17 00:00:00 2001 From: YNH Webdev Date: Sun, 10 Nov 2013 15:10:00 +0100 Subject: [PATCH 10/18] Fix form element control --- .../kernel/webcontrol/wsf_form_element_control.e | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) 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 5a9e9e2d..d99333d6 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 @@ -77,9 +77,22 @@ feature {WSF_PAGE_CONTROL, WSF_CONTROL} -- State management read_state_changes (states: WSF_JSON_OBJECT) -- Read states_changes in subcontrols + local + sub_states: WSF_JSON_OBJECT + control_state: WSF_JSON_OBJECT do Precursor (states) - value_control.read_state_changes (states) + create sub_states.make + value_control.read_state_changes (sub_states) + if sub_states.count>0 then + if attached {JSON_OBJECT}states.item (control_name) as changes then + changes.put (sub_states, "controls") + else + create control_state.make + control_state.put (sub_states, "controls") + states.put (control_state, control_name) + end + end end state: WSF_JSON_OBJECT From 72e74938423427bea35f554f54a10c344e79566f Mon Sep 17 00:00:00 2001 From: YNH Webdev Date: Sun, 10 Nov 2013 16:39:04 +0100 Subject: [PATCH 11/18] Fix event handler --- .../kernel/validator/wsf_agent_validator.e | 32 +++++++++++++++++++ .../webcontrol/wsf_form_element_control.e | 17 ++++++---- .../kernel/webcontrol/wsf_multi_control.e | 18 +++++++---- .../webcontrol/wsf_stateless_multi_control.e | 3 ++ examples/widgetapp/assets/widget.coffee | 2 ++ examples/widgetapp/assets/widget.js | 14 +++++++- 6 files changed, 71 insertions(+), 15 deletions(-) create mode 100644 draft/library/wsf_js_widget/kernel/validator/wsf_agent_validator.e diff --git a/draft/library/wsf_js_widget/kernel/validator/wsf_agent_validator.e b/draft/library/wsf_js_widget/kernel/validator/wsf_agent_validator.e new file mode 100644 index 00000000..8aa58fda --- /dev/null +++ b/draft/library/wsf_js_widget/kernel/validator/wsf_agent_validator.e @@ -0,0 +1,32 @@ +note + description: "Summary description for {WSF_AGENT_VALIDATOR}." + author: "" + date: "$Date$" + revision: "$Revision$" + +class + WSF_AGENT_VALIDATOR [G] +inherit + WSF_VALIDATOR [G] +create + make_with_agent + +feature {NONE} -- Initialization + + make_with_agent (h:like handler; e: STRING) + do + make (e) + handler := h + end + +feature + + is_valid (input: G): BOOLEAN + do + + Result := handler.item ( [input]) + end + + + handler: FUNCTION[ANY,TUPLE[G],BOOLEAN] +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 d99333d6..ee76d77a 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 @@ -84,8 +84,8 @@ feature {WSF_PAGE_CONTROL, WSF_CONTROL} -- State management Precursor (states) create sub_states.make value_control.read_state_changes (sub_states) - if sub_states.count>0 then - if attached {JSON_OBJECT}states.item (control_name) as changes then + if sub_states.count > 0 then + if attached {JSON_OBJECT} states.item (control_name) as changes then changes.put (sub_states, "controls") else create control_state.make @@ -113,16 +113,19 @@ feature {WSF_PAGE_CONTROL, WSF_CONTROL} -- State management feature -- Event handling - handle_callback (cname: LIST[STRING]; event: STRING; event_parameter: detachable STRING) + handle_callback (cname: LIST [STRING]; event: STRING; event_parameter: detachable STRING) -- Pass callback to subcontrols do - if cname[1].same_string (control_name) then + if cname [1].same_string (control_name) then cname.go_i_th (1) cname.remove - if event.same_string ("validate") then - validate + if cname.is_empty then + if event.same_string ("validate") then + validate + end + else + value_control.handle_callback (cname, event, event_parameter) end - value_control.handle_callback (cname, event, event_parameter) end end diff --git a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_multi_control.e b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_multi_control.e index 33aec384..bf5ad890 100644 --- a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_multi_control.e +++ b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_multi_control.e @@ -100,8 +100,8 @@ feature {WSF_PAGE_CONTROL, WSF_CONTROL} -- State management Precursor (states) create sub_states.make read_subcontrol_state_changes (sub_states) - if sub_states.count>0 then - if attached {JSON_OBJECT}states.item (control_name) as changes then + if sub_states.count > 0 then + if attached {JSON_OBJECT} states.item (control_name) as changes then changes.put (sub_states, "controls") else create control_state.make @@ -138,11 +138,15 @@ feature -- Event handling if equal (cname [1], control_name) then cname.go_i_th (1) cname.remove - across - controls as c - loop - if attached {WSF_CONTROL} c.item as cont then - cont.handle_callback (cname, event, event_parameter) + if not cname.is_empty then + across + controls as c + until + cname.is_empty + loop + if attached {WSF_CONTROL} c.item as cont then + cont.handle_callback (cname, event, event_parameter) + end end end end 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 8ce9321e..7dba1109 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 @@ -1,3 +1,4 @@ + note description: "Summary description for {WSF_STATELESS_MULTI_CONTROL}." author: "" @@ -80,6 +81,8 @@ feature -- Event handling do across controls as c + until + cname.is_empty loop if attached {WSF_CONTROL} c.item as cont then cont.handle_callback (cname, event, event_parameter) diff --git a/examples/widgetapp/assets/widget.coffee b/examples/widgetapp/assets/widget.coffee index 6c362ab0..0c0195dc 100644 --- a/examples/widgetapp/assets/widget.coffee +++ b/examples/widgetapp/assets/widget.coffee @@ -360,6 +360,8 @@ class WSF_INPUT_CONTROL extends WSF_CONTROL @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 update: (state) -> super diff --git a/examples/widgetapp/assets/widget.js b/examples/widgetapp/assets/widget.js index 3eb2c515..2a1ab483 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_PROGRESS_CONTROL, WSF_REGEXP_VALIDATOR, WSF_REPEATER_CONTROL, WSF_SLIDER_CONTROL, WSF_TEXTAREA_CONTROL, WSF_VALIDATOR, build_control, cache, controls, lazy_load, loaded, parseSuggestions, 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_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, 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,18 @@ WSF_INPUT_CONTROL = (function(_super) { })(WSF_CONTROL); +WSF_PASSWORD_CONTROL = (function(_super) { + + __extends(WSF_PASSWORD_CONTROL, _super); + + function WSF_PASSWORD_CONTROL() { + return WSF_PASSWORD_CONTROL.__super__.constructor.apply(this, arguments); + } + + return WSF_PASSWORD_CONTROL; + +})(WSF_INPUT_CONTROL); + WSF_NAVLIST_ITEM_CONTROL = (function(_super) { __extends(WSF_NAVLIST_ITEM_CONTROL, _super); From 40bb88a55f5578175fb4a930b77c41be0226aa8b Mon Sep 17 00:00:00 2001 From: YNH Webdev Date: Sun, 10 Nov 2013 16:53:21 +0100 Subject: [PATCH 12/18] Validate all fields and make regexp stricter --- .../wsf_js_widget/kernel/validator/wsf_regexp_validator.e | 3 ++- .../library/wsf_js_widget/kernel/webcontrol/wsf_form_control.e | 2 -- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/draft/library/wsf_js_widget/kernel/validator/wsf_regexp_validator.e b/draft/library/wsf_js_widget/kernel/validator/wsf_regexp_validator.e index 95fd6d94..ccb74c3e 100644 --- a/draft/library/wsf_js_widget/kernel/validator/wsf_regexp_validator.e +++ b/draft/library/wsf_js_widget/kernel/validator/wsf_regexp_validator.e @@ -35,7 +35,8 @@ feature -- Implementation if not regexp.is_compiled then regexp.compile (regexp_string) end - Result := regexp.matches (input) + + Result := (not input.is_empty) and regexp.matches (input) end feature -- State diff --git a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_form_control.e b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_form_control.e index 42bb258a..e30ea200 100644 --- a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_form_control.e +++ b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_form_control.e @@ -36,8 +36,6 @@ feature -- Validation is_valid := True across controls as c - until - is_valid = False loop if attached {WSF_VALIDATABLE} c.item as elem then elem.validate From f369b26d8859413489d22f849f38d39a2051ebce Mon Sep 17 00:00:00 2001 From: YNH Webdev Date: Sun, 10 Nov 2013 17:22:28 +0100 Subject: [PATCH 13/18] Rename validators, Make forms resizable --- .../kernel/validator/wsf_agent_validator.e | 17 +++++++----- .../kernel/validator/wsf_decimal_validator.e | 7 +++-- .../kernel/validator/wsf_email_validator.e | 7 +++-- .../kernel/validator/wsf_max_validator.e | 10 ++++--- .../kernel/validator/wsf_min_validator.e | 10 ++++--- .../validator/wsf_phone_number_validator.e | 3 +++ .../kernel/validator/wsf_regexp_validator.e | 8 +++--- .../kernel/webcontrol/wsf_form_control.e | 26 +++++++++++++++++-- .../webcontrol/wsf_form_element_control.e | 13 ++++++++-- examples/widgetapp/assets/widget.coffee | 4 +-- examples/widgetapp/assets/widget.js | 2 +- examples/widgetapp/sample_page.e | 8 +++--- 12 files changed, 83 insertions(+), 32 deletions(-) diff --git a/draft/library/wsf_js_widget/kernel/validator/wsf_agent_validator.e b/draft/library/wsf_js_widget/kernel/validator/wsf_agent_validator.e index 8aa58fda..779b4fd4 100644 --- a/draft/library/wsf_js_widget/kernel/validator/wsf_agent_validator.e +++ b/draft/library/wsf_js_widget/kernel/validator/wsf_agent_validator.e @@ -6,16 +6,22 @@ note class WSF_AGENT_VALIDATOR [G] + inherit + WSF_VALIDATOR [G] + rename + make as make_validator + end + create - make_with_agent + make feature {NONE} -- Initialization - make_with_agent (h:like handler; e: STRING) + make (h: like handler; e: STRING) do - make (e) + make_validator (e) handler := h end @@ -23,10 +29,9 @@ feature is_valid (input: G): BOOLEAN do - - Result := handler.item ( [input]) + Result := handler.item ([input]) end + handler: FUNCTION [ANY, TUPLE [G], BOOLEAN] - handler: FUNCTION[ANY,TUPLE[G],BOOLEAN] end diff --git a/draft/library/wsf_js_widget/kernel/validator/wsf_decimal_validator.e b/draft/library/wsf_js_widget/kernel/validator/wsf_decimal_validator.e index 5c7f2939..bfb3fcd7 100644 --- a/draft/library/wsf_js_widget/kernel/validator/wsf_decimal_validator.e +++ b/draft/library/wsf_js_widget/kernel/validator/wsf_decimal_validator.e @@ -10,13 +10,16 @@ class inherit WSF_REGEXP_VALIDATOR + rename + make as make_regexp_validator + end create - make_decimal_validator + make feature {NONE} -- Initialization - make_decimal_validator (e: STRING) + make (e: STRING) -- Initialize with specified error message which will be displayed on validation failure do make_regexp_validator ("^[0-9]+(\.[0-9]*)?$|^\.[0-9]+$", e) diff --git a/draft/library/wsf_js_widget/kernel/validator/wsf_email_validator.e b/draft/library/wsf_js_widget/kernel/validator/wsf_email_validator.e index 64dfee02..e5b64f41 100644 --- a/draft/library/wsf_js_widget/kernel/validator/wsf_email_validator.e +++ b/draft/library/wsf_js_widget/kernel/validator/wsf_email_validator.e @@ -10,13 +10,16 @@ class inherit WSF_REGEXP_VALIDATOR + rename + make as make_regexp_validator + end create - make_email_validator + make feature {NONE} -- Initialization - make_email_validator (e: STRING) + make (e: STRING) -- Initialize with specified error message which will be displayed on validation failure do make_regexp_validator ("^[a-zA-Z0-9._%%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$", e) diff --git a/draft/library/wsf_js_widget/kernel/validator/wsf_max_validator.e b/draft/library/wsf_js_widget/kernel/validator/wsf_max_validator.e index 2357f93f..ad472e1b 100644 --- a/draft/library/wsf_js_widget/kernel/validator/wsf_max_validator.e +++ b/draft/library/wsf_js_widget/kernel/validator/wsf_max_validator.e @@ -5,24 +5,26 @@ note revision: "$Revision$" class - WSF_MAX_VALIDATOR [G->FINITE[ANY]] + WSF_MAX_VALIDATOR [G -> FINITE [ANY]] inherit WSF_VALIDATOR [G] + rename + make as make_validator redefine state end create - make_max_validator + make feature {NONE} -- Initialization - make_max_validator (m: INTEGER; e: STRING) + make (m: INTEGER; e: STRING) -- Initialize with specified maximum and error message which will be displayed on validation failure do - make (e) + make_validator (e) max := m end diff --git a/draft/library/wsf_js_widget/kernel/validator/wsf_min_validator.e b/draft/library/wsf_js_widget/kernel/validator/wsf_min_validator.e index a496f500..1175c147 100644 --- a/draft/library/wsf_js_widget/kernel/validator/wsf_min_validator.e +++ b/draft/library/wsf_js_widget/kernel/validator/wsf_min_validator.e @@ -5,24 +5,26 @@ note revision: "$Revision$" class - WSF_MIN_VALIDATOR [G->FINITE[ANY]] + WSF_MIN_VALIDATOR [G -> FINITE [ANY]] inherit WSF_VALIDATOR [G] + rename + make as make_validator redefine state end create - make_min_validator + make feature {NONE} -- Initialization - make_min_validator (m: INTEGER; e: STRING) + make (m: INTEGER; e: STRING) -- Initialize with specified minimum and error message which will be displayed on validation failure do - make (e) + make_validator (e) min := m end diff --git a/draft/library/wsf_js_widget/kernel/validator/wsf_phone_number_validator.e b/draft/library/wsf_js_widget/kernel/validator/wsf_phone_number_validator.e index e5ca0cc4..3f377d12 100644 --- a/draft/library/wsf_js_widget/kernel/validator/wsf_phone_number_validator.e +++ b/draft/library/wsf_js_widget/kernel/validator/wsf_phone_number_validator.e @@ -10,6 +10,9 @@ class inherit WSF_REGEXP_VALIDATOR + rename + make as make_regexp_validator + end create make_with_message diff --git a/draft/library/wsf_js_widget/kernel/validator/wsf_regexp_validator.e b/draft/library/wsf_js_widget/kernel/validator/wsf_regexp_validator.e index ccb74c3e..0914acd3 100644 --- a/draft/library/wsf_js_widget/kernel/validator/wsf_regexp_validator.e +++ b/draft/library/wsf_js_widget/kernel/validator/wsf_regexp_validator.e @@ -10,19 +10,21 @@ class inherit WSF_VALIDATOR [STRING] + rename + make as make_validator redefine state end create - make_regexp_validator + make feature {NONE} -- Initialization - make_regexp_validator (r, e: STRING) + make (r, e: STRING) -- Initialize with specified regular expression and error message which will be displayed on validation failure do - make (e) + make_validator (e) regexp_string := r create regexp end diff --git a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_form_control.e b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_form_control.e index e30ea200..81fc8796 100644 --- a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_form_control.e +++ b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_form_control.e @@ -9,23 +9,41 @@ class inherit - WSF_STATELESS_MULTI_CONTROL [WSF_CONTROL] + WSF_STATELESS_MULTI_CONTROL [WSF_STATELESS_CONTROL] rename make as make_multi_control + redefine + add_control end WSF_VALIDATABLE create - make + make, make_with_label_width feature {NONE} -- Initialization make -- Initialize + do + make_with_label_width (2) + end + + make_with_label_width (w: INTEGER) do make_multi_control tag_name := "form" + label_width := w + end + +feature + + add_control (c: WSF_STATELESS_CONTROL) + do + Precursor (c) + if attached {WSF_FORM_ELEMENT_CONTROL[ANY]} c as fec then + fec.set_label_width (label_width) + end end feature -- Validation @@ -49,4 +67,8 @@ feature -- Validation is_valid: BOOLEAN -- Tells whether the last validation was valid +feature + + label_width: INTEGER + 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 ee76d77a..e4b860b6 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 @@ -48,6 +48,13 @@ feature {NONE} -- Initialization error := "" end +feature + + set_label_width (w: INTEGER) + do + label_width := w + end + feature {WSF_PAGE_CONTROL, WSF_CONTROL} -- State management load_state (new_states: JSON_OBJECT) @@ -138,9 +145,9 @@ feature -- Implementation do body := "" if not label.is_empty then - body.append ("") + body.append ("") end - body.append ("
") + body.append ("
") body.append (value_control.render) body.append ("
") Result := render_tag (body, "") @@ -200,4 +207,6 @@ feature -- Properties error: STRING -- The error message that is displayed when client side validation fails + label_width: INTEGER + end diff --git a/examples/widgetapp/assets/widget.coffee b/examples/widgetapp/assets/widget.coffee index 0c0195dc..289bab4d 100644 --- a/examples/widgetapp/assets/widget.coffee +++ b/examples/widgetapp/assets/widget.coffee @@ -359,7 +359,7 @@ class WSF_INPUT_CONTROL extends WSF_CONTROL 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 @@ -489,7 +489,7 @@ class WSF_FORM_ELEMENT_CONTROL extends WSF_CONTROL if message.length>0 @$el.addClass("has-error") errordiv = $("
").addClass('help-block').addClass('validation').text(message) - @$el.find(".col-lg-10").append(errordiv) + @$el.children("div").append(errordiv) update: (state) -> if state.error? diff --git a/examples/widgetapp/assets/widget.js b/examples/widgetapp/assets/widget.js index 2a1ab483..abfe580e 100644 --- a/examples/widgetapp/assets/widget.js +++ b/examples/widgetapp/assets/widget.js @@ -817,7 +817,7 @@ WSF_FORM_ELEMENT_CONTROL = (function(_super) { if (message.length > 0) { this.$el.addClass("has-error"); errordiv = $("
").addClass('help-block').addClass('validation').text(message); - return this.$el.find(".col-lg-10").append(errordiv); + return this.$el.children("div").append(errordiv); } }; diff --git a/examples/widgetapp/sample_page.e b/examples/widgetapp/sample_page.e index 5b6d74e6..c7b70f15 100644 --- a/examples/widgetapp/sample_page.e +++ b/examples/widgetapp/sample_page.e @@ -35,13 +35,13 @@ feature --Number 1 create textbox1.make ("1") create n1_container.make ("Number1", textbox1) - n1_container.add_validator (create {WSF_DECIMAL_VALIDATOR}.make_decimal_validator ("Invalid Number")) + n1_container.add_validator (create {WSF_DECIMAL_VALIDATOR}.make ("Invalid Number")) n1_container.add_validator (create {OWN_VALIDATOR}.make_own) form.add_control (n1_container) --Number 2 create textbox2.make ("2") create n2_container.make ("Number2", textbox2) - n2_container.add_validator (create {WSF_DECIMAL_VALIDATOR}.make_decimal_validator ("Invalid Number")) + n2_container.add_validator (create {WSF_DECIMAL_VALIDATOR}.make ("Invalid Number")) form.add_control (n2_container) --Flag autocomplete create autocompletion1.make (create {FLAG_AUTOCOMPLETION}.make) @@ -61,8 +61,8 @@ feature cklist.add_control (create {WSF_CHECKBOX_CONTROL}.make ("Operating Systems", "os")) cklist.add_control (create {WSF_CHECKBOX_CONTROL}.make ("Formal Methods and Functional Programming", "fmfp")) create cats_container.make ("Categories", cklist) - cats_container.add_validator (create {WSF_MIN_VALIDATOR [LIST[STRING]]}.make_min_validator (1, "Choose at least one category")) - cats_container.add_validator (create {WSF_MAX_VALIDATOR [LIST[STRING]]}.make_max_validator (2, "Choose at most two category")) + cats_container.add_validator (create {WSF_MIN_VALIDATOR [LIST[STRING]]}.make (1, "Choose at least one category")) + cats_container.add_validator (create {WSF_MAX_VALIDATOR [LIST[STRING]]}.make (2, "Choose at most two category")) form.add_control (cats_container) --Button 1 create button1.make ("Update") From 51c4e8ab9e3c227b4f565600ad6aa9bddb514ec5 Mon Sep 17 00:00:00 2001 From: YNH Webdev Date: Mon, 11 Nov 2013 08:28:08 +0100 Subject: [PATCH 14/18] Rename files --- .../navlist/{wsf_navlist_item.e => wsf_navlist_item_control.e} | 0 .../slider/{wsf_image_slider_control.e => wsf_slider_control.e} | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename draft/library/wsf_js_widget/kernel/navlist/{wsf_navlist_item.e => wsf_navlist_item_control.e} (100%) rename draft/library/wsf_js_widget/kernel/slider/{wsf_image_slider_control.e => wsf_slider_control.e} (100%) diff --git a/draft/library/wsf_js_widget/kernel/navlist/wsf_navlist_item.e b/draft/library/wsf_js_widget/kernel/navlist/wsf_navlist_item_control.e similarity index 100% rename from draft/library/wsf_js_widget/kernel/navlist/wsf_navlist_item.e rename to draft/library/wsf_js_widget/kernel/navlist/wsf_navlist_item_control.e diff --git a/draft/library/wsf_js_widget/kernel/slider/wsf_image_slider_control.e b/draft/library/wsf_js_widget/kernel/slider/wsf_slider_control.e similarity index 100% rename from draft/library/wsf_js_widget/kernel/slider/wsf_image_slider_control.e rename to draft/library/wsf_js_widget/kernel/slider/wsf_slider_control.e From 7a5d1e378dbf232932c564508fc837876c64f923 Mon Sep 17 00:00:00 2001 From: YNH Webdev Date: Tue, 31 Dec 2013 12:10:05 +0100 Subject: [PATCH 15/18] Fix dropdown list, clean up actions --- .../kernel/dropdown/wsf_dropdown_control.e | 2 +- .../kernel/webcontrol/wsf_control.e | 35 ++++++++++--------- examples/widgetapp/assets/widget.coffee | 8 +++-- examples/widgetapp/assets/widget.js | 12 ++++--- examples/widgetapp/base_page.e | 2 +- examples/widgetapp/sample_page.e | 7 +++- 6 files changed, 40 insertions(+), 26 deletions(-) diff --git a/draft/library/wsf_js_widget/kernel/dropdown/wsf_dropdown_control.e b/draft/library/wsf_js_widget/kernel/dropdown/wsf_dropdown_control.e index 3693c02a..c7001da8 100644 --- a/draft/library/wsf_js_widget/kernel/dropdown/wsf_dropdown_control.e +++ b/draft/library/wsf_js_widget/kernel/dropdown/wsf_dropdown_control.e @@ -9,7 +9,7 @@ class inherit - WSF_STATELESS_MULTI_CONTROL [WSF_STATELESS_CONTROL] + WSF_MULTI_CONTROL [WSF_STATELESS_CONTROL] rename make as make_multi_control, make_with_tag_name as make_multi_control_with_tag_name 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 c65d7d9b..c7fffb10 100644 --- a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_control.e +++ b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_control.e @@ -33,38 +33,41 @@ feature {NONE} -- Initialization feature -- Actions - start_modal (url: STRING; title: STRING) + start_modal (url: STRING; title: STRING; big: BOOLEAN) --Start a modal window containg an other or the same page local modal: WSF_JSON_OBJECT do create modal.make - modal.put_string ("start_modal", "type") + if big then + modal.put_string ("start_modal_big", "type") + else + modal.put_string ("start_modal", "type") + end modal.put_string (url, "url") modal.put_string (title, "title") actions.add (modal) end - start_modal_big (url: STRING; title: STRING) - --Start a modal window containg an other or the same page - local - modal: WSF_JSON_OBJECT - do - create modal.make - modal.put_string ("start_modal_big", "type") - modal.put_string (url, "url") - modal.put_string (title, "title") - actions.add (modal) - end - - show_alert (mesage: STRING) + show_alert (message: STRING) --Start a modal window containg an other or the same page local modal: WSF_JSON_OBJECT do create modal.make modal.put_string ("show_alert", "type") - modal.put_string (mesage, "message") + modal.put_string (message, "message") + actions.add (modal) + end + + redirect (url: STRING) + --Redirect to an other page + local + modal: WSF_JSON_OBJECT + do + create modal.make + modal.put_string ("redirect", "type") + modal.put_string (url, "url") actions.add (modal) end diff --git a/examples/widgetapp/assets/widget.coffee b/examples/widgetapp/assets/widget.coffee index 289bab4d..aed793aa 100644 --- a/examples/widgetapp/assets/widget.coffee +++ b/examples/widgetapp/assets/widget.coffee @@ -79,6 +79,7 @@ parseSuggestions = (data)-> return d return null loaded = {} + lazy_load = (requirements,fn,that)-> if requirements.length == 0 return ()-> @@ -249,8 +250,6 @@ class WSF_CONTROL cache: no .done (new_states)-> #Update all classes - if new_states.actions? - self.process_actions(new_states.actions) self.get_page().process_update(new_states) #Simple event listener @@ -290,13 +289,14 @@ class WSF_PAGE_CONTROL extends WSF_CONTROL @load_subcontrols() process_update: (new_states)-> + if new_states.actions? + @process_actions(new_states.actions) for control in @controls if control? control.process_update(new_states) return - get_full_control_name: ()-> "" @@ -599,6 +599,8 @@ class WSF_REPEATER_CONTROL extends WSF_CONTROL #### actions +redirect = (action) -> + document.location.href = action.url show_alert = (action)-> alert(action.message) diff --git a/examples/widgetapp/assets/widget.js b/examples/widgetapp/assets/widget.js index abfe580e..a4215d29 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, 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_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; }; @@ -394,9 +394,6 @@ WSF_CONTROL = (function() { contentType: 'application/json', cache: false }).done(function(new_states) { - if (new_states.actions != null) { - self.process_actions(new_states.actions); - } return self.get_page().process_update(new_states); }); }; @@ -456,6 +453,9 @@ WSF_PAGE_CONTROL = (function(_super) { WSF_PAGE_CONTROL.prototype.process_update = function(new_states) { var control, _i, _len, _ref; + if (new_states.actions != null) { + this.process_actions(new_states.actions); + } _ref = this.controls; for (_i = 0, _len = _ref.length; _i < _len; _i++) { control = _ref[_i]; @@ -1029,6 +1029,10 @@ WSF_REPEATER_CONTROL = (function(_super) { })(WSF_CONTROL); +redirect = function(action) { + return document.location.href = action.url; +}; + show_alert = function(action) { return alert(action.message); }; diff --git a/examples/widgetapp/base_page.e b/examples/widgetapp/base_page.e index 6602a52e..7e05d5d1 100644 --- a/examples/widgetapp/base_page.e +++ b/examples/widgetapp/base_page.e @@ -46,7 +46,7 @@ feature show_code do - start_modal_big ("/codeview?file=" + generator.as_lower, "Eiffel code " + generator) + start_modal ("/codeview?file=" + generator.as_lower, "Eiffel code " + generator, true) end feature diff --git a/examples/widgetapp/sample_page.e b/examples/widgetapp/sample_page.e index c7b70f15..9015dc24 100644 --- a/examples/widgetapp/sample_page.e +++ b/examples/widgetapp/sample_page.e @@ -71,7 +71,7 @@ feature form.add_control (button1) --Button 2 create button2.make ("Start Modal Grid") - button2.set_click_event (agent handle_click) + button2.set_click_event (agent run_modal) form.add_control (button2) --Result create result_html.make ("p", "") @@ -109,6 +109,11 @@ feature end end + run_modal + do + start_modal("/","Test Modal", true); + end + process do end From 1ae44e74e79864b6780a9d94cfa2b5ac1cf62709 Mon Sep 17 00:00:00 2001 From: YNH Webdev Date: Tue, 31 Dec 2013 16:03:24 +0100 Subject: [PATCH 16/18] 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 From b39dd5c40d84750e0cc26dad5d73644ea5322861 Mon Sep 17 00:00:00 2001 From: YNH Webdev Date: Tue, 31 Dec 2013 21:25:01 +0100 Subject: [PATCH 17/18] Change parameter type --- .../kernel/grid/wsf_pagination_control.e | 4 +- .../kernel/input/wsf_autocomplete_control.e | 2 +- .../kernel/input/wsf_checkbox_control.e | 2 +- .../kernel/input/wsf_file_control.e | 13 +++- .../kernel/input/wsf_input_control.e | 2 +- .../kernel/progressbar/wsf_progress_control.e | 2 +- .../kernel/slider/wsf_slider_control.e | 2 +- .../kernel/webcontrol/wsf_button_control.e | 2 +- .../kernel/webcontrol/wsf_control.e | 12 ++-- .../webcontrol/wsf_form_element_control.e | 2 +- .../kernel/webcontrol/wsf_html_control.e | 2 +- .../kernel/webcontrol/wsf_multi_control.e | 2 +- .../kernel/webcontrol/wsf_page_control.e | 9 ++- .../webcontrol/wsf_stateless_multi_control.e | 2 +- examples/widgetapp/assets/widget.coffee | 58 ++++++++++++++-- examples/widgetapp/assets/widget.js | 67 +++++++++++++++++-- examples/widgetapp/sample_page.e | 1 + 17 files changed, 153 insertions(+), 31 deletions(-) diff --git a/draft/library/wsf_js_widget/kernel/grid/wsf_pagination_control.e b/draft/library/wsf_js_widget/kernel/grid/wsf_pagination_control.e index 1e377627..df09e443 100644 --- a/draft/library/wsf_js_widget/kernel/grid/wsf_pagination_control.e +++ b/draft/library/wsf_js_widget/kernel/grid/wsf_pagination_control.e @@ -48,7 +48,7 @@ feature {WSF_PAGE_CONTROL, WSF_CONTROL} -- State management feature --Event handling - handle_callback (cname: LIST[STRING]; event: STRING; event_parameter: detachable STRING) + handle_callback (cname: LIST[STRING]; event: STRING; event_parameter: detachable ANY) -- Handle goto/next/prev events do if Current.control_name.same_string (cname[1]) then @@ -57,7 +57,7 @@ feature --Event handling elseif event.same_string ("prev") then datasource.set_page (datasource.page - 1) elseif event.same_string ("goto") then - if attached event_parameter as p and then attached p.to_integer as i then + if attached {STRING}event_parameter as p and then attached p.to_integer as i then datasource.set_page (i) end end diff --git a/draft/library/wsf_js_widget/kernel/input/wsf_autocomplete_control.e b/draft/library/wsf_js_widget/kernel/input/wsf_autocomplete_control.e index f484947c..ae9de051 100644 --- a/draft/library/wsf_js_widget/kernel/input/wsf_autocomplete_control.e +++ b/draft/library/wsf_js_widget/kernel/input/wsf_autocomplete_control.e @@ -49,7 +49,7 @@ feature -- State feature -- Callback - handle_callback (cname: LIST[STRING]; event: STRING; event_parameter: detachable STRING) + handle_callback (cname: LIST[STRING]; event: STRING; event_parameter: detachable ANY) do Precursor {WSF_INPUT_CONTROL} (cname, event, event_parameter) if cname[1].same_string (control_name) and event.same_string ("autocomplete") then diff --git a/draft/library/wsf_js_widget/kernel/input/wsf_checkbox_control.e b/draft/library/wsf_js_widget/kernel/input/wsf_checkbox_control.e index 6afa3e6f..dbb35c61 100644 --- a/draft/library/wsf_js_widget/kernel/input/wsf_checkbox_control.e +++ b/draft/library/wsf_js_widget/kernel/input/wsf_checkbox_control.e @@ -54,7 +54,7 @@ feature --Event handling change_event := e end - handle_callback (cname: LIST[STRING]; event: STRING; event_parameter: detachable STRING) + handle_callback (cname: LIST[STRING]; event: STRING; event_parameter: detachable ANY) do if Current.control_name.same_string (cname[1]) and attached change_event as cevent then if event.same_string ("change") then 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 index 4d2449c4..c1bef063 100644 --- a/draft/library/wsf_js_widget/kernel/input/wsf_file_control.e +++ b/draft/library/wsf_js_widget/kernel/input/wsf_file_control.e @@ -49,7 +49,7 @@ feature --Event handling change_event := e end - handle_callback (cname: LIST [STRING]; event: STRING; event_parameter: detachable STRING) + handle_callback (cname: LIST [STRING]; event: STRING; event_parameter: detachable ANY) do if Current.control_name.same_string (cname [1]) and attached change_event as cevent then if event.same_string ("change") then @@ -58,6 +58,17 @@ feature --Event handling end end +feature -- Upload + + start_upload + local + upload: WSF_JSON_OBJECT + do + create upload.make + upload.put_string ("start_upload", "type") + actions.add (upload) + end + feature -- Implementation value: detachable WSF_PENDING_FILE diff --git a/draft/library/wsf_js_widget/kernel/input/wsf_input_control.e b/draft/library/wsf_js_widget/kernel/input/wsf_input_control.e index e0511bb0..d243bd7d 100644 --- a/draft/library/wsf_js_widget/kernel/input/wsf_input_control.e +++ b/draft/library/wsf_js_widget/kernel/input/wsf_input_control.e @@ -53,7 +53,7 @@ feature --Event handling change_event := e end - handle_callback (cname: LIST[STRING]; event: STRING; event_parameter: detachable STRING) + handle_callback (cname: LIST[STRING]; event: STRING; event_parameter: detachable ANY) do if Current.control_name.same_string (cname[1]) and attached change_event as cevent then if event.same_string ("change") then diff --git a/draft/library/wsf_js_widget/kernel/progressbar/wsf_progress_control.e b/draft/library/wsf_js_widget/kernel/progressbar/wsf_progress_control.e index 2f772db6..07113ecf 100644 --- a/draft/library/wsf_js_widget/kernel/progressbar/wsf_progress_control.e +++ b/draft/library/wsf_js_widget/kernel/progressbar/wsf_progress_control.e @@ -51,7 +51,7 @@ feature -- State handling feature -- Event handling - handle_callback (cname: LIST[STRING]; event: STRING; event_parameter: detachable STRING) + handle_callback (cname: LIST[STRING]; event: STRING; event_parameter: detachable ANY) do if cname[1].same_string (control_name) and event.same_string ("progress_fetch") then state_changes.put_integer (progress_value, "progress") diff --git a/draft/library/wsf_js_widget/kernel/slider/wsf_slider_control.e b/draft/library/wsf_js_widget/kernel/slider/wsf_slider_control.e index 0e5263e1..c952977c 100644 --- a/draft/library/wsf_js_widget/kernel/slider/wsf_slider_control.e +++ b/draft/library/wsf_js_widget/kernel/slider/wsf_slider_control.e @@ -43,7 +43,7 @@ feature -- State handling feature -- Callback - handle_callback (cname: LIST[STRING]; event: STRING; event_parameter: detachable STRING) + handle_callback (cname: LIST[STRING]; event: STRING; event_parameter: detachable ANY) do -- Do nothing here end diff --git a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_button_control.e b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_button_control.e index dd06596f..3b49767e 100644 --- a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_button_control.e +++ b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_button_control.e @@ -54,7 +54,7 @@ feature --Event handling click_event := e end - handle_callback (cname: LIST[STRING]; event: STRING; event_parameter: detachable STRING) + handle_callback (cname: LIST[STRING]; event: STRING; event_parameter: detachable ANY) do if Current.control_name.same_string (cname[1]) and attached click_event as cevent then cevent.call (Void) 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 c7fffb10..102d8b5e 100644 --- a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_control.e +++ b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_control.e @@ -52,12 +52,12 @@ feature -- Actions show_alert (message: STRING) --Start a modal window containg an other or the same page local - modal: WSF_JSON_OBJECT + alert: WSF_JSON_OBJECT do - create modal.make - modal.put_string ("show_alert", "type") - modal.put_string (message, "message") - actions.add (modal) + create alert.make + alert.put_string ("show_alert", "type") + alert.put_string (message, "message") + actions.add (alert) end redirect (url: STRING) @@ -154,7 +154,7 @@ feature -- Rendering feature -- Event handling - handle_callback (cname: LIST [STRING]; event: STRING; event_parameter: detachable STRING) + handle_callback (cname: LIST [STRING]; event: STRING; event_parameter: detachable ANY) -- Method called if any callback received. In this method you can route the callback to the event handler deferred 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 acd49e18..1c759e94 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 @@ -121,7 +121,7 @@ feature {WSF_PAGE_CONTROL, WSF_CONTROL} -- State management feature -- Event handling - handle_callback (cname: LIST [STRING]; event: STRING; event_parameter: detachable STRING) + handle_callback (cname: LIST [STRING]; event: STRING; event_parameter: detachable ANY) -- Pass callback to subcontrols do if cname [1].same_string (control_name) then diff --git a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_html_control.e b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_html_control.e index 11335fd4..59998e00 100644 --- a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_html_control.e +++ b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_html_control.e @@ -43,7 +43,7 @@ feature {WSF_PAGE_CONTROL, WSF_CONTROL} -- State management feature --Event handling - handle_callback (cname: LIST[STRING]; event: STRING; event_parameter: detachable STRING) + handle_callback (cname: LIST[STRING]; event: STRING; event_parameter: detachable ANY) do end diff --git a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_multi_control.e b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_multi_control.e index bf5ad890..44da1df7 100644 --- a/draft/library/wsf_js_widget/kernel/webcontrol/wsf_multi_control.e +++ b/draft/library/wsf_js_widget/kernel/webcontrol/wsf_multi_control.e @@ -132,7 +132,7 @@ feature {WSF_PAGE_CONTROL, WSF_CONTROL} -- State management feature -- Event handling - handle_callback (cname: LIST [STRING]; event: STRING; event_parameter: detachable STRING) + handle_callback (cname: LIST [STRING]; event: STRING; event_parameter: detachable ANY) -- Pass callback to subcontrols do if equal (cname [1], control_name) then 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 e4848ca9..9ec447df 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 @@ -59,7 +59,7 @@ feature -- Implementation -- If request is not a callback. Run process and render the html page local event: detachable STRING - event_parameter: detachable STRING + event_parameter: detachable ANY event_control_name: detachable STRING states: STRING states_changes: WSF_JSON_OBJECT @@ -74,6 +74,11 @@ feature -- Implementation create json_parser.make_parser (states) if attached {JSON_OBJECT} json_parser.parse_json as sp then set_state (sp) + else + if attached request.form_parameter ("file") as o then + response.put_string (o.name) + end + end handle_callback (event_control_name.split ('-'), event, event_parameter) create states_changes.make @@ -147,7 +152,7 @@ feature -- Implementation feature -- Event handling - handle_callback (cname: LIST[STRING]; event: STRING; event_parameter: detachable STRING) + handle_callback (cname: LIST[STRING]; event: STRING; event_parameter: detachable ANY) -- Forward callback to control do control.handle_callback (cname, event, event_parameter) 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 7dba1109..9e3579cd 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 @@ -76,7 +76,7 @@ feature end feature -- Event handling - handle_callback (cname: LIST [STRING]; event: STRING; event_parameter: detachable STRING) + handle_callback (cname: LIST [STRING]; event: STRING; event_parameter: detachable ANY) -- Pass callback to subcontrols do across diff --git a/examples/widgetapp/assets/widget.coffee b/examples/widgetapp/assets/widget.coffee index 2bbb9686..6ee695ff 100644 --- a/examples/widgetapp/assets/widget.coffee +++ b/examples/widgetapp/assets/widget.coffee @@ -180,13 +180,21 @@ class WSF_CONTROL process_actions: (actions)-> for action in actions try - fn = eval(action.type) - fn(action) + fn = null + #Check if action exists in class then check global + if @[action.type]? + fn = @[action.type] + fn.call(@, action) + else + fn = eval(action.type) + fn(action) catch e console.log "Failed preforming action #{action.type}" process_update: (new_states)-> try + if new_states.actions? + @process_actions(new_states.actions) if new_states[@control_name]? @update(new_states[@control_name]) for control in @controls @@ -289,8 +297,6 @@ class WSF_PAGE_CONTROL extends WSF_CONTROL @load_subcontrols() process_update: (new_states)-> - if new_states.actions? - @process_actions(new_states.actions) for control in @controls if control? control.process_update(new_states) @@ -361,6 +367,50 @@ class WSF_INPUT_CONTROL extends WSF_CONTROL @$el.val(state.text) class WSF_FILE_CONTROL extends WSF_CONTROL + constructor: ()-> + super + @uploading = false + start_upload: ()-> + if @uploading + return + @uploading = true + @$el.hide() + @progressbar = $ """
""" + @$el.parent().append(@progressbar) + + formData = new FormData(); + action = @callback_url + control_name: @control_name + event: "uploadfile" + event_parameter: "" + file = @$el[0].files[0]; + formData.append('our-file', file) + formData.append('state', JSON.stringify(@get_context_state())) + @sendXHRequest(formData, action) + + sendXHRequest: (formData, uri)-> + #Get an XMLHttpRequest instance + xhr = new XMLHttpRequest(); + self = @ + onprogressHandler = (evt)-> + percent = evt.loaded/evt.total*100 + self.progressbar.find('.progress-bar').css {'width':percent+"%"} + onloadHandler = (evt)-> + alert "DONE" + xhr.upload.addEventListener('progress', onprogressHandler, false); + xhr.upload.addEventListener('load', onloadHandler, false); + + ###Set up events + xhr.upload.addEventListener('loadstart', onloadstartHandler, false); + + + xhr.addEventListener('readystatechange', onreadystatechangeHandler, false); + ### + #Set up request + xhr.open('POST', uri, true); + #Fire! + xhr.send(formData); + attach_events: ()-> super self = @ diff --git a/examples/widgetapp/assets/widget.js b/examples/widgetapp/assets/widget.js index 03cbe912..8894892e 100644 --- a/examples/widgetapp/assets/widget.js +++ b/examples/widgetapp/assets/widget.js @@ -298,8 +298,14 @@ WSF_CONTROL = (function() { for (_i = 0, _len = actions.length; _i < _len; _i++) { action = actions[_i]; try { - fn = eval(action.type); - _results.push(fn(action)); + fn = null; + if (this[action.type] != null) { + fn = this[action.type]; + _results.push(fn.call(this, action)); + } else { + fn = eval(action.type); + _results.push(fn(action)); + } } catch (e) { _results.push(console.log("Failed preforming action " + action.type)); } @@ -310,6 +316,9 @@ WSF_CONTROL = (function() { WSF_CONTROL.prototype.process_update = function(new_states) { var control, _i, _len, _ref; try { + if (new_states.actions != null) { + this.process_actions(new_states.actions); + } if (new_states[this.control_name] != null) { this.update(new_states[this.control_name]); _ref = this.controls; @@ -453,9 +462,6 @@ WSF_PAGE_CONTROL = (function(_super) { WSF_PAGE_CONTROL.prototype.process_update = function(new_states) { var control, _i, _len, _ref; - if (new_states.actions != null) { - this.process_actions(new_states.actions); - } _ref = this.controls; for (_i = 0, _len = _ref.length; _i < _len; _i++) { control = _ref[_i]; @@ -601,9 +607,58 @@ 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.__super__.constructor.apply(this, arguments); + this.uploading = false; } + WSF_FILE_CONTROL.prototype.start_upload = function() { + var action, file, formData; + if (this.uploading) { + return; + } + this.uploading = true; + this.$el.hide(); + this.progressbar = $("
"); + this.$el.parent().append(this.progressbar); + formData = new FormData(); + action = this.callback_url({ + control_name: this.control_name, + event: "uploadfile", + event_parameter: "" + }); + file = this.$el[0].files[0]; + formData.append('our-file', file); + formData.append('state', JSON.stringify(this.get_context_state())); + return this.sendXHRequest(formData, action); + }; + + WSF_FILE_CONTROL.prototype.sendXHRequest = function(formData, uri) { + var onloadHandler, onprogressHandler, self, xhr; + xhr = new XMLHttpRequest(); + self = this; + onprogressHandler = function(evt) { + var percent; + percent = evt.loaded / evt.total * 100; + return self.progressbar.find('.progress-bar').css({ + 'width': percent + "%" + }); + }; + onloadHandler = function(evt) { + return alert("DONE"); + }; + xhr.upload.addEventListener('progress', onprogressHandler, false); + xhr.upload.addEventListener('load', onloadHandler, false); + /*Set up events + xhr.upload.addEventListener('loadstart', onloadstartHandler, false); + + + xhr.addEventListener('readystatechange', onreadystatechangeHandler, false); + */ + + xhr.open('POST', uri, true); + return xhr.send(formData); + }; + WSF_FILE_CONTROL.prototype.attach_events = function() { var self; WSF_FILE_CONTROL.__super__.attach_events.apply(this, arguments); diff --git a/examples/widgetapp/sample_page.e b/examples/widgetapp/sample_page.e index 688995cb..18ac3f7d 100644 --- a/examples/widgetapp/sample_page.e +++ b/examples/widgetapp/sample_page.e @@ -100,6 +100,7 @@ feature do form.validate if form.is_valid then + filebox.start_upload --progress.set_progress ((textbox1.text.to_integer_64 / textbox2.text.to_integer_64 * 100).ceiling) text := textbox1.text + " + " + textbox2.text + " = " + (textbox1.text.to_integer_64 + textbox2.text.to_integer_64).out text.append ("
    ") From 29356c0b618c8159ff43bbb44135bbee9e6620e4 Mon Sep 17 00:00:00 2001 From: YNH Webdev Date: Wed, 1 Jan 2014 01:35:43 +0100 Subject: [PATCH 18/18] Workin file upload --- .../kernel/input/wsf_file_control.e | 35 ++++++++++++++-- .../kernel/webcontrol/wsf_page_control.e | 34 ++++++++------- examples/widgetapp/assets/widget.coffee | 31 +++++++------- examples/widgetapp/assets/widget.css | 5 +++ examples/widgetapp/assets/widget.js | 30 ++++++-------- examples/widgetapp/sample_page.e | 41 +++++++++++++++---- 6 files changed, 116 insertions(+), 60 deletions(-) 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 index c1bef063..8b2f57a5 100644 --- a/draft/library/wsf_js_widget/kernel/input/wsf_file_control.e +++ b/draft/library/wsf_js_widget/kernel/input/wsf_file_control.e @@ -32,6 +32,9 @@ feature {WSF_PAGE_CONTROL, WSF_CONTROL} -- State management 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 + if attached {JSON_STRING} new_state.item ("upload_file") as f then + upload_file:=f.unescaped_string_32; + end end state: WSF_JSON_OBJECT @@ -41,7 +44,18 @@ feature {WSF_PAGE_CONTROL, WSF_CONTROL} -- State management Result.put_boolean (attached change_event, "callback_change") end -feature --Event handling +feature -- Uploaded Files + + set_uploaded_file (p: detachable STRING) + -- Store link to uploaded file in control state. In order to make it availabe for future callbacks + do + if attached p as a_p then + upload_file := a_p + state_changes.put_string (a_p, "upload_file") + end + end + +feature -- Event handling set_change_event (e: attached like change_event) -- Set text change event handle @@ -49,11 +63,20 @@ feature --Event handling change_event := e end + set_upload_function (e: attached like upload_function) + -- Set button click event handle + do + upload_function := e + end + handle_callback (cname: LIST [STRING]; event: STRING; event_parameter: detachable ANY) do - if Current.control_name.same_string (cname [1]) and attached change_event as cevent then - if event.same_string ("change") then + if Current.control_name.same_string (cname [1]) then + if attached change_event as cevent and event.same_string ("change") then cevent.call (Void) + elseif attached upload_function as ufunction and event.same_string ("uploadfile") and attached {ITERABLE[WSF_UPLOADED_FILE]}event_parameter as files then + + set_uploaded_file(ufunction.item ([files])) end end end @@ -89,4 +112,10 @@ feature -- Properties change_event: detachable PROCEDURE [ANY, TUPLE] -- Procedure to be execued on change + upload_function: detachable FUNCTION [ANY, TUPLE[ITERABLE[WSF_UPLOADED_FILE]],detachable STRING] + -- Procedure to be execued on change + + upload_file: detachable STRING + -- Link to uploaded file + 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 9ec447df..4b49e234 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 @@ -23,8 +23,8 @@ feature {NONE} -- Initialization make (req: WSF_REQUEST; res: WSF_RESPONSE) -- Initialize do - control_name:=req.request_time_stamp.out - make_control ( "body") + control_name := req.request_time_stamp.out + make_control ("body") request := req response := res initialize_controls @@ -69,16 +69,21 @@ feature -- Implementation event := get_parameter ("event") event_parameter := get_parameter ("event_parameter") if attached event and attached event_control_name and attached control then - create states.make_empty - request.read_input_data_into (states) - create json_parser.make_parser (states) - if attached {JSON_OBJECT} json_parser.parse_json as sp then - set_state (sp) - else - if attached request.form_parameter ("file") as o then - response.put_string (o.name) + if not event.is_equal ("uploadfile") then + create states.make_empty + request.read_input_data_into (states) + create json_parser.make_parser (states) + if attached {JSON_OBJECT} json_parser.parse_json as sp then + set_state (sp) end - + else + if attached request.form_parameter ("state") as statedata then + create json_parser.make_parser (statedata.as_string.value) + if attached {JSON_OBJECT} json_parser.parse_json as sp then + set_state (sp) + end + end + event_parameter:=request.uploaded_files end handle_callback (event_control_name.split ('-'), event, event_parameter) create states_changes.make @@ -128,7 +133,6 @@ feature -- Implementation Result.append (");page.initialize();});") Result.append ("
") end - end read_state_changes (states: WSF_JSON_OBJECT) @@ -152,7 +156,7 @@ feature -- Implementation feature -- Event handling - handle_callback (cname: LIST[STRING]; event: STRING; event_parameter: detachable ANY) + handle_callback (cname: LIST [STRING]; event: STRING; event_parameter: detachable ANY) -- Forward callback to control do control.handle_callback (cname, event, event_parameter) @@ -185,8 +189,10 @@ feature {WSF_PAGE_CONTROL, WSF_CONTROL} -- State management Result.put (controls_state, "controls") Result.put (state, "state") end + feature - control_name:STRING + + control_name: STRING feature {NONE} -- Root control diff --git a/examples/widgetapp/assets/widget.coffee b/examples/widgetapp/assets/widget.coffee index 6ee695ff..0e7f7cc0 100644 --- a/examples/widgetapp/assets/widget.coffee +++ b/examples/widgetapp/assets/widget.coffee @@ -370,21 +370,22 @@ class WSF_FILE_CONTROL extends WSF_CONTROL constructor: ()-> super @uploading = false + start_upload: ()-> if @uploading return @uploading = true @$el.hide() - @progressbar = $ """
""" + @progressbar = $ """
""" @$el.parent().append(@progressbar) formData = new FormData(); action = @callback_url - control_name: @control_name + control_name: @get_full_control_name() event: "uploadfile" event_parameter: "" file = @$el[0].files[0]; - formData.append('our-file', file) + formData.append('file', file) formData.append('state', JSON.stringify(@get_context_state())) @sendXHRequest(formData, action) @@ -395,20 +396,15 @@ class WSF_FILE_CONTROL extends WSF_CONTROL onprogressHandler = (evt)-> percent = evt.loaded/evt.total*100 self.progressbar.find('.progress-bar').css {'width':percent+"%"} - onloadHandler = (evt)-> - alert "DONE" - xhr.upload.addEventListener('progress', onprogressHandler, false); - xhr.upload.addEventListener('load', onloadHandler, false); + onstatechange = (evt)-> + if xhr.readyState==4 && xhr.status==200 + self.get_page().process_update(JSON.parse(xhr.responseText)) + + xhr.upload.addEventListener('progress', onprogressHandler, false); - ###Set up events - xhr.upload.addEventListener('loadstart', onloadstartHandler, false); - - xhr.addEventListener('readystatechange', onreadystatechangeHandler, false); - ### - #Set up request + xhr.addEventListener('readystatechange', onstatechange, false); xhr.open('POST', uri, true); - #Fire! xhr.send(formData); attach_events: ()-> @@ -435,9 +431,10 @@ class WSF_FILE_CONTROL extends WSF_CONTROL return @$el.val() update: (state) -> - if state.text? - @state['text'] = state.text - @$el.val(state.text) + if state.upload_file? + @progressbar.hide() + @$el.parent().append($("""

""").addClass("form-control-static").text(@state['file'])) + @state['upload_file'] = state.upload_file class WSF_PASSWORD_CONTROL extends WSF_INPUT_CONTROL diff --git a/examples/widgetapp/assets/widget.css b/examples/widgetapp/assets/widget.css index 3f27bf68..9c215361 100644 --- a/examples/widgetapp/assets/widget.css +++ b/examples/widgetapp/assets/widget.css @@ -97,4 +97,9 @@ body { .CodeMirror-code{ line-height: 1.4em; +} + +.upload.progress{ + margin-top: 7px; + margin-bottom: 0px; } \ No newline at end of file diff --git a/examples/widgetapp/assets/widget.js b/examples/widgetapp/assets/widget.js index 8894892e..2dac6b4d 100644 --- a/examples/widgetapp/assets/widget.js +++ b/examples/widgetapp/assets/widget.js @@ -618,22 +618,22 @@ WSF_FILE_CONTROL = (function(_super) { } this.uploading = true; this.$el.hide(); - this.progressbar = $("
"); + this.progressbar = $("
"); this.$el.parent().append(this.progressbar); formData = new FormData(); action = this.callback_url({ - control_name: this.control_name, + control_name: this.get_full_control_name(), event: "uploadfile", event_parameter: "" }); file = this.$el[0].files[0]; - formData.append('our-file', file); + formData.append('file', file); formData.append('state', JSON.stringify(this.get_context_state())); return this.sendXHRequest(formData, action); }; WSF_FILE_CONTROL.prototype.sendXHRequest = function(formData, uri) { - var onloadHandler, onprogressHandler, self, xhr; + var onprogressHandler, onstatechange, self, xhr; xhr = new XMLHttpRequest(); self = this; onprogressHandler = function(evt) { @@ -643,18 +643,13 @@ WSF_FILE_CONTROL = (function(_super) { 'width': percent + "%" }); }; - onloadHandler = function(evt) { - return alert("DONE"); + onstatechange = function(evt) { + if (xhr.readyState === 4 && xhr.status === 200) { + return self.get_page().process_update(JSON.parse(xhr.responseText)); + } }; xhr.upload.addEventListener('progress', onprogressHandler, false); - xhr.upload.addEventListener('load', onloadHandler, false); - /*Set up events - xhr.upload.addEventListener('loadstart', onloadstartHandler, false); - - - xhr.addEventListener('readystatechange', onreadystatechangeHandler, false); - */ - + xhr.addEventListener('readystatechange', onstatechange, false); xhr.open('POST', uri, true); return xhr.send(formData); }; @@ -690,9 +685,10 @@ WSF_FILE_CONTROL = (function(_super) { }; WSF_FILE_CONTROL.prototype.update = function(state) { - if (state.text != null) { - this.state['text'] = state.text; - return this.$el.val(state.text); + if (state.upload_file != null) { + this.progressbar.hide(); + this.$el.parent().append($("

").addClass("form-control-static").text(this.state['file'])); + return this.state['upload_file'] = state.upload_file; } }; diff --git a/examples/widgetapp/sample_page.e b/examples/widgetapp/sample_page.e index 18ac3f7d..2a1d4c49 100644 --- a/examples/widgetapp/sample_page.e +++ b/examples/widgetapp/sample_page.e @@ -21,23 +21,19 @@ 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] n4_container: WSF_FORM_ELEMENT_CONTROL [STRING] n5_container: WSF_FORM_ELEMENT_CONTROL [STRING] + n6_container: WSF_FORM_ELEMENT_CONTROL [detachable WSF_PENDING_FILE] + n7_container: WSF_FORM_ELEMENT_CONTROL [detachable WSF_PENDING_FILE] cats_container: WSF_FORM_ELEMENT_CONTROL [LIST [STRING]] source: INCREASING_PROGRESSSOURCE do 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) @@ -67,9 +63,24 @@ feature cklist.add_control (create {WSF_CHECKBOX_CONTROL}.make ("Operating Systems", "os")) cklist.add_control (create {WSF_CHECKBOX_CONTROL}.make ("Formal Methods and Functional Programming", "fmfp")) create cats_container.make ("Categories", cklist) - cats_container.add_validator (create {WSF_MIN_VALIDATOR [LIST[STRING]]}.make (1, "Choose at least one category")) - cats_container.add_validator (create {WSF_MAX_VALIDATOR [LIST[STRING]]}.make (2, "Choose at most two category")) + cats_container.add_validator (create {WSF_MIN_VALIDATOR [LIST [STRING]]}.make (1, "Choose at least one category")) + cats_container.add_validator (create {WSF_MAX_VALIDATOR [LIST [STRING]]}.make (2, "Choose at most two category")) form.add_control (cats_container) + --File + create filebox.make + filebox.set_upload_function (agent upload_file) + create n6_container.make ("File Upload", filebox) + n6_container.add_validator (create {WSF_FILESIZE_VALIDATOR}.make (10000000, "File must be smaller than 10MB")) + form.add_control (n6_container) + --File + create filebox2.make + filebox2.set_upload_function (agent upload_file) + filebox2.set_change_event (agent do + filebox2.start_upload + end) + create n7_container.make ("Auto Upload", filebox2) + n7_container.add_validator (create {WSF_FILESIZE_VALIDATOR}.make (10000000, "File must be smaller than 10MB")) + form.add_control (n7_container) --Button 1 create button1.make ("Update") button1.set_click_event (agent handle_click) @@ -94,6 +105,16 @@ feature navbar.set_active (1) end + upload_file (f: ITERABLE [WSF_UPLOADED_FILE]): detachable String + do + -- Store file on server and return link + across + f as i + loop + Result:=i.item.filename + end + end + handle_click local text: STRING @@ -118,7 +139,7 @@ feature run_modal do - start_modal("/","Test Modal", true); + start_modal ("/", "Test Modal", true); end process @@ -131,6 +152,8 @@ feature filebox: WSF_FILE_CONTROL + filebox2: WSF_FILE_CONTROL + textbox1: WSF_INPUT_CONTROL textbox2: WSF_INPUT_CONTROL