"Upload file input"

This commit is contained in:
Doug Le Tough 2017-12-02 01:06:13 +01:00
parent bcb80405be
commit ee4727dde1
13 changed files with 178 additions and 18 deletions

View File

@ -1,2 +1,3 @@
SQLALCHEMY_TRACK_MODIFICATIONS = True
SQLALCHEMY_DATABASE_URI = "postgresql://tetawebapp:tetawebapp@localhost/tetawebapp"
UPLOADED_FILES_DEST = "./upload"

Binary file not shown.

After

Width:  |  Height:  |  Size: 244 B

View File

@ -4,6 +4,9 @@ var light_red = "#FCD5DC";
var light_green = "#D5FCD8";
var base_bg = "#FFFFFF";
var base_border = "#888888";
var coloured_bg = "#FF5D00";
var clear_bg = "#E5E5E5";
var text_color = "#555555";
/* **************************************************************************************
* GLOBAL
@ -26,6 +29,17 @@ function getcookie(cname) {
}
// Eye candies
function valid_input(obj) {
// Valid input makes obj background to glow green for 2 seconds
// If obj borders were red, they get they normal color back
obj.style.backgroundColor = light_green;
obj.style.borderColor = base_border;
setTimeout( function() {
obj.style.backgroundColor = base_bg;
}
, 2000);
}
function invalid_input(obj) {
// Invalid input makes obj borders and background to glow red for 2 seconds
// Border color will stay red until a valid input is sent
@ -37,17 +51,48 @@ function invalid_input(obj) {
, 2000);
}
function valid_input(obj) {
function valid_upload(obj) {
// Valid input makes obj background to glow green for 2 seconds
// If obj borders were red, they get they normal color back
obj.style.backgroundColor = light_green;
obj.style.borderColor = base_border;
obj.style.backgroundColor = green;
obj.style.borderColor = text_color;
obj.style.borderStyle = 'solid';
setTimeout( function() {
obj.style.backgroundColor = base_bg;
obj.style.backgroundColor = clear_bg;
obj.style.borderStyle = 'none';
}
, 2000);
}
function invalid_upload(obj) {
// Invalid input makes obj borders and background to glow red for 2 seconds
// Border color will stay red until a valid input is sent
obj.style.backgroundColor = red;
obj.style.borderColor = text_color;
obj.style.borderStyle = 'solid';
setTimeout( function() {
obj.style.borderStyle = 'solid';
obj.style.backgroundColor = clear_bg;
obj.style.borderColor = red;
}
, 2000);
}
function lit(obj) {
// Lit bacground and border on obj (use by input type=file)
obj.style.backgroundColor = coloured_bg;
obj.style.borderColor = text_color;
obj.style.borderStyle = 'solid';
}
function unlit(obj) {
// Unlit bacground and border on obj (use by input type=file)
obj.style.backgroundColor = clear_bg;
obj.style.borderColor = clear_bg;
obj.style.borderStyle = 'none';
}
function verify_login() {
// Verify login inputs
login = document.getElementById('login');
@ -140,7 +185,7 @@ function get_value_from_ajax(obj, url, err_code) {
xhttp.onload = function(){
if (xhttp.status != 200) {
invalid_input(obj);
}
}
};
xhttp.onreadystatechange = function() {
@ -156,6 +201,44 @@ function get_value_from_ajax(obj, url, err_code) {
}
};
xhttp.open('POST', url, true);
alert(xhttp.readyState);
xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhttp.send();
}
function upload_file_from_ajax(obj, url, err_code) {
// Upload files get from <obj> to the specified <url>
// if <errcode> is returned input is invalidated
var files = obj.files;
var icon_id = obj.id.substring(obj.id.lastIndexOf("_") + 1);
var icon_obj = document.getElementById("upload_icon_" + icon_id)
var xhttp = new XMLHttpRequest();
xhttp.onerror = function(){
invalid_upload(icon_obj);
};
xhttp.onload = function(){
if (xhttp.status != 200) {
invalid_upload(icon_obj);
}
};
xhttp.onreadystatechange = function() {
if (xhttp.readyState == 4 && xhttp.status == 200) {
var response = xhttp.responseText;
if (response == err_code) {
invalid_upload(icon_obj);
return;
}
valid_upload(icon_obj);
return;
}
};
xhttp.open('POST', url, true);
var formData = new FormData();
for (var i=0; i < files.length; i++){
formData.append("files", files[i], files[i].name);
}
xhttp.send(formData);
}

View File

@ -25,4 +25,5 @@
--save_icon: url(/static/images/save.png);
--search_icon: url(/static/images/search.png);
--trash_icon: url(/static/images/trash.png);
--upload_icon: url(/static/images/upload.png);
}

View File

@ -254,12 +254,36 @@ input[type="submit"] {
button:hover,
input[type="button"]:hover,
input[type="submit"]:hover {
input[type="submit"]:hover,
input[type="file"]:hover {
background-color: var(--light-coloured-bg);
color: var(--text-color);
cursor: pointer;
}
div.file_upload {
display: inline-block;
position: relative;
width: 20px;
height: 20px;
margin: 0;
padding: 0;
border-radius: 2px;
border-style: solid;
border-width: 1px;
border-color: var(--clear-bg);
}
input[type="file"] {
position: absolute;
width: 18px;
height: 18px;
left: 0;
top: 1px;
opacity: 0;
}
input.add,
input.edit,
input.login,
@ -267,7 +291,8 @@ input.logout,
input.refresh,
input.save,
input.search,
input.trash {
input.trash,
input.upload {
width: 20px;
height: 20px;
margin: 0;
@ -283,7 +308,8 @@ input.logout:hover,
input.refresh:hover,
input.save:hover,
input.search:hover,
input.trash:hover {
input.trash:hover,
input.upload:hover {
border-color: var(--text-color);
border-style: solid;
border-width: 1px;
@ -331,3 +357,8 @@ input.trash {
background-repeat: no-repeat;
background-position: center center;
}
input.upload {
background: var(--upload_icon);
background-repeat: no-repeat;
background-position: center center;
}

View File

@ -25,4 +25,16 @@
<input type='button' value="Try me" onclick='javascript:get_value_from_ajax(document.getElementById("value_receiver"), "/get_value_from_ajax", "TETA_ERR");'>
</article>
</section>
<article class='left'>
<h3>Upload files with AJAX</h3>
<p>Select files to upload</p>
<p>The response may randomly be an error response so you should try it more than once.</p>
<div class='file_upload'>
<!--
Input file is a tricky hack (see tetawebapp.css and tetawebapp.js)
-->
<input type='button' id='upload_icon_1' class='upload' title='Upload' value=' '/>
<input type='file' id='upload_input_1' multiple title='Upload' value='' onchange='javascript:upload_file_from_ajax(this, "/upload", "TETA_ERR");' onmouseover='javascript:lit(document.getElementById("upload_icon_1"));' onmouseout='javascript:unlit(document.getElementById("upload_icon_1"));'/>
</div>
</article>
{% endblock %}

View File

@ -20,14 +20,21 @@
<br/>
<input type='button' value='And me !' />
<br/>
<input type='button' class='add' title='add' value=' '/>
<input type='button' class='edit' title='edit' value=' '/>
<input type='button' class='login' title='login' value=' '/>
<input type='button' class='logout' title='logout' value=' '/>
<input type='button' class='refresh' title='refresh' value=' '/>
<input type='button' class='save' title='save' value=' '/>
<input type='button' class='search' title='search' value=' '/>
<input type='button' class='trash' title='trash' value=' '/>
<input type='button' class='add' title='Add' value=' '/>
<input type='button' class='edit' title='Edit' value=' '/>
<input type='button' class='login' title='Login' value=' '/>
<input type='button' class='logout' title='Logout' value=' '/>
<input type='button' class='refresh' title='Refresh' value=' '/>
<input type='button' class='save' title='Save' value=' '/>
<input type='button' class='search' title='Search' value=' '/>
<input type='button' class='trash' title='Trash' value=' '/>
<!--
Input file is a tricky hack (see tetawebapp.css and tetawebapp.js)
-->
<div class='file_upload'>
<input type='button' id='upload_icon_1' class='upload' title='Upload' value=' '/>
<input type='file' id='upload_input_1' name='files' multiple title='Upload' value='' onchange='javascript:upload_file_from_ajax(this, "/upload", "TETA_ERR");' onmouseover='javascript:lit(document.getElementById("upload_icon_1"));' onmouseout='javascript:unlit(document.getElementById("upload_icon_1"));'/>
</div>
<br/>
<pre>
#!/bin/sh

View File

@ -224,7 +224,7 @@ def get_html_from_ajax():
""" Return HTML code to an AJAX request
It may generate a 404 http error for testing purpose """
if int(random.random()*10) % 2:
# Randomlu generate 404 HTTP response
# Randomly generate 404 HTTP response
return render_template('error.html'), 404
return render_template('ajax_html.html')
@ -236,7 +236,7 @@ def get_value_from_ajax():
err_code = 'TETA_ERR'
RND = int(random.random()*10)
if RND % 2:
# Randomlu generate error
# Randomly generate error
return err_code
return str(RND)
@ -250,6 +250,31 @@ def set_value_from_ajax(value):
return 'True'
return err_code
@app.route("/upload", methods=['POST'])
@check_session
def upload():
""" Accept a value from an AJAX request
It may return an error code for testing purpose """
err_code = 'TETA_ERR'
RND = int(random.random()*10)
if RND % 2:
# Randomly generate error
print err_code
return err_code
uploaded_files = []
if len(request.files) > 0 and request.files['files']:
uploaded_files = request.files.getlist("files")
print "Uploaded files:"
for f in uploaded_files:
print ' [+] %s [%s]' % (f.filename, f.content_type)
# Befor saving you should:
# - Secure the filename
# - Check file size
# - Check content type
f.save(os.path.join(app.config['UPLOADED_FILES_DEST'], f.filename))
f.close()
return "OK"
########################################################################
# Main
########################################################################

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 MiB

Binary file not shown.