Digicted

Takenlijst met “toevoegen” en “verwijderen” maken met prototype

Eerder deze week schreef ik al over het toevoegen van een nieuwe rij met prototype waar ik uitlegde hoe je een tabel gemakkelijk dynamisch kunt uitbreiden met behulp van wat Javascript.
Dit keer gaan we weer aan de slag met prototype, maar maken we een dynamische todolist. We willen gebruikers items laten toevoegen en verwijderen en vervolgens opslaan. Voor het gemak heb ik hier een plat tekstbestand voor gebruikt, maar het is natuurlijk ook mogelijk om het naar een database te schrijven. Laten we maar weer beginnen de HTML te schrijven:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
  "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <title>Todolist</title>
    <script type="text/javascript" src="prototype.js"></script>
    <script type="text/javascript" src="todolist.js"></script>
  </head>
  <body>
    <form action="displaylist.php" method="post" id="items">
      <fieldset>
        <legend>Items</legend>
        <ul id="todolist">

        </ul>
        <input type="submit" name="done" value="Klaar" id="done">
      </fieldset>
    </form>
    <form id="addtodo" action="" method="post">
      <fieldset>
        <legend>Nieuwe items</legend>
        <label for="item">Item</label>
        <input type="text" name="item" id="item">
        <input type="submit" name="add" value="Voeg toe" id="add">
      </fieldset>
    </form>
  </body>
</html>

Het lijkt me niet dat ik hier veel uitleg bij hoef te geven. Er komen simpelweg twee formulieren en een lijst. Het tweede formulier is voor het toevoegen van nieuwe items en het eerste formulier hebben we straks nodig om de waarden echt op te slaan.

En dan het Javascript:

function addItem()
{
  $( 'addtodo' ).onsubmit = function()
  {
    var item = $F( 'item' );
    id = id + 1;
    var newitem = '<li id="todo-' + id  + '">' + item;
    newitem += ' (<a href="#" id="delete-item-' + id + '" class="delete">verwijderen</a>)';
    newitem += '<input type="hidden" name="items[]" value="' + item + '">';
    newitem += '</li>';
    new Insertion.Bottom( "todolist", newitem );
    deleteItem();
    $('item').value = '';
    Form.Element.focus( 'item' );
    return false;
  }
}

function deleteItem()
{
  var items = document.getElementsByClassName("delete");
  for (var i=0; i < items.length; i++)
  {
    var myitem = items[i];
    items[i].onclick = function()
    {
      $( 'todo-' + this.id.substring( 12 ) ).remove();
      return false;
    }
  }
}

function init()
{
  id = 0;
  addItem();
}

Event.observe(window, 'load', init, false);

Hier zien we eerst een functie om een nieuw item toe te voegen aan de lijst (additem) als het onderste form gesubmit wordt. We voegen het item toe aan de lijst en maken daarna het vak leeg. Daarna plaatsen we de focus in het vak, zodat er gelijk een nieuw item getypt kan worden.
De return false; is om te voorkomen dat het formulier echt gesubmit wordt.

Daarna deleteItem() om ook items te kunnen verwijderen. Eerst halen we daar alle elementen op met de class “delete” en daarna kijken we of er op geklikt wordt. Als dit zo is verwijderen we de complete li met het dat id van het DOM.
De andere functies zullen aardig vanzelfsprekend zijn als je het vorige artikel hebt gelezen

Nu komt de PHP:

<?php
$sList = '';
foreach( $_POST[ 'items' ] as $sItem )
{
  $sList .= "- " . $sItem . "\n\r";
}
file_put_contents( "list.txt", $sList );
?>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
  "http://www.w3.org/TR/html4/strict.dtd">
<html>
  <head>
    <title>Resultaat</title>
  </head>
  <body>
    <p><a href="list.txt">De lijst</a> is succesvol weggeschreven.</p>
  </body>
</html>

Ook dit stelt op zich niet zo heel veel voor:

  1. Loop door alle inputvelden heen en voeg ze toe aan een variable.
  2. Schrijf deze variable weg naar een bestand. Ik gebruik hier de functie file_put_contents, die pas beschikbaar is vanaf versie 5; als er behoefte is aan een PHP4-versie wil ik deze later nog posten.
  3. Geef de gebruiker een linkje naar zijn nieuwe todolist. Het is natuurlijk ook mogelijk om de lijst al gelijk weer te geven.

Bekijk hier de demo en stel eventuele vragen in de reacties.

2 reacties to “Takenlijst met “toevoegen” en “verwijderen” maken met prototype”

  1. Dietrich:

    Twee kleine opmerkingen: a) het is mogelijk om een naamloze taak aan te maken en b) om te voorkomen dat de browser effectief # (dit bevindt zich in de href van de verwijderen-links) aanroept en de pagina niet terug naar het begin springt kan een return false eventueel helpen in uw onclick-functiedefinitie. Dit laatste heb ik echter niet getest.

  2. Martijn Engler:

    Van de lege taken ben ik me bewust, dat vond ik niet zo erg voor het voorbeeld maar is uiteraard op te lossen door dit stukje in de PHP te veranderen:

    foreach( $_POST[ 'items' ] as $sItem )
    {
      $sList .= "- " . $sItem . "nr";
    }
    

    Naar:

    foreach( $_POST[ 'items' ] as $sItem )
    {
      if( !empty( $sItem ) )
      {
        $sList .= "- " . $sItem . "nr";
      }
    }
    

    Je andere punt heb ik aangepast, bedankt voor de tip. In de “echte” versie wordt er niet gelinkt naar “#” maar naar een PHP-bestand, om het verwijderen ook mogelijk te maken zonder Javascript. Ik zal nog even zien of ik dat hier ook nog post.

Reageer