1<!doctype html> 2<!-- 3@license 4Copyright (c) 2015 The Polymer Project Authors. All rights reserved. 5This code may only be used under the BSD style license found at http://polymer.github.io/LICENSE.txt 6The complete set of authors may be found at http://polymer.github.io/AUTHORS.txt 7The complete set of contributors may be found at http://polymer.github.io/CONTRIBUTORS.txt 8Code distributed by Google as part of the polymer project is also 9subject to an additional IP rights grant found at http://polymer.github.io/PATENTS.txt 10--> 11 12<html> 13<head> 14 15 <title>iron-selector-multi</title> 16 <meta charset="utf-8"> 17 <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0"> 18 19 <script src="../../webcomponentsjs/webcomponents-lite.js"></script> 20 <script src="../../web-component-tester/browser.js"></script> 21 <script src="../../test-fixture/test-fixture-mocha.js"></script> 22 23 <link rel="import" href="../../test-fixture/test-fixture.html"> 24 <link rel="import" href="../../iron-test-helpers/iron-test-helpers.html"> 25 <link rel="import" href="../iron-selector.html"> 26 27 <style> 28 .iron-selected { 29 background: #ccc; 30 } 31 </style> 32 33</head> 34<body> 35 36 <test-fixture id="test"> 37 <template> 38 <iron-selector multi> 39 <div>Item 0</div> 40 <div>Item 1</div> 41 <div>Item 2</div> 42 <div>Item 3</div> 43 <div>Item 4</div> 44 </iron-selector> 45 </template> 46 </test-fixture> 47 48 <test-fixture id="valueById"> 49 <template> 50 <iron-selector multi attr-for-selected="id"> 51 <div id="item0">Item 0</div> 52 <div id="item1">Item 1</div> 53 <div id="item2">Item 2</div> 54 <div id="item3">Item 3</div> 55 <div id="item4">Item 4</div> 56 </iron-selector> 57 </template> 58 </test-fixture> 59 60 <!-- 61 NOTE(cdata): Enable test-fixture when polymer/polymer#2495 is resolved 62 --> 63 <!--<test-fixture id="repeatedItems"> 64 <template>--> 65 <iron-selector multi id="repeatedItems"> 66 <template is="dom-repeat" items='["foo", "bar", "baz"]'> 67 <div>[[item]]</div> 68 </template> 69 <div>vim</div> 70 </iron-selector> 71 <!--</template> 72 </test-fixture>--> 73 74 <script> 75 76 suite('multi', function() { 77 78 var s; 79 80 setup(function () { 81 s = fixture('test'); 82 t = Polymer.dom(s).querySelector('[is="dom-repeat"]'); 83 }); 84 85 test('honors the multi attribute', function() { 86 assert.isTrue(s.multi); 87 }); 88 89 test('has sane defaults', function() { 90 assert.equal(s.selectedValues, undefined); 91 assert.equal(s.selectedClass, 'iron-selected'); 92 assert.equal(s.items.length, 5); 93 }); 94 95 test('set multi-selection via selected property', function() { 96 // set selectedValues 97 s.selectedValues = [0, 2]; 98 // check selected class 99 assert.isTrue(s.children[0].classList.contains('iron-selected')); 100 assert.isTrue(s.children[2].classList.contains('iron-selected')); 101 // check selectedItems 102 assert.equal(s.selectedItems.length, 2); 103 assert.equal(s.selectedItems[0], s.children[0]); 104 assert.equal(s.selectedItems[1], s.children[2]); 105 }); 106 107 test('set multi-selection via tap', function() { 108 // set selectedValues 109 MockInteractions.tap(s.children[0]); 110 MockInteractions.tap(s.children[2]); 111 // check selected class 112 assert.isTrue(s.children[0].classList.contains('iron-selected')); 113 assert.isTrue(s.children[2].classList.contains('iron-selected')); 114 // check selectedItems 115 assert.equal(s.selectedItems.length, 2); 116 assert.equal(s.selectedItems[0], s.children[0]); 117 assert.equal(s.selectedItems[1], s.children[2]); 118 }); 119 120 test('fire iron-select/deselect events when selectedValues changes', function() { 121 // setup listener for iron-select/deselect events 122 var items = [s.children[0], s.children[1], s.children[2]], 123 selectEventCounters = [0, 0, 0], 124 deselectEventCounters = [0, 0, 0]; 125 126 s.addEventListener('iron-select', function(e) { 127 selectEventCounters[items.indexOf(e.detail.item)]++; 128 }); 129 s.addEventListener('iron-deselect', function(e) { 130 deselectEventCounters[items.indexOf(e.detail.item)]++; 131 }); 132 133 // programatically select values 0 and 1 (both fire select) 134 s.selectedValues = [0, 1]; 135 136 // programatically select values 1 and 2 (2 fires select, 0 fires deselect) 137 s.selectedValues = [1, 2]; 138 139 // programatically deselect all values (1 and 2 fire deselect) 140 s.selectedValues = []; 141 142 // check events 143 assert.equal(selectEventCounters[0], 1); 144 assert.equal(deselectEventCounters[0], 1); 145 assert.equal(selectEventCounters[1], 1); 146 assert.equal(deselectEventCounters[1], 1); 147 assert.equal(selectEventCounters[2], 1); 148 assert.equal(deselectEventCounters[2], 1); 149 }); 150 151 test('fire iron-select/deselect events when selectedValues is modified', function() { 152 // setup listener for iron-select/deselect events 153 var items = [s.children[0], s.children[1], s.children[2]], 154 selectEventCounters = [0, 0, 0], 155 deselectEventCounters = [0, 0, 0]; 156 157 s.addEventListener('iron-select', function(e) { 158 selectEventCounters[items.indexOf(e.detail.item)]++; 159 }); 160 s.addEventListener('iron-deselect', function(e) { 161 deselectEventCounters[items.indexOf(e.detail.item)]++; 162 }); 163 164 s.selectedValues = [] 165 166 // programatically select value 0 167 s.push('selectedValues', 0, 1); 168 169 // programatically deselect value 0 170 s.shift('selectedValues'); 171 172 // programatically select value 2 173 s.push('selectedValues', 2); 174 175 // programatically deselect value 1 176 s.shift('selectedValues'); 177 178 assert.equal(selectEventCounters[0], 1); 179 assert.equal(deselectEventCounters[0], 1); 180 assert.equal(selectEventCounters[1], 1); 181 assert.equal(deselectEventCounters[1], 1); 182 assert.equal(selectEventCounters[2], 1); 183 assert.equal(deselectEventCounters[2], 0); 184 }); 185 186 test('fire iron-select/deselect events when toggling items', function() { 187 // setup listener for iron-select/deselect events 188 var items = [s.children[0], s.children[1], s.children[2]], 189 selectEventCounters = [0, 0, 0], 190 deselectEventCounters = [0, 0, 0]; 191 192 s.addEventListener('iron-select', function(e) { 193 selectEventCounters[items.indexOf(e.detail.item)]++; 194 }); 195 s.addEventListener('iron-deselect', function(e) { 196 deselectEventCounters[items.indexOf(e.detail.item)]++; 197 }); 198 199 // tap to select items 0 and 1 (both fire select) 200 MockInteractions.tap(items[0]); 201 MockInteractions.tap(items[1]); 202 203 // programatically select values 1 and 2 (2 fires select, 0 fires deselect) 204 s.selectedValues = [1, 2]; 205 206 // tap to deselect items 1 and 2 (both fire deselect) 207 MockInteractions.tap(items[1]); 208 MockInteractions.tap(items[2]); 209 210 // check events 211 assert.equal(selectEventCounters[0], 1); 212 assert.equal(deselectEventCounters[0], 1); 213 assert.equal(selectEventCounters[1], 1); 214 assert.equal(deselectEventCounters[1], 1); 215 assert.equal(selectEventCounters[2], 1); 216 assert.equal(deselectEventCounters[2], 1); 217 }); 218 219 test('toggle iron-selected class when toggling items selection', function() { 220 // setup listener for iron-item-select/deselect events 221 var item0 = s.children[0], item1 = s.children[1]; 222 223 assert.isFalse(item0.classList.contains('iron-selected')); 224 assert.isFalse(item1.classList.contains('iron-selected')); 225 226 // tap to select item 0 (add iron-selected class) 227 MockInteractions.tap(item0); 228 229 assert.isTrue(item0.classList.contains('iron-selected')); 230 assert.isFalse(item1.classList.contains('iron-selected')); 231 232 // tap to select item 1 (add iron-selected class) 233 MockInteractions.tap(item1); 234 235 assert.isTrue(item0.classList.contains('iron-selected')); 236 assert.isTrue(item1.classList.contains('iron-selected')); 237 238 // tap to deselect item 1 (remove iron-selected class) 239 MockInteractions.tap(item1); 240 241 assert.isTrue(item0.classList.contains('iron-selected')); 242 assert.isFalse(item1.classList.contains('iron-selected')); 243 244 // programatically select both values (1 add iron-selected class) 245 s.selectedValues = [0, 1]; 246 247 assert.isTrue(item0.classList.contains('iron-selected')); 248 assert.isTrue(item1.classList.contains('iron-selected')); 249 250 // programatically deselect all values (both removes iron-selected class) 251 s.selectedValues = []; 252 253 assert.isFalse(item0.classList.contains('iron-selected')); 254 assert.isFalse(item1.classList.contains('iron-selected')); 255 }); 256 257 test('fires selected-values-changed when selection changes', function() { 258 var selectedValuesChangedEventCounter = 0; 259 260 s.addEventListener('selected-values-changed', function(e) { 261 selectedValuesChangedEventCounter++; 262 }); 263 264 MockInteractions.tap(Polymer.dom(s).children[0]); 265 MockInteractions.tap(Polymer.dom(s).children[0]); 266 MockInteractions.tap(Polymer.dom(s).children[0]); 267 268 expect(selectedValuesChangedEventCounter); 269 }); 270 271 test('selects from items created by dom-repeat', function(done) { 272 var selectEventCounter = 0; 273 var firstChild; 274 275 s = document.querySelector('#repeatedItems'); 276 s.addEventListener('iron-select', function(e) { 277 selectEventCounter++; 278 }); 279 280 // NOTE(cdata): I guess `dom-repeat` doesn't stamp synchronously.. 281 Polymer.Base.async(function() { 282 firstChild = Polymer.dom(s).querySelector('div'); 283 MockInteractions.tap(firstChild); 284 285 assert.equal(s.selectedItems[0].textContent, 'foo'); 286 done(); 287 }); 288 }); 289 290 test('updates selection when dom changes', function(done) { 291 var selectEventCounter = 0; 292 293 s = fixture('test'); 294 295 Polymer.Base.async(function() { 296 var firstChild = Polymer.dom(s).querySelector(':first-child'); 297 var lastChild = Polymer.dom(s).querySelector(':last-child'); 298 299 MockInteractions.tap(firstChild); 300 MockInteractions.tap(lastChild); 301 302 expect(s.selectedItems.length).to.be.equal(2); 303 304 Polymer.dom(s).removeChild(lastChild); 305 306 Polymer.dom.flush(); 307 308 expect(s.selectedItems.length).to.be.equal(1); 309 expect(s.selectedItems[0]).to.be.equal(firstChild); 310 311 done(); 312 }); 313 314 }); 315 316 suite('`select()` and `selectIndex()`', function() { 317 var selector; 318 319 setup(function() { 320 selector = fixture('valueById'); 321 }); 322 323 test('`select()` selects an item with the given value', function() { 324 selector.select('item1'); 325 assert.equal(selector.selectedValues.length, 1); 326 assert.equal(selector.selectedValues.indexOf('item1'), 0); 327 328 selector.select('item3'); 329 assert.equal(selector.selectedValues.length, 2); 330 assert.isTrue(selector.selectedValues.indexOf('item3') >= 0); 331 332 selector.select('item2'); 333 assert.equal(selector.selectedValues.length, 3); 334 assert.isTrue(selector.selectedValues.indexOf('item2') >= 0); 335 }); 336 337 test('`selectIndex()` selects an item with the given index', function() { 338 selector.selectIndex(1); 339 assert.equal(selector.selectedValues.length, 1); 340 assert.isTrue(selector.selectedValues.indexOf('item1') >= 0); 341 assert.equal(selector.selectedItems.length, 1); 342 assert.isTrue(selector.selectedItems.indexOf(selector.items[1]) >= 0); 343 344 selector.selectIndex(3); 345 assert.equal(selector.selectedValues.length, 2); 346 assert.isTrue(selector.selectedValues.indexOf('item3') >= 0); 347 assert.equal(selector.selectedItems.length, 2); 348 assert.isTrue(selector.selectedItems.indexOf(selector.items[3]) >= 0); 349 350 selector.selectIndex(0); 351 assert.equal(selector.selectedValues.length, 3); 352 assert.isTrue(selector.selectedValues.indexOf('item0') >= 0); 353 assert.equal(selector.selectedItems.length, 3); 354 assert.isTrue(selector.selectedItems.indexOf(selector.items[0]) >= 0); 355 }); 356 }); 357 358 /* test('toggle multi from true to false', function() { 359 // set selected 360 s.selected = [0, 2]; 361 var first = s.selected[0]; 362 // set mutli to false, so to make it single-selection 363 s.multi = false; 364 // selected should not be an array 365 assert.isNotArray(s.selected); 366 // selected should be the first value from the old array 367 assert.equal(s.selected, first); 368 }); */ 369 370 }); 371 372 </script> 373 374</body> 375</html> 376