2012-06-15 8 views
5

Sto scrivendo un plug-in jQuery per simulare un div modificabile.
Ecco il mio codice:Gestire l'evento di modifica del testo di input

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

Finora, this works abbastanza bene ..

Ora, quello che voglio fare, e non hai idea di come, è quello di effettuare la modifica del testo div se il nascosto modifica del valore di input.
Means, se faccio $('#editable').val('new text') il div dovrebbe cambiare ..

Non posso innescare cambiamento evento manualmente, perché il cambiamento di ingresso avverrà entro altri plugin che io non controllo ..

+0

Si può espandere su come ci si aspetta '$ ('# modificabile'). Val()' per lavorare? Perché 'val()' al contrario di 'html()'? E quale elemento ha l'ID modificabile? –

+0

@palintropos ha aggiornato il mio jsFiddle – skafandri

+1

Come parte, hai esaminato 'contenteEditable'? Credo che sia supportato in maniera abbastanza approfondita –

risposta

3

Dai un'occhiata a questo, nel tuo plugin puoi estendere la funzione val come questa in modo che l'evento change si inneschi quando il valore viene cambiato usando la funzione val.

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

+0

Questo attiverà invece doppi eventi '.change()' per i plugin che chiamano correttamente '.change()' dopo '.val()'. La tecnica potrebbe essere combinata con un elenco di input, in modo che (in questo caso) solo '$ (" # editable "). Val (" nuovo valore ")" attivi una modifica. ("Correttamente" dipende dallo scopo del plugin, suppongo.) –

+0

potresti spiegarmi di più o darmi un campione? –

+0

Ecco un esempio http://jsfiddle.net/joelpurra/Emyk2/ –

-2

Suggerisco di rendere i vostri metodi di supporto plug-in jQuery come descritto a Plugins/Authoring - Namespacing:

allora si avrà qualcosa di simile:

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

Poi si intende utilizzare in questo modo:

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

vi consiglio vivamente di leggere l'articolo 's il Plugins/Authoring - Namespacing su jQuery.


UPDATE Da quando ho fatto un errore capire la domanda, mi è venuto con le seguenti soluzioni proposte. Non è il modo migliore per farlo.

Si consiglia vivamente di rivedere il design del plug-in, perché non è accessibile secondo la mia opinione personale.

Ma, dal momento che non riesco a vedere l'intero scenario, il seguente pezzo di codice farà il trucco

(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

Posso aggiungere '.trigger ('change')' non è più semplice? ma gli input saranno utilizzati da altri plugin come detto, quindi sarà solo '.val ('nuovo testo')' – skafandri

+0

La domanda non era: Come scrivere i plugin jQuery. – skafandri

+0

Per motivi di punti negativi, I cercherò di accendere la mia risposta proposta con un JSFiddle con il tuo comportamento descritto. Ho già scritto il mio plugin jQuery Editable e ho già affrontato questa situazione _common_, sono sicuro che questo modo di fare farà ciò che vuoi. –

2

Quando si fare doppio clic sul <div> per modificare il <input>, si sta sovrascrivendo il valore dell'ingresso con questa linea:

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

Se l'evento .change() non è stato attivato (come indicato), significa che stai sovrascrivendo le modifiche apportate dal plugin esterno con il "vecchio" contenuto del tuo div. Rimuovi .val() per evitare questo problema.

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

In alternativa al basandosi sul plugin esterno scatenante .change(), è possibile controllare il valore di polling. Anche se questo non è raccomandato se gli eventi sono disponibili, non avrà un impatto enorme se si imposta l'intervallo di polling in modo ragionevole. Dato che hai a che fare con l'immissione di dati da parte di umani in un modulo, suppongo che non sia necessario eseguire il polling più spesso di ogni 250 millisecondi.

Vedere $("#editable").changePolling(); per un wrapper che controlla il valore corrente e attiva .change() se è stato modificato. Vedi the forked jsfiddle per un esempio basato sul tuo codice.

+0

jsFiddle non funziona .. facendo clic sul pulsante non fare nulla .. – skafandri

+0

@sonia: stai provando in IE? IE (e probabilmente altri browser) sono schizzinosi sull'includere gli script che non sono offerti con il giusto tipo di contenuto. I'v –

+0

@sonia: il tipo di contenuto corretto sarebbe ['application/javascript' o' text/javascript'] (http://en.wikipedia.org/wiki/JavaScript). Ho [collegato lo script raw dal mio gist] (https://gist.github.com/raw/2944926/d87c96c1529d7f5e8c8c4015c7b9100a5f6a8db8/changepolling.joelpurra.js) che non offre il giusto tipo di contenuto. A scopo di test, è possibile copiare e incollare l'intero codice sorgente '.changePolling()' in jsFiddle e quindi eseguirlo. –

Problemi correlati