55 < meta charset ="UTF-8 ">
66 < title > Trrack Demo</ title >
77 < script src ="https://d3js.org/d3.v7.js "> </ script >
8+ < style >
9+ .limit-control {
10+ display : inline-block;
11+ position : relative;
12+ }
13+
14+ .limit-tooltip {
15+ background : # 1f2933 ;
16+ border-radius : 4px ;
17+ bottom : calc (100% + 8px );
18+ color : # ffffff ;
19+ font : 12 px/1.4 Arial, Helvetica, sans-serif;
20+ left : 50% ;
21+ opacity : 0 ;
22+ padding : 6px 8px ;
23+ pointer-events : none;
24+ position : absolute;
25+ transform : translateX (-50% );
26+ visibility : hidden;
27+ white-space : nowrap;
28+ z-index : 1 ;
29+ }
830
31+ .limit-control : hover .limit-tooltip ,
32+ .limit-control : focus .limit-tooltip ,
33+ .limit-control : focus-within .limit-tooltip {
34+ opacity : 1 ;
35+ visibility : visible;
36+ }
37+
38+ .limit-tooltip [hidden ] {
39+ display : none;
40+ }
41+ </ style >
942</ head >
1043
1144< body >
1750 < div class ="non-btns ">
1851 < div id ="dots ">
1952 < div >
20- < button id ="add "> Add</ button >
21- < button id ="rem "> Remove</ button >
53+ < span class ="limit-control " id ="add-control ">
54+ < button id ="add "> Add</ button >
55+ < span class ="limit-tooltip " id ="add-limit-tooltip " role ="tooltip " hidden > Maximum of 20 dots reached.</ span >
56+ </ span >
57+ < span class ="limit-control " id ="remove-control ">
58+ < button id ="rem "> Remove</ button >
59+ < span class ="limit-tooltip " id ="remove-limit-tooltip " role ="tooltip " hidden > Minimum of 0 dots reached.</ span >
60+ </ span >
2261 </ div >
2362 </ div >
2463 </ div >
3271
3372 // Task id should match the task's answer id in the config file
3473 const taskId = 'circlesCount' ;
74+ const maxDots = 20 ;
3575
3676 function dots ( initialDots ) {
3777 const height = 50 ;
110150 // Render the dots on screen using state from trrack
111151 const dotActions = dots ( trrack . getState ( ) . dots ) ;
112152
113- // Register a listener to update the dot chart based on trrack updates.
114- trrack . currentChange ( ( ) => {
153+ const addButton = document . getElementById ( "add" ) ;
154+ const removeButton = document . getElementById ( "rem" ) ;
155+ const addControl = document . getElementById ( "add-control" ) ;
156+ const removeControl = document . getElementById ( "remove-control" ) ;
157+ const addTooltip = document . getElementById ( "add-limit-tooltip" ) ;
158+ const removeTooltip = document . getElementById ( "remove-limit-tooltip" ) ;
159+
160+ function setLimitState ( button , control , tooltip , disabled ) {
161+ button . disabled = disabled ;
162+ tooltip . hidden = ! disabled ;
163+
164+ if ( disabled ) {
165+ button . setAttribute ( "aria-describedby" , tooltip . id ) ;
166+ control . tabIndex = 0 ;
167+ } else {
168+ button . removeAttribute ( "aria-describedby" ) ;
169+ control . removeAttribute ( "tabindex" ) ;
170+ }
171+ }
172+
173+ function renderState ( currentDots ) {
174+ dotActions . update ( currentDots ) ;
175+ setLimitState ( addButton , addControl , addTooltip , currentDots . length >= maxDots ) ;
176+ setLimitState ( removeButton , removeControl , removeTooltip , currentDots . length === 0 ) ;
177+ }
178+
179+ function publishState ( ) {
115180 const dots = trrack . getState ( ) . dots ;
116- dotActions . update ( dots ) ;
181+ renderState ( dots ) ;
117182 Revisit . postAnswers ( {
118183 [ taskId ] : dots . length
119184 } ) ;
120185 Revisit . postProvenance ( trrack . graph . backend ) ;
121- } ) ;
186+ }
187+
188+ // Register a listener to update the dot chart based on trrack updates.
189+ trrack . currentChange ( publishState ) ;
122190
123191 // Bind button to update dots
124- document . getElementById ( "add" ) . onclick = ( ) =>
125- trrack . apply ( "Add Dot" , updateDots ( "add" ) ) ;
192+ addButton . onclick = ( ) => {
193+ if ( trrack . getState ( ) . dots . length < maxDots ) {
194+ trrack . apply ( "Add Dot" , updateDots ( "add" ) ) ;
195+ }
196+ } ;
126197
127- document . getElementById ( "rem" ) . onclick = ( ) =>
128- trrack . apply ( "Remove Dot" , updateDots ( "remove" ) ) ;
198+ removeButton . onclick = ( ) => {
199+ if ( trrack . getState ( ) . dots . length > 0 ) {
200+ trrack . apply ( "Remove Dot" , updateDots ( "remove" ) ) ;
201+ }
202+ } ;
129203
130204 // Bind undo/redo
131205 document . getElementById ( "undo" ) . onclick = ( ) => trrack . undo ( ) ;
132206 document . getElementById ( "redo" ) . onclick = ( ) => trrack . redo ( ) ;
133207
134208 Revisit . onProvenanceReceive ( ( prov ) => {
135- dotActions . update ( prov . dots ) ;
136- } )
209+ if ( Array . isArray ( prov ?. dots ) ) {
210+ renderState ( prov . dots ) ;
211+ }
212+ } ) ;
213+
214+ publishState ( ) ;
137215
138216</ script >
139217
140- </ html >
218+ </ html >
0 commit comments