diff --git a/view-webapp/src/main/kotlin/org/jeudego/pairgoth/ratings/PlayerIndex.kt b/view-webapp/src/main/kotlin/org/jeudego/pairgoth/ratings/PlayerIndex.kt index ffaa8cd..df253a8 100644 --- a/view-webapp/src/main/kotlin/org/jeudego/pairgoth/ratings/PlayerIndex.kt +++ b/view-webapp/src/main/kotlin/org/jeudego/pairgoth/ratings/PlayerIndex.kt @@ -74,7 +74,7 @@ class PlayerIndex { .filter { !it.isEmpty() } .map { "$it~" } .joinToString(" ") - .let { if (it.isEmpty()) it else "$it ${it.substring(0, it.length - 1) + "*^5"}" } + .let { if (it.isEmpty()) it else "$it ${it.substring(0, it.length - 1) + "*^4"}" } if (terms.isEmpty()) return emptyList() logger.info("Search query: $terms") val fuzzy = queryParser.parse(terms) diff --git a/view-webapp/src/main/sass/tour.scss b/view-webapp/src/main/sass/tour.scss index 473184d..0a74e9b 100644 --- a/view-webapp/src/main/sass/tour.scss +++ b/view-webapp/src/main/sass/tour.scss @@ -50,11 +50,18 @@ /* registration section */ #player { - &.create .edition { - display: none; + &.create { + .edition { + display: none; + } + #unregister { + display: none; + } } - &.edit .creation { - display: none; + &.edit { + .creation { + display: none; + } } } @@ -117,9 +124,13 @@ } .result-line { cursor: pointer; - &:hover { + &:hover, &.highlighted { background-color: rgba(100,200,255,200); } } } + + #player.popup { + min-width: 65vw; + } } diff --git a/view-webapp/src/main/webapp/js/api.js b/view-webapp/src/main/webapp/js/api.js index cbb021d..db6906e 100644 --- a/view-webapp/src/main/webapp/js/api.js +++ b/view-webapp/src/main/webapp/js/api.js @@ -128,6 +128,27 @@ let api = { .finally(() => { spinner(false); }); - } + }, + + deleteJson: (path, body) => { + clearFeedback(); + spinner(true); + return api.delete(path, body) + .then(resp => { + if (resp.ok) { + success(); + return resp.json(); + } + else throw resp; + }) + .catch(err => { + error(err); + return 'error'; + }) + .finally(() => { + spinner(false); + }); + } + }; diff --git a/view-webapp/src/main/webapp/js/domhelper.js b/view-webapp/src/main/webapp/js/domhelper.js index fbeed62..b826a23 100644 --- a/view-webapp/src/main/webapp/js/domhelper.js +++ b/view-webapp/src/main/webapp/js/domhelper.js @@ -47,10 +47,15 @@ Element.prototype.toggleClass = function(className) { return this; } NodeList.prototype.hasClass = function(className) { + console.log('nodelist.hasClass') + console.log(this.item(0)); return this.item(0).classList.contains(className); } Element.prototype.hasClass = function(className) { - this.classList.contains(className); + console.log('element.hasClass') + console.log(this.classList) + console.log(this.classList.contains(className)) + return this.classList.contains(className); } Node.prototype.offset = function() { let _x = 0; @@ -142,3 +147,8 @@ Element.prototype.val = function(value) { } } */ + +NodeList.prototype.focus = function() { + let first = this.item(0); + if (first) first.focus(); +} diff --git a/view-webapp/src/main/webapp/js/main.js b/view-webapp/src/main/webapp/js/main.js index 70491b0..ee2ea20 100644 --- a/view-webapp/src/main/webapp/js/main.js +++ b/view-webapp/src/main/webapp/js/main.js @@ -171,8 +171,57 @@ onLoad(() => { $('body').removeClass('dimmed'); } }); + /* commented for now - do we want this? $('#dimmer').on('click', e => $('.popup').removeClass('shown'); */ + + // keyboard handling + document.on('keyup', e => { + switch (e.key) { + case 'Escape': { + if ($('#player').hasClass('shown')) { + if ($('#needle')[0].value) { + $('#needle')[0].value = ''; + initSearch(); + } else { + close_modal(); + } + } + break; + } + case 'ArrowDown': { + if (searchResultShown()) { + let lines = $('.result-line'); + if (typeof (searchHighlight) === 'undefined') searchHighlight = 0; + else ++searchHighlight; + searchHighlight = Math.min(searchHighlight, lines.length - 1); + lines.removeClass('highlighted'); + lines[searchHighlight].addClass('highlighted'); + } + break; + } + case 'ArrowUp': { + if (searchResultShown()) { + let lines = $('.result-line'); + if (typeof (searchHighlight) === 'undefined') searchHighlight = 0; + else --searchHighlight; + searchHighlight = Math.max(searchHighlight, 0); + lines.removeClass('highlighted'); + lines[searchHighlight].addClass('highlighted'); + } + break; + } + case 'Enter': { + if (searchResultShown()) { + fillPlayer(searchResult[searchHighlight]); + } else { + $('#register')[0].click(); + } + break; + } + } + }); + }); diff --git a/view-webapp/src/main/webapp/js/tour-registration.inc.js b/view-webapp/src/main/webapp/js/tour-registration.inc.js index c13ed98..d949745 100644 --- a/view-webapp/src/main/webapp/js/tour-registration.inc.js +++ b/view-webapp/src/main/webapp/js/tour-registration.inc.js @@ -1,9 +1,11 @@ const SEARCH_DELAY = 100; let searchTimer = undefined; let resultTemplate; +let searchResult; +let searchHighlight; function initSearch() { - let needle = $('#needle')[0].value; + let needle = $('#needle')[0].value.trim(); if (searchTimer) { clearTimeout(searchTimer); } @@ -12,9 +14,12 @@ function initSearch() { }, SEARCH_DELAY); } +function searchResultShown() { + return !(typeof(searchHighlight) === 'undefined' || !searchResult || !searchResult.length || typeof(searchResult[searchHighlight]) === 'undefined') +} + function search(needle) { needle = needle.trim(); - console.log(needle) if (needle && needle.length > 2) { let form = $('#player-form')[0]; let search = { @@ -32,17 +37,46 @@ function search(needle) { ffg: search.ffg }; store('searchFormState', searchFormState); - console.log(search) api.postJson('search', search) .then(result => { if (Array.isArray(result)) { - console.log(result) + searchResult = result let html = resultTemplate.render(result); $('#search-result')[0].innerHTML = html; } else console.log(result); }) - } else $('#search-result').clear(); + } else { + $('#search-result').clear(); + searchTimer = undefined; + searchResult = undefined; + searchHighlight = undefined; + } +} +function parseRank(rank) { + let groups = /(\d+)([kd])/.exec(rank) + if (groups) { + let level = parseInt(groups[1]); + let letter = groups[2]; + switch (letter) { + case 'k': return -level; + case 'd': return level - 1; + } + } + return ''; +} + +function fillPlayer(player) { + let form = $('#player-form')[0]; + form.val('name', player.name); + form.val('firstname', player.firstname); + form.val('country', player.country.toLowerCase()); + form.val('club', player.club); + form.val('rank', parseRank(player.rank)); + form.val('rating', player.rating); + $('#needle')[0].value = ''; + initSearch(); + $('#register').focus(); } onLoad(() => { @@ -60,10 +94,12 @@ onLoad(() => { form.reset(); $('#player').removeClass('edit').addClass('create'); modal('player'); + $('#needle').focus(); }); $('#cancel-register').on('click', e => { e.preventDefault(); close_modal(); + searchHighlight = undefined; return false; }); @@ -82,10 +118,13 @@ onLoad(() => { } } if (!valid) return; + // $('#player-form')[0].requestSubmit() not working?! + $('#player-form')[0].dispatchEvent(new CustomEvent('submit', {cancelable: true})); }); $('#player-form').on('submit', e => { + ("submitting!!") e.preventDefault(); - let form = e.target; + let form = $('#player-form')[0]; let player = { name: form.val('name'), firstname: form.val('firstname'), @@ -95,11 +134,10 @@ onLoad(() => { club: form.val('club'), skip: form.find('input.participation').map((input,i) => [i+1, input.checked]).filter(arr => !arr[1]).map(arr => arr[0]) } - console.log(player); if (form.hasClass('add')) { + ("ADDING") api.postJson(`tour/${tour_id}/part`, player) .then(player => { - console.log(player) if (player !== 'error') { window.location.reload(); } @@ -109,7 +147,6 @@ onLoad(() => { player['id'] = id; api.putJson(`tour/${tour_id}/part/${id}`, player) .then(player => { - console.log(player) if (player !== 'error') { window.location.reload(); } @@ -158,4 +195,21 @@ onLoad(() => { checkbox.checked = !checkbox.checked; initSearch(); }); + document.on('click', e => { + let resultLine = e.target.closest('.result-line'); + if (resultLine) { + let index = e.target.closest('.result-line').data('index'); + fillPlayer(searchResult[index]); + } + }); + $('#unregister').on('click', e => { + let form = $('#player-form')[0]; + let id = form.val('id'); + api.deleteJson(`tour/${tour_id}/part/${id}`) + .then(ret => { + if (ret !== 'error') { + window.location.reload(); + } + }); + }); }); diff --git a/view-webapp/src/main/webapp/tour-registration.inc.html b/view-webapp/src/main/webapp/tour-registration.inc.html index e43b8ea..8164089 100644 --- a/view-webapp/src/main/webapp/tour-registration.inc.html +++ b/view-webapp/src/main/webapp/tour-registration.inc.html @@ -150,12 +150,16 @@ +#[[ +]]#