@@ -7,13 +7,15 @@ import "../../core/jquery-ext";
77export const parser = new Parser ( "checklist" ) ;
88parser . addArgument ( "select" , ".select-all" ) ;
99parser . addArgument ( "deselect" , ".deselect-all" ) ;
10+ parser . addArgument ( "toggle" , ".toggle-all" ) ;
1011
1112export default Base . extend ( {
1213 name : "checklist" ,
1314 trigger : ".pat-checklist" ,
1415 jquery_plugin : true ,
1516 all_selects : [ ] ,
1617 all_deselects : [ ] ,
18+ all_toggles : [ ] ,
1719 all_checkboxes : [ ] ,
1820 all_radios : [ ] ,
1921
@@ -24,7 +26,9 @@ export default Base.extend({
2426 } ,
2527
2628 _init ( ) {
27- this . all_checkboxes = this . el . querySelectorAll ( "input[type=checkbox]" ) ;
29+ this . all_checkboxes = this . el . querySelectorAll (
30+ `input[type=checkbox]:not(${ this . options . toggle } `
31+ ) ;
2832 this . all_radios = this . el . querySelectorAll ( "input[type=radio]" ) ;
2933
3034 this . all_selects = dom . find_scoped ( this . el , this . options . select ) ;
@@ -37,14 +41,19 @@ export default Base.extend({
3741 btn . addEventListener ( "click" , this . deselect_all . bind ( this ) ) ;
3842 }
3943
44+ this . all_toggles = dom . find_scoped ( this . el , this . options . toggle ) ;
45+ for ( const btn of this . all_toggles ) {
46+ btn . addEventListener ( "click" , this . toggle_all . bind ( this ) ) ;
47+ }
48+
4049 // update select/deselect button status
4150 this . el . addEventListener ( "change" , this . _handler_change . bind ( this ) ) ;
42- this . change_buttons ( ) ;
51+ this . change_buttons_and_toggles ( ) ;
4352 this . change_checked ( ) ;
4453 } ,
4554
4655 _handler_change ( ) {
47- utils . debounce ( ( ) => this . change_buttons ( ) , 50 ) ( ) ;
56+ utils . debounce ( ( ) => this . change_buttons_and_toggles ( ) , 50 ) ( ) ;
4857 utils . debounce ( ( ) => this . change_checked ( ) , 50 ) ( ) ;
4958 } ,
5059
@@ -65,7 +74,7 @@ export default Base.extend({
6574 let res ;
6675 let parent = el . parentNode ;
6776 while ( parent ) {
68- res = parent . querySelectorAll ( sel ) ;
77+ res = parent . querySelectorAll ( ` ${ sel } :not( ${ this . options . toggle } )` ) ;
6978 if ( res . length || parent === this . el ) {
7079 // return if results were found or we reached the pattern top
7180 return res ;
@@ -84,7 +93,7 @@ export default Base.extend({
8493 return chkbxs ;
8594 } ,
8695
87- change_buttons ( ) {
96+ change_buttons_and_toggles ( ) {
8897 let chkbxs ;
8998 for ( const btn of this . all_selects ) {
9099 chkbxs = this . find_checkboxes ( btn , "input[type=checkbox]" ) ;
@@ -98,6 +107,12 @@ export default Base.extend({
98107 . map ( ( el ) => el . matches ( ":checked" ) )
99108 . every ( ( it ) => it === false ) ;
100109 }
110+ for ( const tgl of this . all_toggles ) {
111+ chkbxs = this . find_checkboxes ( tgl , "input[type=checkbox]" ) ;
112+ tgl . checked = [ ...chkbxs ]
113+ . map ( ( el ) => el . matches ( ":checked" ) )
114+ . every ( ( it ) => it === true ) ;
115+ }
101116 } ,
102117
103118 select_all ( e ) {
@@ -121,19 +136,28 @@ export default Base.extend({
121136 }
122137 } ,
123138
139+ toggle_all ( e ) {
140+ e . preventDefault ( ) ;
141+ const checked = e . target . checked ;
142+ const chkbxs = this . find_checkboxes ( e . target , "input[type=checkbox]" ) ;
143+ for ( const box of chkbxs ) {
144+ box . checked = checked ;
145+ box . dispatchEvent ( new Event ( "change" , { bubbles : true , cancelable : true } ) ) ;
146+ }
147+ } ,
148+
124149 change_checked ( ) {
125- for ( const it of [ ...this . all_checkboxes ] . concat ( [ ... this . all_radios ] ) ) {
150+ for ( const it of [ ...this . all_checkboxes , ... this . all_radios ] ) {
126151 for ( const label of it . labels ) {
127- label . classList . remove ( "unchecked" ) ;
128- label . classList . remove ( "checked" ) ;
152+ label . classList . remove ( "checked" , "unchecked" ) ;
129153 label . classList . add ( it . checked ? "checked" : "unchecked" ) ;
130154 }
131155 }
132156
133157 for ( const fieldset of dom . querySelectorAllAndMe ( this . el , "fieldset" ) ) {
134158 if (
135159 fieldset . querySelectorAll (
136- " input[type=checkbox]:checked, input[type=radio]:checked"
160+ ` input[type=checkbox]:checked:not( ${ this . options . toggle } ) , input[type=radio]:checked`
137161 ) . length
138162 ) {
139163 fieldset . classList . remove ( "unchecked" ) ;
0 commit comments