-
Notifications
You must be signed in to change notification settings - Fork 16
Search #145
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: version2.0
Are you sure you want to change the base?
Search #145
Changes from all commits
029ae1a
6306122
c6fee2b
797ccb6
9a4babf
4c3343d
fb35b87
d65ad0d
967adac
4ef6862
bcc24ac
15809f4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Large diffs are not rendered by default.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -238,13 +238,36 @@ export default class Aside { | |
| * @param {number} noteData.folderId | ||
| * | ||
| * @param {Boolean} isRootFolder - true if Note is included to the Root Folder | ||
| * @param {Object} searchData - object with search data | ||
| */ | ||
| addMenuItem(noteData, isRootFolder) { | ||
| addMenuItem(noteData, isRootFolder, searchData) { | ||
| /** | ||
| * Creating note DOM | ||
| * @param {String} title - name of the note | ||
| * @param {Object} dataset - dataset of the root DOM note element | ||
| * @param {Object} highlight - object with coords of highlight for search | ||
| */ | ||
| let createNoteDOM = (title, dataset, highlight) => { | ||
| let item = this.makeMenuItem(title, dataset, highlight); | ||
|
|
||
| notesMenu.insertAdjacentElement('afterbegin', item); | ||
|
|
||
| item.addEventListener('click', event => this.menuItemClicked(event) ); | ||
| }; | ||
|
|
||
| if (!noteData.title) { | ||
| console.warn('Can not add Note to the Aside because it has no title', noteData); | ||
| return; | ||
| } | ||
|
|
||
| if (searchData) { | ||
| notesMenu = document.querySelector('[name="js-found-notes-menu"]'); | ||
| createNoteDOM(noteData.title, {id: noteData._id}, searchData.highlight); | ||
| return; | ||
| } else { | ||
| codex.notes.searcher.pushData({title: noteData.title, _id: noteData._id}); | ||
| } | ||
|
|
||
| let notesMenu; | ||
|
|
||
| if (isRootFolder) { | ||
|
|
@@ -266,11 +289,7 @@ export default class Aside { | |
| return; | ||
| } | ||
|
|
||
| let item = this.makeMenuItem(noteData.title, {id: noteData._id}); | ||
|
|
||
| notesMenu.insertAdjacentElement('afterbegin', item); | ||
|
|
||
| item.addEventListener('click', event => this.menuItemClicked(event) ); | ||
| createNoteDOM(noteData.title, {id: noteData._id}); | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -295,16 +314,23 @@ export default class Aside { | |
|
|
||
| /** | ||
| * Makes aside menu item | ||
| * @param {String} title - item title | ||
| * @param {object} dataset - data to store in dataset | ||
| * @param {String} title - item title | ||
| * @param {Object} dataset - data to store in dataset | ||
| * @param {Object} highlight - pointers to part of title text to highlight | ||
| * @return {Element} | ||
| */ | ||
| makeMenuItem(title, dataset) { | ||
| makeMenuItem(title, dataset, highlight) { | ||
| title = this.createMenuItemTitle(title); | ||
|
|
||
| let item = $.make('li', null, { | ||
| textContent: title | ||
| }); | ||
| let item = $.make('li'); | ||
|
|
||
| if (highlight) { | ||
| item.innerHTML = title.substring(0, highlight.start) + | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. replace |
||
| '<span>' + title.substring(highlight.start, highlight.end) + '</span>' | ||
| + title.substring(highlight.end); | ||
| } else { | ||
| item.textContent = title; | ||
| } | ||
|
|
||
| for (let key in dataset) { | ||
| item.dataset[key] = dataset[key]; | ||
|
|
@@ -337,7 +363,10 @@ export default class Aside { | |
| notesMenu.forEach( menu => { | ||
| let existingNote = menu.querySelector('[data-id="' + itemId + '"]'); | ||
|
|
||
| if (existingNote) existingNote.remove(); | ||
| if (existingNote) { | ||
| existingNote.remove(); | ||
| codex.notes.searcher.removeData(itemId); | ||
| } | ||
| }); | ||
| } | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,146 @@ | ||
| /** | ||
| * Class for searching through notes | ||
| */ | ||
| export default class Searcher { | ||
|
|
||
| /** | ||
| * @constructor | ||
| */ | ||
| constructor() { | ||
| /** | ||
| * DOM tree of class | ||
| * @type {Object} | ||
| */ | ||
| this.DOM = { | ||
| input: document.getElementsByClassName('searcher__input')[0], | ||
| foldersContainer: document.getElementsByName('js-folders-container')[0], | ||
| notes: { | ||
| created: document.getElementsByName('js-notes-menu')[0], | ||
| found: document.getElementsByName('js-found-notes-menu')[0] | ||
| } | ||
| }; | ||
|
|
||
| /** | ||
| * CSS classes for DOM | ||
| * @type {Object} | ||
| */ | ||
| this.CSS = { | ||
| hidden: 'searcher__hidden' | ||
| }; | ||
|
|
||
| /** | ||
| * Default value in the search input form | ||
| * @type {String} | ||
| */ | ||
| this.defaultInputValue = 'Search'; | ||
|
|
||
| /** | ||
| * Where to search | ||
| * @type {Array} | ||
| */ | ||
| this.dataset = []; | ||
|
|
||
| /** | ||
| * Keyword from search field saved after search mode was disabled | ||
| * @type {Strng} | ||
| */ | ||
| this.lastSearch = ''; | ||
|
|
||
| this.DOM.input.addEventListener('focus', () => { | ||
| this.DOM.notes.created.classList.add(this.CSS.hidden); | ||
| this.DOM.notes.found.classList.remove(this.CSS.hidden); | ||
| this.DOM.foldersContainer.classList.add(this.CSS.hidden); | ||
|
|
||
| this.DOM.input.value = this.lastSearch; | ||
| }); | ||
|
|
||
| this.DOM.input.addEventListener('blur', (event) => { | ||
| if (event.relatedTarget != this.DOM.notes.found) { | ||
| this.DOM.notes.found.classList.add(this.CSS.hidden); | ||
| this.DOM.notes.found.classList.add(this.CSS.hidden); | ||
| this.DOM.notes.created.classList.remove(this.CSS.hidden); | ||
| this.DOM.foldersContainer.classList.remove(this.CSS.hidden); | ||
|
|
||
| this.lastSearch = this.DOM.input.value; | ||
| this.DOM.input.value = this.defaultInputValue; | ||
| } | ||
| }); | ||
|
|
||
| this.DOM.input.addEventListener('keyup', () => { | ||
| this.search(this.DOM.input.value); | ||
| }); | ||
| } | ||
|
|
||
| /** | ||
| * Cleans search results | ||
| * @param {Object} data - data to push to the dataset | ||
| */ | ||
| reset() { | ||
| let found = this.DOM.notes.found, | ||
| parent = found.parentNode; | ||
|
|
||
| this.DOM.notes.found = parent.removeChild(found).cloneNode(false); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. innerHTML= ''; |
||
| parent.appendChild(this.DOM.notes.found); | ||
| } | ||
|
|
||
| /** | ||
| * Push note data to array where search will be done | ||
| * @param {Object} data - data to push to the dataset | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. описать объект |
||
| */ | ||
| pushData( data ) { | ||
| let existingDataIndex = this.dataset.length; | ||
|
|
||
| this.dataset.forEach((item, index) => { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. написать комментарий |
||
| if (item._id == data._id) { | ||
| existingDataIndex = index; | ||
| return; | ||
| } | ||
| }); | ||
|
|
||
| this.dataset.splice(existingDataIndex, 1, data); | ||
| } | ||
|
|
||
| /** | ||
| * Remove note data from array where search will be done | ||
| * @param {Object} dataId - the id of data to remove from the dataset | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. это не объект |
||
| */ | ||
| removeData( dataId ) { | ||
| let existingDataIndex = this.dataset.length; | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. вынести код в метод |
||
|
|
||
| this.dataset.forEach((item, index) => { | ||
| if (item._id == dataId) { | ||
| existingDataIndex = index; | ||
| return; | ||
| } | ||
| }); | ||
|
|
||
| this.dataset.splice(existingDataIndex, 1); | ||
| } | ||
|
|
||
| /** | ||
| * Find data in the dataset array | ||
| * @param {String} title - key to find data | ||
| */ | ||
| search( title ) { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. query |
||
| this.reset(); | ||
|
|
||
| if (title == '') { | ||
| return; | ||
| } | ||
|
|
||
| let highlight = { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. выделять на выводе через replace |
||
| start: 0, | ||
| end: 0 | ||
| }; | ||
|
|
||
| this.dataset.forEach((element) => { | ||
| highlight.start = element.title.indexOf(title); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. inlcudes
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
|
||
| if (highlight.start > -1) { | ||
| highlight.end = highlight.start + title.length; | ||
| codex.notes.aside.addMenuItem(element, true, {highlight: highlight}); | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. передавать подстроку, которую нужно выделить |
||
| } | ||
| }); | ||
| } | ||
|
|
||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| .searcher { | ||
|
|
||
| &__hidden { | ||
| display: none; | ||
| } | ||
|
|
||
| &__container { | ||
| display: flex; | ||
| font-size: 15px; | ||
| padding: 5px 0px; | ||
| border-bottom: 2px solid rgba(130,156,176,.42); | ||
| margin-bottom: 15px; | ||
| } | ||
|
|
||
| &__input { | ||
| display: flex; | ||
| width: 100%; | ||
| border: none; | ||
| color: #63758c; | ||
| background: none; | ||
| } | ||
|
|
||
| &__input:focus { | ||
| color: white; | ||
| outline: none; | ||
| } | ||
|
|
||
| } | ||
|
|
||
| [name='js-found-notes-menu'] span { | ||
| color: white; | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6,6 +6,14 @@ | |
|
|
||
| .aside-swiper__left | ||
|
|
||
| //- | ||
| //- Search | ||
| //- | ||
| .searcher__container | ||
| input.searcher__input(value="Search") | ||
| include ../../public/svg/search.svg | ||
|
|
||
|
|
||
| //- | ||
| //- Header | ||
| //- | ||
|
|
@@ -19,28 +27,35 @@ | |
| .aside__scrollable | ||
| .aside__scrollable-content(name="js-scrollable") | ||
|
|
||
| .aside__section-title Folders | ||
| .aside__content-wrap(name="js-folders-container") | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. проверить скролл |
||
| .aside__section-title Folders | ||
|
|
||
| section#folders-section | ||
| section#folders-section | ||
|
|
||
| .notes-list | ||
| ul.notes-list__content(name="js-folders-menu") | ||
| .notes-list | ||
| ul.notes-list__content(name="js-folders-menu") | ||
|
|
||
| .aside__add-button(name="js-new-folder-button") | ||
| include ../../public/svg/plus.svg | ||
| | Add folder | ||
| .aside__add-button(name="js-new-folder-button") | ||
| include ../../public/svg/plus.svg | ||
| | Add folder | ||
|
|
||
| fieldset.aside__input.hide(name="js-new-folder-field") | ||
| input(placeholder="Enter title", type="text") | ||
| include ../../public/svg/arrow-right.svg | ||
| fieldset.aside__input.hide(name="js-new-folder-field") | ||
| input(placeholder="Enter title", type="text") | ||
| include ../../public/svg/arrow-right.svg | ||
|
|
||
| .aside__section-title Notes | ||
| .aside__content-wrap(name="js-notes-container") | ||
| .aside__section-title Notes | ||
|
|
||
| .notes-list | ||
| ul.notes-list__content(name="js-notes-menu") | ||
| //- | ||
| //- div.notes-list__scroll | ||
| //- | ||
| .notes-list | ||
| ul.notes-list__content(name="js-notes-menu") | ||
| //- | ||
| //- div.notes-list__scroll | ||
| //- | ||
| ul.notes-list__content(name="js-found-notes-menu", tabindex="0") | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. скрывать поиск после очистки инпута |
||
| //- | ||
| //- div.notes-list__scroll | ||
| //- | ||
| .aside-swiper__right | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
перенести в else if