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
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!)
IDeste folosit pentru a fi trimis spre server. Cum XHTML nu prea permite să avem ID-uri numerice, punem o literă/secvenţă de litere;classeste folosit ca selector pentru jQuery. Putem folosi orice clasă, fără nicio restricţie, cât timp nu există niciun conflict;- TAG-ul nu este important. Poate fi
h1, poate fidivsau 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
- La fiecare click pe elmentul cu clasa
editable, calculăm dacă elementul are un rând de text sau mai multe. - În funcţie de câte rânduri are, apelăm o funcţie care injectează un
input type="text"sau untextarea
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
- Creăm un element
textareasauinput. Aşa cum am mai zis, metodadocument.create()este mai rapidă. În plus, faptul că folosim argumentultypene scuteşte de o condiţie - Îl poziţionăm absolut şi îi setăm dimensiunile conform cu elementul editabil
- Îi adăugăm o clasă pentru o stilizare ulterioară
- Îl adăugăm la
bodyşi îi facem focus - La eventu-ul
blur()trimitem datele spre server. - 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.

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)
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.
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 ?
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.
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.
Se va face
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.
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
Asta va fi în V2
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
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.
@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?
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
Da, e de admirat partea educativă. La mai multe
@add
Evident, ceva de genul “eip_users_password_id”, nu?
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.
* 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ă…
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)
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. >:)
@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