Nina: Komplexe if-Bedingung

Hallo!

Kann es sein, dass manche Bedingungen zu komplex für JS sind?
Meine Bedingung sieht so aus:

if(((document.formular.REGION.options[0].selected == true) &&
    (document.formular.PRODUCTLINE.options[0].selected == true) &&
    (document.formular.PROJECT_STATUS.options[0].selected == true) &&
    (document.formular.TIER.options[0].selected == true) &&
    (document.formular.APPLICATIONS.options[0].selected == true) &&
    (document.formular.PRODUCT_PROJECT.options[0].selected == true) &
    (document.formular.OEM.options[0].selected == true) &&
    (document.formular.MISC.options[0].selected == true) &&
    (document.formular.REPORT_DETAIL_TYPE.value == 1))
    ||
   ((document.formular.REGION.options[0].selected == true) &&
    (document.formular.TIER.options[0].selected == true) &&
    (document.formular.OEM.options[0].selected == true) &&
    (document.formular.MISC.options[0].selected == true) &&
    (document.formular.REPORT_DETAIL_TYPE.value == 2))
    ||
   ((document.formular.REGION.options[0].selected == true) &&
    (document.formular.PRODUCTLINE.options[0].selected == true) &&
    (document.formular.TIER.options[0].selected == true) &&
    (document.formular.APPLICATIONS.options[0].selected == true) &&
    (document.formular.PRODUCT_PROJECT.options[0].selected == true) &
    (document.formular.OEM.options[0].selected == true) &&
    (document.formular.MISC.options[0].selected == true) &&
    (document.formular.REPORT_DETAIL_TYPE.value == 3))
  )
  {
   AnweisungsBlock
  }

Meiner Meinung nach wird das && nicht so ernst genommen, bei einem Block trifft die Bedingung zu, bei einem anderen nicht, das ganze scheint mir jedoch recht willkürlich!

Für eine Einschätzung wäre ich dankbar
Nina

  1. Hi Nina,

    na ja also meiner "Einschätzung" nach: Nein, Das if-Statement ist nicht zu komplex. Wenn man sich den entsprechenden Maschinen-Code ansieht, ist es sogar ziemlich trivial.

    (document.formular.PRODUCT_PROJECT.options[0].selected == true) &

    ^

    vielleicht zählst Du noch mal die einen oder anderen "&"s nach :-)

    Ciao
    Hans-Peter

  2. Hi Nina,

    es gibt keine Beschränkung, dem Parser ist es egal, ob es sich um zwei oder tausende if's handelt. Einzig wenn der Hauptspeicher knapp wird, ist irgendwann Schluss.

    Du hast bei einigen Angaben Flüchtigkeitsfehler gemacht und statt && nur & angegeben.

    Außerdem solltest Du versuchen, diese Monster-Abfrage zu optimieren, man kann es bestimmt kürzer schreiben und übersichtlicher, z.B. so:

    df = document.formular;

    if (
         (
           (df.REGION.options[0].selected == true) &&
           etc.
         )
       )
    {
      etc.
    }

    MfG
    Danny

    1. Hallo Ihr beiden!
      Danke erst mal!

      Ja, das zweite & ist wohl bei der Copy-Paste-Nachbearbeitung verloren gegangen.

      Selbst bei der vereinfachten Version

      if((document.formular.REPORT_DETAIL_TYPE.value == 1) &&
           (document.formular.REGION.options[0].selected == true) &&
           (document.formular.OEM.options[0].selected == true))

      klappt's nicht.
      Die beiden letzten Bedingungen werden behandelt, als wären sie mit einem 'oder' verknüpft
      Schnief, ich dachte immer, wenigstens Parser arbeiten logisch

      Danke
      Nina

      1. Am Parser liegt's bestimmt nicht ;)

        Bist Du sicher, dass die beiden Optionen überhaupt auf true stehen?

        alert(document.formular.REPORT_DETAIL_TYPE.value);
        alert(document.formular.REGION.options[0].selected);
        alert(document.formular.OEM.options);

  3. Für eine Einschätzung wäre ich dankbar

    Ich würde versuchen das massiv zu vereinfachen.

    1. Die Formularreferenz wenn möglich schon bei Funktionsaufruf der Funktion übergeben:

    <form ... onsubmit="return funktion(this);">

    oder

    <input type="submit" onclick="return funktion(this.form);">

    Das spart dir dann schonmal eine Menge Tipparbeit.

    function funktion(form)
    {

    }

    und dann auch um die Lesbarkeit zu erhöhen, die einzelnen Bedingungen in Funktionen packen und sinnvoll benamen:

    function checkDetailType1(form)
    {
    return  form.REGION.options[0].selected == true
    && form.PRODUCTLINE.options[0].selected == true
    && form.PROJECT_STATUS.options[0].selected == true
    && form.TIER.options[0].selected == true
    && form.APPLICATIONS.options[0].selected == true
    && form.PRODUCT_PROJECT.options[0].selected == true
    && form.OEM.options[0].selected == true
    && form.MISC.options[0].selected == true
    && form.REPORT_DETAIL_TYPE.value == 1;
    }

    function checkDetailType2(form)
    {
    return ((form.REGION.options[0].selected == true) &&
        (form.TIER.options[0].selected == true) &&
        (form.OEM.options[0].selected == true) &&
        (form.MISC.options[0].selected == true) &&
        (form.REPORT_DETAIL_TYPE.value == 2));

    }

    function checkDetailType2(form)
    {
    return  ((form.REGION.options[0].selected == true) &&
        (form.PRODUCTLINE.options[0].selected == true) &&
        (form.TIER.options[0].selected == true) &&
        (form.APPLICATIONS.options[0].selected == true) &&
        (form.PRODUCT_PROJECT.options[0].selected == true) &
        (form.options[0].selected == true) &&
        (form.options[0].selected == true) &&
        (form.REPORT_DETAIL_TYPE.value == 3))
    }

    und dann in deiner Hauptfunktion:

    if( checkDetailType1(form) || checkDetailType2(form) || checkDetailType3(form) )
    {
    ....
    }

    So liesse sich dein Programm auch leichter debuggen, da du die einzelnen Funktionen separat testen kannst.

    Struppi.

  4. Hi,
    Man muss boolsche Ausdrücke nicht noch gegen true testen:
        if (boolscherAusdruck == true)
    ist dasselbe wie
        if (boolscherAusdruck)

    Entsprechend:
        if (boolscherAusdruck == false)
    ist
        if (! boolscherAusdruck)

    Gunnar

  5. Danke an alle für Ihre Bemühungen, hab dies und das eurer Vorschläge eingearbeitet und irgendwie klappt es jetzt.
    Warum genau, weiss ich allerdings auch nicht (das sind mir immer die liebsten Fehler...)
    (Mein Form hatte je nach REPORT_DETAIL_TYPE verschiedene Felder; vielleicht hatte der Parser ein Problem, wenn ich sozusagen nach einem Feld gefragt hatte, was in diesem Form nicht vorhanden war, dann hat er die gesamte Bedingung einfach übersprungen,
    aber wie gesagt, das sind nur Mutmassungen)

    Wen's interessiert, mein Code sieht nun so aus:

    function checkHeader(form)
    {
     if (form.REPORT_DETAIL_TYPE.value == 1)
     {
      if (form.REGION.options[0].selected
       && form.PRODUCTLINE.options[0].selected
       && form.PROJECT_STATUS.options[0].selected
       && form.TIER.options[0].selected
       && form.APPLICATIONS.options[0].selected
       && form.PRODUCT_PROJECT.options[0].selected
       && form.OEM.options[0].selected
       && form.MISC.options[0].selected)
      {
      alert("Headline!");
      document.formular.REGION.focus();
      return false;
      }
     }
     else if (form.REPORT_DETAIL_TYPE.value == 2)
     {
      if (form.REGION.options[0].selected
       && form.TIER.options[0].selected
       && form.OEM.options[0].selected
       && form.MISC.options[0].selected)
      {
      alert("Headline!");
      document.formular.REGION.focus();
      return false;
      }
      //alert(form.REPORT_DETAIL_TYPE.value);
     }
     else
     {
      if (form.REGION.options[0].selected
       && form.PRODUCTLINE.options[0].selected
       && form.TIER.options[0].selected
       && form.APPLICATIONS.options[0].selected
       && form.PRODUCT_PROJECT.options[0].selected
       && form.OEM.options[0].selected
       && form.MISC.options[0].selected)
      {
      alert("Headline!");
      document.formular.REGION.focus();
      return false;
      }
     }
    }

    1. hallo,

      ich habe noch einige schönheitsfehler entdeckt:

      1. um die ganzen form(s) wegzulassen, kannst du http://selfhtml.teamone.de/javascript/sprache/objekte.htm#with verwenden.

      2. es sieht viel besser aus, wenn du du an Stelle von if ...== 1, 2, 3 die switch-Anweisung verwendest (mein geschmack).

      3. du könntest den quelltext natürlich auch unlesber gestalten. diese technik ins besondere bei perl-programmierern weit verbreitet.

      with(document.form) {
        if ((REPORT_DETAIL_TYPE.value == 1
          && REGION.options[0].selected
          && PRODUCTLINE.options[0].selected
          && PROJECT_STATUS.options[0].selected
          && TIER.options[0].selected
          && APPLICATIONS.options[0].selected
          && PRODUCT_PROJECT.options[0].selected
          && OEM.options[0].selected
          && MISC.options[0].selected)
          ||
          (REPORT_DETAIL_TYPE.value == 2
          && REGION.options[0].selected
          && TIER.options[0].selected
          && OEM.options[0].selected
          && MISC.options[0].selected)
          ||
          (REGION.options[0].selected
          && PRODUCTLINE.options[0].selected
          && TIER.options[0].selected
          && APPLICATIONS.options[0].selected
          && PRODUCT_PROJECT.options[0].selected
          && OEM.options[0].selected
          && MISC.options[0].selected)) {
            alert("Headline!");
            REGION.focus();
            return false;
          }
      }

      du könntest hier natürlich noch einiges ausklammern, sodass das ergebnis so aussähe:

      with(document.form) {
        if (
          REGION.options[0].selected
          && TIER.options[0].selected
          && OEM.options[0].selected
          && MISC.options[0].selected
          &&
          (
            (
              REPORT_DETAIL_TYPE.value == 1
              && PRODUCTLINE.options[0].selected
              && PROJECT_STATUS.options[0].selected
              && APPLICATIONS.options[0].selected
              && PRODUCT_PROJECT.options[0].selected
            )
            ||
            REPORT_DETAIL_TYPE.value == 2
            ||
            (
              PRODUCTLINE.options[0].selected
              && APPLICATIONS.options[0].selected
              && PRODUCT_PROJECT.options[0].selected
            )
          )
        )
        {
          alert("Headline!");
          REGION.focus();
          return false;
        }
      }

      wie man jetzt leicht erkennen kann, ist der letzte ausdruck des gesamten terms (also die große klammer) immer dann wahr, wenn der letzte klammerausruck in dieser klammer wahr ist, oder wenn REPORT_DETAIL_TYPE.value gleich zwei ist.

      oder:

      REPORT_DETAIL_TYPE.value == 1
              && PRODUCTLINE.options[0].selected
              && PROJECT_STATUS.options[0].selected
              && APPLICATIONS.options[0].selected
              && PRODUCT_PROJECT.options[0].selected

      impliziert

      PRODUCTLINE.options[0].selected
              && APPLICATIONS.options[0].selected
              && PRODUCT_PROJECT.options[0].selected

      da all die aussagen durch ein logischer oder verknüpft sind, reicht es vollkommen aus, wenn die letztere aussage wahr ist. man kann also die gesamte if-anweisung vereinfachen:

      with(document.form) {
        if (
          REGION.options[0].selected
          && TIER.options[0].selected
          && OEM.options[0].selected
          && MISC.options[0].selected
          &&
          (
            REPORT_DETAIL_TYPE.value == 2
            ||
            (
              PRODUCTLINE.options[0].selected
              && APPLICATIONS.options[0].selected
              && PRODUCT_PROJECT.options[0].selected
            )
          )
        )
        {
          alert("Headline!");
          REGION.focus();
          return false;
        }
      }

      und schon sieht der ausdruck ordentlich aus. ich hoffe einfach mal, dass ich keinen fehler gemacht habe. aber vom grundansatz her, sollte es stimmen. der nachteil des vereinfachten ausdrucks ist, dass änderungen sich nur schwerlich einbringen lassen. deswegen würde ich dir raten, erst einmal mit vielen verschachtelten if-else blöcken zu arbeiten, und dann, wenn du dir sicher bist, dass nichts mehr geändert werden muss, versuchen, den term zu vereinfachen.

      mit freundlichen grüßen
         dimitri rettig

      1. hallo,

        jetzt ist es mir noch eingefallen, dass && eine höhere priorität als || hat, sodass man einige unnötige klammern weglassen könnte.

        with(document.form) {
          if (
            REGION.options[0].selected
            && TIER.options[0].selected
            && OEM.options[0].selected
            && MISC.options[0].selected
            &&
            (
              REPORT_DETAIL_TYPE.value == 2
              ||
                PRODUCTLINE.options[0].selected
                && APPLICATIONS.options[0].selected
                && PRODUCT_PROJECT.options[0].selected
            )
          )
          {
            alert("Headline!");
            REGION.focus();
            return false;
          }
        }

        ... na gut, es war nur eine, aber es geht hier schließich auch noch ums prinzip!

        mit freundlichen grüßen
           dimitri rettig