[JS] Verwijder script

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • bindsa
  • Registratie: Juli 2009
  • Niet online
Ik wil een script maken dat aangemaakte links kan verwijderen. Wat ik nu heb is een AJAX script die als output een lijst met links op het scherm genereert, met naast elke link een plaatje met een verwijder kruisje erop. De bedoeling is dat als mensen op het kruisje klikken, de link verwijderd wordt d.m.v. AJAX en PHP. Het script dat de links ophaalt zit als volgt in elkaar:

JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
window.onload = function() {
    XmlHttp = GetXmlHttpObject();
    var url = "index.php?action=getlinks";
    url = url + "&sid=" + Math.random();
    XmlHttp.onreadystatechange = stateChanged;
    XmlHttp.open("GET", url, true);
    XmlHttp.send(null);
    document.getElementById("loader").style.display = "block";
    document.getElementById("submit").disabled = true;
    var submitId = document.getElementById("submit");
    addEvent(submitId, 'click', submit);
}
function GetXmlHttpObject()
{
    if (window.XMLHttpRequest)
      {
      //IE7+, Firefox, Chrome, Opera, Safari
      return new XMLHttpRequest();
      }
    if (window.ActiveXObject) {
      //IE6, IE5
      return new ActiveXObject("Microsoft.XMLHTTP");
      }
    return null;
}
function stateChanged() {
if (XmlHttp.readyState == 4) {
    document.getElementById("links").innerHTML = XmlHttp.responseText;
    document.getElementById("loader").style.display = "none";
    document.getElementById("submit").disabled = false;
  }
}
function submit() {
    XmlHttp = GetXmlHttpObject();
    var name = document.getElementById("newName").value;
    var uri = document.getElementById("newUri").value;
    var url = "index.php?action=submit&name=" + name + "&uri=" + uri;
    url = url + "&sid=" + Math.random();
    XmlHttp.onreadystatechange = stateChanged;
    XmlHttp.open("GET", url, true);
    XmlHttp.send(null);
    document.getElementById("loader").style.display = "block";
    document.getElementById("submit").disabled = true;
}
function addEvent(element, type, fn)
{
    if (element.addEventListener) {
        element.addEventListener(type, fn, true);
    } else if (element.attachEvent) {
        element.attachEvent("on"+type, fn);
    }
}

Met een HTML dat er zo uitziet:
HTML:
1
2
3
4
5
6
7
8
9
10
11
12
13
<h1>Alle bestanden op de lokale webserver:</h1><br />
<div id = 'loader' style = 'display: none'>
<img src = 'loader.gif' />
<br /><br />
</div>
<div id = 'links'>
</div>
<br />
Naam van de nieuwe link:
<br /><input type = 'text' id = 'newName' /><br />
Adres waarna de link moet verwijzen:
<br /><input type = 'text' id = 'newUri' /><br />
<input id = 'submit' type = 'submit' value = 'Voeg link toe'/><br />


En tot slot het PHP connector script:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
<?php 
if ($_GET['action'] == 'submit') {
    if(!empty($_GET['name']) and !empty($_GET['uri'])) {
        $name = $_GET['name']; 
        $link = $_GET['uri'];
        mysql_query("INSERT INTO links (name, link) VALUES ('$name', '$link')", $mysql);
        echoContents();
    }
}
if ($_GET['action'] == 'getlinks') {
    echoContents();
}
function echoContents() {
    global $mysql;
    $links = mysql_query("SELECT name, link FROM links", $mysql);
    if (mysql_num_rows($links) == 0) {
        echo "<i>Nog geen links toegevoegd</i>";
    }
    else {
        echo "<b>Links:</b>";
        echo "<table cellspacing = '0' celpadding = '0' border = '0'>";
        while(list($name, $link) = mysql_fetch_row($links)) {
            echo "<tr>";
            echo "<td><a href = '" . $link . "'>" . $name . "</a></td>";
            echo "<td class = 'icon'><a href = '#'><img border = '0' src = 'close_na.gif' /></a></td>";
            echo "</tr>";
        }
        echo "</table>";
    }
    echo "<br><br>";
    exit;
}
?>


Nou dacht ik dat het als volgt gedaan kon worden: Ik geef elk kruisje een id mee (de 1e id = 1, de 2e id = 2 enz.) En dan na de table nog een hidden input field met daarin de waarde van het aantal id's. Vervolgens laat ik bij window.onload = function() een loopje lopen die aan elk kruisje een een onclick event koppelt met een functie. Die functie doet dan het AJAX gedeelte om de link te verwijderen.

Mijn eerste vraag is, hoe kan ik dat loopje omzeilen, want ik kan me voorstellen dat het bij lange lijsten links nog wel eens traag kan worden.

De tweede vraag heeft betrekking op het later aankoppelen van events, want bij HTML zou dit werken: onclick = doSomething(this). Maar hoe doe ik dat met events die ik er later aan koppel? (Ik wil de events er per se later aan koppelen).

Alvast bedankt

Acties:
  • 0 Henk 'm!

  • André
  • Registratie: Maart 2002
  • Laatst online: 12-09 14:32

André

Analytics dude

Waarom zou je achteraf met een loopje de onclick toevoegen. Dat kun je toch ook direct tijdens het opbouwen van de lijst doen? Je geeft dan elke link een attribuut id mee met daarin een nummer. In de onclick roep je dan ongeveer zo een functie aan: onclick="remove(this.id)".

Acties:
  • 0 Henk 'm!

  • wackmaniac
  • Registratie: Februari 2004
  • Laatst online: 11-09 10:21
Twee extragratis tips zo aan het eind van de dag;
# gebruik een JS framework. Of je JQuery, Prototype of Mootools gebruikt maakt niet uit, maar het houdt je javascript code zoveel overzichtelijker, zeker als je met AJAX-requests gaat werken.
# Escape de zaken die je in je SQL gooit.
# Aanroepen die een aanpassing aan de database als gevolg hebben altijd POSTEN en niet via een get-query.

Aanpak die ik zou kiezen; Elke invoer een formulier geven met een hidden id en een submit knop en daar een javascript onSubmit-event aanhangen. Als je teveel formulieren krijgt moet je misschien denken aan pagineren. Als je dan al deze formulieren ook nog eens eenzelfde class geeft, kan je met javascript in een keer een submit-event laten afhandelen voor alle formulieren. In Prototype zou dat worden:

JavaScript:
1
2
3
4
5
document.observe( 'dom:ready', function() {
  $$('form.verwijderen').observe( 'submit' , function ( event ) {
    // doe je ding
  });
});


Als je de javascript onderaan je pagina zet kan je zelfs de dom:ready-event weglaten.

@André
Dat zou je doen, omdat dat je dan je HTML schoon houdt :)

[ Voor 0% gewijzigd door wackmaniac op 22-02-2010 23:37 . Reden: typo ]

Read the code, write the code, be the code!


Acties:
  • 0 Henk 'm!

  • André
  • Registratie: Maart 2002
  • Laatst online: 12-09 14:32

André

Analytics dude

wackmaniac schreef op maandag 22 februari 2010 @ 23:37:

@André
Dat zou je doen, omdat dat je dan je HTML schoon houdt :)
:?

Dus je HTML moet schoon zijn, maar dat je via allerlei scripts zaken aan de DOM toevoegt maakt niet uit? In beide gevallen is de echte HTML even groot.

Eerlijk gezegd vind ik het net zo'n kul reden als wanneer men later attributen of elementen middels script toevoegt om zo de HTML te laten valideren...Je houdt eigenlijk jezelf voor gek door de 'view-source' knop. Eigenlijk zou je alleen de 'view generated source' knop van de webdeveloper add-on moeten hebben ;)

Acties:
  • 0 Henk 'm!

  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 10-09 08:45
Ik zou vooral niet de html serverside samenstellen, maar daar gewoon een JSON feed leveren met de informatie. De html kun je eenvoudig clientside samenstellen.

Waar/hoe je events koppelt boeit niet zo, al is deze direct meenemen in de html-opbouw wel een stuk sneller ipv acheraf dynamisch.

[ Voor 29% gewijzigd door Bosmonster op 23-02-2010 09:41 ]


Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:53

crisp

Devver

Pixelated

Bosmonster schreef op dinsdag 23 februari 2010 @ 09:39:
Ik zou vooral niet de html serverside samenstellen, maar daar gewoon een JSON feed leveren met de informatie. De html kun je eenvoudig clientside samenstellen.
Ik zou wel in eerste instantie uitgaan van een HTML formulier dat zonder javascript ook bruikbaar is ;)

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 10-09 08:45
crisp schreef op dinsdag 23 februari 2010 @ 09:41:
[...]

Ik zou wel in eerste instantie uitgaan van een HTML formulier dat zonder javascript ook bruikbaar is ;)
Ik bedoel het lijstje met links dat ie ophaalt via XHR. Ipv dat aan te leveren als kant-en-klare html, zou ik die opbouw door de client laten plaatsvinden.

Neemt niet weg dat je ook een niet-javascript-handler kan schrijven natuurlijk in je template.

[ Voor 11% gewijzigd door Bosmonster op 23-02-2010 09:49 ]


Acties:
  • 0 Henk 'm!

  • crisp
  • Registratie: Februari 2000
  • Laatst online: 00:53

crisp

Devver

Pixelated

Bosmonster schreef op dinsdag 23 februari 2010 @ 09:46:
[...]


Ik bedoel het lijstje met links dat ie ophaalt via XHR. Ipv dat aan te leveren als kant-en-klare html, zou ik die opbouw door de client laten plaatsvinden.
Dat ligt er een beetje aan; als je al code hebt die die HTML genereert dan zou ik gewoon die output gebruiken. Daarbij is het injecteren van een fragment mbv innerHTML ipv via DOM methods allemaal elementen aanmaken ook een stuk sneller. Dat zijn dus al een paar afwegingen die je moet maken.

Intentionally left blank


Acties:
  • 0 Henk 'm!

  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 10-09 08:45
crisp schreef op dinsdag 23 februari 2010 @ 09:49:
[...]

Dat ligt er een beetje aan; als je al code hebt die die HTML genereert dan zou ik gewoon die output gebruiken. Daarbij is het injecteren van een fragment mbv innerHTML ipv via DOM methods allemaal elementen aanmaken ook een stuk sneller. Dat zijn dus al een paar afwegingen die je moet maken.
Je kunt nu alleen die feed nergens anders meer voor gebruiken. Overigens kun je ook clientside natuurlijk gewoon een string (of array dan) opbouwen en via innerHTML injecteren. Dat is sowieso veel sneller bij het opbouwen van grote delen html.

[ Voor 6% gewijzigd door Bosmonster op 23-02-2010 09:55 ]


Acties:
  • 0 Henk 'm!

  • wackmaniac
  • Registratie: Februari 2004
  • Laatst online: 11-09 10:21
André schreef op dinsdag 23 februari 2010 @ 08:41:
[...]

:?

Dus je HTML moet schoon zijn, maar dat je via allerlei scripts zaken aan de DOM toevoegt maakt niet uit? In beide gevallen is de echte HTML even groot.

Eerlijk gezegd vind ik het net zo'n kul reden als wanneer men later attributen of elementen middels script toevoegt om zo de HTML te laten valideren...Je houdt eigenlijk jezelf voor gek door de 'view-source' knop. Eigenlijk zou je alleen de 'view generated source' knop van de webdeveloper add-on moeten hebben ;)
Ik vind het volgende
HTML:
1
2
3
4
<a href="/mooie-url" class="javascript-dingetje">linkje</a>
<script type="text/javascript">
  // een berg javascript met observers enzo
</script>


Een stuk overzichterlijker dan:
HTML:
1
<a href="/mooie-url" class="javascript-dingetje" onclick="// ook allemaal javascript met functionaliteit;">linkje</a>


Die onclick heeft niets met opmaak te maken en hoort mijn inziens dus niet in je tag thuis. Is gewoon onderdeel van de scheiding van opmaak en functionaliteit.

En over de grootte van de HTML heb je mij niet gehoord, dat trek je er een beetje met de haren bij.

Read the code, write the code, be the code!


Acties:
  • 0 Henk 'm!

  • bindsa
  • Registratie: Juli 2009
  • Niet online
Over het strippen van de MySQL input, daar ben ik me van bewust, het is maar een testscript dat draait op een lokale server :)

De grote vragen blijven:
- Hoe kan ik aan evt. een hele class een event hangen?
- Wat is een bruikbare vervanging van onclick = "doSomething(this)" (als ik de events er later aan hang)?

Acties:
  • 0 Henk 'm!

  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 10-09 08:45
wackmaniac schreef op dinsdag 23 februari 2010 @ 10:58:
[...]
Ik vind het volgende

Een stuk overzichterlijker dan:

Die onclick heeft niets met opmaak te maken en hoort mijn inziens dus niet in je tag thuis. Is gewoon onderdeel van de scheiding van opmaak en functionaliteit.
Het gaat om dynamisch geinjecteerde html. Niemand die daar iets van ziet en het resultaat is hetzelfde.
L0calh0st schreef op dinsdag 23 februari 2010 @ 19:21:

De grote vragen blijven:
- Hoe kan ik aan evt. een hele class een event hangen?
- Wat is een bruikbare vervanging van onclick = "doSomething(this)" (als ik de events er later aan hang)?
Een library pakken zoals jQuery.

[ Voor 28% gewijzigd door Bosmonster op 23-02-2010 19:34 ]


Acties:
  • 0 Henk 'm!

  • bindsa
  • Registratie: Juli 2009
  • Niet online
Een library pakken zoals jQuery.
Misschien gezeur, maar jQuery is een stuk trager dan gewone JavaScript code, plus dat jQuery nog wel eens errors geeft in IE. Bovendien is dit script ook een beetje bedoeld om JavaScript en AJAX goed in de vingers te krijgen.

Acties:
  • 0 Henk 'm!

  • R4gnax
  • Registratie: Maart 2009
  • Laatst online: 06-09 17:51
L0calh0st schreef op dinsdag 23 februari 2010 @ 19:40:
[...]


Misschien gezeur, maar jQuery is een stuk trager dan gewone JavaScript code, plus dat jQuery nog wel eens errors geeft in IE. Bovendien is dit script ook een beetje bedoeld om JavaScript en AJAX goed in de vingers te krijgen.
Ten eerste is jQuery voor common usage scenarios even snel als straight-up DOM manipulatie. Sowieso maakt dat bij responstijden onder de 200ms voor eenmalige (dus niet doorlopende dan wel animerende) acties niet uit, vanwege het menselijk reactievermogen.

Ten tweede: als jQuery echt harde errors geeft in IE kun je er geriefelijk van uit gaan dat je zelf iets fout gedaan hebt. JQuery is zo gebouwd dat het alles cross-browser normaliseert en standardiseert: het neemt je 'tig bugs, pitfalls en gotcha's uit handen die je anders zelf op mag lopen lossen. Tenzij je een echte bug in de library gevonden hebt, maak je gebruik van ongespecificeerd gedrag in de API of zo iets.


Dan in het algemeen over je huidige aanpak: ik zou er voor kiezen om eens wat meer CSS en wat minder tables te gebruiken. Een grafische verwijder button als image tag in een anchor tag is not-done. Dat doe je vanuit usability oogpunt ten minste als anchor tag met daarin de tekst 'verwijder' die je met CSS verbergt (negatieve text-indent, bijvoorbeeld), een tooltip met dezelfde 'verwijder' tekst via het title attribuut en de grafische look via een background image. Aangezien het hier een lijst betreft en geen volledig tabulaire data zou ik ook gewoon een unordered list gebruiken en niet een table.

En wat betreft problemen met event handlers op alle items in een dynamische lijst: event delegation anyone?

HTML:
1
2
3
4
5
6
<ul id="files">
 <li>File A <a href="?delete=File%20A" title="Verwijder">Verwijder</a></li>
 <li>File B <a href="?delete=File%20B" title="Verwijder">Verwijder</a></li>
 <li>File C <a href="?delete=File%20C" title="Verwijder">Verwijder</a></li>
 <li>File D <a href="?delete=File%20D" title="Verwijder">Verwijder</a></li>
</ul>


JavaScript:
1
2
3
4
5
6
7
8
9
10
11
12
$(document).ready(function(){
  $("#files").bind("click", function(event){
   var $target = $(event.target);
   if ($target.is("a")) {
     event.preventDefault();

     $.get($target.attr("href"), function(){
       $target.closest("li").remove();
     });
   }
  });
});

Acties:
  • 0 Henk 'm!

  • Bosmonster
  • Registratie: Juni 2001
  • Laatst online: 10-09 08:45
L0calh0st schreef op dinsdag 23 februari 2010 @ 19:40:
[...]


Misschien gezeur, maar jQuery is een stuk trager dan gewone JavaScript code, plus dat jQuery nog wel eens errors geeft in IE. Bovendien is dit script ook een beetje bedoeld om JavaScript en AJAX goed in de vingers te krijgen.
De jQuery codebase is in veel gevallen veel verder geoptimaliseerd dan je zelf toe zult kunnen passen xbrowser. jQuery zal dan ook vaak juist als een stuk sneller uit de bus komen dan de code die je zelf schrijft, tenzij je precies alle optimalisaties weet en ook uitwerkt per browser.

En jQuery geeft geen errors in IE, dat is gewoon onzin. Dan doe je zelf iets verkeerd.
R4gnax schreef op dinsdag 23 februari 2010 @ 23:13:
[...]
En wat betreft problemen met event handlers op alle items in een dynamische lijst: event delegation anyone?
Ja, maar pak dan gewoon de live (en sinds 1.4.2 delegate) functies.

[ Voor 22% gewijzigd door Bosmonster op 24-02-2010 09:40 ]


Acties:
  • 0 Henk 'm!

  • R4gnax
  • Registratie: Maart 2009
  • Laatst online: 06-09 17:51
Bosmonster schreef op woensdag 24 februari 2010 @ 09:37:
Ja, maar pak dan gewoon de live (en sinds 1.4.2 delegate) functies.
In jQuery 1.3 kon je nog geen context opgeven en moesten alle events helemaal door bubblen naar de root document node, maar nu je .live() in 1.4 een context mee kunt geven (of inderdaad .delegate() kunt gebruiken, wat onder de kap .live() met een context gebruikt) is dat naar alle waarschijnlijkheid inderdaad beter.

Acties:
  • 0 Henk 'm!

  • tonyisgaaf
  • Registratie: November 2000
  • Niet online
offtopic:
Wow, ik leefde tot nu toe in de veronderstelling dat dit soort functies een handler aan elke node attacheten. In één klap een hoop geleerd.

NL Weerradar widget Euro Stocks widget Brandstofprijzen widget voor 's Dashboard

Pagina: 1