-
-
Save robert-carroll/f70594aa4b6f6b8acfe7887eeb838b06 to your computer and use it in GitHub Desktop.
module mashup
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#module_filters { | |
list-style-type: none; | |
display: inline; | |
margin: 0; | |
} | |
#module_filters li { | |
padding: 0 .5em 0 0; | |
display: inline-block; | |
} | |
#module_filters li.separator::after { | |
content: " "; | |
border-left: 1px dashed grey; | |
padding: -1px; | |
} | |
#module_filters button { | |
background: none; | |
border: none; | |
border-color: transparent; | |
box-shadow: none; | |
margin: 0; | |
outline-style: none; | |
padding: 0 0 4px 0; | |
} | |
#module_filters button.active { | |
color: #00AC18; | |
} | |
.module_filters_hide { | |
display: none; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* module mashup | |
1) allow module items to be filtered, hiding content of the selected filter, with single click | |
2) allow focus on specific module item, hiding all content except the active filter, with double click | |
3) allow all modules to be expanded and collapsed with a single button, students and teachers | |
todo: | |
4) show module completion/progress, and create a filter by progress | |
5) show/hide published/unpublished module items, for teachers | |
*/ | |
if (/^\/courses\/\d+\/modules/.test(window.location.pathname)) { | |
var controls = { | |
filters: [ | |
{ id: 'wiki_page', label: 'Pages', icon: 'icon-document' }, | |
{ id: 'assignment', label: 'Assignments', icon: 'icon-assignment' }, | |
{ id: 'quiz', label: 'Quizzes', icon: 'icon-quiz' }, | |
{ id: 'discussion_topic', label: 'Discussion Topics', icon: 'icon-discussion' }, | |
{ id: 'external_url', label: 'Links', icon: 'icon-link' }, | |
{ id: 'attachment', label: 'Files', icon: 'icon-paperclip' }, | |
{ id: 'context_external_tool', label: 'External Tools', icon: 'icon-integrations' }, | |
], | |
toggles: [ | |
{ id: 'expand_collapse', label: 'Collapse All Modules', icon: 'icon-collapse', callback: xc }, | |
{ id: 'module_progress', label: 'Module Progress', icon: 'icon-complete', callback: mp } | |
] | |
}; | |
// toolbar html | |
var filters = controls.filters.map(f => `<li><button class="btn filter active" id="${f['id']}" aria-expanded="true" title="${f['label']}"><i class="${f['icon']}"></i></button></li>`).join(' '), | |
divider = `<li class="separator"></li>`, | |
toggles = controls.toggles.map(f => `<li><button class="btn toggle active" id="${f['id']}" aria-expanded="true" title="${f['label']}"><i class="${f['icon']}"></i></button></li>`).join(' '), | |
html = `<div><ul id="module_filters">${filters+divider+toggles}</ul></div>` | |
//document.getElementById('module_filters').remove(); | |
document.querySelector('div.header-bar').insertAdjacentHTML('beforeend', html) | |
const mm = { | |
filters: document.querySelectorAll('#module_filters button.filter'), | |
toggles: document.querySelectorAll('#module_filters button.toggle'), | |
filter: { | |
switch: btn => { | |
// console.log(btn) | |
let flip = btn.getAttribute('aria-expanded') == 'true' ? 'false' : 'true'; | |
btn.setAttribute('aria-expanded', flip) | |
if (btn.getAttribute('aria-expanded') == 'true') { | |
btn.classList.add('active') | |
} else if (btn.classList.contains('active')) { | |
btn.classList.remove('active') | |
} | |
// console.log(btn) | |
}, | |
}, | |
toggle: { | |
all: { | |
click: target => { | |
for (var i = target.length - 1; i >= 0; i--) { | |
target[i].click(); | |
} | |
}, | |
collapse: items => { | |
console.log('collapse') | |
var collapse_btns = document.querySelectorAll('#context_modules span.collapse_module_link'); | |
mm.toggle.all.click(collapse_btns) | |
}, | |
expand: items => { | |
console.log('expand') | |
//console.log(mm.toggle.all.collapsed()) | |
// on expand/collapse reset, we need to unhide anything that's hidden | |
document.querySelectorAll('.module_filters_hide').forEach(item => { | |
item.classList.remove('module_filters_hide') | |
}) | |
var expand_btns = document.querySelectorAll('#context_modules .collapsed_module span.collapse_module_link'); | |
mm.toggle.all.click(expand_btns) | |
// also need to reset the filter buttons to active | |
mm.filters.forEach(function (on) { | |
on.setAttribute('aria-expanded', 'true') | |
on.classList.add('active') | |
}) | |
}, | |
} | |
}, | |
items: { | |
hide: items => { | |
items.forEach(item => { | |
item.classList.add('module_filters_hide') | |
}) | |
}, | |
show: items => { | |
items.forEach(item => { | |
item.classList.remove('module_filters_hide') | |
}) | |
}, | |
} | |
} | |
mm.filters.forEach(function (btn) { | |
// double click, toggle filter | |
btn.addEventListener('click', function (e) { | |
var is_expanded = btn.getAttribute('aria-expanded') | |
//console.log(`${e.type} - ${btn.id}: ${is_expanded}`) | |
// toggle state | |
switch (is_expanded) { | |
case 'true': | |
mm.items.hide(document.querySelectorAll(`li.${btn.id}`)) | |
mm.filter.switch(btn) | |
break; | |
case 'false': | |
mm.items.show(document.querySelectorAll(`li.${btn.id}`)) | |
mm.filter.switch(btn) | |
break; | |
} | |
// switch the state of the expand/collapse button | |
// if any filters are active, show the expand button | |
var active = document.querySelectorAll('#module_filters button[aria-expanded="false"]') | |
if (active.length > 0) { | |
console.log(active) | |
console.log('update xc') | |
document.getElementById('expand_collapse').classList.remove('active') | |
document.getElementById('expand_collapse').setAttribute('aria-expanded', 'false') | |
document.getElementById('expand_collapse').setAttribute('title', 'Expand All Modules') | |
} | |
}); | |
// double click toggle, disable all filters and enable clicked filter | |
btn.addEventListener('dblclick', function (e) { | |
// console.log(`${e.type} - ${btn.id}`) | |
// toggle buttons off | |
mm.filters.forEach(function (off) { | |
off.setAttribute('aria-expanded', 'false') | |
off.classList.remove('active') | |
}) | |
// toggle hidden items | |
mm.items.hide(document.querySelectorAll(`li[id^="context_module_item_"]:not(.${btn.id})`)) | |
// show filtered items | |
mm.items.show(document.querySelectorAll(`li.${btn.id}.module_filters_hide`)) | |
// active button | |
btn.classList.add('active') | |
btn.setAttribute('aria-expanded', 'true') | |
}); | |
}) | |
function xc(btn) { | |
console.log('xc') | |
console.log(btn.getAttribute('aria-expanded')) | |
// toggle state (true = expanded, false = collapsed) | |
switch (btn.getAttribute('aria-expanded')) { | |
case 'true': | |
mm.toggle.all.collapse([]) | |
// switch state | |
document.getElementById('expand_collapse').classList.remove('active') | |
document.getElementById('expand_collapse').setAttribute('title', 'Expand All Modules') | |
document.getElementById('expand_collapse').setAttribute('aria-expanded', 'false') | |
break; | |
case 'false': | |
mm.toggle.all.expand([]) | |
// switch state | |
document.getElementById('expand_collapse').classList.add('active') | |
document.getElementById('expand_collapse').setAttribute('title', 'Collapse All Modules') | |
document.getElementById('expand_collapse').setAttribute('aria-expanded', 'true') | |
break; | |
} | |
} | |
function mp(btn) { | |
console.log('mp') | |
console.log(btn.getAttribute('aria-expanded')) | |
} | |
function cb(callback, btn) { | |
callback(btn) | |
} | |
mm.toggles.forEach(function (btn) { | |
btn.addEventListener('click', function (e) { | |
cb(controls.toggles.filter(t => t.id == btn.id)[0].callback, btn) | |
}); | |
}) | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment