"Upload file input"
This commit is contained in:
parent
bcb80405be
commit
ee4727dde1
@ -1,2 +1,3 @@
|
|||||||
SQLALCHEMY_TRACK_MODIFICATIONS = True
|
SQLALCHEMY_TRACK_MODIFICATIONS = True
|
||||||
SQLALCHEMY_DATABASE_URI = "postgresql://tetawebapp:tetawebapp@localhost/tetawebapp"
|
SQLALCHEMY_DATABASE_URI = "postgresql://tetawebapp:tetawebapp@localhost/tetawebapp"
|
||||||
|
UPLOADED_FILES_DEST = "./upload"
|
||||||
|
BIN
tetawebapp/static/images/upload.png
Normal file
BIN
tetawebapp/static/images/upload.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 244 B |
@ -4,6 +4,9 @@ var light_red = "#FCD5DC";
|
|||||||
var light_green = "#D5FCD8";
|
var light_green = "#D5FCD8";
|
||||||
var base_bg = "#FFFFFF";
|
var base_bg = "#FFFFFF";
|
||||||
var base_border = "#888888";
|
var base_border = "#888888";
|
||||||
|
var coloured_bg = "#FF5D00";
|
||||||
|
var clear_bg = "#E5E5E5";
|
||||||
|
var text_color = "#555555";
|
||||||
|
|
||||||
/* **************************************************************************************
|
/* **************************************************************************************
|
||||||
* GLOBAL
|
* GLOBAL
|
||||||
@ -26,6 +29,17 @@ function getcookie(cname) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Eye candies
|
// 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) {
|
function invalid_input(obj) {
|
||||||
// Invalid input makes obj borders and background to glow red for 2 seconds
|
// Invalid input makes obj borders and background to glow red for 2 seconds
|
||||||
// Border color will stay red until a valid input is sent
|
// Border color will stay red until a valid input is sent
|
||||||
@ -37,17 +51,48 @@ function invalid_input(obj) {
|
|||||||
, 2000);
|
, 2000);
|
||||||
}
|
}
|
||||||
|
|
||||||
function valid_input(obj) {
|
function valid_upload(obj) {
|
||||||
// Valid input makes obj background to glow green for 2 seconds
|
// Valid input makes obj background to glow green for 2 seconds
|
||||||
// If obj borders were red, they get they normal color back
|
// If obj borders were red, they get they normal color back
|
||||||
obj.style.backgroundColor = light_green;
|
obj.style.backgroundColor = green;
|
||||||
obj.style.borderColor = base_border;
|
obj.style.borderColor = text_color;
|
||||||
|
obj.style.borderStyle = 'solid';
|
||||||
setTimeout( function() {
|
setTimeout( function() {
|
||||||
obj.style.backgroundColor = base_bg;
|
obj.style.backgroundColor = clear_bg;
|
||||||
|
obj.style.borderStyle = 'none';
|
||||||
}
|
}
|
||||||
, 2000);
|
, 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() {
|
function verify_login() {
|
||||||
// Verify login inputs
|
// Verify login inputs
|
||||||
login = document.getElementById('login');
|
login = document.getElementById('login');
|
||||||
@ -156,6 +201,44 @@ function get_value_from_ajax(obj, url, err_code) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
xhttp.open('POST', url, true);
|
xhttp.open('POST', url, true);
|
||||||
|
alert(xhttp.readyState);
|
||||||
xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
|
xhttp.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
|
||||||
xhttp.send();
|
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);
|
||||||
|
}
|
||||||
|
@ -25,4 +25,5 @@
|
|||||||
--save_icon: url(/static/images/save.png);
|
--save_icon: url(/static/images/save.png);
|
||||||
--search_icon: url(/static/images/search.png);
|
--search_icon: url(/static/images/search.png);
|
||||||
--trash_icon: url(/static/images/trash.png);
|
--trash_icon: url(/static/images/trash.png);
|
||||||
|
--upload_icon: url(/static/images/upload.png);
|
||||||
}
|
}
|
||||||
|
@ -254,12 +254,36 @@ input[type="submit"] {
|
|||||||
|
|
||||||
button:hover,
|
button:hover,
|
||||||
input[type="button"]:hover,
|
input[type="button"]:hover,
|
||||||
input[type="submit"]:hover {
|
input[type="submit"]:hover,
|
||||||
|
input[type="file"]:hover {
|
||||||
background-color: var(--light-coloured-bg);
|
background-color: var(--light-coloured-bg);
|
||||||
color: var(--text-color);
|
color: var(--text-color);
|
||||||
cursor: pointer;
|
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.add,
|
||||||
input.edit,
|
input.edit,
|
||||||
input.login,
|
input.login,
|
||||||
@ -267,7 +291,8 @@ input.logout,
|
|||||||
input.refresh,
|
input.refresh,
|
||||||
input.save,
|
input.save,
|
||||||
input.search,
|
input.search,
|
||||||
input.trash {
|
input.trash,
|
||||||
|
input.upload {
|
||||||
width: 20px;
|
width: 20px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@ -283,7 +308,8 @@ input.logout:hover,
|
|||||||
input.refresh:hover,
|
input.refresh:hover,
|
||||||
input.save:hover,
|
input.save:hover,
|
||||||
input.search:hover,
|
input.search:hover,
|
||||||
input.trash:hover {
|
input.trash:hover,
|
||||||
|
input.upload:hover {
|
||||||
border-color: var(--text-color);
|
border-color: var(--text-color);
|
||||||
border-style: solid;
|
border-style: solid;
|
||||||
border-width: 1px;
|
border-width: 1px;
|
||||||
@ -331,3 +357,8 @@ input.trash {
|
|||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: center center;
|
background-position: center center;
|
||||||
}
|
}
|
||||||
|
input.upload {
|
||||||
|
background: var(--upload_icon);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: center center;
|
||||||
|
}
|
||||||
|
@ -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");'>
|
<input type='button' value="Try me" onclick='javascript:get_value_from_ajax(document.getElementById("value_receiver"), "/get_value_from_ajax", "TETA_ERR");'>
|
||||||
</article>
|
</article>
|
||||||
</section>
|
</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 %}
|
{% endblock %}
|
||||||
|
@ -20,14 +20,21 @@
|
|||||||
<br/>
|
<br/>
|
||||||
<input type='button' value='And me !' />
|
<input type='button' value='And me !' />
|
||||||
<br/>
|
<br/>
|
||||||
<input type='button' class='add' title='add' value=' '/>
|
<input type='button' class='add' title='Add' value=' '/>
|
||||||
<input type='button' class='edit' title='edit' value=' '/>
|
<input type='button' class='edit' title='Edit' value=' '/>
|
||||||
<input type='button' class='login' title='login' value=' '/>
|
<input type='button' class='login' title='Login' value=' '/>
|
||||||
<input type='button' class='logout' title='logout' value=' '/>
|
<input type='button' class='logout' title='Logout' value=' '/>
|
||||||
<input type='button' class='refresh' title='refresh' value=' '/>
|
<input type='button' class='refresh' title='Refresh' value=' '/>
|
||||||
<input type='button' class='save' title='save' value=' '/>
|
<input type='button' class='save' title='Save' value=' '/>
|
||||||
<input type='button' class='search' title='search' value=' '/>
|
<input type='button' class='search' title='Search' value=' '/>
|
||||||
<input type='button' class='trash' title='trash' 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/>
|
<br/>
|
||||||
<pre>
|
<pre>
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
@ -224,7 +224,7 @@ def get_html_from_ajax():
|
|||||||
""" Return HTML code to an AJAX request
|
""" Return HTML code to an AJAX request
|
||||||
It may generate a 404 http error for testing purpose """
|
It may generate a 404 http error for testing purpose """
|
||||||
if int(random.random()*10) % 2:
|
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('error.html'), 404
|
||||||
return render_template('ajax_html.html')
|
return render_template('ajax_html.html')
|
||||||
|
|
||||||
@ -236,7 +236,7 @@ def get_value_from_ajax():
|
|||||||
err_code = 'TETA_ERR'
|
err_code = 'TETA_ERR'
|
||||||
RND = int(random.random()*10)
|
RND = int(random.random()*10)
|
||||||
if RND % 2:
|
if RND % 2:
|
||||||
# Randomlu generate error
|
# Randomly generate error
|
||||||
return err_code
|
return err_code
|
||||||
return str(RND)
|
return str(RND)
|
||||||
|
|
||||||
@ -250,6 +250,31 @@ def set_value_from_ajax(value):
|
|||||||
return 'True'
|
return 'True'
|
||||||
return err_code
|
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
|
# Main
|
||||||
########################################################################
|
########################################################################
|
||||||
|
BIN
tetawebapp/upload/what_you_ride_final.xcf
Normal file
BIN
tetawebapp/upload/what_you_ride_final.xcf
Normal file
Binary file not shown.
BIN
tetawebapp/upload/what_you_ride_final2.png
Normal file
BIN
tetawebapp/upload/what_you_ride_final2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.4 MiB |
BIN
tetawebapp/upload/what_you_ride_final2.xcf
Normal file
BIN
tetawebapp/upload/what_you_ride_final2.xcf
Normal file
Binary file not shown.
BIN
tetawebapp/upload/what_you_ride_final3.png
Normal file
BIN
tetawebapp/upload/what_you_ride_final3.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.6 MiB |
BIN
tetawebapp/upload/what_you_ride_final3.xcf
Normal file
BIN
tetawebapp/upload/what_you_ride_final3.xcf
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user