2010-01-13 10 views
27

Existe-t-il un moyen de surcharger facilement la fonction val() de jQuery?Remplacer la fonction jQuery .val()?

La raison pour laquelle je souhaite le remplacer est que je veux ajouter un traitement à chaque fois qu'une valeur est définie pour un élément. Et je ne veux pas faire un autre setter de valeur personnalisé, tel que myVal().

+0

Je fais l'hypothèse que l'événement .change() ne fonctionne pas pour vous ici? –

+0

@Mark: Lorsque je définis la valeur des éléments en faisant $ ('# foo'). Val ('someValue') l'événement .change() n'est pas déclenché. Il semble seulement être déclenché lorsque la valeur est modifiée par l'utilisateur sur l'interface graphique/navigateur. – 7wp

+0

$ ('# foo'). Val ('someValue'). Trigger ('change'); Peut-être utile d'enchaîner le trigger là-dedans alors ... –

Répondre

46

Vous pouvez stocker une référence à la fonction val d'origine, puis la remplacer et faire votre traitement, puis invoquer avec call, d'utiliser le bon contexte:

(function ($) { 
    var originalVal = $.fn.val; 
    $.fn.val = function(value) { 
    if (typeof value != 'undefined') { 
     // setter invoked, do processing 
    } 
    return originalVal.call(this, value); 
    }; 
})(jQuery); 

Notez que vous pouvez distinguer entre un getter appel $(selector).val(); et un setter appel $(selector).val('new value'); juste en vérifiant si l'argument value est undefined ou non.

+0

Merci, très apprécié. – 7wp

+4

Cela ne fonctionnera pas (au moins pas dans jQuery 1.7). La fonction jQuery d'origine repose sur le nombre d'arguments. Elle considère donc que l'appel de la méthode val() d'origine est toujours un setter. Pour résoudre ce problème, remplacez "return originalVal.call (this, value);" avec "return originalVal.apply (this, arguments);" – dkl

+4

Ni l'original, ni la modification proposée par @dkl ne fonctionne avec Chrome. Utiliser un if..else pour tester si vous obtenez ou paramètres fonctionne. Voici un remplacement transparent, modifier au besoin. (function ($) {var originalVal = $ .fn.val; $ .fn.val = function (value) { si (valeur typeof == 'undefined') { originalVal.call de retour (ce); } else { return originalVal.call (this, value); } }; }) (jQuery); – Martijn

1

Si je vous comprends bien, quelque chose comme cela devrait faire l'affaire très bien:

jQuery.fn.val = function (new_val) { 
    alert("You set a val! How wonderful!"); 
    this.value = new_val; 
}; 

Assurez-vous d'inclure la fonctionnalité régulière: obtenir des valeurs de sélectionne et ainsi de suite. Il suffit de coller ce code après après la bibliothèque jQuery régulière.

+0

Ne pas copier le comportement original, il suffit de l'appeler explicitement pour assurer la compatibilité et la compatibilité avec d'autres remplacements de la fonction val(). – Martijn

+0

@Martijn: Si j'avais su il y a deux ans ce que je sais maintenant, je l'aurais fait. Mais malheureusement c'est un peu tard pour ça. – Reid

2

Je sais que le problème est vieux mais juste pour donner une solution complète. Pour que jQuery.val() et jQuery.val (value) fonctionnent après le remplacement, vous devez le remplacer correctement et séparément. Parce que lors de l'appel jQuery.val() puis originalVal.call (this, value); ne fonctionnera pas correctement.

Pour le faire de manière correcte, vous devez faire quelque chose comme ça quand vous obtenez la valeur: originalVal.call (this);

Voici un site où tout est expliqué: http://extremedev.blogspot.com/2012/01/override-jqueryval-and-jqueryvalvalue.html

Cordialement, Roman

+5

Merci Roman Je le savais déjà, mais vous faites un peu de promotion personnelle ici pour votre site. Il serait plus utile de coller au moins votre réponse complète en débordement de pile. De cette façon, si votre site disparaît de l'Internet, votre réponse sera toujours intacte sur ce site pour que les gens puissent le voir. Ce serait beaucoup plus utile Roman. Merci pour votre effort si. – 7wp

+1

@ 7wp +1 joli commentaire. –

+0

Serait bien si ce code a même fonctionné! Où "widgetElementId" est-il défini avant d'essayer de le résoudre avec jQuery? –

15

Je sais qu'il est un vieux sujet, mais il est d'abord dans la recherche Google et la réponse est tout à fait raison ...

Par exemple, si vous essayez dans la console $('#myinput').val(), vous devriez obtenir la valeur de #myinput.

Mais si vous $('#myinput').val(undefined) vous devez définir la valeur de #myinput! ( Avec la réponse actuelle et les commentaires de celui-ci, vous ne définissez la valeur de #myinput)

Voici une réponse améliorée qui utiliser arguments.

(function ($) { 
    var originalVal = $.fn.val; 
    $.fn.val = function(value) { 
    if (arguments.length >= 1) { 
     // setter invoked, do processing 
     return originalVal.call(this, value); 
    } 
    //getter invoked do processing 
    return originalVal.call(this); 
    }; 
})(jQuery); 

si vous voulez passer tous les arguments que vous pouvez également utiliser appliquer

(function ($) { 
    var originalVal = $.fn.val; 
    $.fn.val = function(value) { 
    if (arguments.length >= 1) { 
     // setter invoked, do processing 
    } else { 
     //getter invoked do processing 
    } 
    return originalVal.apply(this, arguments); 
    }; 
})(jQuery); 

Je l'espère aider!

+0

Bonne réponse! Fonctionne parfaitement. – Rajesh

0

J'ai quelque chose à ajouter à la réponse CMS, ma mise en œuvre serait différent et comme ceci:

(function ($) { var fnVal = $.fn.val; 
    $.fn.val = function(value) { 
     if (typeof value == 'undefined') { 
      return fnVal.call(this); 
     } 
     var result = fnVal.call(this, value); 
     $.fn.change.call(this); 
     // here you can add some more implementation 
     return result; 
    }; 
})(jQuery); 

observer la .fn.change $.appelez (ceci); sera appelée avant de quitter la fonction val ('') cela déclenchera aussi le .change() sur chaque affectation val ('').

Questions connexes