Creëer een In-Place Editing System

Gebruikers laten doorklikken door meerdere pagina's alleen al om een ​​veld te bewerken is zo 1999. In deze tutorial leer je hoe je een in-place bewerkingssysteem kunt maken zoals gevonden op populaire sites, zoals Flickr.


Een woord van de auteur

Met alle drukte rondom Web 2.0 is gebruiksgemak nu veel belangrijker dan ooit. Sommige gebruikers kunnen hun content bewerken zonder naar een andere pagina te hoeven gaan. Veel grote namen gebruiken dit patroon al met groot succes. Als je Flickr hebt gebruikt, heb je dit waarschijnlijk in actie gezien.

Ik geloof dat een demo meer zegt dan duizend woorden. Klik op de demo en probeer het zelf uit.

Vandaag gaan we kijken hoe we dit kunnen implementeren, je raadt het althans goed, onze favoriete JavaScript-bibliotheek, jQuery. Geïnteresseerd? Laten we meteen beginnen!

Ontwerpdoelen

Voordat we gaan kijken naar de implementatie van de functionaliteit, volgen hier een paar gedachten over de doelen en de daaruit voortvloeiende beslissingen.

  • We moeten de gebruiker de inhoud laten bewerken zonder de pagina te verlaten. Dit is een gegeven.
  • Dit zou als geheel moeten functioneren of als een geheel falen. Wanneer JS is uitgeschakeld, willen we geen rare eigenaardigheden tegenkomen.
  • De gebruiker moet weten dat de inhoud bewerkbaar is. Een subtiele blauwe achtergrondverandering zou de aandacht van de gebruiker hierop moeten vestigen.
  • Wanneer je te maken hebt met het activeren van de bewerking zijn er een paar opties. We kunnen de gebruiker laten bewerken met een normale klik of dubbelklik. Ik heb gekozen voor dubbelklikken omdat willekeurige dubbelklikken minder vaak voorkomen dan willekeurige klikken. Overschakelen is alleen een kwestie van het wijzigen van de parameter in de bind-gebeurtenis.
  • Een manier voor de gebruiker om de bewerkingen op te slaan of te negeren.
  • Bewaar of bewerk gebeurtenissen kunnen op 2 manieren worden geactiveerd. Toetsenbordevents of muisgebeurtenissen Ik heb voor muisevenementen gekozen omdat toetsenbordgebeurtenissen geen specificiteit hebben.
  • Met betrekking tot muisgebeurtenissen kunt u traditionele knoppen of gebruikelijke koppelingen gebruiken. Ik koos links zonder speciale reden.
  • De gebruiker moet de bewerking kunnen hervatten, zelfs als hij buiten het invoervak ​​klikt of de pagina verlaat en terugkeert.
  • Bovendien moet de gebruiker in staat zijn om zoveel mogelijk velden gelijktijdig te bewerken.

Nu we onze behoeften in kaart hebben gebracht, kunnen we nu verder gaan met hoe we dit gaan doen.

Plan van aanpak

We moeten nu in kaart brengen wat er in een specifieke volgorde moet gebeuren.

Stap 1: We moeten een klasse toevoegen bewerkbare voor elk element dat deze functionaliteit nodig heeft.

Stap 2: We moeten vervolgens zweven toevoegen aan elk bewerkbaar item om de aandacht te vestigen op het feit dat de inhoud van dat item bewerkbaar is. We voegen de zwevend toe en verwijderen deze met JavaScript in plaats van CSS. Dit wordt voornamelijk gedaan voor apparaten of browsers met JavaScript uitgeschakeld. We willen hen geen verkeerde visuele aanwijzingen sturen.

Stap 3: Wanneer er op een bewerkbaar item wordt geklikt, moeten we de inhoud vervangen en vervangen door een tekstvak met de oude tekst erin.

Stap 4a: Wanneer de gebruiker de bewerkingen wil opslaan, kopieert u de waarde van de invoer naar het bovenliggende element en verwijdert u het invoervak.

Stap 4b: Of wanneer de gebruiker de wijzigingen wil negeren, vervangt u de oude inhoud en verwijdert u het invoervak.

Dit zijn de basisstappen voor het maken van deze functionaliteit. Natuurlijk zijn er weinig andere kleine dingen, maar ik zal ze uitleggen als we verder gaan.

Core Markup

De HTML-markering van de demopagina ziet er zo uit.

    In-place editing-systeem - door Siddharth voor NetTuts      

In-place bewerken

door Siddharth voor de lieve mensen van Net Tuts

Elementen met een klasse van bewerkbare zijn, goed, bewerkbaar. In het geval u het nog niet gemerkt heeft, alle elementen die de bevatten bewerkbare klasse krijgen een blauwe achtergrond bij zweven om dit vermogen aan te geven.

Dubbelklik om de inhoud te bewerken. Gebruik de dynamisch gemaakte koppelingen om de wijzigingen op te slaan of weg te gooien. U kunt zoveel velden openen om te bewerken als u wilt, zonder enige hapering.

ik

  • ben Siddharth
  • hou van werken met internet
  • ben een freelancer
  • schrijf voor Net Tuts
  • is te vinden op www.ssiddharth.com
  • zal je nooit in de steek laten of je opgeven :)

Dingen om deze week te doen

  • Ontwerp goedkeuring van Deacon
  • Stuur een factuur naar Albert
  • Begin met werken aan het project van Dwight
  • Praat met Sarah over nieuwe ideeën
  • Controleer de site van Seth voor het renderen van bugs
  • Maak kennis met Clintson om het project te bespreken

Zoals u ziet, hebben we, afgezien van de ketelplaat, twee ongeordende lijsten. Elk li element heeft een klasse van bewerkbare om aan te geven dat de inhoud kan worden bewerkt.

We hebben ook de jQuery-bibliotheek en ons eigen scriptbestand opgenomen.

CSS-styling

 lichaam font-family: "Lucida Grande", "Verdana", sans-serif; lettergrootte: 12px;  a color: # 000;  a: hover text-decoration: none;  p margin: 30px 0 10px 0;  h1 font-size: 30px; opvulling: 0; marge: 0;  h2 font-size: 20px;  #container width: 820px; marge links: auto; marge-rechts: auto; opvulling: 50px 0 0 0;  .editHover achtergrondkleur: # E8F3FF;  .editBox width: 326px; minimale hoogte: 20 px; opvulling: 10px 15px; achtergrondkleur: #fff; rand: 2px vast # E8F3FF;  ul lijststijl: geen;  li width: 330px; minimale hoogte: 20 px; opvulling: 10px 15px; marge: 5px;  li.noPad opvulling: 0; breedte: 360 px;  vorm width: 100%;  .btnSave, .btnCancel opvulling: 6px 30px 6px 75px;  .block float: left; marge: 20 px 0; 

Niets bijzonders hier. Gewoon een hoop code voor lay-out- en stylingsdoeleinden.

Let vooral op de editHover en noPad klassen. We zullen ze een beetje gebruiken.

JavaScript-implementatie

Nu we beschikken over een solide framework en een aantal basisstijlen, kunnen we beginnen met het coderen van de vereiste functionaliteit. Merk op dat we uitgebreid gebruik maken van jQuery. Specifiek hebben we minimaal versie 1.3 of hoger nodig. Alles minder en het zal niet werken.

Hovers toevoegen

Zoals eerder vermeld, moeten we een subtiel blauwe achtergrond toevoegen aan bewerkbare objecten om aan te geven dat ze kunnen worden bewerkt. We hebben het al gemaakt editHover klas om voor dit te zorgen.

 $ (". editable"). hover (function () $ (this) .addClass ("editHover");, function () $ (this) .removeClass ("editHover"););

Dit kleine fragment zorgt voor dat voor ons. We gebruiken jQuery's zweven methode om de. toe te voegen editHover klasse wanneer het element wordt bewogen en verwijder het wanneer dit niet het geval is. We gebruiken deze om te verwijzen naar het specifieke element dat is overgeheveld. Als we het hadden gebruikt .bewerkbare als de selector wordt aan elk element de klasse toegevoegd. Dus we gebruiken deze om alleen het element te targeten dat we nodig hebben.

Uitschakelen van de elementen

Eerst moeten we ervoor zorgen dat onze code wordt uitgevoerd wanneer op het doelelement dubbel wordt geklikt. We koppelen dus eerst de handler voor dit evenement.

 $ (". editable"). bind ("dblclick", replaceHTML);

We hechten de replaceHTML functie naar de Dubbelklik evenement met betrekking tot de bewerkbare element met die ene voering. Nu kunnen we doorgaan met het uitschakelen van de elementen.

 function replaceHTML () oldText = $ (this) .html () .replace (/ "/ g," ")); $ (this) .html ("") .html ("
Wijzigingen opslaan Wijzigingen verwijderen ");

Laten we onze codebit een klein beetje doornemen.

Ik definieer de functionaliteit binnen een afzonderlijke benoemde functie in plaats van een anonieme functie voor een specifieke reden: ik zal deze functie meer dan eens gebruiken. Vervolgens slaan we de inhoud van het element op voor toekomstig gebruik met behulp van jQuery's html methode en vervangt alle aanhalingstekens omdat het onze uitvoer versmalt.

Nu onze inhoud veilig is opgeslagen voor later gebruik, kunnen we de elementen uitschakelen. Eerst halen we de li element door een lege string in te sturen naar de html methode. Vervolgens voegen we wat standaard HTML in voor een invoervak. We voegen er enkele klassen aan toe voor stylingdoeleinden. Wat nog belangrijker is, hebben we zijn waarde attribuut aan de originele tekst van het element dat is opgeslagen in oldText. We voegen ook een aantal koppelingen toe om te zorgen voor het opslaan en verwijderen van de bewerkingen. We hebben ook klassen aan hen toegevoegd, zodat ze gemakkelijk kunnen worden getarget en voor styling.

Zoals altijd gebruiken we deze om het element te targeten dat de gebeurtenis heeft geactiveerd.

De bewerkingen behouden

 $ (". btnSave"). live ("klik", functie () newText = $ (this) .siblings ("form") .children (". editBox") .val (). replace (/ "/ g , "" "); $ (this) .parent () .html (newText););

Laat me eerst jQuery's introduceren leven methode. Je hebt dit waarschijnlijk nog niet zo vaak gezien, dus ik zal snel een introductie geven.

U kunt geen handlers koppelen aan gebeurtenissen die worden geactiveerd door elementen die niet eens aanwezig zijn in de DOM wanneer de pagina en het JavaScript zijn geladen. Als u normale gebeurtenisbindingsfuncties gebruikt, mislukt deze vanwege de bovengenoemde reden. De leven methode zorgt ervoor.

Het bindt handlers aan evenementen, ongeacht wanneer het element is gemaakt. Voor meer informatie hierover kunt u de officiële documenten doornemen.

Laten we nu naar onze code kijken. We binden eerst de code in onze anonieme functie aan de Klik evenement. Binnen de functie bewaren we eerst de tekst in het invoervak. Dit kan een beetje lastig zijn, omdat het invoervak ​​geen ID heeft. We zoeken dus eerst naar het formulierelement dat toevallig de broer of zus is en vervolgens doorloopt om het invoerelement te vinden. We kopiëren vervolgens de waarde na het vervangen van alle aanhalingstekens die het bevat.

Vervolgens verkrijgen we het element links parent, de li element en vervang de HTML-inhoud door de tekst die we in de vorige stap hebben gekopieerd.

Dit blok had gemakkelijk als één voering kunnen worden gemaakt, maar ik koos ervoor om het in twee delen te splitsen in het belang van de leesbaarheid.

De bewerkingen negeren

 $ (". btnDiscard"). live ("klik", functie () $ (this) .parent () .html (oldText););

Dit is net zo eenvoudig als het lijkt. Omdat de gebruiker geen van de bewerkingen wil behouden. We vervangen gewoon de HTML-inhoud van het bovenliggende element door de oorspronkelijke tekst die we eerder naar de kopie hadden gekopieerd oldText veranderlijk.

Hiermee is de kern van ons werk gedaan. We hoeven alleen een paar bewerkingen uit te voeren om ervoor te zorgen dat dingen niet kapot gaan als de gebruiker onverwachte dingen doet.

Bindend en ontvelend

Als je onze code op dit punt hebt getest, kom je waarschijnlijk uit op deze bug voor het breken van functionaliteit: wanneer een gebruiker dubbelklikt in het resulterende invoervak, is deze nu gevuld met de HTML-inhoud van het bewerkingssysteem. Probeer het zelf. Bij elke dubbele klik wordt de waarde van het invoervak ​​weergegeven door er nog een aantal tekst aan toe te voegen. Dit probleem zal waarschijnlijk een stuk slechter zijn als u klikt als de triggergebeurtenis.

Om dit te verhelpen, moeten we de gebeurtenishandler voor dat specifieke element alleen ontbinden en opnieuw binden zodra de gebruiker op opslaan of verwijderen klikt. Laten we dat nu implementeren.

Onze vorige codeblokken moeten nu worden bewerkt om:

 function replaceHTML () // Code $ (this) .html ("") // Oudere invoegcode voor het formulier .unbind ('dblclick', replaceHTML); 

We onthaken de handler voor het element dat de gebeurtenis heeft geactiveerd. De rest van de elementen met de bewerkbare klasse hebben nog steeds hun handlers intact en zullen reageren op evenementen.

 $ (".btnSave"). live ("klik", functie () // Eerdere code $ (this) .parent () .html (newText) .bind ("dblclick", replaceHTML););
 $ (". btnDiscard"). live ("klik", functie () $ (this) .parent () .html (oldText) .bind ("dblclick", replaceHTML););

Vervolgens koppelen we die handlers terug, ongeacht of de gebruiker ervoor kiest ze te bewerken of niet. Als we deze niet opnieuw toevoegen, kunnen de velden slechts één keer worden bewerkt. De tweede keer dat ze dubbel worden geklikt, zijn de handlers niet langer aan de gebeurtenissen gekoppeld. We corrigeren dit door de handlers terug te koppelen aan de evenementen.

Een paar tweaks

Dit laatste stukje code is puur om het uiterlijk van ons effect op te fleuren. Als je het hebt gemerkt, de li heeft een beetje opvulling op zijn plaats om de tekst er beter uit te laten zien. Maar wanneer de tekst wordt verwijderd en vervangen door een tekstvak, zien we er lelijk uit en wordt het effect verbroken. We willen dat het tekstvak exact dezelfde ruimte in beslag neemt als de oorspronkelijke tekst. Met dit in gedachten voegen we een toe noPad klasse aan het element wanneer er dubbel op is geklikt en opnieuw is verwijderd wanneer de gebruiker de bewerking opslaat of weggooit.

 function replaceHTML () // Code $ (this) .addClass ("noPad") .html ("") // Eerdere code

We onthaken de handler voor het element dat de gebeurtenis heeft geactiveerd. De rest van de elementen met de bewerkbare klasse hebben nog steeds hun handlers intact en zullen reageren op evenementen.

 $ (".btnSave"). live ("klik", functie () // Eerdere code $ (this) .parent () .removeClass ("noPad") // Eerdere code);
 $ (". btnDiscard"). live ("klik", functie () $ (this) .parent () .removeClass ("noPad") // Eerdere code);

De volledige code

Hier ziet u hoe de volledige code eruitziet:

 $ (document) .ready (function () var oldText, newText; $ (". editable"). hover (function () $ (this) .addClass ("editHover");, function () $ ( this) .removeClass ("editHover");); $ (". editable"). bind ("dblclick", replaceHTML); $ (". btnSave"). live ("click", function () newText = $ (this) .siblings ("form") .children (". editBox") .val (). replace (/ "/ g," ")); $ (this) .parent () .html (newText). removeClass ("noPad") .bind ("dblclick", replaceHTML);); $ (". btnDiscard"). live ("klik", functie () $ (this) .parent () .html (oldText) .removeClass ("noPad") .bind ("dblclick", replaceHTML);); function replaceHTML () oldText = $ (this) .html () .replace (/ "/ g," ""); $ ( dit) .addClass ("noPad") .html ("") .html ("
Sla wijzigingen op .unbind ('dblclick', replaceHTML); );

Niet slecht. Vijftig oneven lijnen om wat spiffy nieuwe functionaliteit toe te voegen.

Nog een stap verder: de backend

In het belang van het niet te lang maken, heb ik vastgehouden aan het creëren van de client-side-functionaliteit alleen. Als u deze functionaliteit binnen uw eigen projecten wilt implementeren, gaat u er impliciet van uit dat u een back-endsysteem nodig heeft om deze wijzigingen op te slaan en, nog belangrijker, u hebt een AJAX-aanvraag nodig om dit gesprek asynchroon te maken.

Het toevoegen van deze functionaliteit zou een makkie moeten zijn, maar noteer dit wel. De bovenstaande code is gemaakt om dit patroon te illustreren en niet voor productiegebruik. Dus heb ik me onthouden van het toevoegen van extra IDS-attributen aan elementen en naamattributen aan tekstvakken. Voeg ze allemaal toe in uw productiecode, zodat het kenmerk name van de tekstvaknaam op een zinvolle manier kan worden ingesteld en op een dergelijke manier dat de back-end kan herkennen welk stukje gegevens moet worden bijgewerkt.

Om een ​​AJAX-verzoek toe te voegen, zou onze bewaarhandler moeten worden bijgewerkt naar:

 $ (". btnSave"). live ("klik", functie () newText = $ (this) .siblings ("form") .children (". editBox") .val (). replace (/ "/ g , "" "); $ .ajax (type:" POST ", url:" handler.php ", data: newText, success: function (msg) // Enige code hier om een ​​succesvolle bewerking weer te geven;) ; $ (this) .parent () .html (newText) .removeClass ("noPad"). bind ("dblclick", replaceHTML););

Houd er rekening mee dat u voor de back-end geen idee hoeft te hebben van wat u naar de back-end verzendt. U hebt extra gegevens nodig, samen met de bijgewerkte tekst zodat de app weet welke gegevens moeten worden bewerkt. U kunt eenvoudig meer dan één stuk gegevens naar het script verzenden als dat nodig is.

Conclusie

En daar heb je het; hoe u een gebruiksvriendelijke functionaliteit aan uw projecten kunt toevoegen. Hopelijk heb je deze tutorial interessant gevonden en dit was nuttig voor jou. Voel je vrij om deze code elders in je projecten en hier te gebruiken als je in de problemen raakt.

Vragen? Leuke dingen om te zeggen? Kritiek? Klik op het gedeelte Opmerkingen en laat een opmerking achter. Happy codering!

  • Volg ons op Twitter of abonneer je op de Nettuts + RSS-feed voor meer dagelijkse webontwikkelingen, tuts en artikelen.