Removed old static files
@@ -1,309 +0,0 @@
|
||||
/* ------- Media ------- */
|
||||
|
||||
.sidebar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@media (max-width: 440px) {
|
||||
|
||||
.navbar .col-xs-8 {
|
||||
padding-right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
|
||||
tr th#tags,
|
||||
td[name="tags"] {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* button.navbar-toggle[data-target="#navigate-navbar-collapse"]{ */
|
||||
/* margin-left: 20px; */
|
||||
/* } */
|
||||
|
||||
/* .container > .navbar-header, .container-fluid > .navbar-header, .container > .navbar-collapse, .container-fluid > .navbar-collapse { */
|
||||
/* margin-left: 0; */
|
||||
/* margin-right: 0; */
|
||||
/* } */
|
||||
|
||||
}
|
||||
|
||||
@media (max-width: 1198px) {
|
||||
|
||||
.display-up-1198{
|
||||
display: none;
|
||||
}
|
||||
.dropdown{
|
||||
margin:0px;
|
||||
}
|
||||
.btn-group{
|
||||
margin:0px;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 768px) {
|
||||
|
||||
.sidebar {
|
||||
position: fixed !important;
|
||||
top: 51px;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
width: 250px;
|
||||
z-index: 1000;
|
||||
display: block;
|
||||
padding: 15px 0;
|
||||
overflow: auto;
|
||||
background-color: #f5f5f5;
|
||||
border-right: 1px solid #ddd;
|
||||
}
|
||||
|
||||
.main {
|
||||
position: relative;
|
||||
margin-left: 250px;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* --------- general --------- */
|
||||
|
||||
.container-fluid {
|
||||
padding-left: 0;
|
||||
padding-right: 0;
|
||||
}
|
||||
|
||||
/* Form */
|
||||
|
||||
#uprefs_content input[type="checkbox"] {
|
||||
margin-top: 10px;
|
||||
}
|
||||
/* Buttons */
|
||||
|
||||
.navbar .btn-link:hover,
|
||||
.navbar .btn-link:focus{
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.well .nav > li > a {
|
||||
padding: 2px 5px;
|
||||
}
|
||||
|
||||
/* Colapse Nav */
|
||||
|
||||
.navbar-inverse .navbar-toggle span {
|
||||
color: white;
|
||||
}
|
||||
|
||||
.navbar-toggle {
|
||||
margin-top: 4px;
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
|
||||
/* Global */
|
||||
body {
|
||||
padding-top: 50px;
|
||||
padding-bottom: 50px;
|
||||
}
|
||||
|
||||
h5 {
|
||||
font-size: 15px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
label {
|
||||
font-weight: normal;
|
||||
}
|
||||
|
||||
.modals div.input-group{
|
||||
margin-bottom:8px;
|
||||
}
|
||||
|
||||
.form-horizontal .param-label {
|
||||
float: left;
|
||||
padding-top: 5px;
|
||||
text-align: left;
|
||||
width: 250px;
|
||||
margin-left: 20px;
|
||||
}
|
||||
|
||||
.form-horizontal .input-group {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
.dropdown{
|
||||
margin-right: 20px;
|
||||
}
|
||||
|
||||
.dropdown-menu .radio {
|
||||
padding: 3px 15px;
|
||||
}
|
||||
|
||||
.no-margin {
|
||||
margin: 0 !important;
|
||||
}
|
||||
|
||||
.buttons_list .bset {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.buttons_list .active {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.tr-selected {
|
||||
background-color: #F5F5F5;
|
||||
}
|
||||
|
||||
.hidden {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.label a {
|
||||
color: #FFFFFF;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.table-fixed {
|
||||
table-layout: fixed;
|
||||
}
|
||||
|
||||
.menu-link {
|
||||
display: block;
|
||||
padding: 3px 20px;
|
||||
clear: both;
|
||||
font-weight: 400;
|
||||
line-height: 1.42857143;
|
||||
color: #333;
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
/* --------- main page --------- */
|
||||
|
||||
|
||||
/* Top navbar section */
|
||||
|
||||
.top-navbar{
|
||||
border-radius: 0;
|
||||
}
|
||||
|
||||
.display-less-1198{
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* div#navigate-navbar-collapse.navbar-collapse { */
|
||||
/* z-index: 9999; */
|
||||
/* } */
|
||||
html body div.navbar div.container-fluid div#navigate-navbar-collapse.collapse ul.nav li.dropdown a.dropdown-toggle{
|
||||
color: white;
|
||||
}
|
||||
|
||||
/* left sidebar */
|
||||
|
||||
/* Sidebar navigation */
|
||||
.nav-sidebar {
|
||||
/*margin-right: -21px;
|
||||
margin-left: -20px;*/
|
||||
}
|
||||
.nav-sidebar li > a {
|
||||
/*padding-right: 20px;
|
||||
padding-left: 20px;*/
|
||||
}
|
||||
|
||||
.nav-sidebar > li > a:hover {
|
||||
background-color: #eee;
|
||||
}
|
||||
|
||||
.nav-sidebar .active > a,
|
||||
.nav-sidebar .active > a:hover,
|
||||
.nav-sidebar .active > a:focus {
|
||||
color: #fff;
|
||||
background-color: #428bca;
|
||||
}
|
||||
|
||||
.nav-sidebar > .nav-header {
|
||||
color: #959595;
|
||||
font-size: 12px;
|
||||
font-weight: 700;
|
||||
letter-spacing: 1px;
|
||||
text-transform: uppercase;
|
||||
padding-left: 10px;
|
||||
margin-top: 10px;
|
||||
margin-bottom: 5px;
|
||||
}
|
||||
|
||||
/* Action buttons */
|
||||
|
||||
.action-buttons {
|
||||
margin-bottom: 4px;
|
||||
}
|
||||
|
||||
.main {
|
||||
padding: 20px 15px;
|
||||
}
|
||||
|
||||
/* listing */
|
||||
|
||||
/* Bottom navBar*/
|
||||
|
||||
.nav-bottom {
|
||||
margin-top: 80px;
|
||||
}
|
||||
|
||||
#bottom-bar-middle {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#bottom-bar-right{
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
.navbar-text {
|
||||
color: #999999 !important;
|
||||
float:none;
|
||||
}
|
||||
|
||||
/* Tables */
|
||||
table th#actions {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
table td[name="actions"] {
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
/* --------- specific pages --------- */
|
||||
|
||||
/* identities tables */
|
||||
|
||||
.muted a:hover{
|
||||
color: black;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.label {
|
||||
margin-left: 1px;
|
||||
}
|
||||
|
||||
|
||||
/* modals */
|
||||
|
||||
.modal-body .nav-pills {
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
/* settings */
|
||||
|
||||
.container-fluid #uprefs_content .form-horizontal .form-actions {
|
||||
margin-right: 16px;
|
||||
}
|
||||
|
||||
/* Wizard */
|
||||
#wizard .carousel-inner {
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
/* Dashboard */
|
||||
.slogan {
|
||||
padding-top: 15px;
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
.sort-header {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.sort-header i {
|
||||
margin-left: 10px;
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
#searchbox {
|
||||
margin-right: 10px;
|
||||
z-index: 2;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#searchbox img {
|
||||
float: left;
|
||||
margin-top: 4px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
#searchparams {
|
||||
background: white;
|
||||
padding: 5px;
|
||||
width: 90%;
|
||||
border-bottom: 5px solid #CCCCCC;
|
||||
border-left: 5px solid #CCCCCC;
|
||||
border-right: 5px solid #CCCCCC;
|
||||
}
|
||||
|
Before Width: | Height: | Size: 2.5 KiB |
@@ -1,54 +0,0 @@
|
||||
/*
|
||||
* Just an extract of Bootstrap table and alert styles in order to include it
|
||||
* into the 'viewmail' page. It is not really *clean* but I don't know
|
||||
* any other way to do that.
|
||||
*/
|
||||
body{margin:5px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;line-height:18px;color:#333333;background-color:#ffffff;}
|
||||
.alert{padding:8px 35px 8px 14px;margin-bottom:18px;text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;color:#c09853;}
|
||||
.alert-heading{color:inherit;}
|
||||
.alert .close{position:relative;top:-2px;right:-21px;line-height:18px;}
|
||||
.alert-success{background-color:#dff0d8;border-color:#d6e9c6;color:#468847;}
|
||||
.alert-danger{background-color:#f2dede;border-color:#eed3d7;color:#b94a48;}
|
||||
.alert-info{background-color:#d9edf7;border-color:#bce8f1;color:#3a87ad;}
|
||||
.alert-block{padding-top:14px;padding-bottom:14px;}
|
||||
.alert-block>p,.alert-block>ul{margin-bottom:0;}
|
||||
.alert-block p+p{margin-top:5px;}
|
||||
.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #eee;border:1px solid rgba(0, 0, 0, 0.05);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);}.well blockquote{border-color:#ddd;border-color:rgba(0, 0, 0, 0.15);}
|
||||
.well-large{padding:24px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;}
|
||||
.well-small{padding:9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;}
|
||||
.row{margin-left:-20px;*zoom:1;}.row:before,.row:after{display:table;content:"";}
|
||||
.row:after{clear:both;}
|
||||
|
||||
pre {
|
||||
white-space: pre-wrap; /* css-3 */
|
||||
white-space: -moz-pre-wrap !important; /* Mozilla, since 1999 */
|
||||
white-space: -pre-wrap; /* Opera 4-6 */
|
||||
white-space: -o-pre-wrap; /* Opera 7 */
|
||||
word-wrap: break-word; /* Internet Explorer 5.5+ */
|
||||
font-size: medium;
|
||||
border: 0;
|
||||
}
|
||||
#mailcontent {
|
||||
width: 100%;
|
||||
border: 0px transparent none;
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
#emailheaders a, #emailheaders a:visited {
|
||||
color: blue;
|
||||
text-decoration: none;
|
||||
}
|
||||
#emailheaders a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.hidden { display: none; }
|
||||
.header, .value { font-size: 14px; }
|
||||
.header {
|
||||
float: left;
|
||||
margin-left: 10px;
|
||||
margin-right: 20px;
|
||||
font-weight: bold;
|
||||
width: 13.5%;
|
||||
padding: 0 0 2px 0;
|
||||
}
|
||||
@@ -1,198 +0,0 @@
|
||||
(function($) {
|
||||
"use strict";
|
||||
|
||||
var Autocompleter = function(element, options) {
|
||||
this.initialize(element, options);
|
||||
};
|
||||
|
||||
Autocompleter.prototype = {
|
||||
constructor: Autocompleter,
|
||||
|
||||
initialize: function(element, options) {
|
||||
this.$element = $(element);
|
||||
this.options = $.extend({}, $.fn.autocompleter.defaults, options);
|
||||
if (typeof this.options.choices === "function") {
|
||||
this.choices = this.options.choices();
|
||||
} else {
|
||||
this.choices = this.options.choices;
|
||||
}
|
||||
this.$menu =
|
||||
$('<ul class="dropdown-menu autocompleter" data-toggle="dropdown" />');
|
||||
$("body").append(this.$menu);
|
||||
this.$menu.on("click", $.proxy(this.select_entry, this));
|
||||
|
||||
this.$element.attr("autocomplete", "off");
|
||||
this.listen();
|
||||
},
|
||||
|
||||
listen: function() {
|
||||
this.$element.keydown($.proxy(this.keydown, this));
|
||||
this.$element.keyup($.proxy(this.keyup, this));
|
||||
this.$element.blur($.proxy(this.hide_menu, this));
|
||||
},
|
||||
|
||||
unbind: function() {
|
||||
this.$element.off("keydown keyup blur");
|
||||
},
|
||||
|
||||
check_user_input: function() {
|
||||
var value = this.$element.val();
|
||||
var start = -1;
|
||||
var pattern = null;
|
||||
|
||||
if (this.options.from_character) {
|
||||
start = value.indexOf(this.options.from_character);
|
||||
if (start == -1) {
|
||||
return;
|
||||
}
|
||||
pattern = value.substr(start + 1);
|
||||
} else {
|
||||
pattern = value;
|
||||
}
|
||||
|
||||
var exp = new RegExp("^" + pattern);
|
||||
|
||||
this.$menu.empty();
|
||||
$.each(this.choices, $.proxy(function(index, value) {
|
||||
if (exp.test(value)) {
|
||||
this.$menu.append(
|
||||
$('<li><a href="#" name="' + htmlEncode(value) + '">' + htmlEncode(value) + '</a></li>')
|
||||
);
|
||||
}
|
||||
}, this));
|
||||
|
||||
var coords = this.$element.offset();
|
||||
|
||||
this.$menu.css({
|
||||
position: "absolute",
|
||||
top: coords.top + this.$element.outerHeight(),
|
||||
left: coords.left,
|
||||
width: this.$element.outerWidth(),
|
||||
'z-index': 1051
|
||||
});
|
||||
if (this.$menu.children().length) {
|
||||
this.$menu.children().first().addClass("active");
|
||||
this.$menu.show();
|
||||
} else {
|
||||
this.$menu.hide();
|
||||
}
|
||||
},
|
||||
|
||||
hide_menu: function() {
|
||||
setTimeout($.proxy(function() { this.$menu.hide(); }, this), 150);
|
||||
},
|
||||
|
||||
select_entry: function(evt) {
|
||||
if (this.$menu.is(":visible")) {
|
||||
var $link;
|
||||
if (evt !== undefined) {
|
||||
evt.preventDefault();
|
||||
$link = $(evt.target);
|
||||
} else {
|
||||
$link = this.$menu.find('.active > a');
|
||||
}
|
||||
var curvalue = this.$element.val();
|
||||
|
||||
if (curvalue === undefined || curvalue === "") {
|
||||
if (this.options.empty_choice) {
|
||||
this.options.empty_choice();
|
||||
}
|
||||
return;
|
||||
}
|
||||
if ($link.length) {
|
||||
this.$element.val(curvalue.substr(
|
||||
0, curvalue.indexOf(this.options.from_character) + 1
|
||||
) + $link.attr("name"));
|
||||
this.$element.change();
|
||||
}
|
||||
this.hide_menu();
|
||||
}
|
||||
if (this.options.choice_selected) {
|
||||
this.options.choice_selected(this.$element.val());
|
||||
}
|
||||
},
|
||||
|
||||
activate_next: function() {
|
||||
var active = this.$menu.find('.active').removeClass('active'),
|
||||
next = active.next();
|
||||
|
||||
if (!next.length) {
|
||||
next = $(this.$menu.find('li').first());
|
||||
}
|
||||
next.addClass('active');
|
||||
},
|
||||
|
||||
activate_prev: function() {
|
||||
var active = this.$menu.find('.active').removeClass('active'),
|
||||
prev = active.prev();
|
||||
|
||||
if (!prev.length) {
|
||||
prev = this.$menu.find('li').last();
|
||||
}
|
||||
|
||||
prev.addClass('active');
|
||||
},
|
||||
|
||||
keydown: function(evt) {
|
||||
evt.stopPropagation();
|
||||
|
||||
switch (evt.which) {
|
||||
case 13:
|
||||
case 27:
|
||||
evt.preventDefault();
|
||||
break;
|
||||
case 38:
|
||||
evt.preventDefault();
|
||||
this.activate_prev();
|
||||
break;
|
||||
case 40:
|
||||
evt.preventDefault();
|
||||
this.activate_next();
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
keyup: function(evt) {
|
||||
evt.stopPropagation();
|
||||
evt.preventDefault();
|
||||
|
||||
switch (evt.which) {
|
||||
case 40:
|
||||
case 38:
|
||||
break;
|
||||
|
||||
case 13:
|
||||
this.select_entry();
|
||||
break;
|
||||
|
||||
case 27:
|
||||
this.hide_menu();
|
||||
break;
|
||||
|
||||
default:
|
||||
this.check_user_input();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$.fn.autocompleter = function(option) {
|
||||
return this.each(function() {
|
||||
var $this = $(this),
|
||||
data = $this.data('autocompleter'),
|
||||
options = typeof option === "object" && option;
|
||||
|
||||
if (!data) {
|
||||
$this.data('autocompleter', new Autocompleter(this, options));
|
||||
}
|
||||
if (typeof option === "string") {
|
||||
data[option]();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$.fn.autocompleter.defaults = {
|
||||
'choice_selected' : null,
|
||||
'empty_choice' : null
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
@@ -1,127 +0,0 @@
|
||||
(function($) {
|
||||
var Confirm = function(element, options) {
|
||||
this.$element = $(element);
|
||||
this.options = $.extend({}, $.fn.confirm.defaults, options);
|
||||
this.$element.click($.proxy(this.show, this));
|
||||
};
|
||||
|
||||
Confirm.prototype = {
|
||||
constructor: Confirm,
|
||||
|
||||
show: function(e) {
|
||||
e.preventDefault();
|
||||
|
||||
this.box = this.buildbox();
|
||||
this.box.modal();
|
||||
this.box.on('hidden.bs.modal', $.proxy(this.hidden_callback, this));
|
||||
},
|
||||
|
||||
buildcheckboxes: function() {
|
||||
var result = "";
|
||||
|
||||
if (!this.options.checkboxes || !Object.keys(this.options.checkboxes).length) {
|
||||
return "";
|
||||
}
|
||||
result = '<form class="form-horizontal">';
|
||||
$.each(this.options.checkboxes, function(key, val) {
|
||||
result += "<div class='form-group'><div class='col-xs-12'><div class='checkbox'><label><input type='checkbox' name='{0}' value='' />{1}</label></div></div></div>".format(key, val);
|
||||
});
|
||||
result += '</form>';
|
||||
return result;
|
||||
},
|
||||
|
||||
buildbox: function() {
|
||||
var box = $('<div />', {
|
||||
id: "confirmbox",
|
||||
'class': "modal fade"
|
||||
});
|
||||
var question = (typeof this.options.question === 'function') ?
|
||||
this.options.question.apply(this) : this.options.question;
|
||||
var checkboxes = this.buildcheckboxes();
|
||||
var body = "";
|
||||
|
||||
if (this.options.warning) {
|
||||
body += '<div class="alert alert-danger"><h4>{0}</h4>{1}</div>'.format(gettext("Warning"), this.options.warning);
|
||||
}
|
||||
if (checkboxes !== "") {
|
||||
body += "<p>{0}</p>".format(checkboxes);
|
||||
}
|
||||
|
||||
var content = '<div class="modal-dialog"><div class="modal-content">';
|
||||
var title_patten = '<div class="{0}"><h3 class="modal-title">{1}</h3></div>';
|
||||
|
||||
if (body !== "") {
|
||||
content += title_patten.format("modal-header", question);
|
||||
content += '<div class="modal-body">{0}</div>'.format(body);
|
||||
} else {
|
||||
content += title_patten.format("modal-body", question);
|
||||
}
|
||||
content += '<div class="modal-footer"><a href="#" class="btn btn-primary">Ok</a><a href="#" class="btn btn-default">{0}</a></div>'.format(gettext("Cancel"));
|
||||
|
||||
box.append($(content));
|
||||
|
||||
box.find(".btn-primary").click(function(evt) {
|
||||
evt.preventDefault();
|
||||
box.data('result', true);
|
||||
box.modal('hide');
|
||||
});
|
||||
|
||||
box.find(".btn-default").click(function(evt) {
|
||||
evt.preventDefault();
|
||||
box.modal('hide');
|
||||
});
|
||||
|
||||
return box;
|
||||
},
|
||||
|
||||
hidden_callback: function() {
|
||||
if (this.box.data('result') === undefined) {
|
||||
return;
|
||||
}
|
||||
var params = "";
|
||||
|
||||
$('input[type=checkbox]:checked').each(function() {
|
||||
if (params !== "") {
|
||||
params += "&";
|
||||
}
|
||||
params += $(this).attr("name") + "=true";
|
||||
});
|
||||
$.ajax({
|
||||
cache: false,
|
||||
type: this.options.method,
|
||||
data: params,
|
||||
url: this.$element.attr('href')
|
||||
}).done($.proxy(function(data) {
|
||||
if (this.options.success_cb !== undefined) {
|
||||
this.options.success_cb(data);
|
||||
return;
|
||||
}
|
||||
window.location.reload();
|
||||
}, this));
|
||||
this.box.remove();
|
||||
}
|
||||
};
|
||||
|
||||
$.fn.confirm = function(method) {
|
||||
return this.each(function() {
|
||||
var $this = $(this),
|
||||
data = $this.data('confirm'),
|
||||
options = typeof method === "object" && method;
|
||||
|
||||
if (!data) {
|
||||
$this.data('confirm', new Confirm(this, options));
|
||||
}
|
||||
if (typeof method === "string") {
|
||||
data[method]();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$.fn.confirm.defaults = {
|
||||
question: "",
|
||||
method: "GET",
|
||||
warning: null,
|
||||
checkboxes: null
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
@@ -1,129 +0,0 @@
|
||||
(function($) {
|
||||
var Cwizard = function(element, options) {
|
||||
this.initialize(element, options);
|
||||
};
|
||||
|
||||
Cwizard.prototype = {
|
||||
constructor: Cwizard,
|
||||
|
||||
initialize: function(element, options) {
|
||||
this.$element = $(element);
|
||||
this.options = $.extend({}, $.fn.cwizard.defaults, options);
|
||||
this.$element.carousel({pause: true});
|
||||
this.$element.carousel("pause");
|
||||
this.listen();
|
||||
this.titles = {};
|
||||
$('input:text:visible:first').focus();
|
||||
},
|
||||
|
||||
listen: function() {
|
||||
$(".next").on("click", $.proxy(this.next, this));
|
||||
$(".prev").on("click", $.proxy(this.prev, this));
|
||||
$(".submit").on("click", $.proxy(this.submit, this));
|
||||
},
|
||||
|
||||
get_current_step_id: function() {
|
||||
return $(".item.active").attr("id");
|
||||
},
|
||||
|
||||
get_current_title: function() {
|
||||
return $(".modal-header").find("small").html();
|
||||
},
|
||||
|
||||
set_current_title: function(title) {
|
||||
$(".modal-header").find("small").html(title);
|
||||
},
|
||||
|
||||
post: function(last, target) {
|
||||
var $form = (this.options.formid) ? $('#' + this.options.formid) : $('form');
|
||||
var data = $form.serialize() + "&stepid=" + this.get_current_step_id() + "&target=" + target;
|
||||
|
||||
$.ajax({
|
||||
type: 'POST', url: $form.attr("action"), data: data, global: false
|
||||
}).done($.proxy(function(resp) {
|
||||
if (!last) {
|
||||
$('input:text:visible:first').focus();
|
||||
this.set_current_title(resp.title);
|
||||
if (this.options.transition_callbacks[resp.id] !== undefined) {
|
||||
this.options.transition_callbacks[resp.id]();
|
||||
}
|
||||
$(".carousel-inner").css("overflow", "hidden");
|
||||
this.$element.carousel(resp.stepid);
|
||||
} else {
|
||||
$("#modalbox").modal('hide');
|
||||
if (this.options.success_callback !== undefined) {
|
||||
this.options.success_callback(resp);
|
||||
} else {
|
||||
window.location.reload();
|
||||
}
|
||||
}
|
||||
}, this)).fail($.proxy(function(jqxhr) {
|
||||
var resp = $.parseJSON(jqxhr.responseText);
|
||||
if (resp.stepid !== undefined) {
|
||||
var stepid = resp.stepid;
|
||||
display_form_errors("step" + stepid, resp);
|
||||
if (this.options.error_callbacks[stepid] !== undefined) {
|
||||
this.options.error_callbacks[stepid]();
|
||||
}
|
||||
$('input:text:visible:first').focus();
|
||||
if (resp.respmsg) {
|
||||
$(".modal-body").prepend(build_error_alert(resp.respmsg));
|
||||
}
|
||||
return;
|
||||
}
|
||||
$(".modal-body").prepend(build_error_alert(resp));
|
||||
}, this));
|
||||
},
|
||||
|
||||
update_buttons: function() {
|
||||
$(".carousel-inner").css("overflow", "visible");
|
||||
$('.bset.active').removeClass("active");
|
||||
$("#" + $(".item.active").attr("id") + "_buttons").addClass("active");
|
||||
},
|
||||
|
||||
next: function(evt) {
|
||||
evt.preventDefault();
|
||||
var step_id = this.get_current_step_id();
|
||||
this.titles[step_id] = this.get_current_title();
|
||||
this.$element.on('slid.bs.carousel', this.update_buttons);
|
||||
this.post(false, "next");
|
||||
},
|
||||
|
||||
/**
|
||||
* Go back to the previous step.
|
||||
*/
|
||||
prev: function(evt) {
|
||||
var stepid = this.get_current_step_id();
|
||||
|
||||
evt.preventDefault();
|
||||
this.$element.on('slid.bs.carousel', this.update_buttons);
|
||||
this.post(false, "prev", stepid);
|
||||
},
|
||||
|
||||
submit: function(evt) {
|
||||
evt.preventDefault();
|
||||
this.post(true, "next");
|
||||
}
|
||||
};
|
||||
|
||||
$.fn.cwizard = function(method) {
|
||||
return this.each(function() {
|
||||
var $this = $(this),
|
||||
data = $this.data('cwizard'),
|
||||
options = typeof method === "object" && method;
|
||||
|
||||
if (!data) {
|
||||
$this.data('cwizard', new Cwizard(this, options));
|
||||
}
|
||||
if (typeof method === "string") {
|
||||
data[method]();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$.fn.cwizard.defaults = {
|
||||
transition_callbacks: {},
|
||||
error_callbacks: {}
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
@@ -1,47 +0,0 @@
|
||||
function getCookie(name) {
|
||||
var cookieValue = null;
|
||||
if (document.cookie && document.cookie != '') {
|
||||
var cookies = document.cookie.split(';');
|
||||
for (var i = 0; i < cookies.length; i++) {
|
||||
var cookie = jQuery.trim(cookies[i]);
|
||||
// Does this cookie string begin with the name we want?
|
||||
if (cookie.substring(0, name.length + 1) == (name + '=')) {
|
||||
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return cookieValue;
|
||||
}
|
||||
|
||||
function csrfSafeMethod(method) {
|
||||
// these HTTP methods do not require CSRF protection
|
||||
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
|
||||
}
|
||||
|
||||
function sameOrigin(url) {
|
||||
// test that a given url is a same-origin URL
|
||||
// url could be relative or scheme relative or absolute
|
||||
var host = document.location.host; // host + port
|
||||
var protocol = document.location.protocol;
|
||||
var sr_origin = '//' + host;
|
||||
var origin = protocol + sr_origin;
|
||||
// Allow absolute or scheme relative URLs to same origin
|
||||
return (url == origin || url.slice(0, origin.length + 1) == origin + '/') ||
|
||||
(url == sr_origin || url.slice(0, sr_origin.length + 1) == sr_origin + '/') ||
|
||||
// or any other URL that isn't scheme relative or absolute i.e relative.
|
||||
!(/^(\/\/|http:|https:).*/.test(url));
|
||||
}
|
||||
|
||||
$.ajaxSetup({
|
||||
beforeSend: function(xhr, settings) {
|
||||
var csrftoken = getCookie("csrftoken");
|
||||
|
||||
if (csrftoken && !csrfSafeMethod(settings.type) && sameOrigin(settings.url)) {
|
||||
// Send the token to same-origin, relative URLs only.
|
||||
// Send the token only if the method warrants CSRF protection
|
||||
// Using the CSRFToken value acquired earlier
|
||||
xhr.setRequestHeader("X-CSRFToken", csrftoken);
|
||||
}
|
||||
}
|
||||
});
|
||||
@@ -1,160 +0,0 @@
|
||||
(function($) {
|
||||
|
||||
/**
|
||||
* Creates an instance of DynamicInput.
|
||||
*
|
||||
* @constructor
|
||||
* @this DynamicInput
|
||||
* @param {Object} element -
|
||||
* @param {Object} options -
|
||||
*/
|
||||
var DynamicInput = function(element, options) {
|
||||
this.$element = $(element);
|
||||
this.$input = (this.$element.is("input")) ?
|
||||
this.$element : this.$element.find("input");
|
||||
this.options = $.extend({}, $.fn.dynamic_input.defaults, options);
|
||||
this.nextid = 1;
|
||||
this.baseid = this.$input.attr("id");
|
||||
this.basename = this.$input.attr("name").split("_")[0];
|
||||
|
||||
this.$input.keyup($.proxy(this.checknotempty, this));
|
||||
|
||||
for (var cpt = 1; true; cpt++) {
|
||||
var $input = $("#" + this.baseid + "_" + cpt);
|
||||
|
||||
if (!$input.length) {
|
||||
break;
|
||||
}
|
||||
$input.parent().after(this.addrmlink($input));
|
||||
$input.focusout(this.checkempty);
|
||||
this.nextid++;
|
||||
}
|
||||
};
|
||||
|
||||
DynamicInput.prototype = {
|
||||
constructor: DynamicInput,
|
||||
|
||||
/**
|
||||
* Add a remove link right to an input.
|
||||
*
|
||||
* @this DynamicInput
|
||||
* @param {Object} input - target input
|
||||
* @return {Object} - created link
|
||||
*/
|
||||
addrmlink: function(input) {
|
||||
var $rmlink = $(
|
||||
"<a href='#' id='{0}_rmbtn'>".format(input.attr("id")) +
|
||||
"<span class='fa fa-remove'></span></a>"
|
||||
);
|
||||
|
||||
$rmlink.click($.proxy(this.removeinput, this));
|
||||
return $rmlink;
|
||||
},
|
||||
|
||||
/**
|
||||
* Add a new input.
|
||||
*
|
||||
* @this DynamicInput
|
||||
*/
|
||||
addinput: function() {
|
||||
var $clone = this.$element.clone();
|
||||
var id = this.baseid + '_' + this.nextid;
|
||||
var name = this.basename + '_' + this.nextid;
|
||||
|
||||
$clone.insertAfter(this.$element);
|
||||
|
||||
var $ninput = $clone.find("input").attr("id", id).attr("name", name);
|
||||
var $rmlink = this.addrmlink($ninput);
|
||||
|
||||
$clone.append($rmlink);
|
||||
$ninput.focusout(this.checkempty);
|
||||
$ninput.val(this.$input.val());
|
||||
this.$input.val(this.options.emptylabel);
|
||||
this.nextid++;
|
||||
|
||||
if (this.options.input_added) {
|
||||
this.options.input_added($clone);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Click event. Remove an input.
|
||||
*
|
||||
* @this DynamicInput
|
||||
* @param {Object} evt - event object
|
||||
* @param {boolean} force - force the removal if true
|
||||
*/
|
||||
removeinput: function(evt, force) {
|
||||
evt.preventDefault();
|
||||
|
||||
var $link = get_target(evt, "a");
|
||||
var id = "#" + $link.attr("id").replace("_rmbtn", "");
|
||||
var $input = $(id);
|
||||
|
||||
if ($input.val() === "" && (force === undefined || !force)) {
|
||||
return;
|
||||
}
|
||||
if (this.options.input_removed && this.options.input_removed($input)) {
|
||||
return;
|
||||
}
|
||||
$input.remove();
|
||||
$link.remove();
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if input's value is not empty before adding a new input.
|
||||
*
|
||||
* @this DynamicInput
|
||||
* @param {Object} evt - event object
|
||||
*/
|
||||
checknotempty: function(evt) {
|
||||
if (evt.keyCode != 13) {
|
||||
return;
|
||||
}
|
||||
if (this.$input.val() === "") {
|
||||
return;
|
||||
}
|
||||
this.addinput();
|
||||
},
|
||||
|
||||
/**
|
||||
* Focus out event : remove the input if it's value is empty.
|
||||
*
|
||||
* @param {Object} evt - event object
|
||||
*/
|
||||
checkempty: function(evt) {
|
||||
var $input = $(evt.target);
|
||||
|
||||
if ($input.val() === "") {
|
||||
$("#" + $input.attr("id") + "_rmbtn").trigger("click", true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$.fn.dynamic_input = function(method) {
|
||||
return this.each(function() {
|
||||
var $this = $(this),
|
||||
data = $this.data('dynamic_input'),
|
||||
options = typeof method === "object" && method;
|
||||
|
||||
if (!data) {
|
||||
$this.data('dynamic_input', new DynamicInput(this, options));
|
||||
}
|
||||
if (typeof method === "string") {
|
||||
data[method]();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
/*
|
||||
* Allow an external access to the constructor (for inheritance)
|
||||
*/
|
||||
$.fn.dynamic_input.Constructor = DynamicInput;
|
||||
|
||||
$.fn.dynamic_input.defaults = {
|
||||
emptylabel: "",
|
||||
input_added: null,
|
||||
input_removed: null
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
@@ -1,380 +0,0 @@
|
||||
/*
|
||||
* Global javascript utilities
|
||||
*/
|
||||
|
||||
/* global $ */
|
||||
|
||||
var static_url = "";
|
||||
|
||||
/*
|
||||
* A simple function to initialize the value of the global variable
|
||||
* 'media_url' (corresponding to django's MEDIA_URL variable).
|
||||
*/
|
||||
function set_static_url(url) {
|
||||
static_url = url;
|
||||
}
|
||||
|
||||
/*
|
||||
* Shortcut function that construct an url from the media_url and the
|
||||
* given value.
|
||||
*/
|
||||
function get_static_url(value) {
|
||||
return static_url + value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Open a modal box and load its content using an AJAX request.
|
||||
*
|
||||
* @param {Object} e - event object
|
||||
*/
|
||||
function modalbox(e, css, defhref, defcb, defclosecb) {
|
||||
e.preventDefault();
|
||||
var $this = $(this);
|
||||
var href = (defhref !== undefined) ? defhref : $this.attr('href');
|
||||
var modalcb = (defcb !== undefined) ? defcb : $this.attr('modalcb');
|
||||
var closecb = (defclosecb !== undefined) ? defclosecb : $this.attr("closecb");
|
||||
|
||||
if (href.indexOf('#') === 0) {
|
||||
$(href).modal('open');
|
||||
return;
|
||||
}
|
||||
if ($("#modalbox").length) {
|
||||
return;
|
||||
}
|
||||
$.ajax({
|
||||
type: "GET",
|
||||
url: href
|
||||
}).done(function(data) {
|
||||
var $div = $('<div />', {
|
||||
id: "modalbox", 'class': "modal fade", role: "modal",
|
||||
html: data, 'aria-hidden': true
|
||||
});
|
||||
|
||||
$div.modal({show: false});
|
||||
$div.one('shown.bs.modal', function() {
|
||||
if ($(".selectpicker").length) {
|
||||
$(".selectpicker").selectize();
|
||||
}
|
||||
$(".help").popover({
|
||||
container: "#modalbox",
|
||||
trigger: "hover"
|
||||
}).click(function(e) {e.preventDefault();});
|
||||
if (modalcb !== undefined) {
|
||||
if (typeof modalcb === "function") modalcb(); else eval(modalcb + '()');
|
||||
}
|
||||
}).on('hidden.bs.modal', function(e) {
|
||||
var $target = $(e.target);
|
||||
|
||||
if (!$target.is($(this))) {
|
||||
return;
|
||||
}
|
||||
$("#modalbox").remove();
|
||||
if (closecb !== undefined) {
|
||||
if (typeof closecb === "function") closecb(); else eval(closecb + '()');
|
||||
}
|
||||
});
|
||||
$div.modal('show');
|
||||
|
||||
if (css !== undefined) {
|
||||
$div.css(css);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function modalbox_autowidth(e) {
|
||||
modalbox.apply(this, [e]);
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple shorcut do create a bootstrap alert box (error mode)
|
||||
*/
|
||||
function build_alert_box(msg, level) {
|
||||
return $('<div class="alert alert-' + level + '"> \
|
||||
<a class="close" data-dismiss="alert" href="#">×</a>' + msg + "</div>");
|
||||
}
|
||||
|
||||
function build_error_alert(msg) {
|
||||
return build_alert_box(msg, 'danger');
|
||||
}
|
||||
|
||||
function build_success_alert(msg) {
|
||||
return build_alert_box(msg, 'success');
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* '.keys()' method support for old browsers :p
|
||||
*/
|
||||
if (!Object.keys) {
|
||||
Object.keys = function (obj) {
|
||||
var keys = [],
|
||||
k;
|
||||
for (k in obj) {
|
||||
if (Object.prototype.hasOwnProperty.call(obj, k)) {
|
||||
keys.push(k);
|
||||
}
|
||||
}
|
||||
return keys;
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
* Clean all errors in a given form.
|
||||
*/
|
||||
function clean_form_errors(formid) {
|
||||
$("#" + formid + " div.has-error").removeClass("has-error");
|
||||
$("#" + formid + " span.help-block").remove();
|
||||
}
|
||||
|
||||
function display_field_error($field, error) {
|
||||
var spanid = $field.attr('id') + "-error";
|
||||
var $span = $("#" + spanid);
|
||||
|
||||
if (!$field.parents(".form-group").hasClass("has-error")) {
|
||||
$field.parents(".form-group").addClass("has-error");
|
||||
}
|
||||
if (!$span.length) {
|
||||
$span = $("<span />", {
|
||||
class: "help-block",
|
||||
html: error,
|
||||
id: spanid
|
||||
});
|
||||
$field.parents(".form-group").append($span);
|
||||
} else {
|
||||
$span.html(error);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Display validation errors for a given form.
|
||||
*/
|
||||
function display_form_errors(formid, data) {
|
||||
clean_form_errors(formid);
|
||||
$.each(data.form_errors, function(id, value) {
|
||||
var fullid = "id_" + (data.prefix ? data.prefix + "-" : "") + id;
|
||||
var $widget = $("#" + formid + " #" + fullid);
|
||||
var error = value.join(' ');
|
||||
|
||||
display_field_error($widget, error);
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple function that sends a form using an 'ajax' post request.
|
||||
*
|
||||
* The function is intended to be used in a modal environment.
|
||||
*/
|
||||
function simple_ajax_form_post(e, options) {
|
||||
e.preventDefault();
|
||||
var $form = (options.formid !== undefined) ? $("#" + options.formid) : $("form");
|
||||
var defaults = {reload_on_success: true, reload_mode: 'full', modal: true};
|
||||
var opts = $.extend({}, defaults, options);
|
||||
var args = $form.serialize();
|
||||
|
||||
if (options.extradata !== undefined) {
|
||||
args += "&" + options.extradata;
|
||||
}
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
global: false,
|
||||
url: $form.attr("action"),
|
||||
data: args
|
||||
}).done(function(data) {
|
||||
if (opts.modal) {
|
||||
$("#modalbox").modal('hide');
|
||||
}
|
||||
if (opts.success_cb !== undefined) {
|
||||
opts.success_cb(data);
|
||||
return;
|
||||
}
|
||||
if (opts.reload_on_success) {
|
||||
if (opts.reload_mode === 'full') {
|
||||
window.location.reload();
|
||||
} else {
|
||||
histomanager.update(true);
|
||||
}
|
||||
}
|
||||
if (data && data.message) {
|
||||
$("body").notify('success', data.message, 2000);
|
||||
}
|
||||
}).fail(function(jqxhr) {
|
||||
var data = $.parseJSON(jqxhr.responseText);
|
||||
if (data.form_errors) {
|
||||
display_form_errors(options.formid, data);
|
||||
} else {
|
||||
if (opts.modal) {
|
||||
$('.modal-body').prepend(build_error_alert(data));
|
||||
} else {
|
||||
$('body').notify('error', data);
|
||||
}
|
||||
}
|
||||
if (opts.error_cb) {
|
||||
opts.error_cb(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* The following code prevents a bug under IE7 because fullpath is
|
||||
* returned instead of a relative one. (even if mootools uses
|
||||
* getAttribute("href", 2), this is not working for AJAX requests)
|
||||
*/
|
||||
function gethref(obj) {
|
||||
var url = $(obj).attr("href");
|
||||
var re = new RegExp("^(https?):");
|
||||
var scheme = re.exec(url);
|
||||
|
||||
if (scheme !== null) {
|
||||
var baseurl = scheme[0] + "://" + location.host + location.pathname;
|
||||
return url.replace(baseurl, "");
|
||||
}
|
||||
return url;
|
||||
}
|
||||
|
||||
/*
|
||||
* Extract the current URL parameters into a dictionnary.
|
||||
*
|
||||
* Ref:
|
||||
* http://stackoverflow.com/questions/901115/get-query-string-values-in-javascript
|
||||
*/
|
||||
function parse_qs(raw) {
|
||||
if (raw === "") { return {}; }
|
||||
var res = {};
|
||||
|
||||
for (var i = 0; i < raw.length; i++) {
|
||||
var p = raw[i].split('=');
|
||||
|
||||
if (p.length !== 2) { continue; }
|
||||
res[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/*
|
||||
* Extract a specific URL parameter using its name.
|
||||
*
|
||||
* Ref: http://stackoverflow.com/questions/901115/get-query-string-values-in-javascript
|
||||
*/
|
||||
function get_parameter_by_name(url, name, dont_replace_plus) {
|
||||
name = name.replace(/[\[]/, "\\\[").replace(/[\]]/, "\\\]");
|
||||
var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
|
||||
results = regex.exec(url);
|
||||
|
||||
if (results === null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
var result = results[1];
|
||||
if (dont_replace_plus === undefined || !dont_replace_plus) {
|
||||
result = result.replace("/\+/g", "");
|
||||
}
|
||||
return decodeURIComponent(result);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the target associated to an event object. You will generally
|
||||
* use this function within a click event handler configured on a <a/>
|
||||
* tag containg an image. (because e.target will often point to the
|
||||
* image...)
|
||||
*
|
||||
* @param {Object} e - event object
|
||||
* @param {string} tag - desired tag
|
||||
*/
|
||||
function get_target(e, tag) {
|
||||
var $target = $(e.target);
|
||||
|
||||
if (tag === undefined || $target.is(tag)) {
|
||||
return $target;
|
||||
}
|
||||
return $target.parent();
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a simple AJAX request.
|
||||
*/
|
||||
function simple_ajax_request(e, uoptions) {
|
||||
var $this = $(this);
|
||||
var defaults = {};
|
||||
var options = $.extend({}, defaults, uoptions);
|
||||
|
||||
if (e !== undefined) { e.preventDefault(); }
|
||||
$.ajax({
|
||||
url: $this.attr("href"),
|
||||
dataType: 'json'
|
||||
}).done(function(data) {
|
||||
if (options.ok_cb) { options.ok_cb(data); }
|
||||
if (data) {
|
||||
$("body").notify("success", data, 2000);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/*
|
||||
* Simple function that redirect ajax requests to the login page if
|
||||
* the status code received with a response is equal to 278.
|
||||
*/
|
||||
function ajax_login_redirect(xhr) {
|
||||
if (xhr.status !== 278) {
|
||||
return;
|
||||
}
|
||||
var params = "?next=" + window.location.pathname;
|
||||
|
||||
window.location.href =
|
||||
xhr.getResponseHeader("Location").replace(/\?.*$/, params);
|
||||
}
|
||||
|
||||
function activate_widget(e) {
|
||||
var $this = $(this);
|
||||
var widget_id = $this.attr("id").substr(0, $this.attr("id").length - 4);
|
||||
var $widget = $('#' + widget_id);
|
||||
|
||||
if ($this.prop("checked")) {
|
||||
$widget.attr('disabled', true);
|
||||
} else {
|
||||
$widget.attr('disabled', false);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Default error handler for AJAX requests.
|
||||
*/
|
||||
function defaultAjaxErrorHandler(event, jqxhr, settings) {
|
||||
var data;
|
||||
|
||||
try {
|
||||
data = $.parseJSON(jqxhr.responseText);
|
||||
} catch (x) {
|
||||
data = gettext("Internal error");
|
||||
}
|
||||
$('body').notify('error', htmlEncode(data));
|
||||
}
|
||||
|
||||
/**
|
||||
* An equivalent of python .format() method.
|
||||
*/
|
||||
String.prototype.format = function() {
|
||||
var args = arguments;
|
||||
return this.replace(/\{\{|\}\}|\{(\d+)\}/g, function (m, n) {
|
||||
if (m === "{{") { return "{"; }
|
||||
if (m === "}}") { return "}"; }
|
||||
return args[n];
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Simple HTML escape function
|
||||
*/
|
||||
function htmlEncode(str) {
|
||||
return String(str).replace(/[^\w. ]/gi, function(c) {
|
||||
return '&#'+c.charCodeAt(0)+';';
|
||||
});
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
$(document).ajaxSuccess(function(e, xhr, settings) { ajax_login_redirect(xhr); });
|
||||
$(document).ajaxError(defaultAjaxErrorHandler);
|
||||
$(document).on('click', 'a[data-toggle="ajaxmodal"]', modalbox);
|
||||
$(document).on('click', 'a[data-toggle="ajaxmodal-autowidth"]', modalbox_autowidth);
|
||||
$(document).on('click', '.activator', activate_widget);
|
||||
$(".help").popover({trigger: 'hover'}).click(function(e) { e.preventDefault(); });
|
||||
});
|
||||
@@ -1,285 +0,0 @@
|
||||
/**
|
||||
* Creates an instance of History.
|
||||
*
|
||||
* @constructor
|
||||
* @this {History}
|
||||
* @param {dictionary} options - instance options
|
||||
*/
|
||||
var History = function(options) {
|
||||
this.options = $.extend({}, this.defaults, options);
|
||||
this.callbacks = {};
|
||||
this.base = '';
|
||||
this.serialized = null;
|
||||
this.updatenext = true;
|
||||
this.load_params();
|
||||
if (this.options.defcallback) {
|
||||
this.register_callback("default", this.options.defcallback);
|
||||
this.check_id =
|
||||
setInterval($.proxy(this.check, this), this.options.checkinterval);
|
||||
}
|
||||
};
|
||||
|
||||
History.prototype = {
|
||||
constructor: History,
|
||||
|
||||
defaults: {
|
||||
checkinterval: 300,
|
||||
deflocation: null,
|
||||
defcallback: null
|
||||
},
|
||||
|
||||
/**
|
||||
* Return the encoded hash part of the URL (some browsers like FF
|
||||
* automatically decode the location.hash variable).
|
||||
*/
|
||||
get_raw_hash: function() {
|
||||
var parts = window.location.href.split('#');
|
||||
if (parts.length > 1) {
|
||||
return parts[1];
|
||||
}
|
||||
return "";
|
||||
},
|
||||
|
||||
load_params: function() {
|
||||
var rawqs = this.get_raw_hash();
|
||||
|
||||
if (!rawqs || rawqs.indexOf('?') == -1) {
|
||||
this.params = {};
|
||||
return;
|
||||
}
|
||||
var tmp = rawqs.split('?');
|
||||
|
||||
rawqs = (tmp.length == 1) ? tmp[0] : tmp[1];
|
||||
this.params = parse_qs(rawqs.split('&'));
|
||||
},
|
||||
|
||||
paramslength: function() {
|
||||
return Object.keys(this.params).length;
|
||||
},
|
||||
|
||||
reset: function() {
|
||||
this.base = "";
|
||||
this.params = {};
|
||||
return this;
|
||||
},
|
||||
|
||||
parse_string: function(value, reset) {
|
||||
var splits = (value.charAt(0) == '#') ?
|
||||
value.substring(1).split('?') : value.split('?');
|
||||
|
||||
if (splits.length === 0) {
|
||||
this.base = this.options.deflocation;
|
||||
return this;
|
||||
}
|
||||
if (reset === undefined) {
|
||||
reset = false;
|
||||
}
|
||||
if (reset) {
|
||||
this.reset();
|
||||
}
|
||||
|
||||
if ((this.base = splits[0]) !== "") {
|
||||
var re = new RegExp("/$");
|
||||
if (!this.base.match(re)) {
|
||||
this.base += '/';
|
||||
}
|
||||
}
|
||||
if (splits.length > 1) {
|
||||
var params = splits[1].split('&');
|
||||
for (var i = 0; i < params.length; i++) {
|
||||
var tmp = params[i].split('=');
|
||||
this.setparam(tmp[0], tmp[1], false);
|
||||
}
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
from_string: function(value, reset) {
|
||||
this.parse_string(value);
|
||||
this.serialized = value;
|
||||
return this;
|
||||
},
|
||||
|
||||
serialize: function() {
|
||||
var res = this.base;
|
||||
var args = "";
|
||||
|
||||
if (this.paramslength() !== 0) {
|
||||
args += "?";
|
||||
$.each(this.params, function(key, value) {
|
||||
if (args != "?") {
|
||||
args += "&";
|
||||
}
|
||||
args += key + "=" + value;
|
||||
});
|
||||
}
|
||||
return res + args;
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the current location.
|
||||
*
|
||||
* @param {boolean} force - force the update
|
||||
* @param {boolean} noupdate - disable the next update
|
||||
*/
|
||||
update: function(force, noupdate) {
|
||||
location.hash = this.serialize();
|
||||
|
||||
if (noupdate === undefined) {
|
||||
noupdate = false;
|
||||
}
|
||||
if (!noupdate) {
|
||||
if (force) {
|
||||
this.force = force;
|
||||
}
|
||||
} else {
|
||||
this.updatenext = false;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if a parameter is present.
|
||||
*
|
||||
* @param {string} name - name of the parameter
|
||||
* @return {boolean} true if parameter is present, false otherwise
|
||||
*/
|
||||
hasparam: function(name) {
|
||||
return this.params[name] !== undefined;
|
||||
},
|
||||
|
||||
/**
|
||||
* Retrieve a parameter.
|
||||
*
|
||||
* @param {string} name - name of the parameter
|
||||
* @return {string} the parameter's value (URI decoded)
|
||||
*/
|
||||
getparam: function(name, defvalue) {
|
||||
if (this.params[name] === undefined) {
|
||||
return (defvalue !== undefined) ? defvalue : undefined;
|
||||
}
|
||||
return decodeURIComponent(this.params[name]);
|
||||
},
|
||||
|
||||
/**
|
||||
* Set a parameter.
|
||||
*
|
||||
* @param {string} name - name of the parameter
|
||||
* @param {string} value - parameter's value
|
||||
* @param {boolean} encode - URI encode the parameter if true
|
||||
* @return {History}
|
||||
*/
|
||||
setparam: function(name, value, encode) {
|
||||
if (encode === undefined || encode) {
|
||||
this.params[name] = encodeURIComponent(value);
|
||||
} else {
|
||||
this.params[name] = value;
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Set several parameters.
|
||||
*
|
||||
* @param {Object} params - a dictionary of parameters
|
||||
* @return {Object} - History instance
|
||||
*/
|
||||
setparams: function(params) {
|
||||
$.each(params, $.proxy(this.setparam, this));
|
||||
return this;
|
||||
},
|
||||
|
||||
updateparams: function(str) {
|
||||
if (str.charAt(0) == '?') {
|
||||
str = str.substring(1);
|
||||
}
|
||||
var elems = str.split('&');
|
||||
for (var i = 0; i < elems.length; i++) {
|
||||
var pdef = elems[i].split('=');
|
||||
this.setparam(pdef[0], pdef[1]);
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
/**
|
||||
* Delete a parameter.
|
||||
*
|
||||
* @param {string} name - name of the parameter
|
||||
* @return {History}
|
||||
*/
|
||||
delparam: function(name) {
|
||||
if (this.params[name] === undefined) {
|
||||
return this;
|
||||
}
|
||||
delete(this.params[name]);
|
||||
return this;
|
||||
},
|
||||
|
||||
baseurl: function(value, noreset) {
|
||||
if (noreset === undefined || noreset === 0) {
|
||||
this.reset();
|
||||
}
|
||||
this.base = value;
|
||||
var re = new RegExp("/$");
|
||||
if (!this.base.match(re)) {
|
||||
this.base += '/';
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
addbaseurl: function(value) {
|
||||
var newbase = this.base + value;
|
||||
return this.baseurl(newbase);
|
||||
},
|
||||
|
||||
getbaseurl: function() {
|
||||
return decodeURIComponent(this.base.substr(0, this.base.length - 1));
|
||||
},
|
||||
|
||||
register_callback: function(name, callback) {
|
||||
this.callbacks[name] = callback;
|
||||
},
|
||||
|
||||
get_callback: function(name) {
|
||||
return this.callbacks[name];
|
||||
},
|
||||
|
||||
set_default_callback: function(callback) {
|
||||
this.register_callback("default", callback);
|
||||
if (this.ca_id === undefined) {
|
||||
this.ca_id =
|
||||
setInterval($.proxy(this.check, this), this.options.checkinterval);
|
||||
}
|
||||
},
|
||||
|
||||
check: function() {
|
||||
var rawhash = this.get_raw_hash();
|
||||
|
||||
if (this.serialized === rawhash && this.force === undefined) {
|
||||
return;
|
||||
}
|
||||
delete this.force;
|
||||
this.from_string(rawhash);
|
||||
|
||||
if (!this.serialized) {
|
||||
window.location.hash = this.options.deflocation;
|
||||
return;
|
||||
}
|
||||
if (!this.updatenext) {
|
||||
this.updatenext = true;
|
||||
return;
|
||||
}
|
||||
|
||||
$.ajax({
|
||||
url: this.serialized,
|
||||
cache: false,
|
||||
dataType: 'json'
|
||||
}).done($.proxy(function(resp) {
|
||||
var callback = (resp.callback !== undefined) ? resp.callback : "default";
|
||||
|
||||
this.callbacks[callback](resp);
|
||||
if (resp.respmsg) {
|
||||
$("body").notify("success", resp.respmsg, 2000);
|
||||
}
|
||||
}, this));
|
||||
}
|
||||
};
|
||||
@@ -1,217 +0,0 @@
|
||||
(function($) {
|
||||
var HtmlTable = function(element, options) {
|
||||
this.initialize(element, options);
|
||||
};
|
||||
|
||||
HtmlTable.prototype = {
|
||||
constructor: HtmlTable,
|
||||
|
||||
initialize: function(element, options) {
|
||||
this.$element = $(element);
|
||||
this.options = $.extend({}, $.fn.htmltable.defaults, options);
|
||||
this.shift_pressed = false;
|
||||
this.ctrl_pressed = false;
|
||||
this.last_selection = null;
|
||||
this.listen();
|
||||
|
||||
this.$element.css({
|
||||
"-moz-user-select": "-moz-none",
|
||||
"-khtml-user-select": "none",
|
||||
"-webkit-user-select": "none",
|
||||
"-ms-user-select": "none",
|
||||
"user-select": "none"
|
||||
});
|
||||
this.$element.attr("unselectable", "on");
|
||||
},
|
||||
|
||||
listen: function() {
|
||||
this.$element
|
||||
.off("change", "input[type=checkbox]")
|
||||
.on("change", "input[type=checkbox]",
|
||||
$.proxy(this.toggle_select, this));
|
||||
$(document).on("keydown", "body", $.proxy(this.keydown, this));
|
||||
$(document).on("keyup", "body", $.proxy(this.keyup, this));
|
||||
},
|
||||
|
||||
/**
|
||||
* Effective change of a row's state.
|
||||
*/
|
||||
_toggle_select: function($row) {
|
||||
var $input = $row.find(this.options.input_selector);
|
||||
|
||||
if ($row.hasClass(this.options.row_selected_class)) {
|
||||
$input.prop('checked', false);
|
||||
$row.removeClass(this.options.row_selected_class);
|
||||
if (this.options.row_unselected_event !== undefined) {
|
||||
this.options.row_unselected_event($row);
|
||||
}
|
||||
} else {
|
||||
$input.prop('checked', true);
|
||||
$row.addClass(this.options.row_selected_class);
|
||||
if (this.options.row_selected_event !== undefined) {
|
||||
this.options.row_selected_event($row);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Set the row's state, cancel the change if the current state
|
||||
* and the new state are identical
|
||||
*/
|
||||
_set_select: function($row, selected) {
|
||||
var $input = $row.find(this.options.input_selector);
|
||||
|
||||
if (this.is_selected($row) == selected)
|
||||
return;
|
||||
$input.prop('checked', selected);
|
||||
if (selected) {
|
||||
$row.addClass(this.options.row_selected_class);
|
||||
if (this.options.row_unselected_event !== undefined) {
|
||||
this.options.row_unselected_event($row);
|
||||
}
|
||||
} else {
|
||||
$row.removeClass(this.options.row_selected_class);
|
||||
if (this.options.row_selected_event !== undefined) {
|
||||
this.options.row_selected_event($row);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Change the selection state of a given row.
|
||||
*
|
||||
* Holding the shift key between two selections let users
|
||||
* select all rows between those two locations.
|
||||
*
|
||||
* Holding the ctrl key between two selections let users make
|
||||
* an additive selection.
|
||||
*/
|
||||
toggle_select: function(e) {
|
||||
var $row = $(e.target).parents(this.options.row_selector);
|
||||
|
||||
if (this.shift_pressed && this.last_selection) {
|
||||
var select = !this.is_selected($row);
|
||||
var itfunc = ($row.index() >= this.last_selection.index()) ?
|
||||
"next" : "prev";
|
||||
var $cur_row;
|
||||
|
||||
for ($cur_row = this.last_selection;
|
||||
$cur_row.length;
|
||||
$cur_row = $cur_row[itfunc](this.options.row_selector)) {
|
||||
this._set_select($cur_row, select);
|
||||
if ($row.attr("id") == $cur_row.attr("id")) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.last_selection = $row;
|
||||
return;
|
||||
} else if (!this.options.keep_selection && !this.ctrl_pressed &&
|
||||
(!this.last_selection || !this.last_selection.is($row))) {
|
||||
this.clear_selection();
|
||||
}
|
||||
this.last_selection = $row;
|
||||
this._toggle_select($row);
|
||||
},
|
||||
|
||||
/**
|
||||
* Change the selection state of all rows.
|
||||
*/
|
||||
toggleSelectAll: function(value) {
|
||||
if (!value) {
|
||||
this.clear_selection();
|
||||
} else {
|
||||
$(this.options.row_selector).each((index, row) => {
|
||||
this._set_select($(row), true);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if $row is selected or not.
|
||||
*/
|
||||
is_selected: function($row) {
|
||||
return $row.hasClass(this.options.row_selected_class);
|
||||
},
|
||||
|
||||
/**
|
||||
* Return the current selection. (jQuery object)
|
||||
*/
|
||||
current_selection: function() {
|
||||
return this.$element.find("." + this.options.row_selected_class);
|
||||
},
|
||||
|
||||
/**
|
||||
* Cancel the current selection.
|
||||
*/
|
||||
clear_selection: function() {
|
||||
this.last_selection = null;
|
||||
this.current_selection().removeClass(this.options.row_selected_class);
|
||||
this.$element.find(this.options.input_selector).prop('checked', false);
|
||||
if (this.options.row_unselected_event !== undefined) {
|
||||
this.options.row_unselected_event();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Manually select a row.
|
||||
*/
|
||||
select_row: function($row) {
|
||||
if (!this.last_selection) {
|
||||
this.last_selection = $row;
|
||||
}
|
||||
$row.addClass(this.options.row_selected_class);
|
||||
if (this.options.row_selected_event !== undefined) {
|
||||
this.options.row_selected_event($row);
|
||||
}
|
||||
},
|
||||
|
||||
keydown: function(e) {
|
||||
switch (e.which) {
|
||||
case 16:
|
||||
e.preventDefault();
|
||||
this.shift_pressed = true;
|
||||
break;
|
||||
case 17:
|
||||
this.ctrl_pressed = true;
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
keyup: function(e) {
|
||||
switch (e.which) {
|
||||
case 16:
|
||||
e.preventDefault();
|
||||
this.shift_pressed = false;
|
||||
break;
|
||||
case 17:
|
||||
this.ctrl_pressed = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$.fn.htmltable = function(method) {
|
||||
var args = arguments;
|
||||
|
||||
return this.each(function() {
|
||||
var $this = $(this),
|
||||
data = $this.data('htmltable'),
|
||||
options = typeof method === "object" && method;
|
||||
|
||||
if (!data) {
|
||||
$this.data('htmltable', new HtmlTable(this, options));
|
||||
data = $this.data('htmltable');
|
||||
}
|
||||
if (typeof method === "string") {
|
||||
data[method].apply(data, Array.prototype.slice.call(args, 1));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$.fn.htmltable.defaults = {
|
||||
row_selector: 'tr',
|
||||
input_selector: "input[type=checkbox]",
|
||||
row_selected_class: 'tr-selected',
|
||||
keep_selection: false
|
||||
};
|
||||
})(jQuery);
|
||||
@@ -1,199 +0,0 @@
|
||||
/**
|
||||
* Infinite scroll plugin for jQuery.
|
||||
*
|
||||
* @author {Antoine Nguyen}
|
||||
*/
|
||||
!function($) {
|
||||
'use strict';
|
||||
|
||||
/**
|
||||
* Creates an instance of InfiniteScroll.
|
||||
*
|
||||
* @constructor
|
||||
* @this InfiniteScroll
|
||||
* @param {object} element
|
||||
* @param {dictionary} options - instance options
|
||||
*/
|
||||
var InfiniteScroll = function(element, options) {
|
||||
this.$element = $(element);
|
||||
this.$data = $(element).data();
|
||||
this.$options = options;
|
||||
this.executing = false;
|
||||
this.end_of_results = false;
|
||||
if (this.$options.initial_pages !== undefined &&
|
||||
this.$options.initial_pages.length > 0) {
|
||||
this.current_page = this.$options.initial_pages[0];
|
||||
this.loaded_pages = this.$options.initial_pages;
|
||||
} else {
|
||||
this.current_page = 1;
|
||||
this.loaded_pages = [this.current_page];
|
||||
}
|
||||
this.resume();
|
||||
};
|
||||
|
||||
InfiniteScroll.prototype = {
|
||||
constructor: InfiniteScroll,
|
||||
|
||||
/**
|
||||
* Scroll event handler.
|
||||
*
|
||||
* @this InfiniteScroll
|
||||
*/
|
||||
on_scroll: function() {
|
||||
var bottom = this.$options.calculate_bottom(this.$element);
|
||||
|
||||
if (bottom === undefined || bottom < 0) {
|
||||
return;
|
||||
}
|
||||
if (this.$element.scrollTop() >= bottom) {
|
||||
this.load_next_page();
|
||||
} else if (this.$element.scrollTop() === 0) {
|
||||
this.load_previous_page();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Load the previous page from the server.
|
||||
*
|
||||
* @private
|
||||
* @this InfiniteScroll
|
||||
*/
|
||||
load_previous_page: function() {
|
||||
var $this = this;
|
||||
|
||||
if ($this.executing || $.inArray(1, $this.loaded_pages) != -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
while ($this.current_page > 0) {
|
||||
$this.current_page -= 1;
|
||||
if ($.inArray($this.current_page, $this.loaded_pages) == -1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($this.current_page === 0) {
|
||||
$this.current_page = 1;
|
||||
return;
|
||||
}
|
||||
this.load_page("up");
|
||||
},
|
||||
|
||||
/**
|
||||
* Load the next page from the server.
|
||||
*
|
||||
* @this InfiniteScroll
|
||||
*/
|
||||
load_next_page: function() {
|
||||
var $this = this;
|
||||
|
||||
if ($this.executing || $this.end_of_results) {
|
||||
return;
|
||||
}
|
||||
while (true) {
|
||||
$this.current_page += 1;
|
||||
if ($.inArray($this.current_page, $this.loaded_pages) == -1) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
this.load_page("down");
|
||||
},
|
||||
|
||||
/**
|
||||
* Load a page's content.
|
||||
*
|
||||
* @private
|
||||
* @this InfiniteScroll
|
||||
* @param {string} direction - direction of the scroll (up or down)
|
||||
*/
|
||||
load_page: function(direction) {
|
||||
var args = (this.$options.get_args) ? this.$options.get_args() : {};
|
||||
var $this = this;
|
||||
|
||||
this.executing = true;
|
||||
args.page = this.current_page;
|
||||
$.ajax({
|
||||
contentType: 'application/json; charset=UTF-8',
|
||||
data: args,
|
||||
url: $this.$options.url,
|
||||
type: 'GET',
|
||||
success: function(data) {
|
||||
$this.$options.process_results(data, direction);
|
||||
if (data.length === 0) {
|
||||
$this.end_of_results = true;
|
||||
$this.$options.end_of_list_reached($this.$element);
|
||||
}
|
||||
$this.executing = false;
|
||||
$this.loaded_pages.push($this.current_page);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Reset the loaded pages cache.
|
||||
*
|
||||
* @this InfiniteScroll
|
||||
* @param {Array} new_pages - the new loaded pages
|
||||
*/
|
||||
reset_loaded_pages: function(new_pages) {
|
||||
if (new_pages !== undefined) {
|
||||
this.current_page = new_pages[0];
|
||||
this.loaded_pages = new_pages;
|
||||
} else {
|
||||
this.current_page = this.$options.initial_page;
|
||||
this.loaded_pages = [this.$options.initial_pages];
|
||||
}
|
||||
this.end_of_results = false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Suspend the "infinite scroll" mode.
|
||||
*
|
||||
* @this InfiniteScroll
|
||||
*/
|
||||
pause: function() {
|
||||
this.$element.unbind("scroll");
|
||||
},
|
||||
|
||||
/**
|
||||
* Resume the "infinite scroll" mode.
|
||||
*
|
||||
* @this InfiniteScroll
|
||||
*/
|
||||
resume: function() {
|
||||
this.$element.scroll($.proxy(this.on_scroll, this));
|
||||
}
|
||||
};
|
||||
|
||||
$.fn.infinite_scroll = function (option) {
|
||||
var args = arguments;
|
||||
|
||||
return this.each(function () {
|
||||
var $this = $(this),
|
||||
data = $this.data('infinite-scroll'),
|
||||
options = $.extend(
|
||||
{}, $.fn.infinite_scroll.defaults,
|
||||
typeof option == 'object' && option
|
||||
);
|
||||
|
||||
if (!data) {
|
||||
$this.data('infinite-scroll', (
|
||||
data = new InfiniteScroll(this, options))
|
||||
);
|
||||
}
|
||||
if (typeof option == 'string') {
|
||||
data[option].apply(data, Array.prototype.slice.call(args, 1));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$.fn.infinite_scroll.defaults = {
|
||||
initial_page: 1,
|
||||
calculate_bottom: null,
|
||||
get_data: null,
|
||||
process_results: null,
|
||||
end_of_list_reached: null,
|
||||
url: ''
|
||||
};
|
||||
|
||||
$.fn.infinite_scroll.Constructor = InfiniteScroll;
|
||||
}(window.jQuery);
|
||||
@@ -1,95 +0,0 @@
|
||||
(function($) {
|
||||
/**
|
||||
* Return an instance of Sortable.
|
||||
*
|
||||
* @constructor
|
||||
* @param {Object} element -
|
||||
* @param {Object} options - instance options
|
||||
*/
|
||||
var Sortable = function(element, options) {
|
||||
this.initialize(element, options);
|
||||
};
|
||||
|
||||
Sortable.prototype = {
|
||||
constructor: Sortable,
|
||||
|
||||
initialize: function(element, options) {
|
||||
this.$element = $(element);
|
||||
this.options = $.extend({}, $.fn.sortable.defaults, options);
|
||||
this.$element.addClass('sort-header');
|
||||
this.listen();
|
||||
},
|
||||
|
||||
listen: function() {
|
||||
this.$element.click($.proxy(this.sort, this));
|
||||
},
|
||||
|
||||
change_sort_order: function(e, new_sort_order) {
|
||||
if (new_sort_order != this.$element.attr('data-sort_order')) {
|
||||
this.$element.removeClass('sort-header-desc sort-header-asc');
|
||||
}
|
||||
},
|
||||
|
||||
sort: function(e) {
|
||||
e.preventDefault();
|
||||
var dir = this.select();
|
||||
|
||||
if (this.options.onSortOrderChange) {
|
||||
this.options.onSortOrderChange(this.$element.attr('data-sort_order'), dir);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Mark a column as the one used to sort content.
|
||||
*
|
||||
* @this Sortable
|
||||
* @param {string} dir - optional sort direction (up or down)
|
||||
* @return {string} - new sort direction
|
||||
*/
|
||||
select: function(dir) {
|
||||
$("span.sort-selection").remove();
|
||||
if (dir !== undefined) {
|
||||
this.$element.removeClass("sort-header-" + ((dir == "asc") ? "desc" : "asc"));
|
||||
this.$element.addClass("sort-header-" + dir);
|
||||
} else {
|
||||
if (this.$element.hasClass("sort-header-desc")) {
|
||||
this.$element
|
||||
.removeClass("sort-header-desc")
|
||||
.addClass("sort-header-asc");
|
||||
dir = "asc";
|
||||
} else {
|
||||
this.$element
|
||||
.removeClass("sort-header-asc")
|
||||
.addClass("sort-header-desc");
|
||||
dir = "desc";
|
||||
}
|
||||
}
|
||||
this.$element.append($("<span/>", {
|
||||
"class": "sort-selection fa fa-chevron-" + ((dir == 'asc') ? 'up' : 'down')
|
||||
}));
|
||||
return dir;
|
||||
}
|
||||
};
|
||||
|
||||
$.fn.sortable = function(method) {
|
||||
var args = arguments;
|
||||
|
||||
return this.each(function() {
|
||||
var $this = $(this),
|
||||
data = $this.data('sortable'),
|
||||
options = typeof method === "object" && method;
|
||||
|
||||
if (!data) {
|
||||
$this.data('sortable', new Sortable(this, options));
|
||||
data = $this.data('sortable');
|
||||
}
|
||||
if (typeof method === "string") {
|
||||
data[method].apply(data, Array.prototype.slice.call(args, 1));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$.fn.sortable.defaults = {
|
||||
onSortOrderChange: null
|
||||
};
|
||||
})(jQuery);
|
||||
@@ -1,299 +0,0 @@
|
||||
/**
|
||||
* Return an instance of Listing.
|
||||
*
|
||||
* @constructor
|
||||
* @param {Object} options - instance options
|
||||
*/
|
||||
var Listing = function(options) {
|
||||
this.initialize(options);
|
||||
};
|
||||
|
||||
Listing.prototype = {
|
||||
constructor: Listing,
|
||||
|
||||
listing_defaults: {
|
||||
sortable_selector: '.sortable',
|
||||
with_searchform: true,
|
||||
load_page_url: null,
|
||||
navigation_params: ["sort_order", "searchquery"],
|
||||
scroll_container: null,
|
||||
main_table_id: "objects_table",
|
||||
eor_message: gettext("No more entry to show")
|
||||
},
|
||||
|
||||
initialize: function(options) {
|
||||
this.options = $.extend({}, this.listing_defaults, options);
|
||||
this.tag_handlers = {};
|
||||
this.navobj = new History(this.options);
|
||||
$(document).on("click", "a.filter", $.proxy(this.filter_by_tag, this));
|
||||
if (this.options.with_searchform) {
|
||||
this.init_searchform();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Initialize the search form.
|
||||
*/
|
||||
init_searchform: function() {
|
||||
$("#searchquery").focus(function() {
|
||||
$(this).val("");
|
||||
}).blur($.proxy(function(e) {
|
||||
var $this = $(e.target);
|
||||
if ($this.val() === "") {
|
||||
if (this.navobj.getparam("searchquery")) {
|
||||
$this.val(this.navobj.getparam("searchquery"));
|
||||
} else {
|
||||
$this.val(gettext("Search"));
|
||||
}
|
||||
}
|
||||
}, this));
|
||||
if (this.navobj.getparam("searchquery") !== undefined) {
|
||||
$("#searchquery").val(this.navobj.getparam("searchquery"));
|
||||
}
|
||||
$("#searchform").submit($.proxy(this.do_search, this));
|
||||
},
|
||||
|
||||
/**
|
||||
* Apply the current search pattern.
|
||||
*/
|
||||
do_search: function(e) {
|
||||
e.preventDefault();
|
||||
var squery = $("#searchquery").val();
|
||||
if (squery !== "") {
|
||||
this.navobj.setparam("searchquery", squery);
|
||||
} else {
|
||||
this.navobj.delparam("searchquery");
|
||||
}
|
||||
this.navobj.update();
|
||||
},
|
||||
|
||||
|
||||
load_page: function(e) {
|
||||
var $link = get_target(e, "a");
|
||||
e.preventDefault();
|
||||
this.navobj.updateparams($link.attr("href")).update();
|
||||
},
|
||||
|
||||
/**
|
||||
* Return extra arguments used to fetch a page.
|
||||
*
|
||||
* @this Listing
|
||||
*/
|
||||
get_load_page_args: function() {
|
||||
var $this = this;
|
||||
var args = {};
|
||||
|
||||
$.each(this.options.navigation_params, function(pos, param) {
|
||||
if ($this.navobj.hasparam(param)) {
|
||||
args[param] = $this.navobj.getparam(param);
|
||||
}
|
||||
});
|
||||
return args;
|
||||
},
|
||||
|
||||
/**
|
||||
* Calculate the bottom position of the scroll container.
|
||||
*
|
||||
* @param {Object} $element - scroll container object
|
||||
*/
|
||||
calculate_bottom: function($element) {
|
||||
var $last_row = $("#" + this.options.main_table_id)
|
||||
.find("tr").last();
|
||||
return $last_row.offset().top - $element.height();
|
||||
},
|
||||
|
||||
/**
|
||||
* A new page has been received, inject it.
|
||||
*
|
||||
* @param {Object} data - page content
|
||||
* @param {string} direction - scroll direction (up or down)
|
||||
*/
|
||||
add_new_page: function(data, direction) {
|
||||
var $container = $("#{0} tbody".format(this.options.main_table_id));
|
||||
|
||||
if (direction == "down") {
|
||||
$container.html(function(pos, oldhtml) {
|
||||
return oldhtml + data.rows;
|
||||
});
|
||||
} else {
|
||||
$container.html(function(pos, oldhtml) {
|
||||
return data.rows + oldhtml;
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Callback called when no more page can be loaded.
|
||||
*
|
||||
* @this Listing
|
||||
*/
|
||||
end_of_list_reached: function(element) {
|
||||
$("#" + this.options.main_table_id).after(
|
||||
$("<div id='eor_message' class='alert alert-info text-center'>{0}</div>".format(
|
||||
this.options.eor_message
|
||||
))
|
||||
);
|
||||
},
|
||||
|
||||
/**
|
||||
* Update the listing with the received data.
|
||||
*
|
||||
* @this Listing
|
||||
* @param {Object} data - new content
|
||||
*/
|
||||
update_listing: function(data, with_infinite_scroll) {
|
||||
var $this = this;
|
||||
var $scroll_container = (this.options.scroll_container) ?
|
||||
$(this.options.scroll_container) : $(window);
|
||||
|
||||
$scroll_container.scrollTop(0);
|
||||
if (with_infinite_scroll || with_infinite_scroll === undefined) {
|
||||
if ($scroll_container.data("infinite-scroll") !== undefined) {
|
||||
$scroll_container.infinite_scroll("reset_loaded_pages", data.pages);
|
||||
$scroll_container.infinite_scroll("resume");
|
||||
$("#eor_message").remove();
|
||||
} else {
|
||||
$scroll_container.infinite_scroll({
|
||||
initial_pages: data.pages,
|
||||
url: this.options.load_page_url,
|
||||
get_args: $.proxy(this.get_load_page_args, this),
|
||||
calculate_bottom: $.proxy(this.calculate_bottom, this),
|
||||
process_results: $.proxy(this.add_new_page, this),
|
||||
end_of_list_reached: $.proxy(this.end_of_list_reached, this)
|
||||
});
|
||||
}
|
||||
} else if ($scroll_container.data("infinite-scroll") !== undefined) {
|
||||
$scroll_container.infinite_scroll("pause");
|
||||
}
|
||||
|
||||
var $sortables = $(this.options.sortable_selector);
|
||||
if ($sortables.length) {
|
||||
$(this.options.sortable_selector).sortable({
|
||||
onSortOrderChange: $.proxy(this.change_sort_order, this)
|
||||
});
|
||||
this.set_sort_order();
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Set current sort order.
|
||||
*
|
||||
* @this Listing
|
||||
*/
|
||||
set_sort_order: function() {
|
||||
var sort_order = this.navobj.getparam("sort_order");
|
||||
var sort_dir;
|
||||
|
||||
if (!sort_order) {
|
||||
return;
|
||||
}
|
||||
if (sort_order[0] == '-') {
|
||||
sort_dir = "desc";
|
||||
sort_order = sort_order.substr(1);
|
||||
} else {
|
||||
sort_dir = 'asc';
|
||||
}
|
||||
$("th[data-sort_order=" + sort_order + "]").sortable('select', sort_dir);
|
||||
},
|
||||
|
||||
/**
|
||||
* Change current sort order.
|
||||
*
|
||||
* @this Listing
|
||||
*/
|
||||
change_sort_order: function(sort_order, dir) {
|
||||
if (dir == "desc") {
|
||||
sort_order = "-" + sort_order;
|
||||
}
|
||||
this.navobj.setparam("sort_order", sort_order).update();
|
||||
},
|
||||
|
||||
/**
|
||||
* Register a new tag handler.
|
||||
*
|
||||
* @this Listing
|
||||
* @param {string} name - name of the tag
|
||||
* @param {function} handler - reference to a function (optional)
|
||||
*/
|
||||
register_tag_handler: function(name, handler) {
|
||||
if (handler === undefined) {
|
||||
handler = this.generic_tag_handler;
|
||||
}
|
||||
this.tag_handlers[name] = handler;
|
||||
if (this.navobj.getparam(name + "filter") !== undefined) {
|
||||
var text = this.navobj.getparam(name + "filter");
|
||||
$("#taglist").append(this.make_tag(text, name));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Default tag handler.
|
||||
*
|
||||
* @this Listing
|
||||
* @param {string} tag - name of the tag
|
||||
* @param {Object} $link - tag that was clicked
|
||||
* @return {boolean} - return true if handler has been executed
|
||||
*/
|
||||
generic_tag_handler: function(tag, $link) {
|
||||
if (this.navobj.getparam(tag + "filter") === undefined && $link.hasClass(tag)) {
|
||||
var text = $link.attr("name");
|
||||
this.navobj.setparam(tag + "filter", text).update();
|
||||
$("#taglist").append(this.make_tag(text, tag));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* Build a button to remove a specific filter.
|
||||
*
|
||||
* @this Listing
|
||||
* @param {string} text - text of the button
|
||||
* @param {string} type - tag type
|
||||
* @return {Object} - new button object
|
||||
*/
|
||||
make_tag: function(text, type) {
|
||||
var $tag = $("<a />", {
|
||||
"name": type, "class" : "btn btn-default btn-xs",
|
||||
"html": " " + htmlEncode(text)
|
||||
});
|
||||
|
||||
$("<span />", {"class" : "fa fa-remove"}).prependTo($tag);
|
||||
$tag.click($.proxy(this.remove_tag, this));
|
||||
return $tag;
|
||||
},
|
||||
|
||||
/**
|
||||
* Click event : remove a tag button.
|
||||
*
|
||||
* @this Listing
|
||||
* @param {Object} e - event object
|
||||
*/
|
||||
remove_tag: function(e) {
|
||||
var $tag = $(e.target);
|
||||
|
||||
if ($tag.is("i")) {
|
||||
$tag = $tag.parent();
|
||||
}
|
||||
e.preventDefault();
|
||||
this.navobj.delparam($tag.attr("name") + "filter").update();
|
||||
$tag.remove();
|
||||
},
|
||||
|
||||
/**
|
||||
* Click event: filter the listing when a tag is clicked.
|
||||
*
|
||||
* @this Listing
|
||||
* @param {Object} e - event object
|
||||
*/
|
||||
filter_by_tag: function(e) {
|
||||
var $link = $(e.target);
|
||||
e.preventDefault();
|
||||
|
||||
for (var name in this.tag_handlers) {
|
||||
if (this.tag_handlers[name].apply(this, [name, $link])) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,104 +0,0 @@
|
||||
(function($) {
|
||||
var Notify = function(element, options) {
|
||||
this.$element = $(element);
|
||||
this.options = $.extend({}, $.fn.notify.defaults, options);
|
||||
};
|
||||
|
||||
Notify.prototype = {
|
||||
constructor: Notify,
|
||||
|
||||
build_box: function(bid) {
|
||||
if (bid === undefined) {
|
||||
bid = "notifybox";
|
||||
}
|
||||
var div = $("<div class='alert alert-dismissible' role='alert' />", {
|
||||
id: bid,
|
||||
click: $.proxy(this.destroy_box, this)
|
||||
}).css({
|
||||
position: "fixed"
|
||||
});
|
||||
|
||||
return div;
|
||||
},
|
||||
|
||||
destroy_box: function(evt) {
|
||||
evt.preventDefault();
|
||||
this.$element.hide().remove();
|
||||
},
|
||||
|
||||
set_position: function(box) {
|
||||
box.css({
|
||||
'z-index': 100,
|
||||
top: this.options.top_position,
|
||||
left: "50%",
|
||||
'margin-left': -box.outerWidth(true) / 2
|
||||
});
|
||||
},
|
||||
|
||||
set_message: function(box, value) {
|
||||
var content = '<button type="button" class="close" data-dismiss="alert"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>' + value;
|
||||
|
||||
box.html(content);
|
||||
},
|
||||
|
||||
show: function(klass, message, timer) {
|
||||
var nbox = this.build_box();
|
||||
|
||||
if (klass != "normal") {
|
||||
nbox.addClass("alert-" + klass);
|
||||
}
|
||||
this.set_message(nbox, message);
|
||||
this.$element.append(nbox);
|
||||
this.set_position(nbox);
|
||||
if (timer !== undefined) {
|
||||
window.setTimeout(function() {
|
||||
nbox.alert('close');
|
||||
}, timer);
|
||||
}
|
||||
return this;
|
||||
},
|
||||
|
||||
success: function(message, timer) {
|
||||
return this.show.apply(this, ["success", message, timer]);
|
||||
},
|
||||
|
||||
info: function(message, timer) {
|
||||
return this.show.apply(this, ["info", message, timer]);
|
||||
},
|
||||
|
||||
error: function(message, timer) {
|
||||
return this.show.apply(this, ["danger", message, timer]);
|
||||
},
|
||||
|
||||
warning: function(message, timer) {
|
||||
return this.show.apply(this, ["warning", message, timer]);
|
||||
},
|
||||
|
||||
hide: function() {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
$.fn.notify = function(method) {
|
||||
var args = arguments;
|
||||
|
||||
return this.each(function() {
|
||||
var $this = $(this),
|
||||
data = $this.data('notify'),
|
||||
options = typeof method === "object" && method;
|
||||
|
||||
if (!data) {
|
||||
$this.data('notify', new Notify(this, options));
|
||||
data = $this.data('notify');
|
||||
}
|
||||
if (typeof method === "string") {
|
||||
data[method].apply(data, Array.prototype.slice.call(args, 1));
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$.fn.notify.defaults = {
|
||||
top_position: 50
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
@@ -1,80 +0,0 @@
|
||||
/*
|
||||
* Simple poller plugin.
|
||||
*
|
||||
* Sends a request at a given frequency.
|
||||
*/
|
||||
var Poller = function(url, options) {
|
||||
this.initialize(url, options);
|
||||
};
|
||||
|
||||
Poller.prototype = {
|
||||
constructor: Poller,
|
||||
|
||||
defaults: {
|
||||
interval: 2000,
|
||||
success_cb: null,
|
||||
error_cb: null
|
||||
},
|
||||
|
||||
initialize: function(url, options) {
|
||||
this.url = url;
|
||||
this.options = $.extend({}, this.defaults, options);
|
||||
this.running_request = false;
|
||||
this.paused = false;
|
||||
this.reset();
|
||||
},
|
||||
|
||||
reset: function() {
|
||||
if (!this.paused) {
|
||||
this.tid = setTimeout($.proxy(this.send_request, this), this.options.interval);
|
||||
}
|
||||
},
|
||||
|
||||
pause: function() {
|
||||
this.paused = true;
|
||||
if (!this.tid) {
|
||||
return;
|
||||
}
|
||||
clearTimeout(this.tid);
|
||||
},
|
||||
|
||||
resume: function() {
|
||||
if (!this.paused) {
|
||||
return;
|
||||
}
|
||||
this.paused = false;
|
||||
this.reset();
|
||||
},
|
||||
|
||||
send_request: function() {
|
||||
var poller = this;
|
||||
var args = "";
|
||||
|
||||
if (this.options.args != undefined) {
|
||||
args = "?";
|
||||
if (typeof this.options.args === "function") {
|
||||
args += this.options.args();
|
||||
} else {
|
||||
args += this.options.args;
|
||||
}
|
||||
}
|
||||
this.running_request = true;
|
||||
$.ajax({
|
||||
url: this.url + args,
|
||||
dataType: 'json',
|
||||
global: false
|
||||
}).done(function(data) {
|
||||
poller.running_request = false;
|
||||
if (poller.options.success_cb) {
|
||||
poller.options.success_cb(data);
|
||||
}
|
||||
poller.reset();
|
||||
}).fail(function(jqxhr) {
|
||||
var data = $.parseJSON(jqxhr.responseText);
|
||||
$("body").notify("error", data);
|
||||
if (poller.options.error_cb) {
|
||||
poller.options.error_cb(data);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
@@ -1,86 +0,0 @@
|
||||
(function($) {
|
||||
|
||||
/**
|
||||
* Return an instance of SearchBar.
|
||||
*
|
||||
* @constructor
|
||||
* @param {Object} element -
|
||||
* @param {Object} options - instance options
|
||||
*/
|
||||
var SearchBar = function(element, options) {
|
||||
this.initialize(element, options);
|
||||
};
|
||||
|
||||
SearchBar.prototype = {
|
||||
constructor: SearchBar,
|
||||
|
||||
initialize: function(element, options) {
|
||||
this.$element = $(element);
|
||||
this.options = $.extend({}, $.fn.searchbar.defaults, options);
|
||||
|
||||
this.$element.change($.proxy(this.pattern_change, this));
|
||||
this.$element.click(function(e) {
|
||||
$(this).select();
|
||||
});
|
||||
this.$element.blur(function(e) {
|
||||
var $this = $(this);
|
||||
if ($this.val() === "") {
|
||||
$this.val(gettext("Search..."));
|
||||
}
|
||||
});
|
||||
if (this.options.navobj.params.pattern !== undefined) {
|
||||
this.$element.val(this.options.navobj.getparam("pattern"));
|
||||
}
|
||||
if (this.options.navobj.params.criteria !== undefined) {
|
||||
$("#crit_" + this.options.navobj.params.criteria).attr("checked", "checked");
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Change event: apply search criterion.
|
||||
*
|
||||
* @this SearchBar
|
||||
* @param {Object} e - event object
|
||||
*/
|
||||
pattern_change: function(e) {
|
||||
var $input = $(e.target);
|
||||
var criteria = $("input[name=scriteria]:checked").val();
|
||||
var pattern = $input.val();
|
||||
|
||||
if (pattern !== "") {
|
||||
this.options.navobj.setparams({
|
||||
pattern: pattern,
|
||||
criteria: criteria
|
||||
});
|
||||
} else {
|
||||
this.options.navobj.delparam("pattern");
|
||||
this.options.navobj.delparam("criteria");
|
||||
this.options.navobj.delparam("page");
|
||||
}
|
||||
if (this.options.pattern_changed) {
|
||||
this.options.pattern_changed(this.options.navobj);
|
||||
}
|
||||
this.options.navobj.update();
|
||||
}
|
||||
};
|
||||
|
||||
$.fn.searchbar = function(method) {
|
||||
return this.each(function() {
|
||||
var $this = $(this),
|
||||
data = $this.data('searchbar'),
|
||||
options = typeof method === "object" && method;
|
||||
|
||||
if (!data) {
|
||||
$this.data('searchbar', new SearchBar(this, options));
|
||||
}
|
||||
if (typeof method === "string") {
|
||||
data[method]();
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
$.fn.searchbar.defaults = {
|
||||
navobj: null,
|
||||
pattern_changed: null
|
||||
};
|
||||
})(jQuery);
|
||||
@@ -1,101 +0,0 @@
|
||||
/**
|
||||
* Top notifications poller.
|
||||
*/
|
||||
|
||||
var TopNotifications = function(options) {
|
||||
this.initialize(options);
|
||||
};
|
||||
|
||||
TopNotifications.prototype = {
|
||||
constructor: TopNotifications,
|
||||
|
||||
defaults: {
|
||||
container_id: "#top_notifications",
|
||||
global_counter_id: "#alerts-counter",
|
||||
url: null,
|
||||
interval: 1000
|
||||
},
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
initialize: function(options) {
|
||||
this.options = $.extend({}, this.defaults, options);
|
||||
this.poller = new Poller(this.options.url, {
|
||||
interval: this.options.interval,
|
||||
success_cb: $.proxy(this.update, this)
|
||||
});
|
||||
this.$container = $(this.options.container_id);
|
||||
},
|
||||
|
||||
/**
|
||||
* Build a notification entry content.
|
||||
*/
|
||||
build_link_content: function(data) {
|
||||
var content = "";
|
||||
|
||||
if (data.counter) {
|
||||
content = "<span class='label label-" +
|
||||
data.level + "'>" + data.counter + "</span> " +
|
||||
data.text;
|
||||
} else {
|
||||
content = "<span class='fa fa-info-circle'></span> " + data.text;
|
||||
}
|
||||
return content;
|
||||
},
|
||||
|
||||
/**
|
||||
* Append an entry to the notification list.
|
||||
*/
|
||||
append_entry: function(data) {
|
||||
if ((data.counter !== undefined && data.counter === 0) ||
|
||||
(data.counter === undefined && data.text === undefined)) {
|
||||
return;
|
||||
}
|
||||
|
||||
var $li = $("<li />");
|
||||
|
||||
$li.append(
|
||||
$("<a />", {
|
||||
id: data.id, href: data.url,
|
||||
html: this.build_link_content(data)
|
||||
})
|
||||
);
|
||||
this.$container.find(".dropdown-menu").append($li);
|
||||
},
|
||||
|
||||
/**
|
||||
* Update an existing entry in the notification list.
|
||||
*/
|
||||
update_entry: function(data) {
|
||||
var $link = $("#" + data.id);
|
||||
|
||||
if ((data.counter !== undefined && data.counter === 0) ||
|
||||
(data.counter === undefined && data.text === undefined)) {
|
||||
$link.parent().remove();
|
||||
return;
|
||||
}
|
||||
$link.html(this.build_link_content(data));
|
||||
},
|
||||
|
||||
/**
|
||||
* Poller callback.
|
||||
*/
|
||||
update: function(data) {
|
||||
for (var cpt = 0; cpt < data.length; cpt++) {
|
||||
var $link = $("#" + data[cpt].id);
|
||||
if (!$link.length) {
|
||||
this.append_entry(data[cpt]);
|
||||
} else {
|
||||
this.update_entry(data[cpt]);
|
||||
}
|
||||
}
|
||||
var $entries = this.$container.find(".dropdown-menu li");
|
||||
if ($entries.length) {
|
||||
this.$container.removeClass("hidden");
|
||||
$(this.options.global_counter_id).html($entries.length);
|
||||
} else {
|
||||
this.$container.addClass("hidden");
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -1,202 +0,0 @@
|
||||
/**
|
||||
* Return an instance of TwocolsNav.
|
||||
*
|
||||
* @constructor
|
||||
*/
|
||||
|
||||
/* global Listing */
|
||||
|
||||
var TwocolsNav = function(options) {
|
||||
Listing.call(this, options);
|
||||
};
|
||||
|
||||
TwocolsNav.prototype = {
|
||||
defaults: {
|
||||
deflocation: null,
|
||||
formid: "#form",
|
||||
divid: "#content",
|
||||
reload_exceptions: null
|
||||
},
|
||||
|
||||
initialize: function(options) {
|
||||
this.options = $.extend({}, this.defaults, options);
|
||||
this.options.defcallback = $.proxy(this.default_cb, this);
|
||||
Listing.prototype.initialize.call(this, this.options);
|
||||
this.listen();
|
||||
this.navobj.register_callback(
|
||||
"security", $.proxy(this.security_callback, this));
|
||||
},
|
||||
|
||||
listen: function() {
|
||||
$("a.ajaxnav").click($.proxy(this.load_section, this));
|
||||
$(document).on("click", "#update", $.proxy(function(e) {
|
||||
var $form = $(e.target).closest("form");
|
||||
simple_ajax_form_post(e, {
|
||||
formid: $form.attr("id"),
|
||||
modal: false,
|
||||
reload_on_success: false,
|
||||
success_cb: $.proxy(this.save_cb, this)
|
||||
});
|
||||
}, this));
|
||||
var formId = 'parameters_form';
|
||||
$(document).on('submit', '#' + formId, $.proxy(function(evt) {
|
||||
simple_ajax_form_post(evt, {
|
||||
formid: formId,
|
||||
modal: false,
|
||||
reload_on_success: false,
|
||||
success_cb: $.proxy(this.save_cb, this),
|
||||
error_cb: function(data) {
|
||||
window.scrollTo(0, 0);
|
||||
$('a[data-app="' + data.prefix + '"]').tab('show');
|
||||
}
|
||||
});
|
||||
}, this));
|
||||
},
|
||||
|
||||
update_content: function(data) {
|
||||
if (data.content) {
|
||||
$('#' + this.options.divid).html(data.content);
|
||||
}
|
||||
this.update_listing(data, false);
|
||||
if (data.onload_cb) {
|
||||
eval(data.onload_cb + '()');
|
||||
}
|
||||
if (data.respmsg) {
|
||||
$("body").notify("error", data.respmsg);
|
||||
}
|
||||
$('#' + this.options.divid + ' select').change($.proxy(this.select_change, this));
|
||||
$('#' + this.options.divid + ' input[type=radio]').click($.proxy(this.radio_clicked, this));
|
||||
$(".help").popover({
|
||||
placement: 'bottom',
|
||||
trigger: 'hover'
|
||||
}).click(function(e) {e.preventDefault();});
|
||||
$('#' + this.options.divid + ' select').change();
|
||||
$('#' + this.options.divid + ' input[type=radio]:checked').click();
|
||||
},
|
||||
|
||||
propagate_change: function($node) {
|
||||
var $select = $node.find("select");
|
||||
var $radio = $node.find("input[type=radio]");
|
||||
if ($select.length) {
|
||||
$select.change();
|
||||
}
|
||||
if ($radio.length) {
|
||||
$radio.click();
|
||||
}
|
||||
},
|
||||
|
||||
toggle_field_visibility: function($field, $parent, value) {
|
||||
if ($parent.attr("disabled") === undefined &&
|
||||
$field.attr("data-visibility-value") === value) {
|
||||
$field.attr("disabled", null);
|
||||
$field.show();
|
||||
this.propagate_change($field);
|
||||
} else {
|
||||
$field.hide();
|
||||
$field.attr("disabled", "disabled");
|
||||
this.propagate_change($field);
|
||||
}
|
||||
},
|
||||
|
||||
select_change: function(e) {
|
||||
var instance = this;
|
||||
var $target = $(e.target);
|
||||
var $parent = $target.parents("div.form-group");
|
||||
|
||||
$('div[data-visibility-field="' + $target.attr("id") + '"]').each(function(idx) {
|
||||
instance.toggle_field_visibility($(this), $parent, $target.val());
|
||||
});
|
||||
$('h5[data-visibility-field="' + $target.attr("id") + '"]').each(function(idx) {
|
||||
instance.toggle_field_visibility($(this), $parent, $target.val());
|
||||
});
|
||||
},
|
||||
|
||||
radio_clicked: function(e) {
|
||||
var instance = this;
|
||||
var $target = $(e.target);
|
||||
var $parent = $target.parents("div.form-group");
|
||||
var realid = $target.attr("id");
|
||||
|
||||
realid = realid.substr(0, realid.length - 2);
|
||||
$('div[data-visibility-field="' + realid + '"]').each(function(idx) {
|
||||
instance.toggle_field_visibility($(this), $parent, $target.val());
|
||||
});
|
||||
$('h5[data-visibility-field="' + realid + '"]').each(function(idx) {
|
||||
instance.toggle_field_visibility($(this), $parent, $target.val());
|
||||
});
|
||||
},
|
||||
|
||||
save_cb: function(data) {
|
||||
clean_form_errors(this.options.formid);
|
||||
if (this.options.reload_exceptions) {
|
||||
for (var i = 0; i < this.options.reload_exceptions.length; i++) {
|
||||
if (this.navobj.getbaseurl() == this.options.reload_exceptions[i]) {
|
||||
window.location.reload();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
$("body").notify("success", data, 2000);
|
||||
},
|
||||
|
||||
load_section: function(e) {
|
||||
var $link = get_target(e);
|
||||
e.preventDefault();
|
||||
this.navobj.parse_string($link.attr("href"), true).update();
|
||||
},
|
||||
|
||||
/**
|
||||
* Select an entry in the left menu based on current url.
|
||||
*/
|
||||
select_left_menu: function() {
|
||||
$("a.ajaxnav").parent().removeClass("active");
|
||||
$("a[name=" + this.navobj.getbaseurl() + "]").parent().addClass("active");
|
||||
},
|
||||
|
||||
default_cb: function(data) {
|
||||
this.select_left_menu();
|
||||
this.update_content(data);
|
||||
},
|
||||
|
||||
/**
|
||||
* Navigation callback: security.
|
||||
*/
|
||||
security_callback: function (data) {
|
||||
this.select_left_menu();
|
||||
this.update_content(data);
|
||||
$('#start-tfa-setup').click(this.startTFASetup);
|
||||
$('#finalize-tfa-setup').click(this.finalizeTFASetup);
|
||||
},
|
||||
|
||||
startTFASetup: function (evt) {
|
||||
evt.preventDefault();
|
||||
$.ajax({
|
||||
url: window.root_url + '/api/v1/account/tfa/setup/',
|
||||
type: 'post',
|
||||
contentType: 'application/json'
|
||||
}).done(function (resp) {
|
||||
window.location.reload();
|
||||
});
|
||||
},
|
||||
|
||||
finalizeTFASetup: function (evt) {
|
||||
evt.preventDefault();
|
||||
var data = {
|
||||
pin_code: $('#pin-code').val()
|
||||
};
|
||||
$.ajax({
|
||||
url: window.root_url + '/api/v1/account/tfa/setup/check/',
|
||||
type: 'post',
|
||||
global: false,
|
||||
data: JSON.stringify(data),
|
||||
contentType: 'application/json'
|
||||
}).done(function (resp) {
|
||||
window.location.reload();
|
||||
}).fail(function (jqxhr) {
|
||||
var errors = JSON.parse(jqxhr.responseText);
|
||||
display_field_error($('#pin-code'), errors.pin_code.join(' '));
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
TwocolsNav.prototype = $.extend({}, Listing.prototype, TwocolsNav.prototype);
|
||||
|
Before Width: | Height: | Size: 641 B |
|
Before Width: | Height: | Size: 649 B |
|
Before Width: | Height: | Size: 184 B |
|
Before Width: | Height: | Size: 169 B |
|
Before Width: | Height: | Size: 902 B |
|
Before Width: | Height: | Size: 125 B |
|
Before Width: | Height: | Size: 650 B |
|
Before Width: | Height: | Size: 178 B |