2013-05-04 11 views
6

Sto sviluppando web app, ho una tale esigenza che ogni volta che l'utente clicca sul text all'interno span ho bisogno convert in input field e on blur ho bisogno di convert it back per attraversare di nuovo. Quindi sto usando il seguente script in una delle mie pagine jsp.Conversione Span di ingresso

Java Script:

<script type="text/javascript"> 
function covertSpan(id){ 

    $('#'+id).click(function() { 
     var input = $("<input>", { val: $(this).text(), 
            type: "text" }); 
     $(this).replaceWith(input); 
     input.select(); 
    }); 

     $('input').live('blur', function() { 
      var span=$("<span>", {text:$(this).val()}); 
      $(this).replaceWith(span); 

     });   
} 

JSP Codice:

<span id="loadNumId" onmouseover="javascript:covertSpan(this.id);">5566</span> 

Ora il mio problema è, tutto funziona bene solo per la prima volta. Voglio dire ogni volta che clicco sul testo all'interno di span per il first time si converte in campo di input e di nuovo onblur si ricopre dal campo di input al testo normale. Ma se provi ancora una volta a farlo, non funzionerà. Cosa c'è di sbagliato con lo script sopra?

+0

Ci sono anche jQuery Plugin per "Modifica in posizione": http://stackoverflow.com/questions/708801/whats-the-best-edit-in- place-plugin-for-jquery – SailAvid

risposta

12

Wanderers - per risparmiare un po 'di tempo, l'ultima opzione in fondo a questa risposta sarà molto probabilmente la tua soluzione preferita


Credo che questo è quello che stai cercando: http://jsfiddle.net/2D9FW/

var switchToInput = function() { 
    var $input = $("<input>", { 
     val: $(this).text(), 
     type: "text" 
    }); 
    $input.addClass("loadNum"); 
    $(this).replaceWith($input); 
    $input.on("blur", switchToSpan); 
    $input.select(); 
}; 
var switchToSpan = function() { 
    var $span = $("<span>", { 
     text: $(this).val() 
    }); 
    $span.addClass("loadNum"); 
    $(this).replaceWith($span); 
    $span.on("click", switchToInput); 
}; 
$(".loadNum").on("click", switchToInput); 

ho usato una classe invece di un ID in modo che si possa fare di più, ma è possibile passare indietro se si vuole. Se si desidera utilizzare ID: recentemente http://jsfiddle.net/2D9FW/1/


Qualcuno ha alzato questo modo la mia attenzione è tornato ad esso.Questo è un altro modo per farlo (cambiando il DOM un po '): http://jsfiddle.net/2khuobze/

<div class="inputSwitch"> 
First Name: <span>John</span><input /> 
</div> 
<div class="inputSwitch"> 
Last Name: <span>Doe</span><input /> 
</div> 

JS

$(".inputSwitch span").on("click", function() { 
    var $this = $(this); 
    $this.hide().siblings("input").val($this.text()).show(); 
}); 
$(".inputSwitch input").on("blur", function() { 
    var $this = $(this); 
    $this.hide().siblings("span").text($this.val()).show(); 
}).hide(); 

Inoltre, se si voleva sostenere la selezione di tutte sulla messa a fuoco e la tabulazione per arrivare a la successiva/precedente arco/ingresso, si potrebbe fare questo (mi piace questa opzione migliore): http://jsfiddle.net/x33gz6z9/

var $inputSwitches = $(".inputSwitch"), 
    $inputs = $inputSwitches.find("input"), 
    $spans = $inputSwitches.find("span"); 
$spans.on("click", function() { 
    var $this = $(this); 
    $this.hide().siblings("input").show().focus().select(); 
}).each(function() { 
    var $this = $(this); 
    $this.text($this.siblings("input").val()); 
}); 
$inputs.on("blur", function() { 
    var $this = $(this); 
    $this.hide().siblings("span").text($this.val()).show(); 
}).on('keydown', function(e) { 
    if (e.which == 9) { 
    e.preventDefault(); 
    if (e.shiftKey) { 
     $(this).blur().parent().prevAll($inputSwitches).first().find($spans).click(); 
    } else { 
     $(this).blur().parent().nextAll($inputSwitches).first().find($spans).click(); 
    } 
    } 
}).hide(); 
+0

grazie per la tua risposta! –

+0

Ho un problema ora, dopo aver aggiornato la mia versione jQuery il codice sopra non funziona. –

+0

Quale versione? Ho appena eseguito in 2.0 e 2.x (bordo) e ha funzionato bene. Che cosa sta succedendo? Qualche errore nella console? – smerny

1

Innanzitutto, è necessario modificare il gestore di clic per utilizzare anche live(). Dovresti prendere nota, tuttavia, che lo live() è stato deprecato per un po 'di tempo. In entrambi i casi, dovresti utilizzare on().

In secondo luogo, quando si sostituisce l'input con lo span, non si fornisce un id all'elemento. Pertanto, l'elemento non corrisponde più al selettore del gestore di clic.

Personalmente, vorrei adottare un approccio diverso (e più semplice) completamente. Avrei sia lo span che l'input nel mio markup fianco a fianco. Uno sarebbe nascosto mentre l'altro è mostrato. Ciò ti darebbe meno possibilità di commettere errori quando cerchi di ricreare elementi DOM e migliorare le prestazioni poiché non aggiungerai/rimuoverai costantemente elementi dal DOM.

+0

"Pertanto, l'elemento non corrisponde più al selettore del gestore di clic" - quale gestore di clic? 'covertSpan' viene chiamato una sola volta e non vedo nessun altro allegato del gestore di clic. – zeroflagL

+0

Non è una cattiva idea! Devo provarlo un po 'di tempo. –

1

Capisco che tu pensi che la sostituzione degli elementi sia una cosa carina, tuttavia, vorrei usare un prompt per ottenere il testo. Perché? È molto più facile e in realtà un po 'più carino per l'utente. Se sei curioso su come farlo, te lo mostro.

html:

<span class='editable'>foobar</span> 

JS:

$(function() 
{ 
    $('span.editable').click(function() 
    { 
    var span = $(this); 
    var text = span.text(); 

    var new_text = prompt("Change value", text); 

    if (new_text != null) 
     span.text(new_text); 
    }); 
}); 

http://jsfiddle.net/qJxhV/1/

+0

grazie per aver risposto! –

0

Una versione più generica di smerny's excellent answer con id può essere fatta modificando leggermente due linee: $input.attr("ID", "loadNum"); diventa $input.attr("ID", $(this).attr("ID")); - in questo modo, ci vuole semplicemente l'id corrente, e la mantiene, qualunque essa sia.

Analogamente, $span.attr("ID", "loadNum"); diventa $span.attr("ID", $(this).attr("ID"));

Questo consente semplicemente le funzioni da applicare a qualsiasi div. Con due linee simili aggiunte, sia l'id che la classe funzionano bene. Vedi example.

0

Ho fatto pochi cambiamenti nel codice, utilizzando questo tipo di input non può essere vuoto, tornerà al suo valore reale.

var switchToInput = function() { 
     var $input = $("<input>", { 
      val: $(this).text(), 
      type: "text", 
      rel : jQuery(this).text(), 
     }); 
     $input.addClass("loadNum"); 
     $(this).replaceWith($input); 
     $input.on("blur", switchToSpan); 
     $input.select(); 
    }; 
    var switchToSpan = function() { 
      if(jQuery(this).val()){ 
         var $text = jQuery(this).val(); 
       } else { 
         var $text = jQuery(this).attr('rel'); 
       } 
     var $span = $("<span>", { 
      text: $text, 
     }); 
     $span.addClass("loadNum"); 
     $(this).replaceWith($span); 
     $span.on("click", switchToInput); 
    } 
    $(".loadNum").on("click", switchToInput); 

jsFiddle: - https://jsfiddle.net/svsp3wqL/