2012-06-15 13 views
5

Estoy escribiendo un complemento jQuery para simular un div editable.
Aquí está mi código:Controlar el evento de cambio de texto de entrada

(function($){ 
    $.fn.editable = function(){ 
     return this.each(function(){ 
      var $this = $(this).hide(); 
      var div = $('<div>'+$this.val()+'</div>').show().insertAfter($this).data('input',$this); 

      $this.data('div',div); 

      div.dblclick(function(){ 
       $(this).hide(); 
       $(this).data('input').val($(this).text()).show(); 
      }); 
      $this.blur(function(){ 
       $(this).hide(); 
       $(this).data('div').html($(this).val()).show();     
      }); 

      $this.change(function(){ 
       $(this).data('div').html($(this).val());  
      }); 
     }); 
    }; 

})(jQuery); 

Hasta ahora, this works bastante bien ..

Ahora, lo que yo quiero hacer, y no tienen ni idea de cómo, es hacer el cambio de texto si el div oculto cambios en el valor de entrada.
Medios, si lo hago $('#editable').val('new text') el div debe cambiar ..

No puedo desencadenar el cambio caso de forma manual, ya que el cambio de entrada se producirá dentro de otros plugins que no controlo ..

+0

¿Puede ampliar cómo espera '$ ('# editable'). Val()' para trabajar? ¿Por qué 'val()' en oposición a 'html()'? ¿Y qué elemento tiene la id editable? –

+0

@palintropos actualizó mi jsFiddle – skafandri

+1

Como un aparte, ¿has mirado en 'contenteEditable'? Creo que es completamente compatible con –

Respuesta

3

Eche un vistazo a esto, en su complemento puede extender la función val de esta manera para que el evento de cambio se active cuando se cambie el valor utilizando la función val.

How to extend the val method so that the change event is triggered when val is called?

+0

Esto activará en cambio eventos dobles '.change()' para complementos que llaman correctamente '.change()' después de '.val()'. La técnica podría combinarse con una lista de entradas, de modo que (en este caso) solo '$ (" # editable "). Val (" nuevo valor ")' active un cambio. ("Correctamente" depende del propósito del complemento, supongo). –

+0

¿podría explicarme más o darme alguna muestra? –

+0

Aquí hay un ejemplo http://jsfiddle.net/joelpurra/Emyk2/ –

-2

Sugiero que haga sus métodos de apoyo plugin de jQuery como se describe en Plugins/Authoring - Namespacing:

, entonces tendrá algo como esto:

(function($){ 

    var methods = { 

    init : function(options) { 
     return this.each(function() { 
     var $this = $(this).hide(); 
     var div = $('<div>'+$this.val()+'</div>').show().insertAfter($this).data('input',$this); 

     $this.data('div',div); 

     div.dblclick(function(){ 
      $(this).hide(); 
      $(this).data('input').val($(this).text()).show(); 
     }); 
     $this.blur(function(){ 
      $(this).hide(); 
      $(this).data('div').html($(this).val()).show();     
     }); 
    }, 

    value : function(str) { 
     return this.each(function(){ 
     $(this).val(str); 
     $(this).data('div').html($(this).val()); 
     }); 
    } 
    }; 

    $.fn.editable = function(method) { 

    // Method calling logic 
    if (methods[method]) { 
     return methods[ method ].apply(this, Array.prototype.slice.call(arguments, 1)); 
    } else if (typeof method === 'object' || ! method) { 
     return methods.init.apply(this, arguments); 
    } else { 
     $.error('Method ' + method + ' does not exist on jQuery.editable'); 
    }  

    }; 

})(jQuery); 

Entonces lo va a usar como esto:

$('#editable').editable('new value that will sync the related div'); 
// instead of `$('#editable').value('...')` 

Te recomiendo que lea el artículo del Plugins/Authoring - Namespacing 's en jQuery.


ACTUALIZACIÓN Dado que he cometido un error entender la pregunta, vine con las siguientes soluciones propuestas. No es la mejor manera de hacerlo.

Le recomiendo que revise su diseño de complemento, ya que no es accesible en mi opinión personal.

Pero, ya que no puedo ver todo el escenario, el siguiente fragmento de código hará el truco

(function() { 

    // Store the original jQuery.val() 
    var $$val = $.fn.val; 

    // Add a hook. 
    $.fn.val = function(s) { 

     // Call your plugin change event. 
     $(this).editable('change'); 

     // Delegate to the original jQuery.val function. 
     return $$val.apply(this, Array.prototype.slice.call(arguments)); 
    }; 

    // Your plugin stuff... 
}) 

HTH

+0

Puedo agregar '.trigger ('cambiar')' ¿no es más fácil? pero las entradas serán usadas por otros complementos como se dijo, entonces solo será '.val ('new text')' – skafandri

+0

La pregunta no fue: Cómo escribir complementos jQuery .. – skafandri

+0

Por el bien de los puntos negativos, intentaré encender mi respuesta propuesta con un JSFiddle con su comportamiento descrito. Ya he escrito mi complemento jQuery Editable y ya me he enfrentado a esta situación común, estoy bastante seguro de que esta forma de hacer hará lo que quieras. –

2

Al hacer doble clic en el <div> para editar el <input>, está sobreescribiendo el valor de la entrada con esta línea:

$(this).data('input').val($(this).text()).show(); 

Si el evento .change() no se ha activado (como usted indica), significa que está sobrescribiendo los cambios realizados por el complemento externo con el contenido "anterior" de su div. Elimine .val() para evitar ese problema.

$(this).data('input').show(); 

Como alternativa a confiar en el plugin activación externa .change(), se puede comprobar el valor mediante el sondeo. Si bien esto no se recomienda si hay eventos disponibles, no tendrá un gran impacto si configura el intervalo de sondeo de manera razonable. Dado que se trata de seres humanos que ingresan datos de una forma, supongo que no es necesario sondear con más frecuencia que cada 250 milisegundos.

Consulte $("#editable").changePolling(); para ver un contenedor que comprueba el valor actual y desencadena .change() si ha cambiado. Consulte the forked jsfiddle para obtener un ejemplo basado en su código.

+0

El jsFiddle no funciona ... al hacer clic en el botón no hacer nada ... – skafandri

+0

@sonia: ¿estás probando en IE? IE (y posiblemente otros navegadores) son exigentes con la inclusión de scripts que no tienen el tipo de contenido correcto. I'v –

+0

@sonia: el tipo de contenido correcto sería ['application/javascript' o' text/javascript'] (http://en.wikipedia.org/wiki/JavaScript). He [vinculado el script sin procesar desde mi esencia] (https://gist.github.com/raw/2944926/d87c96c1529d7f5e8c8c4015c7b9100a5f6a8db8/changepolling.joelpurra.js) que no muestra el tipo de contenido correcto. Para realizar pruebas, puede copiar y pegar todo el código fuente '.changePolling()' en jsFiddle y luego ejecutarlo. –

Cuestiones relacionadas