Keresés
Hírlevél
 
Kiemelt témák
»10 éves a prog.hu
»Párhuzamos programozás
»Párhuzamos végrehajtás == szemléletváltás!
Állás/munka
»Tanárt keresek
»Port.hu film tartalmának kinyerése
»PHP programozó kerestetik
»Fejlesztői megbízásokat/munkát keresek
»Senior .Net fejlesztő szabad kapacitással
» több téma
Tudástár
? torrent file helyett txt-t
?PHP:keresés szó szerint...
*PHP if-nél megakadtam
Mobilinternet használata robotokban
?Delphi Form méretezési probléma
?HelpProvider alkalmazás .HLP fájlban
2 oldalas form
SetFocus hatástalan
?XP-n megy Win7-en megakad (Delphi)
?Hiányos mp3 hallgatás telefonról! C#
A legalsó scrollTop értéket nem veszi figyelembe
3 dív pozicionálása (2 egymás mellé, 1 ezek alá)
?Curl login Joomla-ba (PHP)
*Java Axis webservice file küldés és fogadás
?C# scrollozható form
» több téma
Társalgó
»Az általános műveltség része kellene, hogy legyen a programozni tudás?
»Get flood elleni védekezés
»Újra programozni fog a Facebook alapítója és multimilliárdos elnöke
»Firebird - Több adatbázis vagy egy?
»Clipper kontra XP
»Webshop ár kb...
»Hogy működik egy apróhirdető oldal (MySQL)?
»Körlevél script PHP + MySQL
»New project probléma VS 2010 C#
»Kezdőknek:grafikus felület választás
» több téma
ASPC#C++CSSDelphiFlashJavaJavaScriptPascalPerlPHPPythonuniPaaSVisual BasicVisual C++  »    

Tudástár

»

2x bind jQuery probléma.

»

2x bind jQuery probléma.

nyitotta: gabordx, idő: 2012.02.06., moderátor: moderator, megoldás elfogadva: 2012.02.07. 00:12
  Értesítés változás esetén Felvétel kedvencekhez Küldés emailben Nyomtatható verzió

Kategóriák:Programozási nyelvek » JavaScript

Sorrend:
Időzóna:
Blokkméret:
Oszd meg másokkal is!
Hali!
function setFieldOk(jArray,inputName,submitName,ok)
        {
            if ( ok )
                eval("jArray." + inputName + "=true");
            else
                eval("jArray." + inputName + "=false");

            $.each(jArray,function(i,j){
                alert(i+j);
            })
}

function passwordInputsManage(jArray,inputName,submitName)
        {
            var $currElement = $('#'+inputName);
            switch( $('#'+inputName).get(0).tagName )
            {
                case 'SELECT':
                    var test = 0;
                    var binding = 'change'
                    break;
                default:
                    var binding = 'textchange'
                    var test = '';
            }
            $currElement.bind(binding,function(){
                var bool = $(this).val() != test ? true : false;
                setFieldOk(jArray, inputName, submitName, bool);
            })
            setFieldOk(jArray, inputName, submitName, ( $(this).val != test ? true : false ));
        }

        var pfields1 = {
            passuname1: false,
            passuquestion: false,
            passuanswer: false
        };

        passwordInputsManage(pfields1, 'passuname1', 'remindque');
        passwordInputsManage(pfields1, 'passuquestion', 'remindque');
        passwordInputsManage(pfields1, 'passuanswer', 'remindque');

Az problémám, hogy 2x bindelődik az inputok textchange eseményére a bennük található függvény. De miért?? :SSSS Nem értem, ha valaki tudja, hogy mit rontok el akkor pls. árulja már el. Köszi.
Szerintem a bemásolt kódrészlet semmiben sem utal arra, hogy egy elemhez egynél többször bindolódna egy handler. Mindazonáltal vannak még ha működő is, de csúnya részek.
Pl. a setFieldOk első négy sora helyett ez sokkal szebb (szerintem):
jArray[inputName] = ok;

A $.each -nek átadott függvény két paramétere a tömbindex és a tömbérték lesz. Ez esetben a tömb, amin végiglépked a pfields1. Itt az, hogy összeadod a kulcsot az értékkel (stringet bool-al), az nem tudom, mit eredményez, de nem hiszem, hogy pont erre van szükséged.

A hibát szerintem ne (csak) ebben a kódrészletben keresd. Lehet, hogy ez a js kétszer van behúzva, vagy egy függvényben van, ami kétszer fut le, stb. előzmény
Nem tudtam, hogy lehet így hivatkozni json indexre köszi. Az az alert csak debug akar lenni és kiírja azokat i-t, j-t. előzmény
Úgy néz ki, hogy nem jól van megírva a textchange event (bővítmény). Írtam egy jóval butábbat és csak 1x futtatja le a kérdéses függvényt. előzmény
Nem mégsem. előzmény
Nem lehet, hogy az a probléma, hogy kétszer hívod meg egymás után a setFieldOk-ot? (ugye egyszer a bind-ben, egyszer meg a bindelésnél)

Ahogy nézem:

setFieldOk(jArray, inputName, submitName, ( $(this).val != test ? true : false ));
Itt ez pl hibás, mert a $(this) az a window object (ha jól sejtem)...

Tákoltam egy kicsit a kódon, hogy valami formája legyen:

function setResult(inputValidationMap, inputName, submitName, notEmpty) {
    inputValidationMap[inputName] = notEmpty;
    $.each(inputValidationMap,function (i,j) {
        alert(i+j);
    })
}

function validate(inputValidationMap, inputName, submitName) {
    var currElement = $('#'+inputName);
    var isSelectInput = (currElement.get(0).tagName == "SELECT");
    var emptyValue;
    var changeEvent;
    if(isSelectInput) {
        emptyValue = 0;
        changeEvent = 'change'
    } else {
        changeEvent = 'textchange'
        emptyValue = '';
    }
    var changeHandler = function() {
        var notEmpty = ($(this).val() != emptyValue);
        setResult(inputValidationMap, inputName, submitName, notEmpty);
    };
    currElement.bind(changeEvent, changeHandler);
    changeHandler.call(currElement);
}

var inputValidationMap = {
    passuname1: false,
    passuquestion: false,
    passuanswer: false
};

$.each(inputValidationMap, function (name) {
    validate(inputValidationMap, name, 'remindque');
});
előzmény
Tovább tákoltam rajta:

var FieldSetValidator = function () {
    this.validMap = {};
};
$.extend(FieldSetValidator.prototype, {
    setFieldSet: function (fieldSet) {
        this.fieldSet = fieldSet;
    },
    validate: function () {
        var validator = this;
        this.fieldSet.each(function (inputName, field){
            var changeObserver = function () {
                validator.validateInput(inputName, field);
            };
            field.bindChange(changeObserver);
            changeObserver();
        });
    },
    validateInput: function (inputName, field) {
        this.validMap[inputName] = field.isValid();
        alert(inputName+field.isValid());
    }
});

var FieldSet = function (inputNames) {
    this.inputMap = {};
    if (inputNames)
        this.addAll(inputNames);
};
$.extend(FieldSet.prototype, {
    addAll: function (inputNames) {
        $.each(inputNames, function (index, inputName) {
            this.add(inputName);
        });
    },
    add: function (inputName) {
        this.inputMap[inputName] = new Field(inputName);
    },
    each: function (callBack){
        $.each(this.inputMap, callBack);
    }
});

var Field = function (inputName) {
    this.inputName = inputName;
    this.inputElement = $("#"+inputName);
};
$.extend(Field.prototye, {
    bindChange: function (callBack) {
        this.inputElement.bind(this.getChangeEvent(), callBack);
    },
    getChangeEvent: function () {
        return (this.isSelectInput() ? "change" : "textchange");
    },
    isValid: function () {
        return (!this.isEmpty());
    },
    isEmpty: function () {
        var value = this.inputElement.val();
        var emptyValue = (this.isSelectInput() ? 0 : "");
        return (value === emptyValue);
    },
    isSelectInput: function () {
        return (this.inputElement.get(0).tagName == "SELECT");
    }
});

var validator=new FieldSetValidator();
validator.setFieldSet(new FieldSet(["passuname1","passuquestion","passuanswer"]));
validator.validate();

A change event csak egyszer kell, hogy lefusson, hacsak az inputElement.val() nem hibás... előzmény
Na ilyenkor megy el az ember kedve a programozástól.

Ír egy elég normális kódot, amiben van egy apró hiba, de nem blődség az egész, és segítséget kér. Erre jön valaki, aki úgy gondolja, hogy sz.r az egész, átírja. Átnevezi a változókat is, mert neki az nem szimpatikus. Aztán úgy gondolja, hogy még fényezi magát, így ír egy egész keretrendszert, és a pofájába dörgöli, hogy nesze, ennyire hulladék, amit te csináltál.

Mellesleg megjegyzem, az ilyenek miatt van az, hogy quadcore proci kell már egy hello word-höz is, mert az emberek elfelejtettek egyszerű kódot írni, tőccsünk le egy fél vindózt azért, hogy megtudjuk, szerencsétlen input mező ki van-e töltve.
Ennyiről beszélünk eredetileg:
if (document.getElementById('passuname1').val != '')

Ha dicsekedni akarsz, lehet, de próbáld meg ne úgy tenni, hogy másba belerúgsz. előzmény
Ez nagyon jó! Csak egy kérdés:
...
setFieldSet: function (fieldSet) {
       this.fieldSet = fieldSet;
    },
...
this.fieldSet az létrejön ilyenkor? (mert csak validMap-ot látok) (Tudom, hogy ki lehetne próbálnom de szeretném először maximálisan érteni.) előzmény
Meg egy másik kérdés: Minek extend? Nem származtattál többfelé így lehetne egyből sajátja amit az extend hoz. előzmény
Utána jártam mindennek, kicsit kiegészítettem meg néhol javítottam, de nagyon jól működik köszönöm!
Ez lett a vége:
var FieldSetValidator = function () {
        this.validMap = {};
    };
    $.extend(FieldSetValidator.prototype, {
        setFieldSet: function (fieldSet) {
            this.fieldSet = fieldSet;
        },
        setSubmitName: function ( name ){
            this.submitName = name;
        },
        validate: function () {
            var validator = this;
            this.fieldSet.each(function (inputName, field){
                var changeObserver = function(){
                    validator.validateInput(inputName, field);
                    validator.enableSubmit();
                }   
                field.bindChange(changeObserver);
                changeObserver();
            });
            this.enableSubmit();
        },
        validateInput: function (inputName, field) {
            this.validMap[inputName] = field.isValid();
        },
        enableSubmit: function() {
            var dataok = true;
            $.each(this.validMap,function(i,j){
                if ( !j )
                {
                    dataok = false;
                    return false;
                }
            })
            setDisableSubmit(this.submitName, !dataok);
        }
    });

    var FieldSet = function (inputNames) {
        this.inputMap = {};
        if (inputNames)
            this.addAll(inputNames);
    };
    $.extend(FieldSet.prototype, {
        addAll: function (inputNames) {
            var self = this;
            $.each(inputNames, function (index, inputName) {
                self.add(inputName);
            });
        },
        add: function (inputName) {
            this.inputMap[inputName] = new Field(inputName);
        },
        each: function (callBack){
            $.each(this.inputMap, callBack);
        }
    });

    var Field = function (inputName) {
        this.inputName = inputName;
        this.inputElement = $("#"+inputName);
    };
    $.extend(Field.prototype, {
        bindChange: function (callBack) {
            this.inputElement.bind(this.getChangeEvent(), callBack);
        },
        getChangeEvent: function () {
            return (this.isSelectInput() ? "change" : "textchange");
        },
        isValid: function () {
            return (!this.isEmpty());
        },
        isEmpty: function () {
            var value = this.inputElement.val();
            var emptyValue = (this.isSelectInput() ? 0 : "");
            return (value == emptyValue);
        },
        isSelectInput: function () {
            return (this.inputElement.get(0).tagName == "SELECT");
        }
    });

    var validator=new FieldSetValidator();
    validator.setFieldSet(new FieldSet(["passuname1","passuquestion","passuanswer"]));
    validator.setSubmitName('remindque');
    validator.validate();
előzmény
Nézz utána java collections framework-nek, abban van néhány alap gyűjtemény, amiket érdemes használni, vagy kiterjeszteni. Sajnos javascript oo szempontjából nem a legkedvezőbb...

Úgy nagyjából amiket érdemes ismerni:

List - A javascript tömbnek felel meg, szám index-ek vannak benne, minden index-hez tartozik egy érték.

Set - Egyedi értékeket tárol, nincsenek index-ei. Pl. egy javascript objektumnak keySet-je van, mert minden kulcs csak egyszer szerepelhet. Ha objektumok vannak a Set-ben, akkor egyedi azonosítót szoktak kérni, ezt hashCode-nak hívják, és megnézik, hogy az egyedi azonosító szerepel e már a gyűjteményben. A gyűjteményt ilyenkor HashSet-nek nevezik. A probléma ott van, hogy DOM objektumoknál az internet explorer-ben nem lehet HashSet-et készíteni, mert nem lehet semmilyen tulajdonságot beállítani rajtuk. DOM objektumokból egyedül úgy készíthető Set, ha végigmész az összes addig hozzáadott elemen, és mindegyikre megnézed, hogy nem egyezik e meg az újonnan hozzáadandó elemmel. Ez rohadt lassú kódot eredményez, emiatt egyszerűbb nem biztosítani a Set-nél, hogy minden csak egyszer szerepelhet. (Annak idején úgy döntöttem, hogy amíg ez a probléma fennáll, addig nem vagyok hajlandó érdemben javascripttel foglalkozni.)

Map - Gyakorlatilag egy sima javascript object-nek felel meg. Kulcs-érték párokból áll, a kulcsok egyediek minden értékhez. Persze lehet HashMap-et is csinálni, ilyenkor a kulcsok objektumok. előzmény
Ezek alapján a FieldSet-et ki lehet cserélni egy sima tömbre, amit FieldList-nek hívsz, felesleges emiatt egy külön osztály, amikor js úgysem támogatja a Set-eket. A Field-et én szétbontanám AbstractField-re, InputField-re és SelectField-re, így megszűnnének benne az isSelectInput-os if-ek. A submitButton-nak is adnék egy külön osztályt, ami az enable/disable dolgokat csinálja rajta.

Szóval még lenne mit javítani a kódon. Én a helyedben elkezdenék ismerkedni az objektum orientált programozással. Ha tudsz angolul, akkor olvasd el a Clean Code című könyvet miután már ismered az alapokat. Ha nem tudsz angolul, akkor keress valamit, amiben elmagyarázzák az absztrakciós szinteket, pl: ebben írnak róluk (nem olvastam, nem tudom mennyire érthetően).

Ha mégsincs kedved oo-t tanulni, akkor van néhány szabály, amit érdemes betartani:

- használj beszélő neveket, amik leírják, hogy mit tartalmaz egy változó, vagy mit csinál egy függvény, kerüld a $-t meg a speciális karaktereket a változónevekben, zavaróak...

$.each(jArray,function(i,j){
        alert(i+j);
});
=>
$.each(fieldValidationMap,function(fieldName,isValid){
        alert(fieldName+isValid);
});
- switch helyett érdemes if-else -t használni, vagy ha van rá lehetőség, akkor egy Map-et, aminek a kulcsai a switch case-ei
switch( $('#'+inputName).get(0).tagName )
{
        case 'SELECT':
                var test = 0;
                var binding = 'change'
                break;
        default:
                var binding = 'textchange'
                var test = '';
}

=>

var binding = 'textchange';
var test = '';
var isSelectInput = ($('#'+inputName).get(0).tagName == "SELECT");
if (isSelectInput) {
        test = 0;
        binding = 'change';
} else {
        test = '';
        binding = 'textchange';
}

=>

var tagMap = {
        SELECT: {test: 0, binding: "change"},
        INPUT: {test: "", binding: "textchange"}
};
var inputTag = $('#'+inputName).get(0).tagName;
var params = tagMap[inputTag];
var test = params.test;
var binding = params.binding;

- kerüld a hosszú paraméter listákat, helyettük adj át egy map-et (sima javascript objektum), aminél a kulcsok a paraméterek nevei (minél hosszabb egy lista, annál könnyebb elfelejteni, hogy milyen sorrendben vannak benne a paraméterek)

function passwordInputsManage(jArray,inputName,submitName)
{
        //...
}
passwordInputsManage(pfields1, 'passuname1', 'remindque');

=>

function passwordInputsManage(params)
{
        var jArray = params.jArray;
        var inputName = params.inputName;
        var submitName = params.submitName;
        //...
}
passwordInputsManage({
        jArray: pfields1,
        inputName: 'passuname1',
        submitName: 'remindque'
});

- kerüld a blokkok egymásba ágyazását (pl if-ben egy switch, stb...), és a hosszú blokkokat. az összes ilyen blokk belseje kiemelhető külön függvénybe
ilyen nem volt a kódodban ...

- kerüld az ismétlődést, ha ismétlődik egy kód, az arra utal, hogy nem a megfelelő helyen van
var $currElement = $('#'+inputName);
switch( $('#'+inputName).get(0).tagName ) {...}

=>

var $currElement = $('#'+inputName);
switch( currElement.get(0).tagName ) {...}
vagy
$currElement.bind(binding,function(){
        var bool = $(this).val() != test ? true : false;
        setFieldOk(jArray, inputName, submitName, bool);
})
setFieldOk(jArray, inputName, submitName, ( $currElement.val() != test ? true : false ));

=>

var validateInput = function (){
        var bool = $(this).val() != test ? true : false;
        setFieldOk(jArray, inputName, submitName, bool);
};
$currElement.bind(binding, validateInput);
validateInput.call($currElement);

Ne használj eval-t, sosincs rá szükség.
if ( ok )
        eval("jArray." + inputName + "=true");
else
        eval("jArray." + inputName + "=false");
       
=>
       
jArray[inputName] = ok;

Alert-es hibakeresés helyett inkább sűrűbben ellenőrizd a paraméterek és változók helyességét, és dobjál kivételt, ha valami nem stimmel. Ha nagy a kódod, és kevés ellenőrzés van benne, akkor végig kell nézned az egészet alert-tel, mire megtalálod, hogy egy változó hol kapott hibás értéket...

var $currElement = $('#'+inputName);
switch( $('#'+inputName).get(0).tagName )
{
        ...
}

=>

var $currElement = $('#'+inputName);
if (!$currElement.length)
        throw new Error("Cannot find input: "+inputName);
switch( $('#'+inputName).get(0).tagName )
{
        ...
}

Mielőtt saját kódot írsz érdemes utánakeresni, hogy a keretrendszer, amit használsz nem e támogatja amit akarsz, vagy hogy nem e írta meg már valakit ugyanazt. Bár nem ismerem a jquery-t, de meglepődnék, ha nem lenne benne valami isEmpty, vagy ilyesmi az input-okra. Elég nagy keretrendszer... A leírása sajnos pocsék.

Egyébként nem hiszem, hogy járna a pont, mert semmi olyat nem írtam, ami a bind duplikálást megoldotta volna. Valószínűleg nem is volt jelen, lehet, hogy csak az zavart be, hogy hibás volt a setFieldOk-os sorod. előzmény
Oszd meg másokkal is!
Belépés
E-mail cím:
Jelszó:

cvonline.hu
»iOS fejlesztő
»Senior web programozó
»Java fejlesztő (Bécs)
»Java fejlesztő (front-end, backend)
»PHP fejlesztő (Ausztria, Németország)
»Solaris rendszermérnök
» még több állás
Kérdésed van?
Problémád, kérdésed van? Segítünk neked is. Csak kattints ide!
RSS források
-Hírek
-Cikkek
-Fórumok
-Állás/munka
Top pontgyűjtők
»Árnyék1.100
»silentworks910
»Robi80910
»szabofe860
»bubori.attila760
»djjjozsi680
»Galovics660
»Riha590
»Frostech0560
»Csaboka2550
A nap kifejezései
»Adatszegmens
»Konstans
»Makró
» ugrás a wikire
Hírek
»Az általános műveltség része kellene, hogy legyen a programozni tudás?
»Újra programozni fog a Facebook alapítója és multimilliárdos elnöke
»Vizuális felülettervezőt adott ki .NET-es Android-alkalmazásfejlesztéshez a Xamarin
» több hír
PC Fórum hírek
»Elvennék és felhasználóinak adnák a Facebook összes pénzét
»Rejtélyes ikont dugdosgat a Microsoft a Windows 8-ban
»Út a Windows 8-ig - a Windows rendszerek három évtizedének története, képekben
»Mától bárki regisztrálhat a so.cl-ra, a Microsoft közösségi oldalára
»Megérkeztek az első képek az Unreal Engine 4 játékmotorról
»Itt az első videó a a Firefox Windows 8-as változatáról
»Nyártól akár 150 megabites nethozzáférést is ad az Invitel
»Kilenc kritikus biztonsági hibát javít az új Google Chrome
Top wikieditorok
»Sting
»Doi
»FlamingClaw
»Argathron
»Csaboka2
»Muki987
»NevemTeve
»Ivn
»Kelemzol
»Joexy
» ugrás a wikire