Autor Zpráva
Camo
Profil
Zdravím vás,
Urobil som po dlhšom čase nejakú validáciu formuláru, ktorá normálne funguje všade okrem IE.
Mohol by mi prosím vás niekto povedať prečo mi IE hlási chybu na riadku 55(var validate = {})?

A ešte by som uvítal nejaké typy na refaktoring toho kódu, ak by sa niekomu chcelo sa na to pozrieť.
<?php

$name = '';
$email = '';
$age = '';
$colors = array();

$errs = array();
/*
if(isset($_POST['name']))
{
    $name = validate_regexp($_POST['name'], $errs, 'name', '/^[a-z]+$/i');
    $email = validate_regexp($_POST['email'], $errs, 'email', '/^[a-zA-Z0-9_.+-]+@([a-zA-Z0-9-]+\.)+[a-zA-Z0-9]+$/');
    $age = validate_regexp($_POST['age'], $errs, 'age', '/^\d+$/');
    $colors = validate_select($_POST, $errs, 'colors');
}*/

?>
<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <style>
    div{padding-left:20px; border:1px solid red}
    .error
    {
        color:red;
        display:none;
    }
    .on
    {
        display:block;
    }
    </style>
</head>
<body>

<form action="" method="post" id="formId">

    <label for="nameId"><b>meno:</b></label><br>
    <input type="text" name="name" id="nameId" value="<?php echo $name ?>"><br>
    <span class="error <?php if(in_array('name', $errs)) echo 'on' ?>" id="nameIdError">V mene máte chybu. Opravte si ju prosím!</span>
    <br><br>
    
    <label for="emailId"><b>email:</b></label><br>
    <input type="text" name="email" id="emailId" value="<?php echo $email ?>"><br>
    <span class="error <?php if(in_array('email', $errs)) echo 'on' ?>" id="emailIdError">V emaily máte chybu. Opravte si ho prosím!</span>
    <br><br>
    
    <label for="ageId"><b>vek:</b></label><br>
    <input type="text" name="age" id="ageId" value="<?php echo $age ?>"><br>
    <span class="error <?php if(in_array('age', $errs)) echo 'on' ?>" id="ageIdError">Vo veku máte chybu. Opravte si ho prosím!</span>
    <br><br>
    
    <label for="colorsId"><b>vaša obľúbená farba:</b></label><br>
    <select name="colors[]" id="colorsId" multiple="multiple" size="5">
        <option value="red" <?php if(in_array('red', $colors)) echo 'on' ?>>red</option>
        <option value="green" <?php if(in_array('green', $colors)) echo 'on' ?>>green</option>
        <option value="blue" <?php if(in_array('blue', $colors)) echo 'on' ?>>blue</option>
        <option value="pink" <?php if(in_array('pink', $colors)) echo 'on' ?>>pink</option>
        <option value="yellow" <?php if(in_array('yellow', $colors)) echo 'on' ?>>yellow</option>
        <option value="white" <?php if(in_array('white', $colors)) echo 'on' ?>>white</option>
        <option value="black" <?php if(in_array('black', $colors)) echo 'on' ?>>black</option>
        <option value="brown" <?php if(in_array('brown', $colors)) echo 'on' ?>>brown</option>
    </select>
    <span class="error <?php if(in_array('colors', $errs)) echo 'on' ?>" id="colorsIdError">Musíte vybrať aspoň jednu farbu. Opravte si prosím chybu!</span>
    <br><br><br>
<?php
echo time();
?>
    
    <input type="submit" name="sbtm">
</form>
</body>
<script type"text/javascript">
var validate = {
    
    valid : true,
    formEl : document.getElementById('formId'),
    nameIdPat : /[a-zA-Z]+/,
    emailIdPat : /^[a-zA-Z0-9\.\-_]+@([a-zA-Z0-9\-_]+\.)+[a-z]/,
    ageIdPat : /^\d+$/,

    name : document.getElementById('nameId'),
    email : document.getElementById('emailId'),
    age : document.getElementById('ageId'),
    errors : document.getElementsByClassName('error'),
    

    init : function()
    {
        //alert('init');
        validate.addEvent(validate.formEl, 'submit', validate.sbmt);
        validate.addEvent(validate.name, 'change', validate.change);
        validate.addEvent(validate.email, 'change', validate.change);
        validate.addEvent(validate.age, 'change', validate.change);
    },
    
    sbmt : function(e)
    {

        validate.valid = true;
        
        e = validate.getEvent(e);
                        
        for(i=0; i<validate.errors.length; i++)
        {
            validate.errors[i].setAttribute('class','error');
        }
            alert('sbmt');        
        
        validate.val_regexp(validate.name, validate.nameIdPat);
        validate.val_regexp(validate.email, validate.emailIdPat);
        validate.val_regexp(validate.age, validate.ageIdPat);
                        
        if(!validate.valid)
        {
            validate.preventDefault(e);            
        }
    },
    
    change : function(e)
    {
        var target = validate.getTarget(e);
        var errSpan = document.getElementById(target.id+'Error');
        errSpan.setAttribute('class', 'error');
        validate.val_regexp(target, validate[target.id+'Pat']);        
    },

    val_regexp : function(el, patern)
    {
        if(!el.value.match(patern))
        {
            span = document.getElementById(el.id+'Error');
            span.setAttribute("class", " error on");
            validate.valid = false;
        }
        else
        {
            validate.valid = validate.valid ? true : false;        
        }        
    },
        

////////event handlers//////////////////////////////////////////////////////////

    getEvent : function(e)
    {
        //alert('getEvent');
        return e ? e : window.event;    
    },
    
    preventDefault : function(e)
    {
        if(e.preventDefault)
        {
            e.preventDefault();
        }
        else
        {
            e.returnValue = false;
        }
    },
    
    addEvent : function(el, event, handler)
    {
        //alert('addEvent');
        if(el.addEventListener)
        {
             el.addEventListener(event, handler, false);
        }        
        else
        {
            el.attachEvent('on'+event, handler);
        }
    },
    
    getTarget : function(e)
    {
        return e.target ? e.target : e.srcElement;
    }
    
}

validate.init();
</script>
</html>
<?php


//////////////php functions////////////////////////////////////

function validate_regexp($val, &$errs, $key, $patern)
{
    if(!preg_match($patern, $val))
    {
        $errs[] = $key;        
    }
    return $val;
}

function validate_select($val, &$errs, $key)
{
    if(!isset($val['colors']))
    {
        $errs[] = $key;
        return array();
    }
    else
    {
        return $val[$key];
    }
}

?>
Chamurappi
Profil
Reaguji na Cama:
Mohol by mi prosím vás niekto povedať prečo mi IE hlási chybu na riadku 55?
Takže si máme číslo řádku odpočítat po odečtení těch PHP kousků? To zní jako skvělá zábava.

document.getElementsByClassName
Neexistuje ve starších Explorerech.

errSpan.setAttribute('class', 'error');
Nefunguje minimálně ve starších Explorerech, používej standardní vlastnosti DOMu.

change : function(e)
Ve starších Explorerech nebude naplněný argument, validate.getTarget selže. U sbmt voláš sjednocení s window.event, tady ne.
Pokud ti to nějak nefunguje ani v novějších Explorerech, dodej prosím odkaz na živou ukázku.

validate.preventDefault(e);
Stačí return false. Ve všech prohlížečích, odjakživa.

for(i=0; i<validate.errors.length; i++)
Chybí var.

validate.valid = validate.valid ? true : false;
Nesmírně užitečné.

Přemýšlím, co by měl prohlížeč dělat s <option value="red" on>, asi by bylo lepší dát tam selected.

V zakomentovaném PHP máš jiné reguláry než v JS, u jména nedovoluješ nepísmenka a u e-mailu hlídáš konec. Bylo by také uživatelsky příjemné všude tolerovat mezery z obou stran zadávaného vstupu.

Metodu getTarget bys nepotřeboval, kdybys u větve s el.attachEvent pojistil, že v this bude el (ve větvi s addEventListenerem je), pak bys mohl používat normálně this. Já bych na tvém místě použil normální el.onchange = něco, nekomplikoval bych si to s addEventListenery.
Camo
Profil
Chamurappi:
Díky moc. Už to funguje aj v IE.

Tie riadky predsa v prehliadači neobsahujú php.

"document.getElementsByClassName"
Díky. Nakoniec som zistil, že to vôbec nepotrebujem(dokážem idčko spanu odvodiť z id input.id).

"errSpan.setAttribute('class', 'error');"
Díky, zmenil som.

"change : function(e)"
Díky.

"validate.preventDefault(e);"
Nechal som.

"for(i=0; i<validate.errors.length; i++)"
Díky.

"validate.valid = validate.valid ? true : false;"
... (to bolo zámerne :))

<option value="red" on>
To som nepochopil.

Reguláry sú len akože.

"Metodu getTarget bys nepotřeboval, kdybys u větve s el.attachEvent pojistil, že v this bude el"
To ako urobím ak chcem použiť attachEvent? eventListener používam, lebo umožňuje na jednu udalosť naviazať viac handlerov. Pri onchange to síce moc nehrozí, ale čo keby náhodou...? Alebo sa mýlim?
Chamurappi
Profil
Reaguji na Cama:
Tie riadky predsa v prehliadači neobsahujú php.
Přesně tak, a proto informace, že k chybě dochází na řádku 55, nebyla moc nápomocná, když zde jsou očíslované řádky včetně PHP kódu. Toho, že jsi později upřesnil řádek, jsem si nevšiml.

To som nepochopil.
Na řádcích 57 až 64 vypisuješ on dovnitř <option>ů. Označené možnosti by měly mít atribut selected, ne on.

To ako urobím ak chcem použiť attachEvent?
el.attachEvent('on' + event, function(e)
{
  handler.call(el, e || window.event);
});
Máš tam rovnou ošetřený i ten globální window.event.

Pri onchange to síce moc nehrozí, ale čo keby náhodou...?
Takových náhod, kdy se ti celý mechanismus rozbije, jde vymyslet víc. Je otázka, jak moc máš věci pod kontrolou. Já nepoužívám listenery nikde a na kolize nenarážím u elementů vůbec, protože drtivá většina elementů je dost jednoúčelová.
A když na kolizi narazím, také jde snadno vyřešit:
    addEvent: function(obj, onevent, handler)
    {
        var original = obj[onevent];
        obj[onevent] = function()
        {
            if(original) original.apply(this, arguments);
            return handler.apply(this, arguments);
        }
    }
… jako bonus se případně můžu rozhodnout, v jakém pořadí je spustím a co udělám s návratovou hodnotou té dřívější funkce.
Camo
Profil
Chamurappi:
Klobúk dole! Je to brutal.
Ale napadá ma jedna vec pri tom: Niezneužívaš tak trochu tie anonymné funkcie(neviem len sa pýtam)? Aký by to malo vplyv napr. V súčinnosti s nejakými animáciami?

Vaše odpověď

Mohlo by se hodit

Neumíte-li správně určit příčinu chyby, vkládejte odkazy na živé ukázky.
Užíváte-li nějakou cizí knihovnu, ukažte odpovídajícím, kde jste ji vzali.

Užitečné odkazy:

Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0