Search and search switches are functional
This commit is contained in:
@@ -25,6 +25,6 @@ object EGFRatingsHandler: RatingsHandler(RatingsManager.Ratings.EGF) {
|
|||||||
}
|
}
|
||||||
// 19574643 Abad Jahin FR 38GJ 20k -- 15 2 T200202B
|
// 19574643 Abad Jahin FR 38GJ 20k -- 15 2 T200202B
|
||||||
var linePattern =
|
var linePattern =
|
||||||
Regex("\\s+(?<egf>\\d{8})\\s+(?<name>$atom+)\\s(?<firstname>$atom+)?,?\\s+(?<country>[A-Z]{2})\\s+(?<club>\\S{1,4})\\s+(?<grade>[1-9][0-9]?[kdp])\\s+(?<promotion>[1-9][0-9]?[kdp]|--)\\s+(?<rating>-?[0-9]+)\\s+(?<nt>[0-9]+)\\s+(?<last>\\S+)\\s*")
|
Regex("\\s+(?<egf>\\d{8})\\s+(?<name>$atom+)\\s(?<firstname>$atom+)?,?\\s+(?<country>[A-Z]{2})\\s+(?<club>\\S{1,4})\\s+(?<rank>[1-9][0-9]?[kdp])\\s+(?<promotion>[1-9][0-9]?[kdp]|--)\\s+(?<rating>-?[0-9]+)\\s+(?<nt>[0-9]+)\\s+(?<last>\\S+)\\s*")
|
||||||
val groups = arrayOf("egf", "name", "firstname", "country", "club", "grade", "rating")
|
val groups = arrayOf("egf", "name", "firstname", "country", "club", "rank", "rating")
|
||||||
}
|
}
|
||||||
|
@@ -22,6 +22,10 @@ object FFGRatingsHandler: RatingsHandler(RatingsManager.Ratings.FFG) {
|
|||||||
}.toTypedArray()
|
}.toTypedArray()
|
||||||
Json.MutableObject(*pairs).also {
|
Json.MutableObject(*pairs).also {
|
||||||
it["origin"] = "FFG"
|
it["origin"] = "FFG"
|
||||||
|
val rating = it["rating"]?.toString()?.toIntOrNull()
|
||||||
|
if (rating != null) {
|
||||||
|
it["rank"] = (rating/100).let { if (it < 0) "${-it}k" else "${it+1}d" }
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -31,8 +31,9 @@ class PlayerIndex {
|
|||||||
val NAME = "name"
|
val NAME = "name"
|
||||||
val FIRSTNAME = "firstname"
|
val FIRSTNAME = "firstname"
|
||||||
val TEXT = "text"
|
val TEXT = "text"
|
||||||
|
val COUNTRY = "country"
|
||||||
|
|
||||||
val MAX_HITS = 100
|
val MAX_HITS = 20
|
||||||
val logger = LoggerFactory.getLogger("index")
|
val logger = LoggerFactory.getLogger("index")
|
||||||
val queryParser = ComplexPhraseQueryParser(TEXT, StandardAnalyzer())
|
val queryParser = ComplexPhraseQueryParser(TEXT, StandardAnalyzer())
|
||||||
}
|
}
|
||||||
@@ -53,10 +54,11 @@ class PlayerIndex {
|
|||||||
players.forEachIndexed { i, p ->
|
players.forEachIndexed { i, p ->
|
||||||
val player = p as Json.Object
|
val player = p as Json.Object
|
||||||
val origin = p.getString(ORIGIN) ?: throw Error("unknown origin")
|
val origin = p.getString(ORIGIN) ?: throw Error("unknown origin")
|
||||||
val text = player.field(NAME)
|
val text = player.field(NAME).lowercase(Locale.ROOT)
|
||||||
val doc = Document()
|
val doc = Document()
|
||||||
doc.add(StoredField(ID, i));
|
doc.add(StoredField(ID, i));
|
||||||
doc.add(StringField(ORIGIN, player.field(ORIGIN), Field.Store.NO))
|
doc.add(StringField(ORIGIN, player.field(ORIGIN).lowercase(Locale.ROOT), Field.Store.NO))
|
||||||
|
doc.add(StringField(COUNTRY, player.field(COUNTRY).lowercase(Locale.ROOT), Field.Store.NO))
|
||||||
doc.add(TextField(TEXT, "${player.field(NAME)} ${player.nullableField(FIRSTNAME)}", Field.Store.NO))
|
doc.add(TextField(TEXT, "${player.field(NAME)} ${player.nullableField(FIRSTNAME)}", Field.Store.NO))
|
||||||
writer.addDocument(doc);
|
writer.addDocument(doc);
|
||||||
++count
|
++count
|
||||||
@@ -65,12 +67,16 @@ class PlayerIndex {
|
|||||||
logger.info("indexed $count players")
|
logger.info("indexed $count players")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun match(needle: String, origins: Int): List<Int> {
|
fun match(needle: String, origins: Int, country: String?): List<Int> {
|
||||||
// val fuzzy = FuzzyQuery(Term(TEXT, needle))
|
val terms = needle.lowercase(Locale.ROOT)
|
||||||
val terms = needle.split(Regex("[ -_']+"))
|
.replace(Regex("([+&|!(){}\\[\\]^\\\\\"~*?:/]|(?<!\\b)-)"), "")
|
||||||
|
.split(Regex("[ -_']+"))
|
||||||
.filter { !it.isEmpty() }
|
.filter { !it.isEmpty() }
|
||||||
.map { "$it~" }
|
.map { "$it~" }
|
||||||
.joinToString(" ")
|
.joinToString(" ")
|
||||||
|
.let { if (it.isEmpty()) it else "$it ${it.substring(0, it.length - 1) + "*^5"}" }
|
||||||
|
if (terms.isEmpty()) return emptyList()
|
||||||
|
logger.info("Search query: $terms")
|
||||||
val fuzzy = queryParser.parse(terms)
|
val fuzzy = queryParser.parse(terms)
|
||||||
val activeMask = RatingsManager.activeMask()
|
val activeMask = RatingsManager.activeMask()
|
||||||
val query = when (origins.countOneBits()) {
|
val query = when (origins.countOneBits()) {
|
||||||
@@ -79,7 +85,7 @@ class PlayerIndex {
|
|||||||
val filter = TermQuery(Term(ORIGIN, RatingsManager.Ratings.codeOf(origins)))
|
val filter = TermQuery(Term(ORIGIN, RatingsManager.Ratings.codeOf(origins)))
|
||||||
BooleanQuery.Builder()
|
BooleanQuery.Builder()
|
||||||
.add(fuzzy, BooleanClause.Occur.SHOULD)
|
.add(fuzzy, BooleanClause.Occur.SHOULD)
|
||||||
.add(filter, BooleanClause.Occur.MUST)
|
.add(filter, BooleanClause.Occur.FILTER)
|
||||||
.build()
|
.build()
|
||||||
}
|
}
|
||||||
2 -> {
|
2 -> {
|
||||||
@@ -94,6 +100,15 @@ class PlayerIndex {
|
|||||||
}
|
}
|
||||||
3 -> fuzzy
|
3 -> fuzzy
|
||||||
else -> throw Error("wrong origins mask")
|
else -> throw Error("wrong origins mask")
|
||||||
|
}.let {
|
||||||
|
if (country == null) it
|
||||||
|
else {
|
||||||
|
val countryFilter = TermQuery(Term(COUNTRY, country.lowercase(Locale.ROOT)))
|
||||||
|
BooleanQuery.Builder()
|
||||||
|
.add(it, BooleanClause.Occur.SHOULD)
|
||||||
|
.add(countryFilter, BooleanClause.Occur.FILTER)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
val docs = searcher.search(query, MAX_HITS)
|
val docs = searcher.search(query, MAX_HITS)
|
||||||
return docs.scoreDocs.map { searcher.doc(it.doc).getField(ID).numericValue().toInt() }.toList()
|
return docs.scoreDocs.map { searcher.doc(it.doc).getField(ID).numericValue().toInt() }.toList()
|
||||||
|
@@ -69,14 +69,14 @@ object RatingsManager: Runnable {
|
|||||||
if (!file.mkdirs() && !file.isDirectory) throw Error("Property pairgoth.ratings.path must be a directory")
|
if (!file.mkdirs() && !file.isDirectory) throw Error("Property pairgoth.ratings.path must be a directory")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun search(needle: String, aga: Boolean, egf: Boolean, ffg: Boolean): Json.Array {
|
fun search(needle: String, aga: Boolean, egf: Boolean, ffg: Boolean, country: String?): Json.Array {
|
||||||
try {
|
try {
|
||||||
updateLock.readLock().lock()
|
updateLock.readLock().lock()
|
||||||
var mask = 0
|
var mask = 0
|
||||||
if (aga && ratingsHandlers[Ratings.AGA]!!.active) mask = mask or Ratings.AGA.flag
|
if (aga && ratingsHandlers[Ratings.AGA]!!.active) mask = mask or Ratings.AGA.flag
|
||||||
if (egf && ratingsHandlers[Ratings.EGF]!!.active) mask = mask or Ratings.EGF.flag
|
if (egf && ratingsHandlers[Ratings.EGF]!!.active) mask = mask or Ratings.EGF.flag
|
||||||
if (ffg && ratingsHandlers[Ratings.FFG]!!.active) mask = mask or Ratings.FFG.flag
|
if (ffg && ratingsHandlers[Ratings.FFG]!!.active) mask = mask or Ratings.FFG.flag
|
||||||
val matches = index.match(needle, mask)
|
val matches = index.match(needle, mask, country)
|
||||||
return matches.map { it -> players[it] }.toCollection(Json.MutableArray())
|
return matches.map { it -> players[it] }.toCollection(Json.MutableArray())
|
||||||
} finally {
|
} finally {
|
||||||
updateLock.readLock().unlock()
|
updateLock.readLock().unlock()
|
||||||
|
@@ -23,10 +23,11 @@ class SearchServlet: HttpServlet() {
|
|||||||
validateContentType(request)
|
validateContentType(request)
|
||||||
val query = request.getAttribute(PAYLOAD_KEY) as Json.Object? ?: throw ApiException(HttpServletResponse.SC_BAD_REQUEST, "no payload")
|
val query = request.getAttribute(PAYLOAD_KEY) as Json.Object? ?: throw ApiException(HttpServletResponse.SC_BAD_REQUEST, "no payload")
|
||||||
val needle = query.getString("needle") ?: throw ApiException(HttpServletResponse.SC_BAD_REQUEST, "no needle")
|
val needle = query.getString("needle") ?: throw ApiException(HttpServletResponse.SC_BAD_REQUEST, "no needle")
|
||||||
|
val country = query.getString("countryFilter")
|
||||||
val aga = query.getBoolean("aga") ?: false
|
val aga = query.getBoolean("aga") ?: false
|
||||||
val egf = query.getBoolean("egf") ?: false
|
val egf = query.getBoolean("egf") ?: false
|
||||||
val ffg = query.getBoolean("ffg") ?: false
|
val ffg = query.getBoolean("ffg") ?: false
|
||||||
payload = RatingsManager.search(needle, aga, egf, ffg)
|
payload = RatingsManager.search(needle, aga, egf, ffg, country)
|
||||||
setContentType(response)
|
setContentType(response)
|
||||||
payload.toString(response.writer)
|
payload.toString(response.writer)
|
||||||
} catch (ioe: IOException) {
|
} catch (ioe: IOException) {
|
||||||
|
@@ -339,32 +339,8 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.checkbox {
|
.clickable {
|
||||||
width: 50px;
|
pointer-events: all;
|
||||||
height: 26px;
|
|
||||||
border-radius: 18px;
|
|
||||||
background-color: #F7D6A3;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
padding-left: 5px;
|
|
||||||
padding-right: 5px;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
.circle {
|
|
||||||
background-color: #6B5E8A;
|
|
||||||
transform: translateX(0px);
|
|
||||||
border-radius: 50%;
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
transition: 300ms;
|
|
||||||
}
|
|
||||||
input {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
&.active {
|
|
||||||
background-color: rgb(218, 114, 80);
|
|
||||||
.circle {
|
|
||||||
transform: translateX(20px);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -48,6 +48,16 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* registration section */
|
/* registration section */
|
||||||
|
|
||||||
|
#player {
|
||||||
|
&.create .edition {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
&.edit .creation {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#player-form {
|
#player-form {
|
||||||
&:not(.add) {
|
&:not(.add) {
|
||||||
#search-form, #search-result {
|
#search-form, #search-result {
|
||||||
@@ -57,6 +67,42 @@
|
|||||||
}
|
}
|
||||||
#search-form {
|
#search-form {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
.toggle {
|
||||||
|
cursor: pointer;
|
||||||
|
input {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
display: block;
|
||||||
|
text-align: center;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.checkbox {
|
||||||
|
width: 50px;
|
||||||
|
height: 26px;
|
||||||
|
border-radius: 18px;
|
||||||
|
background-color: #F7D6A3;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
padding-left: 5px;
|
||||||
|
padding-right: 5px;
|
||||||
|
cursor: pointer;
|
||||||
|
.circle {
|
||||||
|
background-color: #6B5E8A;
|
||||||
|
transform: translateX(0px);
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
transition: 300ms;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
input:checked + .checkbox {
|
||||||
|
background-color: rgb(218, 114, 80);
|
||||||
|
.circle {
|
||||||
|
transform: translateX(20px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#search-result {
|
#search-result {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
@@ -66,9 +112,14 @@
|
|||||||
top: 100%;
|
top: 100%;
|
||||||
padding: 1em;
|
padding: 1em;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
&.hidden {
|
&:empty {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
.result-line {
|
||||||
|
cursor: pointer;
|
||||||
|
&:hover {
|
||||||
|
background-color: rgba(100,200,255,200);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -92,14 +92,13 @@
|
|||||||
$('#lang-list').removeClass('shown');
|
$('#lang-list').removeClass('shown');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$('.popup .close').on('click', e => {
|
$('.popup .popup-footer .close').on('click', e => {
|
||||||
let popup = e.target.closest('.popup');
|
let popup = e.target.closest('.popup');
|
||||||
if (popup) {
|
if (popup) {
|
||||||
popup.classList.remove('shown');
|
popup.classList.remove('shown');
|
||||||
$('body').removeClass('dimmed');
|
$('body').removeClass('dimmed');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// syntaxic sugar for IMask
|
// syntaxic sugar for IMask
|
||||||
|
@@ -113,6 +113,32 @@ NodeList.prototype.find = function(selector) {
|
|||||||
});
|
});
|
||||||
return Reflect.construct(Array, result, NodeList);
|
return Reflect.construct(Array, result, NodeList);
|
||||||
}
|
}
|
||||||
Element.prototype.find = function (selector) {
|
Element.prototype.find = function(selector) {
|
||||||
return this.querySelectorAll(':scope ' + selector);
|
return this.querySelectorAll(':scope ' + selector);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NodeList.prototype.clear = function() {
|
||||||
|
this.forEach(function (elem, i) {
|
||||||
|
elem.clear();
|
||||||
|
});
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
Element.prototype.clear = function() {
|
||||||
|
this.innerHTML = '';
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
TODO - conflicts with from.val(), rename one of the two
|
||||||
|
NodeList.prototype.val = function(value) {
|
||||||
|
this.item(0).val(value);
|
||||||
|
}
|
||||||
|
Element.prototype.val = function(value) {
|
||||||
|
// TODO - check that "this" has the "value" property
|
||||||
|
if (typeof(value) === 'undefined') {
|
||||||
|
return this.value;
|
||||||
|
} else {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
@@ -137,7 +137,7 @@ HTMLFormElement.prototype.val = function(name, value) {
|
|||||||
ctl.checked = value !== 'false' && Boolean(value);
|
ctl.checked = value !== 'false' && Boolean(value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else return ctl.checked;
|
else return ctl.checked && ctl.value ? ctl.value : ctl.checked;
|
||||||
}
|
}
|
||||||
console.error(`unhandled input tag or type for input ${name} (tag: ${tag}, type:${type}`);
|
console.error(`unhandled input tag or type for input ${name} (tag: ${tag}, type:${type}`);
|
||||||
return null;
|
return null;
|
||||||
@@ -171,12 +171,6 @@ onLoad(() => {
|
|||||||
$('body').removeClass('dimmed');
|
$('body').removeClass('dimmed');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
$('.checkbox').on('click', e => {
|
|
||||||
let chk = e.target.closest('.checkbox');
|
|
||||||
chk.toggleClass('active');
|
|
||||||
let checkbox = chk.find('input')[0];
|
|
||||||
checkbox.checked = !checkbox.checked;
|
|
||||||
});
|
|
||||||
/* commented for now - do we want this?
|
/* commented for now - do we want this?
|
||||||
$('#dimmer').on('click', e => $('.popup').removeClass('shown');
|
$('#dimmer').on('click', e => $('.popup').removeClass('shown');
|
||||||
*/
|
*/
|
||||||
|
@@ -1,3 +1,50 @@
|
|||||||
|
const SEARCH_DELAY = 100;
|
||||||
|
let searchTimer = undefined;
|
||||||
|
let resultTemplate;
|
||||||
|
|
||||||
|
function initSearch() {
|
||||||
|
let needle = $('#needle')[0].value;
|
||||||
|
if (searchTimer) {
|
||||||
|
clearTimeout(searchTimer);
|
||||||
|
}
|
||||||
|
searchTimer = setTimeout(() => {
|
||||||
|
search(needle);
|
||||||
|
}, SEARCH_DELAY);
|
||||||
|
}
|
||||||
|
|
||||||
|
function search(needle) {
|
||||||
|
needle = needle.trim();
|
||||||
|
console.log(needle)
|
||||||
|
if (needle && needle.length > 2) {
|
||||||
|
let form = $('#player-form')[0];
|
||||||
|
let search = {
|
||||||
|
needle: needle,
|
||||||
|
aga: form.val('aga'),
|
||||||
|
egf: form.val('egf'),
|
||||||
|
ffg: form.val('ffg'),
|
||||||
|
}
|
||||||
|
let country = form.val('countryFilter');
|
||||||
|
if (country) search.countryFilter = country;
|
||||||
|
let searchFormState = {
|
||||||
|
countryFilter: country ? true : false,
|
||||||
|
aga: search.aga,
|
||||||
|
egf: search.egf,
|
||||||
|
ffg: search.ffg
|
||||||
|
};
|
||||||
|
store('searchFormState', searchFormState);
|
||||||
|
console.log(search)
|
||||||
|
api.postJson('search', search)
|
||||||
|
.then(result => {
|
||||||
|
if (Array.isArray(result)) {
|
||||||
|
console.log(result)
|
||||||
|
let html = resultTemplate.render(result);
|
||||||
|
$('#search-result')[0].innerHTML = html;
|
||||||
|
} else console.log(result);
|
||||||
|
})
|
||||||
|
} else $('#search-result').clear();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
onLoad(() => {
|
onLoad(() => {
|
||||||
$('input.numeric').imask({
|
$('input.numeric').imask({
|
||||||
mask: Number,
|
mask: Number,
|
||||||
@@ -11,6 +58,7 @@ onLoad(() => {
|
|||||||
form.addClass('add');
|
form.addClass('add');
|
||||||
// $('#player-form input.participation').forEach(chk => chk.checked = true);
|
// $('#player-form input.participation').forEach(chk => chk.checked = true);
|
||||||
form.reset();
|
form.reset();
|
||||||
|
$('#player').removeClass('edit').addClass('create');
|
||||||
modal('player');
|
modal('player');
|
||||||
});
|
});
|
||||||
$('#cancel-register').on('click', e => {
|
$('#cancel-register').on('click', e => {
|
||||||
@@ -85,24 +133,29 @@ onLoad(() => {
|
|||||||
form.val(`r${r}`, !(player.skip && player.skip.includes(r)));
|
form.val(`r${r}`, !(player.skip && player.skip.includes(r)));
|
||||||
}
|
}
|
||||||
form.removeClass('add');
|
form.removeClass('add');
|
||||||
|
$('#player').removeClass('create').addClass('edit');
|
||||||
modal('player');
|
modal('player');
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
resultTemplate = jsrender.templates($('#result')[0]);
|
||||||
$('#needle').on('input', e => {
|
$('#needle').on('input', e => {
|
||||||
let needle = $('#needle')[0].value;
|
initSearch();
|
||||||
if (needle && needle.length > 2) {
|
});
|
||||||
let form = $('#player-form')[0];
|
$('#clear-search').on('click', e => {
|
||||||
let search = {
|
$('#needle')[0].value = '';
|
||||||
needle: needle,
|
$('#search-result').clear();
|
||||||
aga: form.val('aga'),
|
});
|
||||||
egf: form.val('egf'),
|
let searchFromState = store('searchFormState')
|
||||||
ffg: form.val('ffg')
|
if (searchFromState) {
|
||||||
}
|
for (let id of ["countryFilter", "aga", "egf", "ffg"]) {
|
||||||
api.postJson('search', search)
|
$(`#${id}`)[0].checked = searchFromState[id];
|
||||||
.then(result => {
|
}
|
||||||
console.log(result);
|
}
|
||||||
})
|
$('.toggle').on('click', e => {
|
||||||
} else $('#search-result').addClass('hidden');
|
let chk = e.target.closest('.toggle');
|
||||||
|
let checkbox = chk.find('input')[0];
|
||||||
|
checkbox.checked = !checkbox.checked;
|
||||||
|
initSearch();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
4
view-webapp/src/main/webapp/lib/jsrender-1.0.13/jsrender.min.js
vendored
Normal file
4
view-webapp/src/main/webapp/lib/jsrender-1.0.13/jsrender.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -49,35 +49,50 @@
|
|||||||
<form id="player-form" class="ui form edit">
|
<form id="player-form" class="ui form edit">
|
||||||
<input type="hidden" name="id"/>
|
<input type="hidden" name="id"/>
|
||||||
<div class="popup-content">
|
<div class="popup-content">
|
||||||
<div id="search-form" class="four stackable fields">
|
<div id="search-form" class="five stackable fields">
|
||||||
<div class="twelve wide field">
|
<div class="two wide field">
|
||||||
|
<div class="toggle">
|
||||||
|
<input id="countryFilter" name="countryFilter" type="checkbox" value="$tour.country"/>
|
||||||
|
<div class="search-param checkbox">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
<label>$tour.country.toUpperCase()</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="ten wide field">
|
||||||
<div class="ui icon input">
|
<div class="ui icon input">
|
||||||
<input id="needle" name="needle" type="text" placeholder="Search...">
|
<input id="needle" name="needle" type="text" placeholder="Search...">
|
||||||
<i class="search icon"></i>
|
<i id="clear-search" class="clickable close icon"></i>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="two wide field">
|
<div class="two wide field">
|
||||||
<div class="active checkbox">
|
<div class="toggle">
|
||||||
<div class="circle"></div>
|
<input id="aga" name="aga" type="checkbox" value="true"/>
|
||||||
<input name="aga" type="checkbox" class="hidden" checked/>
|
<div class="search-param checkbox">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
<label>AGA</label>
|
||||||
</div>
|
</div>
|
||||||
AGA
|
|
||||||
</div>
|
</div>
|
||||||
<div class="two wide field">
|
<div class="two wide field">
|
||||||
<div class="active checkbox">
|
<div class="toggle">
|
||||||
<div class="circle"></div>
|
<input id="egf" name="egf" type="checkbox" checked value="true"/>
|
||||||
<input name="egf" type="checkbox" class="hidden" checked/>
|
<div class="search-param checkbox">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
<label>EGF</label>
|
||||||
</div>
|
</div>
|
||||||
EGF
|
|
||||||
</div>
|
</div>
|
||||||
<div class="two wide field">
|
<div class="two wide field">
|
||||||
<div class="active checkbox">
|
<div class="toggle">
|
||||||
<div class="circle"></div>
|
<input id="ffg" name="ffg" type="checkbox" checked value="true"/>
|
||||||
<input name="ffg" type="checkbox" class="hidden" checked/>
|
<div class="search-param checkbox">
|
||||||
|
<div class="circle"></div>
|
||||||
|
</div>
|
||||||
|
<label>FFG</label>
|
||||||
</div>
|
</div>
|
||||||
FFG
|
|
||||||
</div>
|
</div>
|
||||||
<div id="search-result" class="hidden">hophop</div>
|
<div id="search-result"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="two stackable fields">
|
<div class="two stackable fields">
|
||||||
<div class="eight wide field">
|
<div class="eight wide field">
|
||||||
@@ -137,13 +152,21 @@
|
|||||||
<div class="popup-footer">
|
<div class="popup-footer">
|
||||||
<button id="cancel-register" class="ui gray right labeled icon floating close button">
|
<button id="cancel-register" class="ui gray right labeled icon floating close button">
|
||||||
<i class="times icon"></i>
|
<i class="times icon"></i>
|
||||||
Cancel
|
<span class="edition">Close</span>
|
||||||
|
<span class="creation">Cancel</span>
|
||||||
</button>
|
</button>
|
||||||
<button id="register" class="ui green right labeled icon floating button">
|
<button id="register" class="ui green right labeled icon floating button">
|
||||||
<i class="plus icon"></i>
|
<i class="plus icon"></i>
|
||||||
Register
|
<span class="edition">Update</span>
|
||||||
|
<span class="creation">Register</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<script id="result" type="text/template">
|
||||||
|
{{for #data}}
|
||||||
|
<div class="result-line">[{{:origin}}] {{:country}} {{:name}} {{:firstname}} {{:rank}} ({{:club}})</div>
|
||||||
|
{{/for}}
|
||||||
|
</script>
|
||||||
|
<script type="text/javascript" src="/lib/jsrender-1.0.13/jsrender.min.js"></script>
|
||||||
|
Reference in New Issue
Block a user