Issue #1869 multi-criteria search (#1927)

* First implementation of the new multi-criteria search. It replaces the old search.php form.
* Displays live search criteria above search results. Each change reloads the list of results (displayed as thumbnails).
* New API method pwg.images.filteredSearch.update called in AJAX to live change the filters.
* New kind of filter: added_by
This commit is contained in:
Pierrick Le Gall
2023-06-21 16:11:08 +02:00
committed by GitHub
parent ebcdb34305
commit 60363ecd42
10 changed files with 1468 additions and 246 deletions
+647
View File
@@ -0,0 +1,647 @@
$(document).ready(function () {
related_categories_ids = [];
$(".linkedAlbumPopInContainer .ClosePopIn").addClass("pwg-icon-cancel");
$(".filter-validate").on("click", function () {
$(this).find(".loading").css("display", "block");
$(this).find(".validate-text").hide();
});
$(".filter-form").hover(
function () {
$(this).parent().find(".mcs-icon.remove-filter").css({
display: 'none',
});
$(this).parent().find(".mcs-icon.filter-icon").css({
display: 'block',
});
},
function () {
$(this).parent().find(".mcs-icon.remove-filter").css({
display: 'block',
});
$(this).parent().find(".mcs-icon.filter-icon").css({
display: 'none',
});
});
global_params.search_id = search_id;
console.log("Global params after fetch");
console.log(global_params);
if (!global_params.fields) {
global_params.fields = {};
}
// Declare params sent to pwg.images.filteredSearch.update
PS_params = {};
PS_params.search_id = search_id;
// Setup word filter
if (global_params.fields.allwords) {
$(".filter-word").css("display", "flex");
$(".filter-manager-controller.word").prop("checked", true);
word_search_str = "";
word_search_words = global_params.fields.allwords.words != null ? global_params.fields.allwords.words : [];
word_search_words.forEach(word => {
word_search_str += word + " ";
});
$("#word-search").val(word_search_str.slice(0, -1));
if (global_params.fields.allwords.words && global_params.fields.allwords.words.length > 0) {
$(".filter-word").addClass("filter-filled");
$(".filter-word .search-words").html(word_search_str.slice(0, -1));
} else {
$(".filter-word .search-words").html(str_word_widget);
}
word_search_fields = global_params.fields.allwords.fields;
Object.keys(word_search_fields).forEach(field_key => {
$("#"+word_search_fields[field_key]).prop("checked", true);
});
word_search_mode = global_params.fields.allwords.mode;
$(".word-search-options input[value=" + word_search_mode + "]").prop("checked", true);
if (global_params.fields.search_in_tags) {
$("#tags").prop("checked", true);
}
PS_params.allwords = word_search_str.slice(0, -1);
PS_params.allwords_fields = word_search_fields;
PS_params.allwords_mode = word_search_mode;
}
//Hide filter spinner
$(".filter-spinner").hide();
// Setup tag filter
$("#tag-search").each(function() {
$(this).selectize({
plugins: ['remove_button'],
maxOptions:$(this).find("option").length,
items: global_params.fields.tags ? global_params.fields.tags.words : null,
});
});
if (global_params.fields.tags) {
$(".filter-tag").css("display", "flex");
$(".filter-manager-controller.tags").prop("checked", true);
$(".filter-tag-form .search-params input[value=" + global_params.fields.tags.mode + "]").prop("checked", true);
tag_search_str = "";
$("#tag-search")[0].selectize.getValue().forEach(id => {
tag_search_str += $("#tag-search")[0].selectize.getItem(id).text().replace(/\(\d+ \w+\)×/, '').trim() + ", ";
});
if (global_params.fields.tags.words && global_params.fields.tags.words.length > 0) {
$(".filter-tag").addClass("filter-filled");
$(".filter.filter-tag .search-words").text(tag_search_str.slice(0, -2));
} else {
$(".filter.filter-tag .search-words").text("Tags");
}
PS_params.tags = global_params.fields.tags.words.length > 0 ? global_params.fields.tags.words : '';
PS_params.tags_mode = global_params.fields.tags.mode;
}
// Setup album filter
if (global_params.fields.cat) {
console.log("there is an album in the search");
$(".filter-album").css("display", "flex");
$(".filter-manager-controller.album").prop("checked", true);
album_widget_value = "";
global_params.fields.cat.words.forEach(cat_id => {
add_related_category(cat_id, fullname_of_cat[cat_id]);
album_widget_value += fullname_of_cat[cat_id] + ", ";
});
if (global_params.fields.cat.words && global_params.fields.cat.words.length > 0) {
$(".filter-album").addClass("filter-filled");
$(".filter-album .search-words").html(album_widget_value.slice(0, -2));
} else {
$(".filter-album .search-words").html("Album");
}
if (global_params.fields.cat.sub_inc) {
$("#search-sub-cats").prop("checked", true);
}
PS_params.categories = global_params.fields.cat.words.length > 0 ? global_params.fields.cat.words : '';
PS_params.categories_withsubs = global_params.fields.cat.sub_inc;
}
// Setup author filter
$("#authors").each(function() {
$(this).selectize({
plugins: ['remove_button'],
maxOptions:$(this).find("option").length,
items: global_params.fields.author ? global_params.fields.author.words : null,
});
if (global_params.fields.author) {
$(".filter-author").css("display", "flex");
$(".filter-manager-controller.author").prop("checked", true);
author_search_str = "";
$("#authors")[0].selectize.getValue().forEach(id => {
author_search_str += $("#authors")[0].selectize.getItem(id).text().replace(/\(\d+ \w+\)×/, '').trim() + ", ";
});
if (global_params.fields.author.words && global_params.fields.author.words.length > 0) {
$(".filter-author").addClass("filter-filled");
$(".filter.filter-author .search-words").text(author_search_str.slice(0, -2));
} else {
$(".filter.filter-author .search-words").text("Author");
}
PS_params.authors = global_params.fields.author.words.length > 0 ? global_params.fields.author.words : '';
}
});
// Setup added_by filter
$("#added_by").each(function() {
$(this).selectize({
plugins: ['remove_button'],
maxOptions:$(this).find("option").length,
items: global_params.fields.added_by ? global_params.fields.added_by : null,
});
if (global_params.fields.added_by) {
$(".filter-added_by").css("display", "flex");
$(".filter-manager-controller.added_by").prop("checked", true);
added_search_str = "";
$("#added_by")[0].selectize.getValue().forEach(id => {
added_search_str += $("#added_by")[0].selectize.getItem(id).text().replace(/\(\d+ \w+\)×/, '').trim() + ", ";
});
if (global_params.fields.added_by && global_params.fields.added_by.length > 0) {
$(".filter-added_by").addClass("filter-filled");
$(".filter.filter-added_by .search-words").text(added_search_str.slice(0, -2));
} else {
$(".filter.filter-added_by .search-words").text("Added by");
}
PS_params.added_by = global_params.fields.added_by.length > 0 ? global_params.fields.added_by : '';
}
});
/**
* Filter Manager
*/
$(".filter-manager").on('click', function () {
$(".filter-manager-popin").show();
});
$(document).on('keyup', function (e) {
// 27 is 'Escape'
if(e.keyCode === 27) {
$(".filter-manager-popin").hide();
}
});
$(".filter-manager-popin .filter-cancel, .filter-manager-popin .filter-manager-close").on('click', function () {
$(".filter-manager-popin").hide();
});
$(".filter-manager-popin .filter-validate").on('click', function () {
$(".filter-manager-controller-container input").each(function (e) {
if ($(this).is(':checked')) {
if (!$(".filter.filter-" + $(this).data("wid")).is(':visible')) {
updateFilters($(this).data("wid"), 'add');
}
} else {
if ($(".filter.filter-" + $(this).data("wid")).is(':visible')) {
updateFilters($(this).data("wid"), 'del');
}
}
});
// Set second param to true to trigger reload
performSearch(PS_params ,false);
})
/**
* Filter Word
*/
$(".filter-word").on("click", function (e) {
if ($(".filter-form").has(e.target).length != 0 ||
$(e.target).hasClass("filter-form") ||
$(e.target).hasClass("remove-filter")) {
return;
}
$(".filter-word-form").toggle(0, function () {
if ($(this).is(':visible')) {
$(".filter-word").addClass("show-filter-dropdown");
$("#word-search").focus();
} else {
$(".filter-word").removeClass("show-filter-dropdown");
global_params.fields.allwords = {};
global_params.fields.allwords.words = $("#word-search").val();
global_params.fields.allwords.mode = $(".word-search-options input:checked").attr('value');
PS_params.allwords = $("#word-search").val();
PS_params.allwords_mode = $(".word-search-options input:checked").attr('value');
new_fields = [];
$(".filter-word-form .search-params input:checked").each(function () {
if ($(this).attr("name") == "tags") {
global_params.fields.search_in_tags = true;
}
new_fields.push($(this).attr("name"));
});
if ($(".filter-word-form .search-params input[name='tags']:checked").length == 0) {
delete global_params.fields.search_in_tags;
}
global_params.fields.allwords.fields = new_fields;
PS_params.allwords_fields = new_fields.length > 0 ? new_fields : '';
}
});
});
$(".filter-word .filter-validate").on("click", function () {
$(".filter-word").trigger("click");
performSearch(PS_params, true);
});
$(".filter-word .remove-filter").on("click", function () {
$(this).addClass('pwg-icon-spin6 animate-spin').removeClass('pwg-icon-cancel');
updateFilters('word', 'del');
performSearch(PS_params, $(".filter-word").hasClass("filter-filled"));
if (!$(".filter-word").hasClass("filter-filled")) {
$(".filter-word").hide();
$(".filter-manager-controller.word").prop("checked", false);
}
});
/**
* Filter Tag
*/
$(".filter-tag").on("click", function (e) {
if ($(".filter-form").has(e.target).length != 0 ||
$(e.target).hasClass("filter-form") ||
$(e.target).hasClass("remove") ||
$(e.target).hasClass("remove-filter")) {
return;
}
$(".filter-tag-form").toggle(0, function () {
if ($(this).is(':visible')) {
$(".filter-tag").addClass("show-filter-dropdown");
} else {
$(".filter-tag").removeClass("show-filter-dropdown");
global_params.fields.tags = {};
global_params.fields.tags.mode = $(".filter-tag-form .search-params input:checked").val();
global_params.fields.tags.words = $("#tag-search")[0].selectize.getValue();
PS_params.tags = $("#tag-search")[0].selectize.getValue().length > 0 ? $("#tag-search")[0].selectize.getValue() : '';
PS_params.tags_mode = $(".filter-tag-form .search-params input:checked").val();
}
});
});
$(".filter-tag .filter-validate").on("click", function () {
$(".filter-tag").trigger("click");
performSearch(PS_params, true);
});
$(".filter-tag .remove-filter").on("click", function () {
$(this).addClass('pwg-icon-spin6 animate-spin').removeClass('pwg-icon-cancel');
updateFilters('tag', 'del');
performSearch(PS_params, $(".filter-tag").hasClass("filter-filled"));
if (!$(".filter-tag").hasClass("filter-filled")) {
$(".filter-tag").hide();
$(".filter-manager-controller.tags").prop("checked", false);
}
});
/**
* Filter Date
*/
$(".filter-date").on("click", function (e) {
if ($(".filter-form").has(e.target).length != 0 ||
$(e.target).hasClass("filter-form") ||
$(e.target).hasClass("remove-filter")) {
return;
}
$(".filter-date-form").toggle(0, function () {
if ($(this).is(':visible')) {
$(".filter-date").addClass("show-filter-dropdown");
} else {
$(".filter-date").removeClass("show-filter-dropdown");
performSearch(PS_params, true);
}
});
});
$(".filter-date .remove-filter").on("click", function () {
$(this).addClass('pwg-icon-spin6 animate-spin').removeClass('pwg-icon-cancel');
updateFilters('date', 'del');
performSearch(PS_params, $(".filter-date").hasClass("filter-filled"));
if (!$(".filter-date").hasClass("filter-filled")) {
$(".filter-date").hide();
$(".filter-manager-controller.date").prop("checked", false);
}
});
/**
* Filter Album
*/
$(".filter-album").on("click", function (e) {
if ($(".filter-form").has(e.target).length != 0 ||
$(e.target).hasClass("filter-form") ||
$(e.target).hasClass("remove-item") ||
$(e.target).hasClass("remove-filter")) {
return;
}
$(".filter-album-form").toggle(0, function () {
if ($(this).is(':visible')) {
$(".filter-album").addClass("show-filter-dropdown");
} else {
$(".filter-album").removeClass("show-filter-dropdown");
global_params.fields.cat = {};
global_params.fields.cat.words = related_categories_ids;
// global_params.fields.cat.search_params = $(".filter-form.filter-album-form .search-params input:checked").val().toLowerCase();
global_params.fields.cat.sub_inc = $("input[name='search-sub-cats']:checked").length != 0;
PS_params.categories = related_categories_ids.length > 0 ? related_categories_ids : '';
PS_params.categories_withsubs = $("input[name='search-sub-cats']:checked").length != 0;
}
});
});
$(".filter-album .filter-validate").on("click", function () {
$(".filter-album").trigger("click");
performSearch(PS_params, false);
});
$(".filter-album .remove-filter").on("click", function () {
$(this).addClass('pwg-icon-spin6 animate-spin').removeClass('pwg-icon-cancel');
updateFilters('album', 'del');
performSearch(PS_params, $(".filter-album").hasClass("filter-filled"));
if (!$(".filter-album").hasClass("filter-filled")) {
$(".filter-album").hide();
$(".filter-manager-controller.album").prop("checked", false);
}
});
$(".add-album-button").on("click", function () {
linked_albums_open();
set_up_popin();
});
$("#linkedAlbumSearch .search-input").on('input', function () {
if ($(this).val() != 0) {
$("#linkedAlbumSearch .search-cancel-linked-album").show();
} else {
$("#linkedAlbumSearch .search-cancel-linked-album").hide();
}
// Search input value length required to start searching
if ($(this).val().length > 0) {
linked_albums_search($(this).val());
} else {
$(".limitReached").html(str_no_search_in_progress);
$("#searchResult").empty();
}
})
/**
* Author Widget
*/
$(".filter-author").on("click", function (e) {
if ($(".filter-form").has(e.target).length != 0 ||
$(e.target).hasClass("filter-form") ||
$(e.target).hasClass("remove") ||
$(e.target).hasClass("remove-filter")) {
return;
}
$(".filter-author-form").toggle(0, function () {
if ($(this).is(':visible')) {
$(".filter-author").addClass("show-filter-dropdown");
} else {
$(".filter-author").removeClass("show-filter-dropdown");
global_params.fields.author = {};
global_params.fields.author.mode = "OR";
global_params.fields.author.words = $("#authors")[0].selectize.getValue();
PS_params.authors = $("#authors")[0].selectize.getValue().length > 0 ? $("#authors")[0].selectize.getValue() : '';
}
});
});
$(".filter-author .filter-validate").on("click", function () {
$(".filter-author").trigger("click");
performSearch(PS_params, true);
});
$(".filter-author .remove-filter").on("click", function () {
$(this).addClass('pwg-icon-spin6 animate-spin').removeClass('pwg-icon-cancel');
updateFilters('authors', 'del');
performSearch(PS_params, $(".filter-author").hasClass("filter-filled"));
if (!$(".filter-author").hasClass("filter-filled")) {
$(".filter-author").hide();
$(".filter-manager-controller.author").prop("checked", false);
}
});
/**
* Added by Widget
*/
$(".filter-added_by").on("click", function (e) {
if ($(".filter-form").has(e.target).length != 0 ||
$(e.target).hasClass("filter-form") ||
$(e.target).hasClass("remove") ||
$(e.target).hasClass("remove-filter")) {
return;
}
$(".filter-added_by-form").toggle(0, function () {
if ($(this).is(':visible')) {
$(".filter-added_by").addClass("show-filter-dropdown");
} else {
$(".filter-added_by").removeClass("show-filter-dropdown");
global_params.fields.added_by = {};
global_params.fields.added_by.mode = "OR";
global_params.fields.added_by.words = $("#added_by")[0].selectize.getValue();
PS_params.added_by = $("#added_by")[0].selectize.getValue().length > 0 ? $("#added_by")[0].selectize.getValue() : '';
}
});
});
$(".filter-added_by .filter-validate").on("click", function () {
$(".filter-added_by").trigger("click");
performSearch(PS_params, true);
});
$(".filter-added_by .remove-filter").on("click", function () {
$(this).addClass('pwg-icon-spin6 animate-spin').removeClass('pwg-icon-cancel');
updateFilters('added_by', 'del');
performSearch(PS_params, $(".filter-added_by").hasClass("filter-filled"));
if (!$(".filter-added_by").hasClass("filter-filled")) {
$(".filter-added_by").hide();
$(".filter-manager-controller.added_by").prop("checked", false);
}
});
/* Close dropdowns if you click on the screen */
// $(document).mouseup(function (e) {
// e.stopPropagation();
// let option_is_clicked = false
// $(".mcs-container .filter").each(function () {
// console.log(($(this).hasClass("show-filter-dropdown")));
// if (!($(this).has(e.target).length === 0)) {
// option_is_clicked = true;
// }
// })
// if (!option_is_clicked) {
// $(".filter-form").hide();
// if ($(".show-filter-dropdown").length != 0) {
// $(".show-filter-dropdown").removeClass("show-filter-dropdown");
// performSearch();
// }
// }
// });
})
function performSearch(params, reload = false) {
console.log("params sent to updatesearch");
console.log(params);
$.ajax({
url: "ws.php?format=json&method=pwg.images.filteredSearch.update",
type:"POST",
dataType: "json",
data: PS_params,
success:function(data) {
console.log("perform search");
console.log(data);
if (reload) {
reloadPage();
}
},
error:function(e) {
console.log(e);
},
}).done(function () {
console.log('ajax ended');
$(".filter-validate").find(".validate-text").css("display", "block");
$(".filter-validate").find(".loading").hide();
$(".remove-filter").removeClass('pwg-icon-spin6 animate-spin').addClass('pwg-icon-cancel');
});
}
function set_up_popin() {
$(".ClosePopIn").on('click', function () {
linked_albums_close();
});
$("#addLinkedAlbum").on('keyup', function (e) {
// 27 is 'Escape'
if(e.keyCode === 27) {
linked_albums_close();
}
})
}
function linked_albums_close() {
$("#addLinkedAlbum").fadeOut();
}
function fill_results(cats) {
$("#searchResult").empty();
cats.forEach(cat => {
if (!related_categories_ids.includes(cat.id)) {
$("#searchResult").append(
"<div class='search-result-item' id="+ cat.id + ">" +
"<span class='search-result-path'>" + cat.name +"</span><span id="+ cat.id + " class='icon-plus-circled item-add'></span>" +
"</div>"
);
$(".search-result-item#"+ cat.id).on("click", function () {
add_related_category(cat.id, cat.name);
});
}
});
}
function add_related_category(cat_id, cat_link_path) {
$(".selected-categories-container").append(
"<div class='breadcrumb-item'>" +
"<span class='link-path'>" + cat_link_path + "</span><span id="+ cat_id + " class='mcs-icon pwg-icon-close remove-item'></span>" +
"</div>"
);
related_categories_ids.push(cat_id);
$(".invisible-related-categories-select").append("<option selected value="+ cat_id +"></option>");
$("#"+ cat_id).on("click", function () {
remove_related_category($(this).attr("id"));
});
linked_albums_close();
}
function remove_related_category(cat_id) {
$("#" + cat_id).parent().remove();
cat_to_remove_index = related_categories_ids.indexOf(parseInt(cat_id));
if (cat_to_remove_index > -1) {
related_categories_ids.splice(cat_to_remove_index, 1);
}
if (related_categories_ids.length === 0) {
related_categories_ids = '';
}
}
function updateFilters(filterName, mode) {
switch (filterName) {
case 'word':
if (mode == 'add') {
global_params.fields.allwords = {};
PS_params.allwords = '';
PS_params.allwords_mode = 'AND';
PS_params.allwords_fields = [];
} else if (mode == 'del') {
delete global_params.fields.allwords;
delete PS_params.allwords;
delete PS_params.allwords_mode;
delete PS_params.allwords_fields;
}
break;
case 'tag':
if (mode == 'add') {
global_params.fields.tags = {};
PS_params.tags = '';
PS_params.tags_mode = 'AND';
} else if (mode == 'del') {
delete global_params.fields.tags;
delete PS_params.tags;
delete PS_params.tags_mode;
}
break;
case 'album':
if (mode == 'add') {
global_params.fields.cat = {};
PS_params.categories = '';
PS_params.categories_withsubs = false;
} else if (mode == 'del') {
delete global_params.fields.cat;
delete PS_params.categories;
delete PS_params.categories_withsubs;
}
break;
default:
if (mode == 'add') {
global_params.fields[filterName] = {};
PS_params[filterName] = '';
} else if (mode == 'del') {
delete global_params.fields[filterName];
delete PS_params[filterName];
}
break;
}
}
function reloadPage(){
location.reload(true);
}
+286
View File
@@ -1,6 +1,25 @@
{combine_script id='core.switchbox' load='async' require='jquery' path='themes/default/js/switchbox.js'}
{combine_script id='jquery.selectize' load='footer' path='themes/default/js/plugins/selectize.min.js'}
{combine_css path="admin/themes/default/fontello/css/animation.css" order=10} {* order 10 is required, see issue 1080 *}
{$MENUBAR}
{footer_script}
{if isset($GP)}
global_params = {$GP};
{/if}
{if isset($fullname_of)}
fullname_of_cat = {$fullname_of};
{/if}
{if isset($SEARCH_ID)}
search_id = {$SEARCH_ID};
{/if}
str_word_widget = "{'Search for words'|@translate}";
{/footer_script}
{if isset($errors) or isset($infos)}
<div class="content messages{if isset($MENUBAR)} contentWithMenu{/if}">
@@ -171,11 +190,278 @@
{include file='navigation_bar.tpl'|@get_extent:'navbar' navbar=$cats_navbar}
{/if}
{if !empty($SEARCH_ID)}
{combine_script id='mcs' load='async' require='jquery' path='themes/default/js/mcs.js'}
{* Recherche multicritère *}
<div class="mcs-container">
<div class="filter-manager-popin">
<div class="filter-manager-popin-container">
<span class="pwg-icon-cancel filter-manager-close"></span>
<div class="mcs-popin-title">Filtres</div>
<div class="filter-manager-controller-container">
<label>
<input data-wid='word' class="filter-manager-controller word" type="checkbox"/>
<span class="mcs-icon pwg-icon-search">{'Search for words'|@translate}</span>
</label>
<label>
<input data-wid='tag' class="filter-manager-controller tags" type="checkbox"/>
<span class="mcs-icon pwg-icon-tag">Tags</span>
</label>
<label>
<input data-wid='album' class="filter-manager-controller album" type="checkbox"/>
<span class="mcs-icon pwg-icon-album">Album</span>
</label>
<label>
<input data-wid='authors' class="filter-manager-controller author" type="checkbox"/>
<span class="mcs-icon pwg-icon-user-edit">Authors</span>
</label>
<label>
<input data-wid='added_by' class="filter-manager-controller added_by" type="checkbox"/>
<span class="mcs-icon pwg-icon-user">Added by</span>
</label>
</div>
<div class="filter-manager-actions">
<div class="filter-cancel">
Cancel
</div>
<div class="filter-validate">
<i class="loading pwg-icon-spin6 animate-spin"></i>
<span class="validate-text">Validate</span>
</div>
</div>
</div>
</div>
<div class="filter-manager">
<span class="mcs-icon pwg-icon-cog"></span>Filters
</div>
<i class="filter-spinner pwg-icon-spin6 animate-spin"></i>
<div class="filter filter-word">
<span class="mcs-icon pwg-icon-search filter-icon"></span>
<span class="mcs-icon pwg-icon-cancel remove-filter"></span>
<span class="search-words"></span>
<span class="filter-arrow pwg-icon-up-open"></span>
<div class="filter-form filter-word-form">
<div class="filter-form-title">{'Search for words'|@translate}</div>
{* <span class="word-help"><i class="pwg-icon-help-circled"></i>Conseils de recherche</span> *}
<div class="word-search-options">
<label><input type="radio" name="mode" value="AND" checked> {'Search for all terms'|@translate}</label>
<label><input type="radio" name="mode" value="OR"> {'Search for any term'|@translate}</label>
</div>
<input type="text" id="word-search" name="word">
<span class="search-params-title">Search in :</span>
<div class="search-params">
<div>
<input type="checkbox" id="cat-title" name="cat-title">
<label for="cat-title">Album title</label>
</div>
<div>
<input type="checkbox" id="tags" name="tags">
<label for="tags">Tags</label>
</div>
<div>
<input type="checkbox" id="file" name="file">
<label for="file">File name</label>
</div>
<div>
<input type="checkbox" id="name" name="name">
<label for="name">Photo title</label>
</div>
<div>
<input type="checkbox" id="comment" name="comment">
<label for="comment">Photo description</label>
</div>
<div>
<input type="checkbox" id="cat-desc" name="cat-desc">
<label for="cat-desc">Album description</label>
</div>
</div>
<div class="filter-validate">
<i class="loading pwg-icon-spin6 animate-spin"></i>
<span class="validate-text">Validate</span>
</div>
</div>
</div>
<div class="filter filter-tag">
<span class="mcs-icon pwg-icon-tag filter-icon"></span>
<span class="mcs-icon pwg-icon-cancel remove-filter"></span>
<span class="search-words"></span>
<span class="filter-arrow pwg-icon-up-open"></span>
<div class="filter-form filter-tag-form">
<div class="filter-form-title">Tags</div>
<div class="search-params">
<div>
<input type="radio" id="tag-all" name="tag_mode" value="AND" checked>
<label for="tag-all">{'All tags'|@translate}</label>
</div>
<div>
<input type="radio" id="tag-one" name="tag_mode" value="OR">
<label for="tag-one">{'Any tag'|@translate}</label>
</div>
</div>
<select id="tag-search" placeholder="{'Type in a search term'|translate}" name="tags[]" multiple>
{foreach from=$TAGS item=tag}
<option value="{$tag.id}">{$tag.name} ({$tag.counter|translate_dec:'%d photo':'%d photos'})</option>
{/foreach}
</select>
<div class="filter-validate">
<i class="loading pwg-icon-spin6 animate-spin"></i>
<span class="validate-text">Validate</span>
</div>
</div>
</div>
{* <div class="filter filter-date">
<span class="mcs-icon pwg-icon-calendar"></span>Date: <span class="search-words">Balloon</span><span class="filter-arrow pwg-icon-up-open"></span>
<div class="filter-form filter-date-form">
// Still in porgress
<div class="row">
<div class="col-sm-12" id="htmlTarget">
<label for="datetimepicker1Input" class="form-label">Picker</label>
<div class="input-group log-event" id="datetimepicker1" data-td-target-input="nearest" data-td-target-toggle="nearest">
<input id="datetimepicker1Input" type="text" class="form-control" data-td-target="#datetimepicker1">
<span class="input-group-text" data-td-target="#datetimepicker1" data-td-toggle="datetimepicker">
<i class="fas fa-calendar">blavvla</i>
</span>
</div>
</div>
</div>
</div>
</div> *}
<div class="filter filter-album">
<span class="mcs-icon pwg-icon-album filter-icon"></span>
<span class="mcs-icon pwg-icon-cancel remove-filter"></span>
<span class="search-words"></span>
<span class="filter-arrow pwg-icon-up-open"></span>
<div class="filter-form filter-album-form">
<div class="filter-form-title">Album</div>
<div class="search-params">
{* <div>
<input type="radio" id="album-all" name="album_mode" value="ALL" checked>
<label for="album-all">{'All albums'|@translate}</label>
</div>
<div>
<input type="radio" id="album-any" name="album_mode" value="ANY">
<label for="album-any">{'Any album'|@translate}</label>
</div> *}
</div>
<div class="selected-categories-container">
</div>
<div class="add-album-button">
<label class="head-button-2 icon-add-album">
<p class="mcs-icon pwg-icon-close">{'Add Album'|@translate}</p>
</label>
</div>
<div class="search-sub-cats">
<input type="checkbox" id="search-sub-cats" name="search-sub-cats">
<label for="search-sub-cats">Search in sub-albums</label>
</div>
<div class="filter-validate">
<i class="loading pwg-icon-spin6 animate-spin"></i>
<span class="validate-text">Validate</span>
</div>
</div>
</div>
{include file='admin/themes/default/template/include/album_selector.inc.tpl'
title={'Search in album'|@translate}
searchPlaceholder={'Search'|@translate}
show_root_btn=false
api_method='pwg.categories.getList'
}
<div class="filter filter-author">
<span class="mcs-icon pwg-icon-user-edit filter-icon"></span>
<span class="mcs-icon pwg-icon-cancel remove-filter"></span>
<span class="search-words"></span>
<span class="filter-arrow pwg-icon-up-open"></span>
<div class="filter-form filter-author-form">
<div class="filter-form-title">Author</div>
<select id="authors" placeholder="{'Type in a search term'|translate}" name="authors[]" multiple>
{foreach from=$AUTHORS item=author}
<option value="{$author.author|strip_tags:false|escape:html}">{$author.author|strip_tags:false} ({$author.counter|translate_dec:'%d photo':'%d photos'})</option>
{/foreach}
</select>
<div class="filter-validate">
<i class="loading pwg-icon-spin6 animate-spin"></i>
<span class="validate-text">Validate</span>
</div>
</div>
</div>
<div class="filter filter-added_by">
<span class="mcs-icon pwg-icon-user filter-icon"></span>
<span class="mcs-icon pwg-icon-cancel remove-filter"></span>
</span><span class="search-words"></span>
<span class="filter-arrow pwg-icon-up-open"></span>
<div class="filter-form filter-added_by-form">
<div class="filter-form-title">Added by</div>
<select id="added_by" placeholder="{'Type in a search term'|translate}" name="added_by[]" multiple>
{foreach from=$ADDED_BY item=added_by}
<option value="{$added_by.added_by_id|strip_tags:false|escape:html}">{$added_by.added_by_name|strip_tags:false}<span class="badge">({$added_by.counter|translate_dec:'%d photo':'%d photos'})</span></option>
{/foreach}
</select>
<div class="filter-validate">
<i class="loading pwg-icon-spin6 animate-spin"></i>
<span class="validate-text">Validate</span>
</div>
</div>
</div>
{* <div class="filter filter-note">
Note div
<div class="filter-form filter-note-form">
</div>
</div>
<div class="filter filter-height">
Height div
<div class="filter-form filter-height-form">
</div>
</div>
<div class="filter filter-width">
Width div
<div class="filter-form filter-width-form">
</div>
</div>
<div class="filter filter-file-type">
File type div
<div class="filter-form filter-file-type-form">
</div>
</div>
<div class="filter filter-file-size">
File size div
<div class="filter-form filter-file-size-form">
</div>
</div> *}
</div>
{/if}
{if !empty($THUMBNAILS)}
<div class="loader"><img src="{$ROOT_URL}{$themeconf.img_dir}/ajax_loader.gif"></div>
<ul class="thumbnails" id="thumbnails">
{$THUMBNAILS}
</ul>
{else}
<div class="mcs-no-result">
<div class="text">
<span>No results are available.</span>
<span>You can try to edit your filters and perform a new search.</span>
</div>
</div>
{/if}
{if !empty($thumb_navbar)}
{include file='navigation_bar.tpl'|@get_extent:'navbar' navbar=$thumb_navbar}