From 05425383e510e14747ffe1ca01ba60f016556064 Mon Sep 17 00:00:00 2001 From: Jarno Kurlin Date: Sun, 16 Sep 2012 11:12:41 +0300 Subject: [PATCH] Resources can be loaded with ajax etc Resources can be loaded with ajax and resources can be arrays in event objects. Thanks for thebandit for the pull request. Example options: Resources via ajax: resources: 'http://localhost/fullcalendar/tests/json-resources.php', Resources as arrays in events: events: [ { title: 'All Day Event in resource 2 and 3', start: new Date(y, m, 1), resource: ['resource2','resource3'] } ], --- demos/json-resources.php | 4 + demos/resourceView.html | 13 +-- src/Calendar.js | 9 +- src/ResourceManager.js | 134 ++++++++++++++++++++++++++ src/_loader.js | 1 + src/resource/ResourceDayView.js | 4 +- src/resource/ResourceEventRenderer.js | 17 +++- src/resource/ResourceMonthView.js | 4 +- src/resource/ResourceNextWeeksView.js | 4 +- src/resource/ResourceView.js | 6 +- src/resource/ResourceWeekView.js | 4 +- tests/json-resources.php | 4 + tests/resourceView.html | 17 +--- 13 files changed, 178 insertions(+), 43 deletions(-) create mode 100644 demos/json-resources.php create mode 100644 src/ResourceManager.js create mode 100644 tests/json-resources.php diff --git a/demos/json-resources.php b/demos/json-resources.php new file mode 100644 index 0000000000..38f9214f37 --- /dev/null +++ b/demos/json-resources.php @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/demos/resourceView.html b/demos/resourceView.html index e2ec9eaa17..5e93a6bfdf 100644 --- a/demos/resourceView.html +++ b/demos/resourceView.html @@ -31,23 +31,14 @@ minTime: 8, maxTime:16, selectHelper: true, - resources: [ - { - name: 'Resource 2', - id: 'resource2' - }, - { - name: 'Resource 1', - id: 'resource1' - } - ], + resources: 'json-resources.php', events: [ { title: 'Lunch 12.15-14.45', start: new Date(y, m, d, 12, 15), end: new Date(y, m, d, 14, 45), allDay: false, - resource: 'resource1' + resource: ['resource1','resource2'] }, { title: 'Meeting', diff --git a/src/Calendar.js b/src/Calendar.js index d32595ba53..67193a7d0e 100644 --- a/src/Calendar.js +++ b/src/Calendar.js @@ -1,6 +1,6 @@ -function Calendar(element, options, eventSources) { +function Calendar(element, options, eventSources, resourceSources) { var t = this; @@ -10,6 +10,7 @@ function Calendar(element, options, eventSources) { t.destroy = destroy; t.refetchEvents = refetchEvents; t.reportEvents = reportEvents; + t.refetchResources = refetchResources; t.reportEventChange = reportEventChange; t.rerenderEvents = rerenderEvents; t.changeView = changeView; @@ -35,6 +36,9 @@ function Calendar(element, options, eventSources) { var isFetchNeeded = t.isFetchNeeded; var fetchEvents = t.fetchEvents; + // fetch resources + ResourceManager.call(t, options); + var fetchResources = t.fetchResources; // locals var _element = element[0]; @@ -326,6 +330,9 @@ function Calendar(element, options, eventSources) { fetchEvents(currentView.visStart, currentView.visEnd); // will call reportEvents } + function refetchResources() { + fetchResources(false); + } // called when event data arrives function reportEvents(_events) { diff --git a/src/ResourceManager.js b/src/ResourceManager.js new file mode 100644 index 0000000000..d25a15c497 --- /dev/null +++ b/src/ResourceManager.js @@ -0,0 +1,134 @@ +/* + * Responsible for resources. Resource source object is anything that provides + * data about resources. It can be function, a JSON object or URL to a JSON + * feed. +*/ + + +function ResourceManager(options) { + var t = this; + + // exports + t.fetchResources = fetchResources; + + // local + var sources = []; // source array + var cache; // cached resources + + _addResourceSources(options['resources']); + + + /** + * ---------------------------------------------------------------- + * Categorize and add the provided sources + * ---------------------------------------------------------------- + */ + function _addResourceSources(_sources) { + var source = {}; + + if ($.isFunction(_sources)) { + // is it a function? + source = { + resources: _sources + }; + sources.push(source); + } else if (typeof _sources == 'string') { + // is it a URL string? + source = { + url: _sources + }; + sources.push(source); + } else if (typeof _sources == 'object') { + // is it json object? + for (var i=0; i<_sources.length; i++) { + var s = _sources[i]; + normalizeSource(s); + source = { + resources: s + }; + sources.push(source); + } + } + } + + + /** + * ---------------------------------------------------------------- + * Fetch resources from source array + * ---------------------------------------------------------------- + */ + function fetchResources(useCache) { + // if useCache is not defined, default to true + useCache = typeof useCache !== 'undefined' ? useCache : true; + + if (cache != undefined && useCache) { + // get from cache + return cache; + } else { + // do a fetch resource from source, rebuild cache + cache = []; + var len = sources.length; + for (var i = 0; i < len; i++) { + var resources = _fetchResourceSource(sources[i]); + cache = cache.concat(resources); + } + return cache; + } + } + + + /** + * ---------------------------------------------------------------- + * Fetch resources from each source. If source is a function, call + * the function and return the resource. If source is a URL, get + * the data via synchronized ajax call. If the source is an + * object, return it as is. + * ---------------------------------------------------------------- + */ + function _fetchResourceSource(source) { + var resources = source.resources; + if (resources) { + if ($.isFunction(resources)) { + return resources(); + } + } else { + var url = source.url; + if (url) { + $.ajax({ + url: url, + dataType: 'json', + cache: false, + success: function(res) { + res = res || []; + resources = res; + }, + error: function() { + alert("ajax error getting json from "+url); + }, + async: false // too much work coordinating callbacks so dumb it down + }); + } + } + return resources; + } + + + /** + * ---------------------------------------------------------------- + * normalize the source object + * ---------------------------------------------------------------- + */ + function normalizeSource(source) { + if (source.className) { + if (typeof source.className == 'string') { + source.className = source.className.split(/\s+/); + } + }else{ + source.className = []; + } + var normalizers = fc.sourceNormalizers; + for (var i=0; i" + diff --git a/src/resource/ResourceWeekView.js b/src/resource/ResourceWeekView.js index afcab7b022..2edc695903 100644 --- a/src/resource/ResourceWeekView.js +++ b/src/resource/ResourceWeekView.js @@ -14,7 +14,7 @@ function ResourceWeekView(element, calendar) { var opt = t.opt; var renderBasic = t.renderBasic; var formatDates = calendar.formatDates; - + var getResources = t.getResources; function render(date, delta) { @@ -39,7 +39,7 @@ function ResourceWeekView(element, calendar) { t.end = end; t.visStart = visStart; t.visEnd = visEnd; - renderBasic(opt('resources').length, opt('resources').length, weekends ? 7 : 5, false); + renderBasic(getResources.length, getResources.length, weekends ? 7 : 5, false); } diff --git a/tests/json-resources.php b/tests/json-resources.php new file mode 100644 index 0000000000..86b43f85a9 --- /dev/null +++ b/tests/json-resources.php @@ -0,0 +1,4 @@ + \ No newline at end of file diff --git a/tests/resourceView.html b/tests/resourceView.html index 61e097e162..1ec1f6e4ae 100644 --- a/tests/resourceView.html +++ b/tests/resourceView.html @@ -27,27 +27,14 @@ minTime: 7, maxTime:17, selectHelper: true, - resources: [ - { - name: 'Resource Name 2', - id: 'resource2' - }, - { - name: 'Resource Name 1', - id: 'resource1' - }, - { - name: 'Resource Name 3', - id: 'resource3' - } - ], + resources: 'json-resources.php', events: [ { title: 'Meeting', start: new Date(y, m, d, 10, 30), end: new Date(y, m, d+4, 11, 00), allDay: false, - resource: 'resource1' + resource: ['resource1','resource3'] }, { title: 'All Day Event',