yield生成器生成表单字段,并进行验证,利用fetch方法和formData对象传递数据给后端,后端返回成功,返回数据

这里主要利用生成器函数生成配置的表单字段;然后设置验证规则;验证用户填写的数据信息;

验证通过后,利用fetch异步传递方法将formdata数据传给后端;后端再进行验证返回数据

formfieldgenerator.js文件

javascript 复制代码
//生成器函数,主要用于生成表单的各字段
//参数fields是字段配置表
function * formFieldGenerator(fields)
{
    for(const field of fields)
    {
        let fieldHtml='';
        switch(field.type)
        {
            case 'text':
            case 'email':
            case 'password':
                fieldHtml=`<div class="${field.className||''}"><label>${field.label} <input type="${field.type}" name="${field.name}" value="${field.value||''}" placeholder="${field.placeholder||''}" autocomplete="off"></label><p id="${field.name}"></p></div>`;
                break;
            case 'textarea':
                fieldHtml=`<div class="${field.className||''}"><label>${field.label}<textarea name="${field.name}" rows="${field.rows||5}" cols="${field.cols||10}" placeholder="${field.placeholder||''}"></textarea></label></div>`;
                break;
            case 'checkbox':
                fieldHtml=`<label><input type="${field.type}" name="${field.name}" value="${field.value}">${field.label}</label>`;  
                break;
            case 'submit':
                fieldHtml=`<div class="${field.className||''}"><label><input type="submit" name="${field.name}" id="${field.id}" value="${field.value}"></label></div>`;
                break;
            case 'button':
                fieldHtml=`<div class="${field.className||''}"><label><input type="button" name="${field.name}" id="${field.id}" value="${field.value}"></label></div>`;
                break;
            default:
                fieldHtml=`<!--不支持的字段类型:${field.type}>`;                          
        }
        //最后一定要yield fieldHtml
        yield fieldHtml;
    }
}
//验证各字段用户填写的数据,如果验证没通过isValid返回假,验证通过isValid返回true
function validateForm(formData)
{
    let isValid=true;
    //各段的错误信息
    let msg={
        usernameMsg:'',
        pwdMsg:'',
        pwd2Msg:'',
        emailMsg:'',
    };
   
    let firtPwd='';
    for(const field of formData)
    {
        const inputEle=document.querySelector(`[name="${field.name}"]`);
        
        if(!inputEle){continue;}
        //获取字段名进行验证
        switch(field.name)
        {
            case 'username':
                let user=document.getElementById('username');
                if(inputEle.value.trim().length<=4 || inputEle.value.trim().length>=21)
                {
                    isValid=false;
                    msg.usernameMsg='账户介于5-20个字符之间';
                }
                if(/^[\u4e00-\u9fa5]+$/.test(inputEle.value.trim()))
                {
                    isValid=false;
                    msg.usernameMsg='账户不支持汉字';
                }
                if(msg.usernameMsg!=='')
                {
                    user.innerText=msg.usernameMsg;
                }else
                {
                    msg.usernameMsg='';
                    user.innerText='';
                    user=null;
                }
                formdata.append('username',inputEle.value.trim());
                break;
            case 'pwd':
                let p2=document.getElementById('pwd');
                if(inputEle.value.trim().length<6||inputEle.value.trim().length>21)
                    {
                        isValid=false;
                        msg.pwdMsg='密码介于6-20个字符';
                    } 
                if(!/[A-Z]/.test(inputEle.value.trim()))
                    {
                        isValid=false;
                        msg.pwdMsg='密码必须包含大写字符';
                    } 
                if(msg.pwdMsg!=='')
                    {
                        p2.innerText=msg.pwdMsg;
                    }else
                    {
                        msg.pwdMsg='';
                        p2.innerText='';
                        p2=null;
                    }
                    firtPwd=inputEle.value.trim();
                    formdata.append('pwd',inputEle.value.trim());
                break;
            case 'pwd2':
                let p3=document.getElementById('pwd2');
                if(inputEle.value.trim().toString()!==firtPwd.toString())
                    {
                        isValid=false;
                        msg.pwd2Msg='两次密码不一致';
                    }
                if(msg.pwd2!=='')
                    {
                        p3.innerText=msg.pwd2Msg;
                    }else
                    {
                        msg.pwd2Msg='';
                        p3.innerText='';
                        p3=null;
                    }    
                break; 
            case 'email':
                let mail=document.getElementById('email');
                if(inputEle.value.trim()==='')
                    {
                        isValid=false;
                        msg.emailMsg='邮件不能为空';
                    }                 
                if(!/^\w+([-+.]\w+)*@\w+([-.]\w+)*.\w+([-.]\w+)*/.test(inputEle.value.trim()))
                    {
                        isValid=false;
                        msg.emailMsg='邮件格式不正确';
                    }    
                if(msg.emailMsg!=='')
                    {
                        
                        mail.innerText=msg.emailMsg;
                    }else
                    {
                        mail.innerText='';
                        msg.emailMsg='';
                        mail=null;
                    }
                    formdata.append('email',inputEle.value.trim());
                break;        
        }
    }
    //所有验证都通过则返回true
    return isValid;
}
//字段配置表,根据自己的需要进行配置
const formFields=[
    {name:'username',type:'text',placeholder:'用户名',label:'账&emsp;号&emsp;',className:'regInput'},
    {name:'email',type:'email',placeholder:'电子邮件',label:'邮&emsp;件&emsp;',className:'regInput'},
    {name:'pwd',type:'password',label:'密&emsp;码&emsp;',className:'regInput'},
    {name:'pwd2',type:'password',label:'重复密码',className:'regInput'},
    {name:'checkbox',name:'agree',type:'checkbox',label:'同意条款',value:'yes'},
    {name:'btn',type:'submit',value:'提交',id:'btn1',className:'regInput'},
    
];

//创建表单
const formHtml=document.createElement('form');
//设置表单属性
formHtml.setAttribute('method','post');
formHtml.setAttribute('name','form1');
formHtml.setAttribute('id','form1');
//将表单字段做为参数给到生成器函数,并添加入表单
formHtml.innerHTML=Array.from(formFieldGenerator(formFields)).join('');
let container=document.getElementById('container');
//做为字元素添加到html内
container.appendChild(formHtml);

let btn=document.getElementById('btn1');
//为表单添加事件
formHtml.addEventListener('submit',function(event){
    
    event.preventDefault();
    //除去提交按钮
    const formData=formFields.filter(field=>field.type!=='submit');
    //如果验证都通过则将表单给FormData()对象进行序列化
   if(validateForm(formData))
   {
   //防止第2次提交,禁止提交按钮
    btn.disabled=true;
    let form1=document.getElementById('form1');
    
    let formVal=new FormData(form1);
    //检查FormData()对象里面的是否有表单各项与值
    for(let xx of formVal.entries())
        {
            console.log(xx);
        }
        //添加标头,如果是FormData()提交一要写form-data,千万不能写错了,其它的后端接收不到值为空
        //你也可以不写标头,让fetch自行判断
    let jsonheader=new Headers({
        "Content-Type":"application/form-data"
    });
        fetch('formfieldgenerator.php',{
            method:'POST',
            body:formVal
        })
        .then((response)=>{
            if(response.ok && response.status===200)
                {
                    return response.json();
                }
            throw new Error('返回数据错误');    
        })
        .then((data)=>{
            let result=JSON.stringify(data);
            let res=JSON.parse(result);
            console.log(res.username);
        }).catch(error=>{
            console.log('连接服务器时发生错误!',error);
        })
        
   }else
   {
    
        console.log('表单验证失败');
   }
    
});

//有端index.html

html 复制代码
<!DOCTYPE html>
<html lang="en">
    <head>
        <meta http-equiv="content-type" content="text/html;charset=UTF-8">
        
        <title>用生成器生成表单</title>
        <style type="text/css">
            #container
            {
                width: 1050px;
                margin: 5px auto;
                border: 1px solid red;
                text-align: center;
                font-size: 16px;
                padding-top:10px;
            }
            .regInput
            {
                margin-bottom: 15px;
            }
            .regInput label
            {
                font-family: Arial, Helvetica, sans-serif;
            }
            .regInput input
            {
                text-indent: 5px;
                
            }
            .btn1
            {
                margin-top: 15px;
            }
        </style>
    </head>
    <body>
        <div id="container">
            
        </div>
        <script src="formfieldgenerator.js"></script>
    </body>
</html>

后端代码formfieldgenerator.php

php 复制代码
<?php

if($_SERVER['REQUEST_METHOD']==='POST')
{
    $username=$_POST['username'];
    $pwd=$_POST['pwd'];
    $email=$_POST['email'];
    if(isset($username) && isset($pwd) && isset($email))
    {
        $data=array('username'=>$username,'pwd'=>$pwd,'email'=>$email);
        echo json_encode($data);
    }else
    {
        echo '没有';
    }
    
}else
{
    echo 'no';
}

?>    
相关推荐
Jiaberrr4 分钟前
Vite环境下uniapp Vue 3项目添加和使用环境变量的完整指南
前端·javascript·vue.js·uni-app
Marry1.012 分钟前
uniapp背景图用本地图片
前端·uni-app
2401_8543910815 分钟前
城镇住房保障:SpringBoot系统功能概览
java·spring boot·后端
hummhumm16 分钟前
Oracle 第29章:Oracle数据库未来展望
java·开发语言·数据库·python·sql·oracle·database
夏河始溢18 分钟前
一七八、Node.js PM2使用介绍
前端·javascript·node.js·pm2
记忆深处的声音18 分钟前
vue2 + Element-ui 二次封装 Table 组件,打造通用业务表格
前端·vue.js·代码规范
陈随易19 分钟前
兔小巢收费引发的论坛调研Node和Deno有感
前端·后端·程序员
wainyz25 分钟前
Java NIO操作
java·开发语言·nio
工业3D_大熊31 分钟前
【虚拟仿真】CEETRON SDK在船舶流体与结构仿真中的应用解读
java·python·科技·信息可视化·c#·制造·虚拟现实
熊的猫34 分钟前
webpack 核心模块 — loader & plugins
前端·javascript·chrome·webpack·前端框架·node.js·ecmascript