From d1993ea4b6179757ecae5e9b0ea9d10272662fbc Mon Sep 17 00:00:00 2001 From: Hallaathrad Date: Sat, 30 Jan 2016 20:31:26 -0500 Subject: [PATCH] Filter functions almost ready. Our pretty bar changes visual state of the filtered elements, clears with the X, restores hidden elements when deleting characters. Etc. For the future: if a chapterBlock is collapsed but has results, expand it. No? Also, hopefully getting fontawesome to the latest version... Regardless of that, this is a great opportunity for a legendary 404. Expansion of containers achieved Still working on collapsing them back when search terms change. If users had just pressed "collapse all" before the search, they should remain thus afterwards. The UX focus here is not to change the users' expected behaviour and final result. Future: updating font awesome. Working on a legendary "not found" image to make FCC join the internet hall of fame. (btw, where would I keep that file in the server?) --- client/less/map.less | 82 ++++++++++++++++++++++++++------------ client/main.js | 62 +++++++++++++++++++++------- server/views/map/show.jade | 48 +++++++++++----------- 3 files changed, 130 insertions(+), 62 deletions(-) diff --git a/client/less/map.less b/client/less/map.less index f6c420044d..b6e74a62f8 100644 --- a/client/less/map.less +++ b/client/less/map.less @@ -43,15 +43,9 @@ flex: 1; width: 100%; height: 100%; - border: 0; - overflow: auto; - } -} - -.map-aside-body { - #nested { - margin:0 20px; + overflow: scroll; + -webkit-overflow-scrolling: touch; } } @@ -73,43 +67,69 @@ .map-fixed-header { position: fixed; background: white; - padding-top: 20px; + padding-top: 13px; width: 100%; z-index: 1; left: 0; top: 0; @media (max-width: 720px) { - padding-top:35px; + padding-top:30px; } -} -.map-fixed-header p { + p { margin: 10px 0 20px; - @media (max-width: 720px) { - margin-bottom:15px; + @media (max-width: 720px) { + margin-bottom:10px; + } } -} -.map-fixed-header hr { - margin:35px 0; - @media (max-width: 720px) { - margin:25px 0; + hr { + margin:30px 0; + @media (max-width: 720px) { + margin:25px 0; + } } -} + } .map-buttons button, .map-buttons .input-group{ width:300px; } .map-buttons .input-group{ - margin-top: 10px; + margin-top: 15px; margin-left: auto; margin-right: auto; } +#map-filter { + background:#fff; + border-color: darkgreen; +} +.input-group-addon { + width:40px; + color: darkgreen; + background: #fff; + border-color: darkgreen; + &.filled{ + background: darkgreen; + border-color: #000d00; + color: #fff; + cursor: pointer; + } + .fa { + position:absolute; + top:50%; + transform: translateY(-50%); + right:10px; + } +} + .map-accordion { - margin: 140px auto 0; + margin: 170px auto 0; width:700px; overflow-y: auto; position:relative; + #nested { + margin:0 15px; + } h2 > a { width:100%; display:block; @@ -132,11 +152,11 @@ } } - #nested div :before { + div.chapterBlock :before { margin-right: 15px; } - #nested div p { + div.chapterBlock p { text-indent: -15px; margin-left: 60px; padding-right: 20px @@ -176,7 +196,7 @@ left:0; right:0; width:100%; - margin-top:165px; + margin-top:205px; h2 { margin:15px 0; padding:0; @@ -234,6 +254,18 @@ } } +#noneFound { + display:none; + margin:60px 30px 0; + font-size:60px; + text-align: center; + color:darkgreen; + .fa { + display:block; + font-size:300px; + } +} + .map-aside-action-pop-out { margin-right: -4px; background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZpZXdCb3g9IjAgMCAyMDAgMTcxLjQyOSIgZmlsbD0iIzNhMzEzMyI+PHBhdGggZD0iTTE1Ny4xNDMsMTAzLjU3MXYzNS43MTRjMCw4Ljg1NC0zLjE0NCwxNi40MjYtOS40MzEsMjIuNzEzcy0xMy44NTgsOS40MzEtMjIuNzEyLDkuNDMxSDMyLjE0MyBjLTguODU0LDAtMTYuNDI1LTMuMTQ0LTIyLjcxMi05LjQzMVMwLDE0OC4xNCwwLDEzOS4yODVWNDYuNDI5YzAtOC44NTQsMy4xNDQtMTYuNDI1LDkuNDMxLTIyLjcxMiBjNi4yODctNi4yODcsMTMuODU4LTkuNDMxLDIyLjcxMi05LjQzMWg3OC41NzJjMS4wNDEsMCwxLjg5NiwwLjMzNSwyLjU2NiwxLjAwNGMwLjY3LDAuNjcsMS4wMDQsMS41MjUsMS4wMDQsMi41NjdWMjUgYzAsMS4wNDItMC4zMzQsMS44OTctMS4wMDQsMi41NjdjLTAuNjcsMC42Ny0xLjUyNSwxLjAwNC0yLjU2NiwxLjAwNEgzMi4xNDNjLTQuOTExLDAtOS4xMTUsMS43NDktMTIuNjEyLDUuMjQ2IHMtNS4yNDYsNy43MDEtNS4yNDYsMTIuNjEydjkyLjg1NmMwLDQuOTExLDEuNzQ5LDkuMTE1LDUuMjQ2LDEyLjYxMnM3LjcwMSw1LjI0NSwxMi42MTIsNS4yNDVIMTI1YzQuOTEsMCw5LjExNS0xLjc0OCwxMi42MTEtNS4yNDUgYzMuNDk3LTMuNDk3LDUuMjQ2LTcuNzAxLDUuMjQ2LTEyLjYxMnYtMzUuNzE0YzAtMS4wNDIsMC4zMzQtMS44OTcsMS4wMDQtMi41NjdjMC42Ny0wLjY2OSwxLjUyNS0xLjAwNCwyLjU2Ny0xLjAwNGg3LjE0MyBjMS4wNDIsMCwxLjg5NywwLjMzNSwyLjU2NywxLjAwNEMxNTYuODA5LDEwMS42NzQsMTU3LjE0MywxMDIuNTI5LDE1Ny4xNDMsMTAzLjU3MXogTTIwMCw3LjE0M3Y1Ny4xNDMgYzAsMS45MzUtMC43MDcsMy42MDktMi4xMjEsNS4wMjJjLTEuNDEzLDEuNDE0LTMuMDg4LDIuMTIxLTUuMDIxLDIuMTIxYy0xLjkzNSwwLTMuNjA5LTAuNzA3LTUuMDIyLTIuMTIxbC0xOS42NDQtMTkuNjQzIGwtNzIuNzY3LDcyLjc2OWMtMC43NDQsMC43NDQtMS42LDEuMTE1LTIuNTY3LDEuMTE1cy0xLjgyMy0wLjM3MS0yLjU2Ny0xLjExNUw3Ny41NjcsMTA5LjcxYy0wLjc0NC0wLjc0NC0xLjExNi0xLjYtMS4xMTYtMi41NjcgYzAtMC45NjcsMC4zNzItMS44MjIsMS4xMTYtMi41NjZsNzIuNzY4LTcyLjc2OGwtMTkuNjQ0LTE5LjY0M2MtMS40MTMtMS40MTQtMi4xMi0zLjA4OC0yLjEyLTUuMDIyYzAtMS45MzUsMC43MDctMy42MDksMi4xMi01LjAyMiBDMTMyLjEwNSwwLjcwNywxMzMuNzc5LDAsMTM1LjcxNSwwaDU3LjE0M2MxLjkzNCwwLDMuNjA4LDAuNzA3LDUuMDIxLDIuMTIxQzE5OS4yOTMsMy41MzQsMjAwLDUuMjA4LDIwMCw3LjE0M3oiLz48L3N2Zz4=) diff --git a/client/main.js b/client/main.js index c78dffd8f2..ba0474ed56 100644 --- a/client/main.js +++ b/client/main.js @@ -392,34 +392,68 @@ $(document).ready(function() { }); // live filter - $('#map-filter').on('keyup', () => { + + function clearMapFilter(){ + $('#map-filter').val(''); + $('#map-filter').next().children().removeClass('fa-times').addClass('fa-search'); + $('#map-filter').next().removeClass('filled'); + $('.map-accordion').find('.hidden').removeClass('hidden'); + $('#noneFound').hide(); + } + + $('#map-filter').on('keyup', () => { if($('#map-filter').val().length > 1) { var regex = new RegExp($('#map-filter').val().replace(/ /g, '-'), "gi"); + $('.challenge-title').each((index, title) => { - //console.log("title:", JSON.stringify(title)); if(regex.test($(title).attr('name'))) { - $(title).removeClass('hidden'); + expandBlock($(title).closest('.chapterBlock')); + expandBlock($(title).closest('.chapterBlock').prev('h3')); + expandBlock($(title).closest('.certBlock')); + expandBlock($(title).closest('.certBlock').prev('h2')); + $(title).removeClass('hidden'); } else { $(title).addClass('hidden'); } - }); - $.each($('.map-collapse'), function(i, div) { - console.log("bing"); + + $.each($('.chapterBlock'), function(i, div) { if ($(div).find('.hidden').length === - $(div).find('p').length) { - console.log("hiding parents"); - $(div).addClass('hidden'); - $(div).find('h3').addClass('hidden'); - $(div).prev('h2').addClass('hidden'); + $(div).find('p').length) { + $(div).addClass('hidden'); + $(div).prev('h3').addClass('hidden'); + } else { + $(div).removeClass('hidden'); + $(div).prev('h3').removeClass('hidden'); } }); - } else { - $('.challenge-title').each((title) => { - $(title).removeClass('hidden'); + + $.each($('.certBlock'), function(i, div) { + if ($(div).children('#nested').children('h3.hidden').length === + $(div).children('#nested').children('h3').length) { + $(div).prev('h2').addClass('hidden'); + } else { + $(div).prev('h2').removeClass('hidden'); + } }); + } else if ($('#map-filter').val().length === 0) { + clearMapFilter(); + } else { + $('#map-filter').next() + .children() + .removeClass('fa-search') + .addClass('fa-times'); + $('#map-filter').next().addClass('filled'); + } + if ($.find('.certBlock').length===$('.map-accordion').children('.hidden').length) { + console.log("yass"); + $('#noneFound').show(); + } else { + $('#noneFound').hide(); } }); + + $('.map-buttons .input-group-addon').on('click', clearMapFilter); // keyboard shortcuts: open map window.Mousetrap.bind('g m', function() { diff --git a/server/views/map/show.jade b/server/views/map/show.jade index aec2616d86..1cb4c4dbc6 100644 --- a/server/views/map/show.jade +++ b/server/views/map/show.jade @@ -11,22 +11,24 @@ block content i.fa.fa-search hr #accordion.map-accordion + #noneFound Nope! Your search has produced no results + i.fa.fa-hand-spock-o for superBlock, index in superBlocks h2 a(data-toggle='collapse', data-parent='#accordion', href='#collapse'+superBlock.name.split(' ').join('-')) span.no-link-underline - i.fa.fa-caret-down   + i.fa.fa-caret-down | #{superBlock.name} - div.margin-left-10(id = 'collapse'+superBlock.name.split(' ').join('-') class = "collapse in map-collapse no-transition") + div.margin-left-10(id = 'collapse'+superBlock.name.split(' ').join('-') class = "collapse in map-collapse no-transition certBlock") #nested for challengeBlock in superBlock.blocks h3 a(data-toggle='collapse', data-parent='#nested', href='#nested-collapse'+challengeBlock.name.replace(/(\W)/gi, '').split(' ').join('-')) span.no-link-underline - i.fa.fa-caret-down   + i.fa.fa-caret-down | #{challengeBlock.name} span.challengeBlockTime (#{challengeBlock.time}) - div.margin-left-10(id = "nested-collapse"+challengeBlock.name.replace(/\W/gi, '').split(' ').join('-') class = "collapse in map-collapse no-transition") + div.margin-left-10(id = "nested-collapse"+challengeBlock.name.replace(/\W/gi, '').split(' ').join('-') class = "collapse in map-collapse no-transition chapterBlock") for challenge in challengeBlock.challenges if challenge.completed p.challenge-title.faded.text-primary.ion-checkmark-circled.padded-ionic-icon.negative-15(name="#{challenge.dashedName}") @@ -66,7 +68,7 @@ block content span.no-link-underline i.fa.fa-caret-down   | Full Stack Development Certification - div.margin-left-10(id = 'collapse-full-stack-development-certification' class = "collapse in map-collapse no-transition") + div.margin-left-10(id = 'collapse-full-stack-development-certification' class = "collapse in map-collapse no-transition certBlock") #nested h3 a(data-toggle='collapse', data-parent='#nested', href='#nested-collapse-nonprofit-projects') @@ -74,27 +76,27 @@ block content i.fa.fa-caret-down   | Nonprofit Projects span.challengeBlockTime (800 hours) - div.margin-left-10(id = "nested-collapse-nonprofit-projects" class = "collapse in map-collapse no-transition") - p.challengeBlockDescription To qualify for these nonprofit projects, you must first earn all three foundational certifications: Front End, Data Visualization, and Back End - p.disabled.text-primary.ion-locked.padded-ionic-icon.negative-15(name="Greenfield Nonprofit Project #1") Greenfield Nonprofit Project #1 + div.margin-left-10(id = "nested-collapse-nonprofit-projects" class = "collapse in map-collapse no-transition chapterBlock") + .challengeBlockDescription To qualify for these nonprofit projects, you must first earn all three foundational certifications: Front End, Data Visualization, and Back End + p.challenge-title.disabled.text-primary.ion-locked.padded-ionic-icon.negative-15(name="Greenfield Nonprofit Project #1") Greenfield Nonprofit Project #1 span.text-primary     strong * - p.disabled.text-primary.ion-locked.padded-ionic-icon.negative-15(name="Greenfield Nonprofit Project #2") Greenfield Nonprofit Project #2 + p.challenge-title.disabled.text-primary.ion-locked.padded-ionic-icon.negative-15(name="Greenfield Nonprofit Project #2") Greenfield Nonprofit Project #2 span.text-primary     strong * - p.disabled.text-primary.ion-locked.padded-ionic-icon.negative-15(name="Legacy Code Nonprofit Project #1") Legacy Code Nonprofit Project #1 + p.challenge-title.disabled.text-primary.ion-locked.padded-ionic-icon.negative-15(name="Legacy Code Nonprofit Project #1") Legacy Code Nonprofit Project #1 span.text-primary     strong * - p.disabled.text-primary.ion-locked.padded-ionic-icon.negative-15(name="Legacy Code Nonprofit Project #2") Legacy Code Nonprofit Project #2 + p.challenge-title.disabled.text-primary.ion-locked.padded-ionic-icon.negative-15(name="Legacy Code Nonprofit Project #2") Legacy Code Nonprofit Project #2 span.text-primary     strong * - p.disabled.text-primary.ion-locked.padded-ionic-icon.negative-15(name="Claim your Full Stack Development Certification") Claim your Full Stack Development Certification + p.challenge-title.disabled.text-primary.ion-locked.padded-ionic-icon.negative-15(name="Claim your Full Stack Development Certification") Claim your Full Stack Development Certification h2 a(data-toggle='collapse', data-parent='#accordion', href='#collapse-coding-interview-preparation') span.no-link-underline i.fa.fa-caret-down   | Coding Interview Preparation - div.margin-left-10(id = 'collapse-coding-interview-preparation' class = "collapse in map-collapse no-transition") + div.margin-left-10(id = 'collapse-coding-interview-preparation' class = "collapse in map-collapse no-transition certBlock") #nested h3 a(data-toggle='collapse', data-parent='#nested', href='#nested-collapse-coding-interview-training') @@ -102,20 +104,20 @@ block content i.fa.fa-caret-down   | Coding Interview Training span.challengeBlockTime (70 hours) - div.margin-left-10(id = "nested-collapse-coding-interview-training" class = "collapse in map-collapse no-transition") - p.challengeBlockDescription To qualify for this coding interview training, you must first earn all four certifications: Front End, Data Visualization, Back End, and Full Stack - p.disabled.text-primary.ion-locked.padded-ionic-icon.negative-15(name="Soft Skill Training") Soft Skill Training - p.disabled.text-primary.ion-locked.padded-ionic-icon.negative-15(name="Critical Thinking Training") Critical Thinking Training - p.disabled.text-primary.ion-locked.padded-ionic-icon.negative-15(name="Whiteboard Coding Training") Whiteboard Coding Training + div.margin-left-10(id = "nested-collapse-coding-interview-training" class = "collapse in map-collapse no-transition chapterBlock") + .challengeBlockDescription To qualify for this coding interview training, you must first earn all four certifications: Front End, Data Visualization, Back End, and Full Stack + p.challenge-title.disabled.text-primary.ion-locked.padded-ionic-icon.negative-15(name="Soft Skill Training") Soft Skill Training + p.challenge-title.disabled.text-primary.ion-locked.padded-ionic-icon.negative-15(name="Critical Thinking Training") Critical Thinking Training + p.challenge-title.disabled.text-primary.ion-locked.padded-ionic-icon.negative-15(name="Whiteboard Coding Training") Whiteboard Coding Training h3 a(data-toggle='collapse', data-parent='#nested', href='#nested-collapse-mock-interviews') span.no-link-underline i.fa.fa-caret-down   | Mock Interviews span.challengeBlockTime (10 hours) - div.margin-left-10(id = "nested-collapse-mock-interviews" class = "collapse in map-collapse no-transition") - p.challengeBlockDescription To qualify for these mock interviews, you must first earn all four certifications: Front End, Data Visualization, Back End, and Full Stack - p.disabled.text-primary.ion-locked.padded-ionic-icon.negative-15(name="Mock Interview #1") Mock Interview #1 - p.disabled.text-primary.ion-locked.padded-ionic-icon.negative-15(name="Mock Interview #2") Mock Interview #2 - p.disabled.text-primary.ion-locked.padded-ionic-icon.negative-15(name="Mock Interview #3") Mock Interview #3 + div.margin-left-10(id = "nested-collapse-mock-interviews" class = "collapse in map-collapse no-transition chapterBlock") + .challengeBlockDescription To qualify for these mock interviews, you must first earn all four certifications: Front End, Data Visualization, Back End, and Full Stack + p.challenge-title.disabled.text-primary.ion-locked.padded-ionic-icon.negative-15(name="Mock Interview #1") Mock Interview #1 + p.challenge-title.disabled.text-primary.ion-locked.padded-ionic-icon.negative-15(name="Mock Interview #2") Mock Interview #2 + p.challenge-title.disabled.text-primary.ion-locked.padded-ionic-icon.negative-15(name="Mock Interview #3") Mock Interview #3 .spacer