Bootstrap常用操作笔记
文章目录
一, bootstrap響應式佈局
1.1 響應式佈局
概念: 響應式web佈局是讓用戶通過不同尺寸的瀏覽器都可以獲得良好視覺的一種方法.
實現原理: 通過CSS3 Media Queries(媒體設備查詢), 媒體查詢是讓頁面內容在不同的媒體環境下運行時可以展示不同的樣式
@media是CSS3中規定的屬性, 它可以實現針對不同媒體設備來設置不同的樣式的目的. 而且就算是在同一設備中它也可以在重置瀏覽器大小的過程中, 頁面也會根據瀏覽器的寬度和高度重新渲染頁面.
二, 柵格系統
柵格將一個頁面可以拆分成多個區塊來理解, 而正是這些區塊共同構成了頁面的佈局. 根據不同的屏幕尺寸情況, 調整這些區塊的排版, 就可以實現響應式設計. 另外, 屏幕寬度較大的時候, 區塊傾向於水平分佈, 而屏幕寬度較小的時候, 區塊傾向於豎直堆疊.
柵格樣式庫一般是將頁面劃分為若干等寬的列(column), 然後通過等寬列來創建響應式的頁面區塊.
2.1 容器, 行於列
在bootstrap中一行分為12列,也即是屏幕的寬度被分為了12份.
row代表一行
col 代表列
container, row, column必須保持特定的層級關係, 柵格系統才可以正常工作.
如果列的和超過了12, 那就會換行. 如果有一列的數超過了12, 那就會按照12去顯示
2.2 斷點類型
Bootstrap柵格的column對應的類名形如: .col-xx-y. y是數字, 表示該元素的寬度佔據12列中的多少列. 而xx只有幾個特定的幾個值可供選擇, 分別是xs, sm, md, lg. 它們就是斷點類型.
在bootstrap柵格的設計中, 斷點的意義是, 當視圖寬度小於斷點時, column將豎直堆疊, 而當視口寬度大圩或等於斷點時, column將水平排列. 按照xs, sm, md, lg的順序, 斷點像素值依次增大, 其中xs表示極小, 即認為視口寬度永遠不會小於xs斷點, column將始終水平浮動.
<div class="container">
<div class="row">
<div class="col-lg-12">col-lg-12</div>
</div>
<div class="row">
<div class="col-lg-4">col-lg-4</div>
<div class="col-lg-4">col-lg-4</div>
<div class="col-lg-4">col-lg-4</div>
</div>
<div class="row">
<div class="col-lg-12">col-md-12</div>
</div>
<div class="row">
<div class="col-md-4">col-md-4</div>
<div class="col-md-4">col-md-4</div>
<div class="col-md-4">col-md-4</div>
</div>
<div class="row">
<div class="col-lg-12">col-sm-12</div>
</div>
<div class="row">
<div class="col-sm-4">col-sm-4</div>
<div class="col-sm-4">col-sm-4</div>
<div class="col-sm-4">col-sm-4</div>
</div>
<div class="row">
<div class="col-xs-12">col-xs-12</div>
</div>
<div class="row">
<div class="col-sm-4">col-xs-4</div>
</div>
<div class="row">
<div class="col-sm-4 col-lg-6 col-xs-12">第一行第一列</div>
<div class="col-sm-4 col-lg-6 col-xs-12">第一行第二列</div>
<div class="col-sm-4 col-lg-6 col-xs-12">第一行第三列</div>
</div>
</div>
三, 表單
定義表單
<form class="form-horizontal" role="form">
<div class="form-group">
<label class="col-sm-2 control-label" for="username">username</label>
<div class="col-sm-10">
<input id="username" class="form-control" type="text" placeholder="please input username">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="password">password</label>
<div class="col-sm-10">
<input id="password" class="form-control" type="text" placeholder="please input password">
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10" >
<button type="button" class="btn btn-default">submit</button>
</div>
</div>
</form>
具体解釋:
- form-horizontal: 呈現水平表單
- 給div設置 .form-group類名, 是為了讓每個輸入框上下間隔一定的距離, 不然兩個就會挨著.
- label的for屬性和input的ID必須同名, 是為了標識他倆是一組, 且當鼠標點擊label標籤時, 光標會自動鎖定到輸入框.
- 給form的input, textarea, select添加class=" .form-control"
- 寬度100%顯示
- 設置了一個淺灰色邊框
- 具有4px的圓角
- 設置陰影效果, 並且元素得到聚焦時, 陰影和邊框效果會有所變化
普通輸入框
<div class="form-group">
<label class="col-sm-2 control-label" for="username">username</label>
<div class="col-sm-10">
<input id="username" class="form-control" type="text" placeholder="please input username">
</div>
</div>
密碼輸入框
<div class="form-group">
<label class="col-sm-2 control-label" for="password">password</label>
<div class="col-sm-10">
<input id="password" class="form-control" type="text" placeholder="please input password">
</div>
</div>
單選框
<div class="form-group">
<label class="col-sm-2 control-label">gender</label>
<div class="col-sm-10">
<input type="radio" name="gender" value="male" checked> male
<input type="radio" name="gender" value="female"> female
</div>
</div>
多選框
<div class="form-group">
<label class="col-sm-2 control-label">action</label>
<div class="col-sm-10">
<input type="checkbox" name="action" value="write"> write
<input type="checkbox" name="action" value="read"> read
<input type="checkbox" name="action" value="run"> run
<input type="checkbox" name="action" value="delete"> delete
</div>
</div>
文本框
<div class="form-group">
<label class="control-label col-sm-2" for="desc">desc</label>
<div class="col-sm-10">
<textarea id="desc" class="form-control" rows="3"></textarea>
</div>
</div>
選擇框
<div class="form-group">
<label class="col-sm-2 control-label">area</label>
<div class="col-sm-10">
<select class="col-sm-10 form-control" name="area" >
<option value="JY">JY</option>
<option VALUE="SG">SG</option>
<option value="ZHH">ZHH</option>
</select>
</div>
</div>
禁用
<div class="form-group">
<label class="control-label col-sm-2">禁用</label>
<div class="col-sm-10">
<input class="form-control" value="禁止輸入" disabled />
</div>
</div>
提交表單
$("#formSubmit").on("click", function () {
var formData = new FormData($("#form")[0]);
var action = new Array();
$("input[name='action']:checked").each(function () {
action.push($(this).val())
})
console.log(action)
$.ajax({
url: "/bs/submit",
data: {
username: formData.get("username"),
password: formData.get("password"),
gender: formData.get("gender"),
actions: JSON.stringify(action),
area: formData.get("area"),
desc: formData.get("desc")
},
type: "POST",
success: function(data) {
console.log(data.status)
}
});
});
四, 驗證
引入 bootstrapValidator.js
$('#form').bootstrapValidator({
message: 'This value is not valid',
feedbackIcons: {
valid: 'glyphicon glyphicon-ok',
invalid: 'glyphicon glyphicon-remove',
validating: 'glyphicon glyphicon-refresh',
},
fields: {
username: {
message: '用戶名驗證失敗',
validators: {
notEmpty: {
message: '用戶名不能為空'
},
stringLength: {
min: 6,
max: 18,
message: '用戶名長度必須在6-18之間'
},
regexp: {
regexp: /^[a-zA-Z0-9_]+$/,
message: '用戶名只能包含大寫, 小寫, 數字和下劃線'
},
stringCase: {
message: '姓氏必須只包含大寫字符',
case: 'upper' #其他值或不填表示只能小寫字符
},
different: {
field: 'password',
message: '用戶名和密碼不能相同'
},
identical: {
field: 'confirmPassword',
message: '確認密碼於密碼不相同'
},
date: {
format: 'YYYY/MM/DD',
message: '日期無效'
},
digits: {
message: '該值只能包含數字'
},
//輸入數字範圍
greaterThan: {
value: 18
},
lessThan: {
value: 100
},
choice: {
min: 2,
max: 4,
message: '請選擇2-4項'
},
}
},
email: {
validators: {
notEmpty: {
message: '郵件不能為空'
},
emailAddress: {
message: '郵箱地址格式有誤'
}
}
}
},
})
常用驗證:
- notEmpty: 判空驗證
- stringLength: 長度驗證
- regexp: 正則驗證
- emailAddress: 郵箱格式驗證
- stringCase: 大小寫驗證
- …
//獲取驗證結果
var valid = $("#form").data("bootstrapValidator").isValid();
//手動觸發所有驗證
$("#form").data("bootstrapValidator").validate();
//重置表單所有驗證規則
$("#form").data("bootstrapValidator").resetForm();
五, 日期日曆
引入靜態資源:
<link rel="stylesheet" href="../bootstrap/bootstrap-datetimepicker/css/bootstrap-datetimepicker.min.css">
<script src="../bootstrap/bootstrap-datetimepicker/js/bootstrap-datetimepicker.js" type="text/javascript"></script>
<script src="../bootstrap/bootstrap-datetimepicker/js/bootstrap-datetimepicker.min.js" type="text/javascript"></script>
<script src="../bootstrap/bootstrap-datetimepicker/js/bootstrap-datetimepicker.zh-CN.js" type="text/javascript"></script>
定義標籤:
<div class="form-group">
<label class="col-sm-2 control-label" for="username">選擇日期</label>
<div class="col-sm-9">
<input name="date" id="datetimepicker1" class="form-control" type="text">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="username">選擇日期+時間</label>
<div class="col-sm-9">
<input name="dateTime" id="datetimepicker2" class="form-control" type="text">
</div>
</div>
JavaScript渲染:
//日期時間
$("#datetimepicker1").datetimepicker({
format: 'yyyy-mm-dd',
language: 'zh-CN',
autoclose: true,
clearBtn: true,
startDate: new Date()
}).on("changeDate", function (e) {
if (e.date) {
$("#datetimepicker2").datetimepicker('setStartDate', new Date(e.date.valueOf()))
} else {
$("#datetimepicker2").datetimepicker('setStartDate', new Date());
}
});
$("#datetimepicker2").datetimepicker({
format: 'yyyy-mm-dd HH:ii:ss',
language: 'zh-CN',
autoclose: true,
clearBtn: true,
endDate: '2020-09-27'
}).on("changeDate", function (e) {
if (e.date) {
$("#datetimepicker1").datetimepicker('setEndDate', new Date(e.date.valueOf()))
} else {
$("#datetimepicker1").datetimepicker('setEndDate', new Date());
}
});
屬性說明:
- format: 日期格式
- language: 語言類型
- autoclose: 自動關閉日曆
- clearBtn: 清除按鈕
- startDate: 開始時間
- endDate: 截止時間
六, 表格
6.1 前端分頁
html :
<table id="table"></table>
<script>
$("#table").bootstrapTable({
method: "get",
url: "bs/loadBs", //獲取數據
dataType: "json",
striped: true, //表格顯示條紋
pagination: true, //啟動分頁
pageSize: 5, //每頁顯示記錄數
pageNumber: 1, //當前頁數
pageList: [5,10,20,50,100], //每頁記錄數選擇列表
search: true, //是否啟用查詢
showRefresh: true,
columns: [{
checkbox: true //複選框
}, {
field: 'action',
title: '動作',
valign: 'middle', //垂直居中
align: 'center' //水平居中
}
],
onLoadSuccess: function () { //表格加載成功時執行
console.log("load success...");
}
})
</script>
controller :
@RequestMapping("/loadBs")
public PageHelper<BootstrapUser> load() {
List<BootstrapUser> bootstrapUsers = loadBs();
return bootstrapUsers;
}
6.2 後端分頁
後端分頁時, 應該把參數 sidePagination設置為server (默認是client)
html :
<div class="container">
<div class="panel panel-default">
<div class="panel-body form-group">
<div class="row form-group">
<label class="col-sm-1 control-label" style="text-align: right">用戶名</label>
<div class="col-sm-2">
<input type="text" class="form-control" name="username" id="search_name">
</div>
<label class="col-sm-1 control-label" style="text-align: right">動作</label>
<div class="col-sm-2">
<input type="text" class="form-control" name="username" id="search_action">
</div>
<div class="col-sm-1">
<button class="btn btn-primary" id="search_btn">查詢</button>
</div>
</div>
<div class="row form-group">
<div class="col-sm-12">
<table id="buTable" data-classes="table table-hover" data-search="true"></table>
</div>
</div>
</div>
</div>
</div>
<script>
$("#buTable").bootstrapTable({
method: "get",
url: "bs/loadBs",
dataType: "json",
striped: true, //表格顯示條紋
sortable: true,
sortName: "username",
sortOrder: "asc",
pagination: true, //啟動分頁
pageSize: 5, //每頁顯示記錄數
pageNumber: 1, //當前頁數
pageList: [5,10,20,50,100], //每頁記錄數選擇列表
search: false, //是否啟用查詢
showRefresh: false,
clickToSelect: true, //點擊選中行
sidePagination: 'server',
queryParams: function queryParams(params) {
var param = {
offset: params.offset,
limit: params.limit,
page: (params.offset / params.limit) + 1,
username: $("#search_name").val(),
action: $("#search_action").val()
};
return param;
},
columns: [{
checkbox: true //複選框
}, {
field: 'username',
title: '用戶名',
valign: 'middle',
valign: 'middle',
align: 'center'
}, {
field: 'password',
title: '密碼',
valign: 'middle',
align: 'center'
}, {
field: 'gender',
title: '性別',
valign: 'middle',
align: 'center',
formatter: function (value, row, index) {
if ('male' == row.gender) {
return "男";
}else {
return "女";
}
}
}, {
field: 'email',
title: '郵箱',
valign: 'middle',
align: 'center'
}, {
field: 'action',
title: '動作',
valign: 'middle',
align: 'center'
}, {
title: '操作',
align: 'center',
width: 180,
formatter: function (value, row, index) {
html = "<button class='btn btn-primary' οnclick='editData()'>修改</button> " +
" <button class='btn btn-danger' οnclick='alert(\""+ row.username + "\")'>刪除</button>";
return html;
}
}
],
onLoadSuccess: function () {
console.log("load success...");
}
})
</script>
注意 : 若要進行條件查詢, 則在 queryParams 參數上進行配置
queryParams: function queryParams(params) {
var param = {
offset: params.offset,
limit: params.limit,
page: (params.offset / params.limit) + 1,
username: $("#search_name").val(),
action: $("#search_action").val()
};
return param;
},
後端 :
先創建一個實體類Page :
package com.lmc.util;
/**
* @author: lmc
* @Description: 描述信息
* @version: 1.0
* @date: 2020/9/19 15:59
*/
public class Page {
private int limit;
private int page;
private int offset;
//省略setter和getter方法
}
再將自己要分頁的實體類繼承Page類 :
@Component
public class BootstrapUser extends Page {
......
}
在創建一個分頁的輔助類PageHelper :
package com.lmc.util;
import java.util.ArrayList;
import java.util.List;
/**
* @author: lmc
* @Description: 描述信息
* @version: 1.0
* @date: 2020/9/19 16:03
*/
public class PageHelper<T> {
private List<T> rows = new ArrayList<T>();
private int total;
//省略setter和getter方法
}
controller方法 :
@RequestMapping("/loadBs")
public PageHelper<BootstrapUser> load(int offset, int limit, String username, String action) {
List<BootstrapUser> bootstrapUsers = loadBs(username, action);
int toIndex = (bootstrapUsers.size() > (offset + limit)) ? (offset + limit) : bootstrapUsers.size();
List<BootstrapUser> bus = bootstrapUsers.subList(offset, toIndex);
PageHelper<BootstrapUser> pageHelper = new PageHelper<BootstrapUser>();
pageHelper.setRows(bus);
pageHelper.setTotal(bootstrapUsers.size());
return pageHelper;
}