| 
									
										
										
										
											2017-08-27 21:31:34 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | class EntitySelector { | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     constructor(elem) { | 
					
						
							|  |  |  |         this.elem = elem; | 
					
						
							|  |  |  |         this.search = ''; | 
					
						
							|  |  |  |         this.lastClick = 0; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         let entityTypes = elem.hasAttribute('entity-types') ? elem.getAttribute('entity-types') : 'page,book,chapter'; | 
					
						
							|  |  |  |         this.searchUrl = window.baseUrl(`/ajax/search/entities?types=${encodeURIComponent(entityTypes)}`); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         this.input = elem.querySelector('[entity-selector-input]'); | 
					
						
							|  |  |  |         this.searchInput = elem.querySelector('[entity-selector-search]'); | 
					
						
							|  |  |  |         this.loading = elem.querySelector('[entity-selector-loading]'); | 
					
						
							|  |  |  |         this.resultsContainer = elem.querySelector('[entity-selector-results]'); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         this.elem.addEventListener('click', this.onClick.bind(this)); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         let lastSearch = 0; | 
					
						
							|  |  |  |         this.searchInput.addEventListener('input', event => { | 
					
						
							|  |  |  |             lastSearch = Date.now(); | 
					
						
							|  |  |  |             this.showLoading(); | 
					
						
							|  |  |  |             setTimeout(() => { | 
					
						
							|  |  |  |                 if (Date.now() - lastSearch < 199) return; | 
					
						
							|  |  |  |                 this.searchEntities(this.searchInput.value); | 
					
						
							|  |  |  |             }, 200); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |         this.searchInput.addEventListener('keydown', event => { | 
					
						
							|  |  |  |             if (event.keyCode === 13) event.preventDefault(); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         this.showLoading(); | 
					
						
							|  |  |  |         this.initialLoad(); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     showLoading() { | 
					
						
							|  |  |  |         this.loading.style.display = 'block'; | 
					
						
							|  |  |  |         this.resultsContainer.style.display = 'none'; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     hideLoading() { | 
					
						
							|  |  |  |         this.loading.style.display = 'none'; | 
					
						
							|  |  |  |         this.resultsContainer.style.display = 'block'; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     initialLoad() { | 
					
						
							|  |  |  |         window.$http.get(this.searchUrl).then(resp => { | 
					
						
							|  |  |  |             this.resultsContainer.innerHTML = resp.data; | 
					
						
							|  |  |  |             this.hideLoading(); | 
					
						
							|  |  |  |         }) | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     searchEntities(searchTerm) { | 
					
						
							|  |  |  |         this.input.value = ''; | 
					
						
							|  |  |  |         let url = this.searchUrl + `&term=${encodeURIComponent(searchTerm)}`; | 
					
						
							|  |  |  |         window.$http.get(url).then(resp => { | 
					
						
							|  |  |  |             this.resultsContainer.innerHTML = resp.data; | 
					
						
							|  |  |  |             this.hideLoading(); | 
					
						
							|  |  |  |         }); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     isDoubleClick() { | 
					
						
							|  |  |  |         let now = Date.now(); | 
					
						
							|  |  |  |         let answer = now - this.lastClick < 300; | 
					
						
							|  |  |  |         this.lastClick = now; | 
					
						
							|  |  |  |         return answer; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     onClick(event) { | 
					
						
							|  |  |  |         let t = event.target; | 
					
						
							| 
									
										
										
										
											2017-08-28 20:38:32 +08:00
										 |  |  |         console.log('click', t); | 
					
						
							| 
									
										
										
										
											2017-08-27 21:31:34 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-08-28 20:38:32 +08:00
										 |  |  |         if (t.matches('.entity-list-item  *')) { | 
					
						
							| 
									
										
										
										
											2017-08-27 21:31:34 +08:00
										 |  |  |             event.preventDefault(); | 
					
						
							|  |  |  |             event.stopPropagation(); | 
					
						
							|  |  |  |             let item = t.closest('[data-entity-type]'); | 
					
						
							|  |  |  |             this.selectItem(item); | 
					
						
							|  |  |  |         } else if (t.matches('[data-entity-type]')) { | 
					
						
							|  |  |  |             this.selectItem(t) | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     selectItem(item) { | 
					
						
							|  |  |  |         let isDblClick = this.isDoubleClick(); | 
					
						
							|  |  |  |         let type = item.getAttribute('data-entity-type'); | 
					
						
							|  |  |  |         let id = item.getAttribute('data-entity-id'); | 
					
						
							| 
									
										
										
										
											2017-08-28 20:38:32 +08:00
										 |  |  |         let isSelected = !item.classList.contains('selected') || isDblClick; | 
					
						
							| 
									
										
										
										
											2017-08-27 21:31:34 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |         this.unselectAll(); | 
					
						
							|  |  |  |         this.input.value = isSelected ? `${type}:${id}` : ''; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (!isSelected) window.$events.emit('entity-select-change', null); | 
					
						
							| 
									
										
										
										
											2017-08-28 20:38:32 +08:00
										 |  |  |         if (isSelected) { | 
					
						
							|  |  |  |             item.classList.add('selected'); | 
					
						
							|  |  |  |             item.classList.add('primary-background'); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2017-08-27 21:31:34 +08:00
										 |  |  |         if (!isDblClick && !isSelected) return; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         let link = item.querySelector('.entity-list-item-link').getAttribute('href'); | 
					
						
							|  |  |  |         let name = item.querySelector('.entity-list-item-name').textContent; | 
					
						
							|  |  |  |         let data = {id: Number(id), name: name, link: link}; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         if (isDblClick) window.$events.emit('entity-select-confirm', data); | 
					
						
							|  |  |  |         if (isSelected) window.$events.emit('entity-select-change', data); | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     unselectAll() { | 
					
						
							|  |  |  |         let selected = this.elem.querySelectorAll('.selected'); | 
					
						
							|  |  |  |         for (let i = 0, len = selected.length; i < len; i++) { | 
					
						
							|  |  |  |             selected[i].classList.remove('selected'); | 
					
						
							|  |  |  |             selected[i].classList.remove('primary-background'); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | module.exports = EntitySelector; |