web开发之利用jquery-ajax传输表单数据

15 Aug 2020

表单的重要性不言而喻了吧,开发任何项目都要用到

1.ajax表单提交

最近一个项目必须用传统的html方式开发

一开始我用到了jQuery的一个插件做表单提交:jQuery Form

后来发现这个提交的是原始的字符串类型的参数,不便于后台处理

我需要的是json,因为我有一个name有多个input多个value的情况,还有多选,我想做成数组提交到mongodb

情况如下

  <label for="dingDianYiYuan" class="form-label">定点医院</label>
    <input type="text" class="form-control" id="dingDianYiYuan" name="dingDianYiYuan" placeholder="定点医院1" required="">
    <input type="text" class="form-control mt-1" id="dingDianYiYuan" name="dingDianYiYuan" placeholder="定点医院2" required="">
    <input type="text" class="form-control mt-1" id="dingDianYiYuan" name="dingDianYiYuan" placeholder="定点医院3" required="">
    <div class="invalid-feedback">
      请填写定点医院
    </div>

随后我找到了如下解决方案,正是我想要的

有时候需要将表单Form的input、select、textarea等标签的数据,转化成json格式的数据,以便操作,Jquery的serializeArray 方法已经可以实现将Form的数据序列化为一个数组,只要稍微在这个方法的基础上做些修改即可转化为js的object对象。

方法1

$.fn.serializeObject = function(){
   var o = {};
   var a = this.serializeArray();
   $.each(a, function() {
       if (o[this.name] !== undefined) {
           if (!o[this.name].push) {
               o[this.name] = [o[this.name]];
           }
           o[this.name].push(this.value || '');
       } else {
           o[this.name] = this.value || '';
       }
   });
   return o;
}

方法2

var data = {};
$("form").serializeArray().map(function(x){
	if (data[x.name] !== undefined) {
       if (!data[x.name].push) {
           data[x.name] = [data[x.name]];
       }
       data[x.name].push(x.value || '');
   } else {
       data[x.name] = x.value || '';
   }
});

作者:长跑茗 链接:https://www.cpming.top/p/convert-form-data-to-javascript-object-with-jquery

我选择了更为直观的方法二

最终我的代码如下

    // Example starter JavaScript for disabling form submissions if there are invalid fields
  (function () {
    'use strict'

    // Fetch all the forms we want to apply custom Bootstrap validation styles to
    var forms = document.querySelectorAll('.needs-validation')

    // Loop over them and prevent submission
    Array.prototype.slice.call(forms)
      .forEach(function (form) {
        form.addEventListener('submit', function (event) {
          //bootstrap验证不通过的逻辑
          if (!form.checkValidity()) {
            // 这里阻止浏览器默认的表单提交操作
            event.preventDefault()
            event.stopPropagation()
          }else{
          // else执行通过的逻辑,即发送ajax请求
            event.preventDefault()
            event.stopPropagation()
            //1这里声明一个data对象,用上面提到的方法把myform的值包装到这个data对象里
            var data = {};
            $("#myform").serializeArray().map(function(x){
              if (data[x.name] !== undefined) {
                    if (!data[x.name].push) {
                        data[x.name] = [data[x.name]];
                    }
                    data[x.name].push(x.value || '');
                } else {
                    data[x.name] = x.value || '';
                }
            })
            //2输出后发现这个data可以完美的把多个name相同的input包装成数组,但是是一个普通对象需要序列化成json字符串
            console.log(data)
            $.ajax({
              method: 'POST',
              target: '#myResultsDiv',
              url: '/personInfo',
              contentType: "application/json;charset=utf-8",
              //3在这里做了序列化和传入data的操作(jquery:options对象的data属性)
              data:JSON.stringify(data),
              //这里解决的是登录过期不跳转和提交成功的刷新的问题
              success: (message) => {
                  if(message != "success"){
                    window.alert("提交失败,登录过期")
                  }
                  window.location.reload()
                },
              //错误回调这里也一样,也可以用promise的then但是用jq自带的options写我觉得更直观因为后续没有太复杂的回调
              error: _ => window.alert("提交失败,请检查填写或网络")
            });
          }

          form.classList.add('was-validated')
        }, false)
      })
    })()

最外面的函数是bootstrap官网上表单提交验证部分的代码,链接

// Example starter JavaScript for disabling form submissions if there are invalid fields
(function () {
  'use strict'

  // Fetch all the forms we want to apply custom Bootstrap validation styles to
  var forms = document.querySelectorAll('.needs-validation')

  // Loop over them and prevent submission
  Array.prototype.slice.call(forms)
    .forEach(function (form) {
      form.addEventListener('submit', function (event) {
        if (!form.checkValidity()) {
          event.preventDefault()
          event.stopPropagation()
        }

        form.classList.add('was-validated')
      }, false)
    })
})()

现在说一说成功失败回调函数那里,因为我发现登录过期302以后页面不会自动跳转,于是查阅jq的文档发现status code这个option属性,但是经过测试并不能成功触发,查了相关资料有很多人表示只能判断出失败和成功,虽然是302,但是只有get请求能自动跳,而且转经过浏览器一番操作jq只能拿到200,要么就只能改jq源码,于是曲线救国,如果存进数据库就返回sucess字符串,如果前端没收到就刷新页面,刷新页面就会强制跳转,不过表单本身就需要reset,区别成了没有返回success字符串就alert提示重新登陆,只要成功就刷新,一举两得,保证了客户体验

2. 一些操作表单元素的小技巧

保留两位小数

// 2.不四舍五入 向下取整
num = Math.floor(num * 100) / 100;
console.log(num); //2.44
console.log(typeof num); // number

设置Input标签Date默认值为当前时间

$(document).ready(function () {
  var time = new Date();
  var day = ("0" + time.getDate()).slice(-2);
  var month = ("0" + (time.getMonth() + 1)).slice(-2);
  var today = time.getFullYear() + "-" + (month) + "-" + (day);
  $('#date_info').val(today);
})

textarea框限制字数

<textarea rows="5"  maxlength="200" οnchange="this.value=this.value.substring(0, 200)" οnkeydοwn="this.value=this.value.substring(0, 200)" οnkeyup="this.value=this.value.substring(0, 200)" ></textarea>

** 备注:onchange、onkeydown、onkeyu三者缺一不可。**

如省略onchange,当你用复制功能,此时一直按着ctrl不松开,鼠标去点击其他地方(焦点移出textarea)时,不会自动取消超出部分;

如省略onkeydown,快速录入的时候会有很多个字符突然不见;

如省略onkeyup,原想预计200的情况下,会变成201,并且最后一个字符是最后敲进去的。

Maxlength 也不可省略,加上maxlength 当碰到IE10及以上版本时,可以完美的实现限制输入框字数的功能。不像其他低版本的IE浏览器还可能出现一个字母后消失。

扩展阅读:

  1. jQuery Form:https://www.npmjs.com/package/jquery-form
  2. Javascript将Form数据转化成Json对象:https://www.cpming.top/p/convert-form-data-to-javascript-object-with-jquery
  3. Validation:https://getbootstrap.com/docs/5.0/forms/validation/?#custom-styles
  4. HTML textarea框限制字数的两种方式:https://blog.csdn.net/langzhiyao/article/details/102930368
  5. 设置Input标签Date默认值为当前时间:https://www.cnblogs.com/jcydd/p/10565712.html
  6. js保留两位小数方法总结:https://www.cnblogs.com/le220/p/9756881.html

如有侵权联系删除

创作不易,感谢支持

请选择支付方式
USD

比特币-打赏地址:

1DGiAzDacFRxewyos23C14cKcgD5LGZ5hK

狗币-打赏地址:

DRpHTcQXKcauPktjz9WMALST3Vnf5SviDs

以太坊-打赏地址:

0xd34447399c497337a61eccb29cc2ef3e0dad7d13

其他加密货币-打赏地址:

coming soon