├── 2014-11-05-Test_DP_ARIA_grille_de_saisie.ods ├── LICENSE.md ├── README.md ├── composant.js ├── composant_config.js ├── highlight ├── highlight.pack.js └── styles │ └── tomorrow-night-eighties.css ├── images ├── bloc-sgmap-2.jpg ├── checkbox-checked.png ├── checkbox-unchecked.png ├── menu.png ├── next.png ├── prev.png ├── t1-menu.png ├── t1-next.png ├── t1-next_gray.png ├── t1-prev.png └── t1-prev_gray.png ├── index.htm ├── setContent.js └── style.css /2014-11-05-Test_DP_ARIA_grille_de_saisie.ods: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/DISIC/rgaa_composants_javascript/de653f83da2bbea9ce89d70b55e3f581a96d6ea0/2014-11-05-Test_DP_ARIA_grille_de_saisie.ods -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | # Licence 2 | Ces documents sont des documents de l'État français placés sous licence ouverte 1.0 ou ultérieure. Vous trouverez des précisions sur cette licence sur le [blog de la mission etalab](http://www.etalab.gouv.fr/licence-ouverte-open-licence). 3 | 4 | Vous êtes libres de : 5 | * Reproduire, copier, publier et transmettre ces informations ; 6 | * Diffuser et redistribuer ces informations ; 7 | * Adapter, modifier, extraire et transformer ces information, notamment pour créer des informations dérivées ; 8 | * Exploiter ces informations à titre commercial, par exemple en la combinant avec d'autres informations, ou enl'incluant dans votre propre produit ou application. 9 | 10 | Ces libertés s'appliquent sous réserve de mentionner la paternité de l'information d'origine : sa source et la date de sa dernière mise à jour. Le réutilisateur peut notamment s'acquitter de cette condition en indiquant un ou des liens hypertextes (URL) renvoyant vers le présent dépôt et assurant une mention effective de sa paternité. 11 | 12 | Cette mention de paternité ne doit ni conférer un caractère officiel à la réutilisation de ces informations, ni suggérer une quelconque reconnaissance ou caution par le producteur de l'information, ou par toute autre entité publique, du réutilisateur ou de sa réutilisation. 13 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Présentation 2 | 3 | Cette plateforme de tests présente les implémentations des composants ARIA telles qu'elles sont définies par les motifs de conception. 4 | 5 | Elle permet d'établir les restitutions par défaut obtenues avec les technologies d'assistance définies par la base de référence. 6 | 7 | Une grille d'analyse vierge (fichier 2014-11-05-Test_DP_ARIA_grille_de_saisie.ods) est également fournie pour vous permettre de mener vos propres évaluations de composants interactifs. 8 | 9 | Cette bibliothèque est destinée à servir de référence pour les tests de restitution demandés par le test 7.6 du critère 7.1 du référentiel RGAA. Elle n'est pas destinée à être utilisée en production. 10 | 11 | Note 1 : certains enrichissements, nécessaires à une restitution correcte, sont décrits pour chaque composant. Ces enrichissements ne sont pas demandés par les motifs de conception ARIA car ils sont contextuels à la nature et l'utilisation du composant ou de ses contenus. 12 | 13 | Note 2 : les interactions au clavier sont limitées à celles requises par le référentiel. 14 | 15 | ## Liste des composants de cette section : 16 | 17 | - Potentiomètre 18 | - Barre de progression 19 | - Fenêtre de dialogue 20 | - Système d'onglet 21 | - Infobulle 22 | - Bouton d'action 23 | - case à cocher 24 | - barre de menu 25 | - accordéon 26 | - arborescence 27 | - calendrier de saisie 28 | - liste d'autocomplétion 29 | 30 | ## Consultation en ligne : 31 | 32 | Cette plateforme de test est également consultable en ligne à l'adresse suivante http://disic.github.io/rgaa_composants_javascript/ 33 | -------------------------------------------------------------------------------- /composant.js: -------------------------------------------------------------------------------- 1 | /** 2 | ComposantAria 3 | GPL licence 4 | Réalisé par access42.net 5 | **/ 6 | 7 | // @license magnet:?xt=urn:btih:1f739d935676111cfff4b4693e3816e664797050&dn=gpl-3.0.txt GPL-v3-or-Later 8 | 9 | var ComposantAria = ( function setComposantAria(){ 10 | 11 | 'use strict'; 12 | 13 | /* *** 14 | Generic global Object 15 | opnObj : obj ref for trapping focus 16 | *** */ 17 | var global = { 18 | openObj : null 19 | } 20 | /* ======================= 21 | Onload 22 | =======================*/ 23 | window.onload = function setOnload() { 24 | /* 1 *** slider *** */ 25 | var listSlider = document.getElementsByClassName( acsa_config.slider.cursor ); 26 | for ( var i = 0, len = listSlider.length; i < len; i++ ){ 27 | listSlider[i].addEventListener( 'focus', function setListSlider(){ 28 | var slider = new Slider ( this ); 29 | slider.set( this, slider.keys, slider.posOrigin, slider.posMax, slider.unit, slider.step ); 30 | }, false ); 31 | } 32 | /* 2 *** progressbar *** */ 33 | //simulate a progress bar 34 | document.getElementById('Cprogressbar').addEventListener ( 'click', function setprogressbar(){ 35 | var contenerMaj = document.getElementById( 'Zmaj' ); 36 | var obj = document.getElementById( 'Pgbr' ); 37 | var returnTo = document.getElementById( 'actuTitre' ); 38 | var progressBar = new Progressbar( obj, returnTo, contenerMaj ); 39 | }, false ); 40 | /* 3 *** dialog / alertdialog *** */ 41 | var listDial = document.getElementsByClassName( acsa_config.dialog.button ); 42 | for ( var i = 0, len = listDial.length; i < len; i++ ){ 43 | listDial[i].addEventListener( 'click', function setListDial(){ 44 | var obj = document.getElementById( this.getAttribute(acsa_config.dialog.targetId) ); 45 | var returnTo = this; 46 | var dialog = new Dialog ( obj, returnTo ); 47 | }, false ); 48 | } 49 | /* 4 *** tabPanel *** */ 50 | var listTabPanel = document.getElementsByClassName( acsa_config.tabPanel.tabPanel ); 51 | var tabPanel = new Array(); 52 | for ( var i = 0, len = listTabPanel.length; i < len; i++ ){ 53 | tabPanel[i] = new TabPanel( listTabPanel[i] ); 54 | } 55 | /* 5 *** tooltip *** */ 56 | var listTooltip = document.getElementsByClassName( acsa_config.tooltip.tooltip ); 57 | var tooltip = new Array(); 58 | for ( var i = 0, len = listTooltip.length; i < len; i++ ){ 59 | tooltip[i] = new Tooltip( listTooltip[i] ); 60 | } 61 | /* 6 *** Button *** */ 62 | var listButton = document.getElementsByClassName( acsa_config.button.button ); 63 | for ( var i = 0, len = listButton.length; i < len; i++ ){ 64 | listButton[i].addEventListener( 'keydown', function setListButton( event ){ 65 | var key = event.keyCode; 66 | button = new Button ( this, key ); 67 | }, false ); 68 | } 69 | /* 7 *** checkbox *** */ 70 | var listCheckbox = document.getElementsByClassName( acsa_config.checkbox.checkbox ); 71 | var checkbox = new Array(); 72 | for ( var i = 0, len = listCheckbox.length; i < len; i++ ){ 73 | listCheckbox[i].addEventListener( 'keydown', function setListChekbox( event ){ 74 | var key = event.keyCode; 75 | checkbox[i] = new Checkbox ( this, key, event ); 76 | }, false ); 77 | listCheckbox[i].addEventListener( 'click', function setListChekbox(){ 78 | var key = 32; 79 | checkbox[i] = new Checkbox ( this, key ); 80 | }, false ); 81 | } 82 | /* 8 *** menubar *** */ 83 | var listMenuBar = document.getElementsByClassName( acsa_config.menubar.menuBar ); 84 | var menuBar = new Array(); 85 | for ( var i = 0, len = listMenuBar.length; i < len; i++ ){ 86 | menuBar[i] = new Menubar( listMenuBar[i] ); 87 | } 88 | /* 9 *** Accordion *** */ 89 | var listAccordion = document.getElementsByClassName( acsa_config.accordion.accordion ); 90 | var accordion = new Array(); 91 | for ( var i = 0, len = listAccordion.length; i < len; i++ ){ 92 | accordion[i] = new Accordion( listAccordion[i] ); 93 | } 94 | /* 10 *** Tree *** */ 95 | var listTree = document.getElementsByClassName( acsa_config.tree.tree ); 96 | var tree = new Array(); 97 | for ( var i = 0, len = listTree.length; i < len; i++ ){ 98 | tree[i] = new Tree( listTree[i], i ); 99 | } 100 | /* 11 *** Date picker *** */ 101 | var listDatepicker = document.getElementsByClassName( acsa_config.datepicker.datepicker ); 102 | var datepicker = new Array(); 103 | for ( var i = 0, len = listDatepicker.length; i < len; i++ ){ 104 | datepicker[i] = new DatePicker( listDatepicker[i] ); 105 | } 106 | /* 12 *** Autocomplete *** */ 107 | var listAutocomplete = document.getElementsByClassName( acsa_config.autocomplete.autocomplete ); 108 | var autocomplete = new Array(); 109 | for ( var i = 0, len = listAutocomplete.length; i < len; i++ ){ 110 | autocomplete[i] = new Autocomplete( listAutocomplete[i], acsa_config.autocomplete.autocomplete ); 111 | } 112 | //end onload 113 | } 114 | /* ======================= 115 | Components 116 | =======================*/ 117 | /* 118 | *** Component slider *** 119 | -required obj : slider component 120 | example : var slider = new slider ( document.getElementById( 'my-slider' ) ) 121 | Method set 122 | - required obj : slider component (this) 123 | - required keys : key event 124 | - required posOrigin : initial x offsetleft 125 | - required posMax : final right x position 126 | - required unit : value for aria-valuetext 127 | - required step : relative step unit 128 | example : slider.set( this, slider.keys, slider.posOrigin, slider.posMax, slider.unit, slider.step ) 129 | */ 130 | var Slider = function ( obj ){ 131 | this.obj = obj; 132 | //set 133 | this.objWidth = parseInt( window.getComputedStyle(obj.previousSibling.previousSibling).width ); 134 | this.posOrigin = parseInt ( obj.offsetLeft ); 135 | this.posMax = parseInt( window.getComputedStyle(obj.previousSibling.previousSibling).width ) + parseInt ( obj.offsetLeft ); 136 | obj.getAttribute(acsa_config.slider.unit) ? 137 | this.unit = obj.getAttribute(acsa_config.slider.unit) : 138 | this.unit = ''; 139 | this.step = this.objWidth / Number( obj.getAttribute( 'aria-valuemax' ) ); 140 | //Init aria-valuenow 141 | if (obj.getAttribute('aria-valuenow') == null || isNaN(parseInt(obj.getAttribute('aria-valuenow'))))obj.setAttribute( 'aria-valuenow',"0"); 142 | if (parseInt(obj.getAttribute('aria-valuenow'))parseInt(obj.getAttribute( 'aria-valuemax' ))) 145 | obj.setAttribute( 'aria-valuenow', obj.getAttribute( 'aria-valuemax' ) ); 146 | //define object keycodes 147 | this.keys = new keyCodes(); 148 | } 149 | Slider.prototype.set = function ( obj, keys, posOrigin, posMax, unit, step ){ 150 | obj.addEventListener( 'keydown' , function ( event ) { 151 | var posCurrent; 152 | obj.style.left ? posCurrent = parseFloat( obj.style.left ) : posCurrent = posOrigin; 153 | var valCurrent = parseInt( obj.getAttribute( 'aria-valuenow' ) ); 154 | var handled = false; 155 | if( ( event.keyCode === keys.up || event.keyCode === keys.right ) && valCurrent < Number( obj.getAttribute( 'aria-valuemax' ) ) ){ 156 | posCurrent += step; 157 | valCurrent += 1; 158 | handled = true; 159 | } 160 | if( ( event.keyCode === keys.down || event.keyCode === keys.left ) && valCurrent > Number( obj.getAttribute( 'aria-valuemin' ) ) ){ 161 | posCurrent -= step; 162 | valCurrent -= 1; 163 | handled = true; 164 | } 165 | if( event.keyCode === keys.home ) { 166 | posCurrent = posOrigin; 167 | valCurrent = Number( obj.getAttribute( 'aria-valuemin' ) ); 168 | handled = true; 169 | } 170 | if( event.keyCode === keys.end ) { 171 | posCurrent = posMax; 172 | valCurrent = Number( obj.getAttribute( 'aria-valuemax' ) ); 173 | handled = true; 174 | } 175 | maj (this , posCurrent , valCurrent, unit); 176 | if (handled) event.preventDefault(); 177 | }, false ); 178 | function maj ( obj, posCurrent, valCurrent, unit ) { 179 | var txt = document.getElementById('sliderCurrent').firstChild; 180 | obj.style.left = posCurrent + 'px'; 181 | obj.setAttribute( 'aria-valuenow' , valCurrent ); 182 | obj.setAttribute( 'aria-valuetext', valCurrent + ' ' + unit ); 183 | var newTxt = document.createTextNode( valCurrent + ' ' + unit ); 184 | txt.replaceChild( newTxt, txt.firstChild ); 185 | } 186 | } 187 | /* 188 | *** Component progressbar *** 189 | - required obj : the progressbar component 190 | - optionnal returnTo : element focus result 191 | - optionnal contenerMaj : target element for aria-busy value 192 | */ 193 | function Progressbar ( obj, returnTo, contenerMaj ){ 194 | this.obj = obj; 195 | this.returnTo = returnTo; 196 | this.contenerMaj = contenerMaj; 197 | obj.style.display = 'block'; 198 | obj.setAttribute( 'aria-valuenow' , '0' ); 199 | obj.focus(); 200 | var indicator = obj.querySelector( '.' + acsa_config.progressBar.indicator ); 201 | indicator.style.width = 0; 202 | if( contenerMaj ) contenerMaj.setAttribute('aria-busy','true'); 203 | var cpt = 0; 204 | var progress = setInterval( function(){ 205 | if( cpt === 110 ){ 206 | contenerMaj.setAttribute('aria-busy','true'); 207 | contenerMaj.style.display = 'block'; 208 | obj.style.display = 'none'; 209 | //focus on returnTo zone 210 | returnTo.focus(); 211 | //interruption timer 212 | clearInterval(progress); 213 | } 214 | indicator.style.width = cpt + 'px'; 215 | obj.setAttribute( 'aria-valuenow' , cpt ); 216 | obj.setAttribute( 'aria-valuetext' , cpt + '%'); 217 | cpt += 10; 218 | },1000); 219 | } 220 | /* 221 | *** Component dialog / alertdialog *** 222 | - required obj : dialog component 223 | - required returnTo : element focus result 224 | */ 225 | function Dialog( obj, returnTo ) { 226 | this.obj = obj; 227 | this.returnTo = returnTo; 228 | //set 229 | var focusFirst; 230 | obj.getAttribute( acsa_config.dialog.targetFocus ) ? 231 | focusFirst = document.getElementById( obj.getAttribute( acsa_config.dialog.targetFocus ) ) : 232 | focusFirst = obj.querySelector( '.' + acsa_config.dialog.close ); 233 | var closeButton = obj.querySelector( '.' + acsa_config.dialog.close ); 234 | //open 235 | document.getElementById( 'overlay' ).style.display = 'block'; 236 | obj.style.display = 'block'; 237 | focusFirst.focus(); 238 | //Init events 239 | //escape close 240 | document.addEventListener( 'keydown', escClose, false ); 241 | //button close 242 | closeButton.addEventListener( 'click', buttonClose, false ); 243 | //trappingFocus 244 | global.openObj = obj; 245 | document.addEventListener( 'focus', trappingFocus, true ); 246 | //close functions 247 | function escClose( event ){ 248 | var keys = new keyCodes(); 249 | if( event.keyCode === keys.esc ){ 250 | if( document.getElementById('overlay') ) document.getElementById( 'overlay' ).style.display = 'none'; 251 | obj.style.display='none'; 252 | if( returnTo ) returnTo.focus(); 253 | //reset listener and object trapping focus 254 | document.removeEventListener( 'keydown', escClose , false ); 255 | global.openObj = null; 256 | } 257 | } 258 | function buttonClose(){ 259 | if ( document.getElementById('overlay') ) document.getElementById( 'overlay' ).style.display = 'none'; 260 | obj.style.display='none'; 261 | if( returnTo ) returnTo.focus(); 262 | //reset object trapping focus 263 | global.openObj = null 264 | } 265 | } 266 | /* 267 | *** Component tooltip *** 268 | -required obj : element wich call a tooltip referenced by the aria-describedby attribute 269 | */ 270 | function Tooltip( obj ){ 271 | this.obj = obj; 272 | var target = document.getElementById( obj.getAttribute('aria-describedby') ); 273 | if( target ){ 274 | obj.addEventListener('focus', function(){ 275 | target.style.display = 'block'; 276 | document.addEventListener( 'keydown', escClose, false ); 277 | }, false); 278 | obj.addEventListener('blur', function(){ 279 | target.style.display = 'none'; 280 | }, false); 281 | } 282 | function escClose( event ){ 283 | var keys = new keyCodes(); 284 | if( event.keyCode === keys.esc ){ 285 | target.style.display = 'none'; 286 | document.removeEventListener( 'keydown', escClose , false ); 287 | } 288 | } 289 | } 290 | /* 291 | *** Component Button *** 292 | - required obj : button element 293 | - required key : event.keyCode 294 | */ 295 | function Button( obj, key ){ 296 | this.obj = obj; 297 | this.key = key; 298 | // set keyboard enter and spacebar with aria-disabled restriction 299 | if ( !obj.getAttribute( 'aria-disabled' ) || obj.getAttribute( 'aria-disabled' ) != 'true' ) { 300 | var keys = new keyCodes(); 301 | if ( key === keys.space || key === keys.enter ) { 302 | var event = document.createEvent( 'MouseEvent' ); 303 | event.initEvent( 'click', true, true ); 304 | obj.dispatchEvent( event ); 305 | } 306 | } 307 | } 308 | /* 309 | *** Component Tabpanel *** 310 | - required obj : a tabpanel 311 | */ 312 | function TabPanel( obj ) { 313 | this.obj = obj; 314 | var listHead = obj.getElementsByClassName( acsa_config.tabPanel.head ); 315 | var listPan = obj.getElementsByClassName( acsa_config.tabPanel.pan ); 316 | //set event keyboard 317 | for ( var i = 0, len = listHead.length; i < len ; i++){ 318 | listHead[i].addEventListener( 'keydown', function(event) { 319 | openTab(this,event); 320 | }, false); 321 | listHead[i].addEventListener( 'click', function(){ 322 | openTabC(this); 323 | }, false); 324 | } 325 | function openTab(obj, event){ 326 | var current; 327 | var next = 0; 328 | var maxTab=listHead.length; 329 | var keys = new keyCodes(); 330 | if( event.keyCode >= keys.left && event.keyCode <= keys.down ) { 331 | //get active header/pan, set headers/pans inactives 332 | for ( var j = 0; j < maxTab; j++ ){ 333 | if( listHead[j].getAttribute('aria-selected') === 'true' ) current = j; 334 | listHead[j].className = acsa_config.tabPanel.head; 335 | listHead[j].setAttribute ( 'tabindex', '-1'); 336 | listHead[j].setAttribute ( 'aria-selected', 'false'); 337 | var tabTarget = document.getElementById( listHead[j].getAttribute( 'aria-controls' ) ); 338 | tabTarget.className = acsa_config.tabPanel.pan; 339 | tabTarget.setAttribute ( 'aria-expanded', 'false'); 340 | tabTarget.setAttribute ( 'aria-hidden', 'true'); 341 | } 342 | // next event 343 | if ( event.keyCode === keys.right || event.keyCode === keys.down ) { 344 | current + 1 >= maxTab ? next = 0 : next = current + 1; 345 | } 346 | // prev event 347 | else if ( event.keyCode === keys.left || event.keyCode === keys.up ) { 348 | current - 1 < 0 ? next = maxTab - 1 : next = current - 1; 349 | } 350 | //Maj 351 | listPan[next].className = acsa_config.tabPanel.pan+' '+acsa_config.tabPanel.panActive; 352 | listPan[next].setAttribute( 'aria-expanded', 'true' ); 353 | listPan[next].setAttribute( 'aria-hidden', 'false' ); 354 | listHead[next].className = acsa_config.tabPanel.head + ' '+ acsa_config.tabPanel.headActive; 355 | listHead[next].setAttribute( 'tabindex', '0'); 356 | listHead[next].setAttribute( 'aria-selected', 'true'); 357 | listHead[next].focus(); 358 | event.preventDefault(); 359 | } 360 | } 361 | function openTabC(obj) { 362 | var panObj = obj.getAttribute('aria-controls') ; 363 | // Set headers/pans inactives 364 | for( var i= 0, leni = listHead.length; i < leni; i++ ){ 365 | //if(ListHead[i] === obj) tab = i; 366 | listHead[i].className = acsa_config.tabPanel.head; 367 | listHead[i].setAttribute ( 'tabindex', '-1' ); 368 | listHead[i].setAttribute ( 'aria-selected', 'false' ); 369 | listPan[i].className = acsa_config.tabPanel.pan; 370 | listPan[i].setAttribute ( 'aria-expanded', 'false' ); 371 | listPan[i].setAttribute ( 'aria-hidden', 'true' ); 372 | } 373 | //MAJ 374 | obj.className = acsa_config.tabPanel.head + ' ' +acsa_config.tabPanel.headActive; 375 | obj.setAttribute( 'tabindex', '0' ); 376 | obj.setAttribute( 'aria-selected', 'true'); 377 | document.getElementById( obj.getAttribute('aria-controls') ).className = acsa_config.tabPanel.pan + ' ' + acsa_config.tabPanel.panActive; 378 | document.getElementById( obj.getAttribute('aria-controls') ).setAttribute( 'aria-expanded', 'true' ); 379 | document.getElementById( obj.getAttribute('aria-controls') ).setAttribute( 'aria-hidden', 'false' ); 380 | return false; 381 | } 382 | } 383 | /* 384 | *** Component checkbox *** 385 | -required obj : a checkbox 386 | -required key : keyCode 387 | */ 388 | function Checkbox( obj, key ){ 389 | this.obj = obj; 390 | this.key = key; 391 | var keys = new keyCodes(); 392 | if ( key === keys.space ) { 393 | if ( obj.getAttribute( 'aria-checked' ) === 'true' ) { 394 | obj.classList.remove( acsa_config.checkbox.stateTrue ); 395 | obj.classList.add( acsa_config.checkbox.stateFalse ) 396 | obj.setAttribute( 'aria-checked', 'false' ); 397 | } 398 | else if ( obj.getAttribute( 'aria-checked' ) === 'false' ) { 399 | obj.classList.remove( acsa_config.checkbox.stateFalse ); 400 | obj.classList.add( acsa_config.checkbox.stateTrue ) 401 | obj.setAttribute( 'aria-checked', 'true' ); 402 | } 403 | event.preventDefault(); 404 | } 405 | } 406 | /* 407 | *** Component menubar *** 408 | -required obj : a menu 409 | */ 410 | function Menubar( obj ){ 411 | this.obj = obj; 412 | var listMenuItem = obj.getElementsByClassName( acsa_config.menubar.menuItem ); 413 | var menuItemActive = 0; 414 | var menuListCheckbox = new Array(); 415 | var menuCheckbox; 416 | setEventCheckbox(); 417 | for ( var i = 0, len = listMenuItem.length; i < len; i++ ){ 418 | listMenuItem[i].addEventListener('focus', function setMenu( event ){ 419 | menuCheckbox = this.querySelector( 'ul[role=menu]' ); 420 | menuListCheckbox = menuCheckbox.getElementsByClassName( acsa_config.menubar.menuItemCheckbox ); 421 | menuCheckbox.style.display='block'; 422 | setListCheck( menuCheckbox ); 423 | },false); 424 | listMenuItem[i].addEventListener('mouseover', function menuOn( event ){ 425 | menuCheckbox = this.querySelector( 'ul[role=menu]' ); 426 | menuCheckbox.style.display='block'; 427 | },false); 428 | listMenuItem[i].addEventListener('mouseout', function menuOff(){ 429 | menuCheckbox.style.display='none'; 430 | },false); 431 | listMenuItem[i].addEventListener('keydown', function menuNav( event ){ 432 | var key = event.keyCode 433 | var keys = new keyCodes(); 434 | switch( key ){ 435 | case keys.right : 436 | menuCheckbox.style.display='none'; 437 | menuItemActive += 1; 438 | if( menuItemActive === len) menuItemActive = 0; 439 | listMenuItem[menuItemActive].focus(); 440 | event.stopPropagation(); 441 | event.preventDefault(); 442 | break; 443 | case keys.left : 444 | menuCheckbox.style.display='none'; 445 | menuItemActive -= 1; 446 | if( menuItemActive < 0 ) menuItemActive = len-1; 447 | listMenuItem[menuItemActive].focus(); 448 | event.stopPropagation(); 449 | event.preventDefault(); 450 | break; 451 | case keys.down : 452 | setListCheck( menuCheckbox ); 453 | menuCheckbox.style.display='block'; 454 | menuListCheckbox[0].focus(); 455 | event.stopPropagation(); 456 | event.preventDefault(); 457 | break; 458 | case keys.up : 459 | menuCheckbox.style.display='block'; 460 | menuListCheckbox[0].focus(); 461 | event.stopPropagation(); 462 | event.preventDefault(); 463 | break; 464 | case keys.enter : 465 | menuCheckbox.style.display='block'; 466 | menuListCheckbox[0].focus(); 467 | event.stopPropagation(); 468 | event.preventDefault(); 469 | break; 470 | case keys.space : 471 | menuCheckbox.style.display='block'; 472 | menuListCheckbox[0].focus(); 473 | event.stopPropagation(); 474 | event.preventDefault(); 475 | break; 476 | case keys.esc : 477 | menuCheckbox.style.display='none'; 478 | this.focus(); 479 | event.stopPropagation(); 480 | event.preventDefault(); 481 | break; 482 | case keys.tab : 483 | menuCheckbox.style.display='none'; 484 | event.stopPropagation(); 485 | break; 486 | } 487 | }, false); 488 | } 489 | function setListCheck( listTarget ){ 490 | var arrayCheck = new Array(); 491 | arrayCheck = listTarget.getElementsByClassName( acsa_config.menubar.menuItemCheckbox ); 492 | var menuItemCheckboxActive = 0; 493 | for( var i = 0, len = arrayCheck.length; i < len; i++ ){ 494 | arrayCheck[i].addEventListener( 'keydown', function navCheckBoxSet( event ){ 495 | var key = event.keyCode 496 | var keys = new keyCodes(); 497 | if( key === keys.up ){ 498 | menuItemCheckboxActive -= 1; 499 | if( menuItemCheckboxActive < 0 ) menuItemCheckboxActive = len - 1; 500 | arrayCheck[menuItemCheckboxActive].focus(); 501 | event.stopPropagation(); 502 | event.preventDefault(); 503 | } 504 | else if( key === keys.down ){ 505 | menuItemCheckboxActive += 1; 506 | if( menuItemCheckboxActive === len ) menuItemCheckboxActive = 0 507 | arrayCheck[menuItemCheckboxActive].focus(); 508 | event.stopPropagation(); 509 | event.preventDefault(); 510 | } 511 | else if( key === keys.tab ){ 512 | this.parentNode.style.display = 'none'; 513 | } 514 | event.stopPropagation(); 515 | }, false); 516 | } 517 | } 518 | function setCheckbox( obj ){ 519 | console.log( obj ); 520 | if( obj.getAttribute( 'aria-checked' ) === 'false' ){ 521 | console.log( 'true' ); 522 | obj.setAttribute( 'aria-checked', 'true' ); 523 | obj.classList.remove( acsa_config.menubar.stateFalse ); 524 | obj.classList.add( acsa_config.menubar.stateTrue ); 525 | } 526 | else if( obj.getAttribute( 'aria-checked' ) === 'true' ){ 527 | console.log( 'false' ); 528 | obj.setAttribute( 'aria-checked', 'false' ); 529 | obj.classList.remove( acsa_config.menubar.stateTrue ); 530 | obj.classList.add( acsa_config.menubar.stateFalse ); 531 | } 532 | } 533 | function setEventCheckbox(){ 534 | var target = obj.getElementsByClassName( acsa_config.menubar.menuItemCheckbox ); 535 | for( var i = 0, len = target.length; i < len; i++ ){ 536 | target[i].addEventListener('click', function mouseCheckBoxSet( event ){ 537 | setCheckbox( this ); 538 | }, false); 539 | target[i].addEventListener( 'keydown', function navCheckBoxSet( event ){ 540 | var key = event.keyCode 541 | var keys = new keyCodes(); 542 | if ( key === keys.space || key === keys.enter ) { 543 | console.log("key " + key +" enter " + this.getAttribute( 'aria-checked' )); 544 | setCheckbox( this ); 545 | event.stopPropagation(); 546 | event.preventDefault(); 547 | } 548 | else if( key === keys.right ){ 549 | menuItemActive += 1; 550 | this.parentNode.style.display = 'none'; 551 | if( menuItemActive === listMenuItem.length) menuItemActive = 0; 552 | listMenuItem[menuItemActive].focus(); 553 | event.stopPropagation(); 554 | event.preventDefault(); 555 | } 556 | else if( key === keys.left ){ 557 | menuItemActive -= 1; 558 | this.parentNode.style.display = 'none'; 559 | if( menuItemActive < 0 ) menuItemActive = listMenuItem.length - 1; 560 | listMenuItem[menuItemActive].focus(); 561 | event.stopPropagation(); 562 | event.preventDefault(); 563 | } 564 | }, false); 565 | } 566 | } 567 | } 568 | /* 569 | *** Component Accordion *** 570 | - required obj : an accordion 571 | */ 572 | function Accordion( obj ) { 573 | this.obj = obj; 574 | var listHead = obj.getElementsByClassName( acsa_config.accordion.head ); 575 | var listPan = obj.getElementsByClassName( acsa_config.accordion.pan ); 576 | //set event keyboard 577 | for ( var i = 0, len = listHead.length; i < len ; i++){ 578 | listHead[i].addEventListener( 'keydown', function(event) { 579 | openAccordion(this,event); 580 | }, false); 581 | listHead[i].addEventListener( 'click', function(){ 582 | openAccordionC(this); 583 | }, false); 584 | } 585 | function openAccordion(obj, event){ 586 | var current = parseInt( obj.getAttribute('data-n') ); 587 | var maxTab=listHead.length; 588 | var keys = new keyCodes(); 589 | if( event.keyCode >= keys.left && event.keyCode <= keys.down ) { 590 | // next event 591 | if ( event.keyCode === keys.right || event.keyCode === keys.down ) { 592 | current + 1 >= maxTab ? current = 0 : current += 1; 593 | } 594 | // prev event 595 | else if ( event.keyCode === keys.left || event.keyCode === keys.up ) { 596 | current - 1 < 0 ? current = maxTab - 1 : current -= 1; 597 | } 598 | listHead[current].focus(); 599 | event.preventDefault(); 600 | } 601 | else if( event.keyCode === keys.enter || event.keyCode === keys.space) { 602 | if( obj.getAttribute('aria-selected') === 'true'){ 603 | obj.className = acsa_config.accordion.head; 604 | if( current > 0 )obj.setAttribute( 'tabindex', '-1' ); 605 | obj.setAttribute( 'aria-selected', 'false'); 606 | document.getElementById( obj.getAttribute('aria-controls') ).className = acsa_config.accordion.pan; 607 | document.getElementById( obj.getAttribute('aria-controls') ).setAttribute( 'aria-expanded', 'false' ); 608 | document.getElementById( obj.getAttribute('aria-controls') ).setAttribute( 'aria-hidden', 'true' ); 609 | } 610 | else if( obj.getAttribute('aria-selected') === 'false' ){ 611 | obj.className = acsa_config.accordion.head + ' ' +acsa_config.accordion.headActive; 612 | obj.setAttribute( 'tabindex', '0' ); 613 | obj.setAttribute( 'aria-selected', 'true'); 614 | document.getElementById( obj.getAttribute('aria-controls') ).className = acsa_config.accordion.pan + ' ' + acsa_config.accordion.panActive; 615 | document.getElementById( obj.getAttribute('aria-controls') ).setAttribute( 'aria-expanded', 'true' ); 616 | document.getElementById( obj.getAttribute('aria-controls') ).setAttribute( 'aria-hidden', 'false' ); 617 | } 618 | event.preventDefault(); 619 | } 620 | } 621 | function openAccordionC(obj) { 622 | if( obj.getAttribute('aria-selected') === 'true'){ 623 | obj.className = acsa_config.accordion.head; 624 | if( parseInt( obj.getAttribute( 'data-n' ) ) > 0 ) obj.setAttribute( 'tabindex', '-1' ); 625 | obj.setAttribute( 'aria-selected', 'false'); 626 | document.getElementById( obj.getAttribute('aria-controls') ).className = acsa_config.accordion.pan; 627 | document.getElementById( obj.getAttribute('aria-controls') ).setAttribute( 'aria-expanded', 'false' ); 628 | document.getElementById( obj.getAttribute('aria-controls') ).setAttribute( 'aria-hidden', 'true' ); 629 | } 630 | else if( obj.getAttribute('aria-selected') === 'false' ){ 631 | obj.className = acsa_config.accordion.head + ' ' +acsa_config.accordion.headActive; 632 | obj.setAttribute( 'tabindex', '0' ); 633 | obj.setAttribute( 'aria-selected', 'true'); 634 | document.getElementById( obj.getAttribute('aria-controls') ).className = acsa_config.accordion.pan + ' ' + acsa_config.accordion.panActive; 635 | document.getElementById( obj.getAttribute('aria-controls') ).setAttribute( 'aria-expanded', 'true' ); 636 | document.getElementById( obj.getAttribute('aria-controls') ).setAttribute( 'aria-hidden', 'false' ); 637 | } 638 | } 639 | } 640 | /* 641 | *** Component tree *** 642 | - required obj : a tree 643 | - required ndxTree : index of tree list array 644 | */ 645 | function Tree( obj, ndxTree ) { 646 | this.obj = obj; 647 | var currentItem; 648 | var initKeyboardNavigation; 649 | var refTree = 'tree-' + ndxTree; 650 | var listItem = obj.getElementsByClassName( acsa_config.tree.treeitem ); 651 | for(var i = 0, len = listItem.length; i < len; i++ ){ 652 | listItem[i].setAttribute( 'data-n', i ); 653 | listItem[i].setAttribute( 'id', refTree + '-node-' + i ); 654 | listItem[i].setAttribute( 'aria-selected', 'false' ); 655 | } 656 | //Init aria-activedescendant 657 | obj.setAttribute( 'id', refTree ); 658 | obj.setAttribute( 'tabindex', '0' ); 659 | obj.setAttribute( 'aria-activedescendant', refTree + '-node-0'); 660 | var listItemArray = turnObjToArray( listItem); 661 | var listItemReverse = listItemArray.reverse(); 662 | //for(var i = 0, len = listItem.length; i < len; i++ ){ 663 | //listItem[i].addEventListener( 'keydown', function(event) { 664 | //Set keyboard navigation 665 | obj.addEventListener( 'keydown', function(event) { 666 | var keys = new keyCodes(); 667 | var currentTarget = document.getElementById( obj.getAttribute( 'aria-activedescendant') ); 668 | if( event.keyCode === keys.down ){ 669 | var ndx = parseInt( currentTarget.getAttribute( 'data-n' ) ); 670 | currentItem = ndx; 671 | walkDown( ndx ); 672 | event.preventDefault(); 673 | event.stopPropagation(); 674 | } 675 | if( event.keyCode === keys.up ){ 676 | var ndx = listItemReverse.length - parseInt( currentTarget.getAttribute( 'data-n' ) ); 677 | ndx-=1; 678 | currentItem = ndx; 679 | walkUp( ndx ); 680 | event.preventDefault(); 681 | event.stopPropagation(); 682 | } 683 | if( event.keyCode === keys.right ){ 684 | var target = currentTarget.querySelector( 'ul' ); 685 | if( target ){ 686 | target.classList.add( acsa_config.tree.subtreeActive ); 687 | currentTarget.setAttribute( 'aria-expanded', 'true' ); 688 | currentTarget.classList.add( acsa_config.tree.treeitemSubtreeActive ); 689 | var targetLi = target.querySelectorAll('li'); 690 | for(var i = 0, len = targetLi.length; i < len; i++ ){ 691 | targetLi[i].classList.add( acsa_config.tree.treeitemVisible ); 692 | } 693 | } 694 | event.preventDefault(); 695 | event.stopPropagation(); 696 | } 697 | if( event.keyCode === keys.left ){ 698 | if( currentTarget.getAttribute('aria-expanded', 'true' ) ){ 699 | currentTarget.setAttribute( 'aria-expanded', 'false'); 700 | currentTarget.classList.remove( acsa_config.tree.treeitemSubtreeActive ); 701 | var target = currentTarget.querySelector( 'ul' ); 702 | target.classList.remove( acsa_config.tree.subtreeActive ); 703 | var targetLi = target.querySelectorAll('li'); 704 | for(var i = 0, len = targetLi.length; i < len; i++ ){ 705 | targetLi[i].classList.remove( acsa_config.tree.treeitemVisible ); 706 | } 707 | } 708 | else if( currentTarget.parentNode.parentNode.getAttribute('aria-expanded', 'true' ) ){ 709 | //this.parentNode.parentNode.setAttribute('tabindex','0'); 710 | currentTarget.parentNode.parentNode.focus(); 711 | } 712 | event.preventDefault(); 713 | event.stopPropagation(); 714 | } 715 | }, false); 716 | // set aria-selected and mouse event 717 | for(var i = 0, len = listItem.length; i < len; i++ ){ 718 | listItem[i].addEventListener( 'blur', function() { 719 | if( parseInt( this.getAttribute( 'data-n' ) ) > 0 ) { 720 | //this.setAttribute( 'tabindex', '-1'); 721 | this.setAttribute( 'aria-selected', 'false' ); 722 | } 723 | }, false ); 724 | listItem[i].addEventListener( 'click', function() { 725 | if( this.getAttribute('aria-expanded') === 'false'){ 726 | var target = this.querySelector( 'ul' ); 727 | if( target ){ 728 | target.classList.add( acsa_config.tree.subtreeActive ); 729 | this.setAttribute( 'aria-expanded', 'true' ); 730 | this.classList.add( acsa_config.tree.treeitemSubtreeActive ); 731 | var targetLi = target.querySelectorAll('li'); 732 | for(var i = 0, len = targetLi.length; i < len; i++ ){ 733 | targetLi[i].classList.add( acsa_config.tree.treeitemVisible ); 734 | } 735 | } 736 | } 737 | else if( this.getAttribute('aria-expanded') === 'true'){ 738 | this.setAttribute( 'aria-expanded', 'false'); 739 | this.classList.remove( acsa_config.tree.treeitemSubtreeActive ); 740 | var target = this.querySelector( 'ul' ); 741 | target.classList.remove( acsa_config.tree.subtreeActive ); 742 | var targetLi = target.querySelectorAll('li'); 743 | for(var i = 0, len = targetLi.length; i < len; i++ ){ 744 | targetLi[i].classList.remove( acsa_config.tree.treeitemVisible ); 745 | } 746 | } 747 | }, false ); 748 | } 749 | function walkDown( ndx ){ 750 | listItem[currentItem].setAttribute( 'aria-selected', 'false' ); 751 | for(var i = ndx, len = listItem.length; i < len; i++ ){ 752 | currentItem += 1; 753 | if( listItem[i].getAttribute( 'aria-expanded' ) === 'false'){ 754 | var subGroup = listItem[i].getElementsByClassName( acsa_config.tree.treeitem ); 755 | currentItem += subGroup.length; 756 | i = len; 757 | } 758 | i = len; 759 | } 760 | if( initKeyboardNavigation ){ 761 | if( listItem[currentItem] ) { 762 | //listItem[currentItem].setAttribute( 'tabindex', '0' ); 763 | listItem[currentItem].focus(); 764 | obj.setAttribute( 'aria-activedescendant', listItem[currentItem].getAttribute( 'id' ) ); 765 | listItem[currentItem].setAttribute( 'aria-selected', 'true' ); 766 | } 767 | } 768 | else{ 769 | listItem[0].focus(); 770 | obj.setAttribute( 'aria-activedescendant', listItem[0].getAttribute( 'id' ) ); 771 | listItem[0].setAttribute( 'aria-selected', 'true' ); 772 | initKeyboardNavigation = true; 773 | } 774 | } 775 | function walkUp( ndx ){ 776 | listItem[currentItem].setAttribute( 'aria-selected', 'false' ); 777 | for(var i = ndx, len = listItemReverse.length; i < len; i++ ){ 778 | currentItem += 1; 779 | if( listItemReverse[currentItem] && listItemReverse[currentItem].classList.contains( acsa_config.tree.treeitemVisible ) ) i = len; 780 | } 781 | if( listItemReverse[currentItem] ) { 782 | //listItemReverse[currentItem].setAttribute( 'tabindex', '0' ); 783 | listItemReverse[currentItem].focus(); 784 | obj.setAttribute( 'aria-activedescendant', listItemReverse[currentItem].getAttribute( 'id' ) ); 785 | listItemReverse[currentItem].setAttribute( 'aria-selected', 'true' ); 786 | } 787 | } 788 | function turnObjToArray(obj) { 789 | return [].map.call(obj, function(element) { 790 | return element; 791 | }) 792 | }; 793 | } 794 | /* 795 | *** Component date picker *** 796 | - required obj : a date picker 797 | */ 798 | function DatePicker( obj ) { 799 | this.obj = obj; 800 | var txtDayRef, txtMonthRef, firstDayInMonth; 801 | // array gridcell 802 | var listDay = obj.querySelectorAll( 'td' ); 803 | // init 804 | setCalendar(); 805 | // events prev/next month/year 806 | var target = obj.querySelector( '.'+acsa_config.datepicker.datepickerPrev ); 807 | target.addEventListener( 'click', function(){ 808 | resetCalendar( 'prev' ); 809 | // set tabindex '0' on first day of month ( default focus mode for keyboard ) 810 | if( listDay[firstDayInMonth] ) listDay[firstDayInMonth].firstChild.setAttribute( 'tabindex', '0' ); 811 | }, false); 812 | var target = obj.querySelector( '.'+acsa_config.datepicker.datepickerNext ); 813 | target.addEventListener( 'click', function(){ 814 | resetCalendar( 'next' ); 815 | // set tabindex '0' on first day of month ( default focus mode for keyboard ) 816 | if( listDay[firstDayInMonth] ) listDay[firstDayInMonth].firstChild.setAttribute( 'tabindex', '0' ); 817 | }, false); 818 | function setCalendar( month, year ){ 819 | //init 820 | var nbDays; 821 | var monthRef = [31,28,31,30,31,30,31,31,30,31,30,31]; 822 | var monthTxt = ['Janvier','Fevrier','Mars','Avril','Mai','Juin','Juillet','Aout','Septembre','Octobre','Novembre','Decembre']; 823 | var dayNameTxt = ['Dimanche', 'lundi', 'mardi', 'mercredi', 'jeudi', 'vendredi', 'samedi'] 824 | //default 825 | if( !month && !year ){ 826 | month = new Date().getMonth(); 827 | year = new Date().getFullYear(); 828 | var now = new Date().getDate(); 829 | } 830 | firstDayInMonth = new Date( year, month, 1 ).getDay(); 831 | nbDays = monthRef[ month ]; 832 | if( month === 1 && year % 4 === 0 ) nbDays = monthRef[1] + 1; 833 | // set header 834 | var newHeader = document.createTextNode( monthTxt[ month ] + " " + year ); 835 | var header = obj.querySelector( '.' + acsa_config.datepicker.head ); 836 | header.appendChild( newHeader ); 837 | header.setAttribute('data-month', month); 838 | header.setAttribute('data-year', year); 839 | header.setAttribute('data-begin', firstDayInMonth); 840 | header.setAttribute('data-end', nbDays); 841 | // init day index 842 | var txtDay = 0; 843 | //populate gridcell 844 | for( var i = 0, len = listDay.length + firstDayInMonth; i < len; i++){ 845 | if( i >= firstDayInMonth && txtDay < nbDays ){ 846 | txtDay += 1; 847 | var dayNameRef = new Date( year, month, txtDay).getDay(); 848 | //console.log( dayNameRef ); 849 | var dayName = dayNameTxt[ dayNameRef ]; 850 | var newSpanDayName = document.createElement( 'span' ); 851 | var newNDayName = document.createTextNode( dayName ); 852 | newSpanDayName.appendChild( newNDayName ) 853 | newSpanDayName.classList.add( acsa_config.datepicker.dayName ); 854 | var newSpan = document.createElement( 'span' ); 855 | var newNDay = document.createTextNode( txtDay ); 856 | newSpan.appendChild( newSpanDayName ); 857 | newSpan.appendChild( newNDay ); 858 | // set input data format 859 | ( txtDay < 10 ) ? txtDayRef = '0' + txtDay : txtDayRef = txtDay; 860 | var monthReal = month + 1; 861 | ( monthReal < 10 ) ? txtMonthRef = '0' + monthReal : txtMonthRef = monthReal; 862 | var newDateTxt = txtDayRef + '/' + txtMonthRef + '/' + year; 863 | // set span date and aria-selected 864 | newSpan.setAttribute('data-date', newDateTxt ); 865 | newSpan.setAttribute('aria-selected', 'false' ); 866 | // set gridcell index 867 | newSpan.setAttribute('data-n', i ); 868 | // set today focus in init mode 869 | if( txtDay === now ) { 870 | newSpan.classList.add( acsa_config.datepicker.today); 871 | newSpan.setAttribute( 'tabindex', '0' ); 872 | // reset prev/next tabindex to allow today focus in init mode 873 | var prev = obj.querySelector( '.' + acsa_config.datepicker.datepickerPrev ); 874 | prev.setAttribute( 'tabindex', '-1' ); 875 | var next = obj.querySelector( '.' + acsa_config.datepicker.datepickerNext ); 876 | next.setAttribute( 'tabindex', '-1' ); 877 | // add special event to set prev/next button tabindex to allow to catch it 878 | newSpan.addEventListener( 'focus', function(){ 879 | prev.setAttribute( 'tabindex', '0' ); 880 | next.setAttribute( 'tabindex', '0'); 881 | }, false); 882 | } 883 | // span date listener to update input (mouse mode ) 884 | newSpan.addEventListener( 'click', function(){ 885 | var input = obj.querySelector( 'table' ).getAttribute('data-input'); 886 | document.getElementById( input ).value = this.getAttribute( 'data-date' ); 887 | resetGridCell(); 888 | this.setAttribute( 'tabindex', '0'); 889 | this.setAttribute( 'aria-selected','true' ); 890 | }, false); 891 | // span date listener( keyboard mode ) 892 | newSpan.addEventListener( 'keydown', function( event ){ 893 | var keys = new keyCodes(); 894 | if( event.keyCode === keys.enter || event.keyCode === keys.space ){ 895 | var input = obj.querySelector( 'table' ).getAttribute('data-input'); 896 | document.getElementById( input ).value = this.getAttribute( 'data-date' ); 897 | document.getElementById( input ).focus(); 898 | event.preventDefault(); 899 | event.stopPropagation(); 900 | } 901 | if( event.keyCode === keys.right || event.keyCode === keys.down ){ 902 | this.setAttribute('tabindex','-1' ); 903 | this.setAttribute('aria-selected','false'); 904 | var gotoGridCell = 1; 905 | if( event.keyCode === keys.down ) gotoGridCell = 7; 906 | var newGridcell = parseInt( this.getAttribute('data-n') ) + gotoGridCell; 907 | var begin = parseInt(obj.querySelector( '.' + acsa_config.datepicker.head ).getAttribute( 'data-begin' ) ); 908 | var end = parseInt(obj.querySelector( '.' + acsa_config.datepicker.head ).getAttribute( 'data-end' ) ); 909 | if( newGridcell - begin >= end ){ 910 | resetCalendar( 'next' ); 911 | listDay[firstDayInMonth].firstChild.setAttribute( 'tabindex', '0' ); 912 | listDay[firstDayInMonth].firstChild.focus(); 913 | listDay[firstDayInMonth].firstChild.setAttribute('aria-selected','true'); 914 | 915 | } 916 | else{ 917 | listDay[newGridcell].firstChild.setAttribute('tabindex','0'); 918 | listDay[newGridcell].firstChild.focus(); 919 | listDay[newGridcell].firstChild.setAttribute('aria-selected','true'); 920 | } 921 | event.preventDefault(); 922 | event.stopPropagation(); 923 | } 924 | if( event.keyCode === keys.left || event.keyCode === keys.up ){ 925 | this.setAttribute('tabindex','-1' ); 926 | this.setAttribute('aria-selected','false'); 927 | var gotoGridCell = 1; 928 | if( event.keyCode === keys.up ) gotoGridCell = 7; 929 | var newGridcell = parseInt( this.getAttribute('data-n') ) - gotoGridCell; 930 | var begin = parseInt(obj.querySelector( '.' + acsa_config.datepicker.head ).getAttribute( 'data-begin' ) ); 931 | var end = parseInt(obj.querySelector( '.' + acsa_config.datepicker.head ).getAttribute( 'data-end' ) ); 932 | if( newGridcell - begin < 0 ){ 933 | resetCalendar( 'prev', true ); 934 | } 935 | else{ 936 | listDay[newGridcell].firstChild.setAttribute('tabindex','0'); 937 | listDay[newGridcell].firstChild.focus(); 938 | listDay[newGridcell].firstChild.setAttribute('aria-selected','true'); 939 | } 940 | event.preventDefault(); 941 | event.stopPropagation(); 942 | } 943 | }, false); 944 | // append date 945 | listDay[i].appendChild( newSpan ); 946 | //listDay[i].appendChild( newSpanDayName ); 947 | } 948 | } 949 | } 950 | function resetCalendar( mode, lastDay ){ 951 | var header = obj.querySelector( '.' + acsa_config.datepicker.head ); 952 | var newMonth = parseInt( header.getAttribute( 'data-month' ) ); 953 | var newYear = parseInt( header.getAttribute( 'data-year' ) ); 954 | if( mode === 'prev') newMonth -= 1; 955 | if( mode === 'next') newMonth +=1; 956 | if( newMonth < 0 ){ 957 | newMonth = 11; 958 | newYear -= 1; 959 | } 960 | if( newMonth > 11) { 961 | newMonth = 0; 962 | newYear += 1; 963 | } 964 | //reset values 965 | header.removeChild( header.firstChild ); 966 | // reset gridcell 967 | for( var i = 0, len = listDay.length; i < len; i++){ 968 | if( listDay[i].firstChild ) listDay[i].removeChild( listDay[i].firstChild ); 969 | } 970 | // populate 971 | setCalendar( newMonth, newYear ); 972 | // last day focus for prev keyboard mode 973 | if( lastDay ){ 974 | var begin = parseInt(obj.querySelector( '.' + acsa_config.datepicker.head ).getAttribute( 'data-begin' ) ); 975 | var end = parseInt(obj.querySelector( '.' + acsa_config.datepicker.head ).getAttribute( 'data-end' ) ); 976 | var lastDayRef = begin + end -1; 977 | listDay[lastDayRef].firstChild.setAttribute( 'tabindex', '0' ); 978 | listDay[lastDayRef].firstChild.focus(); 979 | listDay[lastDayRef].firstChild.setAttribute('aria-selected','true'); 980 | } 981 | // reset today highlight if necessary 982 | var monthRef = new Date().getMonth(); 983 | var yearRef = new Date().getFullYear(); 984 | var monthCtrl = parseInt(obj.querySelector( '.' + acsa_config.datepicker.head ).getAttribute( 'data-month' ) ); 985 | var yearCtrl = parseInt(obj.querySelector( '.' + acsa_config.datepicker.head ).getAttribute( 'data-year' ) ); 986 | var begin = parseInt(obj.querySelector( '.' + acsa_config.datepicker.head ).getAttribute( 'data-begin' ) ); 987 | if( monthRef === monthCtrl && yearRef === yearCtrl){ 988 | var now = new Date().getDate(); 989 | var target = now + begin - 1; 990 | listDay[target].firstChild.classList.add( acsa_config.datepicker.today); 991 | } 992 | } 993 | //reset gridcell in mouse mode 994 | function resetGridCell(){ 995 | for( var i = 0, len = listDay.length; i < len; i++){ 996 | if( listDay[i].firstChild ){ 997 | listDay[i].firstChild.setAttribute('tabindex','-1'); 998 | listDay[i].firstChild.setAttribute('aria-selected','false'); 999 | } 1000 | } 1001 | } 1002 | } 1003 | /* 1004 | *** Component autocomplete *** 1005 | - required obj : an autocomplete 1006 | - required type : list or inline 1007 | */ 1008 | function Autocomplete(obj){ 1009 | this.obj = obj; 1010 | //setup 1011 | var type = obj.getAttribute('aria-autocomplete'); 1012 | var type = obj.querySelector( 'input' ).getAttribute('aria-autocomplete'); 1013 | var listOption = obj.querySelectorAll('li'); 1014 | var listBox = obj.querySelector( '.'+acsa_config.autocomplete.listBox ); 1015 | // generic index 1016 | var ndx = 0; 1017 | // patch role application to controle unespected key direction bug 1018 | obj.setAttribute('role','application'); 1019 | obj.setAttribute('tabdindex','-1'); 1020 | switch( type ){ 1021 | case 'list': 1022 | var targetTextBox = obj.querySelector( '.' + acsa_config.autocomplete.textboxList ); 1023 | var idRef = targetTextBox.getAttribute( 'id' ); 1024 | // flags for typed letter search in open list 1025 | var firstSearchOption; 1026 | var findOption; 1027 | // set readonly and autocomplete 1028 | targetTextBox.setAttribute('readonly','true'); 1029 | targetTextBox.setAttribute('autocomplete','off'); 1030 | // setup default value 1031 | targetTextBox.setAttribute('data-start', idRef + '-0'); 1032 | targetTextBox.setAttribute('value',listOption[0].getAttribute( 'data-value' ) ); 1033 | // event on button open/close 1034 | var target = obj.querySelector( '.'+ acsa_config.autocomplete.openClose ); 1035 | // setup default button values 1036 | var txt = document.createTextNode( acsa_config.autocomplete.openCloseTxtClosed ); 1037 | target.querySelector('.' + acsa_config.autocomplete.openCloseTxtOffscreen ).appendChild( txt,target.firstChild ); 1038 | target.addEventListener( 'click', function(){ 1039 | openCloseListBox( this ); 1040 | }, false ); 1041 | // event textbox keyboard mode 1042 | targetTextBox.addEventListener('keydown', function( event ){ 1043 | var keys = new keyCodes(); 1044 | if( event.keyCode === keys.esc ){ 1045 | closeListBox(); 1046 | } 1047 | else if( event.keyCode === keys.down || event.keyCode === keys.right ){ 1048 | ndx += 1; 1049 | if( listBox.classList.contains( acsa_config.autocomplete.listBoxOpen ) ) { 1050 | lastOption(); 1051 | listOption[ndx].setAttribute( 'tabindex','0' ); 1052 | listOption[ndx].focus(); 1053 | } 1054 | if( ndx < listOption.length ){ 1055 | this.setAttribute('value', listOption[ndx].getAttribute( 'data-value' ) ); 1056 | this.setAttribute('data-start', listOption[ndx].getAttribute( 'id' ) ); 1057 | } 1058 | else{ 1059 | ndx = listOption.length; 1060 | } 1061 | event.preventDefault(); 1062 | event.stopPropagation(); 1063 | } 1064 | else if( event.keyCode === keys.up || event.keyCode === keys.left ){ 1065 | ndx -= 1; 1066 | if( listBox.classList.contains( acsa_config.autocomplete.listBoxOpen ) ) { 1067 | lastOption(); 1068 | listOption[ndx].setAttribute( 'tabindex','0' ); 1069 | listOption[ndx].focus(); 1070 | } 1071 | if( ndx >= 0){ 1072 | this.setAttribute('value', listOption[ndx].getAttribute( 'data-value' ) ); 1073 | this.setAttribute('data-start', listOption[ndx].getAttribute( 'id' ) ); 1074 | } 1075 | else{ 1076 | ndx = 0; 1077 | } 1078 | event.preventDefault(); 1079 | event.stopPropagation(); 1080 | } 1081 | }, false ); 1082 | break; 1083 | case 'inline': 1084 | var targetTextBox = obj.querySelector( '.'+acsa_config.autocomplete.textboxInline ); 1085 | var idRef = targetTextBox.getAttribute( 'id' ); 1086 | // set default values 1087 | targetTextBox.setAttribute('data-start', idRef + '-0'); 1088 | targetTextBox.setAttribute('value',listOption[0].getAttribute( 'data-value' ) ); 1089 | // flags for typed string search in open list 1090 | var firstSearchOption; 1091 | var lastSearchOption; 1092 | var findOption; 1093 | var startSelect; 1094 | //flag for first focus on textbox and init keydown 1095 | var searchActive = false; 1096 | var initKeyDown = false; 1097 | // event onchange on textbox 1098 | targetTextBox.addEventListener('keyup', function( event ){ 1099 | var keys = new keyCodes(); 1100 | if( event.keyCode === keys.esc ){ 1101 | closeListBox(); 1102 | } 1103 | else if( event.keyCode === keys.down ){ 1104 | listOption[ndx].classList.remove( acsa_config.autocomplete.listOptionOn ); 1105 | ndx += 1; 1106 | var ndxExtract = this.getAttribute('data-end').lastIndexOf('-'); 1107 | var ndxEnd = parseInt( this.getAttribute( 'data-end' ).substring( ndxExtract + 1 ) ); 1108 | var ndxExtract = this.getAttribute('data-start').lastIndexOf('-'); 1109 | var ndxBegin = parseInt( this.getAttribute( 'data-start' ).substring( ndxExtract + 1 ) ); 1110 | if( ndx < ndxBegin || ndx > ndxEnd){ 1111 | ndx = ndxBegin; 1112 | } 1113 | if( !initKeyDown ){; 1114 | initKeyDown = true; 1115 | startSelect = this.value.length 1116 | } 1117 | //var ndxExtract = this.getAttribute('data-end').lastIndexOf('-'); 1118 | //var ndxEnd = parseInt( this.getAttribute( 'data-end' ).substring( ndxExtract + 1 ) ); 1119 | if( ndx <= ndxEnd ){ 1120 | this.setAttribute('value', listOption[ndx].getAttribute( 'data-value' ) ); 1121 | listOption[ndx].classList.add( acsa_config.autocomplete.listOptionOn ); 1122 | this.select(); 1123 | if( listBox.classList.contains( acsa_config.autocomplete.listBoxOpen ) ){ 1124 | var endSelect = listOption[ndx].getAttribute( 'data-value' ).length; 1125 | this.value = listOption[ndx].getAttribute( 'data-value' ); 1126 | this.setSelectionRange( startSelect, endSelect ); 1127 | } 1128 | } 1129 | else{ 1130 | ndx = listOption.length; 1131 | } 1132 | event.preventDefault(); 1133 | event.stopPropagation(); 1134 | } 1135 | else if( event.keyCode === keys.up ){ 1136 | listOption[ndx].classList.remove( acsa_config.autocomplete.listOptionOn ); 1137 | ndx -= 1; 1138 | var ndxExtract = this.getAttribute('data-end').lastIndexOf('-'); 1139 | var ndxEnd = parseInt( this.getAttribute( 'data-end' ).substring( ndxExtract + 1 ) ); 1140 | var ndxExtract = this.getAttribute('data-start').lastIndexOf('-'); 1141 | var ndxBegin = parseInt( this.getAttribute( 'data-start' ).substring( ndxExtract + 1 ) ); 1142 | if( ndx < ndxBegin || ndx > ndxEnd){ 1143 | ndx = ndxEnd; 1144 | } 1145 | if( !initKeyDown ){ 1146 | initKeyDown = true; 1147 | startSelect = this.value.length 1148 | } 1149 | if( ndx >= ndxBegin && ndx<= ndxEnd ){ 1150 | this.setAttribute('value', listOption[ndx].getAttribute( 'data-value' ) ); 1151 | listOption[ndx].classList.add( acsa_config.autocomplete.listOptionOn ); 1152 | this.select(); 1153 | if( listBox.classList.contains( acsa_config.autocomplete.listBoxOpen ) ){ 1154 | var endSelect = listOption[ndx].getAttribute( 'data-value' ).length; 1155 | this.value = listOption[ndx].getAttribute( 'data-value' ); 1156 | this.setSelectionRange( startSelect, endSelect ); 1157 | } 1158 | } 1159 | event.preventDefault(); 1160 | event.stopPropagation(); 1161 | } 1162 | else if( event.keyCode === keys.enter ){ 1163 | listBox.classList.remove( acsa_config.autocomplete.listBoxOpen ); 1164 | this.select(); 1165 | } 1166 | else{ 1167 | if( targetTextBox.value.length > 0 ){ 1168 | checkEntry( this, type, targetTextBox.value ); 1169 | initKeyDown = false; 1170 | 1171 | } 1172 | else if( targetTextBox.value.length === 0){ 1173 | resetNdxList(); 1174 | initKeyDown = false; 1175 | } 1176 | } 1177 | // init searchActive 1178 | if( !searchActive ) searchActive = true; 1179 | }, false ); 1180 | //blur closed the option list 1181 | targetTextBox.addEventListener('blur', function(){ 1182 | if( listBox.classList.contains( acsa_config.autocomplete.listBoxOpen ) ) 1183 | listBox.classList.remove( acsa_config.autocomplete.listBoxOpen ); 1184 | targetTextBox.setAttribute('aria-expanded', 'false' ); 1185 | }, false); 1186 | break; 1187 | } 1188 | //set List and option events 1189 | setList(); 1190 | function setList(){ 1191 | for( var i = 0, len = listOption.length; i < len; i++){ 1192 | var idRefTxt = idRef + '-' + i; 1193 | var txt = listOption[i].firstChild.innerText || listOption[i].firstChild.textContent; 1194 | listOption[i].setAttribute('tabindex','-1'); 1195 | listOption[i].setAttribute('id', idRefTxt ); 1196 | listOption[i].setAttribute('data-value', txt ); 1197 | listOption[i].setAttribute('data-n', i ); 1198 | // events mouse mode 1199 | listOption[i].addEventListener('click', function(){ 1200 | targetTextBox.setAttribute('data-start', this.getAttribute('id') ); 1201 | targetTextBox.setAttribute('value', this.getAttribute('data-value') ); 1202 | closeListBox(); 1203 | }, false ); 1204 | // events listOption keyboard mode 1205 | listOption[i].addEventListener( 'keydown', function( event ){ 1206 | var keys = new keyCodes(); 1207 | // set start and end flag for inline mode 1208 | if( type === 'inline' ) { 1209 | var target = targetTextBox.getAttribute('data-start'); 1210 | var lastOptionArray = target.split('-') 1211 | var start = parseInt( lastOptionArray[1] ); 1212 | var target = targetTextBox.getAttribute('data-end'); 1213 | var lastOptionArray = target.split('-') 1214 | var end = parseInt( lastOptionArray[1] ); 1215 | } 1216 | if( this.getAttribute( 'data-n' ) ){ 1217 | ndx = parseInt( this.getAttribute( 'data-n' ) ); 1218 | } 1219 | this.setAttribute( 'tabindex', '-1' ); 1220 | if( event.keyCode === keys.esc ){ 1221 | closeListBox(); 1222 | } 1223 | else if( event.keyCode === keys.up || event.keyCode === keys.left ){ 1224 | if( type === 'inline' ){ 1225 | targetTextBox.setAttribute('value', this.getAttribute('data-value') ); 1226 | } 1227 | ndx -= 1; 1228 | if( type === 'inline' ) { 1229 | ndx += start; 1230 | } 1231 | if( ndx === 0 ) ndx = listOption.length -1; 1232 | if ( type === 'inline' ){ 1233 | if( ndx < start) ndx = end; 1234 | } 1235 | listOption[ndx].setAttribute( 'tabindex', '0' ); 1236 | listOption[ndx].focus(); 1237 | if( type === 'inline' ){ 1238 | targetTextBox.setAttribute('value', this.getAttribute('data-value') ); 1239 | } 1240 | event.preventDefault(); 1241 | event.stopPropagation(); 1242 | } 1243 | else if( event.keyCode === keys.down || event.keyCode === keys.right ){ 1244 | if( type === 'inline' ){ 1245 | targetTextBox.setAttribute('value', this.getAttribute('data-value') ); 1246 | } 1247 | ndx += 1; 1248 | if( type === 'inline' ) { 1249 | ndx += start; 1250 | } 1251 | if( ndx === listOption.length ) ndx = 0; 1252 | if ( type === 'inline' ){ 1253 | if( ndx > end) ndx = start; 1254 | } 1255 | listOption[ndx].setAttribute( 'tabindex', '0' ); 1256 | listOption[ndx].focus(); 1257 | event.preventDefault(); 1258 | event.stopPropagation(); 1259 | } 1260 | if( event.keyCode === keys.enter ){ 1261 | targetTextBox.setAttribute('data-start', this.getAttribute('id') ); 1262 | targetTextBox.setAttribute('value', this.getAttribute('data-value') ); 1263 | closeListBox(); 1264 | event.preventDefault(); 1265 | event.stopPropagation(); 1266 | } 1267 | else if( event.keyCode > 47 && event.keyCode < 122 && listBox.classList.contains( acsa_config.autocomplete.listBoxOpen ) ){ 1268 | checkEntry( this, type, event.keyCode ); 1269 | }; 1270 | }, false ); 1271 | } 1272 | } 1273 | function openCloseListBox( button ){ 1274 | if( button.classList.contains( acsa_config.autocomplete.openCloseOpen ) ){ 1275 | obj.querySelector('.' + acsa_config.autocomplete.textboxList ).setAttribute('aria-expanded', 'false' ); 1276 | listBox.classList.remove( acsa_config.autocomplete.listBoxOpen ); 1277 | button.classList.remove( acsa_config.autocomplete.openCloseOpen ); 1278 | var txt = document.createTextNode( acsa_config.autocomplete.openCloseTxtClosed ); 1279 | var invisible = button.querySelector('.' + acsa_config.autocomplete.openCloseTxtOffscreen ); 1280 | invisible.replaceChild( txt, invisible.firstChild ); 1281 | obj.querySelector( '.' + acsa_config.autocomplete.textboxList ).focus(); 1282 | // reset ndx 1283 | lastOption(); 1284 | } 1285 | else if( button.classList.contains( acsa_config.autocomplete.openClose ) ){ 1286 | obj.querySelector('.' + acsa_config.autocomplete.textboxList ).setAttribute('aria-expanded', 'true' ); 1287 | listBox.classList.add( acsa_config.autocomplete.listBoxOpen ); 1288 | button.classList.add( acsa_config.autocomplete.openCloseOpen ); 1289 | var txt = document.createTextNode( acsa_config.autocomplete.openCloseTxtOpen ); 1290 | var invisible = button.querySelector('.' + acsa_config.autocomplete.openCloseTxtOffscreen ); 1291 | invisible.replaceChild( txt, invisible.firstChild ); 1292 | obj.querySelector( '.' + acsa_config.autocomplete.textboxList ).focus(); 1293 | // reset ndx 1294 | lastOption(); 1295 | } 1296 | // reset firstSearchOption used for search entry 1297 | firstSearchOption = false; 1298 | } 1299 | function closeListBox(){ 1300 | targetTextBox.setAttribute('aria-expanded', 'false' ); 1301 | listBox.classList.remove( acsa_config.autocomplete.listBoxOpen ); 1302 | if( type === 'list' ){ 1303 | obj.querySelector('.' + acsa_config.autocomplete.openClose ).classList.remove( acsa_config.autocomplete.openCloseOpen ); 1304 | var txt = document.createTextNode( acsa_config.autocomplete.openCloseTxtClosed ); 1305 | var invisible = obj.querySelector('.' + acsa_config.autocomplete.openCloseTxtOffscreen ); 1306 | invisible.replaceChild( txt, invisible.firstChild ); 1307 | obj.querySelector( '.' + acsa_config.autocomplete.textboxList ).focus(); 1308 | } 1309 | else if( type === 'inline' ){ 1310 | obj.querySelector( '.' + acsa_config.autocomplete.textboxInline).focus(); 1311 | } 1312 | } 1313 | function lastOption(){ 1314 | var target = targetTextBox.getAttribute('data-start'); 1315 | var lastOptionArray = target.split('-'); 1316 | ndx = parseInt( lastOptionArray[1] ); 1317 | } 1318 | function checkEntry( obj, mode, key ){ 1319 | if( mode === 'list' ){ 1320 | for( var i = 0, len = listOption.length; i < len; i++ ){ 1321 | var txtTest = listOption[i].getAttribute( 'data-value' ); 1322 | var charTest = String.fromCharCode( key ); 1323 | if( txtTest.search( charTest ) != -1 && txtTest.indexOf( charTest) === 0 ){ 1324 | if( !firstSearchOption ) firstSearchOption = listOption[i].getAttribute( 'data-n' ); 1325 | if( i > ndx ){ 1326 | var findOption = i; 1327 | i = listOption.length; 1328 | } 1329 | } 1330 | } 1331 | if( findOption ){ 1332 | obj.setAttribute( 'tabindex', '-1' ); 1333 | listOption[ findOption ].setAttribute( 'tabindex','0' ); 1334 | listOption[ findOption ].focus(); 1335 | } 1336 | else if( firstSearchOption ) { 1337 | var findOption = parseInt( firstSearchOption); 1338 | obj.setAttribute( 'tabindex', '-1' ); 1339 | listOption[ findOption ].setAttribute( 'tabindex','0' ); 1340 | listOption[ findOption ].focus(); 1341 | } 1342 | // reset firstSearchOption 1343 | firstSearchOption = false; 1344 | } 1345 | else if( mode === 'inline' ){ 1346 | resetNdxList(); 1347 | firstSearchOption = false; 1348 | findOption = false; 1349 | searchActive = true; 1350 | var ndxSearchRef = 0; 1351 | for( var i = 0, len = listOption.length; i < len; i++ ){ 1352 | var txtTest = listOption[i].getAttribute( 'data-value' ).toLowerCase(); 1353 | var exprTest = targetTextBox.value.toLowerCase(); 1354 | if( txtTest.search( exprTest ) === 0 ){ 1355 | if( !firstSearchOption ) { 1356 | firstSearchOption = listOption[i].getAttribute( 'id' ); 1357 | } 1358 | listOption[i].setAttribute('style','block'); 1359 | listOption[i].setAttribute('data-n', ndxSearchRef); 1360 | ndxSearchRef += 1; 1361 | lastSearchOption = listOption[i].getAttribute( 'id' ); 1362 | } 1363 | else{ 1364 | listOption[i].setAttribute('style','display:none'); 1365 | listOption[i].setAttribute('data-n','-1'); 1366 | } 1367 | } 1368 | // resynchronize ndx 1369 | if( firstSearchOption ) { 1370 | targetTextBox.setAttribute('data-start', firstSearchOption ); 1371 | targetTextBox.setAttribute('data-end', lastSearchOption ); 1372 | findOption = true; 1373 | targetTextBox.setAttribute('aria-expanded', 'true' ); 1374 | } 1375 | firstSearchOption = false; 1376 | findOption = false 1377 | // open listBox 1378 | if( !listBox.classList.contains( acsa_config.autocomplete.listBoxOpen ) ){ 1379 | listBox.classList.add( acsa_config.autocomplete.listBoxOpen ); 1380 | targetTextBox.setAttribute('aria-expanded', 'true' ); 1381 | } 1382 | } 1383 | } 1384 | function resetNdxList(){ 1385 | for( var i = 0, len = listOption.length; i < len; i++ ){ 1386 | listOption[i].setAttribute('data-n', i ); 1387 | listOption[i].setAttribute('style', 'block' ); 1388 | } 1389 | targetTextBox.setAttribute( 'data-start', idRef + '-0' ); 1390 | targetTextBox.setAttribute( 'data-end', idRef + '-'+listOption.length ); 1391 | if( !listBox.classList.contains( acsa_config.autocomplete.listBoxOpen ) ){ 1392 | listBox.classList.add( acsa_config.autocomplete.listBoxOpen ); 1393 | } 1394 | } 1395 | } 1396 | /* ======================= 1397 | Utilities 1398 | =======================*/ 1399 | /* Generic trapping focus function (based on global.openObj setting) */ 1400 | function trappingFocus( event ){ 1401 | if ( global.openObj && !global.openObj.contains( event.target ) ) { 1402 | event.stopPropagation(); 1403 | global.openObj.focus(); 1404 | } 1405 | } 1406 | /* Generic keyCodes properties names */ 1407 | function keyCodes() { 1408 | this.backspace = 8; 1409 | this.tab = 9; 1410 | this.enter = 13; 1411 | this.esc = 27; 1412 | 1413 | this.space = 32; 1414 | this.pageup = 33; 1415 | this.pagedown = 34; 1416 | this.end = 35; 1417 | this.home = 36; 1418 | 1419 | this.left = 37; 1420 | this.up = 38; 1421 | this.right = 39; 1422 | this.down = 40; 1423 | 1424 | } 1425 | })(); 1426 | 1427 | // @license-endd -------------------------------------------------------------------------------- /composant_config.js: -------------------------------------------------------------------------------- 1 | /** 2 | ComposantAria 3 | GPL licence 4 | Réalisé par access42.net 5 | **/ 6 | 7 | // @license magnet:?xt=urn:btih:1f739d935676111cfff4b4693e3816e664797050&dn=gpl-3.0.txt GPL-v3-or-Later 8 | 9 | /* ======================= 10 | General configuration. 11 | You can customise all values by your owns, please be carrefull to distinguish "class CSS" values and "data-" values. 12 | =======================*/ 13 | var acsa_config = { 14 | /* 15 | *** dialog / alertdialog *** 16 | implementation : 17 | [ Open button ] 18 | - required : dialog.button className value 19 | - required : dialog.targetId data attribute Name (value = targeted dialog id ) 20 | example : 21 | [ Dialog element ] 22 | - optional : dialog.targetFocus attribute Name (value = first focused element within dialog element) 23 | (By default the close button get by dialog.close className value) 24 | example :
25 | [ Close Button ] 26 | - required : dialog.close className value 27 | */ 28 | dialog : { 29 | //CSS 30 | button : 'acsa-dial-button', 31 | close : 'acsa-close', 32 | //data- 33 | targetId : 'data-acsa-target', 34 | targetFocus : 'data-acsa-focus' 35 | }, 36 | /* 37 | *** slider *** 38 | implementation 39 | [cursor element] 40 | - required : slider.cursor className value 41 | - optional : slider.unit attribute name (value = textual value of unit input) 42 | example : 43 | */ 44 | slider : { 45 | //CSS 46 | cursor : 'acsa-cursor-button', 47 | //data- 48 | unit : 'data-acsa-unit' 49 | }, 50 | /* 51 | *** progressbar *** 52 | [indicator element] 53 | -required : progressbar.indicator className value 54 | example :
55 | */ 56 | progressBar : { 57 | //CSS 58 | indicator : 'acsa-progress-indicator' 59 | }, 60 | /* 61 | *** button *** 62 | [button element] 63 | - required : button.button className value 64 | example : 65 | */ 66 | button : { 67 | //CSS 68 | button : 'acsa-button' 69 | }, 70 | /* 71 | *** tabpanel *** 72 | [tabpanel element] 73 | -required : tabPanel.tabPanel main element className value 74 | example :
75 | [tablist element] 76 | -required : for each tab in tablist, tabPanel.head className value 77 | -required : for each tab in tablist, tabPanel.headActive className value for selected tab 78 | example : 79 | [pan list element] 80 | -required : for each pan, tabPanel.pan className value 81 | -required : for each pan, tabPanem.panActive className caluer for selected tab. 82 | example :