Help! Een DOM-probleem!

Okay. Dit is a bit of a first: ik ga plat op de vloer liggen bedelen.

Ik zat eigenlijk al in bed, maar ik ben ervan wakker geworden. Er is iets dat ik niet in orde krijg, en ik zou het enorm graag in orde krijgen. Zo snel mogelijk, deze week. En ik ken er niet genoeg van om het meteen en goed te doen, wat wil zeggen dat ik er veel tijd zou moeten in steken, en ik heb niet veel tijd, argl.

Ik kan er ook geen geld voor betalen, maar, euh, er is de eer natuurlijk. Oh, en als ik de mevrouw/meneer/firma met een werkende oplossing een plezier daarmee kan doen: ik zet ze een week in een reuzengrote banner op elke pagina van mijn weblog!

Het probleem is, zoals de titel laat vermoeden, een DOM-probleem. En het gaat om iets technisch, dus Sandra mag nù afhaken.

Korte omschrijving

Ik wil een uitklapding dat een onbeperkt aantal keer kan voorkomen op een pagina, genested kan zijn, en gemakkelijk in het (manueel) html-coderen is.

Werking

Een “uitklapding”, dat is iets dat er zó uitziet:

Uitklapding1

Als ik op “Agenda van de vergadering” klik, of op dat vraagteken-icoontje, dan gebeurt er dit:

Uitklapding2

Dus: het icoontje verandert, en er verschijnt iets onder die eerste zin. Dat “iets” is in dit geval een lijst, maar dat kan om het even wat zijn: één of meer paragrafen, lijsten, tabellen…

Klikken op “Agenda van de vergadering” of op het groene vraagtekentje, doet de tekst weer verdwijnen.

Er moet meer dan één uitklapding op een pagina kunnen staan, bijvoorbeeld:

Uitklapding3

Als ik op één van die drie plusjes klik, of op de tekst die ernaast staat, dan moet daaronder iets uitklappen. Om het gemakkelijker te maken: het gaat hier niét om een toggle group, dus het kan zijn dat er twee of zelfs drie van die plusjes uitgeklapt zijn tegelijk. Voorbeeld:

Uitklapding4

…en hier is al meteen een laatste complexiteit aan bod gekomen: in zo’n uitgeklapt gedeelte van zo’n uitklapding, kunnen er nog andere uitklapdingen zitten. En dààrbinnen nog eens uitklapdingen.

Ik ga dat niet tot in het belachelijke doen, maar het zou wel kunnen dat er pakweg drie, maximum vier niveaus zijn.

HTML

De html gaat met de hand moeten aangemaakt worden, en mag dus niet complex zijn. In de titel van het uitklapding (dat stuk waarop geklikt kan worden), moet ook html-code mogelijk zijn. Het geheel moet (in uitgeklapte toestand, zonder dat die plusjes er minnetjes zichtbaar zijn of dat het in– en uitklappen zelf werkt) kunnen gepreviewed worden met een eenvoudige style sheet.

De html-code zelf ligt ook al vast:

<div class="toggle">
   <tag class="clicktoggle">
      Dit is de zin waarop kan geklikt worden.
   </tag>
   <tag class="hidden">
      Dit is wat er uitkomt als hierboven geklikt wordt.
   </tag>
</div>

Waar hierboven “tag” staat, kan een willekeurige html-tag staan, bijvoorbeeld:

<div class="toggle">
   <p class="clicktoggle">
      Dit is de zin waarop kan geklikt worden.
   </p>
   <ol class="hidden">
      <li>ten eerste</li>
      <li>ten tweede</li>
      <li>ten ten derde</li>
   </ol>
</div>

Of nog:

<div class="toggle">
   <p class="clicktoggle">
      Dit is de zin waarop kan geklikt worden.
   </p>
   <div class="hidden">
      <p>Kies een optie:</p>
      <div class="toggle">
         <p class="clicktoggle">Keuze één</p>
         <p class="hidden">Goed gekozen!</p>
      </div>
      <div class="toggle">
         <p class="clicktoggle">Keuze twee</p>
         <p class="hidden">Awoert!</p>
      </div>
      <p>...en ga dan verder.</p>
   </div>
</div>

De HTML ligt écht al vast, er kan niet meer aan veranderd worden. Als je klikt op een element met class “clicktoggle”, moet het eerstvolgende element met class “hidden” getoond worden. Of, als het al getoond wordt, verborgen worden. 

Voor het editeren, zuiver ter info, zou dat laatste er bijvoorbeeld zo uitzien:

Dit is de zin waarop kan geklikt worden.

Kies een optie:

Keuze één

Goed gekozen!

Keuze twee

Awoert!

…en ga dan verder.

(daar hoeft niemand zich verder iets van aan te trekken trouwens, van hoe dit er precies uit ziet)

DOM, en details

Zoals uit het tweede voorbeeld duidelijk is: op de hele pagina staan geen IDs bij al die klikdingen, en natuurlijk ook geen javascript of behaviours of watdanook. Al die dingen moeten er via DOM geplaatst worden, zodat de juiste klik het juiste ding de juiste actie laat ondernemen.

Ik geef wel een voorbeeld met een vraagteken, maar het zal in de praktijk enkel gaan om plus-tekens die min-tekens worden als ze uitgeklapt zijn, en weer plustekens als ze ingeklapt zijn.

Je kan daarbij gebruik maken van JQuery en/of YUI. Van die uitschuifbeweginkjes of andere fancy stuff hoeven niet: gewoon verschijnen en verdwijnen is goed. Het màg wel, als je je daartoe geroepen voelt.

De bedoeling is dat het werkt in FF, IE7, maar ook perfect in IE6.

Ik kan me inbeelden dat dit niet écht moeilijk is voor wie weet waar hij mee bezig is. Let wel! Ik ben niét op zoek naar pointers in de zin van “zou je niet eens proberen om dat zó of zó op te lossen”, of “volgens mij lijkt dit heel erg op X, Y of Z”. Ik zoek een oplossing die volledig kant-en-klaar is, een stuk code dat ik zó kan gebruiken.

Vergoeding

Zoals ik zei: ik heb er geen geld voor te geef. Maar wel mijn eeuwige dankbaarheid. En pinten als we mekaar zien. En als dat u een plezier doet: een banner op deze site.

Praktisch

Misschien best reageren hieronder, wie van plan is om er een gooi naar te doen. Dat er geen dubbel werk gebeurt.

Ik weet niet wat ik ervan moet verwachten, maar ik hoop er het beste van. Ik hoop dat ik er in de loop van deze week mensen een plezier mee kan doen.

(vingers gekruist)

9 reacties op “Help! Een DOM-probleem!”

  1. Onderstaande werkt met FF en IE6 dus waarschijnlijk ook met IE7.

    $(document).ready(function() {

    function hideOptions() {
    $('.hidden').hide();
    }

    function toggle(evt) {
    $(this).next('.hidden').toggle();
    }

    function addToggleListeners() {
    $('.clicktoggle').click(toggle);
    }

    hideOptions();
    addToggleListeners();

    });

  2. Het mijne is iets uitgebreider, mét support voor icoontjes (demo alhier). 😉


    var plusicon = "plus.gif";
    var minusicon = "minus.gif"

    $(document).ready(function() {
    // Hide all hidden blocks
    $(".hidden").hide();

    // wrap some html around the toggle text
    $(".toggle .clicktoggle").map(function() {
    $(this).html("<img src='" + plusicon + "' alt='vetzak' class='icon realtoggle' style='margin-right: 4px;'><a class='realtoggle' href='#'>" + jQuery.trim($(this).html()) + "</a>");
    });

    $(".toggle .clicktoggle A").css("text-decoration", "underline");

    $("p.clicktoggle .realtoggle").click(function(e) {
    // toggle visibility
    $(e.target).parent().parent().children(".hidden").toggle();

    // toggle the icon
    $(e.target).parent().children("IMG .realtoggle").map(function() {
    var src = $(this).get(0).src;
    $(this).get(0).src = src.indexOf(plusicon) >= 0 ? minusicon : plusicon;
    });

    e.preventDefault();
    });
    });

Reacties zijn gesloten.