Table des matières
Niveau
..........
En rapport...

Quoi

Prenons un span normal. Lorsqu'on clique dessus, il se transforme en zone de saisie de texte et lorsqu'on sort de cette zone de saisie, le <span> revient, avec son nouveau contenu.
Je vais décrire ici la méthode pour faire ceci.
Exemple fonctionnel : editinplace.htm

Ma méthode est adapté aux span mais peu s'adapter a n'importe quelle balise. Par exemple, pour les div faire juste un “Remplacer tout” de “span.” par “div.”

Principe

On va attacher un évènement “onclick” aux <span> qui on la classe CSS “editinplace”. Cet évènement va appeler une fonction qui va remplacer le contenu du span par un textarea auquel on va attacher l'évènement “onblur”. Ainsi, lorsqu'on quitte le textarea, un fonction va mettre la valeur du textarea dans le <span>. Le textarea va donc disparaitre et laisser place à la nouvelle valeur.

Code

javascript
addEvent(window,'load',EditInPlace);
function EditInPlace() {
	var v=getElementsBySelector("span.editinplace");
	var l=v.length;
	for(i=0;i<l;i++)
		addEvent(v[i],'click',ShowEditInPlace);
}
function ShowEditInPlace() {
	removeEvent(this,'click',ShowEditInPlace);
	this.id="editinplace_inprogress";
	var inner=replace(this.innerHTML,"<br>","\n");
	inner=replace(inner,"<BR>","\n");
	this.innerHTML='<textarea class="editinplace">'+inner+'</textarea>';
	var v=getElementsBySelector("textarea.editinplace");
	var l=v.length;
	for(i=0;i<l;i++) {
		v[i].focus();
		addEvent(v[i],'blur',HideEditInPlace);
	}
}
function HideEditInPlace() {
	var e=document.getElementById('editinplace_inprogress');
	e.innerHTML=replace(this.value,"\n","<br />");
	e.id='';
	addEvent(e,'click',ShowEditInPlace);
}
function addEvent( obj, type, fn ) {
//John Resig : http://ejohn.org/projects/flexible-javascript-events/
	if ( obj.attachEvent ) {
		obj['e'+type+fn] = fn;
		obj[type+fn] = function(){obj['e'+type+fn]( window.event );}
		obj.attachEvent( 'on'+type, obj[type+fn] );
	} else
		obj.addEventListener( type, fn, false );
}
function removeEvent( obj, type, fn ) {
//John Resig : http://ejohn.org/projects/flexible-javascript-events/
	if ( obj.detachEvent ) {
		obj.detachEvent( 'on'+type, obj[type+fn] );
		obj[type+fn] = null;
	} else
		obj.removeEventListener( type, fn, false );
}
function getElementsBySelector(selector){
//Extracted from nifty.js
	var i,selid="",selclass="",tag=selector,f,s=[],objlist=[];
	if(selector.indexOf(" ")>0){  //descendant selector like "tag#id tag"
		s=selector.split(" ");
		var fs=s[0].split("#");
		if(fs.length==1) return(objlist);
		f=document.getElementById(fs[1]);
		if(f) return(f.getElementsByTagName(s[1]));
		return(objlist);
	}
	if(selector.indexOf("#")>0){ //id selector like "tag#id"
		s=selector.split("#");
		tag=s[0];
		selid=s[1];
    }
	if(selid!=""){
		f=document.getElementById(selid);
		if(f) objlist.push(f);
		return(objlist);
    }
	if(selector.indexOf(".")>0){  //class selector like "tag.class"
		s=selector.split(".");
		tag=s[0];
		selclass=s[1];
    }
	var v=document.getElementsByTagName(tag);  // tag selector like "tag"
	if(selclass=="")
		return(v);
	for(i=0;i<v.length;i++){
		if(v[i].className.indexOf(selclass)>=0)
			objlist.push(v[i]);
    }
	return(objlist);
}
function replace(string,text,by) {
	// Replaces text with by in string
    var strLength = string.length, txtLength = text.length;
    if ((strLength == 0) || (txtLength == 0)) return string;
    var i = string.indexOf(text);
    if ((!i) && (text != string.substring(0,txtLength))) return string;
    if (i == -1) return string;
    var newstr = string.substring(0,i) + by;
    if (i+txtLength < strLength)
        newstr += replace(string.substring(i+txtLength,strLength),text,by);
    return newstr;
}

Utilisation

Il suffit de placer ce code dans vos page et de mettre la classe “editinplace” aux <span> a rendre éditable. ex:

html4strict
<span class="editinplace">J'édite</span>

Un peu de style

Vois pouvez définir un style pour les span éditable ainsi que pour les textarea.
Pour ce faire définissez les style suivants : span.editinplace et textarea.editinplace.
Ex :

css
span.editinplace {
	border-bottom:1px dashed #000
}
textarea.editinplace {
	border:1px dashed #000;
	border-bottom:0
}

Aller plus loin

Éditer sans sauvegarder n'est pas fort utile. On pourrais imaginer un système de sauvegarde par cookie ou par AJAX.
Si quelqu'un le développe, ça serais sympa de nous en faire profiter :)


iDo 27/12/2005 13:32