src/cm/media/js/lib/yui/yui3.0.0/examples/attribute/attribute-event-speeddate_clean.html
changeset 0 40c8f766c9b8
equal deleted inserted replaced
-1:000000000000 0:40c8f766c9b8
       
     1 
       
     2 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
       
     3 <html>
       
     4 <head>
       
     5 <meta http-equiv="content-type" content="text/html; charset=utf-8">
       
     6 <title>Attribute Event Based Speed Dating</title>
       
     7 
       
     8 <style type="text/css">
       
     9 /*margin and padding on body element
       
    10   can introduce errors in determining
       
    11   element position and are not recommended;
       
    12   we turn them off as a foundation for YUI
       
    13   CSS treatments. */
       
    14 body {
       
    15 	margin:0;
       
    16 	padding:0;
       
    17 }
       
    18 </style>
       
    19 
       
    20 <link type="text/css" rel="stylesheet" href="../../build/cssfonts/fonts-min.css" />
       
    21 <script type="text/javascript" src="../../build/yui/yui-min.js"></script>
       
    22 
       
    23 
       
    24 <!--begin custom header content for this example-->
       
    25 <style type="text/css">
       
    26     #speeddate h1 {
       
    27         font-size: 108%;
       
    28         color:#000;
       
    29         margin-bottom:2em;
       
    30     }
       
    31     
       
    32     #john {
       
    33         margin-bottom:10px;
       
    34     }
       
    35 
       
    36     .interests.disabled, .reconsider.disabled {
       
    37         color:#888;
       
    38     }
       
    39     
       
    40     #john .interest {
       
    41         margin-left:5px;
       
    42     }
       
    43 
       
    44     .sd-nametag {
       
    45         border:1px solid #000;
       
    46         text-align:center;
       
    47         width:25em;
       
    48         margin:20px;
       
    49         
       
    50         background-color:#00f;
       
    51 
       
    52         border-radius: 10px;
       
    53         -webkit-border-radius: 10px;
       
    54         -moz-border-radius: 10px;
       
    55                 
       
    56         box-shadow: 3px 3px 3px #888;
       
    57         -moz-box-shadow: 3px 3px 3px #888;
       
    58         -webkit-box-shadow: 3px 3px 3px #888;
       
    59     }
       
    60 
       
    61     .sd-nametag .sd-hd, 
       
    62     .sd-nametag .sd-ft {
       
    63         padding:5px;
       
    64         text-align:center;
       
    65         font-size:108%;
       
    66         font-weight:900;
       
    67         color:#fff;
       
    68     }
       
    69 
       
    70     .sd-nametag .sd-hd {    
       
    71         border-top-right-radius: 10px;
       
    72         border-top-left-radius: 10px;
       
    73         -moz-border-radius-topright: 10px;
       
    74         -moz-border-radius-topleft: 10px;
       
    75         -webkit-border-top-right-radius: 10px;
       
    76         -webkit-border-top-left-radius: 10px;
       
    77     }
       
    78 
       
    79     .sd-nametag .sd-ft {    
       
    80         border-bottom-right-radius: 10px;
       
    81         border-bottom-left-radius: 10px;
       
    82         -moz-border-radius-bottomright: 10px;
       
    83         -moz-border-radius-bottomleft: 10px;
       
    84         -webkit-border-bottom-right-radius: 10px;
       
    85         -webkit-border-bottom-left-radius: 10px;
       
    86     }
       
    87 
       
    88     .sd-nametag .sd-bd {
       
    89         background-color:#fff;
       
    90         padding:0.5em;
       
    91     }
       
    92 
       
    93     .sd-nametag .sd-bd .sd-name, 
       
    94     .sd-nametag .sd-bd .sd-personality, 
       
    95     .sd-nametag .sd-bd .sd-interests {
       
    96         font-size:108%;
       
    97         font-weight:900;
       
    98         font-family:monospace;
       
    99         text-decoration:underline;
       
   100         color:#00a;
       
   101     }
       
   102 </style>
       
   103 <!--end custom header content for this example-->
       
   104 
       
   105 </head>
       
   106 
       
   107 <body class=" yui-skin-sam">
       
   108 
       
   109 <h1>Attribute Event Based Speed Dating</h1>
       
   110 
       
   111 <div class="exampleIntro">
       
   112 	<p>Attribute change events are one of the key benefits of using attributes to maintain state for your objects, instead of regular object properties.</p>
       
   113 
       
   114 <p>This example refactors the basic <a href="attribute-basic-speeddate.html">"Attribute Based Speed Dating" example</a> to shows how you can listen for attribute change events to tie together your object's internal logic (such as updating the visual presentation of the object), and also to communicate with other objects.</p> 
       
   115 			
       
   116 </div>
       
   117 
       
   118 <!--BEGIN SOURCE CODE FOR EXAMPLE =============================== -->
       
   119 
       
   120 <div id="speeddate">
       
   121 
       
   122     <h1>Communicating With Attribute Events On Speed Dates</h1>
       
   123 
       
   124     <div id="john">
       
   125         <button type="button" class="hi">Hi, I'm John</button>
       
   126 
       
   127         <span class="interests disabled">
       
   128             I enjoy: 
       
   129             <label><input type="checkbox" class="interest" value="Sunsets" disabled="disabled"> Sunsets</label>
       
   130             <label><input type="checkbox" class="interest" value="Reading Specifications" disabled="disabled"> Reading Specifications</label> 
       
   131             <label><input type="checkbox" class="interest" value="Saving Whales" disabled="disabled"> Saving Whales</label>
       
   132             <label><input type="checkbox" class="interest" value="Knitting" disabled="disabled"> Knitting</label>
       
   133         </span>
       
   134         <div class="shirt"></div>
       
   135     </div>
       
   136 
       
   137     <div id="jane">
       
   138         <button type="button" class="hi" disabled="disabled">Hey, I'm Jane</button>
       
   139         <button type="button" class="movingOn" disabled="disabled">I'm Moving On...</button> <span class="reconsider disabled">(unless he likes whales, and avoids knitting <em class="message"></em>)</span>
       
   140         <div class="shirt"></div>
       
   141     </div>
       
   142 </div>
       
   143 
       
   144 <script type="text/javascript">
       
   145 
       
   146 // Get a new instance of YUI and 
       
   147 // load it with the required set of modules
       
   148 
       
   149 YUI({base:"../../build/", timeout: 10000}).use("collection", "event-delegate", "node", "attribute", "substitute", function(Y) {
       
   150 
       
   151     // Setup custom class which we want to add managed attribute support to
       
   152 
       
   153     function SpeedDater(cfg) {
       
   154         // When constructed, setup the initial attributes for the instance, by calling the addAttrs method.
       
   155         var attrs = {
       
   156             name : {
       
   157                 writeOnce:true
       
   158             },
       
   159 
       
   160             personality : {
       
   161                 value:50
       
   162             },
       
   163 
       
   164             available : {
       
   165                 value:true
       
   166             }, 
       
   167 
       
   168             interests : {
       
   169                 value : []
       
   170             }
       
   171         };
       
   172 
       
   173         this.addAttrs(attrs, cfg);
       
   174     }
       
   175 
       
   176     // The HTML template representing the SpeedDater name tag.
       
   177     SpeedDater.NAMETAG = '<div class="sd-nametag"> \
       
   178                             <div class="sd-hd">Hello!</div> \
       
   179                             <div class="sd-bd"> \
       
   180                                 <p>I\'m <span class="sd-name">{name}</span> and my PersonalityQuotientIndex is <span class="sd-personality">{personality}</span></p> \
       
   181                                 <p>I enjoy <span class="sd-interests">{interests}</span>.</p> \
       
   182                             </div> \
       
   183                             <div class="sd-ft sd-availability">{available}</div> \
       
   184                          </div>';
       
   185 
       
   186     // Method used to render the visual representation of a SpeedDater object's state (in this case as a name tag)
       
   187     SpeedDater.prototype.applyNameTag = function(where) {
       
   188 
       
   189         var tokens = {
       
   190             name: this.get("name"),
       
   191             available: (this.get("available")) ? "" : "Sorry, moving on",
       
   192             personality: this.get("personality"),
       
   193             interests: (this.get("interests").length == 0) ? "absolutely nothing" : this.get("interests").join(", ")
       
   194         };
       
   195 
       
   196         this.nameTag = Y.Node.create(Y.substitute(SpeedDater.NAMETAG, tokens));
       
   197         Y.one(where).appendChild(this.nameTag);
       
   198 
       
   199         this.listenForChanges();
       
   200     };
       
   201 
       
   202     // Method used to attach attribute change event listeners, so that the SpeedDater instance 
       
   203     // will react to changes in attribute state, and update what's rendered on the page
       
   204     SpeedDater.prototype.listenForChanges = function() {
       
   205 
       
   206         // Sync up the UI for "available", after the value of the "available" attribute has changed:
       
   207         this.after("availableChange", function(e) {
       
   208             var taken = (e.newVal) ? "" : "Oh, is that the time?";
       
   209             this.nameTag.query(".sd-availability").set("innerHTML", taken);
       
   210         });
       
   211 
       
   212         // Sync up the UI for "name", after the value of the "name" attribute has changed:
       
   213         this.after("nameChange", function(e) {
       
   214             var name = e.newVal;
       
   215             this.nameTag.query(".sd-name").set("innerHTML", name);
       
   216         });
       
   217 
       
   218         // Sync up the UI for "personality", after the value of the "personality" attribute has changed:
       
   219         this.after("personalityChange", function(e) {
       
   220             var personality = e.newVal;
       
   221 
       
   222             var personalityEl = this.nameTag.query(".sd-personality");
       
   223             personalityEl.set("innerHTML", personality);
       
   224 
       
   225             if (personality > 90) {
       
   226                 personalityEl.addClass("sd-max");
       
   227             }
       
   228         });
       
   229 
       
   230         // Sync up the UI for "interests", after the value of the "interests" attribute has changed:
       
   231         this.after("interestsChange", function(e) {
       
   232             var interests = (e.newVal.length == 0) ? "absolutely nothing" : this.get("interests").join(", ");
       
   233             this.nameTag.query(".sd-interests").set("innerHTML", interests);
       
   234         });
       
   235     };
       
   236 
       
   237     // Augment custom class with Attribute
       
   238     Y.augment(SpeedDater, Y.Attribute);
       
   239 
       
   240     var john, jane;
       
   241 
       
   242     Y.on("click", function() {
       
   243 
       
   244         if (!john) {
       
   245 
       
   246             john = new SpeedDater({
       
   247                 name: "John",
       
   248                 personality: 78
       
   249             });
       
   250             john.applyNameTag("#john .shirt");
       
   251 
       
   252             Y.one("#jane .hi").set("disabled", false); 
       
   253         }
       
   254 
       
   255     }, "#john .hi");
       
   256 
       
   257     Y.on("click", function() {
       
   258 
       
   259         if (!jane) {
       
   260 
       
   261             jane = new SpeedDater({
       
   262                 name: "Jane",
       
   263                 personality: 82,
       
   264                 interests: ["Popcorn", "Saving Whales"]
       
   265             });
       
   266             jane.applyNameTag("#jane .shirt");
       
   267 
       
   268             // Update Jane's interests state, after John's interests state changes...
       
   269             john.after("interestsChange", function(e) {
       
   270 
       
   271                 var janesInterests = jane.get("interests"),
       
   272                     johnsInterests = e.newVal,
       
   273 
       
   274                     readingSpecs = "Reading Specifications";
       
   275     
       
   276                 // If it turns out that John enjoys reading specs, then Jane can admit it too...
       
   277                 if (Y.Array.indexOf(johnsInterests, readingSpecs) !== -1) {
       
   278                     if(Y.Array.indexOf(janesInterests, readingSpecs) == -1) {
       
   279                         janesInterests.push(readingSpecs);
       
   280                     }
       
   281                 } else {
       
   282                     janesInterests = Y.Array.reject(janesInterests, function(item){return (item == readingSpecs);});
       
   283                 }
       
   284 
       
   285                 jane.set("interests", janesInterests);
       
   286                 jane.set("available", true);
       
   287 
       
   288                 setMessage("");
       
   289             });
       
   290 
       
   291             // We can also listen before an attribute changes its value, and decide if we want to
       
   292             // allow the state change to occur or not. Invoking e.preventDefault() stops the state from
       
   293             // being updated. 
       
   294 
       
   295             // In this case, Jane can change her mind about making herself unavailable, if John likes 
       
   296             // saving whales, as long as he doesn't dig knitting too.
       
   297  
       
   298             jane.on("availableChange", function(e) {
       
   299                 var johnsInterests = john.get("interests");
       
   300                 var janeAvailable = e.newVal;
       
   301                 if (janeAvailable === false && Y.Array.indexOf(johnsInterests, "Saving Whales") !== -1 &&  Y.Array.indexOf(johnsInterests, "Knitting") == -1 ) {
       
   302                     // Reconsider..
       
   303                     e.preventDefault();
       
   304 
       
   305                     setMessage("... which he does");
       
   306                 };
       
   307             });
       
   308 
       
   309             enableExampleUI();
       
   310         }
       
   311 
       
   312     }, "#jane .hi");
       
   313 
       
   314     Y.on("click", function() { 
       
   315         jane.set("available", false); 
       
   316     }, "#jane .movingOn");
       
   317 
       
   318     // A delegate DOM event listener which will update John's interests, based on the checkbox state, whenever
       
   319     // a checkbox is clicked.
       
   320     Y.on("delegate", function() {
       
   321         var interests = [];
       
   322 
       
   323         Y.Node.all("#john input[type=checkbox].interest").each(function(checkbox) {
       
   324             if (checkbox.get("checked")) {
       
   325                 interests.push(checkbox.get("value"));
       
   326             }
       
   327         });
       
   328         john.set("interests", interests);
       
   329 
       
   330     }, "#john", "click", "input[type=checkbox].interest");
       
   331 
       
   332 
       
   333     // Example helpers...
       
   334     function enableExampleUI() {
       
   335         Y.all("#jane button").set("disabled", false);
       
   336         Y.all("#john button").set("disabled", false);
       
   337         Y.all("#john input").set("disabled", false);
       
   338         Y.one("#john .interests").removeClass("disabled");
       
   339         Y.one("#jane .reconsider").removeClass("disabled");
       
   340     }
       
   341     
       
   342     function setMessage(msg) {
       
   343         Y.one("#jane .message").set("innerHTML", msg);      
       
   344     }
       
   345 
       
   346  });
       
   347 </script>
       
   348 
       
   349 <!--END SOURCE CODE FOR EXAMPLE =============================== -->
       
   350 
       
   351 </body>
       
   352 </html>