Fix stored css bug in all typeahead functions (update typeahead -> bugfix typeahead)

This commit is contained in:
Ozzie Isaacs 2021-10-10 18:02:18 +02:00
parent cd53d57516
commit bad4c01474
5 changed files with 1855 additions and 1001 deletions

View File

@ -737,6 +737,7 @@ class CalibreDB():
self.session.connection().connection.connection.create_function("lower", 1, lcase) self.session.connection().connection.connection.create_function("lower", 1, lcase)
entries = self.session.query(database).filter(tag_filter). \ entries = self.session.query(database).filter(tag_filter). \
filter(func.lower(database.name).ilike("%" + query + "%")).all() filter(func.lower(database.name).ilike("%" + query + "%")).all()
# json_dumps = json.dumps([dict(name=escape(r.name.replace(*replace))) for r in entries])
json_dumps = json.dumps([dict(name=r.name.replace(*replace)) for r in entries]) json_dumps = json.dumps([dict(name=r.name.replace(*replace)) for r in entries])
return json_dumps return json_dumps

View File

@ -145,7 +145,7 @@ fieldset[disabled] .twitter-typeahead .tt-input {
cursor: not-allowed; cursor: not-allowed;
background-color: #eeeeee !important; background-color: #eeeeee !important;
} }
.tt-dropdown-menu { .tt-menu {
position: absolute; position: absolute;
top: 100%; top: 100%;
left: 0; left: 0;
@ -166,7 +166,7 @@ fieldset[disabled] .twitter-typeahead .tt-input {
*border-right-width: 2px; *border-right-width: 2px;
*border-bottom-width: 2px; *border-bottom-width: 2px;
} }
.tt-dropdown-menu .tt-suggestion { .tt-menu .tt-suggestion {
display: block; display: block;
padding: 3px 20px; padding: 3px 20px;
clear: both; clear: both;
@ -175,15 +175,15 @@ fieldset[disabled] .twitter-typeahead .tt-input {
color: #333333; color: #333333;
white-space: nowrap; white-space: nowrap;
} }
.tt-dropdown-menu .tt-suggestion.tt-cursor { .tt-menu .tt-suggestion.tt-cursor {
text-decoration: none; text-decoration: none;
outline: 0; outline: 0;
background-color: #f5f5f5; background-color: #f5f5f5;
color: #262626; color: #262626;
} }
.tt-dropdown-menu .tt-suggestion.tt-cursor a { .tt-menu .tt-suggestion.tt-cursor a {
color: #262626; color: #262626;
} }
.tt-dropdown-menu .tt-suggestion p { .tt-menu .tt-suggestion p {
margin: 0; margin: 0;
} }

View File

@ -46,90 +46,20 @@ $(".datepicker_delete").click(function() {
Takes a prefix, query typeahead callback, Bloodhound typeahead adapter Takes a prefix, query typeahead callback, Bloodhound typeahead adapter
and returns the completions it gets from the bloodhound engine prefixed. and returns the completions it gets from the bloodhound engine prefixed.
*/ */
function prefixedSource(prefix, query, cb, bhAdapter) { function prefixedSource(prefix, query, cb, source) {
bhAdapter(query, function(retArray) { function async(retArray) {
retArray = retArray || [];
var matches = []; var matches = [];
for (var i = 0; i < retArray.length; i++) { for (var i = 0; i < retArray.length; i++) {
var obj = {name : prefix + retArray[i].name}; var obj = {name : prefix + retArray[i].name};
matches.push(obj); matches.push(obj);
} }
cb(matches); cb(matches);
}); }
source.search(query, cb, async);
} }
var authors = new Bloodhound({
name: "authors",
datumTokenizer: function datumTokenizer(datum) {
return [datum.name];
},
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: getPath() + "/get_authors_json?q=%QUERY"
}
});
var series = new Bloodhound({
name: "series",
datumTokenizer: function datumTokenizer(datum) {
return [datum.name];
},
queryTokenizer: function queryTokenizer(query) {
return [query];
},
remote: {
url: getPath() + "/get_series_json?q=",
replace: function replace(url, query) {
return url + encodeURIComponent(query);
}
}
});
var tags = new Bloodhound({
name: "tags",
datumTokenizer: function datumTokenizer(datum) {
return [datum.name];
},
queryTokenizer: function queryTokenizer(query) {
var tokens = query.split(",");
tokens = [tokens[tokens.length - 1].trim()];
return tokens;
},
remote: {
url: getPath() + "/get_tags_json?q=%QUERY"
}
});
var languages = new Bloodhound({
name: "languages",
datumTokenizer: function datumTokenizer(datum) {
return [datum.name];
},
queryTokenizer: function queryTokenizer(query) {
return [query];
},
remote: {
url: getPath() + "/get_languages_json?q=",
replace: function replace(url, query) {
return url + encodeURIComponent(query);
}
}
});
var publishers = new Bloodhound({
name: "publisher",
datumTokenizer: function datumTokenizer(datum) {
return [datum.name];
},
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: getPath() + "/get_publishers_json?q=%QUERY"
}
});
function sourceSplit(query, cb, split, source) { function sourceSplit(query, cb, split, source) {
var bhAdapter = source.ttAdapter();
var tokens = query.split(split); var tokens = query.split(split);
var currentSource = tokens[tokens.length - 1].trim(); var currentSource = tokens[tokens.length - 1].trim();
@ -144,84 +74,148 @@ function sourceSplit(query, cb, split, source) {
for (var i = 0; i < tokens.length; i++) { for (var i = 0; i < tokens.length; i++) {
prefix += tokens[i].trim() + newSplit; prefix += tokens[i].trim() + newSplit;
} }
prefixedSource(prefix, currentSource, cb, bhAdapter); prefixedSource(prefix, currentSource, cb, source);
} }
var promiseAuthors = authors.initialize(); var authors = new Bloodhound({
promiseAuthors.done(function() { name: "authors",
$("#bookAuthor").typeahead( identify: function(obj) { return obj.name; },
{ datumTokenizer: function datumTokenizer(datum) {
highlight: true, minLength: 1, return [datum.name];
hint: true },
}, { queryTokenizer: Bloodhound.tokenizers.whitespace,
name: "authors", remote: {
displayKey: "name", url: getPath() + "/get_authors_json?q=%QUERY",
source: function source(query, cb) { wildcard: '%QUERY',
return sourceSplit(query, cb, "&", authors); //sourceSplit //("&") },
}
}
);
}); });
var promiseSeries = series.initialize(); $(".form-group #bookAuthor").typeahead(
promiseSeries.done(function() { {
$("#series").typeahead( highlight: true,
{ minLength: 1,
highlight: true, minLength: 0, hint: true
hint: true }, {
}, { name: "authors",
name: "series", display: 'name',
displayKey: "name", source: function source(query, cb, asyncResults) {
source: series.ttAdapter() return sourceSplit(query, cb, "&", authors);
} }
); }
);
var series = new Bloodhound({
name: "series",
datumTokenizer: function datumTokenizer(datum) {
return [datum.name];
},
// queryTokenizer: Bloodhound.tokenizers.whitespace,
queryTokenizer: function queryTokenizer(query) {
return [query];
},
remote: {
url: getPath() + "/get_series_json?q=%QUERY",
wildcard: '%QUERY',
/*replace: function replace(url, query) {
return url + encodeURIComponent(query);
}*/
}
});
$(".form-group #series").typeahead(
{
highlight: true,
minLength: 0,
hint: true
}, {
name: "series",
displayKey: "name",
source: series
}
);
var tags = new Bloodhound({
name: "tags",
datumTokenizer: function datumTokenizer(datum) {
return [datum.name];
},
queryTokenizer: function queryTokenizer(query) {
var tokens = query.split(",");
tokens = [tokens[tokens.length - 1].trim()];
return tokens;
},
remote: {
url: getPath() + "/get_tags_json?q=%QUERY",
wildcard: '%QUERY'
}
}); });
var promiseTags = tags.initialize(); $(".form-group #tags").typeahead(
promiseTags.done(function() { {
$("#tags").typeahead( highlight: true,
{ minLength: 0,
highlight: true, minLength: 0, hint: true
hint: true }, {
}, { name: "tags",
name: "tags", display: "name",
displayKey: "name", source: function source(query, cb, asyncResults) {
source: function source(query, cb) { return sourceSplit(query, cb, ",", tags);
return sourceSplit(query, cb, ",", tags);
}
} }
); }
);
var languages = new Bloodhound({
name: "languages",
datumTokenizer: function datumTokenizer(datum) {
return [datum.name];
},
queryTokenizer: function queryTokenizer(query) {
return [query];
},
remote: {
url: getPath() + "/get_languages_json?q=%QUERY",
wildcard: '%QUERY'
/*replace: function replace(url, query) {
return url + encodeURIComponent(query);
}*/
}
}); });
var promiseLanguages = languages.initialize(); $(".form-group #languages").typeahead(
promiseLanguages.done(function() { {
$("#languages").typeahead( highlight: true, minLength: 0,
{ hint: true
highlight: true, minLength: 0, }, {
hint: true name: "languages",
}, { display: "name",
name: "languages", source: function source(query, cb, asyncResults) {
displayKey: "name", return sourceSplit(query, cb, ",", languages);
source: function source(query, cb) {
return sourceSplit(query, cb, ",", languages); //(",")
}
} }
); }
);
var publishers = new Bloodhound({
name: "publisher",
datumTokenizer: function datumTokenizer(datum) {
return [datum.name];
},
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: getPath() + "/get_publishers_json?q=%QUERY",
wildcard: '%QUERY'
}
}); });
var promisePublishers = publishers.initialize(); $(".form-group #publisher").typeahead(
promisePublishers.done(function() { {
$("#publisher").typeahead( highlight: true, minLength: 0,
{ hint: true
highlight: true, minLength: 0, }, {
hint: true name: "publishers",
}, { displayKey: "name",
name: "publishers", source: publishers
displayKey: "name", }
source: publishers.ttAdapter() );
}
);
});
$("#search").on("change input.typeahead:selected", function(event) { $("#search").on("change input.typeahead:selected", function(event) {
if (event.target.type === "search" && event.target.tagName === "INPUT") { if (event.target.type === "search" && event.target.tagName === "INPUT") {

File diff suppressed because it is too large Load Diff

View File

@ -58,11 +58,11 @@
<div class="text-center"> <div class="text-center">
<button type="button" class="btn btn-default" id="xchange" ><span class="glyphicon glyphicon-arrow-up"></span><span class="glyphicon glyphicon-arrow-down"></span></button> <button type="button" class="btn btn-default" id="xchange" ><span class="glyphicon glyphicon-arrow-up"></span><span class="glyphicon glyphicon-arrow-down"></span></button>
</div> </div>
<div id="author_div" class="form-group">
<div class="form-group">
<label for="bookAuthor">{{_('Author')}}</label> <label for="bookAuthor">{{_('Author')}}</label>
<input type="text" class="form-control typeahead" name="author_name" id="bookAuthor" value="{{' & '.join(authors)}}" autocomplete="off"> <input type="text" class="form-control typeahead" name="author_name" id="bookAuthor" value="{{' & '.join(authors)}}" autocomplete="off">
</div> </div>
<div class="form-group"> <div class="form-group">
<label for="description">{{_('Description')}}</label> <label for="description">{{_('Description')}}</label>
<textarea class="form-control" name="description" id="description" rows="7">{% if book.comments %}{{book.comments[0].text}}{%endif%}</textarea> <textarea class="form-control" name="description" id="description" rows="7">{% if book.comments %}{{book.comments[0].text}}{%endif%}</textarea>