Added HDBits Category, Codec, and Medium Filtering Capability (#1458)

* Added advanced configuration options to support filtering Categories, Codecs, and Medium to the HDBits indexer.

* Changes to use the existing tags with a controlled vocabulary.

* 1) Sorting select options by name
2) Moved the autocomplete tag code into taginput as requested

* removed commented out line

* require cleanups
This commit is contained in:
randellhodges
2017-05-29 10:56:16 -05:00
committed by Leonardo Galli
parent 86634006e5
commit 3d48da2111
7 changed files with 129 additions and 52 deletions

View File

@@ -1,8 +1,8 @@
<div class="form-group {{#if advanced}}advanced-setting{{/if}}">
<div class="form-group {{#if advanced}}advanced-setting{{/if}}">
<label class="col-sm-3 control-label">{{label}}</label>
<div class="col-sm-5">
<input type="text" name="fields.{{order}}.value" validation-name="{{name}}" class="form-control x-form-tag"/>
<input type="text" name="fields.{{order}}.value" validation-name="{{name}}" tag-source="{{json selectOptions}}" class="form-control x-form-tag"/>
</div>
{{> FormHelpPartial}}

View File

@@ -1,7 +1,11 @@
var Handlebars = require('handlebars');
var Handlebars = require('handlebars');
Handlebars.registerHelper('TitleCase', function(input) {
return new Handlebars.SafeString(input.replace(/\w\S*/g, function(txt) {
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
}));
});
Handlebars.registerHelper('json', function (obj) {
return JSON.stringify(obj);
});

View File

@@ -1,14 +1,14 @@
var $ = require('jquery');
var $ = require('jquery');
var _ = require('underscore');
var TagCollection = require('../Tags/TagCollection');
var TagModel = require('../Tags/TagModel');
require('bootstrap.tagsinput');
var substringMatcher = function(tagCollection) {
var substringMatcher = function(tags, selector) {
return function findMatches (q, cb) {
q = q.replace(/[^-_a-z0-9]/gi, '').toLowerCase();
var matches = _.select(tagCollection.toJSON(), function(tag) {
return tag.label.toLowerCase().indexOf(q) > -1;
var matches = _.select(tags, function(tag) {
return selector(tag).toLowerCase().indexOf(q) > -1;
});
cb(matches);
};
@@ -108,49 +108,91 @@ $.fn.tagsinput.Constructor.prototype.build = function(options) {
};
$.fn.tagInput = function(options) {
options = $.extend({}, { allowNew : true }, options);
var input = this;
var model = options.model;
var property = options.property;
this.each(function () {
var tagInput = $(this).tagsinput({
tagCollection : TagCollection,
freeInput : true,
allowNew : options.allowNew,
itemValue : 'id',
itemText : 'label',
trimValue : true,
typeaheadjs : {
name : 'tags',
displayKey : 'label',
source : substringMatcher(TagCollection)
var input = $(this);
var tagInput = null;
if (input[0].hasAttribute('tag-source')) {
var listItems = JSON.parse(input.attr('tag-source'));
tagInput = input.tagsinput({
freeInput: false,
allowNew: false,
allowDuplicates: false,
itemValue: 'value',
itemText: 'name',
typeaheadjs: {
displayKey: 'name',
source: substringMatcher(listItems, function (t) { return t.name; })
}
});
var origValue = input.val();
input.tagsinput('removeAll');
if (origValue) {
_.each(origValue.split(','), function (v) {
var parsed = parseInt(v);
var found = _.find(listItems, function (t) { return t.value === parsed; });
if (found) {
input.tagsinput('add', found);
}
});
}
}
else {
options = $.extend({}, { allowNew: true }, options);
var model = options.model;
var property = options.property;
tagInput = input.tagsinput({
tagCollection: TagCollection,
freeInput: true,
allowNew: options.allowNew,
itemValue: 'id',
itemText: 'label',
trimValue: true,
typeaheadjs: {
name: 'tags',
displayKey: 'label',
source: substringMatcher(TagCollection.toJSON(), function (t) { return t.label; })
}
});
//Override the free input being set to false because we're using objects
$(tagInput)[0].options.freeInput = true;
if (model) {
var tags = getExistingTags(model.get(property));
//Remove any existing tags and re-add them
input.tagsinput('removeAll');
_.each(tags, function (tag) {
input.tagsinput('add', tag);
});
input.tagsinput('refresh');
input.on('itemAdded', function (event) {
var tags = model.get(property);
tags.push(event.item.id);
model.set(property, tags);
});
input.on('itemRemoved', function (event) {
if (!event.item) {
return;
}
var tags = _.without(model.get(property), event.item.id);
model.set(property, tags);
});
}
}
});
//Override the free input being set to false because we're using objects
$(tagInput)[0].options.freeInput = true;
if (model) {
var tags = getExistingTags(model.get(property));
//Remove any existing tags and re-add them
$(this).tagsinput('removeAll');
_.each(tags, function(tag) {
$(input).tagsinput('add', tag);
});
$(this).tagsinput('refresh');
$(this).on('itemAdded', function(event) {
var tags = model.get(property);
tags.push(event.item.id);
model.set(property, tags);
});
$(this).on('itemRemoved', function(event) {
if (!event.item) {
return;
}
var tags = _.without(model.get(property), event.item.id);
model.set(property, tags);
});
}
};

View File

@@ -1,4 +1,4 @@
var _ = require('underscore');
var _ = require('underscore');
var $ = require('jquery');
var vent = require('vent');
var Marionette = require('marionette');
@@ -8,11 +8,16 @@ var AsValidatedView = require('../../../Mixins/AsValidatedView');
var AsEditModalView = require('../../../Mixins/AsEditModalView');
require('../../../Form/FormBuilder');
require('../../../Mixins/AutoComplete');
require('../../../Mixins/TagInput');
require('bootstrap');
var view = Marionette.ItemView.extend({
template : 'Settings/Indexers/Edit/IndexerEditViewTemplate',
ui: {
tags : '.x-form-tag'
},
events : {
'click .x-back' : '_back',
'click .x-captcha-refresh' : '_onRefreshCaptcha'
@@ -24,6 +29,10 @@ var view = Marionette.ItemView.extend({
this.targetCollection = options.targetCollection;
},
onRender: function () {
this.ui.tags.tagInput({});
},
_onAfterSave : function() {
this.targetCollection.add(this.model, { merge : true });
vent.trigger(vent.Commands.CloseModalCommand);