IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)

Programmation orientée objet par prototype avec jQuery


précédentsommairesuivant

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.

Contenu du fichier JS (poopj7.js)
Sélectionnez
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);
}
Contenu de la page web (poopj7.html)
Sélectionnez
<!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>

précédentsommairesuivant