Edit in place (EiP)

Dacă ai edit in place (EiP) pe site nu înseamnă că ai un site cool. Nu înseamnă că ai un site de succes. Nu înseamnă nici măcar că ai un site 2.0. De fapt, termenul de 2.0 a fost atât de folosit încât a început să fie evitat de majoritatea. Dacă stau bine să mă gândesc, nu știu de ce îl folosesc eu :D

Revenind. EiP înseamnă doar că îi oferi utilizatorului opțiunea de a edita un text fără a fi nevoie să părăsească pagina curentă. Desigur, EiP îl oferi doar unui utilizator înregistrat. Păi dacă e înregistrat, de ce să-ți mai bați capul? Că de plecat din site nu pleacă, nu? Păi el nu pleacă, dar asta nu înseamnă să-i facem în ciudă, nu? Câteva linii de cod se transferă mai repede față de o pagină întreagă. Sau cel puțin după matematica mea.

Markup

Dacă la sistemul de votare spuneam că avem un markup simplu, am cam mințit. Sunt deja două taguri, e stil inline, ce mai? E prea mult de scris! La EiP, markup-ul constă într-un SINGUR tag:

<h1 id="eip-102" class="editable">Edit in place demo</h1>

Cam asta e tot. Ăsta cred că e singurul tutorial unde voi folosi UN tag.

Explicații (da, e nevoie!)
  1. ID este folosit pentru a fi trimis spre server. Cum XHTML nu prea permite să avem ID-uri numerice, punem o literă/secvență de litere;
  2. class este folosit ca selector pentru jQuery. Putem folosi orice clasă, fără nicio restricție, cât timp nu există niciun conflict;
  3. TAG-ul nu este important. Poate fi h1, poate fi div sau doar un simplu paragraf, este irelevant, codul funcționând la fel. Exemplul final va conține mai multe elemente editabile. De asemenea, CSS-ul nu este important în momentul de față.

Javascript

$('.editable').click(function(){
var t=$(this);
	if(parseInt(t.css('line-height'), 10) < t.height()) {
		replaceField('textarea', t);
	}else {
		replaceField('input', t);
	}
});
&#91;/js&#93;

<h5>Explicații</h5>
<ol>
	<li>La fiecare click pe elmentul cu clasa <code>editable</code>, calculăm dacă elementul are un rând de text sau mai multe.</li>
	<li>În funcție de câte rânduri are, apelăm o funcție care injectează un <code>input type="text"</code> sau un <code>textarea</code></li>
</ol>

<h5>Funcția <code>replaceField()</code></h5>


function replaceField(type, e) {
	$(document.createElement(type))
		.css({
			position:'absolute',
			left:e.offset().left,
			top:e.offset().top,
			width:e.innerWidth(),
			height:e.innerHeight(),
			fontSize:e.css('font-size')
		}).addClass('editInPlaceField')
		.val(e.html())
		.appendTo('body').focus().blur(function(){
			var t=$(this);
			t.addClass('saving');
			$.ajax({
				type: "GET",
				url: "save.php",
				data: {id:e.attr('id'), data:t.val()},
				cache: false,
				success: function(data){
					e.html(data);
					t.remove();
				}
			});
		});
};//replaceField
Explicații
  1. Creăm un element textarea sau input. Așa cum am mai zis, metoda document.create() este mai rapidă. În plus, faptul că folosim argumentul type ne scutește de o condiție
  2. Îl poziționăm absolut și îi setăm dimensiunile conform cu elementul editabil
  3. Îi adăugăm o clasă pentru o stilizare ulterioară
  4. Îl adăugăm la body și îi facem focus
  5. La eventu-ul blur() trimitem datele spre server.
  6. Dacă totul este ok, textul vechi este înlocuit iar field-ul este șters
save.php

În save.php, doar ca exemplu, curățăm textul editat. Desigur, urmează și partea cu inserarea în baza de date șamd:

<?php
	echo strip_tags($_REQUEST&#91;'data'&#93;, '<a>');
?>
Gata

Cam asta a fost tot. Ca și până acum, am făcut o treabă ce ar fi „costat” o grămadă de kb dacă foloseai un plugin existent în doar câteva linii de cod.

13 Comentarii to “Edit in place (EiP)”

  1. In 30 min urma sa ma apuc de un edit in place, nu am gasit solutii care sa imi placa. Ai ales o rezolvare eleganta, simpla si… atat, nu te mai laud, you get the point: good job :)

    Thanks & keep up the good work (and posts) ;)

  2. cateva idei:

    – la edit in place ar trebui folosit font de aceeasi marime si typeface, inputul fara padding in plus fata de cum e el, astfel incat in momentul in care e editat, sa nu se miste.
    – o conventie pt edit in place este bg galben la hover, helps
    – la inputuri ar fi misto sa poti face submit cu enter cand termini de editat

    foarte misto articolul.

    PS: Ar merge o functie o idee mai complexa care sa citeasca id-ul de forma “eip_tabela_camp_id” sa poata fi folosita pt orice valoare din baza de date. Evident, necesita verificari in php.

  3. Nu sunt sigur cat de intuitiv ar fi submit pe blur, la mine cel putin ar fi a 3-a sau a 4-a chestie pe care as incerca-o ( evident dupa momentul de uitat in firebug sa vad daca nu cumva e un buton de submit ascuns pe undeva ).

    Personal as fi facut un form pe care sa am la submit request-ul ajax.

    Ah, si inca o chestie: salvare de date pe request GET ? o.O

    geh, si uitasem, ar trebui sa verifici inainte de request daca sunt datele diferite ( input fata de element ) ca sa nu te duci la server aiurea.

    Asta, si singura varianta cancel dupa cate ma prind ar fi un reload sanatos de pagina.

  4. Staicu Ionuț-Bogdan

    Am zis-o la taburi și nu am mai repetat și aici: dacă un anumit post prezintă un interes crescut, aprofundez subiectul. Iar acest articol a trezit un oareșce interes. Prin urmare, foarte probabil că va fi și un v2 al acestui articol ce va conține ceva completări.

    – la inputuri ar fi misto sa poti face submit cu enter cand termini de editat

    Se va face

    Nu sunt sigur cat de intuitiv ar fi submit pe blur, la mine cel putin ar fi a 3-a sau a 4-a chestie pe care as incerca-o ( evident dupa momentul de uitat in firebug sa vad daca nu cumva e un buton de submit ascuns pe undeva ).

    Mă gândesc să pun două butoane: unul pentru submit și unul pentru cancel. De astea am cam uitat, fiind destul de obosit la momentul scrierii.

    Ah, si inca o chestie: salvare de date pe request GET ? o.O

    Well… Da. Nu sunt programator back end și nu m-am gândit decât că GET e mai rapid, nu și că GET e mai limitat :D

    geh, si uitasem, ar trebui sa verifici inainte de request daca sunt datele diferite ( input fata de element ) ca sa nu te duci la server aiurea.

    Asta va fi în V2 :)

  5. Un mic bug, mai trebuie sa faci si stripslashes in save.php, la echo.

  6. Staicu Ionuț-Bogdan

    Un mic bug, mai trebuie sa faci si stripslashes in save.php, la echo.

    PHP-ul (și server side-ul în general) nu sunt chiar punctele mele forte :D

  7. Salut, există deja un plugin pt. jQuery: jEditable.

    Dar e interesantă ideea cu selectarea automată input | textarea.

    A, și pentru WordPress ai Front-end Editor.

  8. Staicu Ionuț-Bogdan

    @scribu: sunt conștient că există plugin-uri pentru tot ce am scris până acum pe blog, dar eu ofer două chestii pe care acele pluginuri nu le oferă:
    – explicații despre ce face (aproape) fiecare linie
    – ceva mai puțini KB.

    Desigur, dezavantajul major la ceea ce scriu eu este că nu sunt atât de multe opțiuni ca într-un plugin. Dar cine folosește toate acele opțiuni? :D

    Cât despre wordpress… Chiar mă bătea gândul să fac așa ceva acum câteva zile. Habar n-aveam că există așa ceva :D

  9. Da, e de admirat partea educativă. La mai multe :)

  10. @add
    Evident, ceva de genul “eip_users_password_id”, nu? :D
    Părerea mea e că e bun “eip_id”, numai că id-ul să fie de fapt un string criptat care să conțină datele de care zici tu, generat pe server cu vre-o funcție mcrypt sau ceva de genul.

    @Ionuț
    * În afară de butoane, ai putea pune “submit” la Enter pe input-uri (pentru că, evident, pe textarea nu se poate) și “cancel” la Esc

    * Apoi, parcă ți-am mai zis și eu, nu se fac modificări pe server prin GET.
    GET: a primi
    POST: a expedia
    Nu-i nici o diferență de viteză, e diferență doar la cantitatea și tipul de date pe care le poți trimite.

    * Nu trebuie să dai stripslashes în PHP decât dacă “magic_quotes_gpc” e On (folosești funcția get_magic_quotes_gpc() pentru a verifica asta)

    * Cum ți-am mai zis, scrie și tu cod mai lizibil, nu mai îmbârliga atât JS-ul ăla. Știu că “chaining”-ul e unul din punctele de atracție la jQuery/MooTools/etc., dar parcă prea abuzezi de el. :P

    * Ce se-ntâmplă în cazul în care ajax returnează o eroare? Ar trebui să adaugi o funcție și pentru “error” că așa îți rămâne clasa “saving” pe input și …atât! Utilizatorul tot așteaptă…

  11. probabil il voia la nivel conceptual, omul nu e programator server side deci nu intram pe partea aia.

    oricum, edit in place se face numai cand esti logat undeva, deci verificarile se pot face usor server side.

    pluginurile de jquery sunt in marea lor majoritate niste cacaturi. (mult prea mari daca ma intrebi pe mine)

  12. Arata bine, pacat ca nu merge in Internet Explorer. E un tutorial asemanator pe Nettuts care merge si pe IE dar are alte bug-uri mai nasoale. Lucrez la o versiune imbunatatita. >:)

  13. Staicu Ionuț-Bogdan

    @Flavius: merge în IE. Oarecum. Sunt doar probleme ce țin de CSS. Voi încerca să fac a doua versiune a acestui tutorial sub formă de plugin jQuery :)

Show trackbacks

Ți-a plăcut articolul? Lasă un comentariu!

You can insert code snippets using BBcode:
[js].[/js] [html].[/html] [php].[/php] [css].[/css]
You can also use some HTML tags:
<blockquote>.</blockquote> <code>.</code> <a href="">.</a> <strong>.</strong> <em>.</em>

windows apple dropbox facebook twitter