VII. « Fonction classe » poopj, un exemple plus élaboré▲
On construit un système du genre MVC :
- M pour les objets du modèle ;
- V pour l'objet responsable de l'affichage des résultats ;
- C pour l'objet qui contrôle le programme.
Table est la « fonction classe » de type V. L'objet instancié affichera la table à la demande, elle contiendra les informations qui lui auront été communiquées par l'objet C.
Pair est une « fonction classe » de type M. L'objet instancié communiquera à l'objet C le résultat de son calcul.
Impair est une autre « fonction classe » de type M. L'objet instancié communiquera à l'objet C le résultat de son calcul.
Total est la « fonction classe » de type C. L'objet instancié jouera le rôle d'initiateur et de contrôleur du programme. Il crée une instance des objets M et de l'objet V.
L'objet C reçoit les résultats envoyés par les objets M, il les traite et envoie le résultat à l'objet V. Lorsque le temps est venu, il demande à l'objet V d'afficher les résultats.
Comme il se doit, les « fonctions classes » poopj sont définies dans un fichier JavaScript indépendant.
try {
/*
* On construit un système type MVC.
* M pour les objets du modèle.
* V pour l'objet responsable de l'affichage des résultats.
* C pour l'objet qui contrôle le programme.
*
* Table est la fonction classe V.
*
* L'objet instancié affichera la table à la demande, elle
* contiendra les informations qui lui auront été communiquées
* par l'objet C.
*/
var Table = $.dvjhClass._create({
_builder: function(){
this.eventName = "tableEvent.Table";
this.th = null;
this.trs = [];
// bonne pratique car jQuery peut modifier this
var self = this;
$(this).bind(self.eventName, self.tableEventHandler);
},
tableEventHandler: function(event){
if (event.dvjh && event.dvjh.length == 1){
if (this.th == null) {
this.th = event.dvjh.p1Name;
}
this.trs.push(event.dvjh.p1Data);
}
return false;
},
print: function(id){
// suppprime une éventuelle table précédente
$("#"+id).find(".tablesorter").remove();
if (this.th != null && this.trs[0] != null){
var self = this;
var t0 = this.trs[0][3];
var tableID = "vue" + t0;
var deltaT = [];
var n = this.trs.length;
deltaT.push(0);
for(var i = 1; i < n; i++){
deltaT.push(this.trs[i][3] - t0);
}
var tdlength = this.th.length;
var trlength = this.trs.length;
var array = ["<table id='" + tableID +
"' class='tablesorter'>"];
var arrayHead = ["<thead><tr>"];
for(var i = 0; i < tdlength; i++) {
arrayHead.push("<th>" + self.th[i] + "</th>");
}
arrayHead.push("<th>Delta T ms</th></tr></thead>");
var arrayFoot = ["<tfoot><tr>"];
for(var i = 0; i < tdlength; i++) {
arrayFoot.push("<th>" + self.th[i] + "</th>");
}
arrayFoot.push("<th>Delta T ms</th></tr></tfoot>");
array.push(arrayHead.join(''), arrayFoot.join(''),
"<tbody>");
for(var j = 0; j < trlength; j++) {
array.push("<tr>");
for(var i = 0; i < tdlength; i++) {
array.push("<td>" + self.trs[j][i] + "</td>");
}
array.push("<td>" + deltaT[j] + "</td></tr>");
}
array.push("</tbody></table>");
$("#"+id).append(array.join(''));
$("#"+tableID).tablesorter({
sortList: [[3,0]],
widgets: ['zebra'],
headers: {
4:{sorter: false}
}
});
} else {
$("#"+id).html("<p>Il n'y a aucune information" +
" à afficher !</p>");
}
},
toString: function(){
return "Table : ";
}
});
/*
* Pair est une fonction classe M.
*
* L'objet instancié communiquera à l'objet C
* le résultat de son calcul.
*/
var Pair = $.dvjhClass._create({
number: 0,
_builder: function(number){
this.number = number || this.number;
},
add: function(obj){
this.number++;
if ((this.number % 2 == 0) && (obj.eventName)){
var objEvent = new $.Event(obj.eventName);
/*
* On adopte la convention suivante :
* event.dvjh.length donne le nombre de params : p1,
* p2, etc.
* event.dvjh.p1Name donne le(s) libellé(s) du param p1
* event.dvjh.p1Data contient la/les donnée(s) du
* param p1.
*/
objEvent.dvjh = {
length: 1,
p1Name: "Pair",
p1Data: this.number
};
$(obj).trigger(objEvent);
}
},
toString: function(){
return "Pair : ";
}
});
/*
* Impair est une fonction classe M.
*
* L'objet instancié communiquera à l'objet C
* le résultat de son calcul.
*/
var Impair = $.dvjhClass._create({
number: 0,
_builder: function(number){
this.number = number || this.number;
},
add:function(obj){
this.number++;
if ((this.number % 2 != 0) && (obj.eventName)){
var objEvent = new $.Event(obj.eventName);
objEvent.dvjh = {
length: 1,
p1Name: "Impair",
p1Data: this.number
};
$(obj).trigger(objEvent);
}
},
toString: function(){
return "Impair : ";
}
});
/*
* Total est la fonction classe C.
*
* L'objet instancié jouera le rôle d'initiateur et de contrôleur
* du programme. Il crée une instance des objets M et de l'objet V.
*
* Il questionne les objets M et stockent leurs
* résultats dans l'objet V. Lorsque le temps est venu
* il demande à l'objet V d'afficher les résultats.
*/
var Total = $.dvjhClass._create({
_builder: function(milliseconds, divID){
this.eventName = "totalEvent.Total";
this.number = 0;
this.source = "";
this.total = 0;
this.timeStamp = 0;
this.output = new Table();
this.pair = new Pair();
this.impair = new Impair();
this.milliseconds = milliseconds || 1000;
var self = this;
$(this).bind(self.eventName, self.totalEventHandler);
var pairInterval = window.setInterval(function(){
self.pair.add(self);
}, 30);
var impairInterval = window.setInterval(function(){
self.impair.add(self);
}, 40);
window.setTimeout(function(){
window.clearInterval(pairInterval);
window.clearInterval(impairInterval);
self.output.print(divID);
}, this.milliseconds);
},
totalEventHandler: function(event){
if (event.dvjh && event.dvjh.length == 1){
this.number = event.dvjh.p1Data;
this.source = event.dvjh.p1Name;
this.total += this.number;
this.timeStamp = event.timeStamp;
if (this.output){
var self = this;
var outputEvent = new $.Event(self.output.eventName);
outputEvent.dvjh = {
length: 1,
p1Name: ["Total", "Nombre", "Source",
"TimeStamp ms"],
p1Data: [this.total, this.number, this.source,
this.timeStamp]
};
$(this.output).trigger(outputEvent);
}
}
return false;
},
toString: function(){
return "Total : ";
}
});
}
catch(err){
alert(err);
}<!doctype html>
<html lang="fr">
<head>
<meta charset="utf-8">
<meta name="Author" content="Daniel Hagnoul">
<title>POOPJ</title>
<style>
/* BASE */
body {
background-color:#dcdcdc;
color:#000000;
font-family:sans-serif;
font-size:medium;
font-style:normal;
font-weight:normal;
line-height:normal;
letter-spacing:normal;
}
h1,h2,h3,h4,h5 {
font-family:serif;
}
div,p,h1,h2,h3,h4,h5,h6,ul,ol,dl,form,table,img {
margin:0px;
padding:0px;
}
p {
padding:6px;
}
ul,ol,dl {
list-style:none;
padding-left:6px;
padding-top:6px;
}
li {
padding-bottom:6px;
}
/* dvjh */
h1 {
text-align:center;
font-style:italic;
text-shadow: 4px 4px 4px #bbbbbb;
}
h2 {
text-align:center;
}
div#conteneur {
width:95%;
height:auto;
margin:12px auto;
padding:6px;
background-color:#FFFFFF;
color:#000000;
border:1px solid #666666;
}
div#affiche {
clear:both;
margin:40px;
padding:6px;
border:1px solid #999999;
background-color:#FFFFFF;
color:#000000;
}
/* TABLE */
table.dvjhTable {
width:95%;
margin:12px auto;
/* table-layout = problèmes */
empty-cells:show;
border-collapse:collapse;
border-spacing:0px;
border-width:1px;
border-style:solid;
border-color:#666666;
background-color:#CDCDCD;
color:#000000;
font-size:0.9em;
font-style:normal;
font-weight:normal;
line-height:normal;
letter-spacing:normal;
}
table.dvjhTable caption {
caption-side:top;
padding-top:6px;
padding-bottom:6px;
text-align:center;
font-size:1.2em;
font-style:oblique;
font-weight:bold;
line-height:normal;
letter-spacing:0.2em;
color:#000000;
}
table.dvjhTable thead tr th {
border-width:1px;
border-style:solid;
border-color:#999999;
background-color: #e6eeee;
color:#000000;
padding:6px;
text-align:center;
font-size:0.9em;
font-style:normal;
font-weight:bold;
line-height:1.8em;
letter-spacing:normal;
}
table.dvjhTable tfoot tr th {
border-width:1px;
border-style:solid;
border-color:#999999;
background-color: #e6eeee;
color:#000000;
padding:6px;
text-align:left;
font-size:0.9em;
font-style:italic;
font-weight:normal;
line-height:1.8em;
letter-spacing:normal;
}
table.dvjhTable thead tr .header {
background-image:url(../images/bg.gif);
background-repeat: no-repeat;
background-position:right;
cursor: pointer;
min-width:80px;
}
table.dvjhTable thead tr .headerSortUp {
background-image: url(../images/asc.gif);
}
table.dvjhTable thead tr .headerSortDown {
background-image: url(../images/desc.gif);
}
table.dvjhTable thead tr .headerSortDown, table.dvjhTable thead tr .headerSortUp {
background-color: #8dbdd8;
}
table.dvjhTable tbody th {
border-width:1px;
border-style:solid;
border-color:#999999;
background-color:#e6eeee;
color:#000000;
vertical-align:middle;
padding:6px;
text-align:left;
font-size:0.9em;
font-style:normal;
font-weight:normal;
line-height:1.2em;
letter-spacing:normal;
}
table.dvjhTable tbody td {
border-width:1px;
border-style:solid;
border-color:#999999;
background-color:#FFFFFF;
color:#000000;
vertical-align:middle;
padding:6px;
text-align:left;
font-size:0.9em;
font-style:normal;
font-weight:normal;
line-height:1.2em;
letter-spacing:normal;
}
table.dvjhTable tbody tr.dvjhTableOdd td {
background-color:#FDFFD9;
}
/* TEST */
</style>
<script charset="utf-8"
src="../lib/jqueryui/js/jquery-1.4.2.min.js"></script>
<script charset="utf-8" src="../lib/dvjh/Tablesorter.js"></script>
<script charset="utf-8" src="../lib/dvjh/poopj.js"></script>
<script charset="utf-8" src="poopj7.js"></script>
<script>
$(function(){
try {
/*
* L'utilisateur peut appeler plusieurs fois le programme,
*, mais il ne doit y avoir qu'un objet contrôleur.
*
* L'utilisateur crée et initialise l'objet contrôleur en
* cliquant sur le bouton Afficher.
*
* L'objet contrôleur se charge du bon fonctionnement du
* programme et de l'affichage des résultats.
*
* L'affichage des résultats nécessite le plugin
* jquery.tablesorter.min.js
*/
var objTotal = null;
$("#btn").click(function(){
if (objTotal != null) {
objTotal = null;
}
objTotal = new Total($("#choix").val(), "affiche");
});
}
catch(err){
alert(err);
}
});
</script>
</head>
<body>
<h1>POOPJ</h1>
<div id="conteneur">
<select id="choix">
<option value="1000" selected="selected">1000 ms</option>
<option value="1500">1500 ms</option>
<option value="2000">2000 ms</option>
<option value="2500">2500 ms</option>
<option value="3000">3000 ms</option>
<option value="3500">3500 ms</option>
<option value="4000">4000 ms</option>
</select>
<button id="btn" type="button">Afficher</button>
<div id="affiche"></div>
</div>
</body>
</html>

