2010-01-13 37 views
27

¿Hay alguna manera de anular fácilmente la función val() de jQuery?¿Anula la función jQuery .val()?

El motivo por el que deseo anularlo es que quiero agregar algo de procesamiento cada vez que se establece un valor para un elemento. Y no quiero hacer otro setter de valor personalizado, como myVal().

+0

Supongo que el evento .change() no funciona para usted aquí. –

+0

@Mark: Cuando establezco el valor de los elementos haciendo $ ('# foo'). Val ('someValue') el evento .change() no se desencadena. Solo parece activarse cuando el usuario cambia el valor en la GUI/navegador. – 7wp

+0

$ ('# foo'). Val ('someValue'). Trigger ('cambio'); podría ser útil para encadenar el gatillo allí entonces ... –

Respuesta

46

Puede almacenar una referencia a la función original val, a continuación, anularla y hacer su procesamiento, y más tarde lo debe invocar con call, para utilizar el contexto adecuado:

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

Tenga en cuenta que se puede distinguir entre una getter call $(selector).val(); y una llamada setter $(selector).val('new value'); simplemente marcando si el argumento value es undefined o no.

+0

Gracias, muy apreciado. – 7wp

+4

Esto no funcionará (al menos no en jQuery 1.7). La función jQuery original se basa en el recuento de argumentos, por lo que considerará que la llamada al método val() original siempre es un setter. Para solucionar esto, reemplace "return originalVal.call (this, value);" con "return originalVal.apply (this, arguments);" – dkl

+4

Ni el cambio original ni el propuesto por @dkl funciona con Chrome. Usar un if..else para probar si está obteniendo o funciona la configuración. Lo siguiente es una anulación transparente, cambie según sea necesario. (function ($) {var originalVal = $ .fn.val; $ .fn.val = función (valor) { si (valor typeof == 'no definido') { retorno originalVal.call (this); } else { return originalVal.call (esto, valor); } }; }) (jQuery); – Martijn

1

Si Estoy comprendiendo que la derecha, algo como esto debe hacer el truco muy bien:

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

Sólo asegúrese de incluir la funcionalidad normal: obtener valores de selecciona y así sucesivamente. Simplemente inserte el código después de después de la biblioteca jQuery normal.

+0

No copie el comportamiento original, simplemente llámelo explícitamente para asegurar la compatibilidad y compatibilidad con otras sustituciones de la función val(). – Martijn

+0

@Martijn: Si hubiera sabido hace dos años lo que sé ahora, lo habría hecho. Pero desafortunadamente es un poco tarde para eso. – Reid

2

Sé que el problema es antiguo, pero solo para dar una solución completa. Para que tanto el jQuery.val() como el jQuery.val (value) funcionen después de la anulación, debe sobrescribirlo correctamente y por separado. Porque cuando se llama a jQuery.val() entonces originalVal.call (this, value); no funcionará correctamente

Para hacerlo de forma correcta, debe hacer algo como eso al obtener el valor: originalVal.call (this);

Aquí es un sitio donde todo se explica: http://extremedev.blogspot.com/2012/01/override-jqueryval-and-jqueryvalvalue.html

Saludos, romana

+5

Gracias Roman Ya lo sabía, pero estás haciendo una promoción aquí para tu sitio. Sería más útil si al menos también pegas la respuesta completa en el desbordamiento de pila. De esta forma, si su sitio desaparece de Internet, su respuesta estará intacta en este sitio para que la gente la vea. Eso sería mucho más útil Romano. Gracias por tu esfuerzo. – 7wp

+1

@ 7wp +1 buen comentario. –

+0

¡Sería bueno si ese código funcionara! ¿Dónde se define "widgetElementId" antes de intentar resolverlo con jQuery? –

15

Sé que es un tema viejo, pero está por primera vez en Búsqueda de Google y la respuesta no es del todo correcto ...

Por ejemplo, si intenta en la consola $('#myinput').val(), debería obtener el valor de #myinput.

Pero si lo hace $('#myinput').val(undefined) debe establecer el valor de #myinput! ( Con la respuesta actual y los comentarios de la misma, no se establece el valor de #myinput)

Aquí es una respuesta mejorada que use 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 quieres pasar todos los argumentos también se puede utilizar aplica

(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); 

espero que ayude!

+0

¡Gran respuesta! Funciona perfectamente. – Rajesh

0

que tienen algo que añadir a la respuesta de la CMS, mi implementación sería diferente y ser como este:

(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); 

observar el $ .fn.change.llama esto); se invocará antes de salir de la función val (''), esto activará también .change() en cada asignación val ('').

Cuestiones relacionadas