Oppgave 1, 2 & 3

Lag et skjema for å opprette en bruker på en nettside som inneholder materiale som kun er egnet for et voksent publikum. Skjemaet skal bestå av felter for ønsket brukernavn, passord, passordbekreftelse, alderskontroll og en registrer knapp. Når man trykker knappen skal programmet sjekke om man har fylt ut feltene, at passordet i passordfeltene er like og at brukeren er minst 18 år gammel. Om ett eller begge feltene ikke inneholder noe skal du gi brukeren beskjed om hvilke felter som ikke er fylt ut. Om brukeren ikke har skrevet inn passordet likt i feltene skal du gi en beskjed om dette. Om brukeren er under 18 år skal du gi en passende tilbakemelding ang dette. Om feltene er korrekt fylt ut skal du takke brukeren for registreringen.

Resultat

Hei! :)

Du kan registrere deg i skjema under. Etter du har registrert deg, vil du kunne logge inn!

Merk: Brukernavnet ditt må være unikt. Alle passord blir kryptert.

Koden

JavaScript

                
window.onload = ready;

function ready() {
    var regForm = document.getElementById("o1-form-register");
    var logForm = document.getElementById("o1-form-login");

    // Kjør submit function når bruker prøver å submite skjema
    document.getElementById("o1-submit").onclick = function() {
        submit(regForm);
    };
    document.getElementById("o1-login").onclick = function() {
        submit(logForm);
    };

    regForm.addEventListener("submit", function(e) {
        e.preventDefault(); // Stop skjema fra å sende data
    });

    logForm.addEventListener("submit", function(e) {
        e.preventDefault();
    });
}

function submit(form) {
    document.getElementById("o1-submit").disabled = true;

    var errorOutput = document.getElementById("o1-error-msg");
    var formStatus = validate(form); // Kjør validate på skjema og lagre det funksjonen retunerer

    if (formStatus === true) { // Hvis alt gikk som det skulle
        showMessage("", "string");
        sendData(form);
    } else { // Noe gikk galt, vis feilmelding
        document.getElementById("o1-submit").disabled = false;
        var error = formStatus;

        // Påkrevde felter er ikke fylt ut
        if (error.requiredFields.length > 0) {
            error = error.requiredFields;

            errorOutput = "Vennligst fyll ut de påkrevde feltene.";
            for (var i = 0; i < error.length; i++) {
                errorOutput += "<br>";
                errorOutput += "<b>" + error[i] + "</b>";
            }

            showMessage(errorOutput, "string");
        } else if (error.matchingFields.length > 0) { // Felter som skal matche er ikke like
            error = error.matchingFields;

            errorOutput = "Feltene matched ikke!";
            for (var i = 0; i < error.length; i++) {
                errorOutput += "<br>";
                errorOutput += "<b>" + error[i] + "</b>";
            }

            showMessage(errorOutput, "string");
        } else if (error.minLengthFields.length > 0) { // Felter som ikke er lange nok
            error = error.minLengthFields;


            errorOutput = "Feltene oppfyller ikke krav";
            for (var i = 0; i < error.length; i++) {
                errorOutput += "<br>";
                errorOutput += "<b>" + error[i] + "</b>";
            }

            showMessage(errorOutput, "string");
        } else if (error.minFields.length > 0) { // Felter som ikke er over minimum verdi
            error = error.minFields;

            errorOutput = "Feltene oppfyller ikke krav";
            for (var i = 0; i < error.length; i++) {
                errorOutput += "<br>";
                errorOutput += "<b>" + error[i] + "</b>";
            }

            showMessage(errorOutput, "string");
        }
    }
}

// Validerer skjema felter
// Param: form er et form element
function validate(form) {
    var inputs = form.getElementsByTagName("input");
    var errors = {};             // Samle errors i et object
    var errorCheck = false;      // bolean man kan skjekke for å se om det har blitt registrert noen errors, eller ikke
    errors.requiredFields = [];  // påkrevde felter som ikke ble fylt ut
    errors.matchingFields = [];  // felter som skal match et annet felt, ment ikke matcher
    errors.minFields = [];       // felter som ikke er større enn sin minimum verdi
    errors.minLengthFields = []; // felter som ikke er lengere enn sin minimum lengde

    function markField(field) {
        field.style.backgroundColor = "#FF5254"; // Rød
        field.style.color = "#8d0002";           // Mørk rød

        // Når bruker skriver noe i feltet, fjern markering
        field.addEventListener("keypress", function() {
            unmarkField(this);
            this.removeEventListener("keypress", arguments.callee); // Slett eventListeneren
        });
    }

    function unmarkField(field) {
        field.style.backgroundColor = "";
        field.style.color = "";
    }

    // For hvert input felt i skjema
    for (var i = 0; i < inputs.length; i++) {
        unmarkField(inputs[i]); // Fjern markering på felt

        // Sjekk at påkrevde felter ikke er tomme
        if (inputs[i].hasAttribute("required") && inputs[i].value.length === 0) {
            errorCheck = true;

            errors.requiredFields[errors.requiredFields.length] = inputs[i].getAttribute("placeholder"); // Legg til feltet i array

            markField(inputs[i]); // Marker feltet
        } else if (inputs[i].hasAttribute("data-match")) { // Sjekk om felter som skal matche er like
            // Kunne brukt 'dataset.match' her, men SELVFØGELIG funker det ikke i tidligere
            // Internet Explorer versjoner. IE 11 og opp faktisk..... microsoft pls :(
            var match = document.getElementById(inputs[i].getAttribute("data-match"));

            if (inputs[i].value !== match.value) {
                errorCheck = true;

                errors.matchingFields[errors.matchingFields.length] = match.getAttribute("placeholder");
                errors.matchingFields[errors.matchingFields.length] = inputs[i].getAttribute("placeholder");

                markField(match);
                markField(inputs[i]);
            }
        } else if (inputs[i].hasAttribute("length-min")) { // Sjekk om feltene er lange nok
            if (inputs[i].value.length < inputs[i].getAttribute("length-min")) {
                errorCheck = true;

                errors.minLengthFields[errors.minLengthFields.length] = inputs[i].getAttribute("placeholder") + " (Må være lengere enn " + inputs[i].getAttribute("length-min") + ")";

                markField(inputs[i]);
            }
        } else if (inputs[i].hasAttribute("data-min")) { // Sjekk om felter er over minimum verdi
            if (parseInt(inputs[i].value) < inputs[i].getAttribute("data-min")) {
                errorCheck = true;

                errors.minFields[errors.minFields.length] = inputs[i].getAttribute("placeholder") + " (Minst " + inputs[i].getAttribute("data-min") + ")";

                markField(inputs[i]);
            }
        }
    }

    // Hvis noen error har blir registrert
    if (errorCheck) {
        return errors;
    } else { // Alt gikk fint, return true
        return true;
    }
}

// Sender skjema data
// Param: form er et form element.
function sendData(form) {
    var xhr = new XMLHttpRequest();
    var data  = new FormData(form);

    // Status endret, om ajax requestet er ferdig, return svar
    xhr.addEventListener("readystatechange", function() {
        if (xhr.readyState == XMLHttpRequest.DONE) {
            document.getElementById("o1-submit").disabled = false;

            showMessage(this.responseText, "json"); // Vis svar fra server

            if ("error" in JSON.parse(this.responseText)) {
                document.getElementById("o1-username").focus(); // Sett markør i username feltet
            } else {
                document.getElementById("o1-form-register").style.display = "none"; // Skjul registrer knapp
                document.getElementById("o1-form-login").style.display = "block"; // og vis login

                // Tøm skjema
                var inputs = form.getElementsByTagName("input");
                for (var i = 0; i < inputs.length; i++) {
                    inputs[i].value = "";
                }
            }
        }
    });

    // Noe gikk feil :/
    xhr.addEventListener("error", function() {
        showMessage(this.responseText, "string");
        document.getElementById("o1-submit").disabled = false;
    });

    // Åpne request, hent metode og action fra skjema
    xhr.open(form.getAttribute("method"), form.getAttribute("action"));

    // Send data skrevet inn i skjema
    xhr.send(data);
}

function showMessage(msg, type) {
    var msgOutput = document.getElementById("o1-error-msg");

    if (type == "string") {
        msgOutput.innerHTML = msg;
    } else if (type == "json") {
        msg = JSON.parse(msg);
        var tmpMsg = "<b>Følgende data ble mottatt:</b><br>";

        // Loop gjennom object
        for (var key in msg) {
            if (msg.hasOwnProperty(key) && msg[key] !== null) { // Fjern meta info og tomme properties
                tmpMsg += "<b>" + key + "</b>: " + msg[key] + "<br>";
           }
        }

        msg = tmpMsg;
        msgOutput.innerHTML = msg;
    }
}
                
            

PHP

En god del av PHP koden har blitt sensurert av sikkerhetsmessige årsaker.

Submit.php - Håndteer bruker registrasjon

                
<?php
    **SENSURERT**

    if ($_POST == NULL) {
        die("Ingen data ble motatt, noe gikk galt.");
    }

    function encryptData($data) {
        return **SENSURERT**
    }

    $data = $_POST;

    // Escape post data
    foreach($data as $name => $value) {
        $data[$name] = htmlspecialchars($value);
    }

    $conn = new PDO(**SENSURERT**);
    $sth = $conn->prepare('
        **SENSURERT**
    ');

    $sth->bindParam(':username', $data['username'], PDO::PARAM_STR);
    $sth->execute();
    $result = $sth->fetchColumn();
    $sth = null;

    if ($result === false) {
        if (isset($data['password'])) {
            if (isset($data['password-repeat'])) {
                if ($data['password'] !== $data['password-repeat']) {
                    die('Passordene matcher ikke');
                }
            }

            $data['password'] = encryptData($data['password']);
        }

        // Open connection
        $conn = new PDO(**SENSURERT**);

        $sth = $conn->prepare('
            **SENSURERT**
        ');

        $sth->bindParam(':username', $data['username'], PDO::PARAM_STR);
        $sth->bindParam(':password', $data['password'], PDO::PARAM_STR);
        $sth->bindParam(':age', $data['age'], PDO::PARAM_INT);
        $sth->bindParam(':name_display', $data['username'], PDO::PARAM_STR);
        $sth->execute();
        $sth = null;

        // Close connection
        $conn = null;

        echo(json_encode($data));
    } else {
        $error = new stdClass;

        $error->error = "Dessverre så er '" . $data['username'] . "' er allerede tatt. Du må velge et annet brukernavn.";
        echo(json_encode($error));
    }
                
            

Login.php - Håndteer login

                
<?php
    **SENSURERT**

    if ($_POST == NULL) {
        die("Ingen data ble motatt, noe gikk galt.");
    }

    function showError($msg) {
        $error = new stdClass;
        $error->error = $msg;
        echo(json_encode($error));
    }

    $data = $_POST;

    // Escape post data
    foreach($data as $name => $value) {
        $data[$name] = htmlspecialchars($value);
    }

    $conn = new PDO(SENSURERT);

    $sth = $conn->prepare('
        **SENSURERT**
    ');
    $sth->bindParam(':username', $data["username"], PDO::PARAM_STR);
    $sth->execute();
    $result = $sth->fetch(PDO::FETCH_ASSOC);
    $sth = null;
    
    if (**SENSURERT**) {
        $sth = $conn->prepare('
            **SENSURERT**
        ');

        $sth->bindParam(':username', $data["username"], PDO::PARAM_STR);
        $sth->execute();
        $result = $sth->fetch(PDO::FETCH_ASSOC);
        $sth = null;

        if ($result === false) {
            showError("Noe gikk galt :/");
        } else {
            echo(json_encode($result));
        }
    } else if ($result === false) {
        showError("Brukeren finnes ikke");
    } else {
        showError("Feil passord :/");
    }

    $conn = null;

                
            

HTML

                
<form id="o1-form-register" action="submit.php" method="POST">
    <div class="row input-field">
        <label for="o1-username" class="col s1"><i class="icon-user-2"></i></label>
        <input type="text" id="o1-username" class="col s11" name="username" placeholder="Brukernavn" required>
    </div>
    <div class="row input-field">
        <label for="o1-password" class="col s1"><i class="icon-lock-2"></i></label>
        <input type="password" id="o1-password" class="col s11" name="password" placeholder="Passord" required>
    </div>
    <div class="row input-field">
        <label for="o1-password-repeat" class="col s1"><i class="icon-lock-2"></i></label>
        <input type="password" id="o1-password-repeat" class="col s11" name="password-repeat" placeholder="Passord igjen" required data-match="o1-password">
    </div>
    <div class="row input-field">
        <label for="o1-age" class="col s1"><i class="icon-cake-2"></i></label>
        <input type="number" id="o1-age" class="col s11" name="age" placeholder="Hvor gammel er du?" required data-min="18">
    </div>
    <div class="row input-field">
        <button id="o1-submit" type="submit" class="btn black">Registrer</button>
    </div>
</form>
<form id="o1-form-login" action="login.php" method="POST">
    <div class="row input-field">
        <label for="o1-username" class="col s1"><i class="icon-user-2"></i></label>
        <input type="text" id="o1-username" class="col s11" name="username" placeholder="Brukernavn" required>
    </div>
    <div class="row input-field">
        <label for="o1-password" class="col s1"><i class="icon-lock-2"></i></label>
        <input type="password" id="o1-password" class="col s11" name="password" placeholder="Passord" required>
    </div>
    <div class="row input-field">
        <button id="o1-login" type="submit" class="btn black">Login</button>
    </div>
</form>