3 votes

L'événement Prototype.js observe l'interception du clic et l'arrêt de la propagation.

J'ai une page qui est construite autour d'un wrapper avec une logique très définie. Il y a un bouton Enregistrer en bas du formulaire enveloppé qui ressemble à ceci :

<form>
... my page goes here...
<input id="submitBtnSaveId" type="button" onclick="submitPage('save', 'auto', event)" value="Save">
</form>

Cela ne peut pas changer...

Maintenant, j'écris du javascript dans la page qui est chargée dans "...ma page va ici...". Le code se charge très bien et fonctionne comme prévu. Il effectue un certain travail autour des éléments du formulaire et j'ai même injecté une validation sur la page. C'est là que je suis bloqué. J'essaie d'"intercepter" le onclick et d'empêcher la page d'appeler "submitPage()" si la validation échoue. J'utilise prototype.js, et j'ai donc essayé toutes les variations et combinaisons possibles :

document.observe("dom:loaded", function() {
    Element.observe('submitBtnSaveId', 'click', function (e) {
        console.log('Noticed a submit taking place... please make it stop!');
        //validateForm(e);
        Event.stop(e);
        e.stopPropagation();
        e.cancelBubble = true;
        console.log(e);
        alert('Stop the default submit!');
        return false;
    }, false);
});

Rien n'empêche l'appel de "submitPage()" ! L'observation fonctionne réellement et déclenche le message de la console et affiche l'alerte pendant une seconde. Puis le "submitPage()" se déclenche et tout s'arrête. J'ai supprimé le onclick lié au bouton dans Firebug, et ma validation et mon alerte fonctionnent comme prévu, ce qui m'amène à penser que la propagation n'est pas vraiment arrêtée pour le onclick ?

Qu'est-ce que je rate ?

3voto

Geek Num 88 Points 3707

En partant du fait que vous ne pouvez pas modifier le HTML, voici une idée.

laissez votre javascript actuel tel quel pour attraper l'événement de clic - mais ajoutez ceci à l'événement dom:loaded

$('submitBtnSaveId').writeAttribute('onclick',null);

cela supprimera l'attribut onclick de sorte que Avec un peu de chance, l'événement ne sera pas appelé

Ainsi, votre javascript ressemblera à ceci

document.observe("dom:loaded", function() {
    $('submitBtnSaveId').writeAttribute('onclick',null);
    Element.observe('submitBtnSaveId', 'click', function (e) {
        console.log('Noticed a submit taking place... please make it stop!');
        //validateForm(e);
        Event.stop(e);
        e.stopPropagation();
        e.cancelBubble = true;
        console.log(e);
        alert('Stop the default submit!');
        return false;

        submitPage('save', 'auto', e);
        //run submitPage() if all is good
    }, false);
});

2voto

Nino Skilj Points 271

J'ai repris l'idée présentée par Geek Num 88 et l'ai étendue pour répondre pleinement à mon besoin. Je ne connaissais pas la possibilité d'écraser l'attribut, ce qui est génial ! Le problème restait que j'avais besoin d'exécuter submitPage() si tout est bon, et que les paramètres et l'appel de cette méthode pouvaient être différents par page. Cela s'est avéré plus délicat qu'un simple appel en cas de succès. Voici mon code final :

document.observe("dom:loaded", function() {
    var allButtons = $$('input[type=button]');
    allButtons.each(function (oneButton) {
        if (oneButton.value === 'Save') {
            var originalSubmit = oneButton.readAttribute('onclick');
            var originalMethod = getMethodName(originalSubmit);
            var originalParameters = getMethodParameters(originalSubmit);
            oneButton.writeAttribute('onclick', null);
            Element.observe(oneButton, 'click', function (e) {
                if (validateForm(e)) {
                    return window[originalMethod].apply(this, originalParameters || []);
                }
            }, false);
        }
    });
});

function getMethodName(theMethod) {
    return theMethod.substring(0, theMethod.indexOf('('))
}

function getMethodParameters(theMethod) {
    var parameterCommaDelimited = theMethod.substring(theMethod.indexOf('(') + 1, theMethod.indexOf(')'));
    var parameterArray = parameterCommaDelimited.split(",");
    var finalParamArray = [];
    parameterArray.forEach(function(oneParam) {
        finalParamArray.push(oneParam.trim().replace("'","", 'g'));
    });
    return finalParamArray;
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X