Essayons d'y arriver.
Vous ne pouvez pas rendre un div modifiable. Il n'existe pas de div modifiable, du moins pour l'instant. Le problème est donc de trouver quoi utiliser à la place pour l'édition. Un textarea fonctionne parfaitement. L'idée est donc d'obtenir une zone de texte là où se trouve actuellement la division.
La question est de savoir comment et d'où nous pouvons obtenir le textarea. Il existe plusieurs moyens, mais l'un d'entre eux consiste à créer dynamiquement une zone de texte à la volée :
var editableText = $("<textarea />");
et le remplacer par le div :
$("#myDiv").replaceWith(editableText);
Le textarea est en place maintenant. Mais il est vide et nous venons de remplacer le div et nous avons tout perdu. Nous devons donc préserver le texte de la division d'une manière ou d'une autre. Une façon de le faire est de copier le texte/html à l'intérieur du div avant de le remplacer :
var divHtml = $("#myDiv").html(); // or text(), whatever suits.
Une fois que nous avons le html du div, nous pouvons remplir la zone de texte et remplacer en toute sécurité le div par la zone de texte. Et mettre le focus à l'intérieur de la zone de texte car l'utilisateur pourrait vouloir commencer à éditer. En combinant tout le travail effectué jusqu'à ce point, nous obtenons :
// save the html within the div
var divHtml = $("#myDiv").html();
// create a dynamic textarea
var editableText = $("<textarea />");
// fill the textarea with the div's text
editableText.val(divHtml);
// replace the div with the textarea
$("#myDiv").replaceWith(editableText);
// editableText.focus();
Il est fonctionnel, mais rien ne se passe lorsqu'un utilisateur clique sur une division, car nous n'avons pas configuré d'événements. Mettons en place les événements. Lorsque l'utilisateur clique sur un div $("div").click(..)
nous créons un gestionnaire de clics, et faisons tout ce qui précède.
$("div").click(function() {
var divHtml = $(this).html(); // notice "this" instead of a specific #myDiv
var editableText = $("<textarea />");
editableText.val(divHtml);
$(this).replaceWith(editableText);
editableText.focus();
});
C'est bien, mais nous voulons un moyen de récupérer notre div lorsqu'un utilisateur clique pour sortir ou quitter la zone de texte. Il existe un blur
pour les contrôles de formulaires qui est déclenché lorsqu'un utilisateur quitte le contrôle. Cela peut être utilisé pour détecter quand un utilisateur quitte le textarea, et replacer le div. Cette fois-ci, nous faisons exactement l'inverse. Nous conservons la valeur de textarea, créons un div dynamique, définissons son html, et remplaçons le textarea.
$(editableText).blur(function() {
// Preserve the value of textarea
var html = $(this).val();
// create a dynamic div
var viewableText = $("<div>");
// set it's html
viewableText.html(html);
// replace out the textarea
$(this).replaceWith(viewableText);
});
Tout est parfait, sauf que ce nouveau div ne se convertira plus en textarea au clic. Il s'agit d'une div nouvellement créée, et nous devrons configurer l'attribut click
événement à nouveau. Nous avons déjà le code complet, mais plutôt que de le répéter deux fois, il est préférable d'en faire une fonction.
function divClicked() {
var divHtml = $(this).html();
var editableText = $("<textarea />");
editableText.val(divHtml);
$(this).replaceWith(editableText);
editableText.focus();
// setup the blur event for this new textarea
editableText.blur(editableTextBlurred);
}
Comme toute l'opération est réversible dans les deux sens, nous devrons faire de même pour la zone de texte. Convertissons-la également en fonction.
function editableTextBlurred() {
var html = $(this).val();
var viewableText = $("<div>");
viewableText.html(html);
$(this).replaceWith(viewableText);
// setup the click event for this new div
$(viewableText).click(divClicked);
}
En reliant tout ensemble, nous avons 2 fonctions, divClicked
, editableTextBlurred
et la ligne ci-dessous déclenche tout :
$("div").click(divClicked);
Vérifiez ce code à http://jsfiddle.net/GeJkU/ . Ce n'est en aucun cas la meilleure façon d'écrire des divs modifiables, mais juste une façon de commencer et d'aborder la solution étape par étape. Honnêtement, j'ai appris autant que vous en écrivant ce long texte. Je termine, adios !