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);
	}
});
Explicaţii
  1. La fiecare click pe elmentul cu clasa editable, calculăm dacă elementul are un rând de text sau mai multe.
  2. În funcţie de câte rânduri are, apelăm o funcţie care injectează un input type="text" sau un textarea
Funcţia replaceField()
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['data'], '<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!

Poți insera blocuri de cod folosind BBcode:
[js].[/js] [html].[/html] [php].[/php] [css].[/css]
Poți folosi și câteva tag-uri HTML:
<blockquote>.</blockquote> <a href="">.</a> <strong>.</strong> <em>.</em>