Skip to content

Commit 7b2ea44

Browse files
Merge pull request #560 from creativecommons/stepper-flow
setup baseline file for stepper logic, hide/show steps, adds minimal license rec capacity
2 parents 1ee5e8e + 2ff11c7 commit 7b2ea44

File tree

2 files changed

+283
-0
lines changed

2 files changed

+283
-0
lines changed

src/scripts.js

Lines changed: 279 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,279 @@
1+
2+
// all possible State Path Routes
3+
let rawStatePathRoutes = [
4+
'do-you-know-which-license-you-need/yes/which-license-do-you-need/cc-0/waive-your-copyright+waive+read/(attribution-details)&license=cc-0',
5+
'do-you-know-which-license-you-need/yes/which-license-do-you-need/cc-by/(attribution-details)&license=cc-by',
6+
'do-you-know-which-license-you-need/yes/which-license-do-you-need/cc-by-sa/(attribution-details)&license=cc-by-sa',
7+
'do-you-know-which-license-you-need/yes/which-license-do-you-need/cc-by-nd/(attribution-details)&license=cc-by-nd',
8+
'do-you-know-which-license-you-need/yes/which-license-do-you-need/cc-by-nc/(attribution-details)&license=cc-by-nc',
9+
'do-you-know-which-license-you-need/yes/which-license-do-you-need/cc-by-nc-sa/(attribution-details)&license=cc-by-nc-sa',
10+
'do-you-know-which-license-you-need/yes/which-license-do-you-need/cc-by-nc-nd/(attribution-details)&license=cc-by-nc-nd',
11+
12+
'do-you-know-which-license-you-need/no/require-attribution/yes/allow-commercial-use/yes/allow-derivatives/yes/share-alike/no/confirmation+ownership+read+revocation/(attribution-details)&license=cc-by',
13+
'do-you-know-which-license-you-need/no/require-attribution/yes/allow-commercial-use/yes/allow-derivatives/yes/share-alike/yes/confirmation+ownership+read+revocation/(attribution-details)&license=cc-by-sa',
14+
'do-you-know-which-license-you-need/no/require-attribution/yes/allow-commercial-use/yes/allow-derivatives/no/confirmation+ownership+read+revocation/(attribution-details)&license=cc-by-nd',
15+
'do-you-know-which-license-you-need/no/require-attribution/yes/allow-commercial-use/no/allow-derivatives/yes/share-alike/no/confirmation+ownership+read+revocation/(attribution-details)&license=cc-by-nc',
16+
'do-you-know-which-license-you-need/no/require-attribution/yes/allow-commercial-use/no/allow-derivatives/yes/share-alike/yes/confirmation+ownership+read+revocation/(attribution-details)&license=cc-by-nc-sa',
17+
'do-you-know-which-license-you-need/no/require-attribution/yes/allow-commercial-use/no/allow-derivatives/no/confirmation+ownership+read+revocation/(attribution-details)&license=cc-by-nc-nd',
18+
'do-you-know-which-license-you-need/no/require-attribution/no/waive-your-copyright+waive+read/(attribution-details)&license=cc-0'
19+
];
20+
21+
// empty state obj
22+
let state = {};
23+
24+
// all found fieldsets
25+
const fieldsets = document.querySelectorAll('fieldset');
26+
27+
// empty defaults obj
28+
let applyDefaults = {};
29+
30+
// set elemnts which need defaults
31+
// on initial page load
32+
applyDefaults.elements = [
33+
'#require-attribution',
34+
'#allow-commercial-use',
35+
'#allow-derivatives',
36+
'#share-alike',
37+
'#waive-your-copyright',
38+
'#confirmation'
39+
];
40+
41+
// function to parse and build state.possibilities
42+
// from rawStatePathRoutes
43+
function setStatePossibilities(state) {
44+
45+
// create state possibilities from possible licenses with adjoining statePaths
46+
state.possibilities = [];
47+
rawStatePathRoutes.forEach((path, index) => {
48+
49+
statePath = path.split("&");
50+
statepath = statePath;
51+
license = statePath[statePath.length - 1].split("=");
52+
license = license[1];
53+
54+
regEx = /\(([^)]+)\)/g;
55+
optionals = statePath[0].match(regEx);
56+
57+
optionals.forEach ((optional) => {
58+
59+
noOptionalsPath = statePath[0].replace(optional,'');
60+
61+
});
62+
63+
fullPath = statePath[0].replace(/[{()}]/g, '') + '/';
64+
65+
if (state.possibilities[license] == undefined) {
66+
state.possibilities[license] = [];
67+
}
68+
state.possibilities[license].push(fullPath);
69+
state.possibilities[license].push(noOptionalsPath);
70+
71+
});
72+
}
73+
74+
// function to establish state.parts
75+
function setStateParts(state) {
76+
state.parts = [];
77+
78+
// temp defaults
79+
state.parts[0] = 'do-you-know-which-license-you-need/yes/';
80+
state.parts[1] = 'which-license-do-you-need/cc-by/';
81+
state.parts[8] = 'attribution-details/';
82+
}
83+
// function to update state.parts
84+
function updateStateParts(element, index, event, state) {
85+
86+
state.parts[index] = element.id + '/' + event.target.value + '/';
87+
88+
// check if checkbox, with siblings
89+
if (event.target.getAttribute('type') == 'checkbox') {
90+
let checkboxElements = element.querySelectorAll('input[type="checkbox"]');
91+
let checkboxes = [];
92+
checkboxElements.forEach((checkbox, index) => {
93+
if (checkbox.checked) {
94+
checkboxes[index] = checkbox.value;
95+
}
96+
});
97+
98+
99+
let joinedCheckboxes = checkboxes.filter(Boolean).join('+');
100+
101+
state.parts[index] = element.id + '+' + joinedCheckboxes + '/';;
102+
}
103+
104+
// check if text input
105+
if (event.target.getAttribute('type') == 'text') {
106+
107+
state.parts[index] = element.id + '/';
108+
109+
}
110+
111+
console.log("state.parts (after change)");
112+
console.log(state.parts);
113+
}
114+
115+
// function to combine current tracked
116+
// state.parts into state.current
117+
function setStateCurrent(element, index, state) {
118+
state.parts.forEach((element, i) => {
119+
if (i > index) {
120+
state.parts.splice(i);
121+
}
122+
});
123+
// [T]: also reset value to nothing each time
124+
125+
state.current = state.parts.join('') //.slice(0, -1);
126+
}
127+
128+
// function to set state.props
129+
// including setting state.props.license (if valid)
130+
// or error
131+
function setStateProps(state) {
132+
133+
state.props = {};
134+
state.props.license = 'unknown';
135+
136+
// check and match possibilities
137+
Object.keys(state.possibilities).forEach((possibility) => {
138+
if(state.possibilities[possibility].includes(state.current)) {
139+
state.props.license = possibility;
140+
console.log('matched');
141+
}
142+
});
143+
144+
}
145+
146+
// function to render "license recommendation",
147+
// if valid license from state.parts and/or state.current
148+
function renderLicenseRec(state) {
149+
document.querySelector('#license-recommendation header h3').textContent = state.props.license;
150+
}
151+
152+
// function to set default UX states on Steps
153+
// set default visibly disabled pathways
154+
155+
function setDefaults(applyDefaults) {
156+
157+
applyDefaults.elements.forEach((element) => {
158+
document.querySelector(element).classList.toggle('disable');
159+
});
160+
161+
if (state.parts[0] == 'do-you-know-which-license-you-need/yes/' ) {
162+
applyDefaults.elements.forEach((element) => {
163+
document.querySelector(element).classList.add('disable');
164+
});
165+
}
166+
}
167+
168+
// stepper logic here for what parts of form are
169+
// displayed/hidden, as state.parts and state.current
170+
// are updated
171+
function renderSteps(applyDefaults, state) {
172+
173+
// check if visitor needs help, start help pathways
174+
if (state.current == 'do-you-know-which-license-you-need/no/' ) {
175+
176+
applyDefaults.elements.forEach((element) => {
177+
document.querySelector(element).classList.remove('disable');
178+
});
179+
document.querySelector('#which-license-do-you-need').classList.toggle('disable');
180+
document.querySelector('#waive-your-copyright').classList.add('disable');
181+
182+
console.log("pass one");
183+
184+
}
185+
186+
// if visitor doesn't need help
187+
if (state.current == 'do-you-know-which-license-you-need/yes/' ) {
188+
189+
applyDefaults.elements.forEach((element) => {
190+
document.querySelector(element).classList.add('disable');
191+
});
192+
document.querySelector('#which-license-do-you-need').classList.toggle('disable');
193+
document.querySelector('#waive-your-copyright').classList.add('disable');
194+
195+
}
196+
197+
// check if cc0
198+
if (state.parts[2] == 'require-attribution/no/' || state.parts[1] == 'which-license-do-you-need/cc-0/' ) {
199+
200+
applyDefaults.elements.forEach((element) => {
201+
document.querySelector(element).classList.add('disable');
202+
});
203+
204+
//if (state.parts[0] == 'do-you-know-which-license-you-need/no/') {
205+
//document.querySelector('#require-attribution').classList.remove('disable');
206+
//}
207+
document.querySelector('#waive-your-copyright').classList.remove('disable');
208+
209+
} else {
210+
document.querySelector('#waive-your-copyright').classList.add('disable');
211+
}
212+
if (state.parts[2] == 'require-attribution/no/') {
213+
document.querySelector('#require-attribution').classList.remove('disable');
214+
//document.querySelector('#confirmation').classList.remove('disable');
215+
}
216+
217+
// walk away from cc-0, reset attribution choice point
218+
if (state.parts[2] == 'require-attribution/yes/') {
219+
applyDefaults.elements.forEach((element) => {
220+
document.querySelector(element).classList.remove('disable');
221+
});
222+
document.querySelector('#require-attribution').classList.remove('disable');
223+
document.querySelector('#waive-your-copyright').classList.add('disable');
224+
225+
//document.querySelector('#confirmation').classList.remove('disable');
226+
}
227+
228+
// tie SA to ND choice
229+
if (state.parts[4] == 'allow-derivatives/no/') {
230+
document.querySelector('#share-alike').classList.add('disable');
231+
}
232+
233+
}
234+
235+
// function to render "mark your work", from attribution fields
236+
// if valid license from state.parts and/or state.current
237+
238+
// function to handle error state
239+
240+
// function to watch for fieldset changes
241+
function watchFieldsets(fieldsets, state) {
242+
fieldsets.forEach((element, index) => {
243+
244+
// [T]: set defaults here first in state.parts dynamically
245+
246+
element.addEventListener("change", (event) => {
247+
248+
console.log("something changed!");
249+
updateStateParts(element, index, event, state);
250+
251+
setStateCurrent(element, index, state);
252+
console.log("state.current (after change)");
253+
console.log(state.current);
254+
255+
setStateProps(state);
256+
console.log("state.props (after change)");
257+
console.log(state.props);
258+
259+
renderSteps(applyDefaults, state);
260+
261+
renderLicenseRec(state);
262+
});
263+
264+
});
265+
}
266+
267+
// full flow logic
268+
setStateParts(state);
269+
console.log("state.parts (at default)");
270+
console.log(state.parts);
271+
272+
setStatePossibilities(state);
273+
console.log("state.possibilities");
274+
console.log(state.possibilities);
275+
276+
setDefaults(applyDefaults);
277+
console.log("initial defaults applied");
278+
279+
watchFieldsets(fieldsets, state);

src/style.css

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,10 @@ dd {
7474
margin-left: .2em;
7575
}
7676

77+
ol li:has(.disable) {
78+
display: none;
79+
}
80+
7781

7882
.license header {
7983
display: flex;

0 commit comments

Comments
 (0)