Adam Shaw пре 8 година
родитељ
комит
a27806749a
2 измењених фајлова са 237 додато и 192 уклоњено
  1. 87 0
      demos/js/theme-chooser.js
  2. 150 192
      demos/themes.html

+ 87 - 0
demos/js/theme-chooser.js

@@ -0,0 +1,87 @@
+
+function initThemeChooser(settings) {
+	var isInitialized = false;
+	var $currentStylesheet = $();
+	var $loading = $('#loading');
+	var $systemSelect = $('#theme-system-selector select')
+		.on('change', function() {
+			setThemeSystem(this.value);
+		});
+
+	setThemeSystem($systemSelect.val());
+
+
+	function setThemeSystem(themeSystem) {
+		var $allSelectWraps = $('[data-theme-system]').hide();
+		var $selectWrap = $allSelectWraps.filter('[data-theme-system="' + themeSystem +'"]').show();
+		var $select = $selectWrap.find('select')
+			.off('change') // avoid duplicate handlers :(
+			.on('change', function() {
+				setTheme(themeSystem, this.value);
+			});
+
+		setTheme(themeSystem, $select.val());
+	}
+
+
+	function setTheme(themeSystem, themeName) {
+		var stylesheetUrl = generateStylesheetUrl(themeSystem, themeName);
+		var $stylesheet;
+
+		function done() {
+			if (!isInitialized) {
+				isInitialized = true;
+				settings.init(themeSystem);
+			}
+			else {
+				settings.change(themeSystem);
+			}
+		}
+
+		if (stylesheetUrl) {
+			$stylesheet = $('<link rel="stylesheet" type="text/css" href="' + stylesheetUrl + '"/>').appendTo('head');
+			$loading.show();
+
+			whenStylesheetLoaded($stylesheet[0], function() {
+				$currentStylesheet.remove();
+				$currentStylesheet = $stylesheet;
+				$loading.hide();
+				done();
+			});
+		} else {
+			$currentStylesheet.remove();
+			$currentStylesheet = $();
+			done();
+		}
+	}
+
+
+	function generateStylesheetUrl(themeSystem, themeName) {
+		if (themeSystem === 'jquery-ui') {
+			return 'https://code.jquery.com/ui/1.12.1/themes/' + themeName + '/jquery-ui.css';
+		}
+		else if (themeSystem === 'bootstrap3') {
+			if (themeName) {
+				return 'http://bootswatch.com/' + themeName + '/bootstrap.min.css';
+			}
+			else { // the default bootstrap theme
+				return 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css';
+			}
+		}
+	}
+
+
+	function whenStylesheetLoaded(linkNode, callback) {
+		var isReady = false;
+
+		function ready() {
+			if (!isReady) { // avoid double-call
+				isReady = true;
+				callback();
+			}
+		}
+
+		linkNode.onload = ready; // does not work cross-browser
+		setTimeout(ready, 2000); // max wait. also handles browsers that don't support onload
+	}
+}

+ 150 - 192
demos/themes.html

@@ -2,154 +2,95 @@
 <html>
 <head>
 <meta charset='utf-8' />
-
-<!-- preload the first theme's stylesheet -->
-<link href='https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css' rel='stylesheet' data-theme-stylesheet />
-
 <link href='../dist/fullcalendar.css' rel='stylesheet' />
 <link href='../dist/fullcalendar.print.css' rel='stylesheet' media='print' />
 <script src='../node_modules/moment/moment.js'></script>
 <script src='../node_modules/jquery/dist/jquery.js'></script>
 <script src='../dist/fullcalendar.js'></script>
+<script src='js/theme-chooser.js'></script>
 <script>
 
 	$(document).ready(function() {
-		var $themeStylesheet = $('link[data-theme-stylesheet]');
-		var $themeSystemSelect = $('#theme-system-selector select');
-		var $themeNameSelects = $('#theme-name-selector select');
-		var currentThemeSystem;
-		var calendarObj;
-
-
-		setThemeSystem($themeSystemSelect.val()); // whatever is selected
 
-
-		$('#calendar').fullCalendar({
-			theme: currentThemeSystem, // set by setThemeSystem
-			header: {
-				left: 'prev,next today',
-				center: 'title',
-				right: 'month,agendaWeek,agendaDay,listMonth'
+		initThemeChooser({
+
+			init: function(themeSystem) {
+				$('#calendar').fullCalendar({
+					theme: themeSystem,
+					header: {
+						left: 'prev,next today',
+						center: 'title',
+						right: 'month,agendaWeek,agendaDay,listMonth'
+					},
+					defaultDate: '2017-07-12',
+					weekNumbers: true,
+					navLinks: true, // can click day/week names to navigate views
+					editable: true,
+					eventLimit: true, // allow "more" link when too many events
+					events: [
+						{
+							title: 'All Day Event',
+							start: '2017-07-01'
+						},
+						{
+							title: 'Long Event',
+							start: '2017-07-07',
+							end: '2017-07-10'
+						},
+						{
+							id: 999,
+							title: 'Repeating Event',
+							start: '2017-07-09T16:00:00'
+						},
+						{
+							id: 999,
+							title: 'Repeating Event',
+							start: '2017-07-16T16:00:00'
+						},
+						{
+							title: 'Conference',
+							start: '2017-07-11',
+							end: '2017-07-13'
+						},
+						{
+							title: 'Meeting',
+							start: '2017-07-12T10:30:00',
+							end: '2017-07-12T12:30:00'
+						},
+						{
+							title: 'Lunch',
+							start: '2017-07-12T12:00:00'
+						},
+						{
+							title: 'Meeting',
+							start: '2017-07-12T14:30:00'
+						},
+						{
+							title: 'Happy Hour',
+							start: '2017-07-12T17:30:00'
+						},
+						{
+							title: 'Dinner',
+							start: '2017-07-12T20:00:00'
+						},
+						{
+							title: 'Birthday Party',
+							start: '2017-07-13T07:00:00'
+						},
+						{
+							title: 'Click for Google',
+							url: 'http://google.com/',
+							start: '2017-07-28'
+						}
+					]
+				});
 			},
-			defaultDate: '2017-07-12',
-			weekNumbers: true,
-			navLinks: true, // can click day/week names to navigate views
-			editable: true,
-			eventLimit: true, // allow "more" link when too many events
-			events: [
-				{
-					title: 'All Day Event',
-					start: '2017-07-01'
-				},
-				{
-					title: 'Long Event',
-					start: '2017-07-07',
-					end: '2017-07-10'
-				},
-				{
-					id: 999,
-					title: 'Repeating Event',
-					start: '2017-07-09T16:00:00'
-				},
-				{
-					id: 999,
-					title: 'Repeating Event',
-					start: '2017-07-16T16:00:00'
-				},
-				{
-					title: 'Conference',
-					start: '2017-07-11',
-					end: '2017-07-13'
-				},
-				{
-					title: 'Meeting',
-					start: '2017-07-12T10:30:00',
-					end: '2017-07-12T12:30:00'
-				},
-				{
-					title: 'Lunch',
-					start: '2017-07-12T12:00:00'
-				},
-				{
-					title: 'Meeting',
-					start: '2017-07-12T14:30:00'
-				},
-				{
-					title: 'Happy Hour',
-					start: '2017-07-12T17:30:00'
-				},
-				{
-					title: 'Dinner',
-					start: '2017-07-12T20:00:00'
-				},
-				{
-					title: 'Birthday Party',
-					start: '2017-07-13T07:00:00'
-				},
-				{
-					title: 'Click for Google',
-					url: 'http://google.com/',
-					start: '2017-07-28'
-				}
-			]
-		});
-
-		calendarObj = $('#calendar').fullCalendar('getCalendar'); // for cleaner API access
-
-
-		$themeSystemSelect.on('change', function() {
-			setThemeSystem(this.value);
-		});
-
-		$themeNameSelects.on('change', function() {
-			setThemeStylesheet(this.value);
-		});
-
-
-		function setThemeSystem(newThemeSystem) {
-			var $nameSelector = $('#theme-name-selector select').hide() // hide all selects
-				.filter('[data-theme-type="' + newThemeSystem + '"]').show(); // then show new select
-
-			currentThemeSystem = newThemeSystem;
 
-			if ($nameSelector.length) {
-				$('#theme-name-selector').show();
-				setThemeStylesheet($nameSelector.val());
+			change: function(themeSystem) {
+				$('#calendar').fullCalendar('option', 'theme', themeSystem);
 			}
-			else {
-				$('#theme-name-selector').hide();
-				clearThemeStylesheet();
-			}
-
-			if (calendarObj) { // if already initialized
-				calendarObj.option('theme', newThemeSystem);
-			}
-		}
-
-
-		function setThemeStylesheet(themeName) {
-			$themeStylesheet.attr('href', buildThemeStylesheetUrl(themeName));
-		}
-
-
-		function clearThemeStylesheet() {
-			$themeStylesheet.attr('href', '');
-		}
 
-
-		function buildThemeStylesheetUrl(themeName) {
-			if (currentThemeSystem === 'jquery-ui') {
-				return 'https://code.jquery.com/ui/1.12.1/themes/' + themeName + '/jquery-ui.css';
-			}
-			else if (currentThemeSystem === 'bootstrap3') {
-				if (themeName) {
-					return 'http://bootswatch.com/' + themeName + '/bootstrap.min.css';
-				}
-				else { // the default bootstrap theme
-					return 'https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css';
-				}
-			}
-		}
+		});
 
 	});
 
@@ -185,6 +126,10 @@
 		font: inherit; /* mock what Boostrap does, don't compete  */
 	}
 
+	.left { float: left }
+	.right { float: right }
+	.clear { clear: both }
+
 	#calendar {
 		max-width: 900px;
 		margin: 40px auto;
@@ -197,68 +142,81 @@
 
 	<div id='top'>
 
-		<div id='theme-system-selector' class='selector'>
-			Theme System:
+		<div class='left'>
+
+			<div id='theme-system-selector' class='selector'>
+				Theme System:
+
+				<select>
+					<option value='bootstrap3' selected>Bootstrap 3</option>
+					<option value='jquery-ui'>jQuery UI</option>
+					<option value='standard'>unthemed</option>
+				</select>
+			</div>
+
+			<div data-theme-system="bootstrap3" class='selector' style='display:none'>
+				Theme Name:
+
+				<select>
+					<option value='' selected>Default</option>
+					<option value='cerulean'>Cerulean</option>
+					<option value='cosmo'>Cosmo</option>
+					<option value='cyborg'>Cyborg</option>
+					<option value='darkly'>Darkly</option>
+					<option value='flatly'>Flatly</option>
+					<option value='journal'>Journal</option>
+					<option value='lumen'>Lumen</option>
+					<option value='paper'>Paper</option>
+					<option value='readable'>Readable</option>
+					<option value='sandstone'>Sandstone</option>
+					<option value='simplex'>Simplex</option>
+					<option value='slate'>Slate</option>
+					<option value='solar'>Solar</option>
+					<option value='spacelab'>Spacelab</option>
+					<option value='superhero'>Superhero</option>
+					<option value='united'>United</option>
+					<option value='yeti'>Yeti</option>
+				</select>
+			</div>
+
+			<div data-theme-system="jquery-ui" class='selector' style='display:none'>
+				Theme Name:
+
+				<select>
+					<option value='black-tie'>Black Tie</option>
+					<option value='blitzer'>Blitzer</option>
+					<option value='cupertino' selected>Cupertino</option>
+					<option value='dark-hive'>Dark Hive</option>
+					<option value='dot-luv'>Dot Luv</option>
+					<option value='eggplant'>Eggplant</option>
+					<option value='excite-bike'>Excite Bike</option>
+					<option value='flick'>Flick</option>
+					<option value='hot-sneaks'>Hot Sneaks</option>
+					<option value='humanity'>Humanity</option>
+					<option value='le-frog'>Le Frog</option>
+					<option value='mint-choc'>Mint Choc</option>
+					<option value='overcast'>Overcast</option>
+					<option value='pepper-grinder'>Pepper Grinder</option>
+					<option value='redmond'>Redmond</option>
+					<option value='smoothness'>Smoothness</option>
+					<option value='south-street'>South Street</option>
+					<option value='start'>Start</option>
+					<option value='sunny'>Sunny</option>
+					<option value='swanky-purse'>Swanky Purse</option>
+					<option value='trontastic'>Trontastic</option>
+					<option value='ui-darkness'>UI Darkness</option>
+					<option value='ui-lightness'>UI Lightness</option>
+					<option value='vader'>Vader</option>
+				</select>
+			</div>
 
-			<select>
-				<option value='bootstrap3' selected>Bootstrap 3</option>
-				<option value='jquery-ui'>jQuery UI</option>
-				<option value='standard'>unthemed</option>
-			</select>
 		</div>
 
-		<div id='theme-name-selector' class='selector' style='display:none'>
-			Theme Name:
-
-			<select data-theme-type='jquery-ui'>
-				<option value='black-tie'>Black Tie</option>
-				<option value='blitzer'>Blitzer</option>
-				<option value='cupertino' selected>Cupertino</option>
-				<option value='dark-hive'>Dark Hive</option>
-				<option value='dot-luv'>Dot Luv</option>
-				<option value='eggplant'>Eggplant</option>
-				<option value='excite-bike'>Excite Bike</option>
-				<option value='flick'>Flick</option>
-				<option value='hot-sneaks'>Hot Sneaks</option>
-				<option value='humanity'>Humanity</option>
-				<option value='le-frog'>Le Frog</option>
-				<option value='mint-choc'>Mint Choc</option>
-				<option value='overcast'>Overcast</option>
-				<option value='pepper-grinder'>Pepper Grinder</option>
-				<option value='redmond'>Redmond</option>
-				<option value='smoothness'>Smoothness</option>
-				<option value='south-street'>South Street</option>
-				<option value='start'>Start</option>
-				<option value='sunny'>Sunny</option>
-				<option value='swanky-purse'>Swanky Purse</option>
-				<option value='trontastic'>Trontastic</option>
-				<option value='ui-darkness'>UI Darkness</option>
-				<option value='ui-lightness'>UI Lightness</option>
-				<option value='vader'>Vader</option>
-			</select>
-
-			<select data-theme-type='bootstrap3' style='display:none'>
-				<option value='' selected>Default</option>
-				<option value='cerulean'>Cerulean</option>
-				<option value='cosmo'>Cosmo</option>
-				<option value='cyborg'>Cyborg</option>
-				<option value='darkly'>Darkly</option>
-				<option value='flatly'>Flatly</option>
-				<option value='journal'>Journal</option>
-				<option value='lumen'>Lumen</option>
-				<option value='paper'>Paper</option>
-				<option value='readable'>Readable</option>
-				<option value='sandstone'>Sandstone</option>
-				<option value='simplex'>Simplex</option>
-				<option value='slate'>Slate</option>
-				<option value='solar'>Solar</option>
-				<option value='spacelab'>Spacelab</option>
-				<option value='superhero'>Superhero</option>
-				<option value='united'>United</option>
-				<option value='yeti'>Yeti</option>
-			</select>
+		<div class='right'>
+			<div id='loading' style='display:none'>loading theme...</div>
 		</div>
 
+		<div class='clear'></div>
 	</div>
 
 	<div id='calendar'></div>