2

I have some input fields outside the form. using HTML5 form attribute

<form id="myform">
    <input type="text" name="mytext" />
    <input type="submit" value="test" />
</form>
<input form="myform" type="hidden" name="extra" id="extra" value="777" />
<select form="myform" name="filter" id="filter">
    <option>1</option>
    <option>2</option>
    <option>3</option>
</select>

and try serialize form on submit

$('#myform').on('submit', function (e) {
    var query = $(this).serialize();
    if ($.browser.msie) { 
        //fixed form attribute not supported in IE
        var extra = $('[form=myform]').each(function () {
            if (/(=)\w*/gi.test(query)) query += '&';
            query += this.name + '=' + this.value;
        });
    }
    console.log(query);
    return false;
});

but currently http://api.jquery.com/jquery.browser/ said

"This property was removed in jQuery 1.9 and is available only through the jQuery.migrate plugin. Please try to use feature detection instead."

so how do I detect that browser suppport this form attribute feature? or is there a better approach to do this

aifarfa
  • 3,939
  • 2
  • 23
  • 35

3 Answers3

2

If you would like to check for the form attribute without using an external plugin or library you could try the following:

Change:

if ($.browser.msie) { 

To:

if ($("#extra")[0].form === null) {

See document.getElementById vs jQuery $() for more information on why $("#extra")[0] is used.

Resulting in:

$('#myform').on('submit', function (e) {
    var query = $(this).serialize();
    if ($("#extra")[0].form === null) { 
        //fixed form attribute not supported in IE
        var extra = $('[form=myform]').each(function () {
            if (/(=)\w*/gi.test(query)) query += '&';
            query += this.name + '=' + this.value;
        });
    }
    console.log(query);
    return false;
});

JS Fiddle:

http://jsfiddle.net/ezq9mu1a/1/

As far as I am aware this is the sort of check that Modernizr does (although I think it dynamically creates the input to test on). Running this fiddle in IE triggers the fallback code while Safari, Chrome, Firefox and Opera just use serialize.

EDIT

As we can't rely on an existing element in the page we will need to create a test form and input for the purposes of checking if the form attribute is supported. To do this we can modify the code in the following way:

Add:

//Create test elements and amend them to the DOM
var testForm = $('<form />', { 'id': "testForm" })[0];
var testInput = $('<input />', { 'form': "testForm" })[0];
$('body').append(testForm, testInput);
//Set a variable to store whether the form attribute is supported
var formSupported = (testInput.form !== null) ? true : false;
//Remove the test elements from the DOM
$(testForm).remove();
$(testInput).remove(); 

Change:

if ($("#extra")[0].form === null) {

To:

if (!formSupported) {

Resulting in:

//Create test elements and amend them to the DOM
var testForm = $('<form />', { 'id': "testForm" })[0];
var testInput = $('<input />', { 'form': "testForm" })[0];
$('body').append(testForm, testInput);
//Set a variable to store whether the form attribute is supported
var formSupported = (testInput.form !== null) ? true : false;
//Remove the test elements from the DOM
$(testForm).remove();
$(testInput).remove();

if (!formSupported) {
    $("#formSupported").html("No");
}

$('#myform').on('submit', function (e) {
    var query = $(this).serialize();
    if (!formSupported) { 
        //fixed form attribute not supported in IE
        var extra = $('[form=myform]').each(function () {
            if (/(=)\w*/gi.test(query)) query += '&';
            query += this.name + '=' + this.value;
        });
    }
    console.log(query);
    return false;
});

JS Fiddle:

http://jsfiddle.net/ezq9mu1a/3/

Community
  • 1
  • 1
Hidden Hobbes
  • 13,893
  • 3
  • 38
  • 64
  • Thanks, may be the simplest way to check if attribute is supported but the reason I placing `` outside `
    ` is I'm implementing plugin architecture that load extra fields on run time so that I can't use actual input's ID
    – aifarfa Aug 30 '14 at 16:18
  • 1
    No problem, please see my edit which uses dynamically created elements to do the same check. This may be more suitable for your needs. – Hidden Hobbes Aug 30 '14 at 20:28
1

Use jQuery Migrate plugin https://github.com/jquery/jquery-migrate/#readme

Or use modernizr (http://modernizr.com/)

Ramanan
  • 1,000
  • 1
  • 7
  • 20
1

Edit, updated

Note, Tried at ie 11

v2

// click `test`
$("#myform").on("submit", function(e) {
e.preventDefault();
if ("msFlex" in document.body.style) {
var query = "";
$("[form=myform]").not("form *").each(function (k, v) {
    var params = ["name", "value"];
    $.each(params, function (i, val) {
        query += (val === "name" 
                   ? "&" + $(v).prop(val) + "=" 
                   : $(v).prop(val)
                   );
    });
});
// do stuff
// tried at ie11 , `$("[form=myform]").serialize()`
// appear to serialize those elements ?
// see `console` ?
// either `query` or `$("[form=myform]").serialize()`
// should return `&extra=777&filter=1` 
// possible reason `checkFormAttr()` returned `true` ?
// tried `v1` with `checkFormAttr()` ? without `!` ?
console.log(query, $("[form=myform]").serialize());
$("body").append(query)
};
})

http://jsfiddle.net/guest271314/g4v2fcaa/10/ (v2)

&extra=777&filter=1

should be append to document

v1

function checkFormAttr() {
  var form = document.createElement("form");
  form.id = "abc";
  var input = document.createElement("input");
  input.type = "text";
  input.form = "abc";
  form.appendChild(input);
  console.log(form, input.form);
  // (form === input.form) => `true` if supported 
  // (form !== input.form) => cast as `false`
  return (form === input.form) // `false` if not supported
};

for including within piece at OP ,

$("#myform").on("submit", function( event ) {
  event.preventDefault();
  var query = $(this).serialize();
    if (!checkFormAttr()) { 
        //fixed form attribute not supported in IE
        var extra = $('[form=myform]').each(function () {
            if (/(=)\w*/gi.test(query)) query += '&';
            query += this.name + '=' + this.value;
        });
    }
    console.log(query);
    return false;
});

alternatively , to check document.body.style for specific vendor-prefixes ,

var ms = (("msFlex" || "msAnimation") in document.body.style );
var webkit = ("WebkitAnimation" in document.body.style );
var moz = ("MozAnimation" in document.body.style );
var opera = ("OTransition" in document.body.style );

console.log("form attribute:"+ checkFormAttr()
            + "\nform attribute , cast as `false`:"+ !checkFormAttr()
            + "\nms:" + ms 
            + "\nwebkit:" + webkit
            + "\nmoz:" + moz 
            + "\nopera:" + opera);

jsfiddle http://jsfiddle.net/guest271314/g4v2fcaa/

See HTML5 at 4.10.18.3 Association of controls and forms

guest271314
  • 1
  • 15
  • 104
  • 177