mirror of
https://github.com/fergalmoran/dss.git
synced 2026-01-06 17:04:30 +00:00
Added missing backgrid files
This commit is contained in:
215
static/js/libs/backgrid/backgrid.css
Normal file
215
static/js/libs/backgrid/backgrid.css
Normal file
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
backgrid
|
||||
http://github.com/wyuenho/backgrid
|
||||
|
||||
Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
|
||||
Licensed under the MIT @license.
|
||||
*/
|
||||
|
||||
.backgrid-container {
|
||||
position: relative;
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 465px;
|
||||
padding: 0;
|
||||
overflow: auto;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.backgrid {
|
||||
width: 100%;
|
||||
max-width: 100%;
|
||||
background-color: transparent;
|
||||
border: 1px solid #DDD;
|
||||
border-collapse: collapse;
|
||||
-webkit-border-radius: 4px;
|
||||
-moz-border-radius: 4px;
|
||||
border-radius: 4px;
|
||||
}
|
||||
|
||||
.backgrid th,
|
||||
.backgrid td {
|
||||
height: 20px;
|
||||
max-width: 250px;
|
||||
padding: 4px 5px;
|
||||
overflow: hidden;
|
||||
line-height: 20px;
|
||||
text-align: left;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
border: 1px solid #DDD;
|
||||
}
|
||||
|
||||
.backgrid th {
|
||||
font-weight: bold;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.backgrid th a {
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.backgrid thead th {
|
||||
vertical-align: bottom;
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
|
||||
.backgrid.backgrid-striped tbody tr:nth-child(odd) td,
|
||||
.backgrid.backgrid-striped tbody tr:nth-child(odd) th {
|
||||
background-color: #f9f9f9;
|
||||
}
|
||||
|
||||
.backgrid tbody tr.empty {
|
||||
font-style: italic;
|
||||
color: gray;
|
||||
}
|
||||
|
||||
.backgrid tbody tr.empty td {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.backgrid td.editor,
|
||||
.backgrid tbody tr:nth-child(odd) td.editor {
|
||||
background-color: rgba(82, 168, 236, 0.1);
|
||||
outline: 1px solid rgba(82, 168, 236, 0.8);
|
||||
outline-offset: -1px;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
-webkit-transition-duration: 200ms;
|
||||
-moz-transition-duration: 200ms;
|
||||
-o-transition-duration: 200ms;
|
||||
transition-duration: 200ms;
|
||||
-webkit-transition-property: width, outline, background-color;
|
||||
-moz-transition-property: width, outline, background-color;
|
||||
-o-transition-property: width, outline, background-color;
|
||||
transition-property: width, outline, background-color;
|
||||
-webkit-transition-timing-function: ease-in-out;
|
||||
-moz-transition-timing-function: ease-in-out;
|
||||
-o-transition-timing-function: ease-in-out;
|
||||
transition-timing-function: ease-in-out;
|
||||
}
|
||||
|
||||
.backgrid td.editor input[type=text] {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
background-color: transparent;
|
||||
border: 0;
|
||||
outline: 0;
|
||||
-webkit-box-shadow: none;
|
||||
-moz-box-shadow: none;
|
||||
box-shadow: none;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
-webkit-appearance: none;
|
||||
-moz-appearance: none;
|
||||
}
|
||||
|
||||
.backgrid td.error,
|
||||
.backgrid tbody tr:nth-child(odd) td.error {
|
||||
background-color: rgba(255, 210, 77, 0.1);
|
||||
outline: 1px solid #ffd24d;
|
||||
}
|
||||
|
||||
.backgrid td.editor :focus,
|
||||
.backgrid th.editor :focus {
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.backgrid .sort-caret {
|
||||
display: inline-block;
|
||||
width: 0;
|
||||
height: 0;
|
||||
margin-left: 0.3em;
|
||||
border: 0;
|
||||
content: "";
|
||||
}
|
||||
|
||||
.backgrid .ascending .sort-caret {
|
||||
vertical-align: baseline;
|
||||
border-top: none;
|
||||
border-right: 4px solid transparent;
|
||||
border-bottom: 4px solid #000000;
|
||||
border-left: 4px solid transparent;
|
||||
}
|
||||
|
||||
.backgrid .descending .sort-caret {
|
||||
vertical-align: super;
|
||||
border-top: 4px solid #000000;
|
||||
border-right: 4px solid transparent;
|
||||
border-bottom: none;
|
||||
border-left: 4px solid transparent;
|
||||
}
|
||||
|
||||
.backgrid .string-cell,
|
||||
.backgrid .uri-cell,
|
||||
.backgrid .email-cell,
|
||||
.backgrid .string-cell.editor input[type=text],
|
||||
.backgrid .uri-cell.editor input[type=text],
|
||||
.backgrid .email-cell.editor input[type=text] {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
.backgrid .date-cell,
|
||||
.backgrid .time-cell,
|
||||
.backgrid .datetime-cell,
|
||||
.backgrid .number-cell,
|
||||
.backgrid .integer-cell,
|
||||
.backgrid .date-cell.editor input[type=text],
|
||||
.backgrid .time-cell.editor input[type=text],
|
||||
.backgrid .datetime-cell.editor input[type=text],
|
||||
.backgrid .number-cell.editor input[type=text],
|
||||
.backgrid .integer-cell.editor input[type=text] {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.backgrid .boolean-cell,
|
||||
.backgrid .boolean-cell.editor input[type=checkbox] {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.backgrid .select-cell {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.backgrid .select-cell.editor {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.backgrid .select-cell.editor select {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height: 28px;
|
||||
padding: 4px 5px;
|
||||
margin: 0;
|
||||
line-height: 28px;
|
||||
vertical-align: middle;
|
||||
background-color: white;
|
||||
border: 0;
|
||||
outline: 0;
|
||||
-webkit-box-shadow: none;
|
||||
-moz-box-shadow: none;
|
||||
box-shadow: none;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.backgrid .select-cell.editor :focus {
|
||||
border: 0;
|
||||
outline: 0;
|
||||
}
|
||||
|
||||
.backgrid .select-cell.editor select::-moz-focus-inner,
|
||||
.backgrid .select-cell.editor optgroup::-moz-focus-inner,
|
||||
.backgrid .select-cell.editor option::-moz-focus-inner,
|
||||
.backgrid .select-cell.editor select::-o-focus-inner,
|
||||
.backgrid .select-cell.editor optgroup::-o-focus-inner,
|
||||
.backgrid .select-cell.editor option::-o-focus-inner {
|
||||
border: 0;
|
||||
}
|
||||
2531
static/js/libs/backgrid/backgrid.js
Normal file
2531
static/js/libs/backgrid/backgrid.js
Normal file
File diff suppressed because it is too large
Load Diff
8
static/js/libs/backgrid/backgrid.min.css
vendored
Normal file
8
static/js/libs/backgrid/backgrid.min.css
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
backgrid
|
||||
http://github.com/wyuenho/backgrid
|
||||
|
||||
Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
|
||||
Licensed under the MIT @license.
|
||||
*/
|
||||
.backgrid-container{position:relative;display:block;width:100%;height:465px;padding:0;overflow:auto;border:0}.backgrid{width:100%;max-width:100%;background-color:transparent;border:1px solid #DDD;border-collapse:collapse;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.backgrid th,.backgrid td{height:20px;max-width:250px;padding:4px 5px;overflow:hidden;line-height:20px;text-align:left;text-overflow:ellipsis;white-space:nowrap;vertical-align:middle;border:1px solid #DDD}.backgrid th{font-weight:bold;cursor:pointer}.backgrid th a{white-space:nowrap}.backgrid thead th{vertical-align:bottom;background-color:#f9f9f9}.backgrid.backgrid-striped tbody tr:nth-child(odd) td,.backgrid.backgrid-striped tbody tr:nth-child(odd) th{background-color:#f9f9f9}.backgrid tbody tr.empty{font-style:italic;color:gray}.backgrid tbody tr.empty td{text-align:center}.backgrid td.editor,.backgrid tbody tr:nth-child(odd) td.editor{background-color:rgba(82,168,236,0.1);outline:1px solid rgba(82,168,236,0.8);outline-offset:-1px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition-duration:200ms;-moz-transition-duration:200ms;-o-transition-duration:200ms;transition-duration:200ms;-webkit-transition-property:width,outline,background-color;-moz-transition-property:width,outline,background-color;-o-transition-property:width,outline,background-color;transition-property:width,outline,background-color;-webkit-transition-timing-function:ease-in-out;-moz-transition-timing-function:ease-in-out;-o-transition-timing-function:ease-in-out;transition-timing-function:ease-in-out}.backgrid td.editor input[type=text]{display:block;width:100%;height:100%;padding:0;margin:0;background-color:transparent;border:0;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-appearance:none;-moz-appearance:none}.backgrid td.error,.backgrid tbody tr:nth-child(odd) td.error{background-color:rgba(255,210,77,0.1);outline:1px solid #ffd24d}.backgrid td.editor :focus,.backgrid th.editor:focus{outline:0}.backgrid .sort-caret{display:inline-block;width:0;height:0;margin-left:.3em;border:0;content:""}.backgrid .ascending .sort-caret{vertical-align:baseline;border-top:0;border-right:4px solid transparent;border-bottom:4px solid #000;border-left:4px solid transparent}.backgrid .descending .sort-caret{vertical-align:super;border-top:4px solid #000;border-right:4px solid transparent;border-bottom:0;border-left:4px solid transparent}.backgrid .string-cell,.backgrid .uri-cell,.backgrid .email-cell,.backgrid .string-cell.editor input[type=text],.backgrid .uri-cell.editor input[type=text],.backgrid .email-cell.editor input[type=text]{text-align:left}.backgrid .date-cell,.backgrid .time-cell,.backgrid .datetime-cell,.backgrid .number-cell,.backgrid .integer-cell,.backgrid .date-cell.editor input[type=text],.backgrid .time-cell.editor input[type=text],.backgrid .datetime-cell.editor input[type=text],.backgrid .number-cell.editor input[type=text],.backgrid .integer-cell.editor input[type=text]{text-align:right}.backgrid .boolean-cell,.backgrid .boolean-cell.editor input[type=checkbox]{text-align:center}.backgrid .select-cell{text-align:center}.backgrid .select-cell.editor{padding:0}.backgrid .select-cell.editor select{display:block;width:100%;height:28px;padding:4px 5px;margin:0;line-height:28px;vertical-align:middle;background-color:white;border:0;outline:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.backgrid .select-cell.editor :focus{border:0;outline:0}.backgrid .select-cell.editor select::-moz-focus-inner,.backgrid .select-cell.editor optgroup::-moz-focus-inner,.backgrid .select-cell.editor option::-moz-focus-inner,.backgrid .select-cell.editor select::-o-focus-inner,.backgrid .select-cell.editor optgroup::-o-focus-inner,.backgrid .select-cell.editor option::-o-focus-inner{border:0}
|
||||
8
static/js/libs/backgrid/backgrid.min.js
vendored
Normal file
8
static/js/libs/backgrid/backgrid.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
backgrid-filter
|
||||
http://github.com/wyuenho/backgrid
|
||||
|
||||
Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
|
||||
Licensed under the MIT @license.
|
||||
*/
|
||||
|
||||
.backgrid-filter .close {
|
||||
display: inline-block;
|
||||
float: none;
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
margin-top: -4px;
|
||||
font-size: 20px;
|
||||
line-height: 20px;
|
||||
text-align: center;
|
||||
vertical-align: text-top;
|
||||
}
|
||||
365
static/js/libs/backgrid/extensions/filter/backgrid-filter.js
Normal file
365
static/js/libs/backgrid/extensions/filter/backgrid-filter.js
Normal file
@@ -0,0 +1,365 @@
|
||||
/*
|
||||
backgrid-filter
|
||||
http://github.com/wyuenho/backgrid
|
||||
|
||||
Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
|
||||
Licensed under the MIT @license.
|
||||
*/
|
||||
|
||||
(function ($, _, Backbone, Backgrid, lunr) {
|
||||
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
ServerSideFilter is a search form widget that submits a query to the server
|
||||
for filtering the current collection.
|
||||
|
||||
@class Backgrid.Extension.ServerSideFilter
|
||||
*/
|
||||
var ServerSideFilter = Backgrid.Extension.ServerSideFilter = Backbone.View.extend({
|
||||
|
||||
/** @property */
|
||||
tagName: "form",
|
||||
|
||||
/** @property */
|
||||
className: "backgrid-filter form-search",
|
||||
|
||||
/** @property {function(Object, ?Object=): string} template */
|
||||
template: _.template('<div class="input-prepend input-append"><span class="add-on"><i class="icon-search"></i></span><input type="text" <% if (placeholder) { %> placeholder="<%- placeholder %>" <% } %> name="<%- name %>" /><span class="add-on"><a class="close" href="#">×</a></span></div>'),
|
||||
|
||||
/** @property */
|
||||
events: {
|
||||
"click .close": "clear",
|
||||
"submit": "search"
|
||||
},
|
||||
|
||||
/** @property {string} [name='q'] Query key */
|
||||
name: "q",
|
||||
|
||||
/** @property The HTML5 placeholder to appear beneath the search box. */
|
||||
placeholder: null,
|
||||
|
||||
/**
|
||||
@param {Object} options
|
||||
@param {Backbone.Collection} options.collection
|
||||
@param {String} [options.name]
|
||||
@param {String} [options.placeholder]
|
||||
*/
|
||||
initialize: function (options) {
|
||||
Backgrid.requireOptions(options, ["collection"]);
|
||||
Backbone.View.prototype.initialize.apply(this, arguments);
|
||||
this.name = options.name || this.name;
|
||||
this.placeholder = options.placeholder || this.placeholder;
|
||||
|
||||
var collection = this.collection, self = this;
|
||||
if (Backbone.PageableCollection &&
|
||||
collection instanceof Backbone.PageableCollection &&
|
||||
collection.mode == "server") {
|
||||
collection.queryParams[this.name] = function () {
|
||||
return self.$el.find("input[type=text]").val();
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
Upon search form submission, this event handler constructs a query
|
||||
parameter object and pass it to Collection#fetch for server-side
|
||||
filtering.
|
||||
*/
|
||||
search: function (e) {
|
||||
if (e) e.preventDefault();
|
||||
var data = {};
|
||||
data[this.name] = this.$el.find("input[type=text]").val();
|
||||
this.collection.fetch({data: data});
|
||||
},
|
||||
|
||||
/**
|
||||
Event handler for the close button. Clears the search box and refetch the
|
||||
collection.
|
||||
*/
|
||||
clear: function (e) {
|
||||
if (e) e.preventDefault();
|
||||
this.$("input[type=text]").val(null);
|
||||
this.collection.fetch();
|
||||
},
|
||||
|
||||
/**
|
||||
Renders a search form with a text box, optionally with a placeholder and
|
||||
a preset value if supplied during initialization.
|
||||
*/
|
||||
render: function () {
|
||||
this.$el.empty().append(this.template({
|
||||
name: this.name,
|
||||
placeholder: this.placeholder,
|
||||
value: this.value
|
||||
}));
|
||||
this.delegateEvents();
|
||||
return this;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
ClientSideFilter is a search form widget that searches a collection for
|
||||
model matches against a query on the client side. The exact matching
|
||||
algorithm can be overriden by subclasses.
|
||||
|
||||
@class Backgrid.Extension.ClientSideFilter
|
||||
@extends Backgrid.Extension.ServerSideFilter
|
||||
*/
|
||||
var ClientSideFilter = Backgrid.Extension.ClientSideFilter = ServerSideFilter.extend({
|
||||
|
||||
/** @property */
|
||||
events: {
|
||||
"click .close": function (e) {
|
||||
e.preventDefault();
|
||||
this.clear();
|
||||
},
|
||||
"change input[type=text]": "search",
|
||||
"keyup input[type=text]": "search",
|
||||
"submit": function (e) {
|
||||
e.preventDefault();
|
||||
this.search();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
@property {?Array.<string>} A list of model field names to search
|
||||
for matches. If null, all of the fields will be searched.
|
||||
*/
|
||||
fields: null,
|
||||
|
||||
/**
|
||||
@property wait The time in milliseconds to wait since for since the last
|
||||
change to the search box's value before searching. This value can be
|
||||
adjusted depending on how often the search box is used and how large the
|
||||
search index is.
|
||||
*/
|
||||
wait: 149,
|
||||
|
||||
/**
|
||||
Debounces the #search and #clear methods and makes a copy of the given
|
||||
collection for searching.
|
||||
|
||||
@param {Object} options
|
||||
@param {Backbone.Collection} options.collection
|
||||
@param {String} [options.placeholder]
|
||||
@param {String} [options.fields]
|
||||
@param {String} [options.wait=149]
|
||||
*/
|
||||
initialize: function (options) {
|
||||
ServerSideFilter.prototype.initialize.apply(this, arguments);
|
||||
|
||||
this.fields = options.fields || this.fields;
|
||||
this.wait = options.wait || this.wait;
|
||||
|
||||
this._debounceMethods(["search", "clear"]);
|
||||
|
||||
var collection = this.collection;
|
||||
var shadowCollection = this.shadowCollection = collection.clone();
|
||||
shadowCollection.url = collection.url;
|
||||
shadowCollection.sync = collection.sync;
|
||||
shadowCollection.parse = collection.parse;
|
||||
|
||||
this.listenTo(collection, "add", function (model, collection, options) {
|
||||
shadowCollection.add(model, options);
|
||||
});
|
||||
this.listenTo(collection, "remove", function (model, collection, options) {
|
||||
shadowCollection.remove(model, options);
|
||||
});
|
||||
this.listenTo(collection, "sort reset", function (collection, options) {
|
||||
options = _.extend({reindex: true}, options || {});
|
||||
if (options.reindex) shadowCollection.reset(collection.models);
|
||||
});
|
||||
},
|
||||
|
||||
_debounceMethods: function (methodNames) {
|
||||
if (_.isString(methodNames)) methodNames = [methodNames];
|
||||
|
||||
this.undelegateEvents();
|
||||
|
||||
for (var i = 0, l = methodNames.length; i < l; i++) {
|
||||
var methodName = methodNames[i];
|
||||
var method = this[methodName];
|
||||
this[methodName] = _.debounce(method, this.wait);
|
||||
}
|
||||
|
||||
this.delegateEvents();
|
||||
},
|
||||
|
||||
/**
|
||||
This default implementation takes a query string and returns a matcher
|
||||
function that looks for matches in the model's #fields or all of its
|
||||
fields if #fields is null, for any of the words in the query
|
||||
case-insensitively.
|
||||
|
||||
Subclasses overriding this method must take care to conform to the
|
||||
signature of the matcher function. In addition, when the matcher function
|
||||
is called, its context will be bound to this ClientSideFilter object so
|
||||
it has access to the filter's attributes and methods.
|
||||
|
||||
@param {string} query The search query in the search box.
|
||||
@return {function(Backbone.Model):boolean} A matching function.
|
||||
*/
|
||||
makeMatcher: function (query) {
|
||||
var regexp = new RegExp(query.trim().split(/\W/).join("|"), "i");
|
||||
return function (model) {
|
||||
var keys = this.fields || model.keys();
|
||||
for (var i = 0, l = keys.length; i < l; i++) {
|
||||
if (regexp.test(model.get(keys[i]) + "")) return true;
|
||||
}
|
||||
return false;
|
||||
};
|
||||
},
|
||||
|
||||
/**
|
||||
Takes the query from the search box, constructs a matcher with it and
|
||||
loops through collection looking for matches. Reset the given collection
|
||||
when all the matches have been found.
|
||||
*/
|
||||
search: function () {
|
||||
var matcher = _.bind(this.makeMatcher(this.$("input[type=text]").val()), this);
|
||||
this.collection.reset(this.shadowCollection.filter(matcher), {reindex: false});
|
||||
},
|
||||
|
||||
/**
|
||||
Clears the search box and reset the collection to its original.
|
||||
*/
|
||||
clear: function () {
|
||||
this.$("input[type=text]").val(null);
|
||||
this.collection.reset(this.shadowCollection.models, {reindex: false});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
LunrFilter is a ClientSideFilter that uses [lunrjs](http://lunrjs.com/) to
|
||||
index the text fields of each model for a collection, and performs
|
||||
full-text searching.
|
||||
|
||||
@class Backgrid.Extension.LunrFilter
|
||||
@extends Backgrid.Extension.ClientSideFilter
|
||||
*/
|
||||
Backgrid.Extension.LunrFilter = ClientSideFilter.extend({
|
||||
|
||||
/**
|
||||
@property {string} [ref="id"]`lunrjs` document reference attribute name.
|
||||
*/
|
||||
ref: "id",
|
||||
|
||||
/**
|
||||
@property {Object} fields A hash of `lunrjs` index field names and boost
|
||||
value. Unlike ClientSideFilter#fields, LunrFilter#fields is _required_ to
|
||||
initialize the index.
|
||||
*/
|
||||
fields: null,
|
||||
|
||||
/**
|
||||
Indexes the underlying collection on construction. The index will refresh
|
||||
when the underlying collection is reset. If any model is added, removed
|
||||
or if any indexed fields of any models has changed, the index will be
|
||||
updated.
|
||||
|
||||
@param {Object} options
|
||||
@param {Backbone.Collection} options.collection
|
||||
@param {String} [options.placeholder]
|
||||
@param {string} [options.ref] `lunrjs` document reference attribute name.
|
||||
@param {Object} [options.fields] A hash of `lunrjs` index field names and
|
||||
boost value.
|
||||
@param {number} [options.wait]
|
||||
*/
|
||||
initialize: function (options) {
|
||||
ClientSideFilter.prototype.initialize.apply(this, arguments);
|
||||
|
||||
this.ref = options.ref || this.ref;
|
||||
|
||||
var collection = this.collection;
|
||||
this.listenTo(collection, "add", this.addToIndex);
|
||||
this.listenTo(collection, "remove", this.removeFromIndex);
|
||||
this.listenTo(collection, "reset", this.resetIndex);
|
||||
this.listenTo(collection, "change", this.updateIndex);
|
||||
|
||||
this.resetIndex(collection);
|
||||
},
|
||||
|
||||
/**
|
||||
Reindex the collection. If `options.reindex` is `false`, this method is a
|
||||
no-op.
|
||||
|
||||
@param {Backbone.Collection} collection
|
||||
@param {Object} [options]
|
||||
@param {boolean} [options.reindex=true]
|
||||
*/
|
||||
resetIndex: function (collection, options) {
|
||||
options = _.extend({reindex: true}, options || {});
|
||||
|
||||
if (options.reindex) {
|
||||
var self = this;
|
||||
this.index = lunr(function () {
|
||||
_.each(self.fields, function (boost, fieldName) {
|
||||
this.field(fieldName, boost);
|
||||
this.ref(self.ref);
|
||||
}, this);
|
||||
});
|
||||
|
||||
collection.each(function (model) {
|
||||
this.addToIndex(model);
|
||||
}, this);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
Adds the given model to the index.
|
||||
|
||||
@param {Backbone.Model} model
|
||||
*/
|
||||
addToIndex: function (model) {
|
||||
var index = this.index;
|
||||
var doc = model.toJSON();
|
||||
if (index.documentStore.has(doc[this.ref])) index.update(doc);
|
||||
else index.add(doc);
|
||||
},
|
||||
|
||||
/**
|
||||
Removes the given model from the index.
|
||||
|
||||
@param {Backbone.Model} model
|
||||
*/
|
||||
removeFromIndex: function (model) {
|
||||
var index = this.index;
|
||||
var doc = model.toJSON();
|
||||
if (index.documentStore.has(doc[this.ref])) index.remove(doc);
|
||||
},
|
||||
|
||||
/**
|
||||
Updates the index for the given model.
|
||||
|
||||
@param {Backbone.Model} model
|
||||
*/
|
||||
updateIndex: function (model) {
|
||||
var changed = model.changedAttributes();
|
||||
if (changed && !_.isEmpty(_.intersection(_.keys(this.fields),
|
||||
_.keys(changed)))) {
|
||||
this.index.update(model.toJSON());
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
Takes the query from the search box and performs a full-text search on
|
||||
the client-side. The search result is returned by resetting the
|
||||
underlying collection to the models after interrogating the index for the
|
||||
query answer.
|
||||
*/
|
||||
search: function () {
|
||||
var searchResults = this.index.search(this.$("input[type=text]").val());
|
||||
var models = [];
|
||||
for (var i = 0; i < searchResults.length; i++) {
|
||||
var result = searchResults[i];
|
||||
models.push(this.shadowCollection.get(result.ref));
|
||||
}
|
||||
this.collection.reset(models, {reindex: false});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}(jQuery, _, Backbone, Backgrid, lunr));
|
||||
8
static/js/libs/backgrid/extensions/filter/backgrid-filter.min.css
vendored
Normal file
8
static/js/libs/backgrid/extensions/filter/backgrid-filter.min.css
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
backgrid-filter
|
||||
http://github.com/wyuenho/backgrid
|
||||
|
||||
Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
|
||||
Licensed under the MIT @license.
|
||||
*/
|
||||
.backgrid-filter .close{display:inline-block;float:none;width:20px;height:20px;margin-top:-4px;font-size:20px;line-height:20px;text-align:center;vertical-align:text-top}
|
||||
8
static/js/libs/backgrid/extensions/filter/backgrid-filter.min.js
vendored
Normal file
8
static/js/libs/backgrid/extensions/filter/backgrid-filter.min.js
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
backgrid-filter
|
||||
http://github.com/wyuenho/backgrid
|
||||
|
||||
Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
|
||||
Licensed under the MIT @license.
|
||||
*/
|
||||
(function(e,t,i,n,s){"use strict";var a=n.Extension.ServerSideFilter=i.View.extend({tagName:"form",className:"backgrid-filter form-search",template:t.template('<div class="input-prepend input-append"><span class="add-on"><i class="icon-search"></i></span><input type="text" <% if (placeholder) { %> placeholder="<%- placeholder %>" <% } %> name="<%- name %>" /><span class="add-on"><a class="close" href="#">×</a></span></div>'),events:{"click .close":"clear",submit:"search"},name:"q",placeholder:null,initialize:function(e){n.requireOptions(e,["collection"]),i.View.prototype.initialize.apply(this,arguments),this.name=e.name||this.name,this.placeholder=e.placeholder||this.placeholder;var t=this.collection,s=this;i.PageableCollection&&t instanceof i.PageableCollection&&t.mode=="server"&&(t.queryParams[this.name]=function(){return s.$el.find("input[type=text]").val()})},search:function(e){e&&e.preventDefault();var t={};t[this.name]=this.$el.find("input[type=text]").val(),this.collection.fetch({data:t})},clear:function(e){e&&e.preventDefault(),this.$("input[type=text]").val(null),this.collection.fetch()},render:function(){return this.$el.empty().append(this.template({name:this.name,placeholder:this.placeholder,value:this.value})),this.delegateEvents(),this}}),l=n.Extension.ClientSideFilter=a.extend({events:{"click .close":function(e){e.preventDefault(),this.clear()},"change input[type=text]":"search","keyup input[type=text]":"search",submit:function(e){e.preventDefault(),this.search()}},fields:null,wait:149,initialize:function(e){a.prototype.initialize.apply(this,arguments),this.fields=e.fields||this.fields,this.wait=e.wait||this.wait,this._debounceMethods(["search","clear"]);var i=this.collection,n=this.shadowCollection=i.clone();n.url=i.url,n.sync=i.sync,n.parse=i.parse,this.listenTo(i,"add",function(e,t,i){n.add(e,i)}),this.listenTo(i,"remove",function(e,t,i){n.remove(e,i)}),this.listenTo(i,"sort reset",function(e,i){i=t.extend({reindex:!0},i||{}),i.reindex&&n.reset(e.models)})},_debounceMethods:function(e){t.isString(e)&&(e=[e]),this.undelegateEvents();for(var i=0,n=e.length;n>i;i++){var s=e[i],a=this[s];this[s]=t.debounce(a,this.wait)}this.delegateEvents()},makeMatcher:function(e){var t=new RegExp(e.trim().split(/\W/).join("|"),"i");return function(e){for(var i=this.fields||e.keys(),n=0,s=i.length;s>n;n++)if(t.test(e.get(i[n])+""))return!0;return!1}},search:function(){var e=t.bind(this.makeMatcher(this.$("input[type=text]").val()),this);this.collection.reset(this.shadowCollection.filter(e),{reindex:!1})},clear:function(){this.$("input[type=text]").val(null),this.collection.reset(this.shadowCollection.models,{reindex:!1})}});n.Extension.LunrFilter=l.extend({ref:"id",fields:null,initialize:function(e){l.prototype.initialize.apply(this,arguments),this.ref=e.ref||this.ref;var t=this.collection;this.listenTo(t,"add",this.addToIndex),this.listenTo(t,"remove",this.removeFromIndex),this.listenTo(t,"reset",this.resetIndex),this.listenTo(t,"change",this.updateIndex),this.resetIndex(t)},resetIndex:function(e,i){if(i=t.extend({reindex:!0},i||{}),i.reindex){var n=this;this.index=s(function(){t.each(n.fields,function(e,t){this.field(t,e),this.ref(n.ref)},this)}),e.each(function(e){this.addToIndex(e)},this)}},addToIndex:function(e){var t=this.index,i=e.toJSON();t.documentStore.has(i[this.ref])?t.update(i):t.add(i)},removeFromIndex:function(e){var t=this.index,i=e.toJSON();t.documentStore.has(i[this.ref])&&t.remove(i)},updateIndex:function(e){var i=e.changedAttributes();i&&!t.isEmpty(t.intersection(t.keys(this.fields),t.keys(i)))&&this.index.update(e.toJSON())},search:function(){for(var e=this.index.search(this.$("input[type=text]").val()),t=[],i=0;i<e.length;i++){var n=e[i];t.push(this.shadowCollection.get(n.ref))}this.collection.reset(t,{reindex:!1})}})})(jQuery,_,Backbone,Backgrid,lunr);
|
||||
@@ -0,0 +1,14 @@
|
||||
/*
|
||||
backgrid-moment-cell
|
||||
http://github.com/wyuenho/backgrid
|
||||
|
||||
Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
|
||||
Licensed under the MIT @license.
|
||||
*/
|
||||
.backgrid .moment-cell {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.backgrid .moment-cell.editor input[type=text] {
|
||||
text-align: right;
|
||||
}
|
||||
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
backgrid-moment-cell
|
||||
http://github.com/wyuenho/backgrid
|
||||
|
||||
Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
|
||||
Licensed under the MIT @license.
|
||||
*/
|
||||
(function ($, _, Backbone, Backgrid, moment) {
|
||||
|
||||
/**
|
||||
MomentFormatter converts bi-directionally any datetime values in any format
|
||||
supported by [moment()](http://momentjs.com/docs/#/parsing/) to any
|
||||
datetime format
|
||||
[moment.fn.format()](http://momentjs.com/docs/#/displaying/format/)
|
||||
supports.
|
||||
|
||||
@class Backgrid.Extension.MomentFormatter
|
||||
@extends Backgrid.CellFormatter
|
||||
@constructor
|
||||
*/
|
||||
var MomentFormatter = Backgrid.Extension.MomentFormatter = function (options) {
|
||||
_.extend(this, this.defaults, options);
|
||||
};
|
||||
MomentFormatter.prototype = new Backgrid.CellFormatter;
|
||||
_.extend(MomentFormatter.prototype, {
|
||||
|
||||
/**
|
||||
@cfg {Object} options
|
||||
|
||||
@cfg {boolean} [options.modelInUnixOffset=false] Whether the model values
|
||||
should be read/written as the number of milliseconds since UNIX Epoch.
|
||||
|
||||
@cfg {boolean} [options.modelInUnixTimestamp=false] Whether the model
|
||||
values should be read/written as the number of seconds since UNIX Epoch.
|
||||
|
||||
@cfg {boolean} [options.modelInUTC=true] Whether the model values should
|
||||
be read/written in UTC mode or local mode.
|
||||
|
||||
@cfg {string} [options.modelLang=moment.lang()] The locale the model
|
||||
values should be read/written in.
|
||||
|
||||
@cfg {string} [options.modelFormat=moment.defaultFormat] The format this
|
||||
moment formatter should use to read/write model values. Only meaningful if
|
||||
the values are strings.
|
||||
|
||||
@cfg {boolean} [options.displayInUnixOffset=false] Whether the display
|
||||
values should be read/written as the number of milliseconds since UNIX
|
||||
Epoch.
|
||||
|
||||
@cfg {boolean} [options.displayInUnixTimestamp=false] Whether the display
|
||||
values should be read/written as the number of seconds since UNIX Epoch.
|
||||
|
||||
@cfg {boolean} [options.displayInUTC=true] Whether the display values
|
||||
should be read/written in UTC mode or local mode.
|
||||
|
||||
@cfg {string} [options.displayLang=moment.lang()] The locale the display
|
||||
values should be read/written in.
|
||||
|
||||
@cfg {string} [options.displayFormat=moment.defaultFormat] The format
|
||||
this moment formatter should use to read/write dislay values.
|
||||
*/
|
||||
defaults: {
|
||||
modelInUnixOffset: false,
|
||||
modelInUnixTimestamp: false,
|
||||
modelInUTC: true,
|
||||
modelLang: moment.lang(),
|
||||
modelFormat: moment.defaultFormat,
|
||||
displayInUnixOffset: false,
|
||||
displayInUnixTimestamp: false,
|
||||
displayInUTC: true,
|
||||
displayLang: moment.lang(),
|
||||
displayFormat: moment.defaultFormat
|
||||
},
|
||||
|
||||
/**
|
||||
Converts datetime values from the model for display.
|
||||
|
||||
@member Backgrid.Extension.MomentFormatter
|
||||
@param {*} rawData
|
||||
@return {string}
|
||||
*/
|
||||
fromRaw: function (rawData) {
|
||||
if (rawData == null) return '';
|
||||
|
||||
var m = this.modelInUnixOffset ? moment(rawData) :
|
||||
this.modelInUnixTimestamp ? moment.unix(rawData) :
|
||||
this.modelInUTC ?
|
||||
moment.utc(rawData, this.modelFormat, this.modelLang) :
|
||||
moment(rawData, this.modelFormat, this.modelLang);
|
||||
|
||||
if (this.displayInUnixOffset) return +m;
|
||||
|
||||
if (this.displayInUnixTimestamp) return m.unix();
|
||||
|
||||
if (this.displayLang) m.lang(this.displayLang);
|
||||
|
||||
if (this.displayInUTC) m.utc(); else m.local();
|
||||
|
||||
return m.format(this.displayFormat);
|
||||
},
|
||||
|
||||
/**
|
||||
Converts datetime values from user input to model values.
|
||||
|
||||
@member Backgrid.Extension.MomentFormatter
|
||||
@param {string} formattedData
|
||||
@return {string}
|
||||
*/
|
||||
toRaw: function (formattedData) {
|
||||
|
||||
var m = this.displayInUnixOffset ? moment(+formattedData) :
|
||||
this.displayInUnixTimestamp ? moment.unix(+formattedData) :
|
||||
this.displayInUTC ?
|
||||
moment.utc(formattedData, this.displayFormat, this.displayLang) :
|
||||
moment(formattedData, this.displayFormat, this.displayLang);
|
||||
|
||||
if (!m || !m.isValid()) return;
|
||||
|
||||
if (this.modelInUnixOffset) return +m;
|
||||
|
||||
if (this.modelInUnixTimestamp) return m.unix();
|
||||
|
||||
if (this.modelLang) m.lang(this.modelLang);
|
||||
|
||||
if (this.modelInUTC) m.utc(); else m.local();
|
||||
|
||||
return m.format(this.modelFormat);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
Renders a datetime cell that uses a Backgrid.Extension.MomentFormatter to
|
||||
convert and validate values.
|
||||
|
||||
@class Backgrid.Extension.MomentCell
|
||||
@extends Backgrid.Cell
|
||||
*/
|
||||
var MomentCell = Backgrid.Extension.MomentCell = Backgrid.Cell.extend({
|
||||
|
||||
editor: Backgrid.InputCellEditor,
|
||||
|
||||
/** @property */
|
||||
className: "moment-cell",
|
||||
|
||||
/** @property {Backgrid.CellFormatter} [formatter=Backgrid.Extension.MomentFormatter] */
|
||||
formatter: MomentFormatter,
|
||||
|
||||
/**
|
||||
Initializer. Accept Backgrid.Extension.MomentFormatter.options and
|
||||
Backgrid.Cell.initialize required parameters.
|
||||
*/
|
||||
initialize: function (options) {
|
||||
|
||||
Backgrid.Cell.prototype.initialize.apply(this, arguments);
|
||||
|
||||
var formatterDefaults = MomentFormatter.prototype.defaults;
|
||||
var formatterDefaultKeys = _.keys(formatterDefaults);
|
||||
var classAttrs = _.pick(this, formatterDefaultKeys);
|
||||
var formatterOptions = _.pick(options, formatterDefaultKeys);
|
||||
|
||||
this.formatter = new this.formatter(_.extend({}, formatterDefaults, classAttrs, formatterOptions));
|
||||
|
||||
this.editor = this.editor.extend({
|
||||
attributes: _.extend({}, this.editor.prototype.attributes || this.editor.attributes || {}, {
|
||||
placeholder: this.formatter.displayFormat
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
_.extend(MomentCell.prototype, MomentFormatter.prototype.defaults);
|
||||
|
||||
}(jQuery, _, Backbone, Backgrid, moment));
|
||||
8
static/js/libs/backgrid/extensions/moment-cell/backgrid-moment-cell.min.css
vendored
Normal file
8
static/js/libs/backgrid/extensions/moment-cell/backgrid-moment-cell.min.css
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
backgrid-moment-cell
|
||||
http://github.com/wyuenho/backgrid
|
||||
|
||||
Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
|
||||
Licensed under the MIT @license.
|
||||
*/
|
||||
.backgrid .moment-cell{text-align:right}.backgrid .moment-cell.editor input[type=text]{text-align:right}
|
||||
8
static/js/libs/backgrid/extensions/moment-cell/backgrid-moment-cell.min.js
vendored
Normal file
8
static/js/libs/backgrid/extensions/moment-cell/backgrid-moment-cell.min.js
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
backgrid-moment-cell
|
||||
http://github.com/wyuenho/backgrid
|
||||
|
||||
Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
|
||||
Licensed under the MIT @license.
|
||||
*/
|
||||
(function(t,i,e,a,n){var s=a.Extension.MomentFormatter=function(t){i.extend(this,this.defaults,t)};s.prototype=new a.CellFormatter,i.extend(s.prototype,{defaults:{modelInUnixOffset:!1,modelInUnixTimestamp:!1,modelInUTC:!0,modelLang:n.lang(),modelFormat:n.defaultFormat,displayInUnixOffset:!1,displayInUnixTimestamp:!1,displayInUTC:!0,displayLang:n.lang(),displayFormat:n.defaultFormat},fromRaw:function(t){if(null==t)return"";var i=this.modelInUnixOffset?n(t):this.modelInUnixTimestamp?n.unix(t):this.modelInUTC?n.utc(t,this.modelFormat,this.modelLang):n(t,this.modelFormat,this.modelLang);return this.displayInUnixOffset?+i:this.displayInUnixTimestamp?i.unix():(this.displayLang&&i.lang(this.displayLang),this.displayInUTC?i.utc():i.local(),i.format(this.displayFormat))},toRaw:function(t){var i=this.displayInUnixOffset?n(+t):this.displayInUnixTimestamp?n.unix(+t):this.displayInUTC?n.utc(t,this.displayFormat,this.displayLang):n(t,this.displayFormat,this.displayLang);if(i&&i.isValid())return this.modelInUnixOffset?+i:this.modelInUnixTimestamp?i.unix():(this.modelLang&&i.lang(this.modelLang),this.modelInUTC?i.utc():i.local(),i.format(this.modelFormat))}});var o=a.Extension.MomentCell=a.Cell.extend({editor:a.InputCellEditor,className:"moment-cell",formatter:s,initialize:function(t){a.Cell.prototype.initialize.apply(this,arguments);var e=s.prototype.defaults,n=i.keys(e),o=i.pick(this,n),l=i.pick(t,n);this.formatter=new this.formatter(i.extend({},e,o,l)),this.editor=this.editor.extend({attributes:i.extend({},this.editor.prototype.attributes||this.editor.attributes||{},{placeholder:this.formatter.displayFormat})})}});i.extend(o.prototype,s.prototype.defaults)})(jQuery,_,Backbone,Backgrid,moment);
|
||||
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
backgrid-paginator
|
||||
http://github.com/wyuenho/backgrid
|
||||
|
||||
Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
|
||||
Licensed under the MIT @license.
|
||||
*/
|
||||
|
||||
.backgrid-paginator {
|
||||
text-align: center;
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
border-top: none;
|
||||
-webkit-border-radius: 0 0 4px 4px;
|
||||
-moz-border-radius: 0 0 4px 4px;
|
||||
border-radius: 0 0 4px 4px;
|
||||
}
|
||||
|
||||
.backgrid-paginator ul {
|
||||
display: inline-block;
|
||||
*display: inline;
|
||||
margin: 5px 0;
|
||||
*zoom: 1;
|
||||
}
|
||||
|
||||
.backgrid-paginator ul > li {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.backgrid-paginator ul > li > a,
|
||||
.backgrid-paginator ul > li > span {
|
||||
float: left;
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
padding: 0;
|
||||
line-height: 30px;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.backgrid-paginator ul > li > a:hover,
|
||||
.backgrid-paginator ul > .active > a,
|
||||
.backgrid-paginator ul > .active > span {
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
.backgrid-paginator ul > .active > a,
|
||||
.backgrid-paginator ul > .active > span {
|
||||
color: #999999;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.backgrid-paginator ul > .disabled > span,
|
||||
.backgrid-paginator ul > .disabled > a,
|
||||
.backgrid-paginator ul > .disabled > a:hover {
|
||||
color: #999999;
|
||||
cursor: default;
|
||||
}
|
||||
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
backgrid-paginator
|
||||
http://github.com/wyuenho/backgrid
|
||||
|
||||
Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
|
||||
Licensed under the MIT @license.
|
||||
*/
|
||||
|
||||
(function ($, _, Backbone, Backgrid) {
|
||||
|
||||
"use strict";
|
||||
|
||||
/**
|
||||
Paginator is a Backgrid extension that renders a series of configurable
|
||||
pagination handles. This extension is best used for splitting a large data
|
||||
set across multiple pages. If the number of pages is larger then a
|
||||
threshold, which is set to 10 by default, the page handles are rendered
|
||||
within a sliding window, plus the fast forward, fast backward, previous and
|
||||
next page handles. The fast forward, fast backward, previous and next page
|
||||
handles can be turned off.
|
||||
|
||||
@class Backgrid.Extension.Paginator
|
||||
*/
|
||||
Backgrid.Extension.Paginator = Backbone.View.extend({
|
||||
|
||||
/** @property */
|
||||
className: "backgrid-paginator",
|
||||
|
||||
/** @property */
|
||||
windowSize: 10,
|
||||
|
||||
/**
|
||||
@property {Object} fastForwardHandleLabels You can disable specific
|
||||
handles by setting its value to `null`.
|
||||
*/
|
||||
fastForwardHandleLabels: {
|
||||
first: "《",
|
||||
prev: "〈",
|
||||
next: "〉",
|
||||
last: "》"
|
||||
},
|
||||
|
||||
/** @property */
|
||||
template: _.template('<ul><% _.each(handles, function (handle) { %><li <% if (handle.className) { %>class="<%= handle.className %>"<% } %>><a href="#" <% if (handle.title) {%> title="<%= handle.title %>"<% } %>><%= handle.label %></a></li><% }); %></ul>'),
|
||||
|
||||
/** @property */
|
||||
events: {
|
||||
"click a": "changePage"
|
||||
},
|
||||
|
||||
/**
|
||||
Initializer.
|
||||
|
||||
@param {Object} options
|
||||
@param {Backbone.Collection} options.collection
|
||||
@param {boolean} [options.fastForwardHandleLabels] Whether to render fast forward buttons.
|
||||
*/
|
||||
initialize: function (options) {
|
||||
Backgrid.requireOptions(options, ["collection"]);
|
||||
|
||||
var collection = this.collection;
|
||||
var fullCollection = collection.fullCollection;
|
||||
if (fullCollection) {
|
||||
this.listenTo(fullCollection, "add", this.render);
|
||||
this.listenTo(fullCollection, "remove", this.render);
|
||||
this.listenTo(fullCollection, "reset", this.render);
|
||||
}
|
||||
else {
|
||||
this.listenTo(collection, "add", this.render);
|
||||
this.listenTo(collection, "remove", this.render);
|
||||
this.listenTo(collection, "reset", this.render);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
jQuery event handler for the page handlers. Goes to the right page upon
|
||||
clicking.
|
||||
|
||||
@param {Event} e
|
||||
*/
|
||||
changePage: function (e) {
|
||||
e.preventDefault();
|
||||
|
||||
var $li = $(e.target).parent();
|
||||
if (!$li.hasClass("active") && !$li.hasClass("disabled")) {
|
||||
|
||||
var label = $(e.target).text();
|
||||
var ffLabels = this.fastForwardHandleLabels;
|
||||
|
||||
var collection = this.collection;
|
||||
|
||||
if (ffLabels) {
|
||||
switch (label) {
|
||||
case ffLabels.first:
|
||||
collection.getFirstPage();
|
||||
return;
|
||||
case ffLabels.prev:
|
||||
collection.getPreviousPage();
|
||||
return;
|
||||
case ffLabels.next:
|
||||
collection.getNextPage();
|
||||
return;
|
||||
case ffLabels.last:
|
||||
collection.getLastPage();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
var state = collection.state;
|
||||
var pageIndex = +label;
|
||||
collection.getPage(state.firstPage === 0 ? pageIndex - 1 : pageIndex);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
Internal method to create a list of page handle objects for the template
|
||||
to render them.
|
||||
|
||||
@return {Array.<Object>} an array of page handle objects hashes
|
||||
*/
|
||||
makeHandles: function () {
|
||||
|
||||
var handles = [];
|
||||
var collection = this.collection;
|
||||
var state = collection.state;
|
||||
|
||||
// convert all indices to 0-based here
|
||||
var firstPage = state.firstPage;
|
||||
var lastPage = +state.lastPage;
|
||||
lastPage = Math.max(0, firstPage ? lastPage - 1 : lastPage);
|
||||
var currentPage = Math.max(state.currentPage, state.firstPage);
|
||||
currentPage = firstPage ? currentPage - 1 : currentPage;
|
||||
var windowStart = Math.floor(currentPage / this.windowSize) * this.windowSize;
|
||||
var windowEnd = Math.min(lastPage + 1, windowStart + this.windowSize);
|
||||
|
||||
if (collection.mode !== "infinite") {
|
||||
for (var i = windowStart; i < windowEnd; i++) {
|
||||
handles.push({
|
||||
label: i + 1,
|
||||
title: "No. " + (i + 1),
|
||||
className: currentPage === i ? "active" : undefined
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
var ffLabels = this.fastForwardHandleLabels;
|
||||
if (ffLabels) {
|
||||
|
||||
if (ffLabels.prev) {
|
||||
handles.unshift({
|
||||
label: ffLabels.prev,
|
||||
className: collection.hasPrevious() ? void 0 : "disabled"
|
||||
});
|
||||
}
|
||||
|
||||
if (ffLabels.first) {
|
||||
handles.unshift({
|
||||
label: ffLabels.first,
|
||||
className: collection.hasPrevious() ? void 0 : "disabled"
|
||||
});
|
||||
}
|
||||
|
||||
if (ffLabels.next) {
|
||||
handles.push({
|
||||
label: ffLabels.next,
|
||||
className: collection.hasNext() ? void 0 : "disabled"
|
||||
});
|
||||
}
|
||||
|
||||
if (ffLabels.last) {
|
||||
handles.push({
|
||||
label: ffLabels.last,
|
||||
className: collection.hasNext() ? void 0 : "disabled"
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return handles;
|
||||
},
|
||||
|
||||
/**
|
||||
Render the paginator handles inside an unordered list.
|
||||
*/
|
||||
render: function () {
|
||||
this.$el.empty();
|
||||
|
||||
this.$el.append(this.template({
|
||||
handles: this.makeHandles()
|
||||
}));
|
||||
|
||||
this.delegateEvents();
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}(jQuery, _, Backbone, Backgrid));
|
||||
8
static/js/libs/backgrid/extensions/paginator/backgrid-paginator.min.css
vendored
Normal file
8
static/js/libs/backgrid/extensions/paginator/backgrid-paginator.min.css
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
backgrid-paginator
|
||||
http://github.com/wyuenho/backgrid
|
||||
|
||||
Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
|
||||
Licensed under the MIT @license.
|
||||
*/
|
||||
.backgrid-paginator{text-align:center;border-top:0;-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.backgrid-paginator ul{display:inline-block;*display:inline;margin:5px 0;*zoom:1}.backgrid-paginator ul>li{display:inline}.backgrid-paginator ul>li>a,.backgrid-paginator ul>li>span{float:left;width:30px;height:30px;padding:0;line-height:30px;text-decoration:none}.backgrid-paginator ul>li>a:hover,.backgrid-paginator ul>.active>a,.backgrid-paginator ul>.active>span{background-color:#f5f5f5}.backgrid-paginator ul>.active>a,.backgrid-paginator ul>.active>span{color:#999;cursor:default}.backgrid-paginator ul>.disabled>span,.backgrid-paginator ul>.disabled>a,.backgrid-paginator ul>.disabled>a:hover{color:#999;cursor:default}
|
||||
8
static/js/libs/backgrid/extensions/paginator/backgrid-paginator.min.js
vendored
Normal file
8
static/js/libs/backgrid/extensions/paginator/backgrid-paginator.min.js
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
backgrid-paginator
|
||||
http://github.com/wyuenho/backgrid
|
||||
|
||||
Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
|
||||
Licensed under the MIT @license.
|
||||
*/
|
||||
(function(e,t,a,s){"use strict";s.Extension.Paginator=a.View.extend({className:"backgrid-paginator",windowSize:10,fastForwardHandleLabels:{first:"《",prev:"〈",next:"〉",last:"》"},template:t.template('<ul><% _.each(handles, function (handle) { %><li <% if (handle.className) { %>class="<%= handle.className %>"<% } %>><a href="#" <% if (handle.title) {%> title="<%= handle.title %>"<% } %>><%= handle.label %></a></li><% }); %></ul>'),events:{"click a":"changePage"},initialize:function(e){s.requireOptions(e,["collection"]);var t=this.collection,a=t.fullCollection;a?(this.listenTo(a,"add",this.render),this.listenTo(a,"remove",this.render),this.listenTo(a,"reset",this.render)):(this.listenTo(t,"add",this.render),this.listenTo(t,"remove",this.render),this.listenTo(t,"reset",this.render))},changePage:function(t){t.preventDefault();var a=e(t.target).parent();if(!a.hasClass("active")&&!a.hasClass("disabled")){var s=e(t.target).text(),i=this.fastForwardHandleLabels,l=this.collection;if(i)switch(s){case i.first:return l.getFirstPage(),void 0;case i.prev:return l.getPreviousPage(),void 0;case i.next:return l.getNextPage(),void 0;case i.last:return l.getLastPage(),void 0}var n=l.state,r=+s;l.getPage(n.firstPage===0?r-1:r)}},makeHandles:function(){var e=[],t=this.collection,a=t.state,s=a.firstPage,i=+a.lastPage;i=Math.max(0,s?i-1:i);var l=Math.max(a.currentPage,a.firstPage);l=s?l-1:l;var n=Math.floor(l/this.windowSize)*this.windowSize,r=Math.min(i+1,n+this.windowSize);if(t.mode!=="infinite")for(var d=n;r>d;d++)e.push({label:d+1,title:"No. "+(d+1),className:l===d?"active":void 0});var h=this.fastForwardHandleLabels;return h&&(h.prev&&e.unshift({label:h.prev,className:t.hasPrevious()?void 0:"disabled"}),h.first&&e.unshift({label:h.first,className:t.hasPrevious()?void 0:"disabled"}),h.next&&e.push({label:h.next,className:t.hasNext()?void 0:"disabled"}),h.last&&e.push({label:h.last,className:t.hasNext()?void 0:"disabled"})),e},render:function(){return this.$el.empty(),this.$el.append(this.template({handles:this.makeHandles()})),this.delegateEvents(),this}})})(jQuery,_,Backbone,Backgrid);
|
||||
@@ -0,0 +1,11 @@
|
||||
/*
|
||||
backgrid-select-all
|
||||
http://github.com/wyuenho/backgrid
|
||||
|
||||
Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
|
||||
Licensed under the MIT @license.
|
||||
*/
|
||||
.backgrid .select-row-cell,
|
||||
.backgrid .select-all-header-cell {
|
||||
text-align: center;
|
||||
}
|
||||
@@ -0,0 +1,215 @@
|
||||
/*
|
||||
backgrid-select-all
|
||||
http://github.com/wyuenho/backgrid
|
||||
|
||||
Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
|
||||
Licensed under the MIT @license.
|
||||
*/
|
||||
(function (window, $, _, Backbone, Backgrid) {
|
||||
|
||||
/**
|
||||
Renders a checkbox for row selection.
|
||||
|
||||
@class Backgrid.Extension.SelectRowCell
|
||||
@extends Backbone.View
|
||||
*/
|
||||
var SelectRowCell = Backgrid.Extension.SelectRowCell = Backbone.View.extend({
|
||||
|
||||
/** @property */
|
||||
className: "select-row-cell",
|
||||
|
||||
/** @property */
|
||||
tagName: "td",
|
||||
|
||||
/** @property */
|
||||
events: {
|
||||
"keydown :checkbox": "onKeydown",
|
||||
"change :checkbox": "onChange",
|
||||
"click :checkbox": "enterEditMode"
|
||||
},
|
||||
|
||||
/**
|
||||
Initializer. If the underlying model triggers a `select` event, this cell
|
||||
will change its checked value according to the event's `selected` value.
|
||||
|
||||
@param {Object} options
|
||||
@param {Backgrid.Column} options.column
|
||||
@param {Backbone.Model} options.model
|
||||
*/
|
||||
initialize: function (options) {
|
||||
Backgrid.requireOptions(options, ["model", "column"]);
|
||||
|
||||
this.column = options.column;
|
||||
if (!(this.column instanceof Backgrid.Column)) {
|
||||
this.column = new Backgrid.Column(this.column);
|
||||
}
|
||||
|
||||
this.listenTo(this.model, "backgrid:select", function (model, selected) {
|
||||
this.$el.find(":checkbox").prop("checked", selected).change();
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
Focuses the checkbox.
|
||||
*/
|
||||
enterEditMode: function () {
|
||||
this.$el.find(":checkbox").focus();
|
||||
},
|
||||
|
||||
/**
|
||||
Unfocuses the checkbox.
|
||||
*/
|
||||
exitEditMode: function () {
|
||||
this.$el.find(":checkbox").blur();
|
||||
},
|
||||
|
||||
/**
|
||||
Process keyboard navigation.
|
||||
*/
|
||||
onKeydown: function (e) {
|
||||
var command = new Backgrid.Command(e);
|
||||
if (command.passThru()) return true; // skip ahead to `change`
|
||||
if (command.cancel()) {
|
||||
e.stopPropagation();
|
||||
this.$el.find(":checkbox").blur();
|
||||
}
|
||||
else if (command.save() || command.moveLeft() || command.moveRight() ||
|
||||
command.moveUp() || command.moveDown()) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
this.model.trigger("backgrid:edited", this.model, this.column, command);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
When the checkbox's value changes, this method will trigger a Backbone
|
||||
`backgrid:selected` event with a reference of the model and the
|
||||
checkbox's `checked` value.
|
||||
*/
|
||||
onChange: function (e) {
|
||||
this.model.trigger("backgrid:selected", this.model, $(e.target).prop("checked"));
|
||||
},
|
||||
|
||||
/**
|
||||
Renders a checkbox in a table cell.
|
||||
*/
|
||||
render: function () {
|
||||
this.$el.empty().append('<input tabindex="-1" type="checkbox" />');
|
||||
this.delegateEvents();
|
||||
return this;
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
Renders a checkbox to select all rows on the current page.
|
||||
|
||||
@class Backgrid.Extension.SelectAllHeaderCell
|
||||
@extends Backgrid.Extension.SelectRowCell
|
||||
*/
|
||||
var SelectAllHeaderCell = Backgrid.Extension.SelectAllHeaderCell = SelectRowCell.extend({
|
||||
|
||||
/** @property */
|
||||
className: "select-all-header-cell",
|
||||
|
||||
/** @property */
|
||||
tagName: "th",
|
||||
|
||||
/**
|
||||
Initializer. When this cell's checkbox is checked, a Backbone
|
||||
`backgrid:select` event will be triggered for each model for the current
|
||||
page in the underlying collection. If a `SelectRowCell` instance exists
|
||||
for the rows representing the models, they will check themselves. If any
|
||||
of the SelectRowCell instances trigger a Backbone `backgrid:selected`
|
||||
event with a `false` value, this cell will uncheck its checkbox. In the
|
||||
event of a Backbone `backgrid:refresh` event, which is triggered when the
|
||||
body refreshes its rows, which can happen under a number of conditions
|
||||
such as paging or the columns were reset, this cell will still remember
|
||||
the previously selected models and trigger a Backbone `backgrid:select`
|
||||
event on them such that the SelectRowCells can recheck themselves upon
|
||||
refreshing.
|
||||
|
||||
@param {Object} options
|
||||
@param {Backgrid.Column} options.column
|
||||
@param {Backbone.Collection} options.collection
|
||||
*/
|
||||
initialize: function (options) {
|
||||
Backgrid.requireOptions(options, ["column", "collection"]);
|
||||
|
||||
this.column = options.column;
|
||||
if (!(this.column instanceof Backgrid.Column)) {
|
||||
this.column = new Backgrid.Column(this.column);
|
||||
}
|
||||
|
||||
var collection = this.collection;
|
||||
var selectedModels = this.selectedModels = {};
|
||||
this.listenTo(collection, "backgrid:selected", function (model, selected) {
|
||||
if (selected) selectedModels[model.id || model.cid] = model;
|
||||
else {
|
||||
delete selectedModels[model.id || model.cid];
|
||||
this.$el.find(":checkbox").prop("checked", false);
|
||||
}
|
||||
});
|
||||
|
||||
this.listenTo(collection, "remove", function (model) {
|
||||
delete selectedModels[model.cid];
|
||||
});
|
||||
|
||||
this.listenTo(collection, "backgrid:refresh", function () {
|
||||
this.$el.find(":checkbox").prop("checked", false);
|
||||
for (var i = 0; i < collection.length; i++) {
|
||||
var model = collection.at(i);
|
||||
if (selectedModels[model.id || model.cid]) {
|
||||
model.trigger('backgrid:select', model, true);
|
||||
}
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
Progagates the checked value of this checkbox to all the models of the
|
||||
underlying collection by triggering a Backbone `backgrid:select` event on
|
||||
the models themselves, passing each model and the current `checked` value
|
||||
of the checkbox in each event.
|
||||
*/
|
||||
onChange: function (e) {
|
||||
var checked = $(e.target).prop("checked");
|
||||
|
||||
var collection = this.collection;
|
||||
collection.each(function (model) {
|
||||
model.trigger("backgrid:select", model, checked);
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
Convenient method to retrieve a list of selected models. This method only
|
||||
exists when the `SelectAll` extension has been included.
|
||||
|
||||
@member Backgrid.Grid
|
||||
@return {Array.<Backbone.Model>}
|
||||
*/
|
||||
Backgrid.Grid.prototype.getSelectedModels = function () {
|
||||
var selectAllHeaderCell;
|
||||
var headerCells = this.header.row.cells;
|
||||
for (var i = 0, l = headerCells.length; i < l; i++) {
|
||||
var headerCell = headerCells[i];
|
||||
if (headerCell instanceof SelectAllHeaderCell) {
|
||||
selectAllHeaderCell = headerCell;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var result = [];
|
||||
if (selectAllHeaderCell) {
|
||||
for (var modelId in selectAllHeaderCell.selectedModels) {
|
||||
result.push(this.collection.get(modelId));
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
}(window, jQuery, _, Backbone, Backgrid));
|
||||
8
static/js/libs/backgrid/extensions/select-all/backgrid-select-all.min.css
vendored
Normal file
8
static/js/libs/backgrid/extensions/select-all/backgrid-select-all.min.css
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
backgrid-select-all
|
||||
http://github.com/wyuenho/backgrid
|
||||
|
||||
Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
|
||||
Licensed under the MIT @license.
|
||||
*/
|
||||
.backgrid .select-row-cell,.backgrid .select-all-header-cell{text-align:center}
|
||||
8
static/js/libs/backgrid/extensions/select-all/backgrid-select-all.min.js
vendored
Normal file
8
static/js/libs/backgrid/extensions/select-all/backgrid-select-all.min.js
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
backgrid-select-all
|
||||
http://github.com/wyuenho/backgrid
|
||||
|
||||
Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
|
||||
Licensed under the MIT @license.
|
||||
*/
|
||||
(function(e,t,i,n,o){var c=o.Extension.SelectRowCell=n.View.extend({className:"select-row-cell",tagName:"td",events:{"keydown :checkbox":"onKeydown","change :checkbox":"onChange","click :checkbox":"enterEditMode"},initialize:function(e){o.requireOptions(e,["model","column"]),this.column=e.column,this.column instanceof o.Column||(this.column=new o.Column(this.column)),this.listenTo(this.model,"backgrid:select",function(e,t){this.$el.find(":checkbox").prop("checked",t).change()})},enterEditMode:function(){this.$el.find(":checkbox").focus()},exitEditMode:function(){this.$el.find(":checkbox").blur()},onKeydown:function(e){var t=new o.Command(e);return t.passThru()?!0:(t.cancel()?(e.stopPropagation(),this.$el.find(":checkbox").blur()):(t.save()||t.moveLeft()||t.moveRight()||t.moveUp()||t.moveDown())&&(e.preventDefault(),e.stopPropagation(),this.model.trigger("backgrid:edited",this.model,this.column,t)),void 0)},onChange:function(e){this.model.trigger("backgrid:selected",this.model,t(e.target).prop("checked"))},render:function(){return this.$el.empty().append('<input tabindex="-1" type="checkbox" />'),this.delegateEvents(),this}}),l=o.Extension.SelectAllHeaderCell=c.extend({className:"select-all-header-cell",tagName:"th",initialize:function(e){o.requireOptions(e,["column","collection"]),this.column=e.column,this.column instanceof o.Column||(this.column=new o.Column(this.column));var t=this.collection,i=this.selectedModels={};this.listenTo(t,"backgrid:selected",function(e,t){t?i[e.id||e.cid]=e:(delete i[e.id||e.cid],this.$el.find(":checkbox").prop("checked",!1))}),this.listenTo(t,"remove",function(e){delete i[e.cid]}),this.listenTo(t,"backgrid:refresh",function(){this.$el.find(":checkbox").prop("checked",!1);for(var e=0;e<t.length;e++){var n=t.at(e);i[n.id||n.cid]&&n.trigger("backgrid:select",n,!0)}})},onChange:function(e){var i=t(e.target).prop("checked"),n=this.collection;n.each(function(e){e.trigger("backgrid:select",e,i)})}});o.Grid.prototype.getSelectedModels=function(){for(var e,t=this.header.row.cells,i=0,n=t.length;n>i;i++){var o=t[i];if(o instanceof l){e=o;break}}var c=[];if(e)for(var s in e.selectedModels)c.push(this.collection.get(s));return c}})(window,jQuery,_,Backbone,Backgrid);
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
backgrid-select2-cell
|
||||
http://github.com/wyuenho/backgrid
|
||||
|
||||
Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
|
||||
Licensed under the MIT @license.
|
||||
*/
|
||||
|
||||
.backgrid .select2-cell {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.backgrid .select2-cell.editor {
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.backgrid .select2-cell.editor .select2-container {
|
||||
width: 100%;
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
/*
|
||||
backgrid-select2-cell
|
||||
http://github.com/wyuenho/backgrid
|
||||
|
||||
Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
|
||||
Licensed under the MIT @license.
|
||||
*/
|
||||
|
||||
(function (window, $, _, Backbone, Backgrid) {
|
||||
|
||||
/**
|
||||
Select2CellEditor is a cell editor that renders a `select2` select box
|
||||
instead of the default `<select>` HTML element.
|
||||
|
||||
See:
|
||||
|
||||
- [Select2](http://ivaynberg.github.com/select2/)
|
||||
|
||||
@class Backgrid.Extension.Select2CellEditor
|
||||
@extends Backgrid.SelectCellEditor
|
||||
*/
|
||||
var Select2CellEditor = Backgrid.Extension.Select2CellEditor = Backgrid.SelectCellEditor.extend({
|
||||
|
||||
/** @property */
|
||||
events: {
|
||||
"close": "save",
|
||||
"change": "save"
|
||||
},
|
||||
|
||||
/** @property */
|
||||
select2Options: null,
|
||||
|
||||
initialize: function () {
|
||||
Backgrid.SelectCellEditor.prototype.initialize.apply(this, arguments);
|
||||
this.close = _.bind(this.close, this);
|
||||
},
|
||||
|
||||
/**
|
||||
Sets the options for `select2`. Called by the parent Select2Cell during
|
||||
edit mode.
|
||||
*/
|
||||
setSelect2Options: function (options) {
|
||||
this.select2Options = _.extend({containerCssClass: "select2-container"},
|
||||
options || {});
|
||||
},
|
||||
|
||||
/**
|
||||
Renders a `select2` select box instead of the default `<select>` HTML
|
||||
element using the supplied options from #select2Options.
|
||||
|
||||
@chainable
|
||||
*/
|
||||
render: function () {
|
||||
Backgrid.SelectCellEditor.prototype.render.apply(this, arguments);
|
||||
this.$el.select2(this.select2Options);
|
||||
this.delegateEvents();
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
Attach event handlers to the select2 box and focus it.
|
||||
*/
|
||||
postRender: function () {
|
||||
var self = this;
|
||||
this.$el.parent()
|
||||
.find("." + this.select2Options.containerCssClass)
|
||||
.on("blur", function (e) {
|
||||
if (!e.relatedTarget) self.close(e);
|
||||
})
|
||||
.on("keydown", this.close)
|
||||
.attr("tabindex", -1).focus();
|
||||
},
|
||||
|
||||
remove: function () {
|
||||
this.$el.select2("destroy");
|
||||
return Backgrid.SelectCellEditor.prototype.remove.apply(this, arguments);
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
Select2Cell is a cell class that renders a `select2` select box during edit
|
||||
mode.
|
||||
|
||||
@class Backgrid.Extension.Select2Cell
|
||||
@extends Backgrid.SelectCell
|
||||
*/
|
||||
Backgrid.Extension.Select2Cell = Backgrid.SelectCell.extend({
|
||||
|
||||
/** @property */
|
||||
className: "select2-cell",
|
||||
|
||||
/** @property */
|
||||
editor: Select2CellEditor,
|
||||
|
||||
/** @property */
|
||||
select2Options: null,
|
||||
|
||||
/**
|
||||
Initializer.
|
||||
|
||||
@param {Object} options
|
||||
@param {Backbone.Model} options.model
|
||||
@param {Backgrid.Column} options.column
|
||||
@param {Object} [options.select2Options]
|
||||
|
||||
@throws {TypeError} If `optionsValues` is undefined.
|
||||
*/
|
||||
initialize: function (options) {
|
||||
Backgrid.SelectCell.prototype.initialize.apply(this, arguments);
|
||||
this.select2Options = options.select2Options || this.select2Options;
|
||||
this.listenTo(this.model, "backgrid:edit", function (model, column, cell, editor) {
|
||||
if (column.get("name") == this.column.get("name")) {
|
||||
editor.setSelect2Options(this.select2Options);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
}(window, jQuery, _, Backbone, Backgrid));
|
||||
8
static/js/libs/backgrid/extensions/select2-cell/backgrid-select2-cell.min.css
vendored
Normal file
8
static/js/libs/backgrid/extensions/select2-cell/backgrid-select2-cell.min.css
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
backgrid-select2-cell
|
||||
http://github.com/wyuenho/backgrid
|
||||
|
||||
Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
|
||||
Licensed under the MIT @license.
|
||||
*/
|
||||
.backgrid .select2-cell{text-align:center}.backgrid .select2-cell.editor{padding:0}.backgrid .select2-cell.editor .select2-container{width:100%}
|
||||
8
static/js/libs/backgrid/extensions/select2-cell/backgrid-select2-cell.min.js
vendored
Normal file
8
static/js/libs/backgrid/extensions/select2-cell/backgrid-select2-cell.min.js
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
backgrid-select2-cell
|
||||
http://github.com/wyuenho/backgrid
|
||||
|
||||
Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
|
||||
Licensed under the MIT @license.
|
||||
*/
|
||||
(function(e,t,i,s,n){var l=n.Extension.Select2CellEditor=n.SelectCellEditor.extend({events:{close:"save",change:"save"},select2Options:null,initialize:function(){n.SelectCellEditor.prototype.initialize.apply(this,arguments),this.close=i.bind(this.close,this)},setSelect2Options:function(e){this.select2Options=i.extend({containerCssClass:"select2-container"},e||{})},render:function(){return n.SelectCellEditor.prototype.render.apply(this,arguments),this.$el.select2(this.select2Options),this.delegateEvents(),this},postRender:function(){var e=this;this.$el.parent().find("."+this.select2Options.containerCssClass).on("blur",function(t){t.relatedTarget||e.close(t)}).on("keydown",this.close).attr("tabindex",-1).focus()},remove:function(){return this.$el.select2("destroy"),n.SelectCellEditor.prototype.remove.apply(this,arguments)}});n.Extension.Select2Cell=n.SelectCell.extend({className:"select2-cell",editor:l,select2Options:null,initialize:function(e){n.SelectCell.prototype.initialize.apply(this,arguments),this.select2Options=e.select2Options||this.select2Options,this.listenTo(this.model,"backgrid:edit",function(e,t,i,s){t.get("name")==this.column.get("name")&&s.setSelect2Options(this.select2Options)})}})})(window,jQuery,_,Backbone,Backgrid);
|
||||
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
backgrid-text-cell
|
||||
http://github.com/wyuenho/backgrid
|
||||
|
||||
Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
|
||||
Licensed under the MIT @license.
|
||||
*/
|
||||
|
||||
.backgrid .text-cell {
|
||||
max-width: 150px;
|
||||
overflow: hidden;
|
||||
text-align: left;
|
||||
-o-text-overflow: ellipsis;
|
||||
text-overflow: ellipsis;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.backgrid .text-cell.editor {
|
||||
max-width: 100%;
|
||||
height: 28px;
|
||||
}
|
||||
|
||||
.backgrid .text-cell.editor * {
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.backgrid .text-cell.editor textarea {
|
||||
width: 100%;
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
/*
|
||||
backgrid-text-cell
|
||||
http://github.com/wyuenho/backgrid
|
||||
|
||||
Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
|
||||
Licensed under the MIT @license.
|
||||
*/
|
||||
|
||||
(function (window, $, _, Backbone, Backgrid) {
|
||||
|
||||
/**
|
||||
Renders a form with a text area and a save button in a modal dialog.
|
||||
|
||||
@class Backgrid.Extension.TextareaEditor
|
||||
@extends Backgrid.CellEditor
|
||||
*/
|
||||
var TextareaEditor = Backgrid.Extension.TextareaEditor = Backgrid.CellEditor.extend({
|
||||
|
||||
/** @property */
|
||||
tagName: "div",
|
||||
|
||||
/** @property */
|
||||
className: "modal hide fade",
|
||||
|
||||
/** @property {function(Object, ?Object=): string} template */
|
||||
template: _.template('<form><div class="modal-header"><button type="button" class="close" data-dismiss="modal">×</button><h3><%- column.get("label") %></h3></div><div class="modal-body"><textarea cols="<%= cols %>" rows="<%= rows %>"><%- content %></textarea></div><div class="modal-footer"><input class="btn" type="submit" value="Save"/></div></form>'),
|
||||
|
||||
/** @property */
|
||||
cols: 80,
|
||||
|
||||
/** @property */
|
||||
rows: 10,
|
||||
|
||||
/** @property */
|
||||
events: {
|
||||
"keydown textarea": "clearError",
|
||||
"submit": "saveOrCancel",
|
||||
"hide": "saveOrCancel",
|
||||
"hidden": "close",
|
||||
"shown": "focus"
|
||||
},
|
||||
|
||||
/**
|
||||
@property {Object} modalOptions The options passed to Bootstrap's modal
|
||||
plugin.
|
||||
*/
|
||||
modalOptions: {
|
||||
backdrop: false
|
||||
},
|
||||
|
||||
/**
|
||||
Renders a modal form dialog with a textarea, submit button and a close button.
|
||||
*/
|
||||
render: function () {
|
||||
this.$el.html($(this.template({
|
||||
column: this.column,
|
||||
cols: this.cols,
|
||||
rows: this.rows,
|
||||
content: this.formatter.fromRaw(this.model.get(this.column.get("name")))
|
||||
})));
|
||||
|
||||
this.delegateEvents();
|
||||
|
||||
this.$el.modal(this.modalOptions);
|
||||
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
Event handler. Saves the text in the text area to the model when
|
||||
submitting. When cancelling, if the text area is dirty, a confirmation
|
||||
dialog will pop up. If the user clicks confirm, the text will be saved to
|
||||
the model.
|
||||
|
||||
Triggers a Backbone `backgrid:error` event from the model along with the
|
||||
model, column and the existing value as the parameters if the value
|
||||
cannot be converted.
|
||||
|
||||
@param {Event} e
|
||||
*/
|
||||
saveOrCancel: function (e) {
|
||||
if (e && e.type == "submit") {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
|
||||
var model = this.model;
|
||||
var column = this.column;
|
||||
var val = this.$el.find("textarea").val();
|
||||
var newValue = this.formatter.toRaw(val);
|
||||
|
||||
if (_.isUndefined(newValue)) {
|
||||
model.trigger("backgrid:error", model, column, val);
|
||||
|
||||
if (e) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
}
|
||||
}
|
||||
else if (!e || e.type == "submit" ||
|
||||
(e.type == "hide" &&
|
||||
newValue !== (this.model.get(this.column.get("name")) || '').replace(/\r/g, '') &&
|
||||
window.confirm("Would you like to save your changes?"))) {
|
||||
|
||||
model.set(column.get("name"), newValue);
|
||||
this.$el.modal("hide");
|
||||
}
|
||||
else if (e.type != "hide") this.$el.modal("hide");
|
||||
},
|
||||
|
||||
/**
|
||||
Clears the error class on the parent cell.
|
||||
*/
|
||||
clearError: _.debounce(function () {
|
||||
if (!_.isUndefined(this.formatter.toRaw(this.$el.find("textarea").val()))) {
|
||||
this.$el.parent().removeClass("error");
|
||||
}
|
||||
}, 150),
|
||||
|
||||
/**
|
||||
Triggers a `backgrid:edited` event along with the cell editor as the
|
||||
parameter after the modal is hidden.
|
||||
|
||||
@param {Event} e
|
||||
*/
|
||||
close: function (e) {
|
||||
var model = this.model;
|
||||
model.trigger("backgrid:edited", model, this.column,
|
||||
new Backgrid.Command(e));
|
||||
},
|
||||
|
||||
/**
|
||||
Focuses the textarea when the modal is shown.
|
||||
*/
|
||||
focus: function () {
|
||||
this.$el.find("textarea").focus();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
TextCell is a string cell type that renders a form with a text area in a
|
||||
modal dialog instead of an input box editor. It is best suited for entering
|
||||
a large body of text.
|
||||
|
||||
@class Backgrid.Extension.TextCell
|
||||
@extends Backgrid.StringCell
|
||||
*/
|
||||
var TextCell = Backgrid.Extension.TextCell = Backgrid.StringCell.extend({
|
||||
|
||||
/** @property */
|
||||
className: "text-cell",
|
||||
|
||||
/** @property */
|
||||
editor: TextareaEditor
|
||||
|
||||
});
|
||||
|
||||
}(window, jQuery, _, Backbone, Backgrid));
|
||||
8
static/js/libs/backgrid/extensions/text-cell/backgrid-text-cell.min.css
vendored
Normal file
8
static/js/libs/backgrid/extensions/text-cell/backgrid-text-cell.min.css
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
backgrid-text-cell
|
||||
http://github.com/wyuenho/backgrid
|
||||
|
||||
Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
|
||||
Licensed under the MIT @license.
|
||||
*/
|
||||
.backgrid .text-cell{max-width:150px;overflow:hidden;text-align:left;-o-text-overflow:ellipsis;text-overflow:ellipsis;white-space:nowrap}.backgrid .text-cell.editor{height:28px;max-width:100%}.backgrid .text-cell.editor *{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}.backgrid .text-cell.editor textarea{width:100%}
|
||||
8
static/js/libs/backgrid/extensions/text-cell/backgrid-text-cell.min.js
vendored
Normal file
8
static/js/libs/backgrid/extensions/text-cell/backgrid-text-cell.min.js
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
backgrid-text-cell
|
||||
http://github.com/wyuenho/backgrid
|
||||
|
||||
Copyright (c) 2013 Jimmy Yuen Ho Wong and contributors
|
||||
Licensed under the MIT @license.
|
||||
*/
|
||||
(function(e,t,o,a,s){var i=s.Extension.TextareaEditor=s.CellEditor.extend({tagName:"div",className:"modal hide fade",template:o.template('<form><div class="modal-header"><button type="button" class="close" data-dismiss="modal">×</button><h3><%- column.get("label") %></h3></div><div class="modal-body"><textarea cols="<%= cols %>" rows="<%= rows %>"><%- content %></textarea></div><div class="modal-footer"><input class="btn" type="submit" value="Save"/></div></form>'),cols:80,rows:10,events:{"keydown textarea":"clearError",submit:"saveOrCancel",hide:"saveOrCancel",hidden:"close",shown:"focus"},modalOptions:{backdrop:!1},render:function(){return this.$el.html(t(this.template({column:this.column,cols:this.cols,rows:this.rows,content:this.formatter.fromRaw(this.model.get(this.column.get("name")))}))),this.delegateEvents(),this.$el.modal(this.modalOptions),this},saveOrCancel:function(t){t&&t.type=="submit"&&(t.preventDefault(),t.stopPropagation());var a=this.model,s=this.column,i=this.$el.find("textarea").val(),l=this.formatter.toRaw(i);o.isUndefined(l)?(a.trigger("backgrid:error",a,s,i),t&&(t.preventDefault(),t.stopPropagation())):!t||t.type=="submit"||t.type=="hide"&&l!==(this.model.get(this.column.get("name"))||"").replace(/\r/g,"")&&e.confirm("Would you like to save your changes?")?(a.set(s.get("name"),l),this.$el.modal("hide")):t.type!="hide"&&this.$el.modal("hide")},clearError:o.debounce(function(){o.isUndefined(this.formatter.toRaw(this.$el.find("textarea").val()))||this.$el.parent().removeClass("error")},150),close:function(e){var t=this.model;t.trigger("backgrid:edited",t,this.column,new s.Command(e))},focus:function(){this.$el.find("textarea").focus()}});s.Extension.TextCell=s.StringCell.extend({className:"text-cell",editor:i})})(window,jQuery,_,Backbone,Backgrid);
|
||||
Reference in New Issue
Block a user