bootstrap 為 flask 使用人員提供了一個非常優(yōu)美且有效的前端頁面組件,但是完美之處還存在些許缺陷,比如文件的上傳功能.而 bootstrap-fileinput 是基于 bootstrap 的控件,非常完美的填補了這個空缺.
注意:
本文是基于 bootstrap-fileinput v4.4.2. github 地址: https://github.com/kartik-v/bootstrap-fileinput
注意:
本文是主要是以 http://plugins.krajee.com/file-input/demo 示例為基礎(chǔ)進行講解.
創(chuàng)建藍圖 advanced
創(chuàng)建方法請參照 flask 項目中使用 bootstrapFileInput(構(gòu)建篇) 中 lib 藍圖的創(chuàng)建方法,此處不在贅述.
構(gòu)建基礎(chǔ) html 模板
app/advanced/templates/advanced_common/base.html
內(nèi)容如下:
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<!-- The above 3 meta tags *must* come first in the head; any other head content must come *after* these tags -->
<meta name="description" content="">
<meta name="author" content="">
<link rel="icon" href="{{ url_for('lib.static', filename='favicon.ico')}}">
<title>{% block title %}{% endblock %}</title>
{% block css %}
<!-- 新 Bootstrap 核心 CSS 文件 -->
<link rel="stylesheet" href="{{ url_for('lib.static', filename='css/bootstrap.min.css') }}">
<!-- 可選的Bootstrap主題文件(一般不用引入) -->
<link rel="stylesheet" href="{{ url_for('lib.static', filename='css/bootstrap-theme.min.css') }}">
<!-- 個性化主題文件 -->
<!-- font-awesome樣式主題文體 -->
<link href="{{ url_for('lib.static',filename='css/font-awesome.css') }}" media="all" rel="stylesheet" type="text/css" />
<!-- fileinput樣式主題文體 -->
<link href="{{ url_for('lib.static',filename='css/fileinput.min.css') }}" media="all" rel="stylesheet" type="text/css" />
{% endblock %}
{% block js %}
<!-- jQuery文件。務(wù)必在bootstrap.min.js 之前引入 -->
<script src="{{ url_for('lib.static', filename='js/jquery.min.js') }}"></script>
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="{{ url_for('lib.static', filename='js/bootstrap.min.js') }}"></script>
<!-- 個性化 js 文件 -->
<!-- piexif.min.js is only needed if you wish to resize images before upload to restore exif data.
This must be loaded before fileinput.min.js -->
<script src="{{ url_for('lib.static',filename='js/plugins/piexif.min.js') }}" type="text/javascript"></script>
<!-- sortable.min.js is only needed if you wish to sort / rearrange files in initial preview.
This must be loaded before fileinput.min.js -->
<script src="{{ url_for('lib.static',filename='js/plugins/sortable.min.js') }}" type="text/javascript"></script>
<!-- purify.min.js is only needed if you wish to purify HTML content in your preview for HTML files.
This must be loaded before fileinput.min.js -->
<script src="{{ url_for('lib.static',filename='js/plugins/purify.js') }}" type="text/javascript"></script>
<!-- the main fileinput plugin file -->
<script src="{{ url_for('lib.static',filename='js/fileinput.min.js') }}"></script>
<!-- optionally if you need a theme like font awesome theme you can include
it as mentioned below -->
<script src="{{ url_for('lib.static',filename='js/themes/fa/theme.min.js') }}"></script>
<!-- optionally if you need translation for your language then include
locale file as mentioned below -->
<script src="{{ url_for('lib.static',filename='js/locales/zh.js') }}"></script>
{% endblock %}
</head>
<body>
<div class="container">
<div class="row">
<div class="col-xs-12 col-sm-offset-2">
<div class="col-xs-12 col-sm-8">
{% block content %}
{% endblock %}
</div>
</div>
</div><!--/row-->
</div><!--/.container-->
</body>
</html>
base.html 模板引入 css 和 js 時的幾個坑
注意 css 和 js 文件的導(dǎo)入順序
- 首先需要導(dǎo)入的 js 文件是 jquery.js.
- 第二需要導(dǎo)入 bootstrap 相關(guān)的 css 和 js.
- 第三需要導(dǎo)入 fileinput 相關(guān)的 css 和 js, 請注意項目中的注釋, 相關(guān)的文件導(dǎo)入也需要有先后順序的要求.
注意版本問題
- 此項目所需的 jquery 是 jQuery v2.1.1.
- 此項目所需的 bootstrap 是 v3.3.7 版本
- 此項目所需的 fileinput 是 v4.4.2 的版本.
其它版本可能會有所不同.
注意 fileinput 使用模式
fileinput 有兩種使用模式,一種是利用 form 提交,一種是 ajax 方式提交.其中 ajax 提交方式,需要從 js 中進行設(shè)置, 并將類樣式 class 設(shè)置為 file-loading
. 而非 ajax 提交方式需要引入 form 表單, 類樣式 class 需設(shè)置為 file
, 本基礎(chǔ)示例都需要引入 form 表單.
進階示例 1
展示
從該圖的右下角可以清晰的看到, 這個 form data 里裹夾著數(shù)據(jù) key: 2. 那么我們用 flask 寫視圖函數(shù)的時候,就可以用到這個 key 值.
模板內(nèi)容
app/advanced/templates/exam_1.html
內(nèi)容如下:
{% extends 'advanced_common/base.html' %}
{% block content %}
<h1>進階示例1</h1>
<label class="control-label">Planets and Satellites</label>
<input id="input-24" name="input24[]" type="file" multiple class="file-loading">
<script>
$(document).on('ready', function() {
$("#input-24").fileinput({
initialPreview: [
'http://upload.wikimedia.org/wikipedia/commons/thumb/e/e1/FullMoon2010.jpg/631px-FullMoon2010.jpg',
'http://upload.wikimedia.org/wikipedia/commons/thumb/6/6f/Earth_Eastern_Hemisphere.jpg/600px-Earth_Eastern_Hemisphere.jpg'
],
initialPreviewAsData: true,
initialPreviewConfig: [
{caption: "Moon.jpg", size: 6930321, width: "120px", key: 1},
{caption: "Earth.jpg", size: 1218822, width: "120px", key: 2}
],
deleteUrl: "{{ url_for('advanced.delete') }}",
overwriteInitial: false,
maxFileSize: 100,
initialCaption: "進階示例第一例"
});
});
</script>
<hr>
<p>
設(shè)置最大的文件上傳大小為 100K . 展示服務(wù)器上的圖片內(nèi)容,實現(xiàn) finder 功能. 設(shè)置 <code>overwriteInitial</code> 為 <code>false</code>, 新選擇的文件不會覆蓋原有文件.
</p>
{% endblock %}
{% block title %}
進階示例1
{% endblock %}
知識點
- html 模板的名稱最好在整個項目中,也就是所有的藍圖中都具有唯一性.
- 模板中的 js 代碼有多種寫法, 詳細內(nèi)容請見: http://plugins.krajee.com/file-input#options
- 請注意 js 代碼中的 deleteUrl 項, 此處有多種寫法. 請參閱第二點之后, 選擇適合自己的方法.
- 請大膽的想象, 如果此示例實際上已具有 finder 的影子.你可以實現(xiàn)文件上傳, 刪除, 更新, 展示等所有你能想象的功能.
- initialPreviewAsData 項, 如果設(shè)置為 false, 將不會展示圖片,而只會顯示圖片鏈接, 如果設(shè)置為 true, 則展示圖片.
- overwriteInitial 項, 是設(shè)置是否覆蓋原有的已上傳項.
- maxFileSize 項, 上傳文件的最大大小.
- initialCaption 項, 初始化 input 選擇框內(nèi)的內(nèi)容.
視圖函數(shù)
app/advanced/views.py
內(nèi)容如下:
@advanced.route('/delete', methods=['GET', 'POST'])
def delete():
key = request.form.get('key')
print key
return jsonify()
@advanced.route('/example_1', methods=['GET', 'POST'])
def example_1():
return render_template('exam_1.html')
知識點
- 第一個 url 函數(shù)是實現(xiàn)了文件的刪除功能. 其中的
request.form.get('key')
就是為了獲取 ajax 提交的 form data 的值, 也就是示意圖中右下角所展示的內(nèi)容. - 第二個 url 函數(shù)實現(xiàn)了上傳功能的頁面.
進階示例 2
該示例僅僅是把 js 中的 overwriteInitial
項設(shè)置成了 true
, 選擇新文件的時候, 將會覆蓋原有的文件.
進階示例 3
模板內(nèi)容
app/advanced/templates/exam_3.html
內(nèi)容如下:
{% extends 'advanced_common/base.html' %}
{% block content %}
<h1>進階示例3</h1>
<label class="control-label">Select File</label>
<input id="input-20" type="file" class="file-loading">
<script>
$(document).on('ready', function() {
$("#input-20").fileinput({
browseClass: "btn btn-primary btn-block",
showCaption: false,
showRemove: false,
showUpload: false
});
});
</script>
{% endblock %}
{% block title %}
進階示例3
{% endblock %}
知識點
- browseClass 項, 用來設(shè)置上傳按鈕的樣式.
- showCaption 項, 用來設(shè)置是否顯示文件選擇 input 框.
- showRemove 項, 用來設(shè)置是否顯示刪除按鈕.
- showUpload 項, 用來設(shè)置是否顯示上傳按鈕.
- 該示例僅僅顯示選擇文件按鈕, 僅此而已.
視圖函數(shù)
views.py 視圖函數(shù)和示例1基本相同,不在贅述.
進階示例 4
模板內(nèi)容
app/advanced/templates/exam_4.html
內(nèi)容如下:
{% extends 'advanced_common/base.html' %}
{% block content %}
<h1>進階示例4</h1>
<label class="control-label">Select File</label>
<input id="input-21" type="file" accept="image/*" class="file-loading">
<script>
$(document).on('ready', function() {
$("#input-21").fileinput({
previewFileType: "image",
browseClass: "btn btn-success",
browseLabel: "Pick Image",
browseIcon: "<i class=\"glyphicon glyphicon-picture\"></i> ",
removeClass: "btn btn-danger",
removeLabel: "Delete",
removeIcon: "<i class=\"glyphicon glyphicon-trash\"></i> ",
uploadClass: "btn btn-info",
uploadLabel: "Upload",
uploadIcon: "<i class=\"glyphicon glyphicon-upload\"></i> "
});
});
</script>
{% endblock %}
{% block title %}
進階示例4
{% endblock %}
知識點
- accept="image/*", input 標簽中的屬性, 表示只能選擇圖片文件.
- previewFileType: image 設(shè)置要選擇的文件格式是圖片格式.
- 其它的都是為了設(shè)置各個按鈕的樣式, 可以自由組合.
視圖函數(shù)
views.py 視圖函數(shù)和示例1基本相同,不在贅述.
進階示例 5
模板內(nèi)容
app/advanced/templates/exam_5.html
內(nèi)容如下:
{% extends 'advanced_common/base.html' %}
{% block content %}
<h1>進階示例5</h1>
<label class="control-label">Select File</label>
<input id="input-22" name="input22[]" type="file" class="file-loading" accept="text/plain" multiple>
<script>
$(document).on('ready', function() {
$("#input-22").fileinput({
previewFileType: "text",
allowedFileExtensions: ["txt", "md", "ini", "text"],
previewClass: "bg-warning"
});
});
</script>
{% endblock %}
{% block title %}
進階示例5
{% endblock %}
知識點
- previewFileType: "text" 設(shè)置要選擇的文件格式是文件格式.
- allowedFileExtensions 設(shè)置能夠接受上傳的集中文件的格式, 具有驗證功能.
- previewClass 預(yù)覽框的背景樣式.
視圖函數(shù)
views.py 視圖函數(shù)和示例1基本相同,不在贅述.
進階示例 6
模板內(nèi)容
app/advanced/templates/exam_6.html
內(nèi)容如下:
{% extends 'advanced_common/base.html' %}
{% block content %}
<h1>進階示例6</h1>
<label class="control-label">Select File</label>
<input id="input-23" name="input23[]" type="file" multiple class="file-loading">
<script>
$(document).on('ready', function() {
$("#input-23").fileinput({
showUpload: false,
layoutTemplates: {
main1: "{preview}\n" +
"<div class=\'input-group {class}\'>\n" +
" <div class=\'input-group-btn\'>\n" +
" {browse}\n" +
" {upload}\n" +
" {remove}\n" +
" </div>\n" +
" {caption}\n" +
"</div>"
}
});
});
</script>
{% endblock %}
{% block title %}
進階示例6
{% endblock %}
知識點
- showUpload: false. 不顯示上傳按鈕.
- layoutTemplates. 用于設(shè)置文件上傳插件的樣式. 詳見 http://plugins.krajee.com/file-input#options 的 layoutTemplates 項.
視圖函數(shù)
views.py 視圖函數(shù)和示例1基本相同,不在贅述.
進階示例 7
模板內(nèi)容
app/advanced/templates/exam_7.html
內(nèi)容如下:
{% extends 'advanced_common/base.html' %}
{% block content %}
<h1>進階示例7</h1>
<label class="control-label">Select File</label>
<input id="input-40" name="input40[]" type="file" class="file" multiple>
<br>
<button type="button" class="btn btn-warning btn-modify">Modify</button>
<script>
$(document).on('ready', function() {
$(".btn-modify").on("click", function() {
var $btn = $(this), $input = $("#input-40");
if ($btn.text() == "Modify") {
$("#input-40").fileinput("disable").fileinput("refresh", {showUpload: false});
$btn.html("Revert");
alert("Hurray! I have disabled the input and hidden the upload button.");
}
else {
$("#input-40").fileinput("enable").fileinput("refresh", {showUpload: true});
$btn.html("Modify");
alert("Hurray! I have reverted back the input to enabled with the upload button.");
}
});
});
</script>
<br>
<p>
調(diào)用插件方法, 點擊 modify 按鈕來打開獲關(guān)閉插件功能.
</p>
{% endblock %}
{% block title %}
進階示例7
{% endblock %}
知識點
- $("#input-40").fileinput("disable").fileinput("refresh", {showUpload: false}); 其中,第一個 fileinput("disable") 的功能是讓文件上傳插件不可用. 第二個 fileinput("refresh", {showUpload: false}) 的功能是不顯示上傳預(yù)覽模板.
- 如果只調(diào)用第一個 fileinput("disable"), 將只是關(guān)閉文件上傳插件, 假如你已經(jīng)選擇了文件, 已有預(yù)覽效果圖, 則不關(guān)閉預(yù)覽效果圖.
視圖函數(shù)
views.py 視圖函數(shù)和示例1基本相同,不在贅述.
進階示例 8
模板內(nèi)容
app/advanced/templates/exam_8.html
內(nèi)容如下:
{% extends 'advanced_common/base.html' %}
{% block content %}
<h1>進階示例8</h1>
<label class="control-label">Select File</label>
<input id="input-41" name="input41[]" type="file" multiple class="file-loading">
<script>
$(document).on('ready', function() {
$("#input-41").fileinput({
maxFileCount: 10,
allowedFileTypes: ["image", "video"]
});
});
</script>
<br>
<p>
僅僅允許上傳的文件為圖片和視頻. 最大上傳的文件數(shù)是 10.
</p>
{% endblock %}
{% block title %}
進階示例8
{% endblock %}
知識點
- allowedFileTypes: ["image", "video"] 插件的驗證功能, 僅僅允許上傳的文件為圖片和視頻. 可以將 "image", "video" 換成 "text" 試試.
視圖函數(shù)
views.py 視圖函數(shù)和示例1基本相同,不在贅述.
進階示例 9
模板內(nèi)容
app/advanced/templates/exam_9.html
內(nèi)容如下:
<label class="control-label">Select File</label>
<input id="input-42" name="input42[]" type="file" multiple class="file-loading">
<script>
$(document).on('ready', function() {
$("#input-42").fileinput({
maxFileCount: 10,
allowedFileExtensions: ["jpg", "gif", "png", "txt"]
});
});
</script>
知識點
- allowedFileExtensions 插件的驗證功能, 僅僅允許上傳后綴為 "jpg", "gif", "png", "txt" 的文件.
視圖函數(shù)
views.py 視圖函數(shù)和示例1基本相同,不在贅述.
進階示例 10
模板內(nèi)容
app/advanced/templates/exam_10.html
內(nèi)容如下:
{% extends 'advanced_common/base.html' %}
{% block content %}
<h1>進階示例10</h1>
<label class="control-label">Select File</label>
<input id="input-43" name="input43[]" type="file" multiple class="file-loading">
<div id="errorBlock" class="help-block"></div>
<script>
$(document).on('ready', function() {
$("#input-43").fileinput({
showPreview: false,
allowedFileExtensions: ["jpg", "jpeg", "gif", "png"],
elErrorContainer: "#errorBlock"
});
});
</script>
<br>
<p>
僅僅允許上傳后綴為 "jpg", "gif", "png", "txt" 的文件. 不顯示文件預(yù)覽功能. 且設(shè)置錯誤提示的顯示位置.
</p>
{% endblock %}
{% block title %}
進階示例10
{% endblock %}
知識點
- showPreview: false, 不顯示文件的預(yù)覽功能.
- elErrorContainer: "#errorBlock". 設(shè)置 id 為 errorBlock 的區(qū)域來顯示錯誤提示.
視圖函數(shù)
views.py 視圖函數(shù)和示例1基本相同,不在贅述.
進階示例 11
模板內(nèi)容
app/advanced/templates/exam_11.html
內(nèi)容如下:
<label class="control-label">Select File</label>
<input id="input-44" name="input44[]" type="file" multiple class="file-loading">
<script>
$(document).on('ready', function() {
$("#input-44").fileinput({
uploadUrl: '/file-upload-batch/2',
maxFilePreviewSize: 10240
});
});
</script>
知識點
- uploadUrl 設(shè)置上傳文件的鏈接. 此處請參閱 flask 項目中使用 bootstrapFileInput(基礎(chǔ)篇) 中的視圖函數(shù)內(nèi)容.
- maxFilePreviewSize: 10240 驗證功能, 設(shè)置預(yù)覽的文件的大小最大為 10M.
視圖函數(shù)
views.py 視圖函數(shù)和示例1基本相同,不在贅述.
本章源代碼下載:
<a class="btn btn-primary" >zip壓縮包</a>
<a class="btn btn-primary" >tar.gz壓縮包</a>