Submitting a form via JSON I have a file named feedback.js that I would like to improve.

function feedback(feedbackform) {

    // collect the feedbackform data while iterating over the inputs
    var data = {};
    for (var i = 0; i &lt; feedbackform.length; i++) {
        var input = feedbackform[i];
        if (input.name &amp;&amp; input.value) {
            data[input.name] = input.value;
        }
    }

    // construct an HTTP request
    var xhr = new XMLHttpRequest();
    xhr.open(feedbackform.method, feedbackform.action);
    xhr.setRequestHeader('Content-Type', 'application/json; charset=UTF-8');
    // send the collected data as JSON
    xhr.send(JSON.stringify(data));
    feedbackform.send.disabled = true;

    xhr.onloadend = function () {
        if (xhr.status == 200) {
            feedbackform.send.value = "Sent!";
            feedbackform.send.className = "success";
        } else {
            feedbackform.send.value = "Failed to send";
            feedbackform.send.className = "fail";
        }
    };

    return false;
}



Is there a modern way to collect form inputs? E.g. json enctype?
Is disabling the submit button a good idea to prevent multiple form submissions?
If the form fails to send, what's a good recourse (to prevent data loss of the filled form) I can give the user? Perhaps munge it into a mailto: command?


Are there any other tweaks I can make without relying on any dependencies, such as trying to reduce code size?
Fetch API is now supported by Firefox, Chrome and Opera, you could use it instead of the ugly XMLHttpRequest. How ironic, by the way, is using XMLHttpRequest to make a JSON reqest?




var data = {};



Since you likely won't be reassigning this variable, you could use const instead. The same is true for var xhr = new XMLHttpRequest();.



for (var i = 0; i &lt; feedbackform.length; i++) {
    var input = feedbackform[i];
    if (input.name &amp;&amp; input.value) {
        data[input.name] = input.value;
    }
}


First, that's a perfect use case for a for...of loop. Secondly, if you want to check if a string is empty, it's better to explicitly compare it with an empty string.

I would rewrite this loop like this:

for (let input of feedbackform) {
  if (input.name !== "" &amp;&amp; input.value !== "") {
    data[input.name] = input.value
  }
}





feedbackform.send.disabled = true;



It's better to disable the whole form, instead of just the submit button. Did you know that you can submit a form by pressing Enter while focused in an input?




xhr.onloadend = function () {}



Oh come on, it's the 21st century! Why do you still use .onevent properties? You should totally drop that and try jQuery .addEventListener(). See addEventListener vs onclick.

You can also use an arrow function here.

I would rewrite it like this:

xhr.addEventListener("loadend", () =&gt; {
  // event listener code
})





if (xhr.status == 200) 



Always use three-equals operator (===) for equality comparisons. See Does it matter which equals operator (== vs ===) I use in JavaScript comparisons?.

Besides, 200 isn't the only status code which means that request was successful. There is for example status code 204—No Content. Therefore, you should be checking whether the status code is in 200-299 range:

if (xhr.status &gt;= 200 &amp;&amp; xhr.status &lt; 300)





return false;



What purpose does it serve?