repeater-thumbnail.js 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. /*
  2. * Fuel UX Repeater - Thumbnail View Plugin
  3. * https://github.com/ExactTarget/fuelux
  4. *
  5. * Copyright (c) 2014 ExactTarget
  6. * Licensed under the BSD New license.
  7. */
  8. // -- BEGIN UMD WRAPPER PREFACE --
  9. // For more information on UMD visit:
  10. // https://github.com/umdjs/umd/blob/master/jqueryPlugin.js
  11. (function (factory) {
  12. if (typeof define === 'function' && define.amd) {
  13. // if AMD loader is available, register as an anonymous module.
  14. define(['jquery', 'fuelux/repeater'], factory);
  15. } else {
  16. // OR use browser globals if AMD is not present
  17. factory(jQuery);
  18. }
  19. }(function ($) {
  20. // -- END UMD WRAPPER PREFACE --
  21. // -- BEGIN MODULE CODE HERE --
  22. if ($.fn.repeater) {
  23. //ADDITIONAL METHODS
  24. $.fn.repeater.Constructor.prototype.thumbnail_clearSelectedItems = function () {
  25. this.$canvas.find('.repeater-thumbnail-cont .selectable.selected').removeClass('selected');
  26. };
  27. $.fn.repeater.Constructor.prototype.thumbnail_getSelectedItems = function () {
  28. var selected = [];
  29. this.$canvas.find('.repeater-thumbnail-cont .selectable.selected').each(function () {
  30. selected.push($(this));
  31. });
  32. return selected;
  33. };
  34. $.fn.repeater.Constructor.prototype.thumbnail_setSelectedItems = function (items, force) {
  35. var selectable = this.viewOptions.thumbnail_selectable;
  36. var self = this;
  37. var i, $item, l, n;
  38. //this function is necessary because lint yells when a function is in a loop
  39. function compareItemIndex () {
  40. if (n === items[i].index) {
  41. $item = $(this);
  42. return false;
  43. } else {
  44. n++;
  45. }
  46. }
  47. //this function is necessary because lint yells when a function is in a loop
  48. function compareItemSelector () {
  49. $item = $(this);
  50. if ($item.is(items[i].selector)) {
  51. selectItem($item, items[i].selected);
  52. }
  53. }
  54. function selectItem ($itm, select) {
  55. select = (select !== undefined) ? select : true;
  56. if (select) {
  57. if (!force && selectable !== 'multi') {
  58. self.thumbnail_clearSelectedItems();
  59. }
  60. $itm.addClass('selected');
  61. } else {
  62. $itm.removeClass('selected');
  63. }
  64. }
  65. if (!$.isArray(items)) {
  66. items = [items];
  67. }
  68. if (force === true || selectable === 'multi') {
  69. l = items.length;
  70. } else if (selectable) {
  71. l = (items.length > 0) ? 1 : 0;
  72. } else {
  73. l = 0;
  74. }
  75. for (i = 0; i < l; i++) {
  76. if (items[i].index !== undefined) {
  77. $item = $();
  78. n = 0;
  79. this.$canvas.find('.repeater-thumbnail-cont .selectable').each(compareItemIndex);
  80. if ($item.length > 0) {
  81. selectItem($item, items[i].selected);
  82. }
  83. } else if (items[i].selector) {
  84. this.$canvas.find('.repeater-thumbnail-cont .selectable').each(compareItemSelector);
  85. }
  86. }
  87. };
  88. //ADDITIONAL DEFAULT OPTIONS
  89. $.fn.repeater.defaults = $.extend({}, $.fn.repeater.defaults, {
  90. thumbnail_alignment: 'left',
  91. thumbnail_infiniteScroll: false,
  92. thumbnail_itemRendered: null,
  93. thumbnail_selectable: false,
  94. thumbnail_template: '<div class="thumbnail repeater-thumbnail"><img height="75" src="{{src}}" width="65"><span>{{name}}</span></div>'
  95. });
  96. //EXTENSION DEFINITION
  97. $.fn.repeater.viewTypes.thumbnail = {
  98. selected: function () {
  99. var infScroll = this.viewOptions.thumbnail_infiniteScroll;
  100. var opts;
  101. if (infScroll) {
  102. opts = (typeof infScroll === 'object') ? infScroll : {};
  103. this.infiniteScrolling(true, opts);
  104. }
  105. },
  106. before: function (helpers) {
  107. var alignment = this.viewOptions.thumbnail_alignment;
  108. var $cont = this.$canvas.find('.repeater-thumbnail-cont');
  109. var data = helpers.data;
  110. var response = {};
  111. var $empty, validAlignments;
  112. if ($cont.length < 1) {
  113. $cont = $('<div class="clearfix repeater-thumbnail-cont" data-container="true" data-infinite="true" data-preserve="shallow"></div>');
  114. if (alignment && alignment !== 'none') {
  115. validAlignments = {
  116. 'center': 1,
  117. 'justify': 1,
  118. 'left': 1,
  119. 'right': 1
  120. };
  121. alignment = (validAlignments[alignment]) ? alignment : 'justify';
  122. $cont.addClass('align-' + alignment);
  123. this.thumbnail_injectSpacers = true;
  124. response.item = $cont;
  125. } else {
  126. this.thumbnail_injectSpacers = false;
  127. response.action = 'none';
  128. }
  129. }
  130. if (data.items && data.items.length < 1) {
  131. $empty = $('<div class="empty"></div>');
  132. $empty.append(this.viewOptions.thumbnail_noItemsHTML);
  133. $cont.append($empty);
  134. } else {
  135. $cont.find('.empty:first').remove();
  136. }
  137. return response;
  138. },
  139. renderItem: function (helpers) {
  140. var selectable = this.viewOptions.thumbnail_selectable;
  141. var selected = 'selected';
  142. var self = this;
  143. var $thumbnail = $(fillTemplate(helpers.subset[helpers.index], this.viewOptions.thumbnail_template));
  144. if (selectable) {
  145. $thumbnail.addClass('selectable');
  146. $thumbnail.on('click', function () {
  147. if (!$thumbnail.hasClass(selected)) {
  148. if (selectable !== 'multi') {
  149. self.$canvas.find('.repeater-thumbnail-cont .selectable.selected').each(function () {
  150. var $itm = $(this);
  151. $itm.removeClass(selected);
  152. self.$element.trigger('deselected.fu.repeaterThumbnail', $itm);
  153. });
  154. }
  155. $thumbnail.addClass(selected);
  156. self.$element.trigger('selected.fu.repeaterThumbnail', $thumbnail);
  157. } else {
  158. $thumbnail.removeClass(selected);
  159. self.$element.trigger('deselected.fu.repeaterThumbnail', $thumbnail);
  160. }
  161. });
  162. }
  163. helpers.container.append($thumbnail);
  164. if (this.thumbnail_injectSpacers) {
  165. $thumbnail.after('<span class="spacer">&nbsp;</span>');
  166. }
  167. if (this.viewOptions.thumbnail_itemRendered) {
  168. this.viewOptions.thumbnail_itemRendered({
  169. container: helpers.container,
  170. item: $thumbnail,
  171. itemData: helpers.subset[helpers.index]
  172. }, function () {});
  173. }
  174. return false;
  175. }
  176. };
  177. }
  178. //ADDITIONAL METHODS
  179. function fillTemplate (itemData, template) {
  180. var invalid = false;
  181. function replace () {
  182. var end, start, val;
  183. start = template.indexOf('{{');
  184. end = template.indexOf('}}', start + 2);
  185. if (start > -1 && end > -1) {
  186. val = $.trim(template.substring(start + 2, end));
  187. val = (itemData[val] !== undefined) ? itemData[val] : '';
  188. template = template.substring(0, start) + val + template.substring(end + 2);
  189. } else {
  190. invalid = true;
  191. }
  192. }
  193. while (!invalid && template.search('{{') >= 0) {
  194. replace(template);
  195. }
  196. return template;
  197. }
  198. // -- BEGIN UMD WRAPPER AFTERWORD --
  199. }));
  200. // -- END UMD WRAPPER AFTERWORD --