[JavaScript] 空のGETパラメータを送信しない方法

以前投稿した方法は、jQuery に依存していたので、Vanilla で実装し直してみた。

方法

前提

こんな感じのフォームがある。

<form name="form1">
  <input name="hoge1" type="text" />
  <input name="hoge2" type="text" />
  <input name="hoge3" type="text" />
  <input name="hoge4" type="text" />
  <input type="submit" />
</form>

このフォームのhoge1だけ入力してサブミットするとパラメータが以下のようになる。

?hoge1=a&hoge2=&hoge3=&hoge4=

未入力のパラメータは以下のように消したい。

?hoge1=a

コード

document.forms.form1.addEventListener("submit", clean_query);

function clean_query(e) {
  e.preventDefault();
  this.removeEventListener("submit", clean_query);
  var query = serialize(this);
  location.href =
    this.action +
    "?" +
    (function () {
      var arr = [];
      [].forEach.call(query.split("&"), function (item) {
        if (item.split("=")[1]) {
          arr.push(item);
        }
      });
      return arr.join("&");
    })();
}

function serialize(form) {
  var s = [];
  if (typeof form !== "object" && form.nodeName.toUpperCase() !== "FORM") {
    return s;
  }

  var length = form.elements.length;
  for (var i = 0; i < length; i++) {
    var field = form.elements[i];
    if (
      field.name &&
      !field.disabled &&
      field.type != "file" &&
      field.type != "reset" &&
      field.type != "submit" &&
      field.type != "button"
    ) {
      if (field.type == "select-multiple") {
        var l = form.elements[i].options.length;
        for (var j = 0; j < l; j++) {
          if (field.options[j].selected) {
            s[s.length] =
              encodeURIComponent(field.name) +
              "=" +
              encodeURIComponent(field.options[j].value);
          }
        }
      } else if (
        (field.type != "checkbox" && field.type != "radio") ||
        field.checked
      ) {
        s[s.length] =
          encodeURIComponent(field.name) +
          "=" +
          encodeURIComponent(field.value);
      }
    }
  }
  return s.join("&").replace(/%20/g, "+");
}