Added support for stacked inline models.
Added highlighting to sorted inline. Added migrations to add Note class to database. Added SortableInlineBase for checking type of model specified in inline model subclasses Sortable.master
parent
4e38d8fbe1
commit
971de8423c
|
|
@ -1,7 +1,8 @@
|
|||
import json
|
||||
from django.conf import settings
|
||||
from django.conf.urls.defaults import patterns, url
|
||||
from django.contrib.admin import ModelAdmin, TabularInline
|
||||
from django.contrib.admin import ModelAdmin, TabularInline, StackedInline
|
||||
from django.contrib.admin.options import InlineModelAdmin
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.http import HttpResponse
|
||||
from django.shortcuts import render
|
||||
|
|
@ -22,9 +23,10 @@ class SortableAdmin(ModelAdmin):
|
|||
def __init__(self, *args, **kwargs):
|
||||
super(SortableAdmin, self).__init__(*args, **kwargs)
|
||||
self.has_sortable_tabular_inlines = False
|
||||
self.has_sortable_stacked_inlines = False
|
||||
for klass in self.inlines:
|
||||
if issubclass(klass, SortableTabularInline):
|
||||
self.has_sortable_tabular_inlines = True
|
||||
if issubclass(klass, SortableTabularInline) and klass.model.is_sortable(): self.has_sortable_tabular_inlines = True
|
||||
if issubclass(klass, SortableStackedInline) and klass.model.is_sortable(): self.has_sortable_stacked_inlines = True
|
||||
|
||||
def get_urls(self):
|
||||
urls = super(SortableAdmin, self).get_urls()
|
||||
|
|
@ -90,10 +92,12 @@ class SortableAdmin(ModelAdmin):
|
|||
return super(SortableAdmin, self).changelist_view(request, extra_context=extra_context)
|
||||
|
||||
def change_view(self, request, object_id, extra_context=None):
|
||||
has_sortable_tabular_inlines = self.has_sortable_tabular_inlines
|
||||
if has_sortable_tabular_inlines:
|
||||
if self.has_sortable_tabular_inlines or self.has_sortable_stacked_inlines:
|
||||
self.change_form_template = 'adminsortable/change_form.html'
|
||||
extra_context = {'has_sortable_tabular_inlines' : self.has_sortable_tabular_inlines}
|
||||
extra_context = {
|
||||
'has_sortable_tabular_inlines' : self.has_sortable_tabular_inlines,
|
||||
'has_sortable_stacked_inlines' : self.has_sortable_stacked_inlines
|
||||
}
|
||||
return super(SortableAdmin, self).change_view(request, object_id, extra_context=extra_context)
|
||||
|
||||
@csrf_exempt
|
||||
|
|
@ -124,18 +128,38 @@ class SortableAdmin(ModelAdmin):
|
|||
mimetype='application/json')
|
||||
|
||||
|
||||
class SortableTabularInline(TabularInline):
|
||||
"""Custom template that enables sorting for tabular inlines"""
|
||||
class SortableInlineBase(InlineModelAdmin):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(SortableTabularInline, self).__init__(*args, **kwargs)
|
||||
super(SortableInlineBase, self).__init__(*args, **kwargs)
|
||||
|
||||
if not issubclass(self.model, Sortable):
|
||||
raise Warning(u'Models that inherit SortableTabluarInline must inherit from Sortable')
|
||||
raise Warning(u'Models that are specified in SortableTabluarInline and SortableStackedInline must inherit from Sortable')
|
||||
|
||||
"""
|
||||
This property is referenced by tabular.html's <h2> to show a message on whether or
|
||||
not the inlines are sortable. It is exposed in: inline_admin_formset.opts
|
||||
"""
|
||||
self.is_sortable = self.model.is_sortable()
|
||||
|
||||
|
||||
class SortableTabularInline(SortableInlineBase, TabularInline):
|
||||
"""Custom template that enables sorting for tabular inlines"""
|
||||
template = 'adminsortable/edit_inline/tabular.html'
|
||||
|
||||
|
||||
class SortableStackedInline(SortableInlineBase, StackedInline):
|
||||
"""Custom template that enables sorting for stacked inlines"""
|
||||
template = 'adminsortable/edit_inline/stacked.html'
|
||||
|
||||
|
||||
#class SortableTabularInline(TabularInline):
|
||||
# """Custom template that enables sorting for tabular inlines"""
|
||||
# def __init__(self, *args, **kwargs):
|
||||
# super(SortableTabularInline, self).__init__(*args, **kwargs)
|
||||
#
|
||||
# if not issubclass(self.model, Sortable):
|
||||
# raise Warning(u'Models that inherit SortableTabluarInline must inherit from Sortable')
|
||||
#
|
||||
# """
|
||||
# This property is referenced by tabular.html's <h2> to show a message on whether or
|
||||
# not the inlines are sortable. It is exposed in: inline_admin_formset.opts
|
||||
# """
|
||||
# self.is_sortable = self.model.is_sortable()
|
||||
#
|
||||
# template = 'adminsortable/edit_inline/tabular.html'
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
jQuery(function($){
|
||||
if ($(':hidden[name="admin_sorting_url"]').length > 0)
|
||||
{
|
||||
$('.inline-group').sortable({
|
||||
axis : 'y',
|
||||
containment : 'parent',
|
||||
tolerance : 'pointer',
|
||||
items : '.inline-related',
|
||||
stop : function(event, ui)
|
||||
{
|
||||
var indexes = Array();
|
||||
ui.item.parent().children('.inline-related').each(function(i)
|
||||
{
|
||||
index_value = $(this).find(':hidden[name$="-id"]').val();
|
||||
if (index_value != "" && index_value != undefined)
|
||||
indexes.push(index_value);
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
url: ui.item.parent().find(':hidden[name="admin_sorting_url"]').val(),
|
||||
type: 'POST',
|
||||
data: { indexes : indexes.join(',') },
|
||||
success: function()
|
||||
{
|
||||
ui.effect('highlight');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
@ -24,7 +24,8 @@ jQuery(function($){
|
|||
data: { indexes : indexes.join(',') },
|
||||
success: function()
|
||||
{
|
||||
//re-stripe table
|
||||
//highlight sorted row, then re-stripe table
|
||||
ui.item.effect('highlight', {}, 1000);
|
||||
tabular_inline_rows.removeClass('row1 row2');
|
||||
$('.tabular table tbody tr:odd').addClass('row2');
|
||||
$('.tabular table tbody tr:even').addClass('row1');
|
||||
|
|
|
|||
|
|
@ -0,0 +1,763 @@
|
|||
/*
|
||||
* jQuery UI Effects 1.8.16
|
||||
*
|
||||
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Effects/
|
||||
*/
|
||||
;jQuery.effects || (function($, undefined) {
|
||||
|
||||
$.effects = {};
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/****************************** COLOR ANIMATIONS ******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
// override the animation for color styles
|
||||
$.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor',
|
||||
'borderRightColor', 'borderTopColor', 'borderColor', 'color', 'outlineColor'],
|
||||
function(i, attr) {
|
||||
$.fx.step[attr] = function(fx) {
|
||||
if (!fx.colorInit) {
|
||||
fx.start = getColor(fx.elem, attr);
|
||||
fx.end = getRGB(fx.end);
|
||||
fx.colorInit = true;
|
||||
}
|
||||
|
||||
fx.elem.style[attr] = 'rgb(' +
|
||||
Math.max(Math.min(parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0], 10), 255), 0) + ',' +
|
||||
Math.max(Math.min(parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1], 10), 255), 0) + ',' +
|
||||
Math.max(Math.min(parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2], 10), 255), 0) + ')';
|
||||
};
|
||||
});
|
||||
|
||||
// Color Conversion functions from highlightFade
|
||||
// By Blair Mitchelmore
|
||||
// http://jquery.offput.ca/highlightFade/
|
||||
|
||||
// Parse strings looking for color tuples [255,255,255]
|
||||
function getRGB(color) {
|
||||
var result;
|
||||
|
||||
// Check if we're already dealing with an array of colors
|
||||
if ( color && color.constructor == Array && color.length == 3 )
|
||||
return color;
|
||||
|
||||
// Look for rgb(num,num,num)
|
||||
if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color))
|
||||
return [parseInt(result[1],10), parseInt(result[2],10), parseInt(result[3],10)];
|
||||
|
||||
// Look for rgb(num%,num%,num%)
|
||||
if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color))
|
||||
return [parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55];
|
||||
|
||||
// Look for #a0b1c2
|
||||
if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color))
|
||||
return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)];
|
||||
|
||||
// Look for #fff
|
||||
if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color))
|
||||
return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)];
|
||||
|
||||
// Look for rgba(0, 0, 0, 0) == transparent in Safari 3
|
||||
if (result = /rgba\(0, 0, 0, 0\)/.exec(color))
|
||||
return colors['transparent'];
|
||||
|
||||
// Otherwise, we're most likely dealing with a named color
|
||||
return colors[$.trim(color).toLowerCase()];
|
||||
}
|
||||
|
||||
function getColor(elem, attr) {
|
||||
var color;
|
||||
|
||||
do {
|
||||
color = $.curCSS(elem, attr);
|
||||
|
||||
// Keep going until we find an element that has color, or we hit the body
|
||||
if ( color != '' && color != 'transparent' || $.nodeName(elem, "body") )
|
||||
break;
|
||||
|
||||
attr = "backgroundColor";
|
||||
} while ( elem = elem.parentNode );
|
||||
|
||||
return getRGB(color);
|
||||
};
|
||||
|
||||
// Some named colors to work with
|
||||
// From Interface by Stefan Petre
|
||||
// http://interface.eyecon.ro/
|
||||
|
||||
var colors = {
|
||||
aqua:[0,255,255],
|
||||
azure:[240,255,255],
|
||||
beige:[245,245,220],
|
||||
black:[0,0,0],
|
||||
blue:[0,0,255],
|
||||
brown:[165,42,42],
|
||||
cyan:[0,255,255],
|
||||
darkblue:[0,0,139],
|
||||
darkcyan:[0,139,139],
|
||||
darkgrey:[169,169,169],
|
||||
darkgreen:[0,100,0],
|
||||
darkkhaki:[189,183,107],
|
||||
darkmagenta:[139,0,139],
|
||||
darkolivegreen:[85,107,47],
|
||||
darkorange:[255,140,0],
|
||||
darkorchid:[153,50,204],
|
||||
darkred:[139,0,0],
|
||||
darksalmon:[233,150,122],
|
||||
darkviolet:[148,0,211],
|
||||
fuchsia:[255,0,255],
|
||||
gold:[255,215,0],
|
||||
green:[0,128,0],
|
||||
indigo:[75,0,130],
|
||||
khaki:[240,230,140],
|
||||
lightblue:[173,216,230],
|
||||
lightcyan:[224,255,255],
|
||||
lightgreen:[144,238,144],
|
||||
lightgrey:[211,211,211],
|
||||
lightpink:[255,182,193],
|
||||
lightyellow:[255,255,224],
|
||||
lime:[0,255,0],
|
||||
magenta:[255,0,255],
|
||||
maroon:[128,0,0],
|
||||
navy:[0,0,128],
|
||||
olive:[128,128,0],
|
||||
orange:[255,165,0],
|
||||
pink:[255,192,203],
|
||||
purple:[128,0,128],
|
||||
violet:[128,0,128],
|
||||
red:[255,0,0],
|
||||
silver:[192,192,192],
|
||||
white:[255,255,255],
|
||||
yellow:[255,255,0],
|
||||
transparent: [255,255,255]
|
||||
};
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/****************************** CLASS ANIMATIONS ******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
var classAnimationActions = ['add', 'remove', 'toggle'],
|
||||
shorthandStyles = {
|
||||
border: 1,
|
||||
borderBottom: 1,
|
||||
borderColor: 1,
|
||||
borderLeft: 1,
|
||||
borderRight: 1,
|
||||
borderTop: 1,
|
||||
borderWidth: 1,
|
||||
margin: 1,
|
||||
padding: 1
|
||||
};
|
||||
|
||||
function getElementStyles() {
|
||||
var style = document.defaultView
|
||||
? document.defaultView.getComputedStyle(this, null)
|
||||
: this.currentStyle,
|
||||
newStyle = {},
|
||||
key,
|
||||
camelCase;
|
||||
|
||||
// webkit enumerates style porperties
|
||||
if (style && style.length && style[0] && style[style[0]]) {
|
||||
var len = style.length;
|
||||
while (len--) {
|
||||
key = style[len];
|
||||
if (typeof style[key] == 'string') {
|
||||
camelCase = key.replace(/\-(\w)/g, function(all, letter){
|
||||
return letter.toUpperCase();
|
||||
});
|
||||
newStyle[camelCase] = style[key];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (key in style) {
|
||||
if (typeof style[key] === 'string') {
|
||||
newStyle[key] = style[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return newStyle;
|
||||
}
|
||||
|
||||
function filterStyles(styles) {
|
||||
var name, value;
|
||||
for (name in styles) {
|
||||
value = styles[name];
|
||||
if (
|
||||
// ignore null and undefined values
|
||||
value == null ||
|
||||
// ignore functions (when does this occur?)
|
||||
$.isFunction(value) ||
|
||||
// shorthand styles that need to be expanded
|
||||
name in shorthandStyles ||
|
||||
// ignore scrollbars (break in IE)
|
||||
(/scrollbar/).test(name) ||
|
||||
|
||||
// only colors or values that can be converted to numbers
|
||||
(!(/color/i).test(name) && isNaN(parseFloat(value)))
|
||||
) {
|
||||
delete styles[name];
|
||||
}
|
||||
}
|
||||
|
||||
return styles;
|
||||
}
|
||||
|
||||
function styleDifference(oldStyle, newStyle) {
|
||||
var diff = { _: 0 }, // http://dev.jquery.com/ticket/5459
|
||||
name;
|
||||
|
||||
for (name in newStyle) {
|
||||
if (oldStyle[name] != newStyle[name]) {
|
||||
diff[name] = newStyle[name];
|
||||
}
|
||||
}
|
||||
|
||||
return diff;
|
||||
}
|
||||
|
||||
$.effects.animateClass = function(value, duration, easing, callback) {
|
||||
if ($.isFunction(easing)) {
|
||||
callback = easing;
|
||||
easing = null;
|
||||
}
|
||||
|
||||
return this.queue(function() {
|
||||
var that = $(this),
|
||||
originalStyleAttr = that.attr('style') || ' ',
|
||||
originalStyle = filterStyles(getElementStyles.call(this)),
|
||||
newStyle,
|
||||
className = that.attr('class');
|
||||
|
||||
$.each(classAnimationActions, function(i, action) {
|
||||
if (value[action]) {
|
||||
that[action + 'Class'](value[action]);
|
||||
}
|
||||
});
|
||||
newStyle = filterStyles(getElementStyles.call(this));
|
||||
that.attr('class', className);
|
||||
|
||||
that.animate(styleDifference(originalStyle, newStyle), {
|
||||
queue: false,
|
||||
duration: duration,
|
||||
easing: easing,
|
||||
complete: function() {
|
||||
$.each(classAnimationActions, function(i, action) {
|
||||
if (value[action]) { that[action + 'Class'](value[action]); }
|
||||
});
|
||||
// work around bug in IE by clearing the cssText before setting it
|
||||
if (typeof that.attr('style') == 'object') {
|
||||
that.attr('style').cssText = '';
|
||||
that.attr('style').cssText = originalStyleAttr;
|
||||
} else {
|
||||
that.attr('style', originalStyleAttr);
|
||||
}
|
||||
if (callback) { callback.apply(this, arguments); }
|
||||
$.dequeue( this );
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
$.fn.extend({
|
||||
_addClass: $.fn.addClass,
|
||||
addClass: function(classNames, speed, easing, callback) {
|
||||
return speed ? $.effects.animateClass.apply(this, [{ add: classNames },speed,easing,callback]) : this._addClass(classNames);
|
||||
},
|
||||
|
||||
_removeClass: $.fn.removeClass,
|
||||
removeClass: function(classNames,speed,easing,callback) {
|
||||
return speed ? $.effects.animateClass.apply(this, [{ remove: classNames },speed,easing,callback]) : this._removeClass(classNames);
|
||||
},
|
||||
|
||||
_toggleClass: $.fn.toggleClass,
|
||||
toggleClass: function(classNames, force, speed, easing, callback) {
|
||||
if ( typeof force == "boolean" || force === undefined ) {
|
||||
if ( !speed ) {
|
||||
// without speed parameter;
|
||||
return this._toggleClass(classNames, force);
|
||||
} else {
|
||||
return $.effects.animateClass.apply(this, [(force?{add:classNames}:{remove:classNames}),speed,easing,callback]);
|
||||
}
|
||||
} else {
|
||||
// without switch parameter;
|
||||
return $.effects.animateClass.apply(this, [{ toggle: classNames },force,speed,easing]);
|
||||
}
|
||||
},
|
||||
|
||||
switchClass: function(remove,add,speed,easing,callback) {
|
||||
return $.effects.animateClass.apply(this, [{ add: add, remove: remove },speed,easing,callback]);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/*********************************** EFFECTS **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
$.extend($.effects, {
|
||||
version: "1.8.16",
|
||||
|
||||
// Saves a set of properties in a data storage
|
||||
save: function(element, set) {
|
||||
for(var i=0; i < set.length; i++) {
|
||||
if(set[i] !== null) element.data("ec.storage."+set[i], element[0].style[set[i]]);
|
||||
}
|
||||
},
|
||||
|
||||
// Restores a set of previously saved properties from a data storage
|
||||
restore: function(element, set) {
|
||||
for(var i=0; i < set.length; i++) {
|
||||
if(set[i] !== null) element.css(set[i], element.data("ec.storage."+set[i]));
|
||||
}
|
||||
},
|
||||
|
||||
setMode: function(el, mode) {
|
||||
if (mode == 'toggle') mode = el.is(':hidden') ? 'show' : 'hide'; // Set for toggle
|
||||
return mode;
|
||||
},
|
||||
|
||||
getBaseline: function(origin, original) { // Translates a [top,left] array into a baseline value
|
||||
// this should be a little more flexible in the future to handle a string & hash
|
||||
var y, x;
|
||||
switch (origin[0]) {
|
||||
case 'top': y = 0; break;
|
||||
case 'middle': y = 0.5; break;
|
||||
case 'bottom': y = 1; break;
|
||||
default: y = origin[0] / original.height;
|
||||
};
|
||||
switch (origin[1]) {
|
||||
case 'left': x = 0; break;
|
||||
case 'center': x = 0.5; break;
|
||||
case 'right': x = 1; break;
|
||||
default: x = origin[1] / original.width;
|
||||
};
|
||||
return {x: x, y: y};
|
||||
},
|
||||
|
||||
// Wraps the element around a wrapper that copies position properties
|
||||
createWrapper: function(element) {
|
||||
|
||||
// if the element is already wrapped, return it
|
||||
if (element.parent().is('.ui-effects-wrapper')) {
|
||||
return element.parent();
|
||||
}
|
||||
|
||||
// wrap the element
|
||||
var props = {
|
||||
width: element.outerWidth(true),
|
||||
height: element.outerHeight(true),
|
||||
'float': element.css('float')
|
||||
},
|
||||
wrapper = $('<div></div>')
|
||||
.addClass('ui-effects-wrapper')
|
||||
.css({
|
||||
fontSize: '100%',
|
||||
background: 'transparent',
|
||||
border: 'none',
|
||||
margin: 0,
|
||||
padding: 0
|
||||
}),
|
||||
active = document.activeElement;
|
||||
|
||||
element.wrap(wrapper);
|
||||
|
||||
// Fixes #7595 - Elements lose focus when wrapped.
|
||||
if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
|
||||
$( active ).focus();
|
||||
}
|
||||
|
||||
wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually loose the reference to the wrapped element
|
||||
|
||||
// transfer positioning properties to the wrapper
|
||||
if (element.css('position') == 'static') {
|
||||
wrapper.css({ position: 'relative' });
|
||||
element.css({ position: 'relative' });
|
||||
} else {
|
||||
$.extend(props, {
|
||||
position: element.css('position'),
|
||||
zIndex: element.css('z-index')
|
||||
});
|
||||
$.each(['top', 'left', 'bottom', 'right'], function(i, pos) {
|
||||
props[pos] = element.css(pos);
|
||||
if (isNaN(parseInt(props[pos], 10))) {
|
||||
props[pos] = 'auto';
|
||||
}
|
||||
});
|
||||
element.css({position: 'relative', top: 0, left: 0, right: 'auto', bottom: 'auto' });
|
||||
}
|
||||
|
||||
return wrapper.css(props).show();
|
||||
},
|
||||
|
||||
removeWrapper: function(element) {
|
||||
var parent,
|
||||
active = document.activeElement;
|
||||
|
||||
if (element.parent().is('.ui-effects-wrapper')) {
|
||||
parent = element.parent().replaceWith(element);
|
||||
// Fixes #7595 - Elements lose focus when wrapped.
|
||||
if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
|
||||
$( active ).focus();
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
|
||||
return element;
|
||||
},
|
||||
|
||||
setTransition: function(element, list, factor, value) {
|
||||
value = value || {};
|
||||
$.each(list, function(i, x){
|
||||
unit = element.cssUnit(x);
|
||||
if (unit[0] > 0) value[x] = unit[0] * factor + unit[1];
|
||||
});
|
||||
return value;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
function _normalizeArguments(effect, options, speed, callback) {
|
||||
// shift params for method overloading
|
||||
if (typeof effect == 'object') {
|
||||
callback = options;
|
||||
speed = null;
|
||||
options = effect;
|
||||
effect = options.effect;
|
||||
}
|
||||
if ($.isFunction(options)) {
|
||||
callback = options;
|
||||
speed = null;
|
||||
options = {};
|
||||
}
|
||||
if (typeof options == 'number' || $.fx.speeds[options]) {
|
||||
callback = speed;
|
||||
speed = options;
|
||||
options = {};
|
||||
}
|
||||
if ($.isFunction(speed)) {
|
||||
callback = speed;
|
||||
speed = null;
|
||||
}
|
||||
|
||||
options = options || {};
|
||||
|
||||
speed = speed || options.duration;
|
||||
speed = $.fx.off ? 0 : typeof speed == 'number'
|
||||
? speed : speed in $.fx.speeds ? $.fx.speeds[speed] : $.fx.speeds._default;
|
||||
|
||||
callback = callback || options.complete;
|
||||
|
||||
return [effect, options, speed, callback];
|
||||
}
|
||||
|
||||
function standardSpeed( speed ) {
|
||||
// valid standard speeds
|
||||
if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// invalid strings - treat as "normal" speed
|
||||
if ( typeof speed === "string" && !$.effects[ speed ] ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$.fn.extend({
|
||||
effect: function(effect, options, speed, callback) {
|
||||
var args = _normalizeArguments.apply(this, arguments),
|
||||
// TODO: make effects take actual parameters instead of a hash
|
||||
args2 = {
|
||||
options: args[1],
|
||||
duration: args[2],
|
||||
callback: args[3]
|
||||
},
|
||||
mode = args2.options.mode,
|
||||
effectMethod = $.effects[effect];
|
||||
|
||||
if ( $.fx.off || !effectMethod ) {
|
||||
// delegate to the original method (e.g., .show()) if possible
|
||||
if ( mode ) {
|
||||
return this[ mode ]( args2.duration, args2.callback );
|
||||
} else {
|
||||
return this.each(function() {
|
||||
if ( args2.callback ) {
|
||||
args2.callback.call( this );
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return effectMethod.call(this, args2);
|
||||
},
|
||||
|
||||
_show: $.fn.show,
|
||||
show: function(speed) {
|
||||
if ( standardSpeed( speed ) ) {
|
||||
return this._show.apply(this, arguments);
|
||||
} else {
|
||||
var args = _normalizeArguments.apply(this, arguments);
|
||||
args[1].mode = 'show';
|
||||
return this.effect.apply(this, args);
|
||||
}
|
||||
},
|
||||
|
||||
_hide: $.fn.hide,
|
||||
hide: function(speed) {
|
||||
if ( standardSpeed( speed ) ) {
|
||||
return this._hide.apply(this, arguments);
|
||||
} else {
|
||||
var args = _normalizeArguments.apply(this, arguments);
|
||||
args[1].mode = 'hide';
|
||||
return this.effect.apply(this, args);
|
||||
}
|
||||
},
|
||||
|
||||
// jQuery core overloads toggle and creates _toggle
|
||||
__toggle: $.fn.toggle,
|
||||
toggle: function(speed) {
|
||||
if ( standardSpeed( speed ) || typeof speed === "boolean" || $.isFunction( speed ) ) {
|
||||
return this.__toggle.apply(this, arguments);
|
||||
} else {
|
||||
var args = _normalizeArguments.apply(this, arguments);
|
||||
args[1].mode = 'toggle';
|
||||
return this.effect.apply(this, args);
|
||||
}
|
||||
},
|
||||
|
||||
// helper functions
|
||||
cssUnit: function(key) {
|
||||
var style = this.css(key), val = [];
|
||||
$.each( ['em','px','%','pt'], function(i, unit){
|
||||
if(style.indexOf(unit) > 0)
|
||||
val = [parseFloat(style), unit];
|
||||
});
|
||||
return val;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/*********************************** EASING ***********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/*
|
||||
* jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
|
||||
*
|
||||
* Uses the built in easing capabilities added In jQuery 1.1
|
||||
* to offer multiple easing options
|
||||
*
|
||||
* TERMS OF USE - jQuery Easing
|
||||
*
|
||||
* Open source under the BSD License.
|
||||
*
|
||||
* Copyright 2008 George McGinley Smith
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the author nor the names of contributors may be used to endorse
|
||||
* or promote products derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
// t: current time, b: begInnIng value, c: change In value, d: duration
|
||||
$.easing.jswing = $.easing.swing;
|
||||
|
||||
$.extend($.easing,
|
||||
{
|
||||
def: 'easeOutQuad',
|
||||
swing: function (x, t, b, c, d) {
|
||||
//alert($.easing.default);
|
||||
return $.easing[$.easing.def](x, t, b, c, d);
|
||||
},
|
||||
easeInQuad: function (x, t, b, c, d) {
|
||||
return c*(t/=d)*t + b;
|
||||
},
|
||||
easeOutQuad: function (x, t, b, c, d) {
|
||||
return -c *(t/=d)*(t-2) + b;
|
||||
},
|
||||
easeInOutQuad: function (x, t, b, c, d) {
|
||||
if ((t/=d/2) < 1) return c/2*t*t + b;
|
||||
return -c/2 * ((--t)*(t-2) - 1) + b;
|
||||
},
|
||||
easeInCubic: function (x, t, b, c, d) {
|
||||
return c*(t/=d)*t*t + b;
|
||||
},
|
||||
easeOutCubic: function (x, t, b, c, d) {
|
||||
return c*((t=t/d-1)*t*t + 1) + b;
|
||||
},
|
||||
easeInOutCubic: function (x, t, b, c, d) {
|
||||
if ((t/=d/2) < 1) return c/2*t*t*t + b;
|
||||
return c/2*((t-=2)*t*t + 2) + b;
|
||||
},
|
||||
easeInQuart: function (x, t, b, c, d) {
|
||||
return c*(t/=d)*t*t*t + b;
|
||||
},
|
||||
easeOutQuart: function (x, t, b, c, d) {
|
||||
return -c * ((t=t/d-1)*t*t*t - 1) + b;
|
||||
},
|
||||
easeInOutQuart: function (x, t, b, c, d) {
|
||||
if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
|
||||
return -c/2 * ((t-=2)*t*t*t - 2) + b;
|
||||
},
|
||||
easeInQuint: function (x, t, b, c, d) {
|
||||
return c*(t/=d)*t*t*t*t + b;
|
||||
},
|
||||
easeOutQuint: function (x, t, b, c, d) {
|
||||
return c*((t=t/d-1)*t*t*t*t + 1) + b;
|
||||
},
|
||||
easeInOutQuint: function (x, t, b, c, d) {
|
||||
if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
|
||||
return c/2*((t-=2)*t*t*t*t + 2) + b;
|
||||
},
|
||||
easeInSine: function (x, t, b, c, d) {
|
||||
return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
|
||||
},
|
||||
easeOutSine: function (x, t, b, c, d) {
|
||||
return c * Math.sin(t/d * (Math.PI/2)) + b;
|
||||
},
|
||||
easeInOutSine: function (x, t, b, c, d) {
|
||||
return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
|
||||
},
|
||||
easeInExpo: function (x, t, b, c, d) {
|
||||
return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
|
||||
},
|
||||
easeOutExpo: function (x, t, b, c, d) {
|
||||
return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
|
||||
},
|
||||
easeInOutExpo: function (x, t, b, c, d) {
|
||||
if (t==0) return b;
|
||||
if (t==d) return b+c;
|
||||
if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
|
||||
return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
|
||||
},
|
||||
easeInCirc: function (x, t, b, c, d) {
|
||||
return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
|
||||
},
|
||||
easeOutCirc: function (x, t, b, c, d) {
|
||||
return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
|
||||
},
|
||||
easeInOutCirc: function (x, t, b, c, d) {
|
||||
if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
|
||||
return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
|
||||
},
|
||||
easeInElastic: function (x, t, b, c, d) {
|
||||
var s=1.70158;var p=0;var a=c;
|
||||
if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
|
||||
if (a < Math.abs(c)) { a=c; var s=p/4; }
|
||||
else var s = p/(2*Math.PI) * Math.asin (c/a);
|
||||
return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
|
||||
},
|
||||
easeOutElastic: function (x, t, b, c, d) {
|
||||
var s=1.70158;var p=0;var a=c;
|
||||
if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
|
||||
if (a < Math.abs(c)) { a=c; var s=p/4; }
|
||||
else var s = p/(2*Math.PI) * Math.asin (c/a);
|
||||
return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
|
||||
},
|
||||
easeInOutElastic: function (x, t, b, c, d) {
|
||||
var s=1.70158;var p=0;var a=c;
|
||||
if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5);
|
||||
if (a < Math.abs(c)) { a=c; var s=p/4; }
|
||||
else var s = p/(2*Math.PI) * Math.asin (c/a);
|
||||
if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
|
||||
return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
|
||||
},
|
||||
easeInBack: function (x, t, b, c, d, s) {
|
||||
if (s == undefined) s = 1.70158;
|
||||
return c*(t/=d)*t*((s+1)*t - s) + b;
|
||||
},
|
||||
easeOutBack: function (x, t, b, c, d, s) {
|
||||
if (s == undefined) s = 1.70158;
|
||||
return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
|
||||
},
|
||||
easeInOutBack: function (x, t, b, c, d, s) {
|
||||
if (s == undefined) s = 1.70158;
|
||||
if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
|
||||
return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
|
||||
},
|
||||
easeInBounce: function (x, t, b, c, d) {
|
||||
return c - $.easing.easeOutBounce (x, d-t, 0, c, d) + b;
|
||||
},
|
||||
easeOutBounce: function (x, t, b, c, d) {
|
||||
if ((t/=d) < (1/2.75)) {
|
||||
return c*(7.5625*t*t) + b;
|
||||
} else if (t < (2/2.75)) {
|
||||
return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
|
||||
} else if (t < (2.5/2.75)) {
|
||||
return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
|
||||
} else {
|
||||
return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
|
||||
}
|
||||
},
|
||||
easeInOutBounce: function (x, t, b, c, d) {
|
||||
if (t < d/2) return $.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
|
||||
return $.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
*
|
||||
* TERMS OF USE - EASING EQUATIONS
|
||||
*
|
||||
* Open source under the BSD License.
|
||||
*
|
||||
* Copyright 2001 Robert Penner
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the author nor the names of contributors may be used to endorse
|
||||
* or promote products derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
})(jQuery);
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* jQuery UI Effects Highlight 1.8.16
|
||||
*
|
||||
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Effects/Highlight
|
||||
*
|
||||
* Depends:
|
||||
* jquery.effects.core.js
|
||||
*/
|
||||
(function( $, undefined ) {
|
||||
|
||||
$.effects.highlight = function(o) {
|
||||
return this.queue(function() {
|
||||
var elem = $(this),
|
||||
props = ['backgroundImage', 'backgroundColor', 'opacity'],
|
||||
mode = $.effects.setMode(elem, o.options.mode || 'show'),
|
||||
animation = {
|
||||
backgroundColor: elem.css('backgroundColor')
|
||||
};
|
||||
|
||||
if (mode == 'hide') {
|
||||
animation.opacity = 0;
|
||||
}
|
||||
|
||||
$.effects.save(elem, props);
|
||||
elem
|
||||
.show()
|
||||
.css({
|
||||
backgroundImage: 'none',
|
||||
backgroundColor: o.options.color || '#ffff99'
|
||||
})
|
||||
.animate(animation, {
|
||||
queue: false,
|
||||
duration: o.duration,
|
||||
easing: o.options.easing,
|
||||
complete: function() {
|
||||
(mode == 'hide' && elem.hide());
|
||||
$.effects.restore(elem, props);
|
||||
(mode == 'show' && !$.support.opacity && this.style.removeAttribute('filter'));
|
||||
(o.callback && o.callback.apply(this, arguments));
|
||||
elem.dequeue();
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
|
|
@ -6,10 +6,15 @@
|
|||
{{ block.super }}
|
||||
{% url 'admin:jsi18n' as jsi18nurl %}
|
||||
|
||||
{% if has_sortable_tabular_inlines %}
|
||||
{% if has_sortable_tabular_inlines or has_sortable_stacked_inlines %}
|
||||
{% include 'adminsortable/shared/javascript_includes.html' %}
|
||||
{% endif %}
|
||||
{% if has_sortable_tabular_inlines %}
|
||||
<script type="text/javascript" src="{{ STATIC_URL }}adminsortable/js/admin.sortable.tabular.inlines.js"></script>
|
||||
{% endif %}
|
||||
{% if has_sortable_stacked_inlines %}
|
||||
<script type="text/javascript" src="{{ STATIC_URL }}adminsortable/js/jquery.effects.core.js"></script>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block extrastyle %}
|
||||
|
|
@ -18,4 +23,5 @@
|
|||
{% if has_sortable_tabular_inlines %}
|
||||
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}adminsortable/css/admin.sortable.tabular.inline.css" />
|
||||
{% endif %}
|
||||
|
||||
{% endblock %}
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
{% load i18n adminmedia %}
|
||||
<div class="inline-group" id="{{ inline_admin_formset.formset.prefix }}-group">
|
||||
<h2>{{ inline_admin_formset.opts.verbose_name_plural|title }} {% if inline_admin_formset.opts.is_sortable %} - drag and drop to change order{% endif %}</h2>
|
||||
{{ inline_admin_formset.formset.management_form }}
|
||||
{{ inline_admin_formset.formset.non_form_errors }}
|
||||
|
||||
{% for inline_admin_form in inline_admin_formset %}<div class="inline-related{% if forloop.last %} empty-form last-related{% endif %}" id="{{ inline_admin_formset.formset.prefix }}-{% if not forloop.last %}{{ forloop.counter0 }}{% else %}empty{% endif %}">
|
||||
<h3><b>{{ inline_admin_formset.opts.verbose_name|title }}:</b> <span class="inline_label">{% if inline_admin_form.original %}{{ inline_admin_form.original }}{% else %}#{{ forloop.counter }}{% endif %}</span>
|
||||
{% if inline_admin_form.show_url %}<a href="../../../r/{{ inline_admin_form.original_content_type_id }}/{{ inline_admin_form.original.id }}/">{% trans "View on site" %}</a>{% endif %}
|
||||
{% if inline_admin_formset.formset.can_delete and inline_admin_form.original %}<span class="delete">{{ inline_admin_form.deletion_field.field }} {{ inline_admin_form.deletion_field.label_tag }}</span>{% endif %}
|
||||
</h3>
|
||||
{% if inline_admin_form.form.non_field_errors %}{{ inline_admin_form.form.non_field_errors }}{% endif %}
|
||||
{% for fieldset in inline_admin_form %}
|
||||
{% include "admin/includes/fieldset.html" %}
|
||||
{% endfor %}
|
||||
{% if inline_admin_form.has_auto_field %}{{ inline_admin_form.pk_field.field }}{% endif %}
|
||||
{{ inline_admin_form.fk_field.field }}
|
||||
{% if inline_admin_form.original %}
|
||||
<input type="hidden" name="admin_sorting_url" value="{% url admin:admin_do_sorting inline_admin_form.original.model_type_id %}" />
|
||||
{% endif %}
|
||||
</div>{% endfor %}
|
||||
</div>
|
||||
|
||||
<script type="text/javascript">
|
||||
(function($) {
|
||||
$(document).ready(function() {
|
||||
var rows = "#{{ inline_admin_formset.formset.prefix }}-group .inline-related";
|
||||
var updateInlineLabel = function(row) {
|
||||
$(rows).find(".inline_label").each(function(i) {
|
||||
var count = i + 1;
|
||||
$(this).html($(this).html().replace(/(#\d+)/g, "#" + count));
|
||||
});
|
||||
}
|
||||
var reinitDateTimeShortCuts = function() {
|
||||
// Reinitialize the calendar and clock widgets by force, yuck.
|
||||
if (typeof DateTimeShortcuts != "undefined") {
|
||||
$(".datetimeshortcuts").remove();
|
||||
DateTimeShortcuts.init();
|
||||
}
|
||||
}
|
||||
var updateSelectFilter = function() {
|
||||
// If any SelectFilter widgets were added, instantiate a new instance.
|
||||
if (typeof SelectFilter != "undefined"){
|
||||
$(".selectfilter").each(function(index, value){
|
||||
var namearr = value.name.split('-');
|
||||
SelectFilter.init(value.id, namearr[namearr.length-1], false, "{% admin_media_prefix %}");
|
||||
});
|
||||
$(".selectfilterstacked").each(function(index, value){
|
||||
var namearr = value.name.split('-');
|
||||
SelectFilter.init(value.id, namearr[namearr.length-1], true, "{% admin_media_prefix %}");
|
||||
});
|
||||
}
|
||||
}
|
||||
var initPrepopulatedFields = function(row) {
|
||||
row.find('.prepopulated_field').each(function() {
|
||||
var field = $(this);
|
||||
var input = field.find('input, select, textarea');
|
||||
var dependency_list = input.data('dependency_list') || [];
|
||||
var dependencies = [];
|
||||
$.each(dependency_list, function(i, field_name) {
|
||||
dependencies.push('#' + row.find(field_name).find('input, select, textarea').attr('id'));
|
||||
});
|
||||
if (dependencies.length) {
|
||||
input.prepopulate(dependencies, input.attr('maxlength'));
|
||||
}
|
||||
});
|
||||
}
|
||||
$(rows).formset({
|
||||
prefix: "{{ inline_admin_formset.formset.prefix }}",
|
||||
addText: "{% blocktrans with inline_admin_formset.opts.verbose_name|title as verbose_name %}Add another {{ verbose_name }}{% endblocktrans %}",
|
||||
formCssClass: "dynamic-{{ inline_admin_formset.formset.prefix }}",
|
||||
deleteCssClass: "inline-deletelink",
|
||||
deleteText: "{% trans "Remove" %}",
|
||||
emptyCssClass: "empty-form",
|
||||
removed: updateInlineLabel,
|
||||
added: (function(row) {
|
||||
initPrepopulatedFields(row);
|
||||
reinitDateTimeShortCuts();
|
||||
updateSelectFilter();
|
||||
updateInlineLabel(row);
|
||||
})
|
||||
});
|
||||
});
|
||||
})(django.jQuery);
|
||||
</script>
|
||||
|
|
@ -5,4 +5,6 @@
|
|||
<script type="text/javascript" src="{{ STATIC_URL }}adminsortable/js/jquery.ui.draggable.js"></script>
|
||||
<script type="text/javascript" src="{{ STATIC_URL }}adminsortable/js/jquery.ui.droppable.js"></script>
|
||||
<script type="text/javascript" src="{{ STATIC_URL }}adminsortable/js/jquery.ui.sortable.js"></script>
|
||||
<script type="text/javascript" src="{{ STATIC_URL }}adminsortable/js/jquery.effects.highlight.js"></script>
|
||||
<script type="text/javascript" src="{{ STATIC_URL }}adminsortable/js/admin.sortable.stacked.inlines.js"></script>
|
||||
<script type="text/javascript" src="{{ STATIC_URL }}adminsortable/js/admin.sortable.js"></script>
|
||||
Binary file not shown.
|
|
@ -1,7 +1,7 @@
|
|||
from django.contrib import admin
|
||||
|
||||
from adminsortable.admin import SortableAdmin, SortableTabularInline
|
||||
from app.models import Category, Project, Credit
|
||||
from adminsortable.admin import SortableAdmin, SortableTabularInline, SortableStackedInline
|
||||
from app.models import Category, Project, Credit, Note
|
||||
|
||||
|
||||
admin.site.register(Category, SortableAdmin)
|
||||
|
|
@ -11,8 +11,12 @@ class CreditInline(SortableTabularInline):
|
|||
model = Credit
|
||||
|
||||
|
||||
class NoteInline(SortableStackedInline):
|
||||
model = Note
|
||||
|
||||
|
||||
class ProjectAdmin(SortableAdmin):
|
||||
inlines = [CreditInline]
|
||||
inlines = [CreditInline, NoteInline]
|
||||
list_display = ['__unicode__', 'category']
|
||||
|
||||
admin.site.register(Project, ProjectAdmin)
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -0,0 +1,59 @@
|
|||
# encoding: utf-8
|
||||
import datetime
|
||||
from south.db import db
|
||||
from south.v2 import SchemaMigration
|
||||
from django.db import models
|
||||
|
||||
class Migration(SchemaMigration):
|
||||
|
||||
def forwards(self, orm):
|
||||
|
||||
# Adding model 'Note'
|
||||
db.create_table('app_note', (
|
||||
('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
|
||||
('order', self.gf('django.db.models.fields.PositiveIntegerField')(default=1, db_index=True)),
|
||||
('project', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['app.Project'])),
|
||||
('text', self.gf('django.db.models.fields.CharField')(max_length=100)),
|
||||
))
|
||||
db.send_create_signal('app', ['Note'])
|
||||
|
||||
|
||||
def backwards(self, orm):
|
||||
|
||||
# Deleting model 'Note'
|
||||
db.delete_table('app_note')
|
||||
|
||||
|
||||
models = {
|
||||
'app.category': {
|
||||
'Meta': {'ordering': "['order', 'id']", 'object_name': 'Category'},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'order': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1', 'db_index': 'True'}),
|
||||
'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
},
|
||||
'app.credit': {
|
||||
'Meta': {'ordering': "['order', 'id']", 'object_name': 'Credit'},
|
||||
'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30'}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30'}),
|
||||
'order': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1', 'db_index': 'True'}),
|
||||
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['app.Project']"})
|
||||
},
|
||||
'app.note': {
|
||||
'Meta': {'ordering': "['order', 'id']", 'object_name': 'Note'},
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'order': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1', 'db_index': 'True'}),
|
||||
'project': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['app.Project']"}),
|
||||
'text': ('django.db.models.fields.CharField', [], {'max_length': '100'})
|
||||
},
|
||||
'app.project': {
|
||||
'Meta': {'ordering': "['order', 'id']", 'object_name': 'Project'},
|
||||
'category': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['app.Category']"}),
|
||||
'description': ('django.db.models.fields.TextField', [], {}),
|
||||
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
|
||||
'order': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1', 'db_index': 'True'}),
|
||||
'title': ('django.db.models.fields.CharField', [], {'max_length': '50'})
|
||||
}
|
||||
}
|
||||
|
||||
complete_apps = ['app']
|
||||
Binary file not shown.
|
|
@ -37,8 +37,11 @@ class Project(SimpleModel, Sortable):
|
|||
description = models.TextField()
|
||||
|
||||
|
||||
#registered as an inline on project
|
||||
#registered as a tabular inline on project
|
||||
class Credit(Sortable):
|
||||
class Meta(Sortable.Meta):
|
||||
pass
|
||||
|
||||
project = models.ForeignKey(Project)
|
||||
first_name = models.CharField(max_length=30)
|
||||
last_name = models.CharField(max_length=30)
|
||||
|
|
@ -46,3 +49,14 @@ class Credit(Sortable):
|
|||
def __unicode__(self):
|
||||
return '%s %s' % (self.first_name, self.last_name)
|
||||
|
||||
|
||||
#registered as a stacked inline on project
|
||||
class Note(Sortable):
|
||||
class Meta(Sortable.Meta):
|
||||
pass
|
||||
|
||||
project = models.ForeignKey(Project)
|
||||
text = models.CharField(max_length=100)
|
||||
|
||||
def __unicode__(self):
|
||||
return self.text
|
||||
|
|
|
|||
Binary file not shown.
|
|
@ -0,0 +1,32 @@
|
|||
jQuery(function($){
|
||||
if ($(':hidden[name="admin_sorting_url"]').length > 0)
|
||||
{
|
||||
$('.inline-group').sortable({
|
||||
axis : 'y',
|
||||
containment : 'parent',
|
||||
tolerance : 'pointer',
|
||||
items : '.inline-related',
|
||||
stop : function(event, ui)
|
||||
{
|
||||
var indexes = Array();
|
||||
ui.item.parent().children('.inline-related').each(function(i)
|
||||
{
|
||||
index_value = $(this).find(':hidden[name$="-id"]').val();
|
||||
if (index_value != "" && index_value != undefined)
|
||||
indexes.push(index_value);
|
||||
});
|
||||
|
||||
$.ajax({
|
||||
url: ui.item.parent().find(':hidden[name="admin_sorting_url"]').val(),
|
||||
type: 'POST',
|
||||
data: { indexes : indexes.join(',') },
|
||||
success: function()
|
||||
{
|
||||
//highlight sorted stacked inline
|
||||
ui.item.parent().effect('highlight', {}, 1000);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
|
@ -0,0 +1,763 @@
|
|||
/*
|
||||
* jQuery UI Effects 1.8.16
|
||||
*
|
||||
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Effects/
|
||||
*/
|
||||
;jQuery.effects || (function($, undefined) {
|
||||
|
||||
$.effects = {};
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/****************************** COLOR ANIMATIONS ******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
// override the animation for color styles
|
||||
$.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor',
|
||||
'borderRightColor', 'borderTopColor', 'borderColor', 'color', 'outlineColor'],
|
||||
function(i, attr) {
|
||||
$.fx.step[attr] = function(fx) {
|
||||
if (!fx.colorInit) {
|
||||
fx.start = getColor(fx.elem, attr);
|
||||
fx.end = getRGB(fx.end);
|
||||
fx.colorInit = true;
|
||||
}
|
||||
|
||||
fx.elem.style[attr] = 'rgb(' +
|
||||
Math.max(Math.min(parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0], 10), 255), 0) + ',' +
|
||||
Math.max(Math.min(parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1], 10), 255), 0) + ',' +
|
||||
Math.max(Math.min(parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2], 10), 255), 0) + ')';
|
||||
};
|
||||
});
|
||||
|
||||
// Color Conversion functions from highlightFade
|
||||
// By Blair Mitchelmore
|
||||
// http://jquery.offput.ca/highlightFade/
|
||||
|
||||
// Parse strings looking for color tuples [255,255,255]
|
||||
function getRGB(color) {
|
||||
var result;
|
||||
|
||||
// Check if we're already dealing with an array of colors
|
||||
if ( color && color.constructor == Array && color.length == 3 )
|
||||
return color;
|
||||
|
||||
// Look for rgb(num,num,num)
|
||||
if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color))
|
||||
return [parseInt(result[1],10), parseInt(result[2],10), parseInt(result[3],10)];
|
||||
|
||||
// Look for rgb(num%,num%,num%)
|
||||
if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color))
|
||||
return [parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55];
|
||||
|
||||
// Look for #a0b1c2
|
||||
if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color))
|
||||
return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)];
|
||||
|
||||
// Look for #fff
|
||||
if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color))
|
||||
return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)];
|
||||
|
||||
// Look for rgba(0, 0, 0, 0) == transparent in Safari 3
|
||||
if (result = /rgba\(0, 0, 0, 0\)/.exec(color))
|
||||
return colors['transparent'];
|
||||
|
||||
// Otherwise, we're most likely dealing with a named color
|
||||
return colors[$.trim(color).toLowerCase()];
|
||||
}
|
||||
|
||||
function getColor(elem, attr) {
|
||||
var color;
|
||||
|
||||
do {
|
||||
color = $.curCSS(elem, attr);
|
||||
|
||||
// Keep going until we find an element that has color, or we hit the body
|
||||
if ( color != '' && color != 'transparent' || $.nodeName(elem, "body") )
|
||||
break;
|
||||
|
||||
attr = "backgroundColor";
|
||||
} while ( elem = elem.parentNode );
|
||||
|
||||
return getRGB(color);
|
||||
};
|
||||
|
||||
// Some named colors to work with
|
||||
// From Interface by Stefan Petre
|
||||
// http://interface.eyecon.ro/
|
||||
|
||||
var colors = {
|
||||
aqua:[0,255,255],
|
||||
azure:[240,255,255],
|
||||
beige:[245,245,220],
|
||||
black:[0,0,0],
|
||||
blue:[0,0,255],
|
||||
brown:[165,42,42],
|
||||
cyan:[0,255,255],
|
||||
darkblue:[0,0,139],
|
||||
darkcyan:[0,139,139],
|
||||
darkgrey:[169,169,169],
|
||||
darkgreen:[0,100,0],
|
||||
darkkhaki:[189,183,107],
|
||||
darkmagenta:[139,0,139],
|
||||
darkolivegreen:[85,107,47],
|
||||
darkorange:[255,140,0],
|
||||
darkorchid:[153,50,204],
|
||||
darkred:[139,0,0],
|
||||
darksalmon:[233,150,122],
|
||||
darkviolet:[148,0,211],
|
||||
fuchsia:[255,0,255],
|
||||
gold:[255,215,0],
|
||||
green:[0,128,0],
|
||||
indigo:[75,0,130],
|
||||
khaki:[240,230,140],
|
||||
lightblue:[173,216,230],
|
||||
lightcyan:[224,255,255],
|
||||
lightgreen:[144,238,144],
|
||||
lightgrey:[211,211,211],
|
||||
lightpink:[255,182,193],
|
||||
lightyellow:[255,255,224],
|
||||
lime:[0,255,0],
|
||||
magenta:[255,0,255],
|
||||
maroon:[128,0,0],
|
||||
navy:[0,0,128],
|
||||
olive:[128,128,0],
|
||||
orange:[255,165,0],
|
||||
pink:[255,192,203],
|
||||
purple:[128,0,128],
|
||||
violet:[128,0,128],
|
||||
red:[255,0,0],
|
||||
silver:[192,192,192],
|
||||
white:[255,255,255],
|
||||
yellow:[255,255,0],
|
||||
transparent: [255,255,255]
|
||||
};
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/****************************** CLASS ANIMATIONS ******************************/
|
||||
/******************************************************************************/
|
||||
|
||||
var classAnimationActions = ['add', 'remove', 'toggle'],
|
||||
shorthandStyles = {
|
||||
border: 1,
|
||||
borderBottom: 1,
|
||||
borderColor: 1,
|
||||
borderLeft: 1,
|
||||
borderRight: 1,
|
||||
borderTop: 1,
|
||||
borderWidth: 1,
|
||||
margin: 1,
|
||||
padding: 1
|
||||
};
|
||||
|
||||
function getElementStyles() {
|
||||
var style = document.defaultView
|
||||
? document.defaultView.getComputedStyle(this, null)
|
||||
: this.currentStyle,
|
||||
newStyle = {},
|
||||
key,
|
||||
camelCase;
|
||||
|
||||
// webkit enumerates style porperties
|
||||
if (style && style.length && style[0] && style[style[0]]) {
|
||||
var len = style.length;
|
||||
while (len--) {
|
||||
key = style[len];
|
||||
if (typeof style[key] == 'string') {
|
||||
camelCase = key.replace(/\-(\w)/g, function(all, letter){
|
||||
return letter.toUpperCase();
|
||||
});
|
||||
newStyle[camelCase] = style[key];
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (key in style) {
|
||||
if (typeof style[key] === 'string') {
|
||||
newStyle[key] = style[key];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return newStyle;
|
||||
}
|
||||
|
||||
function filterStyles(styles) {
|
||||
var name, value;
|
||||
for (name in styles) {
|
||||
value = styles[name];
|
||||
if (
|
||||
// ignore null and undefined values
|
||||
value == null ||
|
||||
// ignore functions (when does this occur?)
|
||||
$.isFunction(value) ||
|
||||
// shorthand styles that need to be expanded
|
||||
name in shorthandStyles ||
|
||||
// ignore scrollbars (break in IE)
|
||||
(/scrollbar/).test(name) ||
|
||||
|
||||
// only colors or values that can be converted to numbers
|
||||
(!(/color/i).test(name) && isNaN(parseFloat(value)))
|
||||
) {
|
||||
delete styles[name];
|
||||
}
|
||||
}
|
||||
|
||||
return styles;
|
||||
}
|
||||
|
||||
function styleDifference(oldStyle, newStyle) {
|
||||
var diff = { _: 0 }, // http://dev.jquery.com/ticket/5459
|
||||
name;
|
||||
|
||||
for (name in newStyle) {
|
||||
if (oldStyle[name] != newStyle[name]) {
|
||||
diff[name] = newStyle[name];
|
||||
}
|
||||
}
|
||||
|
||||
return diff;
|
||||
}
|
||||
|
||||
$.effects.animateClass = function(value, duration, easing, callback) {
|
||||
if ($.isFunction(easing)) {
|
||||
callback = easing;
|
||||
easing = null;
|
||||
}
|
||||
|
||||
return this.queue(function() {
|
||||
var that = $(this),
|
||||
originalStyleAttr = that.attr('style') || ' ',
|
||||
originalStyle = filterStyles(getElementStyles.call(this)),
|
||||
newStyle,
|
||||
className = that.attr('class');
|
||||
|
||||
$.each(classAnimationActions, function(i, action) {
|
||||
if (value[action]) {
|
||||
that[action + 'Class'](value[action]);
|
||||
}
|
||||
});
|
||||
newStyle = filterStyles(getElementStyles.call(this));
|
||||
that.attr('class', className);
|
||||
|
||||
that.animate(styleDifference(originalStyle, newStyle), {
|
||||
queue: false,
|
||||
duration: duration,
|
||||
easing: easing,
|
||||
complete: function() {
|
||||
$.each(classAnimationActions, function(i, action) {
|
||||
if (value[action]) { that[action + 'Class'](value[action]); }
|
||||
});
|
||||
// work around bug in IE by clearing the cssText before setting it
|
||||
if (typeof that.attr('style') == 'object') {
|
||||
that.attr('style').cssText = '';
|
||||
that.attr('style').cssText = originalStyleAttr;
|
||||
} else {
|
||||
that.attr('style', originalStyleAttr);
|
||||
}
|
||||
if (callback) { callback.apply(this, arguments); }
|
||||
$.dequeue( this );
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
$.fn.extend({
|
||||
_addClass: $.fn.addClass,
|
||||
addClass: function(classNames, speed, easing, callback) {
|
||||
return speed ? $.effects.animateClass.apply(this, [{ add: classNames },speed,easing,callback]) : this._addClass(classNames);
|
||||
},
|
||||
|
||||
_removeClass: $.fn.removeClass,
|
||||
removeClass: function(classNames,speed,easing,callback) {
|
||||
return speed ? $.effects.animateClass.apply(this, [{ remove: classNames },speed,easing,callback]) : this._removeClass(classNames);
|
||||
},
|
||||
|
||||
_toggleClass: $.fn.toggleClass,
|
||||
toggleClass: function(classNames, force, speed, easing, callback) {
|
||||
if ( typeof force == "boolean" || force === undefined ) {
|
||||
if ( !speed ) {
|
||||
// without speed parameter;
|
||||
return this._toggleClass(classNames, force);
|
||||
} else {
|
||||
return $.effects.animateClass.apply(this, [(force?{add:classNames}:{remove:classNames}),speed,easing,callback]);
|
||||
}
|
||||
} else {
|
||||
// without switch parameter;
|
||||
return $.effects.animateClass.apply(this, [{ toggle: classNames },force,speed,easing]);
|
||||
}
|
||||
},
|
||||
|
||||
switchClass: function(remove,add,speed,easing,callback) {
|
||||
return $.effects.animateClass.apply(this, [{ add: add, remove: remove },speed,easing,callback]);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/*********************************** EFFECTS **********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
$.extend($.effects, {
|
||||
version: "1.8.16",
|
||||
|
||||
// Saves a set of properties in a data storage
|
||||
save: function(element, set) {
|
||||
for(var i=0; i < set.length; i++) {
|
||||
if(set[i] !== null) element.data("ec.storage."+set[i], element[0].style[set[i]]);
|
||||
}
|
||||
},
|
||||
|
||||
// Restores a set of previously saved properties from a data storage
|
||||
restore: function(element, set) {
|
||||
for(var i=0; i < set.length; i++) {
|
||||
if(set[i] !== null) element.css(set[i], element.data("ec.storage."+set[i]));
|
||||
}
|
||||
},
|
||||
|
||||
setMode: function(el, mode) {
|
||||
if (mode == 'toggle') mode = el.is(':hidden') ? 'show' : 'hide'; // Set for toggle
|
||||
return mode;
|
||||
},
|
||||
|
||||
getBaseline: function(origin, original) { // Translates a [top,left] array into a baseline value
|
||||
// this should be a little more flexible in the future to handle a string & hash
|
||||
var y, x;
|
||||
switch (origin[0]) {
|
||||
case 'top': y = 0; break;
|
||||
case 'middle': y = 0.5; break;
|
||||
case 'bottom': y = 1; break;
|
||||
default: y = origin[0] / original.height;
|
||||
};
|
||||
switch (origin[1]) {
|
||||
case 'left': x = 0; break;
|
||||
case 'center': x = 0.5; break;
|
||||
case 'right': x = 1; break;
|
||||
default: x = origin[1] / original.width;
|
||||
};
|
||||
return {x: x, y: y};
|
||||
},
|
||||
|
||||
// Wraps the element around a wrapper that copies position properties
|
||||
createWrapper: function(element) {
|
||||
|
||||
// if the element is already wrapped, return it
|
||||
if (element.parent().is('.ui-effects-wrapper')) {
|
||||
return element.parent();
|
||||
}
|
||||
|
||||
// wrap the element
|
||||
var props = {
|
||||
width: element.outerWidth(true),
|
||||
height: element.outerHeight(true),
|
||||
'float': element.css('float')
|
||||
},
|
||||
wrapper = $('<div></div>')
|
||||
.addClass('ui-effects-wrapper')
|
||||
.css({
|
||||
fontSize: '100%',
|
||||
background: 'transparent',
|
||||
border: 'none',
|
||||
margin: 0,
|
||||
padding: 0
|
||||
}),
|
||||
active = document.activeElement;
|
||||
|
||||
element.wrap(wrapper);
|
||||
|
||||
// Fixes #7595 - Elements lose focus when wrapped.
|
||||
if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
|
||||
$( active ).focus();
|
||||
}
|
||||
|
||||
wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually loose the reference to the wrapped element
|
||||
|
||||
// transfer positioning properties to the wrapper
|
||||
if (element.css('position') == 'static') {
|
||||
wrapper.css({ position: 'relative' });
|
||||
element.css({ position: 'relative' });
|
||||
} else {
|
||||
$.extend(props, {
|
||||
position: element.css('position'),
|
||||
zIndex: element.css('z-index')
|
||||
});
|
||||
$.each(['top', 'left', 'bottom', 'right'], function(i, pos) {
|
||||
props[pos] = element.css(pos);
|
||||
if (isNaN(parseInt(props[pos], 10))) {
|
||||
props[pos] = 'auto';
|
||||
}
|
||||
});
|
||||
element.css({position: 'relative', top: 0, left: 0, right: 'auto', bottom: 'auto' });
|
||||
}
|
||||
|
||||
return wrapper.css(props).show();
|
||||
},
|
||||
|
||||
removeWrapper: function(element) {
|
||||
var parent,
|
||||
active = document.activeElement;
|
||||
|
||||
if (element.parent().is('.ui-effects-wrapper')) {
|
||||
parent = element.parent().replaceWith(element);
|
||||
// Fixes #7595 - Elements lose focus when wrapped.
|
||||
if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
|
||||
$( active ).focus();
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
|
||||
return element;
|
||||
},
|
||||
|
||||
setTransition: function(element, list, factor, value) {
|
||||
value = value || {};
|
||||
$.each(list, function(i, x){
|
||||
unit = element.cssUnit(x);
|
||||
if (unit[0] > 0) value[x] = unit[0] * factor + unit[1];
|
||||
});
|
||||
return value;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
function _normalizeArguments(effect, options, speed, callback) {
|
||||
// shift params for method overloading
|
||||
if (typeof effect == 'object') {
|
||||
callback = options;
|
||||
speed = null;
|
||||
options = effect;
|
||||
effect = options.effect;
|
||||
}
|
||||
if ($.isFunction(options)) {
|
||||
callback = options;
|
||||
speed = null;
|
||||
options = {};
|
||||
}
|
||||
if (typeof options == 'number' || $.fx.speeds[options]) {
|
||||
callback = speed;
|
||||
speed = options;
|
||||
options = {};
|
||||
}
|
||||
if ($.isFunction(speed)) {
|
||||
callback = speed;
|
||||
speed = null;
|
||||
}
|
||||
|
||||
options = options || {};
|
||||
|
||||
speed = speed || options.duration;
|
||||
speed = $.fx.off ? 0 : typeof speed == 'number'
|
||||
? speed : speed in $.fx.speeds ? $.fx.speeds[speed] : $.fx.speeds._default;
|
||||
|
||||
callback = callback || options.complete;
|
||||
|
||||
return [effect, options, speed, callback];
|
||||
}
|
||||
|
||||
function standardSpeed( speed ) {
|
||||
// valid standard speeds
|
||||
if ( !speed || typeof speed === "number" || $.fx.speeds[ speed ] ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// invalid strings - treat as "normal" speed
|
||||
if ( typeof speed === "string" && !$.effects[ speed ] ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
$.fn.extend({
|
||||
effect: function(effect, options, speed, callback) {
|
||||
var args = _normalizeArguments.apply(this, arguments),
|
||||
// TODO: make effects take actual parameters instead of a hash
|
||||
args2 = {
|
||||
options: args[1],
|
||||
duration: args[2],
|
||||
callback: args[3]
|
||||
},
|
||||
mode = args2.options.mode,
|
||||
effectMethod = $.effects[effect];
|
||||
|
||||
if ( $.fx.off || !effectMethod ) {
|
||||
// delegate to the original method (e.g., .show()) if possible
|
||||
if ( mode ) {
|
||||
return this[ mode ]( args2.duration, args2.callback );
|
||||
} else {
|
||||
return this.each(function() {
|
||||
if ( args2.callback ) {
|
||||
args2.callback.call( this );
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return effectMethod.call(this, args2);
|
||||
},
|
||||
|
||||
_show: $.fn.show,
|
||||
show: function(speed) {
|
||||
if ( standardSpeed( speed ) ) {
|
||||
return this._show.apply(this, arguments);
|
||||
} else {
|
||||
var args = _normalizeArguments.apply(this, arguments);
|
||||
args[1].mode = 'show';
|
||||
return this.effect.apply(this, args);
|
||||
}
|
||||
},
|
||||
|
||||
_hide: $.fn.hide,
|
||||
hide: function(speed) {
|
||||
if ( standardSpeed( speed ) ) {
|
||||
return this._hide.apply(this, arguments);
|
||||
} else {
|
||||
var args = _normalizeArguments.apply(this, arguments);
|
||||
args[1].mode = 'hide';
|
||||
return this.effect.apply(this, args);
|
||||
}
|
||||
},
|
||||
|
||||
// jQuery core overloads toggle and creates _toggle
|
||||
__toggle: $.fn.toggle,
|
||||
toggle: function(speed) {
|
||||
if ( standardSpeed( speed ) || typeof speed === "boolean" || $.isFunction( speed ) ) {
|
||||
return this.__toggle.apply(this, arguments);
|
||||
} else {
|
||||
var args = _normalizeArguments.apply(this, arguments);
|
||||
args[1].mode = 'toggle';
|
||||
return this.effect.apply(this, args);
|
||||
}
|
||||
},
|
||||
|
||||
// helper functions
|
||||
cssUnit: function(key) {
|
||||
var style = this.css(key), val = [];
|
||||
$.each( ['em','px','%','pt'], function(i, unit){
|
||||
if(style.indexOf(unit) > 0)
|
||||
val = [parseFloat(style), unit];
|
||||
});
|
||||
return val;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
/******************************************************************************/
|
||||
/*********************************** EASING ***********************************/
|
||||
/******************************************************************************/
|
||||
|
||||
/*
|
||||
* jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
|
||||
*
|
||||
* Uses the built in easing capabilities added In jQuery 1.1
|
||||
* to offer multiple easing options
|
||||
*
|
||||
* TERMS OF USE - jQuery Easing
|
||||
*
|
||||
* Open source under the BSD License.
|
||||
*
|
||||
* Copyright 2008 George McGinley Smith
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the author nor the names of contributors may be used to endorse
|
||||
* or promote products derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
// t: current time, b: begInnIng value, c: change In value, d: duration
|
||||
$.easing.jswing = $.easing.swing;
|
||||
|
||||
$.extend($.easing,
|
||||
{
|
||||
def: 'easeOutQuad',
|
||||
swing: function (x, t, b, c, d) {
|
||||
//alert($.easing.default);
|
||||
return $.easing[$.easing.def](x, t, b, c, d);
|
||||
},
|
||||
easeInQuad: function (x, t, b, c, d) {
|
||||
return c*(t/=d)*t + b;
|
||||
},
|
||||
easeOutQuad: function (x, t, b, c, d) {
|
||||
return -c *(t/=d)*(t-2) + b;
|
||||
},
|
||||
easeInOutQuad: function (x, t, b, c, d) {
|
||||
if ((t/=d/2) < 1) return c/2*t*t + b;
|
||||
return -c/2 * ((--t)*(t-2) - 1) + b;
|
||||
},
|
||||
easeInCubic: function (x, t, b, c, d) {
|
||||
return c*(t/=d)*t*t + b;
|
||||
},
|
||||
easeOutCubic: function (x, t, b, c, d) {
|
||||
return c*((t=t/d-1)*t*t + 1) + b;
|
||||
},
|
||||
easeInOutCubic: function (x, t, b, c, d) {
|
||||
if ((t/=d/2) < 1) return c/2*t*t*t + b;
|
||||
return c/2*((t-=2)*t*t + 2) + b;
|
||||
},
|
||||
easeInQuart: function (x, t, b, c, d) {
|
||||
return c*(t/=d)*t*t*t + b;
|
||||
},
|
||||
easeOutQuart: function (x, t, b, c, d) {
|
||||
return -c * ((t=t/d-1)*t*t*t - 1) + b;
|
||||
},
|
||||
easeInOutQuart: function (x, t, b, c, d) {
|
||||
if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
|
||||
return -c/2 * ((t-=2)*t*t*t - 2) + b;
|
||||
},
|
||||
easeInQuint: function (x, t, b, c, d) {
|
||||
return c*(t/=d)*t*t*t*t + b;
|
||||
},
|
||||
easeOutQuint: function (x, t, b, c, d) {
|
||||
return c*((t=t/d-1)*t*t*t*t + 1) + b;
|
||||
},
|
||||
easeInOutQuint: function (x, t, b, c, d) {
|
||||
if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
|
||||
return c/2*((t-=2)*t*t*t*t + 2) + b;
|
||||
},
|
||||
easeInSine: function (x, t, b, c, d) {
|
||||
return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
|
||||
},
|
||||
easeOutSine: function (x, t, b, c, d) {
|
||||
return c * Math.sin(t/d * (Math.PI/2)) + b;
|
||||
},
|
||||
easeInOutSine: function (x, t, b, c, d) {
|
||||
return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
|
||||
},
|
||||
easeInExpo: function (x, t, b, c, d) {
|
||||
return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
|
||||
},
|
||||
easeOutExpo: function (x, t, b, c, d) {
|
||||
return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
|
||||
},
|
||||
easeInOutExpo: function (x, t, b, c, d) {
|
||||
if (t==0) return b;
|
||||
if (t==d) return b+c;
|
||||
if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
|
||||
return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
|
||||
},
|
||||
easeInCirc: function (x, t, b, c, d) {
|
||||
return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
|
||||
},
|
||||
easeOutCirc: function (x, t, b, c, d) {
|
||||
return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
|
||||
},
|
||||
easeInOutCirc: function (x, t, b, c, d) {
|
||||
if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
|
||||
return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
|
||||
},
|
||||
easeInElastic: function (x, t, b, c, d) {
|
||||
var s=1.70158;var p=0;var a=c;
|
||||
if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
|
||||
if (a < Math.abs(c)) { a=c; var s=p/4; }
|
||||
else var s = p/(2*Math.PI) * Math.asin (c/a);
|
||||
return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
|
||||
},
|
||||
easeOutElastic: function (x, t, b, c, d) {
|
||||
var s=1.70158;var p=0;var a=c;
|
||||
if (t==0) return b; if ((t/=d)==1) return b+c; if (!p) p=d*.3;
|
||||
if (a < Math.abs(c)) { a=c; var s=p/4; }
|
||||
else var s = p/(2*Math.PI) * Math.asin (c/a);
|
||||
return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
|
||||
},
|
||||
easeInOutElastic: function (x, t, b, c, d) {
|
||||
var s=1.70158;var p=0;var a=c;
|
||||
if (t==0) return b; if ((t/=d/2)==2) return b+c; if (!p) p=d*(.3*1.5);
|
||||
if (a < Math.abs(c)) { a=c; var s=p/4; }
|
||||
else var s = p/(2*Math.PI) * Math.asin (c/a);
|
||||
if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
|
||||
return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
|
||||
},
|
||||
easeInBack: function (x, t, b, c, d, s) {
|
||||
if (s == undefined) s = 1.70158;
|
||||
return c*(t/=d)*t*((s+1)*t - s) + b;
|
||||
},
|
||||
easeOutBack: function (x, t, b, c, d, s) {
|
||||
if (s == undefined) s = 1.70158;
|
||||
return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
|
||||
},
|
||||
easeInOutBack: function (x, t, b, c, d, s) {
|
||||
if (s == undefined) s = 1.70158;
|
||||
if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
|
||||
return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
|
||||
},
|
||||
easeInBounce: function (x, t, b, c, d) {
|
||||
return c - $.easing.easeOutBounce (x, d-t, 0, c, d) + b;
|
||||
},
|
||||
easeOutBounce: function (x, t, b, c, d) {
|
||||
if ((t/=d) < (1/2.75)) {
|
||||
return c*(7.5625*t*t) + b;
|
||||
} else if (t < (2/2.75)) {
|
||||
return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
|
||||
} else if (t < (2.5/2.75)) {
|
||||
return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
|
||||
} else {
|
||||
return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
|
||||
}
|
||||
},
|
||||
easeInOutBounce: function (x, t, b, c, d) {
|
||||
if (t < d/2) return $.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
|
||||
return $.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
*
|
||||
* TERMS OF USE - EASING EQUATIONS
|
||||
*
|
||||
* Open source under the BSD License.
|
||||
*
|
||||
* Copyright 2001 Robert Penner
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of the author nor the names of contributors may be used to endorse
|
||||
* or promote products derived from this software without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
|
||||
* COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
|
||||
* GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
|
||||
* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||
* OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
})(jQuery);
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/*
|
||||
* jQuery UI Effects Highlight 1.8.16
|
||||
*
|
||||
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about)
|
||||
* Dual licensed under the MIT or GPL Version 2 licenses.
|
||||
* http://jquery.org/license
|
||||
*
|
||||
* http://docs.jquery.com/UI/Effects/Highlight
|
||||
*
|
||||
* Depends:
|
||||
* jquery.effects.core.js
|
||||
*/
|
||||
(function( $, undefined ) {
|
||||
|
||||
$.effects.highlight = function(o) {
|
||||
return this.queue(function() {
|
||||
var elem = $(this),
|
||||
props = ['backgroundImage', 'backgroundColor', 'opacity'],
|
||||
mode = $.effects.setMode(elem, o.options.mode || 'show'),
|
||||
animation = {
|
||||
backgroundColor: elem.css('backgroundColor')
|
||||
};
|
||||
|
||||
if (mode == 'hide') {
|
||||
animation.opacity = 0;
|
||||
}
|
||||
|
||||
$.effects.save(elem, props);
|
||||
elem
|
||||
.show()
|
||||
.css({
|
||||
backgroundImage: 'none',
|
||||
backgroundColor: o.options.color || '#ffff99'
|
||||
})
|
||||
.animate(animation, {
|
||||
queue: false,
|
||||
duration: o.duration,
|
||||
easing: o.options.easing,
|
||||
complete: function() {
|
||||
(mode == 'hide' && elem.hide());
|
||||
$.effects.restore(elem, props);
|
||||
(mode == 'show' && !$.support.opacity && this.style.removeAttribute('filter'));
|
||||
(o.callback && o.callback.apply(this, arguments));
|
||||
elem.dequeue();
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
})(jQuery);
|
||||
Loading…
Reference in New Issue