我们都知道<input type="file" >显示的效果不仅很难看,而且在各种浏览器下面也不尽相同,作为一个完美主义者,你肯定很不想用它展示给自己亲爱的客户,于是乎呢就想到了这样的效果:
点击图片就可以弹出文件选择对话框,跟原先的比起来逼格瞬间翻倍了有木有!
现在来捋一捋要面临的问题:
-
点击图片如何弹出文件选择框?
-
在文件选择框里面选择了图片后我如何马上在页面上回显出来?
先看第一个问题,很简单的解决方案:
先看html:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="<%=request.getContextPath() %>/resources/jquery-1.12.4.min.js" ></script>
<script src="<%=request.getContextPath() %>/resources/js/jquery-form.js" ></script>
<title>test</title>
<style>
.plus{
display:inline-block;
width: 94px;
height: 94px;
line-height: 94px;
border:1px solid #ccc;
text-align: center;
cursor: pointer;
overflow: hidden;
}
img{
width: 92px;
}
</style>
</head>
<body>
<form method="post" enctype="multipart/form-data"
action="backend/saveBusinessLicenseImg" id="fileUploadForm">
<span class="label">营业执照/企业资质证明:</span>
<span class="plus">
<img id="business_license_img" onclick="fileSelect()" data-path=""
src="<%=request.getContextPath() %>/resources/imgs/plus.png">
<input type="file" name="business_license" id="business_license"
onchange="fileSelected()" style="display:none;">
</span>
</form>
</body>
</html>
js代码:
<script type="text/javascript">
function fileSelect() {
document.getElementById("business_license").click();
}
function fileSelected() {
alert("选中");
}
</script>
仅仅需要上边这么多,点击加号的时候就可以弹出文件选择对话框了:
第一个问题解决了,那么怎么回显呢?也就是前边提出的第二个问题怎么解决呢?可以这样子做:在文件选中后,提交表单,直接上传到服务器上,再把上传后的路径返回替换原来的img标签的src属性就可以了。我们修改fileSelected()js函数:
function fileSelected() {
if($("#business_license").val()){
$("#fileUploadForm").ajaxSubmit(function(data) {
$("#business_license_img").prop("src","<%=request.getContextPath() %>"+data.projectPath);
});
}
}
这里我用到了jquery-form.js这个ajax提交表单的插件来通过ajax的形式上传文件,它会提交到id="fileUploadForm"的form标签的action所指定的地址,后台地址返回了所选择图片上传后的路径,把这个路径作为img的src值,就可以回显所上传的图片了。效果如图:
到这里,上边两个问题就解决了。
附上jquery-form插件的使用
当牵涉到上传文件到后台的时候,纯碎的ajax或者jquery的ajax就显得无能为力了,这时候可以使用很多优秀的form提交插件,这次要说的jquery-form插件就是其中的一个。
强大之处:他可以以ajax的形式提交同时含有type=file的表单元素和普通表单元素的表单
如何使用呢?我通过一个简洁的例子还说明,有多简洁呢?一遍看不懂来找我。
页面效果如下图:
先看下页面的html代码:
<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet"
href="<%=request.getContextPath() %>/resources/bootstrap/css/bootstrap.min.css">
<link rel="stylesheet" href="<%=request.getContextPath() %>/resources/css/common.css">
<script src="<%=request.getContextPath() %>/resources/jquery-1.12.4.min.js" ></script>
<script src="<%=request.getContextPath() %>/resources/js/jquery-form.js" ></script>
<script src="<%=request.getContextPath() %>/resources/bootstrap/js/bootstrap.min.js" >
</script>
<title>test</title>
<style>
.h45{
height:45px;
line-height:45px;
border-bottom: 1px solid #ccc;
font-size:18px;
font-weight: bold;
}
.addpro{
display: inline-block;
margin-left: 50px;
font-size:14px;
font-weight: normal;
color:blue;
}
.datagrid{
padding-top:15px
}
.container-fluid{
padding:0;
}
.addForm{
padding-top:15px
}
.control-label{
text-align: left !important;
padding-left:35px;
font-weight: normal;
}
label.control-label{
cursor: pointer;
}
#left_arrow{
width:45px;
display: inline-block;
}
#fileUploadForm>div.form-group{
padding-left:28px;
}
.inline{
display: inline-block;
height: 25px;
width:100px;
}
</style>
</head>
<body>
<div class="container-fluid">
<h2 class="h45"><span id="left_arrow">
<img src="<%=request.getContextPath() %>/resources/imgs/left_arrow.png"></span>新建商家
</h2>
<section class="addForm">
<form class="form-horizontal" method="post" enctype="multipart/form-data"
action="backend/save" id="fileUploadForm" >
<div class="form-group">
<label for="name" class="col-md-2 control-label">商家名称:</label>
<div class="col-md-4">
<input type="text" class="form-control input-sm" id="name" name="name">
</div>
</div>
<div class="form-group">
<label for="business_license" class="col-md-2 control-label">营业执照/企业资质证明:
</label>
<div class="col-md-4">
<input type="file" name="business_license" id="business_license" >
</div>
</div>
<div class="form-group">
<label class="col-md-2 control-label">成立年限:</label>
<div class="col-md-8">
<input type="text" class="form-control input-sm inline" name="age_start">
-
<input type="text" name="age_end" class="form-control input-sm inline">年
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="button" class="btn btn-info" id="commit" value="确认">
</div>
</div>
</form>
</section>
</div>
</body>
</html>
这里为了页面的美观性,我使用了bootstrap,你要不想用直接去掉就好了。
关键的是js代码,jquery-form怎么使用呢,就在下面这里了:
<script type="text/javascript">
$("#commit").click(function(){
var obj={"person_num":1000};
var options = {
beforeSubmit: beforeSubmitFun, //提交前的回调函数
success: successFun, //提交后的回调函数
url: "backend/save", //可覆盖form的action
type: "post", //可覆盖form的method
extraData:obj,//提交到后台时除了form中的表单元素数据,还会加上extraData属性指定的obj里面定义的数据
dataType: 'json', //html(默认), xml, script, json...不可自动转换,需要指定正确的类型
clearForm: true, //成功提交后,清除所有表单元素的值
//resetForm: true, //成功提交后,重置所有表单元素的值
timeout: 3000 //限制请求的时间,当请求大于3秒后,跳出请求
};
function beforeSubmitFun(formData, jqForm, options){ //可做校验工作
//formData: 数组对象,提交表单时,Form插件会以Ajax方式自动提交这些数据,
//格式类似:[{name: "name", value: "2", type: "text", required: false}...]
//jqForm: jQuery对象,封装了表单的元素
//options: 就是上边配置的 options对象
// var queryString = $.param(formData); //转化后格式类似:name=1&age_start=2
// var formElement = jqForm[0]; //将jqForm转换为DOM对象
// var age_start = formElement.age_start.value; //取到值
//提交到后台的额外数据除了可以在定义options的时候通过extraData指定,还可以在这里指定
var age=formData[2]["value"]+"-"+formData[3]["value"]+"年";
obj["age"]=age;
options.extraData=obj;
return true; //只要不返回false,表单都会提交,在这里可以对表单元素进行验证
};
function successFun(responseText, statusText){
if(responseText.status=="success"){
//$("#fileUploadForm")[0].reset();
alert("添加成功");
}else{
alert("添加失败");
}
};
$("#fileUploadForm").ajaxSubmit(options);
});
</script>
应该注意的地方我都写了注释,辛苦啊。提交的url“backend/save”是java代码,用于把上传的文件保存到服务器上以及接受参数,如下:
@RequestMapping("/save") @ResponseBody
public Map<String, Object> toAddAd(@RequestParam("business_license") MultipartFile file,
HttpServletRequest request){
Map<String, Object> retMap=new HashMap<String, Object>();
try{
String originalFilename = file.getOriginalFilename();
if (StringUtils.isNotBlank(originalFilename)) {//把文件保存到工程目录下
String absPath = request.getSession().getServletContext().
getRealPath("/resources/uploads/"+originalFilename);
File destFile=new File(absPath);
CommonsMultipartFile commonsMultipartFile=(CommonsMultipartFile) file;
DiskFileItem diskFileItem=(DiskFileItem) commonsMultipartFile.getFileItem();
diskFileItem.write(destFile);
}
//其他参数的获取
String name=request.getParameter("name");
System.out.println("名字:"+name);
System.out.println("员工数:"+request.getParameter("person_num"));
System.out.println("成立年限:"+request.getParameter("age"));
retMap.put("status", "success");
}catch(Exception e){
e.printStackTrace();
retMap.put("status", "error");
}
return retMap;
}
好的,这就是jquery-form的绝大部分用法了。