mirror of
				https://github.com/janeczku/calibre-web
				synced 2025-11-04 01:03:02 +00:00 
			
		
		
		
	Advanced search tags are now multiselects (#1240)
This commit is contained in:
		@@ -249,18 +249,26 @@ promisePublishers.done(function() {
 | 
				
			|||||||
    );
 | 
					    );
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
$("#search").on("change input.typeahead:selected", function() {
 | 
					$("#search").on("change input.typeahead:selected", function(event) {
 | 
				
			||||||
 | 
					    if (event.target.type == "search" && event.target.tagName == "INPUT") {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    var form = $("form").serialize();
 | 
					    var form = $("form").serialize();
 | 
				
			||||||
    $.getJSON( getPath() + "/get_matching_tags", form, function( data ) {
 | 
					    $.getJSON( getPath() + "/get_matching_tags", form, function( data ) {
 | 
				
			||||||
        $(".tags_click").each(function() {
 | 
					        $(".tags_click").each(function() {
 | 
				
			||||||
            if ($.inArray(parseInt($(this).children("input").first().val(), 10), data.tags) === -1 ) {
 | 
					            if ($.inArray(parseInt($(this).val(), 10), data.tags) === -1) {
 | 
				
			||||||
                if (!($(this).hasClass("active"))) {
 | 
					                if(!$(this).prop("selected")) {
 | 
				
			||||||
                    $(this).addClass("disabled");
 | 
					                    $(this).prop("disabled", true);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            } else {
 | 
					            } else {
 | 
				
			||||||
                $(this).removeClass("disabled");
 | 
					                $(this).prop("disabled", false);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
 | 
					        $("#include_tag option:selected").each(function () {
 | 
				
			||||||
 | 
					            $("#exclude_tag").find("[value="+$(this).val()+"]").prop("disabled", true);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        $('#include_tag').selectpicker("refresh");
 | 
				
			||||||
 | 
					        $('#exclude_tag').selectpicker("refresh");
 | 
				
			||||||
    });
 | 
					    });
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -42,17 +42,17 @@
 | 
				
			|||||||
    <div class="row">
 | 
					    <div class="row">
 | 
				
			||||||
      <div class="form-group col-sm-6" id="tag">
 | 
					      <div class="form-group col-sm-6" id="tag">
 | 
				
			||||||
        <div><label for="include_tag">{{_('Tags')}}</label></div>
 | 
					        <div><label for="include_tag">{{_('Tags')}}</label></div>
 | 
				
			||||||
        <select class="selectpicker" data-live-search="true" data-style="btn-primary" multiple>
 | 
					        <select class="selectpicker" name="include_tag" id="include_tag" data-live-search="true" data-style="btn-primary" multiple>
 | 
				
			||||||
          {% for tag in tags %}
 | 
					          {% for tag in tags %}
 | 
				
			||||||
            <option value="{{tag.id}}">{{tag.name}}</option>
 | 
					            <option class="tags_click" value="{{tag.id}}">{{tag.name}}</option>
 | 
				
			||||||
          {% endfor %}
 | 
					          {% endfor %}
 | 
				
			||||||
        </select>
 | 
					        </select>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
      <div class="form-group col-sm-6">
 | 
					      <div class="form-group col-sm-6">
 | 
				
			||||||
        <div><label for="exclude_tag">{{_('Exclude Tags')}}</label></div>
 | 
					        <div><label for="exclude_tag">{{_('Exclude Tags')}}</label></div>
 | 
				
			||||||
        <select class="selectpicker" data-live-search="true" data-style="btn-danger" multiple>
 | 
					        <select class="selectpicker" name="exclude_tag" id="exclude_tag" data-live-search="true" data-style="btn-danger" multiple>
 | 
				
			||||||
          {% for tag in tags %}
 | 
					          {% for tag in tags %}
 | 
				
			||||||
            <option value="{{tag.id}}">{{tag.name}}</option>
 | 
					            <option  class="tags_click" value="{{tag.id}}">{{tag.name}}</option>
 | 
				
			||||||
          {% endfor %}
 | 
					          {% endfor %}
 | 
				
			||||||
        </select>
 | 
					        </select>
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
@@ -60,7 +60,7 @@
 | 
				
			|||||||
    <div class="row">
 | 
					    <div class="row">
 | 
				
			||||||
      <div class="form-group col-sm-6">
 | 
					      <div class="form-group col-sm-6">
 | 
				
			||||||
        <div><label for="include_serie">{{_('Series')}}</label></div>
 | 
					        <div><label for="include_serie">{{_('Series')}}</label></div>
 | 
				
			||||||
        <select class="selectpicker" data-live-search="true" data-style="btn-primary" multiple>
 | 
					        <select class="selectpicker" name="include_serie" id="include_serie" data-live-search="true" data-style="btn-primary" multiple>
 | 
				
			||||||
          {% for serie in series %}
 | 
					          {% for serie in series %}
 | 
				
			||||||
            <option value="{{serie.id}}">{{serie.name}}</option>
 | 
					            <option value="{{serie.id}}">{{serie.name}}</option>
 | 
				
			||||||
          {% endfor %}
 | 
					          {% endfor %}
 | 
				
			||||||
@@ -68,7 +68,7 @@
 | 
				
			|||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
      <div class="form-group col-sm-6">
 | 
					      <div class="form-group col-sm-6">
 | 
				
			||||||
        <div><label for="exclude_serie">{{_('Exclude Series')}}</label></div>
 | 
					        <div><label for="exclude_serie">{{_('Exclude Series')}}</label></div>
 | 
				
			||||||
        <select class="selectpicker" data-live-search="true" data-style="btn-danger" multiple>
 | 
					        <select class="selectpicker" name="exclude_serie" id="exclude_serie" data-live-search="true" data-style="btn-danger" multiple>
 | 
				
			||||||
          {% for serie in series %}
 | 
					          {% for serie in series %}
 | 
				
			||||||
            <option value="{{serie.id}}">{{serie.name}}</option>
 | 
					            <option value="{{serie.id}}">{{serie.name}}</option>
 | 
				
			||||||
          {% endfor %}
 | 
					          {% endfor %}
 | 
				
			||||||
@@ -79,7 +79,7 @@
 | 
				
			|||||||
    <div class="row">
 | 
					    <div class="row">
 | 
				
			||||||
      <div class="form-group col-sm-6">
 | 
					      <div class="form-group col-sm-6">
 | 
				
			||||||
        <div><label for="include_language">{{_('Languages')}}</label></div>
 | 
					        <div><label for="include_language">{{_('Languages')}}</label></div>
 | 
				
			||||||
        <select class="selectpicker" data-live-search="true" data-style="btn-primary" multiple>
 | 
					        <select class="selectpicker" name="include_language" id="include_language" data-live-search="true" data-style="btn-primary" multiple>
 | 
				
			||||||
          {% for language in languages %}
 | 
					          {% for language in languages %}
 | 
				
			||||||
            <option value="{{language.id}}">{{language.name}}</option>
 | 
					            <option value="{{language.id}}">{{language.name}}</option>
 | 
				
			||||||
          {% endfor %}
 | 
					          {% endfor %}
 | 
				
			||||||
@@ -87,7 +87,7 @@
 | 
				
			|||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
      <div class="form-group col-sm-6">
 | 
					      <div class="form-group col-sm-6">
 | 
				
			||||||
        <div><label for="exclude_language">{{_('Exclude Languages')}}</label></div>
 | 
					        <div><label for="exclude_language">{{_('Exclude Languages')}}</label></div>
 | 
				
			||||||
        <select class="selectpicker" data-live-search="true" data-style="btn-danger" multiple>
 | 
					        <select class="selectpicker" name="exclude_language" id="exclude_language" data-live-search="true" data-style="btn-danger" multiple>
 | 
				
			||||||
          {% for language in languages %}
 | 
					          {% for language in languages %}
 | 
				
			||||||
            <option value="{{language.id}}">{{language.name}}</option>
 | 
					            <option value="{{language.id}}">{{language.name}}</option>
 | 
				
			||||||
          {% endfor %}
 | 
					          {% endfor %}
 | 
				
			||||||
@@ -98,7 +98,7 @@
 | 
				
			|||||||
    <div class="row">
 | 
					    <div class="row">
 | 
				
			||||||
        <div class="form-group col-sm-6">
 | 
					        <div class="form-group col-sm-6">
 | 
				
			||||||
        <div><label for="include_extension">{{_('Extensions')}}</label></div>
 | 
					        <div><label for="include_extension">{{_('Extensions')}}</label></div>
 | 
				
			||||||
        <select id="include_extension" class="selectpicker" data-live-search="true" data-style="btn-primary" multiple>
 | 
					        <select id="include_extension" class="selectpicker" name="include_extension" id="include_extension" data-live-search="true" data-style="btn-primary" multiple>
 | 
				
			||||||
        {% for extension in extensions %}
 | 
					        {% for extension in extensions %}
 | 
				
			||||||
            <option value="{{extension.format}}">{{extension.format}}</option>
 | 
					            <option value="{{extension.format}}">{{extension.format}}</option>
 | 
				
			||||||
          {% endfor %}
 | 
					          {% endfor %}
 | 
				
			||||||
@@ -106,7 +106,7 @@
 | 
				
			|||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        <div class="form-group col-sm-6">
 | 
					        <div class="form-group col-sm-6">
 | 
				
			||||||
        <div><label for="exclude_extension">{{_('Exclude Extensions')}}</label></div>
 | 
					        <div><label for="exclude_extension">{{_('Exclude Extensions')}}</label></div>
 | 
				
			||||||
        <select id="exclude_extension" class="selectpicker" data-live-search="true" data-style="btn-danger" multiple>
 | 
					        <select id="exclude_extension" class="selectpicker" name="exclude_extension" id="exclude_extension" data-live-search="true" data-style="btn-danger" multiple>
 | 
				
			||||||
        {% for extension in extensions %}
 | 
					        {% for extension in extensions %}
 | 
				
			||||||
            <option value="{{extension.format}}">{{extension.format}}</option>
 | 
					            <option value="{{extension.format}}">{{extension.format}}</option>
 | 
				
			||||||
          {% endfor %}
 | 
					          {% endfor %}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -335,8 +335,6 @@ def get_matching_tags():
 | 
				
			|||||||
    title_input = request.args.get('book_title') or ''
 | 
					    title_input = request.args.get('book_title') or ''
 | 
				
			||||||
    include_tag_inputs = request.args.getlist('include_tag') or ''
 | 
					    include_tag_inputs = request.args.getlist('include_tag') or ''
 | 
				
			||||||
    exclude_tag_inputs = request.args.getlist('exclude_tag') or ''
 | 
					    exclude_tag_inputs = request.args.getlist('exclude_tag') or ''
 | 
				
			||||||
    # include_extension_inputs = request.args.getlist('include_extension') or ''
 | 
					 | 
				
			||||||
    # exclude_extension_inputs = request.args.getlist('exclude_extension') or ''
 | 
					 | 
				
			||||||
    q = q.filter(db.Books.authors.any(func.lower(db.Authors.name).ilike("%" + author_input + "%")),
 | 
					    q = q.filter(db.Books.authors.any(func.lower(db.Authors.name).ilike("%" + author_input + "%")),
 | 
				
			||||||
                 func.lower(db.Books.title).ilike("%" + title_input + "%"))
 | 
					                 func.lower(db.Books.title).ilike("%" + title_input + "%"))
 | 
				
			||||||
    if len(include_tag_inputs) > 0:
 | 
					    if len(include_tag_inputs) > 0:
 | 
				
			||||||
@@ -1067,8 +1065,12 @@ def render_adv_search_results(term, offset=None, order=None, limit=None):
 | 
				
			|||||||
                pub_start = u""
 | 
					                pub_start = u""
 | 
				
			||||||
        tag_names = calibre_db.session.query(db.Tags).filter(db.Tags.id.in_(include_tag_inputs)).all()
 | 
					        tag_names = calibre_db.session.query(db.Tags).filter(db.Tags.id.in_(include_tag_inputs)).all()
 | 
				
			||||||
        searchterm.extend(tag.name for tag in tag_names)
 | 
					        searchterm.extend(tag.name for tag in tag_names)
 | 
				
			||||||
 | 
					        tag_names = calibre_db.session.query(db.Tags).filter(db.Tags.id.in_(exclude_tag_inputs)).all()
 | 
				
			||||||
 | 
					        searchterm.extend(tag.name for tag in tag_names)
 | 
				
			||||||
        serie_names = calibre_db.session.query(db.Series).filter(db.Series.id.in_(include_series_inputs)).all()
 | 
					        serie_names = calibre_db.session.query(db.Series).filter(db.Series.id.in_(include_series_inputs)).all()
 | 
				
			||||||
        searchterm.extend(serie.name for serie in serie_names)
 | 
					        searchterm.extend(serie.name for serie in serie_names)
 | 
				
			||||||
 | 
					        serie_names = calibre_db.session.query(db.Series).filter(db.Series.id.in_(exclude_series_inputs)).all()
 | 
				
			||||||
 | 
					        searchterm.extend(serie.name for serie in serie_names)
 | 
				
			||||||
        language_names = calibre_db.session.query(db.Languages).\
 | 
					        language_names = calibre_db.session.query(db.Languages).\
 | 
				
			||||||
            filter(db.Languages.id.in_(include_languages_inputs)).all()
 | 
					            filter(db.Languages.id.in_(include_languages_inputs)).all()
 | 
				
			||||||
        if language_names:
 | 
					        if language_names:
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user