Antworten auf deine Fragen:
Neues Thema erstellen

kleines problem mit javascript

timinol

Noch nicht viel geschrieben

kleines problem mit javascript (Fortsetzung)

hallo zusammen,

ich bin offensichtlich eine absolute null in javascript, wobei ich nicht alleine zu sein scheine, denn nachdem ich mehrere anfragen in andere foren gestellt habe (in frankreich und US) bleibt mir nur noch wenig hoffnung.

das problem ist folgendes:

ich habe eine seite die insgesamt 7 tage der woche darstellt, wobei jeder tag in viertelstunden unterteilt ist. jede viertelstunde wird durch ein graues bild dargestellt.
ich habe nun ein select, wo eine person ausgesucht wird. dieser person wird nun eine farbe zugeordnet und durch klicken der viertelstunden, wird das bild der entsprechenden farbe gezeigt. soweit sogut. das untengezeigt script funktioniert soweit.
das problem ist nun, dass ich als bindeelement zwischen PHP und javaScript ein cookie gewählt habe, was sich letztendlich als unglücklich herausstellt, denn ich schaffe es einfach nicht, das cookie wieder zu löschen, denn das cookie MUSS beim laden der seite (sei es durch laden oder durch F5) leer sein.

also habe ich optiert (nach langem suchen) für ein unsichtbares element, das jeweils von javaScript zur weiteren kontrolle herangezogen wird.

wie man aus dem script ersehen kann, ist der inhalt immer ein 2-dimesionales array indem jedes element jeweils in einem array den namen und die zugeordnete farbe festgehalten wird.

die frage ist: wie sind die jeweiligen funktionen getcookie() und controle_affect_color() zu ändern, dass sie nicht auf ein cookie, sondern auf ein unsichtbares html-tag greifen.

hier das script:
HTML:
<html>
 <head>
   <script language="javascript" type='text/javascript'>
   var perscol = -1; 
   var last_attributed = -1;
   var color = new Array(); 
   var person = "";
   var ptitle = '';
   var col_last = getCookie("colors[last]");
   var temp = 0;
    if (col_last!='') last_attributed = col_last;
   function getCookie(name) {
    if (document.cookie.length>0) {
     start = document.cookie.indexOf(name+"=");
     pos = start+name.length+1;
     if (start != 0) {
      start = document.cookie.indexOf("; "+name+"=");
      pos = start+name.length+3;
     }
     if (start != -1) {
      start = pos;
      end = document.cookie.indexOf(";",start);
      if (end == -1) end = document.cookie.length;
      return unescape(document.cookie.substring(start,end));
     }
    }
    return '';
   }
    function controle_affect_color(val,name) {
    if (val != 0) {
     if (color[val] == null) {
      var col_attrib = getCookie("colors["+name+"]");
      if (col_attrib!='') color[val] = col_attrib;
      else {
       color[val] = parseInt(last_attributed)+1;
       document.cookie = "colors["+name+"]="+color[val]+";";
       last_attributed++;
       document.cookie = "colors[last]="+last_attributed+";";
      }
      }
     ptitle=name;
     return color[val];
    }
    ptitle='';
    return -1;
   }
 
   function maj_img(id,obj,name,src) {
    var div=document.getElementById("total");
    div.innerHTML="<PRE>HEURES ALLOUEES:\n";
    if ((name!=obj.alt)&&(person!=0)) {
     document.getElementById(id).value=person;
     obj.src="img/plan/"+src+".png";
     if(obj.alt=='') temp+=25;
     obj.alt=name;
     obj.title=name;
    } else {
     document.getElementById(id).value=-1;
     obj.src="img/plan/-1.png";
     obj.alt='';
     obj.title='';
     if (temp>0) temp-=25;
    }
    if (temp/100>0) div.innerHTML+=Math.floor(temp/100)+"h"+temp%100+"min</PRE>";
    else div.innerHTML+=temp+"min</PRE>";
   }
   </script>
  <style type="text/css">
   .day {
    text-align: center;
    vertical-align: top;
    font-size: 60%;
    font-weight: bold;
   }
   .spc {
    font-size: 50%;
   }
   img {
    border: 0;
    vertical-align: middle;
   }
   form {
    margin: 0px;
    padding: 0px;
   }
  </style>
 </head>
 <body><center>
  <div id="color" style="visibility:hidden;"></div>
   <form method="post">
   <select name="pers" onChange="person=this.options[this.selectedIndex].value;perscol=controle_affect_color(this.value,this.options[this.selectedIndex].text);">
    <option value="0" selected>----</option>
    <option value="10">Rémi</option>
    <option value="20">Marcel</option>
    <option value="30">Michel</option>
    <option value="40">Christiane</option>
    <option value="50">Julien</option>
    <option value="60">Matthieu</option>
    <option value="70">Vincent</option>
    <option value="80">Stéphane</option>
    <option value="90">Marc</option>
   </select>
   <br /><br /><br />
   <table summary="" border="0" cellspacing="0" cellpadding="0">
    <tr>
     <td class="day" style="height:15px;">Hrs-></td>
     <?php
      if (isset($_POST['tab'])) {
       print_r($_POST['tab']);
       echo "<br>";
       print_r($_COOKIE['colors']);
      }
      else for($j=0;$j<1;$j++) for($i=0;$i<96;$i++) $l[$j][$i]=-1;
      $jrs = array("Lun","Mar","Mer","Jeu","Ven","Sam","Dim");
      for($k=0;$k<24;$k++)  echo '<td class="day" colspan="5">'.$k.'</td>';
      echo "\r</tr>";
      for($j=0;$j<1;$j++) {
       echo '<tr>
         <td valign="middle">'.$jrs[$j].'&nbsp;</td>';
       for($i=0;$i<96;$i++) {
        if ($i%4==0) echo '<td class="spc">&nbsp;</td>';
        $color = -1;
        if (isset($_COOKIE['colors'])) {
         $l[$j][$i] = trim($l[$j][$i]);
         if (array_key_exists($l[$j][$i], $_COOKIE['colors']) !== false) $color = $_COOKIE['colors'][$l[$j][$i]];
        }
        echo '<td valign="middle">
         <input id="'.$j.$i.'" type="hidden" name="tab['.$j.']['.$i.']" value="'.$l[$j][$i].'" />
         <img src="img/plan/'.$color.'.png" onClick="maj_img(\''.$j.$i.'\',this,ptitle,perscol);" alt="" title="" />
         </td>';
       }
       echo "\r</tr>\n\t";
      }
     ?>
   </table>
   <br />
   <input type="submit" value="enregistrer" />
  </form>
  <div id='total' style="float:center; position:relative; center:75px;"></div>
 </center></body>
</html>

ich bin für jede hilfe dankbar und danke im voraus!
 
Zuletzt bearbeitet:

Duddle

Posting-Frequenz: 14µHz

AW: kleines problem mit javascript

Ich werde mich mal nicht durch den ziemlich unübersichtlichen Code wühlen und mich stattdessen auf die Kernfrage konzentrieren:
das cookie MUSS beim laden der seite (sei es durch laden oder durch F5) leer sein.
Was hindert dich daran, es zu löschen? In JS geht das einfach, in PHP ebenso (siehe Example 2).


Duddle
 

timinol

Noch nicht viel geschrieben

AW: kleines problem mit javascript

hi duddle,

danke, dass du dir die zeit genommen hast.
die "kernfrage" ist jedoch nicht, wie ein cookie zu löschen ist. wie du dir vorstellen kannst, habe ich ausnahmlos sämtliche möglichkeiten ausgeschöpft, ein cookie zu löschen. jedoch hat genau dieses cookie ein hartes leben. das liegt mit an sicherheit grenzender wahrscheinlichkeit daran, dass cookie eben VOR jeglichem aufruf jedweder HTML-elemente aufgerufen, bearbeitet, geändert oder gelöscht werden müssen.

wie auch immer, ein cookie ist keine lösung.
also habe ich für einen unsichtbaren <input> optiert, das den zweck logischeweise vollauf erfüllen müsste.

wie du weisst führt jede änderung eines feldes in HTML und PHP zum erneuten laden der seite, was bei 672 inputs (7 tage à 96 viertel-stunden) auf der seite zu ewigen refreshs führt, was sehr unangenehm ist. also versuche ich, das ganze durch javaScript zu ersetzen, was die verwaltung der farben anbelangt.

dass der code unübersichtlich ist, liegt teilweise an der schlechten einrückung beim copy&paste des codes.

einfach erklärt:
beim wählen einer person (select) wird der jeweiligen person die nächste verfügbare farbe zugeordnet; also ein array(array([person1][farbe1],array([person2][farbe2]), usw...))

genau das tun momentan die js-funktionen getcookie() und controlle_affect_color().

nun gilt es einfach die in diesen funktionen enthaltenen griffe auf ein cookie zu ändern, derart, dass sie durch z.B. 'document.getElementById("color");' ersetzt werden. und genau da scheitere ich mangels javascript kenntnisse.

und bitte keine lösungsvorschläge mit AJAX oder jQuery und dergleichen schwere, umständliche und langsame elephanten. :D
 

Duddle

Posting-Frequenz: 14µHz

AW: kleines problem mit javascript

Okay, so langsam scheine ich zu verstehen, was du tust. Es hapert aber noch beim "was du willst".

Nachdem ich Marcel zwei Zeiten zugeordnet habe und das Ding per Knopf abschicke steht im Cookie lediglich welche Farb-Nummer er und andere Nutzer jeweils haben (und die höchste).

Was genau soll nun anders oder zusätzlich passieren wenn ich nach einem "enregistrer" wieder auf die Seite komme?


Duddle
 

timinol

Noch nicht viel geschrieben

AW: kleines problem mit javascript

Okay, so langsam scheine ich zu verstehen, was du tust. Es hapert aber noch beim "was du willst".

was ich will ist relativ einfach: ich will eine völlig leere variable (bzw völlig leeres array), die sich in abhängigkeit der klicks füllt.

dabei versuche ich mittlerweile eben auf einen <input type="hidden" id="color" name="color"> zuzugreifen, der jeweils per javascript updated wird, um im folgenden zu wissen, welche neue farbe an welche neue person zugewiesen wird, falls die person noch nicht anderweitig gewählt wurde.

beispiel:
die seite wird frisch geladen.

es werden 7 mal 96 graue bilder angezeigt.

ich wähle in der auswahl "duddle". javascript schaut nach duddle in der variable und stellt fest, dass er noch nicht da ist; also wird ihm die farbe 0 zugeordnet.
dann klickt man jeweils die viertelstunden an, in denen er eingaplant wurde.

danach wird "timinol" ausgesucht. js stellt fest, dass er auch neu ist und gibt ihm die farbe 1. dann wird wieder geklickt.

desweiteren mit 3 weiteren neuen personen. also ist das array gefüllt mit:
array([duddle]=>0,[timinol]=>1,[dritte]=>2,[vierte]=>3,[fünfte]=>4); (der key [last] könnte eventuell entfallen, denn ein griff auf das letzte element würde klar zeigen, welche farbe zuletzt vergeben wurde).

plötzlich fällt mir auf, dass ich vergessen habe duddle 3 weitere viertelstunden einzuplanen. also wähle ich im select "duddle", worauf js feststellt, dass ihm bvereits die farbe 0 vergeben wurde, diese also aktuell ist.

du siehst also, dass dieses array ausschlisslich und nur für die aktuelle seite gilt, denn beim klicken von "enregistrer" (abspeichern) wird $_POST["tab"] erstmal implodiert und als solches in eine tabelle der DB abgespeichert. womit ich hinterher genau weiss, wer wann um welche zeit eingeplant wurde. und nach "enregistrer" wird diese js-variable einfach wieder initialisiert, gelöscht, vernichtet oder der umweltfreundlichen entsorgung übergeben, wie man auch immer will. :D

und genau diese variable möchte ich nunmehr nicht mehr über cookie haben, sondern über diesen unsichtbaren input mit der id="color".

nachdem ich einen blick auf deine homepage geworfen habe, denke ich, dass es für dich ein klacks ist.

ps: es sei nebenbei bemerkt, dass ein klick auf eine viertelstunde im grunde ein flipflop ist: du klickst und die farbe ändert sich. du stellst fest, dass der klick falsch war, also klckst du wieder drauf, worauf die farbe wieder grau (frei) wird.
 
Zuletzt bearbeitet:

Duddle

Posting-Frequenz: 14µHz

AW: kleines problem mit javascript

Dann hoffe ich mal, dass ich dich korrekt verstanden habe. Hier mal im gesamten:
HTML:
<html>
 <head>
<script language="javascript" type='text/javascript'>

var valueColorMapping = {};

// holt farb-id fuer namen
function getColorByName(name) {
    if(valueColorMapping[name] === undefined) {
	var max = -1;
	for(var key in valueColorMapping) {
	  max = Math.max(valueColorMapping[key], max);
	}
	valueColorMapping[name] = max+1;
    }
    return valueColorMapping[name];
}
// aufgerufen bei namens-wahl
function personSelected(form) {
    var selected = form.options[form.selectedIndex];
    person=selected.value;
    perscol=getColorByName(selected.text);
}

// bei absenden des formulars fuer jeden namen die farb-id in einem hidden input festhalten
function enregistrer() {
    var form = document.getElementById("myform");
    for(var key in valueColorMapping) {
	var val = valueColorMapping[key];

	var inp = document.createElement('input');
	inp.setAttribute('type', 'hidden');
	inp.setAttribute('name', 'colorMapping['+key+']');
	inp.setAttribute('value', val);
	form.appendChild(inp);
    }
    form.submit();
}

var perscol = -1; 
var last_attributed = -1;
var color = new Array(); 
var person = "";
var ptitle = '';
var col_last = getCookie("colors[last]");
var temp = 0;
if (col_last!='') last_attributed = col_last;

function getCookie(name) {

    if (document.cookie.length>0) {
	start = document.cookie.indexOf(name+"=");
	pos = start+name.length+1;
	if (start != 0) {
	    start = document.cookie.indexOf("; "+name+"=");
	    pos = start+name.length+3;
	}
	if (start != -1) {
	    start = pos;
	    end = document.cookie.indexOf(";",start);
	    if (end == -1) end = document.cookie.length;
	    return unescape(document.cookie.substring(start,end));
	}
    }
    return '';
}
function controle_affect_color(val,name) {
    if (val != 0) {
	if (color[val] == null) {
	    var col_attrib = getCookie("colors["+name+"]");
	    if (col_attrib!='') color[val] = col_attrib;
	    else {
		color[val] = parseInt(last_attributed)+1;
		document.cookie = "colors["+name+"]="+color[val]+";";
		last_attributed++;
		document.cookie = "colors[last]="+last_attributed+";";
	    }
	}
	ptitle=name;
	return color[val];
    }
    ptitle='';
    return -1;
}

function maj_img(id,obj,name,src) {
    var div=document.getElementById("total");
    div.innerHTML="<PRE>HEURES ALLOUEES:\n";
    if ((name!=obj.alt)&&(person!=0)) {
	document.getElementById(id).value=person;
	obj.src="img/plan/"+src+".png";
	if(obj.alt=='') temp+=25;
	obj.alt=name;
	obj.title=name;
    } else {
	document.getElementById(id).value=-1;
	obj.src="img/plan/-1.png";
	obj.alt='';
	obj.title='';
	if (temp>0) temp-=25;
    }
    if (temp/100>0) div.innerHTML+=Math.floor(temp/100)+"h"+temp%100+"min</PRE>";
    else div.innerHTML+=temp+"min</PRE>";
}
</script>
  <style type="text/css">
   .day {
    text-align: center;
    vertical-align: top;
    font-size: 60%;
    font-weight: bold;
   }
   .spc {
    font-size: 50%;
   }
   img {
    border: 0;
    vertical-align: middle;
   }
   form {
    margin: 0px;
    padding: 0px;
   }
  </style>
 </head>
 <body><center>
  <div id="color" style="visibility:hidden;"></div>
   <form id="myform" method="post">
   <select name="pers" onChange="personSelected(this);">
    <option value="0" selected>----</option>
    <option value="10">Rémi</option>
    <option value="20">Marcel</option>
    <option value="30">Michel</option>
    <option value="40">Christiane</option>
    <option value="50">Julien</option>
    <option value="60">Matthieu</option>
    <option value="70">Vincent</option>
    <option value="80">Stéphane</option>
    <option value="90">Marc</option>
   </select>
   <br /><br /><br />
   <table summary="" border="0" cellspacing="0" cellpadding="0">
    <tr>
     <td class="day" style="height:15px;">Hrs-></td>
<?php
if (isset($_POST['tab'])) {
    echo "<pre>";
    print_r($_POST['tab']);
    echo "<br>";
    print_r($_COOKIE['colors']);
    echo "</pre>";
}
else for($j=0;$j<1;$j++) for($i=0;$i<96;$i++) $l[$j][$i]=-1;
$jrs = array("Lun","Mar","Mer","Jeu","Ven","Sam","Dim");
for($k=0;$k<24;$k++)  echo '<td class="day" colspan="5">'.$k.'</td>';
echo "\r</tr>";
for($j=0;$j<1;$j++) {
    echo '<tr>
	<td valign="middle">'.$jrs[$j].'&nbsp;</td>';
    for($i=0;$i<96;$i++) {
	if ($i%4==0) echo '<td class="spc">&nbsp;</td>';
	$color = -1;
	if (isset($_COOKIE['colors'])) {
	    $l[$j][$i] = trim($l[$j][$i]);
	    if (array_key_exists($l[$j][$i], $_COOKIE['colors']) !== false) $color = $_COOKIE['colors'][$l[$j][$i]];
	}
	echo '<td valign="middle">
	    <input id="'.$j.$i.'" type="hidden" name="tab['.$j.']['.$i.']" value="'.$l[$j][$i].'" />
	    <img src="img/plan/'.$color.'.png" onClick="maj_img(\''.$j.$i.'\',this,ptitle,perscol);" alt="" title="" />
	    </td>';
    }
    echo "\r</tr>\n\t";
}
?>
   </table>
   <br />
   <input type="submit" value="enregistrer" onclick="enregistrer(this); return false;"/>
  </form>
  <div id='total' style="float:center; position:relative; center:75px;"></div>
 </center></body>
</html>
Du kannst das ja selber diffen, ich habe aber praktisch im Quelltext fast nichts geändert. Bei der Auswahl im <select> wird jetzt eine Hilfsfunktion aufgerufen, bei Absenden des Formulars eine andere, das Formular selbst hat jetzt eine id.

Das tatsächlich neue sind die 3 Funktionen am Anfang, vor deinem alten Zeug. Ich habe die vorhandenen Funktionen nicht angefasst, da ich mich nicht durch Abhängigkeiten usw. durchkämpfen wollte.

Prinzipiell ist es aber nur ein Objekt, das für diesen einen Seitenaufruf die Farbzuordnung verwaltet. Das getColorByName() holt die für den Namen zugewiesene Farb-ID oder setzt im Bedarfsfall eine neue.

Das personSelected() ist quasi das gleiche, was du vorher im onchange vom <select> hattest. Das enregistrere() hängt sich vor das normale Abschicken und erzeugt lediglich pro Name/Farb-ID - Paar ein verstecktes input, dann wird das Formular normal abgeschickt.


Duddle
 

timinol

Noch nicht viel geschrieben

AW: kleines problem mit javascript

erstmal vielen vielen dank!!!
ich bin ein riesenschritt weitergekommen! zum einen bestätigt es, dass ein cookie völlig unnötig ist, abgfesehen von der tatsache, dass es nicht unbedingt verlässlich ist, zum anderen ist es pures javascript, ohne libraries und sonstige konsorten.

feststeht, dass du das prinzip erfasst hast. du bist dabei sogar einen schritt zu weit gegangen.
1. ein abspeichern der information "person=>farbe" NACH abspeichern der seite ist nicht notwendig.
2. um deine idee weiterzuspinnen, und damit das ganze etwas einfacher zu gestalten, habe ich VOR "form" einen hidden input mit namen und id "color" der dazu benutzt werden soll eben diese "person=>farbe"-info bereitzustellen.

in diesem sinne habe ich also das ganze abgespeckt und mit deutschen kommentaren versehen, denn ich möchte dein augenmerk auf die funktion maj_img() richten. diese funktion wird nunmehr nicht mit allen nötigen infos versorgt so, dass die farben sich beim klicken nicht mehr ändern. die fehlermeldung der java-console sagt: ptitle undefined. diese funktion ist es auch, die die geplante zeit addiert und anzeigt (im div id="total").

ich bin aber sicher, dass es sich nur noch um einen klacks ändern kann.

an dieser stelle sei gesagt, dass deine functions genial einfach und kurz sind, so dass sogar ich sie teilweise verstehen kann.

hier also der updatete code:
Code:
<html>
 <head>
  <script language="javascript" type="text/javascript">
   var valueColorMapping = {};
   // holt farb-id fuer namen
   function getColorByName(name) {
    if (valueColorMapping[name] === undefined) {
     var max = -1;
     for (var key in valueColorMapping) {
      max = Math.max(valueColorMapping[key], max);
     }
     valueColorMapping[name] = max+1;
    }
    return valueColorMapping[name];
   }
   // aufgerufen bei namens-wahl
   function personSelected(form) {
    var selected = form.options[form.selectedIndex];
    person = selected.value;
    perscol = getColorByName(selected.text);
   }
   function maj_img(id,obj,name,src) {
    //id: id-parameter des inputs
    //obj: bild (immer this, entspricht dem element in welchem javascript benutzt wird
    //name: inhalt der attribute alt und title
    //src: url des bildes 
    var div = document.getElementById("total");
    div.innerHTML = "<PRE>geplante zeit:\n";
    //setzt die bild-inputs
    if ((name!=obj.alt)&&(person!=0)) {
     //falls der name in alt und title sich vom aktuellen unterscheidet, wird der aktuelle ersetzt
     document.getElementById(id).value = person;
     obj.src = "img/plan/"+src+".png";
     if(obj.alt=='') temp += 25;
     obj.alt = name;
     obj.title = name;
    } else {
     //ansonsten ist es ein flipflop, also default-image, alt und title sind leer und im input wird der default-wert gesetzt
     //auf die default-option des selects (value=-1)
     document.getElementById(id).value = -1;
     obj.src = "img/plan/-1.png";
     obj.alt = '';
     obj.title = '';
     if (temp>0) temp -= 25;
    }
    if (temp/100>0) div.innerHTML += Math.floor(temp/100)+"h"+temp%100+"min</PRE>";
    else div.innerHTML += temp+"min</PRE>";
   }
  </script>
  <style type="text/css">
   .day {
    text-align: center;
    vertical-align: top;
    font-size: 60%;
    font-weight: bold;
   }
   .spc {
    font-size: 50%;
   }
   img {
    border: 0;
    vertical-align: middle;
   }
   form {
    margin: 0px;
    padding: 0px;
   }
  </style>
 </head>
 <body><center>
  <input type="hidden" id="color" name="color">
  <form action="" method="post">
   <select name="pers" onChange="personSelected(this);">
    <option value="0" selected>----</option>
    <option value="10">Rémi</option>
    <option value="20">Marcel</option>
    <option value="30">Michel</option>
    <option value="40">Christiane</option>
    <option value="50">Julien</option>
    <option value="60">Matthieu</option>
    <option value="70">Vincent</option>
    <option value="80">Stéphane</option>
    <option value="90">Marc</option>
   </select>
   <br /><br /><br />
   <table summary="" border="0" cellspacing="0" cellpadding="0">
    <tr>
     <td class="day" style="height:15px;">Hrs-></td>
     <?php
      if (isset($_POST['tab'])) {
       print_r($_POST['tab']);
      }
      else for($j=0;$j<1;$j++) for($i=0;$i<96;$i++) $l[$j][$i]=-1;
      $jrs = array("Lun","Mar","Mer","Jeu","Ven","Sam","Dim");
      for($k=0;$k<24;$k++)  echo '<td class="day" colspan="5">'.$k.'</td>';
      echo "\r</tr>";
      for($j=0;$j<1;$j++) {
       echo '<tr>
        <td valign="middle">'.$jrs[$j].'&nbsp;</td>';
       for($i=0;$i<96;$i++) {
        if ($i%4==0) echo '<td class="spc">&nbsp;</td>';
        $color = -1;
/*        if (isset($_COOKIE['colors'])) {
         $l[$j][$i] = trim($l[$j][$i]);
         if (array_key_exists($l[$j][$i], $_COOKIE['colors']) !== false) $color = $_COOKIE['colors'][$l[$j][$i]];
        }
*/        echo '<td valign="middle">
        <input id="'.$j.$i.'" type="hidden" name="tab['.$j.']['.$i.']" value="'.$l[$j][$i].'" />
        <img src="img/plan/'.$color.'.png" onClick="maj_img(\''.$j.$i.'\',this,ptitle,perscol);" alt="" title="" />
        </td>';
       }
       echo "\r</tr>\n\t";
      }
     ?>
   </table>
   <br />
   <input type="submit" value="enregistrer" />
  </form>
  <div id='total' style="float:center; position:relative; center:75px;"></div>
 </center></body>
</html>
 
Zuletzt bearbeitet:

Duddle

Posting-Frequenz: 14µHz

AW: kleines problem mit javascript

Okay, ich habe jetzt das getan, was ich wohl von Anfang an hätte machen sollen: Zeit zum Neu-Schreiben.

Ohne zu viel antasten zu müssen habe ich versucht dein Konstrukt zu entschlacken. Es ist immer noch nicht nach meinem Geschmack, aber es ist jetzt für mich verständlicher als vorher - und es funktioniert.

HTML:
<html>
 <head>
<script language="javascript" type="text/javascript">
var valueColorMapping = {};
// holt farb-id fuer namen
function getColorByName(name) {
    if (valueColorMapping[name] === undefined) {
	var max = -1;
	for (var key in valueColorMapping) {
	    max = Math.max(valueColorMapping[key], max);
	}
	valueColorMapping[name] = max+1;
    }
    return valueColorMapping[name];
}
function getName() {
    return getSelected().text;
}
function getValue() {
    return getSelected().value;
}
function getSelected() {
    var frm = document.getElementById("nameSelect");
    return frm.options[frm.selectedIndex];
}

var timePlanned = new Date();
timePlanned.setHours(0);
timePlanned.setMinutes(0);

function changeTime(diff) {
    //falls von 0 minuten abgezogen werden soll nix tun
    if(diff < 0 && timePlanned.getMinutes() == 0 && timePlanned.getHours() == 0) {
	return;
    }

    timePlanned.setMinutes(timePlanned.getMinutes() + diff);

    var div = document.getElementById("total");
    div.innerHTML = "<PRE>geplante zeit:"+timePlanned.getHours()+"h"+timePlanned.getMinutes()+"m</PRE>";
}
function maj_img(id,obj) {
    var input = document.getElementById(id);
    var img = obj;
    var newName = getName();
    var newValue = getValue();
    var slotTime = 15;

    if(input.value == newValue) {
	//default
	img.src = "img/plan/-1.png";
	img.title = name;
	input.value = -1;
	changeTime(-slotTime);
    } else { 
	if(input.value == -1) {
	    //nur falls leerer Slot ersetzt, Zeit erhöhen
	    changeTime(slotTime);
	}
	img.src = "img/plan/"+getColorByName(newName)+".png";
	img.title = newName;
	input.value = newValue;
    }
}
</script>
  <style type="text/css">
   .day {
    text-align: center;
    vertical-align: top;
    font-size: 60%;
    font-weight: bold;
   }
   .spc {
    font-size: 50%;
   }
   img {
    border: 0;
    vertical-align: middle;
   }
   form {
    margin: 0px;
    padding: 0px;
   }
  </style>
 </head>
 <body><center>
  <input type="hidden" id="color" name="color">
  <form action="" method="post">
   <select id="nameSelect" name="pers">
    <option value="0" selected>----</option>
    <option value="10">Rémi</option>
    <option value="20">Marcel</option>
    <option value="30">Michel</option>
    <option value="40">Christiane</option>
    <option value="50">Julien</option>
    <option value="60">Matthieu</option>
    <option value="70">Vincent</option>
    <option value="80">Stéphane</option>
    <option value="90">Marc</option>
   </select>
   <br /><br /><br />
   <table summary="" border="0" cellspacing="0" cellpadding="0">
    <tr>
     <td class="day" style="height:15px;">Hrs-></td>
<?php
if (isset($_POST['tab'])) {
    print_r($_POST['tab']);
}
else for($j=0;$j<1;$j++) for($i=0;$i<96;$i++) $l[$j][$i]=-1;
$jrs = array("Lun","Mar","Mer","Jeu","Ven","Sam","Dim");
for($k=0;$k<24;$k++)  echo '<td class="day" colspan="5">'.$k.'</td>';
echo "\r</tr>";
for($j=0;$j<1;$j++) {
    echo '<tr>
	<td valign="middle">'.$jrs[$j].'&nbsp;</td>';
    for($i=0;$i<96;$i++) {
	if ($i%4==0) echo '<td class="spc">&nbsp;</td>';
	$color = -1;
        echo '<td valign="middle">
     <input id="'.$j.$i.'" type="hidden" name="tab['.$j.']['.$i.']" value="'.$l[$j][$i].'" />
     <img src="img/plan/'.$color.'.png" onClick="maj_img(\''.$j.$i.'\',this);" alt="" title="" />
     </td>';
    }
    echo "\r</tr>\n\t";
}
?>
   </table>
   <br />
   <input type="submit" value="enregistrer" />
  </form>
  <div id='total' style="float:center; position:relative; center:75px;"></div>
 </center></body>
</html>
Deine maj_img()-Funktion habe ich neu geschrieben, die grundlegende Logik ist aber die gleiche. Ein paar Hilfs-Funktionen erleichtern den Zugriff auf potenziell mehrfach benötigte Werte.

Die Zeit-Berechnung erfolgt jetzt mit einem Date-Objekt, dafür sind die Dinger gedacht. Ausserdem könntest du dann problemlos von 15 Minuten-Slots auf z.B. 30 Minuten wechseln.

Ich habe immer noch nicht verstanden, was du mit dem <input> vor dem Formular machen willst, aber ich habe es einfach mal drin gelassen.


Duddle
 

timinol

Noch nicht viel geschrieben

AW: kleines problem mit javascript

ALLE ACHTUNG!
ich ziehe echt meinen hut vor dir; und das will was heissen, von einem entwickler mit mehr als 35 jahre erfahrung! (allerdings zum grossen teil auf "echten" computern)

deine funktionen sind nicht nur einfacher, sondern auch für mich erheblich verständlicher. wie du nunmehr weisst, muss man mir alles erklären, wie einem 3-jährigen ;).

wie du von alleine darauf gekommen bist, dass eventuell mal auch halb-stundenweise gearbeitet werden könnte, weiss der teufel, aber auch das ist in der weiteren planung gewesen. bzw vom benutzer als eingestellter wert abspeichbar.

den ominösen input, den du anspricht, dachte ich als notwendig für javascript selbst, um die vorgenommenen änderungen auf der seite festzuhalten. wie du aber recht bemerkt hast, ist auch das völlig unnötig, also habe ich ihn der umweltfreundlichen entsorgung übergeben.

ich verneige nochmals tief mein haupt (AUA! mein ischias!) :D

wenn ich dir mal 'nen stein in den garten werfen soll, ..... anytime dude!
 

timinol

Noch nicht viel geschrieben

kleines problem mit javascript (die zweite)

tach zusammen,

im ersten teil:


wurde das problem von duddle mit brio gelöst!

jetzt wurde eine userin spitzfindig und meinte berechtigterweise, dass wenn man z.b. 4 stunden planen muss, muss man 16 mal auf die jeweilige viertelstunden klicken. ideal wäre aber z.b. den ersten klick normal auszuführen, dann aber auf die letzte (zu planende) viertelstunde geht, die taste "alt" drückt und klickt, was dann automatisch alle dazwischen liegenden viertelstunden als geklickt markiert werden (die farbe also wechselt).

geht das, (wieder) ohne jegliche libraries, mit einfachem javascript, wie im oben erwähnten topic mit bravur gelöst?
 

Duddle

Posting-Frequenz: 14µHz

AW: kleines problem mit javascript (die zweite)

geht das, (wieder) ohne jegliche libraries, mit einfachem javascript, wie im oben erwähnten topic mit bravur gelöst?

Das ist jetzt die dritte Erwähnung von Libraries. Woher kommt denn diese Aversion für nützliche Module?

Natürlich ist jQuery recht groß, aber das Ding wird doch nur einmal geladen und ist dann im Cache. Idealerweise verweist man daher auf die CDNs von Google o.ä., weil es dann wahrscheinlicher wird dass man drei Stunden vorher schon die jQuery-Datei für eine andere Seite angefordert hat.
Wenn der Großteil deiner Nutzer noch in 56k-Zeiten stecken verstehe ich den Drang zur Optimierung, aber heutzutage sind 32kB kein Thema mehr.

Für diesen, meiner Meinung nach kleinen, Nachteil bringen jQuery und Konsorten aber Browser-übergreifende und intelligente Werkzeuge sowie nette Effekte mit. Es gibt einen Grund warum darauf so viele PlugIns gebaut wurden.

/OffTopic

Zu deinem Problem: ja, das Event-Objekt hat Attribute bezüglich gedrückter Tasten während des Events. Der einzige anwendbare Event ist in deinem Fall das onclick vom <img>. Dort wird aber noch kein Event-Objekt explizit übergeben.

Die derzeitige Struktur ist wohl etwas ungeeignet für eine schicke Umsetzung deines Wunsches. Im Idealfall gäbe es eine Funktion zum Setzen eines bestimmten Slots. Dann merkst du dir irgendwo den zuletzt gesetzten Slot (und die dabei gesetzte Farbe, auch "leer"), iterierst über idVonLetztemSlot bis idVonDerzeitigemSlot und rufst jeweils die genannte Funktion auf.

Ich werde die Tage mal schauen, ob das ohne ein großes Neu-Schreiben machbar ist. In der Zwischenzeit kannst du dich ja dran probieren :) Aber erfinde nicht zu viele Hilfs-Funktionen, sonst hast du dir schnell eine eigene Bibliothek geschrieben *grusel*


Duddle
 

timinol

Noch nicht viel geschrieben

AW: kleines problem mit javascript

<offtopic>
Das ist jetzt die dritte Erwähnung von Libraries. Woher kommt denn diese Aversion für nützliche Module?

hi duddle,

meine "aversion" gegen libraries ist irgendwo historisch begründet.
einfaches beispiel: in meinen anfängen in COBOL musste ich eine ergebnisliste liefern, die nach datum sortiert ausgegeben werden musste.
dazu habe ich im programm das datumsfeld unterteilt und habe ein sortfeld angelegt mit inhalt =
jahr*10000+monat*100+tag
und habe dann meine liste bequem sortieren können. das programm war schnell aber einer der kollegen (ein cobol-spezialist) konnte mit diesem programm-teil rein gar nichts anfangen. er fragte, wieso ich denn nicht eine bereits bestehende funktion benuttzt habe, die es bereits in einer funktionssammlung gab.
das tat ich dann versuchsweise. es stelle sich heraus, dass das programm um faktor 10 langsamer war ............

das ist nur EIN beispiel unter vielen.

zweiter grund ist, dass ich gerne immer genau weiss, WAS das programm macht, WANN, WARUM und WIE.

natürlich weiss ich, dass man sich heutzutage einen dreck schert um ressourcen und konsorten, aber nennen wir es mal einfach "professionelle deformation" :)

</offtopic>

deine bemerkung, wie das problem angegangen werden muss ist sehr nützlich, auch habe ich mir sehr wohl gedanken darüber gemacht:
Code:
function detectkey(id) {
     var heldkey = document.getElementById('taste');
     e = e || event;
     heldkey.innerHTML = e.altKey ? 'MIT' : 'OHNE';
     return true;
}

wie du treffend bemerktest, muss natürlich dabei beachtet werden, WELCHES feld zuletzt gedrückt wurde. dabei muss ebenfalls beachtet werden, ob, falls [alt] gedrückt wurde, das feld auch im gleichen tag ist, wobei das immer über die "id" geht, die, wie du weisst, aus zwei elementen besteht.
nehme wir die id 055: die sagt uns: tag 0 feld 55
id 677= tag 6 feld 77

und damit stösst mein javascript sehr schnell an seine grenzen ............
aber ich hirne mal weiter :)
 

Duddle

Posting-Frequenz: 14µHz

AW: kleines problem mit javascript

HTML:
<html>
 <head>
<script language="javascript" type="text/javascript">
var valueColorMapping = {};
// holt farb-id fuer namen
function getColorByName(name) {
    if (valueColorMapping[name] === undefined) {
	var max = -1;
	for (var key in valueColorMapping) {
	    max = Math.max(valueColorMapping[key], max);
	}
	valueColorMapping[name] = max+1;
    }
    return valueColorMapping[name];
}
function getName() {
    return getSelected().text;
}
function getValue() {
    return getSelected().value;
}
function getSelected() {
    var frm = document.getElementById("nameSelect");
    return frm.options[frm.selectedIndex];
}

var timePlanned = new Date();
function updateTime() {
    //setDate ist der Tag ... 0 wäre der letzte Tag vom vorigen Monat, ergo 1
    timePlanned.setDate(1); 
    timePlanned.setHours(0); 
    timePlanned.setMinutes(0); 
    var slotTime = 15;

    //in jQuery wäre folgendes ein 3-Zeiler ...
    var inputs = document.getElementsByTagName("input");
    for(var i in inputs) {
	var inp = inputs[i];
	if(!hasClass(inp, "assigment")) continue;
	if(inp.value == -1) continue;
	changeTime(slotTime);
    }
}

function hasClass(element, cls) {
    var r = new RegExp('\\b' + cls + '\\b');
    return r.test(element.className);
}

function changeTime(diff) {
    timePlanned.setMinutes(timePlanned.getMinutes() + diff);

    var div = document.getElementById("total");
    div.innerHTML = "<PRE>geplante zeit:"+(timePlanned.getDate()-1)+"d"+timePlanned.getHours()+"h"+timePlanned.getMinutes()+"m</PRE>";
}

function change(day, slot, canToggle) {
    var newValue = getValue();
    var newName = getName();
    var input = document.getElementById("input_"+day+"_"+slot);
    var img = document.getElementById("img_"+day+"_"+slot);

    //default-Wert von canToggle ist true
    canToggle = typeof canToggle !== 'undefined' ? canToggle : true;

    //falls kein richtiger Name / value = 0, dann ausschalten
    //gleiches für ein togglen bei gesetztem Namen
    if(newValue == 0 || (input.value == newValue && canToggle)) {
	//default
	img.src = "img/plan/-1.png";
	img.title = name;
	input.value = -1;
    } else { 
	img.src = "img/plan/"+getColorByName(newName)+".png";
	img.title = newName;
	input.value = newValue;
    }
}

var lastClicked = {day:null, slot:null, colorId:null};
function click(e, day, slot) {
    var e = e || window.event;
    var newColor = getColorByName(getName());

    if(e.ctrlKey && lastClicked.day != null && lastClicked.day == day && lastClicked.colorId == newColor) {
	//Bereiche. nur im gleichen Tag möglich
	var min = Math.min(lastClicked.slot, slot);
	var max = Math.max(lastClicked.slot, slot);
	for(var slotToChange = min; slotToChange <= max; slotToChange++) {
	    change(day, slotToChange, false);
	}
    } else {
	change(day, slot);
    }

    lastClicked.day = day;
    lastClicked.slot = slot;
    lastClicked.colorId = newColor;
    updateTime();
}
</script>
  <style type="text/css">
   .day {
    text-align: center;
    vertical-align: top;
    font-size: 60%;
    font-weight: bold;
   }
   .spc {
    font-size: 50%;
   }
   img {
    border: 0;
    vertical-align: middle;
   }
   form {
    margin: 0px;
    padding: 0px;
   }
  </style>
 </head>
 <body><center>
  <input type="hidden" id="color" name="color">
  <form action="" method="post">
   <select id="nameSelect" name="pers">
    <option value="0" selected>----</option>
    <option value="10">Rémi</option>
    <option value="20">Marcel</option>
    <option value="30">Michel</option>
    <option value="40">Christiane</option>
    <option value="50">Julien</option>
    <option value="60">Matthieu</option>
    <option value="70">Vincent</option>
    <option value="80">Stéphane</option>
    <option value="90">Marc</option>
   </select>
   <br /><br /><br />
   <table summary="" border="0" cellspacing="0" cellpadding="0">
    <tr>
     <td class="day" style="height:15px;">Hrs-></td>
<?php
if (isset($_POST['tab'])) {
    print_r($_POST['tab']);
}
else for($j=0;$j<1;$j++) for($i=0;$i<96;$i++) $l[$j][$i]=-1;
$jrs = array("Lun","Mar","Mer","Jeu","Ven","Sam","Dim");
for($k=0;$k<24;$k++)  echo '<td class="day" colspan="5">'.$k.'</td>';
echo "\r</tr>";
for($j=0;$j<1;$j++) {
    echo '<tr>
	<td valign="middle">'.$jrs[$j].'&nbsp;</td>';
    for($i=0;$i<96;$i++) {
	if ($i%4==0) echo '<td class="spc">&nbsp;</td>';
	$color = -1;
        echo '<td valign="middle">
     <input class="assigment" id="input_'.$j.'_'.$i.'" type="hidden" name="tab['.$j.']['.$i.']" value="'.$l[$j][$i].'" />
     <img src="img/plan/'.$color.'.png" id="img_'.$j.'_'.$i.'" onClick="click(event,'.$j.','.$i.')" alt="" title="" />
     </td>';
    }
    echo "\r</tr>\n\t";
}
?>
   </table>
   <br />
   <input type="submit" value="enregistrer" />
  </form>
  <div id='total' style="float:center; position:relative; center:75px;"></div>
 </center></body>
</html>
Die Logik von maj_img steckt jetzt in change(), wobei aber ausschliesslich mit Tag- und Slot-Nummer gearbeitet wird zur Identifizierung der Elemente. Zusätzlich ist noch ein optionales Argument dabei, welches bestimmt ob das zu setzende Feld getogglet werden kann. Das ist hilfreich bei Bereichs-Setzen.
Ausserdem wird noch unterschieden ob der derzeitige Klick für einen richtigen Namen kommt. Wenn nicht ("---" ausgewählt), wird das gelöscht. Damit kann man dann Bereiche löschen.

Der Event selbst, und die Unterscheidung ob Bereich oder nicht, ist in der kreativ als click() bezeichneten Funktion. Ich habe hier nur STRG genommen, weil ALT bei mir mit anderen Funktionen belegt ist. Ein Bereich darf nur im gleichen Tag und mit der gleichen Person gesetzt werden. Der Rest sollte eindeutig sein.

Die dritte Änderung ist die Verwaltung der zugewiesenen Gesamtzeit. Jetzt wird einfach nach jedem Klick gezählt wieviele zugewiesen sind und die Zeit entsprechend berechnet. Das ist zwar immer noch nicht ideal, aber meiner Meinung nach besser als vorher.

So, jetzt bin ich gespannt, was als nächstes im feature creep kommt :)


Duddle
 

timinol

Noch nicht viel geschrieben

AW: kleines problem mit javascript

hi duddle,

So, jetzt bin ich gespannt, was als nächstes im feature creep kommt
smile.gif

ehrlich gesagt, ich auch :), wobei ich sagen muss, dass dieses feature durchaus sinn macht. natürlich schliesst auch das keinen pebcak aus: http://en.wikipedia.org/wiki/Pebcak#Acronyms_and_other_names_for_a_user_error

was die geänderte logik anbelangt, die ist mir sofort aufgefallen, denn ich untersuche einen code grundsätzlich, bevor ich ihn teste.

auch ist mir aufgefallen, dass du den tag und den slot als getrennte parameter übergibst, was allein genial ist, denn im endprodukt wird der tag effektiv als timestamp übergeben.

kannst du dir meine enttäuschung vorstellen, als das script (ich betone "bei mir") nicht funktionierte.

im bereich meiner eingeschränkten javascript kenntnisse habe ich dann zuletzt ein "alert()" als erste zeile der funktion click() eingesetzt und bekomme nicht die geringste ausgabe. ???????
 

Duddle

Posting-Frequenz: 14µHz

AW: kleines problem mit javascript

1) Welcher Browser?
2) Gibt Firebug irgendeine Fehlermeldung aus?

Die einzige Fehlerquelle die ich mir vorstellen kann wäre in Bezug auf falsch kodierte Sonderzeichen, aber die werden ausser in Kommentaren und in den franz. Namen nie benutzt. Wenn ich den Code rauskopiere und mit meiner lokalen Version diffe sehe ich auch keinen Unterschied.

Ich habe den Code mal , dort kannst du den als Datei direkt runterladen statt aus dem Forum zu kopieren.


Duddle
 

timinol

Noch nicht viel geschrieben

AW: kleines problem mit javascript

1. firefox 15.0 und IE8
2. weder firebug noch debugbar! nichts, niente, nada, tipote, nothing, rien! ob mit oder ohne haltepunkte im debugmode!
dabei muss ich hinzufügen, dass ich SÄMTLICHE von debugbar angegebenen warnings ausgebessert habe, also nicht der geringste fehler in irgendwelchen nicht geschlossenen, oder falsch oder unvollständig ausgefüllte tags liegen können.

es passiert einfach nichts und ich kann's mir einfach nicht erklären!

ich habe erst beim zweiten blick festgestellt, dass dein eventhandler eigentlich auf [ctrl] reagiert anstatt auf [alt], was aber der prozedur keinen abbruch tut und im grunde [ctrl] besser ist, da es die allererste taste links ist.

ich danke dir, dass du den PEBCAK ausschliesst, aber ich muss zugeben, dass ich und die wissenschaft vor einem rätsel stehen.

ein erneutes downloaden vom angegebenen link brachte nichts, also können wir fehler beim copy/paste ebenfalls ausschliessen.

das obenstehende gilt, sowohl für meinen entwicklungsrechner, als auch für meinen laptop (toshiba), als auch für mein samsung chromebook, was wiederum heisst, dass es auch unter chrome nicht funzt. ???????? mit meinen kubuntu-rechner habe ich's allerdings noch nicht versucht.
 
Zuletzt bearbeitet:

Duddle

Posting-Frequenz: 14µHz

AW: kleines problem mit javascript

Naja, dann kommentiere eben mal den kompletten JavaScript-Code raus und füg im onclick vom img eine Dummy-Funktion ein. Falls die richtig feuert, kommentiere lediglich die click-Funktion ein und versuch die aufzurufen. Falls die kommt, schau dir die Fehler an und entferne die Kommentare exakt so, dass der Fehler beseitigt wird.
Das machst du so lange bis er nicht mehr reagiert oder du den kompletten Code wiederhergestellt hast.

Alternativ kannst du auch im Firebug die Konsole nutzen und dort alle definierten Funktionen nach und nach mit irgendwelchen Parametern aufrufen. Übrigens bietet Firebug ein console-Objekt an, mit dem du wunderbar Ausgaben machen kannst ohne das lästige alert(). Beispiel:
Code:
function click(e, day, slot) {
   console.log(e);
   console.log(d);
   console.log(slot);
// etc
Du musst dann zwar Firebug beim Laden der Seite geöffnet haben (sonst ist console gleich null), aber dafür gibt sie dir nicht nur kryptische toStrings wie alert() das machen würde, sondern die echten Objekte.

Edit: du kannst mich auch im ICQ hinzufügen, falls du sowas hast. Die Nummer steht in meinem .


Duddle
 

timinol

Noch nicht viel geschrieben

AW: kleines problem mit javascript

leider hat der zusatz nichts genutzt, denn ich klicke wie ein wilder und nichts ruft die funktion auf! :(

ICQ habe ich installiert und aktiviert!
 

Duddle

Posting-Frequenz: 14µHz

AW: kleines problem mit javascript

Keine Ahnung was du im ICQ alles lesen konntest, aber der Fehler in der Online-Version ist das onload="init()". init() ist nirgendwo definiert, also bricht er ab und alle anderen Scripte funktionieren nicht mehr.



Duddle
 
Bilder bitte hier hochladen und danach über das Bild-Icon (Direktlink vorher kopieren) platzieren.
Antworten auf deine Fragen:
Neues Thema erstellen

Willkommen auf PSD-Tutorials.de

In unseren Foren vernetzt du dich mit anderen Personen, um dich rund um die Themen Fotografie, Grafik, Gestaltung, Bildbearbeitung und 3D auszutauschen. Außerdem schalten wir für dich regelmäßig kostenlose Inhalte frei. Liebe Grüße senden dir die PSD-Gründer Stefan und Matthias Petri aus Waren an der Müritz. Hier erfährst du mehr über uns.

Stefan und Matthias Petri von PSD-Tutorials.de

Nächster neuer Gratisinhalt

03
Stunden
:
:
25
Minuten
:
:
19
Sekunden

Flatrate für Tutorials, Assets, Vorlagen

Zurzeit aktive Besucher

Statistik des Forums

Themen
118.635
Beiträge
1.538.477
Mitglieder
67.559
Neuestes Mitglied
hanuta
Oben