9
votes

Attribut de formulaire de Polyfill HTML5 (pour les champs de saisie)

Ceci est le balisage que j'utilise:

<input type="text" form="myform" name="inp1" />
<form id="myform" name="myform">
    ...        
</form>


1 commentaires

Peut ne vaut pas la peine d'être polyfilling s'il ya Ajax et avant / après la logique qui n'est pas déclenchée directement avec .Submit (). Je viens de passer une heure ou de savoir qu'il serait plus rapide de faire onclick () dans l'ensemble du projet au sujet de la forme de polyfilling = ID.


6 Réponses :


1
votes

Après avoir lu à travers les docs de Webshim, il semble qu'il a un polyfill pour cela.

http://afarkas.github.io/webshim/demos/demos/ Webforms.html


1 commentaires

Nouvelles URL: afarkas.github.io/webshim/demos/#forms et < Un href = "http://afarkas.github.io/webshim/demos/demos/forms.html" rel = "Nofollow noreferrer"> afarkas.github.io/webshim/demos/demos/forms.html



12
votes

J'ai écrit ce polyfill à émuler une telle caractéristique par des champs de duplication lors de la soumission de formulaire, testé dans IE6 et cela a fonctionné bien. xxx


9 commentaires

J'ai ajouté ceci au Liste des polyfills .


La partie $ ('[forme]'). Obtenez (0) .Form dans la première ligne de code est susceptible d'augmenter un »Impossible de lire la propriété 'Formulaire' de« erreur d'erreur indéfinie si . obtenez (0) retours indéfini. J'ai stocké $ ('[formulaire]') dans une variable et renvoyé si cette longueur était 0.


Lorsqu'il est utilisé à l'intérieur $ (document) .ajaxcomplete (...) , la ligne de détection exposeellement && window.htmlformelement && expostelement.form Instance de htmlformelement retourne vrai < / code> dans IE 11 (bien que IE11 ne supporte pas cela). Ceci est parce que exposeLement.form renvoie le formulaire réel. Bien que lorsqu'il soit utilisé dans la console, $ ('[formulaire]'). Obtenez (0) .Form renvoie null Comment réparer cela, donc il fonctionne à l'intérieur $ (document) .ajaxcomplete (...) dans IE11?


En outre, cela ne fonctionne pas conjointement avec la formation des attributs, Formtarget, Formmethod


@wertzui ce problème est si bizarre donc je ajoute également à IE 11 comme une exception


Belle solution mais le polyfill ne soumet pas le nom / la valeur d'un (E.G. chrome 48). Vous devez ajouter du code pour ajouter un champ masqué avant la ligne // le supporte, pas besoin de corriger le retour; boutons . Le code peut ressembler à si ($ (échantillon) .attr ("formulaire") == $ fields.attr ("id") && $ (exposeellement) .is ("[nom]")) {$ ( Chaussements) .Cliquez sur (Fonction () {Self._Appendfield ($ formulaire, {nom: $ (exposeellement) .attr ("nom"), valeur: $ (exposeellement) .val ()});}); }


De la lecture, il semble que cela ne fonctionne pas pour les formulaires où le bouton Soumettre ( ou ) est en dehors de la forme.


Cela fonctionne lorsque le bouton Soumettre est en dehors du formulaire, mais il semble contourner la validation de champ «requise».


Le code est écrit en 2014. Mon PC Windows est parti depuis longtemps et je ne me concentre plus sur le développement frontal. Aidez moi à l'améliorer s'il vous plait.



1
votes

Je prends un peu de temps pour envoyer une mise à jour de ce polyfill car il ne fonctionne pas avec MS Bord.

i Ajouter 2 ligne pour le réparer: P>

      var isEdge = navigator.userAgent.indexOf("Edge");
      if (sampleElement && window.HTMLFormElement && sampleElement.form instanceof HTMLFormElement && !isIE11 && isEdge == -1) {
        // browser supports it, no need to fix
        return;
      }


1 commentaires

Ce serait mieux si nous avions une polyfill qui utilisait la détection de fonctionnalités, car Edge le soutiendra probablement à l'avenir.



8
votes

Le polyfill ci-dessus ne prend pas en compte le navigateur de bord. Je l'ai modifié pour utiliser la détection des fonctionnalités, que j'ai testé dans IE7 +, Edge, Firefox (mobile / bureau), chrome (mobile / bureau), safari (mobile / bureau) et navigateur Android 4.0.

(function($) {
    /**
     * polyfill for html5 form attr
     */

    // detect if browser supports this
    var SAMPLE_FORM_NAME = "html-5-polyfill-test";
    var sampleForm = $("<form id='" + SAMPLE_FORM_NAME + "'/>");
    var sampleFormAndHiddenInput = sampleForm.add($("<input type='hidden' form='" + SAMPLE_FORM_NAME + "'/>"));     
    sampleFormAndHiddenInput.prependTo('body'); 
    var sampleElementFound = sampleForm[0].elements[0];
    sampleFormAndHiddenInput.remove();
    if (sampleElementFound) {
        // browser supports it, no need to fix
        return;
    }

    /**
     * Append a field to a form
     *
     */
    $.fn.appendField = function(data) {
      // for form only
      if (!this.is('form')) return;

      // wrap data
      if (!$.isArray(data) && data.name && data.value) {
        data = [data];
      }

      var $form = this;

      // attach new params
      $.each(data, function(i, item) {
        $('<input/>')
          .attr('type', 'hidden')
          .attr('name', item.name)
          .val(item.value).appendTo($form);
      });

      return $form;
    };

    /**
     * Find all input fields with form attribute point to jQuery object
     * 
     */
    $('form[id]').submit(function(e) {
      // serialize data
      var data = $('[form='+ this.id + ']').serializeArray();
      // append data to form
      $(this).appendField(data);
    }).each(function() {
      var form = this,
        $fields = $('[form=' + this.id + ']');

      $fields.filter('button, input').filter('[type=reset],[type=submit]').click(function() {
        var type = this.type.toLowerCase();
        if (type === 'reset') {
          // reset form
          form.reset();
          // for elements outside form
          $fields.each(function() {
            this.value = this.defaultValue;
            this.checked = this.defaultChecked;
          }).filter('select').each(function() {
            $(this).find('option').each(function() {
              this.selected = this.defaultSelected;
            });
          });
        } else if (type.match(/^submit|image$/i)) {
          $(form).appendField({name: this.name, value: this.value}).submit();
        }
      });
    });


  })(jQuery);


1 commentaires

Merci, ça marche parfaitement. J'espère que cela obtient plus de votes



2
votes

J'ai amélioré la polyfill de Patstuart, telle que:

  • Un formulaire peut maintenant être soumis plusieurs fois, par ex. Lorsque vous utilisez l'attribut cible (les champs externes étaient dupliqués précédemment)

  • Les boutons de réinitialisation fonctionnent désormais correctement

    ici il est: xxx

    }) (jQuery);


0 commentaires

1
votes

J'ai fait une polyfille de vanille Javascript basée sur les polyfills ci-dessus et le téléchargé sur GitHub: HTTPS: //github.com/Ununnilium/Form-atribute-Polyfill . J'ai également ajouté un événement personnalisé pour gérer le cas lorsque Soumettre est traité par JavaScript et non directement par le navigateur. J'ai testé le code uniquement sous peu avec IE 11, alors veuillez vérifier vous-même avant d'utiliser. Le scrutin devrait peut-être être remplacé par une fonction de détection plus efficace.

function browserNeedsPolyfill() {
    var TEST_FORM_NAME = "form-attribute-polyfill-test";
    var testForm = document.createElement("form");
    testForm.setAttribute("id", TEST_FORM_NAME);
    testForm.setAttribute("type", "hidden");
    var testInput = document.createElement("input");
    testInput.setAttribute("type", "hidden");
    testInput.setAttribute("form", TEST_FORM_NAME);
    testForm.appendChild(testInput);
    document.body.appendChild(testInput);
    document.body.appendChild(testForm);
    var sampleElementFound = testForm.elements.length === 1;
    document.body.removeChild(testInput);
    document.body.removeChild(testForm);
    return !sampleElementFound;
}

// Ideas from jQuery form attribute polyfill https://stackoverflow.com/a/26696165/2372674
function executeFormPolyfill() {
    function appendDataToForm(data, form) {
        Object.keys(data).forEach(function(name) {
            var inputElem = document.createElement("input");
            inputElem.setAttribute("type", "hidden");
            inputElem.setAttribute("name", name);
            inputElem.value = data[name];
            form.appendChild(inputElem);
        });
    }

    var forms = document.body.querySelectorAll("form[id]");
    Array.prototype.forEach.call(forms, function (form) {
        var fields = document.querySelectorAll('[form="' + form.id + '"]');
        var dataFields = [];
        Array.prototype.forEach.call(fields, function (field) {
            if (field.disabled === false && field.hasAttribute("name")) {
                dataFields.push(field);
            }
        });
        Array.prototype.forEach.call(fields, function (field) {
            if (field.type === "reset") {
                field.addEventListener("click", function () {
                    form.reset();
                    Array.prototype.forEach.call(dataFields, function (dataField) {
                        if (dataField.nodeName === "SELECT") {
                            Array.prototype.forEach.call(dataField.querySelectorAll('option'), function (option) {
                                option.selected = option.defaultSelected;
                            });
                        } else {
                            dataField.value = dataField.defaultValue;
                            dataField.checked = dataField.defaultChecked;
                        }
                    });
                });
            } else if (field.type === "submit" || field.type === "image") {
                field.addEventListener("click", function () {
                    var obj = {};
                    obj[field.name] = field.value;
                    appendDataToForm(obj, form);
                    form.dispatchEvent(eventToDispatch);
                });
            }
        });
        form.addEventListener("submit", function () {
            var data = {};
            Array.prototype.forEach.call(dataFields, function (dataField) {
                data[dataField.name] = dataField.value;
            });
            appendDataToForm(data, form);
        });
    });
}

// Poll for new forms and execute polyfill for them
function detectedNewForms() {
    var ALREADY_DETECTED_CLASS = 'form-already-detected';
    var newForms = document.querySelectorAll('form:not([class="' + ALREADY_DETECTED_CLASS + '"])');
    if (newForms.length !== 0) {
        Array.prototype.forEach.call(newForms, function (form) {
            form.className += ALREADY_DETECTED_CLASS;
        });
        executeFormPolyfill();
    }
    setTimeout(detectedNewForms, 100);
}


// Source: https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent
function polyfillCustomEvent() {
    if (typeof window.CustomEvent === "function") {
        return false;
    }

    function CustomEvent(event, params) {
        params = params || {bubbles: false, cancelable: false, detail: undefined};
        var evt = document.createEvent('CustomEvent');
        evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail);
        return evt;
    }

    CustomEvent.prototype = window.Event.prototype;
    window.CustomEvent = CustomEvent;
}

if (browserNeedsPolyfill()) {
    polyfillCustomEvent();   // IE is missing CustomEvent

    // This workaround is needed if submit is handled by JavaScript instead the browser itself
    // Source: https://stackoverflow.com/a/35155789/2372674
    var eventToDispatch = new CustomEvent("submit", {"bubbles": true, "cancelable": true});
    detectedNewForms();   // Poll for new forms and execute form attribute polyfill for new forms
}


0 commentaires