ko.bindingHandlers.date = {
init: function (element, valueAccessor, bindings) {
ko.bindingHandlers.date._update(element, valueAccessor, bindings);
},
update: function (element, valueAccessor, bindings) {
ko.bindingHandlers.date._update(element, valueAccessor, bindings);
},
_update: function (element, valueAccessor, bindings) {
var value = ko.unwrap(valueAccessor());
if (value) {
var format = bindings.get('format');
$(element).html(moment(value * 1000).format(format || 'YYYY-MM-DD'));
} else {
$(element).html('');
}
}
};
ko.bindingHandlers.datetimepicker = {
init: function (element, valueAccessor, bindings) {
var options = {
format: 'YYYY-MM-DD HH:mm',
sideBySide: true
};
if (bindings.has('datetimepickerOptions')) {
options = _.assign(options, ko.unwrap(bindings.get('datetimepickerOptions')));
}
var date = ko.unwrap(valueAccessor());
if (date) {
options.defaultDate = date;
}
$(element).datetimepicker(options);
$(element).on('dp.change', function (e) {
valueAccessor()(e.date.format(options.format));
});
},
update: function (element, valueAccessor) {
var date = ko.unwrap(valueAccessor());
if (date) {
$(element).data('DateTimePicker').date(date);
}
}
};
ko.bindingHandlers.price = {
update: function (element, valueAccess) {
var value = ko.unwrap(valueAccess());
if (value === null || value === undefined) {
$(element).html('');
} else {
$(element).html(numeral(value / 100).format('0,0.00'));
}
}
};
ko.bindingHandlers.integer = {
update: function (element, valueAccessor) {
var value = ko.unwrap(valueAccessor());
$(element).html(numeral(value).format('0,0'));
}
};
ko.bindingHandlers.select2 = {
init: function (element, valueAccessor, allBindingsAccessor) {
$(element).select2(ko.unwrap(valueAccessor()));
var allBindings = allBindingsAccessor();
if (allBindings.value) {
$(element).val(allBindings.value());
}
}
};
function scrollToElement(element, options, callback) {
options = _.assign({}, { duration: 200, offset: 0 }, options);
$('html,body').animate({ scrollTop: $(element).offset().top - options.offset }, options.duration, callback);
}
function parseQueryString() {
if (!location.search || location.search.length === 1) {
return {};
}
var pairs = location.search.substr(1).split('&');
var qs = { };
_.each(pairs, function (pair) {
var parts = pair.split('=');
qs[parts[0]] = decodeURIComponent(parts[1]);
});
return qs;
}
function buildQueryString(data) {
var qs = _.chain(data)
.map(function (val, key) {
return key + '=' + encodeURIComponent(val);
})
.value()
.join('&');
return qs ? '?' + qs : null;
}
function handleAjaxError(xhr) {
var error = JSON.parse(xhr.responseText);
alert(error.message);
}
function reloadPage(delay) {
delay = delay || 0;
setTimeout(function () {
location.href = location.pathname + location.search;
}, delay);
}
function plainTextToHtml(text) {
if (!text) {
return text;
}
// urls to hyper links
text = text.replace(/((http|https):\/\/[^\s]+)/g, function (url) {
return '' + url + '';
});
// line breaks to
text = text.replace(/\n/g, '
');
return text;
}
// Modal
var Modal = function () {
var self = this;
var id = null;
var opts = null;
var template =
'
';
var defer = null;
var model = null;
self.$modal = function () {
return $('#' + id);
};
self.defer = function () {
return defer;
};
self.open = function (options) {
opts = options;
if (options && options.buttons) {
$.each(options.buttons, function () {
if (!this.id) {
this.id = '__btn_' + new Date().getTime() + Math.floor(Math.random() * 1000);
}
if (!this.className) {
this.className = 'btn-default';
}
})
}
model = {
title: ko.observable(options.title),
body: ko.observable(options.body),
showCloseButton: ko.observable(true),
buttons: ko.observableArray(options.buttons),
close: function () {
self.close();
},
onButtonClick: function (button, e) {
if (button.click) {
button.click.apply(self, [e]);
}
}
};
if (options.showCloseButton !== undefined) {
model.showCloseButton(options.showCloseButton);
}
id = '__modal_' + new Date().getTime();
$(document.body).append($(template).attr('id', id));
ko.applyBindings(model, document.getElementById(id));
var $modal = $('#' + id);
if (options) {
$modal.modal(options);
}
$modal.on('shown.bs.modal', function () {
_.each(options.buttons, function (button) {
if (button.clipboard) {
var clipboard = new Clipboard('#' + button.id, button.clipboard);
if (button.clipboard.success) {
clipboard.on('success', button.clipboard.success.bind(self));
}
}
});
if (opts.callbacks && opts.callbacks.shown) {
opts.callbacks.shown.apply(self);
}
});
self.resize();
$modal.modal('show');
defer = $.Deferred();
return defer.promise();
};
self.resize = function () {
var winHeight = $(window).height();
$('#' + id)
.find('.modal-body')
.css('max-height', Math.round(winHeight * 0.7) + 'px')
.css('overflow', 'auto');
};
self.close = function (options) {
var $modal = $('#' + id);
$modal.modal('hide');
$modal.on('hidden.bs.modal', function () {
$modal.remove();
});
if (opts.callbacks && opts.callbacks.close) {
opts.callbacks.close.apply(self);
}
if (options && options.reject) {
defer.reject();
} else {
defer.resolve();
}
};
};
Modal.instance = new Modal();
Modal.open = function (options) {
return Modal.instance.open(options);
};
Modal.alert = function (options) {
return Modal.instance.open({
title: options.title,
body: options.message,
showCloseButton: false,
buttons: options.buttons || [
{
'className': 'btn-primary',
'text': '确定',
'click': function () {
this.close();
}
}
]
})
};
Modal.confirm = function (options) {
return Modal.instance.open({
title: options.title,
body: '' + options.message + '
',
showCloseButton: false,
buttons: [
{
'className': 'btn-default',
'text': '取消',
'click': function () {
this.close({ reject: true });
}
},
{
'className': 'btn-primary',
'text': '确定',
'click': function () {
this.close();
}
}
]
})
};
var DateRangePicker = function (element) {
var self = this;
var $element = $(element);
this.init = function () {
$element.data('DateRangePicker', self);
$element.find('.from-date-picker').datetimepicker({ format: 'YYYY-MM-DD' });
$element.find('.to-date-picker').datetimepicker({ format: 'YYYY-MM-DD' });
};
this.value = function (value) {
if (arguments.length === 0) {
return {
'from': $element.find('.from-date-picker :text').val(),
'to': $element.find('.to-date-picker :text').val()
};
} else {
$element.find('.from-date-picker').data('DateTimePicker').date(value.from);
$element.find('.to-date-picker').data('DateTimePicker').date(value.to);
}
};
this.timespan = function () {
var range = self.value();
return new Date(range.to).getTime() + 24 * 60 * 60 * 1000 - new Date(range.from).getTime();
}
};
DateRangePicker.create = function (element) {
var picker = new DateRangePicker(element);
picker.init();
return picker;
};
// UI Component
$(function () {
var UIComponent = window.UIComponent = {
init: function (container) {
var $container = $(container);
var $elements = null;
if ($container.data('ui')) {
$elements = $container;
} else {
$elements = $container.find('[data-ui]');
}
var groups = {};
$elements.each(function () {
var $element = $(this);
var componentName = $element.data('ui');
if (!groups[componentName]) {
groups[componentName] = [];
}
groups[componentName].push($element);
});
_.each(_.keys(groups), function (name) {
var handler = UIComponent.handlers[name];
if (handler) {
handler.init(groups[name]);
}
});
}
};
UIComponent.handlers = {};
UIComponent.handlers['inline-user-info'] = {
init: function ($elements) {
var ids = _.map($elements, function ($element) {
return $element.data('uid');
});
ids = _.filter(_.uniq(ids), function (id) { return !!id; });
if (ids.length === 0) {
return;
}
$.get('/backend/users/api_get_user_infos', {ids: ids.join(',')}, function (result) {
_.each($elements, function ($element) {
var uid = $element.data('uid');
var user = result[uid];
if (!user) {
return;
}
$element.html('' + user.nickname + '');
if ($element[0].tagName === 'A') {
UIComponent.handlers['user-info-popover'].init([$element]);
}
});
});
}
};
UIComponent.handlers['user-info-popover'] = {
init: function ($elements) {
var buildHtmlRow = function (label, content) {
return '';
};
_.each($elements, function ($element) {
var uid = $element.data('uid');
if (!uid) {
return;
}
$element.css('cursor', 'pointer');
$element.webuiPopover({
title: null,
trigger: 'hover',
delay: {
show: 300
},
width: 350,
type: 'async',
url: '/backend/users/api_get_user_popover_info/' + uid,
content: function (data) {
var html =
'';
return html;
}
});
});
}
};
UIComponent.handlers['inline-member-info'] = {
init: function ($elements) {
var ids = _.map($elements, function ($element) {
return $element.data('member-id');
});
ids = _.filter(_.uniq(ids), function (id) { return !!id; });
if (ids.length === 0) {
return;
}
$.get('/backend/members/api_get_member_infos', { ids: ids.join(',') }, function (result) {
_.each($elements, function ($element) {
var memberId = $element.data('member-id');
var member = result[memberId];
if (member) {
var html = '';
if (member.headimgurl) {
html += '
'
}
html += '' + member.nickname + '';
if (member.is_vip) {
var now = Math.round(new Date().getTime() / 1000);
var expiryTimeText = moment(member.vip_expiry_time * 1000).format('YYYY-MM-DD HH:mm:ss') + ' 过期';
if (member.vip_expiry_time > now) {
html += ' ';
} else {
html += ' ';
}
}
$element.html(html);
}
});
});
}
};
UIComponent.handlers['table-sort'] = {
init: function ($elements) {
var qs = parseQueryString();
_.each($elements, function ($element) {
$element.css('cursor', 'pointer');
$element.attr('title', '点击排序');
$element.append('');
var $icon = $element.find('.table-sort-icon');
var field = $element.data('field');
var startDir = $element.data('start-dir') || 'asc';
var orderBy = qs.order_by ? parseOrderBy(qs.order_by) : null;
// update icon status from query string
if (orderBy && orderBy.field === field) {
if (orderBy.dir === 'asc') {
$icon.removeClass('fa-caret-down').addClass('fa-caret-up');
} else {
$icon.removeClass('fa-caret-up').addClass('fa-caret-down');
}
$icon.show();
}
$element.click(function () {
var dir = startDir;
if (orderBy && orderBy.field === field) {
dir = orderBy.dir === 'asc' ? 'desc' : 'asc';
}
var newQs = _.assign({}, qs);
delete newQs.page;
newQs.order_by = field + ' ' + dir;
var search = _.chain(newQs)
.map(function (value, key) {
return key + '=' + encodeURIComponent(value);
})
.value()
.join('&');
location.href = location.pathname + '?' + search;
});
});
function parseOrderBy(value) {
if (!value) {
return null;
}
var parts = value.split(' ');
if (parts.length === 1) {
return { field: parts[0], dir: 'asc' };
}
return { field: parts[0], dir: parts[1] };
}
}
};
UIComponent.init(document.body);
});