11548 sujets

JavaScript, DOM et API Web HTML5

Bonjour a toutes et tous,

J'ai voulu créer une sorte de calendrier virtuel en utilisant jQuery (avec scrollLeft pour faire défiler horizontalement) et là pas de problème.

En voulant créer le contenu du calendrier sous forme d'un tableau (liste des jours : 365) et mettre une propriété css width:40px; pour chaque td représentant un jour, le résultat n'est pas conforme : chaque td (donc jour) ne possède pas une largeur de 40px...

Voici mon code :


var MONTHS = new Array ({"id" : '01', "name" : "Janvier", "nbDays" : 31},
				    {"id" : '02', "name" : "Février", "nbDays" : 28},
			             ...
			             {"id" : '12', "name" : "Décembre", "nbDays" : 31});

var DAYS = new Array ('Lun.', 'Mar.', 'Mer.', 'Jeu.', 'Ven.', 'Sam.', 'Dim.');
var FIRST_DAY = 4;
var day_flag = FIRST_DAY;

var table = '<table><tr class="months">';

for(i in MONTHS)
{
	table += '<td colspan="'+MONTHS[i].nbDays+'">'+MONTHS[i].name+'</td>';
}

table += '</tr><tr class="days">';

for(i in MONTHS)
{
	for (var j=1 ; j < 10 ; j++)
        {
        	table += '<td id="2010-'+MONTHS[i].id+'-0'+j+'"'+((day_flag > 4) ? ' class="WE"' : '')+'>'+j+'<span>'+DAYS[day_flag]+'</span></td>';
                day_flag = (day_flag + 1 ) % 7;
        }
        for (var j=10 ; j <= MONTHS[i].nbDays ; j++)
        {
                table += '<td width="40px" id="2010-'+MONTHS[i].id+'-'+j+'"'+((day_flag > 4) ? ' class="WE"' : '')+'>'+j+'<span>'+DAYS[day_flag]+'</span></td>';
                day_flag = (day_flag + 1 ) % 7;
        }
}

table += '</tr></table>';
    
$('#calendar').append(table);

[/i]
Voila, je ne sais pas pourquoi, mais passé un certaine limite WIDTH pour chaque td cela coince ...

Si quelqu'un sais le pourquoi du comment, ou à une meilleure (plus performante et/ou moins lourde) solution que l'utilisation d'un tableau contenant 365 cellules cela m'intéresse beaucoup.

Merci [/i][/i][/i][/i]
Modifié par LucSW (21 Aug 2010 - 13:33)
Salut,

soit tu fait ça en css (ce qui serait plus logique) du genre :
#calendar td {
	width: 40px;
}
soit tu utilises l'attribut width du TD mais dans ce cas tu mets juste width="40" (sans le px).


Personnellement j'aurais plutôt fait ça en php pour ne générer le calendrier qu'une fois par an :
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />
<title>Test Calendrier</title>
<style type="text/css">
table {
	border-collapse: collapse;
}
td, th, span {
	text-align: center;
}
td, th {
	border: 1px solid #060;
}
th {
	background: #0c0;
}
span {
	font-size: .7em;;
	display: block;
}
.WE {
	background: #fc0;
}
</style>
</head>
<body>
<div id="calendar"> 
<?php
$forcer_update = false; // passer à true pour que le tableau soit toujours généré (sans lecture du fichier éventuel)
$annee = intval(date("Y"));
$file = 'calendar_'.$annee.'.txt'; 
if(!$forcer_update && file_exists($file)) { 
	readfile($file); 
} else { 
	setlocale(LC_TIME, 'french', 'fr_FR'); 
	$nb_jours = intval(date("z", strtotime("31 December ".$annee))) + 1; // 365 ou 366 (année bissextile) 
	$mois = array();
	$largeur_td = 40;
	$width_table = $largeur_td * $nb_jours;
	$TR_days = ''; 
	for($jour = 1; $jour <= $nb_jours; $jour++) { 
		$date = strftime("%Y-%m %d %B %a", mktime(0, 0, 0, 1, $jour, $annee)); // on décompose chaque date 
		$date = explode(" ", $date); 
		$we = ($date[3] == 'sam.' || $date[3] == 'dim.') ? ' class="WE"' : ''; 
		$TR_days .= "\t\t".'<td width="'.$largeur_td.'" id="j_'.$date[0].'-'.$date[1].'"'.$we.'>&nbsp;'.intval($date[1]).'&nbsp;<span>'.ucfirst($date[3]).'</span></td>'."\n"; 
		$mois[ucfirst($date[2])] = intval($date[1]); 
	} 
	$TR_months = ''; 
	foreach($mois as $month=>$max_day) { 
		$TR_months .= "\t\t".'<th colspan="'.$max_day.'">'.$month."</th>\n"; 
	} 
	$TR_months .= ''; 
	$table = '<table style="table-layout: fixed; width: '.$width_table.'px">'."\n\t".'<tr class="months">'."\n".$TR_months."\t</tr>\n\t".'<tr class="days">'."\n".$TR_days."\t</tr>\n</table>\n"; 
	$fp = fopen($file, 'w'); 
	fwrite($fp, $table); 
	fclose($fp); 
	echo $table;
} 
?> 
</div>
</body>
</html>
Au passage le nom d'un id ne doit pas commencer par un chiffre.

Edit: modifié pour rajouter table-layout: fixed et width sur l'élément TABLE.
Modifié par Heyoan (21 Aug 2010 - 13:06)
Bonjour,

J'avais déjà essayé juste width="40" et aussi en utilisant css avec width:40px; mais rien ne voulais marcher c'est pourquoi je suis venu demander de l'aide ici ...

Sinon j'avais aussi essayé en le faisant en PHP mais cela ne marchais pas non plus ...

J'ai quand même essayer ton code (qui marche très bien sur le principe) mais tu n'as pas du faire attention mais la propriété width:40px; n'est pas respeceté, on reste bloquer à 24px; : c'est cela qui me pose problème depuis le début.

Après un peu de test, je n'arrive pas à avoir chaque td avec width:40px à partir de 270 jours (269x40 = 10760px de largeur maximum sur une page web ???)

Donc voilà, merci Heyoan pour le code PHP que je vais utiliser, mais le problème n'est pas résolu,
Je pense que c'est parce qu'il y a trop d'éléments, ce qui dépasse une largeur maximum d'une page et qui fait beugué ...

HELP !!!

Merci
Modifié par LucSW (21 Aug 2010 - 13:03)
Il suffit de rajouter le style suivant à l'élément TABLE :
$nb_jours = intval(date("z", strtotime("31 December ".$annee))) + 1; // 365 ou 366 (année bissextile) 
$largeur_td = 40;
$width_table = $largeur_td * $nb_jours;
...
$table = '<table style="table-layout: fixed; width: '.$width_table.'px">'."\n\t".'<tr class="months">'."\n".$TR_months."\t</tr>\n\t".'<tr class="days">'."\n".$TR_days."\t</tr>\n</table>\n"; 


Edit: il y aura quelques ajustements à faire selon que tu mettes ou non un border aux TD (cf. le modèle de boîte).
Modifié par Heyoan (21 Aug 2010 - 13:14)