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