sudoslider
Version:
An extremely versitile content-slider
509 lines (481 loc) • 17.7 kB
text/typescript
/// <reference path="lib/jquery.d.ts" />
/// <reference path="lib/angular.d.ts" />
/// <reference path="events.ts" />
interface JQuery {
sudoSlider(options?:any) : JQuery
}
interface OptionDefinition {
name : string;
type: string;
value?: any;
enabled?: boolean;
stringValue?: any;
}
interface DemoDefinition {
name: string;
options: any;
}
interface GlobalSliderApi {
init: () => void;
destroy: () => void;
setOption: (name: string, value: any) => void;
setOptions: (options : any) => void;
runWhenNotAnimating: (func : () => any) => void;
insertSlide: (html : string, pos: number, numtext? : string, goToSlide? : number) => void;
removeSlide: (slide : number) => void;
goToSlide: (slide : number) => void;
block: () => void;
unblock: () => void;
startAuto: () => void;
stopAuto: () => void;
adjust: (repeat? : boolean) => void;
stopAnimation: () => void;
}
interface SudoSliderFactory {
defaultOptionDefinitions: () => OptionDefinition[];
defaultOptionValues: () => any;
insertValuesIntoOptionDefinitions: (optionDefinitions:OptionDefinition[], options:any) => void;
getDemoDefinitions: () => DemoDefinition[];
filterAllDefaultValueOptionDefinitions : (optionDefinitions:OptionDefinition[]) => OptionDefinition[];
globalSliderApi: () => GlobalSliderApi;
}
(function (angular:ng.IAngularStatic, $:JQueryStatic) {
angular.module('sudoSlider', [])
.directive('sudoSlider', ["sudoSlider", "$timeout", function (factory, $timeout) {
return {
scope: {
sliderApi: '=?',
sudoSlider: "=?"
},
link: function ($scope, element, attrs) {
var slider;
$scope.sliderApi = $scope.sliderApi || {};
EventBus.getInstance().register(SudoSliderApiEvent, function (event:SudoSliderApiEvent) {
return event.callback($scope.sliderApi);
}, false, window);
var updateDefinitions = function (newDefinitions) {
var options;
if ($.isArray(newDefinitions)) {
options = {};
for (var i = 0; i < newDefinitions.length; i++) {
var definition = newDefinitions[i];
var definitionValue = definition.value;
if (definition.optional && !definition.enabled) {
definitionValue = false;
}
options[definition.name] = definitionValue;
}
} else {
options = newDefinitions ? newDefinitions : {};
}
slider.destroy();
slider.setOptions(options);
// When i destroy it myself, i init it myself.
slider.init();
};
$scope.$watch("sudoSlider", updateDefinitions, true);
$timeout(function () {
EventBus.getInstance().register(SudoSliderUpdateOptionsEvent, function (event:SudoSliderUpdateOptionsEvent) {
updateDefinitions(event.newDefinitions);
}, true, window);
});
slider = $(element).sudoSlider();
$scope.slider = slider;
for (var prop in slider) {
if (slider.hasOwnProperty(prop)) {
$scope.sliderApi[prop] = slider[prop];
}
}
element.on('$destroy', function () {
slider.destroy();
});
}
};
}]).controller('SudoSliderSlidesController', ["$scope", "$timeout", "sudoSlider", function ($scope, $timeout, sudoSlider:SudoSliderFactory) {
$scope.slides = [
{html: "<img src=\"../images/01.jpg\"/>"},
{html: "<img src=\"../images/02.jpg\"/>"},
{html: "<img src=\"../images/03.jpg\"/>"},
{html: "<img src=\"../images/04.jpg\"/>"},
{html: "<img src=\"../images/05.jpg\"/>"}
];
EventBus.getInstance().register(SudoSliderSlidesUpdateEvent, function (event:SudoSliderSlidesUpdateEvent) {
$scope.slides = event.newSlides;
// We risk that the last event is fired immediately.
if(!$scope.$$phase) {
$scope.$apply();
}
}, true, window);
}]).factory('sudoSlider', function () {
var result : SudoSliderFactory = {
defaultOptionDefinitions: getOptionDefinitions,
defaultOptionValues: $.fn.sudoSlider.getDefaultOptions,
insertValuesIntoOptionDefinitions: insertValuesIntoOptionDefinitions,
getDemoDefinitions: getDemoDefinitions, // TODO: Something else.
filterAllDefaultValueOptionDefinitions: filterAllDefaultValueOptionDefinitions,
globalSliderApi : getGlobalSliderApi
};
return result;
});
function getGlobalSliderApi() : GlobalSliderApi {
var sliderApi : any = {};
// Events doesn't return anything, so "getOption", "getValue" and "getSlide" doesn't make sense here.
var apiNames = ["init", "destroy", "setOption", "setOptions", "runWhenNotAnimating", "insertSlide", "removeSlide", "goToSlide", "block", "unblock", "startAuto", "stopAuto", "adjust", "stopAnimation"]
$.each(apiNames, function (index, name:string) {
sliderApi[name] = function () {
var args = arguments;
EventBus.getInstance().fireEvent(new SudoSliderApiEvent((api) => api[name].apply(this, args), name));
}
});
return sliderApi;
}
function filterAllDefaultValueOptionDefinitions(optionDefinitions) {
var result = [];
$.each(optionDefinitions, function (index, optionDefinition) {
var defaultValue = $.fn.sudoSlider.getDefaultOptions()[optionDefinition.name];
var currentValue = optionDefinition.value;
if (defaultValue.toString() !== currentValue.toString()) {
result.push(optionDefinition);
}
});
return result;
}
function insertValuesIntoOptionDefinitions(optionDefinitions, options) {
$.each(optionDefinitions, function (index, optionDefinition) {
if (!options.hasOwnProperty(optionDefinition.name)) {
return;
}
var newValue = options[optionDefinition.name];
if (optionDefinition.type == "function") {
if ($.isFunction(newValue)) {
optionDefinition.stringValue = newValue.toString();
optionDefinition.value = newValue;
} else {
optionDefinition.stringValue = newValue;
try {
optionDefinition.value = eval("(" + newValue + ")");
} catch (ignored) {
}
}
} else if (optionDefinition.type == "array") {
if ($.isArray(newValue)) {
optionDefinition.stringValue = "[" + newValue.toString() + "]";
optionDefinition.value = newValue;
} else {
optionDefinition.stringValue = newValue;
optionDefinition.value = JSON.parse(newValue);
}
} else {
optionDefinition.value = newValue;
}
if (optionDefinition.optional) {
optionDefinition.enabled = newValue !== false;
if (!newValue) {
optionDefinition.value = "";
}
}
});
}
function getOptionDefinitions() {
var optionDefinitions:OptionDefinition[] = [
{
name: "effect",
type: "dropdown",
choices: Object.keys($.fn.sudoSlider.effects)
},
{
name: "speed",
type: "number"
},
{
name: "customLink",
optional: true,
enabled: false,
type: "text"
},
{
name: "controlsFadeSpeed",
type: "number"
},
{
name: "controlsFade",
type: "boolean"
},
{
name: "insertAfter",
type: "boolean"
},
{
name: "vertical",
type: "boolean"
},
{
name: "slideCount",
type: "number"
},
{
name: "moveCount",
type: "number"
},
{
name: "startSlide",
type: "number"
},
{
name: "responsive",
type: "boolean"
},
{
name: "ease",
type: "text"
},
{
name: "auto",
type: "boolean"
},
{
name: "CSSease",
type: "text"
},
{
name: "pause",
type: "number"
},
{
name: "resumePause",
optional: true,
enabled: false,
type: "number"
},
{
name: "continuous",
type: "boolean"
},
{
name: "prevNext",
type: "boolean"
},
{
name: "numeric",
type: "boolean"
},
{
name: "numericText",
type: "array"
},
{
name: "slices",
type: "number"
},
{
name: "boxCols",
type: "number"
},
{
name: "boxRows",
type: "number"
},
{
name: "initCallback",
type: "function"
},
{
name: "ajaxLoad",
type: "function"
},
{
name: "beforeAnimation",
type: "function"
},
{
name: "afterAnimation",
type: "function"
},
{
name: "history",
type: "boolean"
},
{
name: "autoHeight",
type: "boolean"
},
{
name: "autoWidth",
type: "boolean"
},
{
name: "updateBefore",
type: "boolean"
},
{
name: "ajax",
optional: true,
enabled: false,
type: "array"
},
{
name: "preloadAjax",
optional: true,
enabled: true,
type: "number"
},
{
name: "loadingText",
type: "text"
},
{
name: "prevHtml",
type: "text"
},
{
name: "nextHtml",
type: "text"
},
{
name: "controlsAttr",
type: "text"
},
{
name: "numericAttr",
type: "text"
},
{
name: "interruptible",
type: "boolean"
},
{
name: "useCSS",
type: "boolean"
},
{
name: "loadStart",
type: "function"
},
{
name: "loadFinish",
type: "function"
},
{
name: "touch",
type: "boolean"
},
{
name: "touchHandle",
optional: true,
enabled: false,
type: "text"
},
{
name: "destroyCallback",
type: "function"
},
{
name: "mouseTouch",
type: "boolean"
},
{
name: "allowScroll",
type: "boolean"
}
];
var defaultOptions = $.fn.sudoSlider.getDefaultOptions();
if (Object.keys(defaultOptions).length != optionDefinitions.length) {
console.error("Mismatch between options (" + Object.keys(defaultOptions).length + ") and option definitions (" + optionDefinitions.length + ") length");
}
$.each(optionDefinitions, function (index, def) {
if (!defaultOptions.hasOwnProperty(def.name)) {
console.error("Could not find the option " + def.name + " in the SudoSlider options. ");
return;
}
if (def.enabled !== false) {
def.value = defaultOptions[def.name];
} else {
def.value = "";
}
});
return optionDefinitions;
}
function getDemoDefinitions() {
return [
{
name: "continous",
options: {
continuous: true
}
},
{
name: "numeric",
options: {
numeric: true
}
},
{
name: "captions",
options: {
effect: "fade",
continuous: true,
initCallback: function () {
var storage:any = {};
$(this).data("captions", storage);
var that = this;
storage.captions = $();
storage.css = {
position: "absolute",
bottom: 0,
left: 0,
width: "100%",
height: "25px",
textAlign: "center",
color: "black",
background: "rgba(255,255,255,0.7)",
filter: "progid:DXImageTransform.Microsoft.gradient(startColorstr=#a3ffffff,endColorstr=#a3ffffff)",
zoom: 1
};
storage.imageText = [
'Just another beautiful sunset',
'Mountains in the Alps',
'Road and mountains in the Alps',
'Behind another beautiful sunset',
'A goat in norway'
];
storage.insertCaption = function (t) {
var slide = that.getSlide(t);
var imageText = storage.imageText[t - 1] || "I don't know what to say about this one.";
var caption = $('<div>' + imageText + '</div>').css(<Object>storage.css).appendTo(slide);
storage.captions = storage.captions.add(caption);
if (slide.css("position") == "static") {
slide.css("position", "relative");
}
};
var ajaxOption = this.getOption("ajax") || [];
for (var i = 0; i < this.getValue("totalslides"); i++) {
if (!ajaxOption[i]) {
storage.insertCaption(i + 1);
}
}
},
destroyCallback: function () {
var storage = $(this).data("captions");
if (!storage) {
return;
}
storage.captions.remove();
storage.captions = $();
},
ajaxLoad: function (t, img, that) {
var storage = $(that).data("captions");
storage.insertCaption(t);
},
beforeAnimation: function (t, that) {
var storage = $(that).data("captions");
$(this).children().filter(storage.captions).hide();
},
afterAnimation: function (t, that) {
var storage = $(that).data("captions");
$(this).children().filter(storage.captions).slideDown(400);
}
}
}
]
}
})(angular, jQuery);