web.py HTML javascript 多附件上传实现


最近在做网站项目,使用 web.py 架构。需要用到多附件上传功能。

如果是单附件上传:

HTML文件里建立表单 

<form id="save">
<input type="file" id="fj" />
<input type="button" οnclick="tijiao()"/>
</form>

JS将其submit 

function tijiao()
{
    var tmp = document.getElementById("save");
    tmp.submit();
}
后台的web.py接收
data = web.input( fj = { } )
return data.fj.filename

注意这里必须有fj={}才能将上传的附件对象初始化,不然是无法获得fj的文件

但是有时候我们需要多附件上传。


HTML里input支持multiple标签,可以实现多附件。但是相对于浏览器的支持,IE10才支持multiple标签。不得不吐槽国内2亿IE6办公用户,所以我们使用javascript来实现多附件上传。


我考虑的想法是每添加一个附件,就将这个文件input项隐藏,在其上面再创建一个文件input项。这也是通常的实现方法。


HTML里,我们创建此表单

<form id="save">
<div id="MyFile">
<input type="file" id="fj0" name="fj0" οnchange="addFile()"/>
<input id ="fileNameSet" name = "fileNameSet" style="display:none" />
</div>
<table id ="fileTable" name="fileTable" border="0"></table>
<input type-"button" οnclick="tijiao()"/>
</form>

其中fj0是我们上传文件项,至于fileNameSet是我们后面会用到,fileTable是用来记载我们要上传哪些文件,并列出来
javascript:

<script>
    var n=0;    //上传文件的id = fjn           
    var fileCount=1;        
    var tempRow=0;        
    var maxRows=0;         
    var num = 1;             
    function addFile()
    { 
        var str = '<input type="file" id="fj'+num+'" name="fj'+num+'" οnchange="addFile()"/>';    //建立一个待会要插入的字符串
        var fileText;       
        var ary;            
        var fileTextValue;  
        fileText = document.getElementById("fj"+n).value;  //获取文件总名称,包括路径
        ary = fileText.split("\\");   //将文件名按\分割成数组               
        fileTextValue = ary[ary.length-1];  //获取文件名称
        document.all("fj" + n).style.display = "none";  //将该文件input项设置为隐藏
        
       
        document.getElementById('MyFile').insertAdjacentHTML("beforeEnd",str);  //之后插入一个新的文件input项,id为fjn 其中n是数字1,2,3...
        tempRow=fileTable.rows.length-1;    //接下来这几步都是将上传的文件名记载道fileTable里
    maxRows=tempRow; 
    tempRow=tempRow+1; 
        var Rows=fileTable.rows;            //获得Rows对象
        var newRow=fileTable.insertRow(fileTable.rows.length);  //table新建一行
        var Cells=newRow.cells;           //获得该行单元格对象                        
        for (i=0;i<3;i++)                                         
        { 
          var newCell=Rows(newRow.rowIndex).insertCell(Cells.length); 
          newCell.align="center"; 
          switch (i)    //插入三个单元格,分别是第一个用来写入文件名称,第二个是添加删除按钮(你不需要上传时)
          { 
            case 0 : newCell.innerHTML="<td width='40%' align='left'><span id='"+n+"'></span></td>";
                   break; 
            case 1 : newCell.innerHTML="<td width='20%' align='left'><a href='javascript:delTableFileRow(\"" + n + "\")'>删除</a></td>";
                   break; 
            case 2 : newCell.innerHTML="<td width='40%' align='left'> </td>"; 
                   break; 
          } 
        } 
        maxRows+=1;
        document.getElementById(n).insertAdjacentText("beforeEnd",fileTextValue);   //将文件名写入第一个单元格
        n++;
        num++;
        fileCount++;
     }
    function delTableFileRow(fileNum)   //这是删除功能
    {  
    var tn = document.getElementById(fileNum);
    fileTable.deleteRow(tn.parentElement.parentElement.rowIndex);   //获得该行的行号并删除
    document.all("MyFile").removeChild(document.getElementById("fj"+fileNum)); //将对应的文件input项也删除
    fileCount--;                    //总数 -1
    }   
</script>
提交时,我们要获得我们需要上传的文件的名称

<script>
    function tijiao()   
    {
    tempLen=fileTable.rows.length;  
    var fileRows=fileTable.rows;    //获得表的rows对象
    for(var i=0;i<tempLen;i++)
    {
        document.getElementById("fileNameSet").value += fileRows[i].cells[0].childNodes[0].innerHTML + ","; //把该文件名写入fileNameSet里
    }
    var subform = document.getElementById("save");
    subform.submit();
    }   
</script>

重点就是web.py后台如何获得文件内容和文件名
因为多附件上传,web.input很难将每个文件对象都初始化,你不清楚附件的数量与对象名称。虽然对象没有初始化,也只是它会缺失某些属性,而它的内容依旧可以传进来。所以我们只需要将文件名称传进来 如果你需要的话,就是之前的fileNameSet里的值。而获得文件内容便需要一个关键的函数getattr(obj,attr,default),这个函数是如果obj对象下有attr属性,则返回attr的值,否者返回我们设定的default值。上传多附件中的文件input项可能有fj0,fj1,fj2... 也可能我们中途不想上传某文件,删除其中一个,就是上面的javascript里fileTable里的delTableFileRow()函数删除。所以可能只是ID为fj0,fj2的文件input项留下来,所以我们需要判断fjn是否是web.input()返回对象的属性,来获得文件内容。

data = web.input()
n = 0
fileNum = 0 #这变量用来传输文件名称用的计数
fileName = data.fileNameSet.split(',')  #传进来文件名称,将其分割成文件名数组
while fileNum<fileName.length:   #如果fileNum=fileName.length说明文件已经操作完毕
    fjID = "fj"+`n`
    fjAttr= getattr(data,fjID,'')   #找到data下的属性是否有fj0,fj1...没有返回''
    if fjAttr != '' :
        #这里便找到了你需要的fj内容,可以对其进行任意操作,存入数据库之类
        #mydb.db.insert("fj", fjName = fileName[fileNum], fj = fjAttr)  #这里fjAttr就是附件的内容,fjName就是附件名称
        fileNum = fileNum + 1
    n = n + 1

到此,我们便成功获得多文件内容和名称(名称主要是记录文件的格式)



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值