Avatar billede googolplex Novice
07. januar 2004 - 23:23 Der er 31 kommentarer og
2 løsninger

Validering - del 1.

Jeg har en formular:

<form action="">
<input type="text" name="field1" style="color: red" />
</form>

Nu vil jeg gerne have lavet en validerings-system, der kan følgende:

1. Løbende validere det der tastes ind i feltet (med onchange() eller onkeyup() går jeg ud fra) og det øjeblik det valideres korrekt skal style="" ændres.

2. Validere mod flere ting på en gang.

Jeg have forestillet mig en at kalde en funktion ved onchange()/onkeyup(), der så kan tjekke 'field1' mod X antal forskellige regex's, men jeg er ikke sikker på hvordan jeg skal bygge systemet op.

Jeg ved ikke hvor svært dette spørgsmål er, men mine javascript færdigheder rækker i hvert fald ikke endnu. Jeg hæver pointene hvis løsningen viser sig at være avanceret :)

Valideringen er en mindre del af et større formular-system jeg er ved at lave, derfor 'del 1'.
Avatar billede roenving Novice
07. januar 2004 - 23:33 #1
Hvad er det for en type input ?-)

Tror du kender smart-input på datoen:

http://roenving.users.whitehat.dk/WD3Input.html
Avatar billede erikjacobsen Ekspert
07. januar 2004 - 23:35 #2
Sådan?

<SCRIPT LANGUAGE="JavaScript">
<!--
  function validate1(felt) {
    if (felt.value.match(/^\d?\d-\d?\d-\d\d\d\d$/)) {
      felt.style.color="blue";
    } else {
      felt.style.color="red";
    }
  }
//-->
</SCRIPT>

<form action="">
<input type="text" name="field1" style="color: red" onkeyup="validate1(this)" />
</form>
Avatar billede googolplex Novice
07. januar 2004 - 23:42 #3
Er ikke helt sikker på hvad du mener ?

Det er alle mulige typer input, emails, url, tlf#, der skal kunne tjekkes mod min/max lændgde osv.

Er det ikke smartest at lave en funktion alla:

function validate(regex, str)
{
    //osv.
}

Men jeg kan ikke hitte ud af hvordan jeg den, så den kan validere forskellige regex på en gang. Så jeg kan tjekke om det er en URL og om den er længere end 4 karakterer uden at skulle lave en ny regex.

Håber du forstår ?
Avatar billede googolplex Novice
07. januar 2004 - 23:43 #4
erik: Ovenstående var til roenving, men JO, det er i den stil. Jeg kan dog ikke komme videre når det drejer sig om flere regex på en gang.
Avatar billede skovenborg Nybegynder
07. januar 2004 - 23:45 #5
øhm, nu er jeg ikke så god til det med regular expressions, men var det mon noget i den her stil:
function valElm(elm)
  {
        var regexps = new Array();
        for (i=1;i<arguments.length;i++)
      {
          regexps[regexps.length] = new RegExp(arguments[i].substring(1,arguments[i].lastIndexOf("/")-1),arguments[i].substr(lastIndexOf("/")));
      }
      var valid = true;
      for (i=0;i<regexps.length;i++)
      {
          if (elm.value.match(regexps[i]));
          else valid = false;
      }
      if (valid) { elm.style.color = "blue";}
      else elm.style.color = "red";
  }

når du skal kalde den skal du skrive:
<input type="text" name="field1" style="color: red" onchange="valElm(this,'/^\d?\d-\d?\d-\d\d\d\d$/gi','/foo/i');">

eller hvad for en event du nu vil bruge (er ikke testet).
Avatar billede skovenborg Nybegynder
07. januar 2004 - 23:49 #6
okay der var i hvert fald mindst én fejl:
regexps[regexps.length] = new RegExp(arguments[i].substring(1,arguments[i].lastIndexOf("/")),arguments[i].substr(arguments[i].lastIndexOf("/")+1));
Avatar billede googolplex Novice
07. januar 2004 - 23:52 #7
skovenborg:

Jeg er kun nået til babystadiet mht. javascript, men kan jeg bare kalde funktionen med alle de argumenter (regexp) jeg har lyst til og checke med arguments.length ? (Kender PHP, der kan man jo noget lignende).

At det muligt at ændrer en hel style i stedet for kun color, eller er jeg nødt til at kalde ændrer en class hvis jeg skal ændrer mere end en ting ?
Avatar billede roenving Novice
07. januar 2004 - 23:52 #8
Tjah, det er jo egentlig en enormt smart metode, du efterlyser !o]

(tror der kunne tjenes mange $ på den !-)

Altså, du vil have en generel funktion, så du kan lave et simpelt kald, og så få checket, om input stemmer med reglerne undervejs, uanset hvilke regle, som gælder for det pågældende input ...

-- kunne forestille mig noget i stil med:

reg = new Array();

reg[0] = /^\d$/;
reg[1] = /^\w{4}$/;

function runningCheck(n,fld){
if(!fld.value.match(reg[n])){
  alert("Fejl i "+fld.name);
  fld.style.color="red";
}else{
  fld.style.color="blue";
}
}
Avatar billede googolplex Novice
07. januar 2004 - 23:52 #9
At det muligt at ændrer = Er det muligt at ændre
Avatar billede googolplex Novice
07. januar 2004 - 23:56 #10
Roenving: Ja lige præcis, kombineret med server-side bliver det helt genialt synes jeg selv... :)

Kan man smide de forskellige regex's direkte i funktionskaldet (tror det er der skovenborg vil hen) eller skal man definere dem først ?
Avatar billede skovenborg Nybegynder
07. januar 2004 - 23:59 #11
googolplex >> Hvis du bruger den funktion jeg har lavet skal du bare tilføje noget mere elm.style.etellerandet = "etellerandet" i funktionen (ikke særlig dynamisk godt nok).
fx:
if (valid) { elm.style.color = "blue";elm.style.backgroundColor = "#f0f"}
      else {elm.style.color = "red";elm.style.backgroundColor = "#fff";}

Men vil du have det sådan at man for hver funktion selv skal bestemme hvad der skal ske med feltet???

TIP: Du kan finde de mange styles på dette link:
http://www.w3.org/TR/2000/REC-DOM-Level-2-Style-20001113/Overview.html#contents

Godt nok lidt lettere forvirrende, men eller må du spørge.
Avatar billede roenving Novice
07. januar 2004 - 23:59 #12
Der er intet i vejen for at smide dem direkte i funktionskaldet (hrm, tror jeg, jeg har aldrig smidt den specielle streng-type i et funktionskald !-)

-- men jeg ville selv bruge database-ideen, for så kunne man jo bare henvise til den samlede mængde (og evt. genbruge den, når manden skulle angive både privat- og arb.-tlf.)
Avatar billede googolplex Novice
08. januar 2004 - 00:05 #13
Først Skovenborg: Jeg ville gerne have det sådan at jeg fx har:

<input type="text" name="field1" style="color: red; font-color: blue; font-size: 8px;" />

Og så med et kunne ændre det til

<input type="text" name="field1" style="color: yellow; font-color: green; font-size: 12px;" />

Altså ændre hele 'stylen' på en gang og ikke kun de enkelt properties.

Kan man eventuelt ændre:

<input type="text" name="field1" class="ikkegodkendt" />

Til:

<input type="text" name="field1" class="godkendt" />

Roenving: Jeg bygger det hele op i en PHP-klasse, jeg tror det passer bedre hvis jeg kan smide de forskellige regex direkte i funktionskaldet. Men kan din funktion tage flere regex's på en gang ?
Avatar billede roenving Novice
08. januar 2004 - 00:33 #14
Det er i hvert ikke de flere regexp's, som kan give problemer !-)

-- men lav _ikke_ classes om, for det har nogle helt andre implikationer, end du åbenbart tænker ...

Når browseren opbygger siden og bagefter renderer den, opbygger den et bibliotek over de forskellige elementers renderings-style, som er eksplicit på hvert enkelt element ...

Eksempel:

<h1>Overskrift<br>
Denne tekst er vigtig</h1>

Altså, den skriver i biblioteket, at det første tekst-element har style: display:block; font-size:x-large; osv. -- det gælder for "Overskrift"

Derefter skriver den et nyt entry for "Denne tekst er vigtig", som er: style: display:block; font-size:x-large;

-- da den gør det på et så basalt niveau, har den et problem, hvis du ændrer een style: Hvordan finder den ud af, om du f.eks. har nestede definitioner, som inkluderer H1 ?-)

-- Hvis den nu oprettede en crossreference-database med den slags oplysninger, kunne den selvfølgelig hurtig klare dette problem, men afhængig af din måde at opbygge nesting, kunne den ende med en database med tusindvis af tabeller, som refererede frem og tilbage, så den bruger en mere pragmatisk løsning:

-- Alt slettes, og vi starter forfra !-)

-- En billede, som svarer til det:

-- forestil dig, at fordi du afleverer een bog på biblioteket, så tager de alle bøgerne ned fra hylderne, og sætter dem tilbage efter de har lavet en sortering, som inkluderer bogen ...

-- for slet ikke at snakke om, at du afleverer flere bøger, for så skal de til at hive alle bøgerne ned flere gange !o]

Morale: Skift _aldrig_ en class, hvis der på nogen måde kan findes en anden rimelig brugbar løsning !-)
Avatar billede googolplex Novice
08. januar 2004 - 00:39 #15
roenving: Jeg skifter ingen classes så!

1. Men hvad så, kan jeg ændrer en hel style="" via javascript ?

2. Hvis jeg skal have en funktion der kan tage flere regex's skal jeg så bruge en løsning som Skovenborgs eller kan din funktion ombygges ?

3. Skal jeg bruge onchange(), onkeyup() eller hvad?

Går i seng nu, håber en vil hjælpe mig færdig, skal nok give point der passer til indsatsen :-)
Avatar billede roenving Novice
08. januar 2004 - 01:36 #16
1: Ja !-)
-- men det er mere hensigtsmæssigt kun at ændre de properties, du har brug for at ændre !-)

element.style="border:1px solid blue;color:lightgreen;";

-- jeg har ikke checket, om den reagerer css-agtigt (kun overskriver nævnte parametre !-) eller reagerer javascript-agtigt (overskriver alle properties ?-)

Ha, jeg skule da lige vide det, så sådan overskriver du alle properties:

.style.cssText='text-decoration:line-through;';" (testet i WebWriter4 !-)

2: Ja !-)

function runningCheck(n1,n2,fld){
if(!fld.value.match(reg[n1])&&!fld.value.match(reg[n2])){
  alert("Fejl i "+fld.name);
  fld.style.color="red";
}else{
  fld.style.color="blue";
}
}

3: Tjah ...
Kigger du på den input-maske, som jeg byggede sammen med en anden bruger herinde (linket !-), fandt vi frem til at det var bruger-uvenligt, at man ændrede i noget allerede indtastet, så det var en anelse mindre uvenligt bare ikke at skrive noget, som var forkert, men situationen kan være meget anderledes i forskellige situationer !-)

-- hvis folk skal indtaste et telefonnmmer, mener jeg, at det er bedst at bruge non-accept-metoden (linket), hvis de taster andet end tal, men ellers er erikjakobsens metode jo egentlig skide-smart: henled opmærsomheden på en ændring (som jeg jo også straks genbrugte !-)

-- og lige en præcisering af, hvornår events forekommer:
- onkeydown: Før tegnet når input-feltet, så det indeholdes ikke i value, en return false fjerner tegnet, og event.keyCode findes som oversat tastatur-kode (ascii-værdi e.l.) -- 'G' = 71
- onkeypress: Når tegnet er sat, value indeholder også tegnet, en return false kan fjerne tegnet (keyCode findes som tegn) -- 'G' = 'G';
- onkeyup: Efter tegnet er indsat, og keyCode findes som oversat tastatur-kode (ascii-værdi e.l.) -- 'G' = 71
- onchange: når feltet ikke mere har fokus, og der er forskel på, hvilken værdi, som var før og efter fokus, tegnet kan ikke findes, men værdien er den fulde felt-værdi ...

-- ovenstående er IE-typen, men lige der reagerer de andre browsere på samme måde !-)
Avatar billede googolplex Novice
08. januar 2004 - 18:20 #17
Jeg har tænkt lidt frem og tilbage og kommet frem til, at det er nemmest hvis jeg bare laver en funktion der kan validere en enkelt regex, det er jo de samme man bruger hele tiden (postnummer, email osv), så det skulle ikke være noget problem at lave dem alle.

Jeg tænkte på at lave funktionen således (en blanding af dit og erik's):

function validate(field, regex, style1, style2)
{
    if (field.value.match(regex))
    {
        field.style.cssText="style1";
    {
    else
    {
        field.style.cssText="style2";
    }
}

Og derefer:

<form action="">
<input type="text" name="field" onkeyup="validate(this)" />
</form

1. Er det korrekt?

2. Er det korrekt at benytte 'onkeyup' ? (Det har jeg stadigvæk ikke forstået, det skal være sådan, at når brugeren skriver i feltet, så tjekker den, men fjerner intet)
Avatar billede roenving Novice
08. januar 2004 - 18:29 #18
-- det ser korrekt ud det meste, men hvorfra kommer regex, style1 og style2 ?-)
Avatar billede googolplex Novice
08. januar 2004 - 18:32 #19
Det hele genereres af en PHP klasse, så jeg havde regnet med at benytte de samme regex's til både client -og serverside validering.

Php sætter det så op, så funktionen bliver kaldt med den korrekte regex, style1 og style2.

Lyder det fornuftigt ?

Er der ellers nogle fejl ?
Avatar billede roenving Novice
08. januar 2004 - 18:39 #20
Næh ...

-- men i små detaljer er der vist en anelse forskel på RegExps i php og javascript, så vær sikker på, at du får testet ordentligt !-)

-- onkeyup er helt fint !o]
Avatar billede googolplex Novice
08. januar 2004 - 20:21 #21
Men der skal selvfølgelig stå:

<form action="">
<input type="text" name="field" onkeyup="validate(this, regex, style1, style2)" />
</form

Var det det du mente ?

Smid et svar alle tre, så deler jeg point ud.

Jeg opretter et spørgsmål senere angående de regex jeg skal bruge :)
Avatar billede roenving Novice
08. januar 2004 - 20:38 #22
Velbekomme '-)
Avatar billede skovenborg Nybegynder
08. januar 2004 - 23:15 #23
helt i orden :-)
Avatar billede googolplex Novice
09. januar 2004 - 12:31 #24
erikjacobsen: Svar udbedes - jeg har jo bl.a. taget udgangspunkt i det du skrev :)
Avatar billede erikjacobsen Ekspert
09. januar 2004 - 17:10 #25
Nej, tak, jeg er holdt op med det point-pjat igen
Avatar billede googolplex Novice
09. januar 2004 - 17:48 #26
Ok, så deler jeg point ud til dem der stadig vil have det :)
Avatar billede roenving Novice
09. januar 2004 - 22:27 #27
-- tak for points ;~}
Avatar billede skovenborg Nybegynder
09. januar 2004 - 23:33 #28
--og held og lykke med din funktion - det ser jo spændende ud ;-)
Avatar billede avminarm Juniormester
30. august 2004 - 15:47 #29
googolplex>> har du haft held til at bikse noget fornuftigt sammen? - jeg har selv tænkt på at det du her er inde på er smart, men er ligesom du selv mere til PHP og knap så meget til javascript - jeg tænkte om man kunne komme til at se det du er kommet frem til? evt. på exp@avminmusearm.dk
Avatar billede googolplex Novice
30. august 2004 - 18:36 #30
Både ja og nej. Jeg mangler faktisk bare at sætte de sidste javascript funktioner ind i mit script, men pga. ekstremt tidspres i år, har jeg lagt projektet på is indtil juletid. Du kan godt se det jeg har, men om du kan hitte rundt i mit rod ved jeg ikke ;) Som du kan se planlægger jeg at omskrive det til PHP5, men det skulle ikke være det store problem:

<?php

/* To be rewritten

class PHP5Form
{
    private $Action;
    private $Enctype;
    private $Error;
    private $Errors;
    private $Method;
   
    public function __construct()
    {
    }
   
    public function __destruct()
    {
    }
   
    public function addInput()
    {
    }

}

*/

// The PHP class so far...

class Form
{
    var $mAction;
    var $mClientValidation;
    var $mCounter;
    var $mError;
    var $mErrors;
    var $mFieldNames;
    var $mFields;
    var $mForm;
    var $mFormAttributes;
    var $mFormIsSent;
    var $mIconPath;
    var $mJavaScriptFunctions;
    var $mMethod;
    var $mRules;
    var $mSubmitName;


/* Constructor */


    function Form($action = null, $method = null, $enctype = null, $attributes = null) // DONE
    {
        $this->mCounter = 1;
        $this->mError = false;
        $this->mErrors = array();
        $this->mFieldNames = array();
        $this->mFields = array();
        $this->mForm = '';
        $this->mFormAttributes = array();
        $this->mFormIsSent = false;
        $this->mIconPath = array();
        $this->mJavaScript = array();
        $this->mRules = array();
        $this->mSubmitName = '';

        if (isset($action))
        {
            $this->setAction($action);
        }
        else
        {
            $this->setAction($_SERVER['PHP_SELF']);
        }

        if (isset($method))
        {
            $this->setMethod($method);
        }
        else
        {
            $this->setMethod('post');
        }

        if (isset($enctype))
        {
            $this->setEnctype($enctype);
        }
        else
        {
            $this->setEnctype('application/x-www-form-urlencoded');
        }

        if (isset($attributes))
        {
            $this->setAttributes($attributes);
        }
        else
        {
            $this->setAttributes('');
        }

        $this->setClientValidation(true);
        $this->setIconPath('/graphics/yes.gif', '/graphics/no.gif');
    }


/* set methods */


    function setAction($action) // DONE
    {
        $this->mFormAttributes['action'] = $action;
    }


    function setAttributes($attributes) // DONE
    {
        $this->mFormAttributes['attributes'] = $attributes;
    }


    function setClientValidation($bool = true) // DONE
    {
        $this->mClientValidation = $bool;
    }


    function setEnctype($enctype) // DONE
    {
        $this->mFormAttributes['enctype'] = $enctype;
    }


    function setIconPath($yes, $no) // DONE
    {
        $this->mIconPath['yes'] = $yes;
        $this->mIconPath['no'] = $no;
    }


    function setMethod($method) // DONE
    {
        $this->mFormAttributes['method'] = $method;

        if ('get' == $method)
        {
            $this->mMethod = &$_GET;
        }
        else
        {
            $this->mMethod = &$_POST;
        }
    }


/* get methods */


    function getForm() // DONE
    {
        return $this->mForm;
    }


/* Method that adds a 'button' to the form */


    function AddButton($name, $value = 'Klik her', $attributes = '') // DONE
    {
        $this->mFields[$this->mCounter]['button']['name'] = $name;
        $this->mFields[$this->mCounter]['button']['value'] = $value;
        $this->mFields[$this->mCounter]['button']['attributes'] = $attributes;
        $this->mCounter++;
    }


/* Method that adds a 'checkbox' field to the form */


    function AddCheckbox($name, $value = 'on', $checked = false, $attributes = '') // DONE
    {
        $this->mFields[$this->mCounter]['checkbox']['name'] = $name;
        $this->mFields[$this->mCounter]['checkbox']['value'] = $value;
        $this->mFields[$this->mCounter]['checkbox']['checked'] = $checked;
        $this->mFields[$this->mCounter]['checkbox']['attributes'] = $attributes;
        $this->mCounter++;
    }


/* Method that adds an alternative 'reset' button to the form. This button 'empties' all fields */


    function AddClear($name = 'jjrclear', $value = 'Slet alt', $clearall = true, $attributes = '') // DONE
    {
        if (true === $clearall)
        {
            $javascript = "
function jjrTotalClearForm(form)
{
    form.reset();

    for(i=0;form.elements.length>i;i++)
    {
        switch(form.elements[i].type)
        {
            case 'checkbox':
            form.elements[i].checked = false;
            break;
            case 'radio':
            form.elements[i].checked = false;
            break;
            case 'password':
            form.elements[i].value = '';
            form.elements[i].focus();
            break;
            case 'select-one':
            form.elements[i].selectedIndex = 0;
            form.elements[i].focus();
            break;
            case 'select-multiple':
            form.elements[i].selectedIndex = 0;
            form.elements[i].focus();
            break;
            case 'text':
            form.elements[i].value = '';
            form.elements[i].focus();
            break;
            case 'textarea':
            form.elements[i].value = '';
            form.elements[i].focus();
        }
    }
}\n\n";

        $attributes .= ' onclick="jjrTotalClearForm(this.form); this.focus();"';
        }
        else
        {
            $javascript = "
function jjrClearForm(form)
{
    form.reset();

    for(i=0;form.elements.length>i;i++)
    {
        switch(form.elements[i].type)
        {
            case 'password':
            form.elements[i].value = '';
            form.elements[i].focus();
            break;
            case 'text':
            form.elements[i].value = '';
            form.elements[i].focus();
            break;
            case 'textarea':
            form.elements[i].value = '';
            form.elements[i].focus();
        }
    }
}\n\n";

        $attributes .= ' onclick="jjrClearForm(this.form); this.focus();"';
        }

        $this->mJavaScript .= $javascript;
        $this->AddButton($name, $value, $attributes);
    }


/* Method that adds a 'file' field to the form */


    function AddFile($name = 'upfile', $attributes = '') // DONE
    {
        $this->setEnctype('multipart/form-data');
        $this->mFields[$this->mCounter]['file']['name'] = $name;
        $this->mFields[$this->mCounter]['file']['attributes'] = $attributes;
        $this->mCounter++;
    }


/* Method that adds a 'hidden' field to the form */


    function AddHidden($name, $value) // DONE
    {
        $this->mFields[$this->mCounter]['hidden']['name'] = $name;
        $this->mFields[$this->mCounter]['hidden']['value'] = $value;
        $this->mCounter++;
    }


/* Method that adds (x)html to the form */


    function AddHtml($html) // DONE
    {
        $this->mFields[$this->mCounter]['html'] = $html;
        $this->mCounter++;
    }


/* Method that adds a 'password' field to the form */


    function AddPassword($name, $value = true, $attributes = '', $errortext = null, $confirmation = true, $inbetweenHtml = '') // IN PROGRESS
    {
        if (!isset($errortext))
        {
            $errortext = "Feltet '$name' er ikke udfyldt korrekt!";
            $errortext_confirmation = "Feltet '$name' (bekræftigelse) er ikke udfyldt korrekt!";
        }
        else
        {
            $errortext_confirmation = $errortext;
        }

        $this->mFieldNames[] = $name;
        $this->mFields[$this->mCounter]['password']['name'] = $name;
        $this->mFields[$this->mCounter]['password']['value'] = $value;
        $this->mFields[$this->mCounter]['password']['attributes'] = $attributes;
        $this->mFields[$this->mCounter]['password']['errortext'] = $errortext;
        $this->mFields[$this->mCounter]['password']['confirmation'] = $confirmation;

        if (true === $confirmation)
        {
            $this->mFields[$this->mCounter]['password']['html'] = $inbetweenHtml;
            $this->mFields[$this->mCounter]['confirmation']['name'] = $name . '_confirmation';
            $this->mFields[$this->mCounter]['confirmation']['errortext'] = $errortext_confirmation;
        }

        $this->mCounter++;
    }


/* Method that adds a 'radio' field to the form */


    function AddRadio($name, $value, $checked = false, $attributes = '') // DONE
    {
        $this->mFields[$this->mCounter]['radio']['name'] = $name;
        $this->mFields[$this->mCounter]['radio']['value'] = $value;
        $this->mFields[$this->mCounter]['radio']['checked'] = $checked;
        $this->mFields[$this->mCounter]['radio']['attributes'] = $attributes;
        $this->mCounter++;
    }


/* Method that adds a 'reset' button to the form */


    function AddReset($name = 'jjrreset', $value = 'Nulstil', $attributes = '') // DONE
    {
            $javascript = "
function jjrResetForm(form)
{
    form.reset();

    for(i=0;form.elements.length>i;i++)
    {
        switch(form.elements[i].type)
        {
            case 'password':
            form.elements[i].focus();
            break;
            case 'text':
            form.elements[i].focus();
            break;
            case 'textarea':
            form.elements[i].focus();
        }
    }
}\n\n";

        $this->mJavaScript .= $javascript;
        $attributes .= ' onclick="jjrResetForm(this.form); this.focus();"';
        $this->AddButton($name, $value, $attributes);
    }


/* Method that adds a rule (PERL /regex/) to the form */


    function AddRule($fieldname, $regex) // DONE
    {
        $this->mRules[$fieldname] = $regex;
    }


/* Method that adds a 'select' to the form */


    function AddSelect($name, $options = array(), $selected = null, $required = true, $attributes = '', $errortext = null) // DONE
    {
        if (!isset($selected))
        {
            $selected = 'jjrvaelg';
        }

        if (!isset($errortext))
        {
            $errortext = "Du skal vælge et emne fra rullemenuen '$name'!";
        }

        $array = array('jjrvaelg' => '- - vælg - -');
        $options = array_merge($array, $options);

        $this->mFieldNames[] = $name;
        $this->mFields[$this->mCounter]['select']['name'] = $name;
        $this->mFields[$this->mCounter]['select']['options'] = $options;
        $this->mFields[$this->mCounter]['select']['selected'] = $selected;
        $this->mFields[$this->mCounter]['select']['attributes'] = $attributes;
        $this->mFields[$this->mCounter]['select']['required'] = $required;
        $this->mFields[$this->mCounter]['select']['errortext'] = $errortext;
        $this->mCounter++;
    }


/* Method that adds a 'submit' button to the form */


    function AddSubmit($name = 'submit', $value = 'Send', $attributes = '') // DONE
    {
        $this->mSubmitName = $name;
        $this->mFields[$this->mCounter]['submit']['name'] = $name;
        $this->mFields[$this->mCounter]['submit']['value'] = $value;
        $this->mFields[$this->mCounter]['submit']['attributes'] = $attributes;
        $this->mCounter++;
    }


/* Method that adds a 'text' field to the form */


    function AddText($name, $value = '', $maxlength = 255, $attributes = '', $errortext = null) // DONE
    {
        if (!isset($errortext))
        {
            $errortext = "Feltet '$name' er ikke udfyldt korrekt!";
        }

        $this->mFieldNames[] = $name;
        $this->mFields[$this->mCounter]['text']['name'] = $name;
        $this->mFields[$this->mCounter]['text']['value'] = $value;
        $this->mFields[$this->mCounter]['text']['maxlength'] = $maxlength;
        $this->mFields[$this->mCounter]['text']['attributes'] = $attributes;
        $this->mFields[$this->mCounter]['text']['errortext'] = $errortext;
        $this->mCounter++;
    }


/* Method that adds a 'textarea' to the form */


    function AddTextarea($name, $value = '', $columns = 25, $rows = 5, $attributes = '', $errortext = null) // DONE
    {
        if (!isset($errortext))
        {
            $errortext = 'Feltet \47' . $name . '\47 er ikke udfyldt korrekt!';
        }
        else
        {
            $errortext = str_replace("'", '\47', $errortext);
        }

        $this->mFieldNames[] = $name;
        $this->mFields[$this->mCounter]['textarea']['name'] = $name;
        $this->mFields[$this->mCounter]['textarea']['value'] = $value;
        $this->mFields[$this->mCounter]['textarea']['columns'] = $columns;
        $this->mFields[$this->mCounter]['textarea']['rows'] = $rows;
        $this->mFields[$this->mCounter]['textarea']['attributes'] = $attributes;
        $this->mFields[$this->mCounter]['textarea']['errortext'] = $errortext;
        $this->mCounter++;
    }


/* Method that builds a 'button', using an array set by the method AddButton */


    function BuildButton($counter) // DONE
    {
        $button = '<input type="button" name="' . $this->mFields[$counter]['button']['name'] . '" value="' . $this->mFields[$counter]['button']['value'] . '" ' . $this->mFields[$counter]['button']['attributes'] . ' />';
        $this->mForm .= $button . "\n";
    }


/* Method that builds a 'checkbox' field, using an array set by the method AddCheckbox */


    function BuildCheckbox($counter) // DONE
    {
        $checkbox = '<input type="checkbox" name="' . $this->mFields[$counter]['checkbox']['name'] . '" value="' . $this->mFields[$counter]['checkbox']['value'] . '" ' . $this->mFields[$counter]['checkbox']['attributes'];

        if (isset($this->mMethod[$this->mFields[$counter]['checkbox']['name']]) || ((false === $this->mFormIsSent) && (true === $this->mFields[$counter]['checkbox']['checked'])))
        {
            $checkbox .= ' checked="checked"';
        }

        $checkbox .= ' />';
        $this->mForm .= $checkbox . "\n";
    }


/* Method that builds a 'file' field, using an array set by the method AddFile */


    function BuildFile($counter) // DONE
    {
        $file = '<input type="file" name="' . $this->mFields[$counter]['file']['name'] . '" ' . $this->mFields[$counter]['file']['attributes'] . ' />';
        $this->mForm .= $file . "\n";
    }


/* Method that builds a 'hidden' field, using an array set by the method AddHidden */


    function BuildHidden($counter) // DONE
    {
        $hidden = '<input type="hidden" name="' . $this->mFields[$counter]['hidden']['name'] . '" value="' . $this->mFields[$counter]['hidden']['value'] . '" />';
        $this->mForm .= $hidden . "\n";
    }


/* Method that builds a 'password'|'confirmation' field, using an array set by the method AddPassword */


    function BuildPassword($counter) // DONE
    {
        /* Checking if the password(s) validate correctly */

        if ((isset($this->mMethod[$this->mFields[$counter]['password']['name']]) && isset($this->mMethod[$this->mFields[$counter]['confirmation']['name']]) && $this->mMethod[$this->mFields[$counter]['password']['name']] != $this->mMethod[$this->mFields[$counter]['confirmation']['name']]) || (isset($this->mRules[$this->mFields[$counter]['password']['name']]) && !preg_match($this->mRules[$this->mFields[$counter]['password']['name']], $this->mMethod[$this->mFields[$counter]['password']['name']])) || (isset($this->mRules[$this->mFields[$counter]['password']['name']]) && !preg_match($this->mRules[$this->mFields[$counter]['password']['name']], $this->mMethod[$this->mFields[$counter]['confirmation']['name']])))
        {
            $passwords_validated = false;
            $this->mError = true;
            $this->mErrors[] = $this->mFields[$counter]['password']['errortext'];
            $this->mErrors[] = $this->mFields[$counter]['confirmation']['errortext'];
        }
        else
        {
            $passwords_validated = true;
        }

        /* Checking if the value for 'password' should be displayed */

        if (isset($this->mMethod[$this->mFields[$counter]['password']['name']]) && (true === $this->mFields[$counter]['password']['value']))
        {
            $value = $this->mMethod[$this->mFields[$counter]['password']['name']];
        }
        else
        {
            $value = '';
        }

        $password = '<input type="password" name="' . $this->mFields[$counter]['password']['name'] . '" value="' . $value . '" />';

        /* Setting the correct icon (yes/no) for 'password' */

        if (true === $passwords_validated)
        {
            $password .= '<img src="' . $this->mIconPath['yes'] . '" title="Feltet er korrekt udfyldt!" id="iconid' . $counter . '" />';
        }
        else
        {
            $password .= '<img src="' . $this->mIconPath['no'] . '" title="' . $this->mFields[$counter]['password']['errortext'] . '" id="iconid' . $counter . '" />';
        }

        /* Checking if the confirmation password has been activated */

        if (true === $this->mFields[$counter]['password']['confirmation'])
        {
            $password .= $this->mFields[$counter]['password']['html'] . "\n";

            /* Checking if the value for 'confirmation' should be displayed */

            if (isset($this->mMethod[$this->mFields[$counter]['confirmation']['name']]) && (true === $this->mFields[$counter]['password']['value']))
            {
                $value = $this->mMethod[$this->mFields[$counter]['confirmation']['name']];
            }
            else
            {
                $value = '';
            }

            $password .= '<input type="password" name="' . $this->mFields[$counter]['confirmation']['name'] . '" value="' . $value . '" />';

            /* Setting the correct icon (yes/no) for 'confirmation' */

            if (true === $passwords_validated)
            {
                $password .= '<img src="' . $this->mIconPath['yes'] . '" title="" id="iconid' . ($counter + 1) . '" />';
            }
            else
            {
                $password .= '<img src="' . $this->mIconPath['no'] . '" title="' . $this->mFields[$counter]['password']['errortext'] . '" id="iconid' . ($counter + 1) . '" />';
            }
        }

        $this->mForm .= $password . "\n";
    }


/* Method that builds a 'radio' field, using an array set by the method AddRadio */


    function BuildRadio($counter) // DONE
    {
        $radio = '<input type="radio" name="' . $this->mFields[$counter]['radio']['name'] . '" value="' . $this->mFields[$counter]['radio']['value'] . '" ' . $this->mFields[$counter]['radio']['attributes'];

        if ((isset($this->mMethod[$this->mFields[$counter]['radio']['name']]) && ($this->mMethod[$this->mFields[$counter]['radio']['name']] == $this->mFields[$counter]['radio']['value'])) || ((false === $this->mFormIsSent) && (true === $this->mFields[$counter]['radio']['checked'])))
        {
            $radio .= ' checked="checked"';
        }

        $radio .= ' />';
        $this->mForm .= $radio . "\n";
    }

/* Method that builds a 'reset' button, using an array set by the method AddReset */

    function BuildReset($counter) // DONE
    {
        $reset = '<input type="reset" name="' . $this->mFields[$counter]['reset']['name'] . '" value="' . $this->mFields[$counter]['reset']['value'] . '" ' . $this->mFields[$counter]['reset']['attributes'] . ' />';
        $this->mForm .= $reset . "\n";
    }


/* Method that builds a 'select', using an array set by the method AddSelect */


    function BuildSelect($counter) // DONE
    {
        $select = '<select name="' . $this->mFields[$counter]['select']['name'] . '" ' . $this->mFields[$counter]['select']['attributes'];

        if (true === $this->mClientValidation && true === $this->mFields[$counter]['select']['required'])
        {
            $select .= ' onchange="jjrValidateSelect(this, ' . "'iconid$counter', '" . str_replace("'", '\47', $this->mFields[$counter]['select']['errortext']) . "')\"";
        }

        $select .= ' >' . "\n";

        foreach ($this->mFields[$counter]['select']['options'] as $key => $value)
        {
            $select .= '<option value="' . $key . '"';

            if ((isset($this->mMethod[$this->mFields[$counter]['select']['name']]) && $this->mMethod[$this->mFields[$counter]['select']['name']] == $key) || (!isset($this->mMethod[$this->mFields[$counter]['select']['name']]) && $this->mFields[$counter]['select']['selected'] == $key))
            {
                $select .= ' selected="selected"';
            }

            $select .= ' >' . $value . '</option>' . "\n";
        }

        $select .= '</select>';

        if(true === $this->mFields[$counter]['select']['required'] && (!isset($this->mMethod[$this->mFields[$counter]['select']['name']]) || (isset($this->mMethod[$this->mFields[$counter]['select']['name']]) && 'jjrvaelg' == $this->mMethod[$this->mFields[$counter]['select']['name']]) || !array_key_exists($this->mMethod[$this->mFields[$counter]['select']['name']], $this->mFields[$counter]['select']['options'])))
        {
            $this->mError = true;
            $this->mErrors[] = $this->mFields[$counter]['select']['errortext'];
            $select .= '<img src="' . $this->mIconPath['no'] . '" title="Vælg venligst et emne fra rullemenuen" id="iconid' . $counter . '" />' . "\n";
        }
        else
        {
            $select .= '<img src="' . $this->mIconPath['yes'] . '" title="Feltet er korrekt udfyldt!" id="iconid' . $counter . '" />' . "\n";
        }

        $this->mForm .= $select . "\n";
    }


/* Method that builds a 'submit' button, using an array set by the method AddSubmit */


    function BuildSubmit($counter) // DONE
    {
        $submit = '<input type="submit" name="' . $this->mFields[$counter]['submit']['name'] . '" value="' . $this->mFields[$counter]['submit']['value'] . '" ';

        if (true === $this->mClientValidation && true === $this->mError)
        {
            $submit .= 'disabled="disabled" ';
        }

        $submit .= $this->mFields[$counter]['submit']['attributes'] . ' />';
        $this->mForm .= $submit . "\n";
    }


/* Method that builds a 'text' field, using an array set by the method AddText */


    function BuildText($counter) // DONE
    {
        if (isset($this->mMethod[$this->mFields[$counter]['text']['name']]))
        {
            $value = $this->mMethod[$this->mFields[$counter]['text']['name']];
        }
        else
        {
            $value = $this->mFields[$counter]['text']['value'];
        }

        $text = '<input type="text" name="' . $this->mFields[$counter]['text']['name'] . '" value="' . $value . '" maxlength="' . $this->mFields[$counter]['text']['maxlength'] . '" ' . $this->mFields[$counter]['text']['attributes'];

        if (true === $this->mClientValidation && isset($this->mRules[$this->mFields[$counter]['text']['name']]))
        {
            $text .= ' autocomplete="off"';
            $text .= ' onfocus="jjrValidate(this, ' . $this->mRules[$this->mFields[$counter]['text']['name']] . ", 'iconid$counter', '" . str_replace("'", '\47', $this->mFields[$counter]['text']['errortext']) . "')\"";
            $text .= ' onkeyup="jjrValidate(this, ' . $this->mRules[$this->mFields[$counter]['text']['name']] . ", 'iconid$counter', '" . str_replace("'", '\47', $this->mFields[$counter]['text']['errortext']) . "')\"";
        }

        $text .= ' />';

        if (isset($this->mRules[$this->mFields[$counter]['text']['name']]) && !preg_match($this->mRules[$this->mFields[$counter]['text']['name']], $value))
        {
            $this->mError = true;
            $this->mErrors[] = $this->mFields[$counter]['text']['errortext'];
            $text .= '<img src="' . $this->mIconPath['no'] . '" title="' . $this->mFields[$counter]['text']['errortext'] . '" id="iconid' . $counter . '" />';
        }
        else
        {
            $text .= '<img src="' . $this->mIconPath['yes'] . '" title="Feltet er korrekt udfyldt!" id="iconid' . $counter . '" />';
        }

        $this->mForm .= $text . "\n";
        }


/* Method that builds a 'textarea', using an array set by the method AddTextarea */


    function BuildTextarea($counter) // DONE
    {
        if (isset($this->mMethod[$this->mFields[$counter]['textarea']['name']]))
        {
            $value = $this->mMethod[$this->mFields[$counter]['textarea']['name']];
        }
        else
        {
            $value = $this->mFields[$counter]['textarea']['value'];
        }

        $textarea = '<textarea name="' . $this->mFields[$counter]['textarea']['name'] . '" cols="' . $this->mFields[$counter]['textarea']['columns'] . '" rows="' . $this->mFields[$counter]['textarea']['rows'] . '" ' . $this->mFields[$counter]['textarea']['attributes'];

        if (true === $this->mClientValidation && isset($this->mRules[$this->mFields[$counter]['textarea']['name']]))
        {
            $text .= ' onfocus="jjrValidate(this, ' . $this->mRules[$this->mFields[$counter]['textarea']['name']] . ", 'iconid$counter', '" . str_replace("'", '\47', $this->mFields[$counter]['textarea']['errortext']) . "')\"";
            $text .= ' onkeyup="jjrValidate(this, ' . $this->mRules[$this->mFields[$counter]['textarea']['name']] . ", 'iconid$counter', '" . str_replace("'", '\47', $this->mFields[$counter]['textarea']['errortext']) . "')\"";
        }

        $textarea .= ' >' . $value . '</textarea>';

        if (isset($this->mRules[$this->mFields[$counter]['textarea']['name']]) && !preg_match($this->mRules[$this->mFields[$counter]['textarea']['name']], $value))
        {
            $this->mError = true;
            $this->mErrors[] = $this->mFields[$counter]['textarea']['errortext'];
            $textarea .= '<img src="' . $this->mIconPath['no'] . '" title="' . $this->mFields[$counter]['textarea']['errortext'] . '" id="iconid' . $counter . '" />';
        }
        else
        {
            $textarea .= '<img src="' . $this->mIconPath['yes'] . '" title="Feltet er korrekt udfyldt!" id="iconid' . $counter . '" />';
        }

        $this->mForm .= $textarea . "\n";
    }


/* Method that builds the entire form */


    function BuildForm() // DONE
    {
        /* Checking if the form has been submittet */

        if (isset($this->mMethod['jjrsubmitcheck']) && ('issubmittet' == $this->mMethod['jjrsubmitcheck']))
        {
            $this->mFormIsSent = true;
        }

        $this->mForm .= '<form action"' . $this->mFormAttributes['action'] . '" method="' . $this->mFormAttributes['method'] . '" enctype="' . $this->mFormAttributes['enctype'] . '" ' . $this->mFormAttributes['attributes'] . ' >' . "\n" . '<input type="hidden" name="jjrsubmitcheck" value="issubmittet" />' . "\n";

        /* $key contains the value of the counter, $value contains an array used in another foreach() */

        foreach ($this->mFields as $key => $value)
        {
            foreach ($value as $key2 => $value2)
            {
                switch($key2)
                {
                    case 'button':
                        $this->BuildButton($key);
                        break;
                    case 'checkbox':
                        $this->BuildCheckbox($key);
                        break;
                    case 'file':
                        $this->BuildFile($key);
                        break;
                    case 'hidden':
                        $this->BuildHidden($key);
                        break;
                    case 'html':
                        $this->mForm .= $this->mFields[$key]['html'];
                        break;
                    case 'password':
                        $this->BuildPassword($key);
                        break;
                    case 'password2':
                        $this->BuildPassword2($key);
                        break;
                    case 'radio':
                        $this->BuildRadio($key);
                        break;
                    case 'reset':
                        $this->BuildReset($key);
                        break;
                    case 'select':
                        $this->BuildSelect($key);
                        break;
                    case 'submit':
                        $this->BuildSubmit($key);
                        break;
                    case 'text':
                        $this->BuildText($key);
                        break;
                    case 'textarea':
                        $this->BuildTextarea($key);
                        break;
                    case 'default':
                        break;
                }
            }
        }

        $this->mForm .= '</form>' . "\n";

        $javascript = '<script type="text/javascript">';
       
        $this->mJavaScriptFunctions = array_unique($this->mJavaScriptFunctions);

        foreach ($this->mJavaScriptFunctions as $value)
        {
            switch ($value)
            {
                case 'checksubmit':

$javascript .= 'var fields = {';
$string = '';
                   
if (true === $this->mError)
{
    foreach ($this->mFieldNames as $value)
    {
        $string .= "'$value':false,";
    }
}
else
{
    foreach ($this->mFieldNames as $value)
    {
        $string .= "'$value':true,";
    }
}

$string = substr($string, 0, (strlen($string)-1));
$javascript .= $string . '};' . "\n";
$javascript .='
function jjrCheckSubmit(field)
{
    var ok = true;

    for(i in fields)
    {
        ok = ok && fields[i];
    }

    field.form.' . $this->mSubmitName . '.disabled = !ok;
}';

                    break;
                case 'clearform':

$javascript .= '
function jjrClearForm(form)
{
    form.reset();

    for(i=0;form.elements.length>i;i++)
    {
        switch(form.elements[i].type)
        {
            case 'password':
            form.elements[i].value = '';
            form.elements[i].focus();
            break;
            case 'text':
            form.elements[i].value = '';
            form.elements[i].focus();
            break;
            case 'textarea':
            form.elements[i].value = '';
            form.elements[i].focus();
        }
    }
}';

                    break;
                case 'clearformii':
                    break;
                case 'focusall':
                    break;
                case 'resetform':
                    break;
                case 'validate':
                    break;
                case 'validateselect':
                    break;
                case 'default':
                    break;
            }


        if (true === $this->mClientValidation)
        {
            $this->mJavaScript .= 'var fields = {';

            $string = '';

            if (true === $this->mError)
            {
                foreach ($this->mFieldNames as $value)
                {
                    $string .= "'$value':false,";
                }
            }
            else
            {
                foreach ($this->mFieldNames as $value)
                {
                    $string .= "'$value':true,";
                }
            }

            $string = substr($string, 0, (strlen($string)-1));
            $this->mJavaScript .= $string . '};' . "\n";
            $this->mJavaScript .= '


function jjrValidate(field, regex, id, errortext)
{
    if (field.value.match(regex))
    {
        document.getElementById(id).src="' . $this->mIconPath['yes'] . '";
        document.getElementById(id).title="Feltet er korrekt udfyldt!";
        fields[field.name] = true;
    }
    else
    {
        document.getElementById(id).src="' . $this->mIconPath['no'] . '";
        document.getElementById(id).title=errortext;
        fields[field.name] = false;
    }

    jjrCheckSubmit(field);
}

function jjrGiveAllFocus(form)
{
    for(i=0;form.elements.length>i;i++)
    {
        switch(form.elements[i].type)
        {
            case 'password':
            form.elements[i].focus();
            break;
            case 'select-one':
            form.elements[i].focus();
            break;
            case 'select-multiple':
            form.elements[i].focus();
            break;
            case 'text':
            form.elements[i].focus();
            break;
            case 'textarea':
            form.elements[i].focus();
        }
    }
}

function jjrValidateSelect(select, id, errortext)
{
    if(select.selectedIndex!=0)
    {
        document.getElementById(id).src="' . $this->mIconPath['yes'] . '";
        document.getElementById(id).title="Feltet er korrekt udfyldt!";
        fields[select.name] = true;
    }
    else
    {
        document.getElementById(id).src="' . $this->mIconPath['no'] . '";
        document.getElementById(id).title=errortext;
        fields[select.name] = false;
    }

    jjrCheckSubmit(select);
}' . "\n\n";
        }

        /* Checking if any JavaScript functions should be added to the form */

        if ('' != $this->mJavaScript)
        {
            $this->mForm = '<script type="text/javascript">' . "\n<!--\n\n" . $this->mJavaScript . "//-->\n</script>\n\n" . $this->mForm;
        }
    }


/* Method that builds the form and returns the validation status */


    function Build() // DONE
    {
        $this->BuildForm();
        return $this->mError;
    }


/* Method that displays all errors */


    function DisplayErrors() // DONE
    {
        foreach ($this->mErrors as $value)
        {
            echo $value . '<br />';
        }
    }


/* Method that displays the form */


    function Display() // DONE
    {
        echo $this->mForm;
    }
}






function jjrClearForm(form)
{
    form.reset();

    for(i=0;form.elements.length>i;i++)
    {
        switch(form.elements[i].type)
        {
            case 'password':
            form.elements[i].value = '';
            form.elements[i].focus();
            break;
            case 'text':
            form.elements[i].value = '';
            form.elements[i].focus();
            break;
            case 'textarea':
            form.elements[i].value = '';
            form.elements[i].focus();
        }
    }
}


function jjrTotalClearForm(form)
{
    form.reset();

    for(i=0;form.elements.length>i;i++)
    {
        switch(form.elements[i].type)
        {
            case 'checkbox':
            form.elements[i].checked = false;
            break;
            case 'radio':
            form.elements[i].checked = false;
            break;
            case 'password':
            form.elements[i].value = '';
            form.elements[i].focus();
            break;
            case 'select-one':
            form.elements[i].selectedIndex = 0;
            form.elements[i].focus();
            break;
            case 'select-multiple':
            form.elements[i].selectedIndex = 0;
            form.elements[i].focus();
            break;
            case 'text':
            form.elements[i].value = '';
            form.elements[i].focus();
            break;
            case 'textarea':
            form.elements[i].value = '';
            form.elements[i].focus();
        }
    }
}


function jjrResetForm(form)
{
    form.reset();

    for(i=0;form.elements.length>i;i++)
    {
        switch(form.elements[i].type)
        {
            case 'password':
            form.elements[i].focus();
            break;
            case 'text':
            form.elements[i].focus();
            break;
            case 'textarea':
            form.elements[i].focus();
        }
    }
}


function jjrCheckSubmit(field)
{
    var ok = true;

    for(i in fields)
    {
        ok = ok && fields[i];
    }

    field.form.' . $this->mSubmitName . '.disabled = !ok;
}


function jjrValidateSelect(select, id, errortext)
{
    if(select.selectedIndex!=0)
    {
        document.getElementById(id).src="' . $this->mIconPath['yes'] . '";
        document.getElementById(id).title="Feltet er korrekt udfyldt!";
        fields[select.name] = true;
    }
    else
    {
        document.getElementById(id).src="' . $this->mIconPath['no'] . '";
        document.getElementById(id).title=errortext;
        fields[select.name] = false;
    }

    jjrCheckSubmit(select);
}


function jjrValidate(field, regex, id, errortext)
{
    if (field.value.match(regex))
    {
        document.getElementById(id).src="' . $this->mIconPath['yes'] . '";
        document.getElementById(id).title="Feltet er korrekt udfyldt!";
        fields[field.name] = true;
    }
    else
    {
        document.getElementById(id).src="' . $this->mIconPath['no'] . '";
        document.getElementById(id).title=errortext;
        fields[field.name] = false;
    }

    jjrCheckSubmit(field);
}


function jjrFocusAll(form)
{
    for(i=0;form.elements.length>i;i++)
    {
        switch(form.elements[i].type)
        {
            case 'password':
            form.elements[i].focus();
            break;
            case 'select-one':
            form.elements[i].focus();
            break;
            case 'select-multiple':
            form.elements[i].focus();
            break;
            case 'text':
            form.elements[i].focus();
            break;
            case 'textarea':
            form.elements[i].focus();
        }
    }
}


?>
Avatar billede avminarm Juniormester
31. august 2004 - 09:14 #31
hold da op sikke en smøre :-) - jeg vil kigge nærmere på det, men du må da gerne holde mig ajour hvis du putter mere (det sidste) på scriptet/klassen - især hvis du lavet et eksemple script på hvordan du har tænkt dig det skal bruges :o), men foreløbig lurer jeg selv lidt på det! tak
Avatar billede googolplex Novice
31. august 2004 - 09:18 #32
Jeg ligger det her når det er færdigt, det er simpelt at bruge.
Avatar billede avminarm Juniormester
31. august 2004 - 09:31 #33
lyder godt ;o)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Vi tilbyder markedets bedste kurser inden for webudvikling

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester