本文講解將以實際開發項目中後臺添加用戶模塊中使用到的Layui異步文件上傳以及上傳圖預覽功能爲例
如果不想Listen Talk只想Show Me Code的話直接拉到文章最後
我將貼上添加用戶模塊完整的模版文件和控制器相應方法代碼
首先貼張圖看一下實際效果:
此模塊使用的是Layui的樣式,接觸過Layui的應該知道Layui自帶的文件上傳功能無法隨表單其他元素一起提交給服務器,所以這裏需要用到異步上傳,基本思路是使用Layui的文件上傳控件然後再添加一個value爲空的img標籤用於顯示預覽圖和一個隱藏域用於提交文件路徑信息,文件上傳使用Layui.upload上傳接口,其中的url字段填我們控制器中自己寫的接口即可,在控制器中我們對圖片格式、大小等進行驗證後傳入具體目錄後獲取路徑並返回,Layui在獲取到路徑信息回調後即可將img的src賦值以顯示預覽圖,並且將隱藏域value賦值從而實現路徑信息和表單其他元素一起提交至服務器,說了這麼多,下面貼出這些模塊的代碼片以供參考:
①圖片上傳+預覽圖+隱藏域
<div class="layui-form-item">
<label class="layui-form-label" for="icon">頭像</label>
<div class="layui-input-inline">
<div class="site-demo-upbar layui-input-inline">
<input type="file" name="iconupload" lay-type="images" class="layui-upload-file" accept="image/*" id="iconupload">
</div>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">頭像預覽</label>
<div class="layui-input-inline"><img style="width:150px;" id="icon_preview" src=""></div>
</div>
<input type="hidden" name="icon" id="icon" value="">
②Layui.upload接口以及回調
layui.upload({
url: '{:url(\'index/user/iconupload\')}' //上傳接口
,success: function(res){
if(res.status==100)
layer.alert(res.message, {icon: 6},function (thiswindow) {
$('#icon_preview').attr('src',res.url);
$('#icon').val(res.url);
layer.close(thiswindow);
});
else
layer.alert(res.message, {icon: 5},function (thiswindow) {
$('#icon_preview').attr('src',res.url);
$('#icon').val(res.url);
layer.close(thiswindow);
});
}
});
③控制器iconupload方法
public function iconupload()
{
$icon = Request::file('iconupload');
$info = $icon->validate([
'size'=>10240000,
'ext'=>'bmp,jpg,png,tif,gif,pcx,tga,exif,fpx,svg,psd,cdr,pcd,dxf,ufo,eps,ai,raw,WMF,webp'
])->move('uploads/usericon/');
if($info)
{
$url = "\\uploads\\usericon\\".$info->getSaveName();
return json(['status'=>100,'message'=>'上傳成功','url'=>$url]);
}
else
{
return json(['status'=>-200,'message'=>$icon->getError(),'url'=>'']);
}
}
在完成以上操作後即實現了異步上傳+預覽圖,並可以將上傳圖片路徑信息同表單其他元素一起提交至服務器
此例爲圖片上傳,如果想要上傳其他文件,你需要自己限定上傳文件的後綴以及上傳按鈕上的文字
文件後綴需要修改input標籤中的lay-ext:
<div class="layui-form-item">
<label class="layui-form-label" for="appupload"><span class="x-red">*</span>上傳安裝包</label>
<div class="layui-input-inline">
<div class="site-demo-upbar layui-input-inline">
<input type="file" lay-type="file" name="appupload" lay-ext="apk" class="layui-upload-file" accept=".apk" id="appupload">
</div>
</div>
<div class="layui-form-mid layui-word-aux">
<span class="x-red" id="tip" style="display:none">已成功上傳</span>
</div>
</div>
按鈕文字需要修改Layui上傳接口,在裏面加入title字段:
layui.upload({
url: '{:url(\'index/app/androidupload\')}' //上傳接口
,title: '上傳安裝包'
,success: function(res){ //上傳成功後的回調
console.log(res);
if(res.status==100)
layer.alert(res.message, {icon: 6},function (thiswindow) {
$('#position').val(res.url);
$('#tip').show();
layer.close(thiswindow);
});
else
layer.alert(res.message, {icon: 5},function (thiswindow) {
layer.close(thiswindow);
});
}
});
此例爲安裝包上傳模塊,效果如下:
下面貼出添加用戶模塊完整的模板文件和相應控制器方法代碼
①Html模版文件
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>
添加用戶
</title>
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="format-detection" content="telephone=no">
<link rel="stylesheet" href="/static/css/x-admin.css" media="all">
</head>
<body>
<div class="x-body">
<form enctype="multipart/form-data" id="useraddinfo" class="layui-form" action="{:url('user/doEdit')}" method="post">
<div class="layui-form-item">
<label for="nickname" class="layui-form-label">
<span class="x-red">*</span>暱稱
</label>
<div class="layui-input-inline">
<input type="text" class="layui-input" id="nickname" name="nickname" required="" placeholder="請輸入暱稱" lay-verify="nickname">
</div>
<div class="layui-form-mid layui-word-aux">
<span class="x-red">*</span>只能使用中文,字母,部分字符
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label" for="icon">頭像</label>
<div class="layui-input-inline">
<div class="site-demo-upbar layui-input-inline">
<input type="file" name="iconupload" lay-type="images" class="layui-upload-file" accept="image/*" id="iconupload">
</div>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label">頭像預覽</label>
<div class="layui-input-inline"><img style="width:150px;" id="icon_preview" src="/static/default_images/user_default_image.jpg"></div>
</div>
<div class="layui-form-item">
<label for="mobile" class="layui-form-label"><span class="x-red">*</span>手機號</label>
<div class="layui-input-inline">
<input type="number" class="layui-input" id="mobile" name="mobile" placeholder="請輸入手機號" lay-verify="mobile" required="">
</div>
<div class="layui-form-mid layui-word-aux">
<span class="x-red">*</span>請填寫真實手機號,用戶唯一憑證
</div>
</div>
<div class="layui-form-item">
<label for="password" class="layui-form-label"><span class="x-red">*</span>密碼</label>
<div class="layui-input-inline">
<input type="password" class="layui-input" required="" id="password" name="password" lay-verify="pass" placeholder="請輸入密碼">
</div>
<div class="layui-form-mid layui-word-aux">
<span class="x-red">*</span>請輸入6-16位的密碼
</div>
</div>
<div class="layui-form-item">
<label for="mobile" class="layui-form-label"><span class="x-red">*</span>性別</label>
<label class="radio-inline">
<input type="radio" name="sex" id="sex_men" value="男" title="男">
</label>
<label class="radio-inline">
<input type="radio" name="sex" id="sex_women" value="女" title="女">
</label>
</div>
<div class="layui-form-item">
<label for="group" class="layui-form-label"><span class="x-red">*</span>用戶組</label>
<div class="layui-input-inline">
<select name="user_group" id="group" class="layui-input" required="">
<option value="">請選擇用戶組</option>
{volist name="grouplist" id="group"}
<option value="{$group.id}">{$group.name}</option>
{/volist}
</select>
</div>
</div>
<div class="layui-form-item">
<label class="layui-form-label"><span class="x-red">*</span>用戶狀態</label>
<label class="radio-inline">
<input type="radio" name="status" id="status_1" value="1" title="正常" checked>
</label>
<label class="radio-inline">
<input type="radio" name="status" id="status_0" value="0" title="封禁">
</label>
</div>
<input type="hidden" name="icon" id="icon" value="\static\default_images\user_default_image.jpg">
<div class="layui-form-item">
<button type="button" id="addbtn" class="layui-btn">確認添加</button>
</div>
</form>
</div>
<script src="/static/lib/layui/layui.js" charset="utf-8">
</script>
<script src="/static/js/x-layui.js" charset="utf-8">
</script>
<script type="text/javascript">
layui.use(['form','layer','upload'], function(){
$ = layui.jquery;
var form = layui.form()
,layer = layui.layer;
//圖片上傳接口
layui.upload({
url: '{:url(\'index/user/iconupload\')}' //上傳接口
,success: function(res){ //上傳成功後的回調
console.log(res);
if(res.status==100)
layer.alert(res.message, {icon: 6},function (thiswindow) {
$('#icon_preview').attr('src',res.url);
$('#icon').val(res.url);
layer.close(thiswindow);
});
else
layer.alert(res.message, {icon: 5},function (thiswindow) {
$('#icon_preview').attr('src',res.url);
$('#icon').val(res.url);
layer.close(thiswindow);
});
}
});
form.verify({
nikename: function(value){
if(value.length < 5){
return '暱稱至少得5個字符啊';
}
}
,pass: [/(.+){6,12}$/, '密碼必須6到12位']
});
$('#addbtn').on('click',function () {
var formData = new FormData();
formData.append("nickname",$('#nickname').val());
formData.append("mobile",$('#mobile').val());
formData.append("password",$('#password').val());
formData.append("user_group",$('#group').val());
formData.append("sex",$("input[name='sex']:checked").val());
formData.append("status",$("input[name='status']:checked").val());
formData.append("icon",$('#icon').val());
$.ajax(
{
type:'post',
url: "{:url('index/user/doadd')}",
data: formData,
contentType: false,
cache:false,
processData : false,
beforeSend: function () {
$("#addbtn").attr({ disabled:true });
},
success: function(returndata){
$("#addbtn").attr({ disabled:false });
if(returndata.status==1)
layer.alert(returndata.message, {icon: 6},function (thiswindow) {
parent.location.reload();
layer.close(thiswindow);
});
else
layer.alert(returndata.message, {icon: 5},function (thiswindow) {
layer.close(thiswindow);
});
},
error: function () {
$("#addbtn").attr({ disabled:false });
layer.alert('請求錯誤.請稍後再試', {icon: 5},function (thiswindow) {
layer.close(thiswindow);
});
}
}
)
})
})
</script>
</body>
</html>
這裏預覽圖和隱藏域都有默認值的原因是如果用戶不上傳頭像也有一個默認頭像
②控制器相應方法
public function useradd()
{
$groupList = Db::table('group')->where('status','=',1)->all();
$this->view->assign('grouplist',$groupList);
return $this->view->fetch();
}
public function doadd()
{
if(!Request::isAjax())
return $this->error('請求非法');
$addinfo = Request::param();
$validate = new Validate();
$validate->rule(['nickname|暱稱'=>'require|max:20|min:1','mobile|手機號'=>'require|mobile|unique:user',
'sex|性別'=>'require', 'user_group|用戶組'=>'require','status|狀態'=>'require',
'password|密碼'=>'require|min:6|max:16|alphaDash']);
$checkres = $validate->check($addinfo);
if(!$checkres)
return ['status'=>-1,'message'=>$validate->getError()];
$nowtime = time();
$addinfo['password'] = md5($addinfo['password']);
$addinfo['create_time'] = $nowtime;
$addinfo['update_time'] = $nowtime;
$addresult = Db::table('user')->insert($addinfo);
if($addresult)
return ['status'=>1,'message'=>'用戶添加成功'];
else
return ['status'=>-2,'message'=>'數據庫錯誤'];
}
public function iconupload()
{
$icon = Request::file('iconupload');
if($icon)
{
$info = $icon->validate([
'size'=>10240000,
'ext'=>'bmp,jpg,png,tif,gif,pcx,tga,exif,fpx,svg,psd,cdr,pcd,dxf,ufo,eps,ai,raw,WMF,webp'
])->move('uploads/usericon/');
if($info)
{
$url = "\\uploads\\usericon\\".$info->getSaveName();
return json(['status'=>100,'message'=>'上傳成功','url'=>$url]);
}
else
{
return json(['status'=>-200,'message'=>$icon->getError(),'url'=>'\static\default_images\user_default_image.jpg']);
}
}
}