PageRenderTime 64ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 1ms

/htdocs/wp-content/plugins/nextgen-gallery/products/photocrati_nextgen/modules/attach_to_post/templates/display_tab_js.php

https://github.com/Fishgate/privatecollectionswp
PHP | 1717 lines | 1332 code | 213 blank | 172 comment | 162 complexity | 7d5bfaf3366e9e6ec968261b54ed2aab MD5 | raw file

Large files files are truncated, but you can click here to view the full file

  1. jQuery(function($){
  2. /*****************************************************************************
  3. ** NGG DEFINITION
  4. ***/
  5. /**
  6. Setup a namespace for NextGEN-offered Backbone components
  7. **/
  8. var Ngg = {
  9. Models: {},
  10. Views: {}
  11. };
  12. /*****************************************************************************
  13. ** NGG MODELS
  14. ***/
  15. /**
  16. * Ngg.Models.SelectableItems
  17. * A collection of items that can be selectable. Commonly used with the
  18. * Ngg.Views.SelectTag widget (view)
  19. **/
  20. Ngg.Models.SelectableItems = Backbone.Collection.extend({
  21. selected: function(){
  22. return this.filter(function(item){
  23. return item.get('selected') == true;
  24. });
  25. },
  26. deselect_all: function(){
  27. this.each(function(item){
  28. item.set('selected', false);
  29. });
  30. },
  31. selected_ids: function(){
  32. return _.pluck(this.selected(), 'id');
  33. },
  34. select: function(ids){
  35. if (!_.isArray(ids)) ids = [ids];
  36. this.each(function(item){
  37. if (_.indexOf(ids, item.id) >= 0) {
  38. item.set('selected', true);
  39. }
  40. });
  41. this.trigger('selected');
  42. }
  43. });
  44. /*****************************************************************************
  45. ** NGG VIEWS
  46. ***/
  47. /**
  48. * Ngg.Views.SelectTag
  49. * Used to render a Select tag (drop-down list)
  50. **/
  51. Ngg.Views.SelectTag = Backbone.View.extend({
  52. tagName: 'select',
  53. collection: null,
  54. multiple: false,
  55. value_field: 'id',
  56. text_field: 'title',
  57. initialize: function(options) {
  58. this.options = options || {};
  59. _.each(this.options, function(value, key){
  60. this[key] = value;
  61. }, this);
  62. this.collection.on('add', this.render_new_option, this);
  63. this.collection.on('remove', this.remove_existing_option, this);
  64. this.collection.on('reset', this.empty_list, this);
  65. },
  66. events: {
  67. 'change': 'selection_changed'
  68. },
  69. empty_list: function(){
  70. this.$el.empty();
  71. },
  72. render_new_option: function(item){
  73. this.$el.append(new this.Option({
  74. model: item,
  75. value_field: this.value_field,
  76. text_field: this.text_field
  77. }).render().el);
  78. },
  79. remove_existing_option: function(item){
  80. this.$el.find("option[value='"+item.id+"']").remove();
  81. },
  82. /**
  83. * After a selection has changed, set the 'selected' property for each item in the
  84. * collection
  85. * @triggers 'selected'
  86. **/
  87. selection_changed: function(){
  88. // Get selected options from DOM
  89. var selections = _.map(this.$el.find(':selected'), function(element){
  90. return $(element).val();
  91. });
  92. // Set the 'selected' attribute for each item in the collection
  93. this.collection.each(function(item){
  94. if (_.indexOf(selections, item.id) >= 0 || _.indexOf(selections, item.id.toString()) >= 0)
  95. item.set('selected', true);
  96. else
  97. item.set('selected', false);
  98. });
  99. this.collection.trigger('selected');
  100. },
  101. render: function(){
  102. this.$el.empty();
  103. if (this.options.include_blank) {
  104. this.$el.append("<option></option>");
  105. }
  106. this.collection.each(function(item){
  107. var option = new this.Option({
  108. model: item,
  109. value_field: this.value_field,
  110. text_field: this.text_field
  111. });
  112. this.$el.append(option.render().el);
  113. }, this);
  114. if (this.multiple) this.$el.prop('multiple', true);
  115. if (this.width) this.$el.width(this.width);
  116. return this;
  117. },
  118. /**
  119. * Represents an option in the Select drop-down
  120. **/
  121. Option: Backbone.View.extend({
  122. tagName: 'option',
  123. model: null,
  124. initialize: function(options) {
  125. this.options = options || {};
  126. _.each(this.options, function(value, key){
  127. this[key] = value;
  128. }, this);
  129. this.model.on('change', this.render, this);
  130. },
  131. render: function(){
  132. var self = this;
  133. this.$el.html(this.model.get(this.text_field).replace(/\\&/g, '&').replace(/\\'/g, "'"));
  134. this.$el.prop({
  135. value: this.value_field == 'id' ? this.model.id : this.model.get(this.value_field),
  136. });
  137. if (self.model.get('selected') == true) {
  138. this.$el.attr('selected', 'selected');
  139. }
  140. return this;
  141. }
  142. })
  143. });
  144. Ngg.Views.Chosen = Backbone.View.extend({
  145. tagName: 'span',
  146. initialize: function(options) {
  147. this.options = options || {};
  148. this.collection = this.options.collection;
  149. if (!this.options.multiple) this.options.include_blank = true;
  150. this.select_tag = new Ngg.Views.SelectTag(this.options);
  151. this.collection.on('change', this.selection_changed, this);
  152. },
  153. selection_changed: function(e){
  154. if (_.isUndefined(e.changed['selected'])) this.render();
  155. },
  156. render: function(){
  157. this.$el.append(this.select_tag.render().$el);
  158. if (this.options.width)
  159. this.select_tag.$el.width(this.options.width);
  160. // Configure select2 options
  161. this.select2_opts = {
  162. placeholder: this.options.placeholder
  163. };
  164. // Create the select2 drop-down
  165. if (this.$el.parent().length == 0) {
  166. $('body').append(this.$el);
  167. this.select_tag.$el.select2(this.select2_opts);
  168. var container = this.select_tag.$el.select2('container').detach();
  169. this.$el.append(container);
  170. this.$el.detach();
  171. }
  172. else this.select_tag.$el.select2(this.select2_opts);
  173. // Hack for multi-select elements
  174. if (this.options.multiple && this.collection.selected().length == 0)
  175. this.select_tag.$el.select2('val', '');
  176. // For IE, ensure that the text field has a width
  177. this.$el.find('.select2-input').width(this.options.width-20);
  178. // For IE8, ensure that the selection is being displayed
  179. if (!this.options.multiple) {
  180. var selected_value = this.$el.find('.select2-choice span:first');
  181. if (selected_value.text().length == 0 && this.collection.selected().length > 0) {
  182. var selected_item = this.collection.selected().pop();
  183. selected_value.text(selected_item.get(this.select_tag.text_field));
  184. }
  185. }
  186. else {
  187. var selected_values = this.$el.find('.select2-search-choice');
  188. if (this.collection.selected().length > 0 && selected_values.length == 0) {
  189. this.select_tag.$el.select2('val', '');
  190. var data = [];
  191. var value_field = this.select_tag.value_field;
  192. _.each(this.collection.selected(), function(item){
  193. var value = value_field == 'id' ? item.id : item.get(value_field);
  194. data.push({
  195. id: value,
  196. text: item.get(this.select_tag.text_field)
  197. });
  198. }, this);
  199. this.select_tag.$el.select2('data', data);
  200. }
  201. }
  202. return this;
  203. }
  204. });
  205. /*****************************************************************************
  206. ** DISPLAY TAB DEFINITION
  207. ***/
  208. /**
  209. * Setup a namespace
  210. **/
  211. Ngg.DisplayTab = {
  212. Models: {},
  213. Views: {},
  214. App: {}
  215. };
  216. /*****************************************************************************
  217. * MODEL CLASSES
  218. **/
  219. /**
  220. * A collection that can fetch it's entities from the server
  221. **/
  222. Ngg.Models.Remote_Collection = Ngg.Models.SelectableItems.extend({
  223. fetch_limit: 5000,
  224. in_progress: false,
  225. fetch_url: photocrati_ajax.url,
  226. action: '',
  227. extra_data: {},
  228. _create_request: function(limit, offset) {
  229. var request = <?php echo $sec_token?>;
  230. request = _.extend(request, {
  231. action: this.action,
  232. limit: limit ? limit : this.fetch_limit,
  233. offset: offset ? offset : 0
  234. });
  235. for (var index in this.extra_data) {
  236. var value = this.extra_data[index];
  237. if (typeof(request[index]) == 'undefined') {
  238. request[index] = {};
  239. }
  240. if (typeof(value['toJSON']) != 'undefined') {
  241. value = value.toJSON();
  242. }
  243. request[index] = _.extend(request[index], value);
  244. }
  245. return request;
  246. },
  247. _add_item: function(item) {
  248. this.push(item);
  249. },
  250. fetch: function(limit, offset){
  251. // Request the entities from the server
  252. var self = this;
  253. this.in_progress = true;
  254. $.post(this.fetch_url, this._create_request(limit, offset), function(response){
  255. if (typeof(_) == 'undefined') return;
  256. if (!_.isObject(response)) response = JSON.parse(response);
  257. if (response.items) {
  258. _.each(response.items, function(item){
  259. self._add_item(item);
  260. });
  261. // Continue fetching ?
  262. if (response.total >= response.limit+response.offset) {
  263. self.fetch(response.limit, response.offset+response.limit);
  264. }
  265. else {
  266. self.in_progress = false;
  267. self.trigger('finished_fetching');
  268. }
  269. }
  270. });
  271. }
  272. });
  273. /**
  274. * Ngg.DisplayTab.Models.Displayed_Gallery
  275. * Represents the displayed gallery being edited or created by the Display Tab
  276. **/
  277. Ngg.DisplayTab.Models.Displayed_Gallery = Backbone.Model.extend({
  278. defaults: {
  279. source: null,
  280. container_ids: [],
  281. entity_ids: [],
  282. display_type: null,
  283. display_settings: {},
  284. exclusions: [],
  285. sortorder: [],
  286. slug: null
  287. }
  288. });
  289. /**
  290. * Ngg.DisplayTab.Models.Source
  291. * Represents an individual source used to collect displayable entities from
  292. **/
  293. Ngg.DisplayTab.Models.Source = Backbone.Model.extend({
  294. idAttribute: 'name',
  295. defaults: {
  296. title: '',
  297. name: '',
  298. selected: false
  299. }
  300. });
  301. /**
  302. * Ngg.DisplayTab.Models.Source_Collection
  303. * Used as a collection of all the available sources for entities
  304. **/
  305. Ngg.DisplayTab.Models.Source_Collection = Ngg.Models.SelectableItems.extend({
  306. model: Ngg.DisplayTab.Models.Source,
  307. selected_value: function(){
  308. var retval = null;
  309. var selected = this.selected();
  310. if (selected.length > 0) {
  311. retval = selected[0].get('name');
  312. }
  313. return retval;
  314. }
  315. });
  316. /**
  317. * Ngg.DisplayTab.Models.Gallery
  318. * Represents an individual gallery entity
  319. **/
  320. Ngg.DisplayTab.Models.Gallery = Backbone.Model.extend({
  321. idAttribute: '<?php echo $gallery_primary_key ?>',
  322. defaults: {
  323. title: '',
  324. name: ''
  325. }
  326. });
  327. /**
  328. * Ngg.DisplayTab.Models.Gallery_Collection
  329. * Collection of gallery objects
  330. **/
  331. Ngg.DisplayTab.Models.Gallery_Collection = Ngg.Models.Remote_Collection.extend({
  332. model: Ngg.DisplayTab.Models.Gallery,
  333. action: 'get_existing_galleries'
  334. });
  335. /**
  336. * Ngg.DisplayTab.Models.Album
  337. * Represents an individual Album object
  338. **/
  339. Ngg.DisplayTab.Models.Album = Backbone.Model.extend({
  340. defaults: {
  341. title: '',
  342. name: ''
  343. }
  344. });
  345. /**
  346. * Ngg.DisplayTab.Models.Album_Collection
  347. * Used as a collection of album objects
  348. **/
  349. Ngg.DisplayTab.Models.Album_Collection = Ngg.Models.Remote_Collection.extend({
  350. model: Ngg.DisplayTab.Models.Album,
  351. action: 'get_existing_albums'
  352. });
  353. /**
  354. * Ngg.DisplayTab.Models.Tag
  355. * Represents an individual tag object
  356. **/
  357. Ngg.DisplayTab.Models.Tag = Backbone.Model.extend({
  358. defaults: {
  359. title: ''
  360. }
  361. });
  362. /**
  363. * Ngg.DisplayTab.Models.Tag_Collection
  364. * Represents a collection of tag objects
  365. **/
  366. Ngg.DisplayTab.Models.Tag_Collection = Ngg.Models.Remote_Collection.extend({
  367. model: Ngg.DisplayTab.Models.Tag,
  368. /*
  369. selected_ids: function(){
  370. return this.selected().map(function(item){
  371. return item.get('name');
  372. });
  373. },
  374. */
  375. action: 'get_existing_image_tags'
  376. });
  377. /**
  378. * Ngg.DisplayTab.Models.Display_Type
  379. * Represents an individual display type
  380. **/
  381. Ngg.DisplayTab.Models.Display_Type = Backbone.Model.extend({
  382. idAttribute: 'name',
  383. defaults: {
  384. title: ''
  385. },
  386. is_compatible_with_source: function(source){
  387. var success = true;
  388. for (index in source.get('returns')) {
  389. var returned_entity_type = source.get('returns')[index];
  390. if (_.indexOf(this.get('entity_types'), returned_entity_type) < 0) {
  391. success = false;
  392. break;
  393. }
  394. }
  395. return success;
  396. }
  397. });
  398. /**
  399. * Ngg.DisplayTab.Models.Display_Type_Collection
  400. * Represents a collection of display type objects
  401. **/
  402. Ngg.DisplayTab.Models.Display_Type_Collection = Ngg.Models.SelectableItems.extend({
  403. model: Ngg.DisplayTab.Models.Display_Type,
  404. selected_value: function(){
  405. var retval = null;
  406. var selected = this.selected();
  407. if (selected.length > 0) {
  408. return selected[0].get('name');
  409. }
  410. return retval;
  411. }
  412. });
  413. /**
  414. * Ngg.DisplayTab.Models.Entity
  415. * Represents an entity to display on the front-end
  416. **/
  417. Ngg.DisplayTab.Models.Entity = Backbone.Model.extend({
  418. entity_id: function(){
  419. return this.get(this.get('id_field'));
  420. },
  421. is_excluded: function() {
  422. current_value = this.get('exclude');
  423. if (_.isUndefined(current_value)) return false;
  424. else if (_.isBoolean(current_value)) return current_value;
  425. else return parseInt(current_value) == 0 ? false : true;
  426. },
  427. is_included: function(){
  428. return !this.is_excluded();
  429. },
  430. is_gallery: function(){
  431. retval = false;
  432. if (this.get('is_gallery') == true) retval = true;
  433. return retval;
  434. },
  435. is_album: function(){
  436. retval = false;
  437. if (this.get('is_album') == true) retval = true;
  438. return retval;
  439. },
  440. is_image: function(){
  441. return !this.is_album() && !this.is_gallery();
  442. },
  443. alttext: function(){
  444. if (this.is_image()) {
  445. return this.get('alttext');
  446. }
  447. else if (this.is_gallery()) {
  448. return this.get('title');
  449. }
  450. else if (this.is_album()) {
  451. return this.get('name');
  452. }
  453. }
  454. });
  455. /**
  456. * Ngg.DisplayTab.Models.Entity_Collection
  457. * Represents a collection of entities
  458. **/
  459. Ngg.DisplayTab.Models.Entity_Collection = Ngg.Models.Remote_Collection.extend({
  460. model: Ngg.DisplayTab.Models.Entity,
  461. action: 'get_displayed_gallery_entities',
  462. _add_item: function(item){
  463. item.exclude = parseInt(item.exclude) == 1 ? true : false;
  464. item.is_gallery = parseInt(item.is_gallery) == 1 ? true : false;
  465. item.is_album = parseInt(item.is_album) == 1 ? true : false;
  466. this.push(item);
  467. },
  468. entity_ids: function(){
  469. return this.map(function(item){
  470. return item.entity_id();
  471. });
  472. },
  473. included_ids: function(){
  474. return _.compact(this.map(function(item){
  475. if (item.is_included()) return item.entity_id();
  476. }));
  477. },
  478. excluded_ids: function() {
  479. return _.compact(this.map(function(item) {
  480. if (!item.is_included()) {
  481. return item.entity_id();
  482. }
  483. }));
  484. }
  485. });
  486. Ngg.DisplayTab.Models.SortOrder = Backbone.Model.extend({
  487. });
  488. Ngg.DisplayTab.Models.SortOrder_Options = Ngg.Models.SelectableItems.extend({
  489. model: Ngg.DisplayTab.Models.SortOrder
  490. });
  491. Ngg.DisplayTab.Models.SortDirection = Backbone.Model.extend({
  492. });
  493. Ngg.DisplayTab.Models.SortDirection_Options = Backbone.Collection.extend({
  494. model: Ngg.DisplayTab.Models.SortDirection
  495. });
  496. Ngg.DisplayTab.Models.Slug = Backbone.Model.extend({});
  497. /*****************************************************************************
  498. * VIEW CLASSES
  499. **/
  500. /**
  501. * Ngg.DisplayTab.Views.Source_Config
  502. * Used to populate the source configuration tab
  503. **/
  504. Ngg.DisplayTab.Views.Source_Config = Backbone.View.extend({
  505. el: '#source_configuration',
  506. selected_view: null,
  507. /**
  508. * Bind to the "sources" collection to know when a selection has been made
  509. * and determine what sub-view to render
  510. **/
  511. initialize: function(){
  512. this.sources = Ngg.DisplayTab.instance.sources;
  513. this.sources.on('selected', this.render, this);
  514. _.bindAll(this, 'render');
  515. this.render();
  516. },
  517. render: function(){
  518. var chosen = new Ngg.Views.Chosen({
  519. id: 'source_select',
  520. collection: this.sources,
  521. placeholder: 'Select a source',
  522. width: 500
  523. });
  524. this.$el.html('<tr><td><label><?php _e('Sources', 'nggallery'); ?></label></td><td id="source_column"></td></tr>');
  525. this.$el.find('#source_column').append(chosen.render().el);
  526. var selected = this.sources.selected();
  527. if (selected.length) {
  528. var view_name = _.str.capitalize(selected.pop().id)+"Source";
  529. if (typeof(Ngg.DisplayTab.Views[view_name]) != 'undefined') {
  530. var selected_view = new Ngg.DisplayTab.Views[view_name];
  531. this.$el.append(selected_view.render().el);
  532. }
  533. }
  534. return this;
  535. }
  536. });
  537. Ngg.DisplayTab.Views.Slug_Config = Backbone.View.extend({
  538. el: '#slug_configuration',
  539. selected_view: null,
  540. initialize: function() {
  541. this.displayed_gallery = Ngg.DisplayTab.instance.displayed_gallery;
  542. this.slug = Ngg.DisplayTab.instance.displayed_gallery.get('slug');
  543. this.render();
  544. },
  545. render: function() {
  546. var self = this;
  547. var input = $('<input>').prop({
  548. type: 'text',
  549. name: 'slug',
  550. value: this.slug,
  551. placeholder: '<?php _e('(optional)', 'nggallery'); ?>',
  552. id: 'field_slug'
  553. });
  554. input.change(function() {
  555. self.displayed_gallery.set('slug', $(this).val());
  556. });
  557. var tooltip = '<?php _e('Sets an SEO-friendly name to this gallery for URLs. Currently only in use by the Pro Lightbox.', 'nggallery'); ?>';
  558. this.$el.append('<tr><td id="slug_label"><label for="field_slug" class="tooltip" title="' + tooltip + '"><?php _e('Slug', 'nggallery'); ?></label></td><td id="slug_column"></td></tr>');
  559. this.$el.find('#slug_column').append(input);
  560. return this;
  561. }
  562. });
  563. Ngg.DisplayTab.Views.Display_Type_Selector = Backbone.View.extend({
  564. el: '#display_type_selector',
  565. initialize: function(){
  566. this.display_types = Ngg.DisplayTab.instance.display_types;
  567. this.display_type_order_base = Ngg.DisplayTab.instance.display_type_order_base;
  568. this.display_type_order_step = Ngg.DisplayTab.instance.display_type_order_step;
  569. this.sources = Ngg.DisplayTab.instance.sources;
  570. this.render();
  571. },
  572. selection_changed: function(value){
  573. var selected_type = null;
  574. this.display_types.each(function(item){
  575. if (item.get('name') == value) {
  576. selected_type = item;
  577. item.set('selected', true);
  578. }
  579. else {
  580. item.set('selected', false);
  581. }
  582. });
  583. if (selected_type) {
  584. var selected_source = this.sources.selected_value();
  585. var default_source = selected_type.get('default_source');
  586. // If the default source isn't selected, then select it
  587. if (default_source && selected_source != default_source) {
  588. // Get the default source object by name
  589. default_source = this.sources.where({
  590. name: default_source
  591. });
  592. // Does the default source exist ?
  593. if (default_source.length > 0) {
  594. default_source = default_source[0];
  595. this.sources.deselect_all();
  596. this.sources.select(default_source.id);
  597. }
  598. }
  599. }
  600. $('.display_settings_form').each(function(){
  601. $this = $(this);
  602. if ($this.attr('rel') == value) $this.removeClass('hidden');
  603. else $this.addClass('hidden');
  604. });
  605. },
  606. render: function(){
  607. var selected_source = this.sources.selected();
  608. var current_step = 0;
  609. selected_source = selected_source.length > 0 ? selected_source[0] : false;
  610. this.$el.empty();
  611. var order_base = this.display_type_order_base;
  612. var order_step = this.display_type_order_step;
  613. this.display_types.each(function(item){
  614. if (selected_source && !item.is_compatible_with_source(selected_source)) {
  615. // Show all display types if we're viewing the display type
  616. // selector tab
  617. var display_tab = $('#display_type_tab_content:visible');
  618. if (display_tab.length == 0) return;
  619. else if (display_tab.css('visibility') == 'hidden') return;
  620. }
  621. var display_type = new this.DisplayType;
  622. display_type.model = item;
  623. display_type.on('selected', this.selection_changed, this);
  624. if (!this.display_types.selected_value()) {
  625. item.set('selected', true);
  626. this.selection_changed(item.id);
  627. }
  628. var display_order = item.get('view_order');
  629. if (!display_order)
  630. display_order = order_base;
  631. var display_step = Math.floor(display_order / order_step);
  632. if (current_step > 0 && display_step > current_step) {
  633. this.$el.append('<li class="clear" style="height: 10px" />');
  634. }
  635. current_step = display_step;
  636. this.$el.append(display_type.render().el);
  637. }, this);
  638. return this;
  639. },
  640. DisplayType: Backbone.View.extend({
  641. className: 'display_type_preview',
  642. events: {
  643. click: 'clicked'
  644. },
  645. clicked: function(e){
  646. this.trigger('selected', this.model.get('name'));
  647. },
  648. render: function() {
  649. // Create all elements
  650. var image_container = $('<div/>').addClass('image_container');
  651. // 2.0.66 did not support plugins_url, 2.0.66.3+ does
  652. var installed_at_version = this.model.get('installed_at_version');
  653. var baseurl = photocrati_ajax.wp_plugins_url;
  654. var preview_image_relpath = this.model.get('preview_image_relpath');
  655. if (typeof installed_at_version == 'undefined') {
  656. baseurl = photocrati_ajax.wp_site_url;
  657. // those who installed 2.0.66.3 lack the 'installed_at_version' setting but have a
  658. // plugin-relative path
  659. if (preview_image_relpath.indexOf('/nextgen-gallery') == 0) {
  660. baseurl = photocrati_ajax.wp_plugins_url;
  661. }
  662. }
  663. var img = $('<img/>').attr({
  664. src: baseurl + '/' + preview_image_relpath,
  665. title: this.model.get('title'),
  666. alt: this.model.get('alt')
  667. });
  668. var inner_div = $('<div/>');
  669. var radio_button = $('<input/>').prop({
  670. type: 'radio',
  671. value: this.model.get('name'),
  672. title: this.model.get('title'),
  673. name: 'display_type',
  674. checked: this.model.get('selected')
  675. });
  676. image_container.append(inner_div);
  677. image_container.append(img);
  678. inner_div.append(radio_button);
  679. inner_div.append(this.model.get('title'));
  680. this.$el.append(image_container);
  681. return this;
  682. }
  683. })
  684. });
  685. Ngg.DisplayTab.Views.Preview_Area = Backbone.View.extend({
  686. el: '#preview_area',
  687. initialize: function(){
  688. this.entities = Ngg.DisplayTab.instance.entities;
  689. this.sources = Ngg.DisplayTab.instance.sources;
  690. this.displayed_gallery = Ngg.DisplayTab.instance.displayed_gallery;
  691. // Create the entity list
  692. this.entity_list = $('<ul/>').attr('id', 'entity_list').append('<li class="clear"/>');
  693. // When an entity is added/removed to the collection, we'll add/remove it on the DOM
  694. this.entities.on('add', this.render_entity, this);
  695. this.entities.on('remove', this.remove_entity, this);
  696. // When the collection is reset, we add a list item to clear the float. This is important -
  697. // jQuery sortable() will break without the cleared element.
  698. this.entities.on('reset', this.entities_reset, this);
  699. // When jQuery sortable() is finished sorting, we need to adjust the order of models in the collection
  700. this.entities.on('change:sortorder', function(model){
  701. this.entities.remove(model, {silent: true});
  702. this.entities.add(model, {at: model.changed.sortorder, silent: true});
  703. this.displayed_gallery.set('sortorder', this.entities.entity_ids());
  704. if (typeof(console) != 'undefined' && typeof(console.log) != 'undefined') {
  705. console.log(this.entities.entity_ids());
  706. }
  707. this.displayed_gallery.set('order_by', 'sortorder');
  708. }, this);
  709. // Reset when the source changes
  710. this.sources.on('selected', this.render, this);
  711. this.render();
  712. },
  713. events: {
  714. opened: 'entities_reset'
  715. },
  716. entities_reset: function(e){
  717. this.entities.reset(null, {silent: true});
  718. this.entity_list.empty().append('<li class="clear"/>');
  719. if (!this.entities.in_progress) this.entities.fetch();
  720. },
  721. render_entity: function(model){
  722. var entity_element = new this.EntityElement({model: model});
  723. this.entity_list.find('.clear').before(entity_element.render().$el);
  724. entity_element.$el.css('visibility', 'hidden');
  725. setTimeout(function(){
  726. entity_element.$el.css('visibility', 'visible');
  727. }, 0);
  728. if (this.$el.find('.no_entities').length == 1) {
  729. this.render();
  730. }
  731. else if (this.entities.length > 1) {
  732. this.entity_list.sortable('refresh');
  733. }
  734. },
  735. remove_entity: function(model){
  736. var id = this.id = model.get('id_field')+'_'+model.entity_id();
  737. var entity = this.entity_list.find('#'+id).remove();
  738. this.entity_list.sortable('refresh');
  739. if (this.entities.length == 0) {
  740. this.render_no_images_notice();
  741. }
  742. },
  743. render_no_images_notice: function(){
  744. this.$el.empty();
  745. this.$el.append("<p class='no_entities'><?php _e('No entities to display for this source.', 'nggallery'); ?></p>");
  746. },
  747. render: function(){
  748. this.$el.empty();
  749. if (this.entities.length > 0 && this.displayed_gallery.get('container_ids').length > 0) {
  750. // Render header rows
  751. this.$el.append(new this.RefreshButton({
  752. entities: this.entities
  753. }).render().el);
  754. this.$el.append(new this.SortButtons({
  755. entities: this.entities,
  756. displayed_gallery: this.displayed_gallery,
  757. sources: this.sources
  758. }).render().el);
  759. this.$el.append(new this.ExcludeButtons({
  760. entities: this.entities
  761. }).render().el);
  762. this.$el.append(this.entity_list);
  763. // Activate jQuery Sortable for the entity list
  764. this.entity_list.sortable({
  765. placeholder: 'placeholder',
  766. forcePlaceholderSize: true,
  767. containment: 'parent',
  768. opacity: 0.7,
  769. revert: true,
  770. dropOnEmpty: true,
  771. start: function(e, ui){
  772. ui.placeholder.css({
  773. height: ui.item.height()
  774. });
  775. return true;
  776. },
  777. stop: function(e, ui) {
  778. ui.item.trigger('drop', ui.item.index());
  779. }
  780. });
  781. this.entity_list.disableSelection();
  782. }
  783. else {
  784. this.render_no_images_notice();
  785. }
  786. return this;
  787. },
  788. RefreshButton: Backbone.View.extend({
  789. className: 'refresh_button',
  790. tagName: 'input',
  791. label: 'Refresh',
  792. events: {
  793. click: 'clicked'
  794. },
  795. clicked: function(){
  796. this.entities.reset();
  797. },
  798. initialize: function(options) {
  799. this.options = options || {};
  800. _.each(this.options, function(value, key){
  801. this[key] = value;
  802. }, this);
  803. },
  804. render: function(){
  805. this.$el.attr({
  806. value: this.label,
  807. type: 'button'
  808. });
  809. return this;
  810. }
  811. }),
  812. ExcludeButtons: Backbone.View.extend({
  813. className: 'header_row',
  814. initialize: function(options) {
  815. this.options = options || {};
  816. _.each(this.options, function(value, key){
  817. this[key] = value;
  818. }, this);
  819. },
  820. render: function(){
  821. this.$el.empty();
  822. this.$el.append('<strong>Exclude:</strong>');
  823. var all_button = new this.Button({
  824. value: true,
  825. text: 'All',
  826. entities: this.entities
  827. });
  828. this.$el.append(all_button.render().el);
  829. this.$el.append('<span class="separator">|</span>');
  830. var none_button = new this.Button({
  831. value: false,
  832. text: 'None',
  833. entities: this.entities
  834. });
  835. this.$el.append(none_button.render().el);
  836. return this;
  837. },
  838. Button: Backbone.View.extend({
  839. tagName: 'a',
  840. value: 1,
  841. text: '',
  842. events: {
  843. click: 'clicked'
  844. },
  845. initialize: function(options) {
  846. this.options = options || {};
  847. _.each(this.options, function(value, key){
  848. this[key] = value;
  849. }, this);
  850. },
  851. clicked: function(e){
  852. e.preventDefault();
  853. this.entities.each(function(item){
  854. item.set('exclude', this.value);
  855. }, this);
  856. },
  857. render: function(){
  858. this.$el.text(this.text).attr('href', '#');
  859. return this;
  860. }
  861. })
  862. }),
  863. SortButtons: Backbone.View.extend({
  864. className: 'header_row',
  865. initialize: function(options) {
  866. this.options = options || {};
  867. _.each(this.options, function(value, key){
  868. this[key] = value;
  869. }, this);
  870. this.sortorder_options = new Ngg.DisplayTab.Models.SortOrder_Options();
  871. this.sortorder_options.on('change:selected', this.sortoption_changed, this);
  872. // Create sort directions and listen for selection changes
  873. this.sortdirection_options = new Ngg.DisplayTab.Models.SortDirection_Options([
  874. {
  875. value: 'ASC',
  876. title: 'Ascending',
  877. selected: this.displayed_gallery.get('order_direction') == 'ASC'
  878. },
  879. {
  880. value: 'DESC',
  881. title: 'Descending',
  882. selected: this.displayed_gallery.get('order_direction') == 'DESC'
  883. }
  884. ]);
  885. this.sortdirection_options.on('change:selected', this.sortdirection_changed, this);
  886. this.displayed_gallery.on('change:order_by', this.displayed_gallery_order_changed, this);
  887. this.displayed_gallery.on('change.order_direction', this.displayed_gallery_order_dir_changed, this);
  888. },
  889. populate_sorting_fields: function(){
  890. // We display difference sorting buttons depending on what type of entities we're dealing with.
  891. var entity_types = this.sources.selected().pop().get('returns');
  892. if (_.indexOf(entity_types, 'image') !== -1) {
  893. this.fill_image_sortorder_options();
  894. }
  895. else {
  896. this.fill_gallery_sortorder_options();
  897. }
  898. },
  899. create_sortorder_option: function(name, title){
  900. return new Ngg.DisplayTab.Models.SortOrder({
  901. name: name,
  902. title: title,
  903. value: name,
  904. selected: this.displayed_gallery.get('order_by') == name
  905. });
  906. },
  907. fill_image_sortorder_options: function(){
  908. this.sortorder_options.reset();
  909. this.sortorder_options.push(this.create_sortorder_option('', 'None'));
  910. this.sortorder_options.push(this.create_sortorder_option('sortorder', 'Custom'));
  911. this.sortorder_options.push(this.create_sortorder_option(Ngg.DisplayTab.instance.image_key, 'Image ID'));
  912. this.sortorder_options.push(this.create_sortorder_option('filename', 'Filename'));
  913. this.sortorder_options.push(this.create_sortorder_option('alttext', 'Alt/Title Text'));
  914. this.sortorder_options.push(this.create_sortorder_option('imagedate', 'Date/Time'));
  915. },
  916. fill_gallery_sortorder_options: function(){
  917. this.sortorder_options.reset();
  918. this.sortorder_options.push(this.create_sortorder_option('', 'None'));
  919. this.sortorder_options.push(this.create_sortorder_option('sortorder' ,'Custom'));
  920. this.sortorder_options.push(this.create_sortorder_option('name', 'Name'));
  921. this.sortorder_options.push(this.create_sortorder_option('galdesc', 'Description'));
  922. },
  923. displayed_gallery_order_changed: function(e){
  924. this.sortorder_options.findWhere({value: e.get('order_by')}).set('selected', true);
  925. },
  926. displayed_gallery_order_dir_changed: function(e){
  927. this.sortdirection_options.findWhere({value: e.get('order_direction')}).set('selected', true);
  928. },
  929. sortoption_changed: function(model){
  930. this.sortorder_options.each(function(item){
  931. item.set('selected', model.get('value') == item.get('value') ? true : false, {silent: true});
  932. });
  933. this.displayed_gallery.set('sortorder', []);
  934. var sort_by = model.get('value');
  935. // If "None" was selected, then clear the "sortorder" property
  936. if (model.get('value').length == 0) {
  937. sort_by = 'sortorder';
  938. }
  939. // Change the "sort by" parameter
  940. this.displayed_gallery.set('order_by', sort_by);
  941. this.entities.reset();
  942. this.$el.find('a.sortorder').each(function(){
  943. var $item = $(this);
  944. if ($item.attr('value') == model.get('value'))
  945. $item.addClass('selected');
  946. else
  947. $item.removeClass('selected');
  948. });
  949. },
  950. sortdirection_changed: function(model){
  951. this.sortdirection_options.each(function(item){
  952. item.set('selected', model.get('value') == item.get('value') ? true : false, {silent: true});
  953. });
  954. this.displayed_gallery.set('order_direction', model.get('value'));
  955. this.entities.reset();
  956. this.$el.find('a.sortdirection').each(function(){
  957. var $item = $(this);
  958. if ($item.attr('value') == model.get('value'))
  959. $item.addClass('selected');
  960. else
  961. $item.removeClass('selected');
  962. });
  963. },
  964. render: function(){
  965. this.$el.empty();
  966. this.populate_sorting_fields();
  967. this.$el.append('<strong>Sort By:</strong>');
  968. this.sortorder_options.each(function(item, index){
  969. var button = new this.Button({model: item, className: 'sortorder'});
  970. this.$el.append(button.render().el);
  971. if (this.sortorder_options.length-1 > index) {
  972. this.$el.append('<span class="separator">|</span>');
  973. }
  974. }, this);
  975. this.$el.append('<strong style="margin-left: 30px;">Order By:</strong>');
  976. this.sortdirection_options.each(function(item, index){
  977. var button = new this.Button({model: item, className: 'sortdirection'});
  978. this.$el.append(button.render().el);
  979. if (this.sortdirection_options.length-1 > index) {
  980. this.$el.append('<span class="separator">|</span>');
  981. }
  982. }, this);
  983. return this;
  984. },
  985. Button: Backbone.View.extend({
  986. tagName: 'a',
  987. initialize: function(options) {
  988. this.options = options || {};
  989. _.each(this.options, function(value, key){
  990. this[key] = value;
  991. }, this);
  992. },
  993. events: {
  994. click: 'clicked'
  995. },
  996. clicked: function(e){
  997. e.preventDefault();
  998. this.model.set('selected', true);
  999. },
  1000. render: function(){
  1001. this.$el.prop({
  1002. value: this.model.get('value'),
  1003. href: '#'
  1004. });
  1005. this.$el.text(this.model.get('title'));
  1006. if (this.model.get('selected')) this.$el.addClass('selected');
  1007. return this;
  1008. }
  1009. })
  1010. }),
  1011. // Individual entity in the preview area
  1012. EntityElement: Backbone.View.extend({
  1013. tagName: 'li',
  1014. events: {
  1015. drop: 'item_dropped'
  1016. },
  1017. initialize: function(options) {
  1018. this.options = options || {};
  1019. _.each(this.options, function(value, key){
  1020. this[key] = value;
  1021. }, this);
  1022. this.model.on('change', this.render, this);
  1023. if (this.model.get('sortorder') == 0) {
  1024. this.model.set('sortorder', -1, {silent: true});
  1025. }
  1026. this.id = this.model.get('id_field')+'_'+this.model.entity_id()
  1027. },
  1028. item_dropped: function(e, index){
  1029. Ngg.DisplayTab.instance.displayed_gallery.set('order_by', 'sortorder');
  1030. //Ngg.DisplayTab.instance.displayed_gallery.set('order_direction', 'ASC');
  1031. this.model.set('sortorder', index);
  1032. },
  1033. render: function(){
  1034. this.$el.empty();
  1035. var image_container = $('<div/>').addClass('image_container');
  1036. var alt_text = this.model.alttext().replace(/\\&/g, '&').replace(/\\'/g, "'");
  1037. var timestamp = new Date().getTime();
  1038. image_container.attr({
  1039. title: alt_text,
  1040. style: "background-image: url('"+this.model.get('thumb_url')+"?timestamp"+timestamp+"')"
  1041. }).css({
  1042. width: this.model.get('max_width'),
  1043. height: this.model.get('max_height'),
  1044. 'max-width': this.model.get('max_width'),
  1045. 'max-height': this.model.get('max_height')
  1046. });
  1047. this.$el.append(image_container).addClass('ui-state-default');
  1048. // Add exclude checkbox
  1049. var exclude_container = $('<div/>').addClass('exclude_container');
  1050. exclude_container.append('Exclude?');
  1051. var exclude_checkbox = new this.ExcludeCheckbox({model: this.model});
  1052. exclude_container.append(exclude_checkbox.render().el);
  1053. image_container.append(exclude_container);
  1054. return this;
  1055. },
  1056. ExcludeCheckbox: Backbone.View.extend({
  1057. tagName: 'input',
  1058. events: {
  1059. 'change': 'entity_excluded'
  1060. },
  1061. type_set: false,
  1062. entity_excluded: function(e){
  1063. this.model.set('exclude', e.target.checked);
  1064. },
  1065. initialize: function(options) {
  1066. this.options = options || {};
  1067. _.each(this.options, function(value, key){
  1068. this[key] = value;
  1069. }, this);
  1070. this.model.on('change:exclude', this.render, this);
  1071. },
  1072. render: function(){
  1073. if (!this.type_set) {
  1074. this.$el.attr('type', 'checkbox');
  1075. this.type_set = true;
  1076. }
  1077. if (this.model.is_excluded()) this.$el.prop('checked', true);
  1078. else this.$el.prop('checked', false);
  1079. return this;
  1080. }
  1081. })
  1082. })
  1083. });
  1084. // Additional source configuration views. These will be rendered dynamically by PHP.
  1085. // Adapters will add them.
  1086. Ngg.DisplayTab.Views.GalleriesSource = Backbone.View.extend({
  1087. tagName: 'tbody',
  1088. initialize: function(){
  1089. this.galleries = Ngg.DisplayTab.instance.galleries;
  1090. },
  1091. render: function(){
  1092. var select = new Ngg.Views.Chosen({
  1093. collection: this.galleries,
  1094. placeholder: '<?php _e('Select a gallery', 'nggallery'); ?>',
  1095. multiple: true,
  1096. width: 500
  1097. });
  1098. var html = $('<tr><td><label><?php _e('Galleries', 'nggallery'); ?></label></td><td class="galleries_column"></td></tr>');
  1099. this.$el.empty();
  1100. this.$el.append(html);
  1101. this.$el.find('.galleries_column').append(select.render().el);
  1102. return this;
  1103. }
  1104. });
  1105. Ngg.DisplayTab.Views.AlbumsSource = Backbone.View.extend({
  1106. tagName: 'tbody',
  1107. initialize: function(){
  1108. this.albums = Ngg.DisplayTab.instance.albums;
  1109. },
  1110. render: function(){
  1111. var album_select = new Ngg.Views.Chosen({
  1112. collection: this.albums,
  1113. multiple: true,
  1114. placeholder: 'Select an album',
  1115. text_field: 'name',
  1116. width: 500
  1117. });
  1118. this.$el.empty();
  1119. this.$el.append('<tr><td><label><?php _e('Albums', 'nggallery'); ?></label></td><td class="albums_column"></td></tr>');
  1120. this.$el.find('.albums_column').append(album_select.render().el);
  1121. return this;
  1122. }
  1123. });
  1124. Ngg.DisplayTab.Views.TagsSource = Backbone.View.extend({
  1125. tagName: 'tbody',
  1126. initialize: function(){
  1127. this.tags = Ngg.DisplayTab.instance.tags;
  1128. },
  1129. render: function(){
  1130. var tag_select = new Ngg.Views.Chosen({
  1131. collection: this.tags,
  1132. multiple: true,
  1133. placeholder: 'Select a tag',
  1134. text_field: 'name',
  1135. width: 500
  1136. });
  1137. this.$el.empty();
  1138. this.$el.append('<tr><td><label>Tags</label></td><td class="tags_column"></td></tr>');
  1139. this.$el.find('.tags_column').append(tag_select.render().el);
  1140. return this;
  1141. }
  1142. });
  1143. Ngg.DisplayTab.Views.Recent_imagesSource = Backbone.View.extend({
  1144. tagName: 'tbody',
  1145. initialize: function(){
  1146. this.displayed_gallery = Ngg.DisplayTab.instance.displayed_gallery;
  1147. this.maximum_entity_count = Ngg.DisplayTab.instance.displayed_gallery.get('maximum_entity_count');
  1148. this.displayed_gallery.set('container_ids', []);
  1149. },
  1150. render: function(){
  1151. var self = this;
  1152. var edit_field = $('<input/>').prop({
  1153. type: 'text',
  1154. value: this.maximum_entity_count,
  1155. name: 'maximum_entity_count'
  1156. });
  1157. edit_field.change(function () {
  1158. self.displayed_gallery.set('maximum_entity_count', $(this).val());
  1159. });
  1160. this.$el.empty();
  1161. this.$el.append('<tr><td><label># of Images To Display</label></td><td class="recent_images_column"></td></tr>');
  1162. this.$el.find('.recent_images_column').append(edit_field);
  1163. return this;
  1164. }
  1165. });
  1166. Ngg.DisplayTab.Views.Random_imagesSource = Backbone.View.extend({
  1167. tagName: 'tbody',
  1168. initialize: function(){
  1169. this.displayed_gallery = Ngg.DisplayTab.instance.displayed_gallery;
  1170. this.maximum_entity_count = Ngg.DisplayTab.instance.displayed_gallery.get('maximum_entity_count');
  1171. this.displayed_gallery.set('container_ids', []);
  1172. },
  1173. render: function(){
  1174. var self = this;
  1175. var edit_field = $('<input/>').prop({
  1176. type: 'text',
  1177. value: this.maximum_entity_count,
  1178. name: 'maximum_entity_count'
  1179. });
  1180. edit_field.change(function () {
  1181. self.displayed_gallery.set('maximum_entity_count', $(this).val());
  1182. });
  1183. this.$el.empty();
  1184. this.$el.append('<tr><td><label># of Images To Display</label></td><td class="random_images_column"></td></tr>');
  1185. this.$el.find('.random_images_column').append(edit_field);
  1186. return this;
  1187. }
  1188. });
  1189. Ngg.DisplayTab.Views.SaveButton = Backbone.View.extend({
  1190. el: '#save_displayed_gallery',
  1191. errors_el: '#errors',
  1192. displayed_gallery: null,
  1193. events: {
  1194. click: 'clicked'
  1195. },
  1196. initialize: function(){
  1197. this.displayed_gallery = Ngg.DisplayTab.instance.displayed_gallery;
  1198. this.entities = Ngg.DisplayTab.instance.entities;
  1199. this.render();
  1200. },
  1201. clicked: function(){
  1202. this.set_display_settings();
  1203. var request = <?php echo $sec_token?>;
  1204. request = _.extend(request, {
  1205. action: 'save_displayed_gallery',
  1206. displayed_gallery: JSON.stringify(this.displayed_gallery.toJSON())
  1207. });
  1208. var self = this;
  1209. $.post(photocrati_ajax.url, request, function(response){
  1210. if (!_.isObject(response)) response = JSON.parse(response);
  1211. if (response['validation_errors'] != undefined) {
  1212. $(self.errors_el).empty().append(response.validation_errors);
  1213. }
  1214. else if (response['error'] != undefined) {
  1215. alert(response.error);
  1216. }
  1217. else {
  1218. var id_field = response.displayed_gallery.id_field;
  1219. var id = response.displayed_gallery[id_field];
  1220. self.displayed_gallery.set('id', id);
  1221. var editor = parent.tinyMCE.activeEditor;
  1222. var preview_url = ngg_displayed_gallery_preview_url + '/id--'+id;
  1223. var snippet = "<img class='ngg_displayed_gallery mceItem' src='" + preview_url + "'/>";
  1224. if (editor.getContent().indexOf(preview_url) < 0)
  1225. editor.execCommand('mceInsertContent', false, snippet);
  1226. else {
  1227. $(editor.contentDocument).find(".ngg_displayed_gallery[src='"+preview_url+"']").attr('src', preview_url);
  1228. }
  1229. close_attach_to_post_window();
  1230. }
  1231. });
  1232. },
  1233. set_display_settings: function(){
  1234. var display_type = this.displayed_gallery.get('display_type');
  1235. if (display_type) {
  1236. // Collect display settings
  1237. var form = $("form[rel='"+display_type+"']");
  1238. var display_settings = (function(item){
  1239. var obj = {};
  1240. $.each(item.serializeArray(), function(key, item) {
  1241. var parts = item.name.split('[');
  1242. var current_obj = obj;
  1243. for (var i=0; i<parts.length; i++) {
  1244. var part = parts[i].replace(/\]$/, '');
  1245. if (!current_obj[part]) {
  1246. if (i == parts.length-1)
  1247. current_obj[part] = item.value;
  1248. else
  1249. current_obj[part] = {};
  1250. }
  1251. current_obj = current_obj[part];
  1252. }
  1253. });
  1254. return obj;
  1255. })(form);
  1256. // Set display settings for displayed gallery
  1257. this.displayed_gallery.set('display_settings', display_settings[display_type]);
  1258. }
  1259. },
  1260. render: function(){
  1261. return this;
  1262. }
  1263. });
  1264. /*****************************************************************************
  1265. * APPLICATION
  1266. **/
  1267. Ngg.DisplayTab.App = Backbone.View.extend({
  1268. /**
  1269. * Initializes the DisplayTab object
  1270. **/
  1271. initialize: function(){
  1272. // TODO: We're currently fetching ALL galleries, albums, and tags
  1273. // in one shot. Instead, we should display the displayed_gallery's
  1274. // containers, if there are any, otherwise get the first 100 or so.
  1275. // We can then use AJAX to fetch the rest of batches.
  1276. this.displayed_gallery = new Ngg.DisplayTab.Models.Displayed_Gallery(
  1277. <?php echo $displayed_gallery ?>
  1278. );
  1279. this.original_displayed_gallery = new Ngg.DisplayTab.Models.Displayed_Gallery(
  1280. <?php echo $displayed_gallery ?>
  1281. );
  1282. this.galleries = new Ngg.DisplayTab.Models.Gallery_Collection(
  1283. <?php echo $galleries ?>
  1284. );
  1285. this.albums = new Ngg.DisplayTab.Models.Album_Collection(
  1286. <?php echo $albums ?>
  1287. );
  1288. this.tags = new Ngg.DisplayTab.Models.Tag_Collection(
  1289. <?php echo $tags ?>
  1290. );
  1291. this.sources = new Ngg.DisplayTab.Models.Source_Collection(
  1292. <?php echo $sources ?>
  1293. )
  1294. this.display_types = new Ngg.DisplayTab.Models.Display_Type_Collection(
  1295. <?php echo $display_types ?>
  1296. );
  1297. this.display_type_order_base = <?php echo NGG_DISPLAY_PRIORITY_BASE; ?>;
  1298. this.display_type_order_step = <?php echo NGG_DISPLAY_PRIORITY_STEP; ?>;
  1299. this.entities = new Ngg.DisplayTab.Models.Entity_Collection();
  1300. this.entities.extra_data.displayed_gallery = this.displayed_gallery;
  1301. this.image_key = "<?php echo $image_primary_key ?>";
  1302. // Pre-select current displayed gallery values
  1303. if (this.displayed_gallery.get('source')) {
  1304. // Pre-select source
  1305. if (this.displayed_gallery.get('source')) {
  1306. var source = this.sources.find(function(item){
  1307. return item.get('name') == this.displayed_gallery.get('source');
  1308. }, this);
  1309. if (source) source.set('selected', true);
  1310. }
  1311. // Pre-select containers
  1312. if (this.displayed_gallery.get('container_ids')) {
  1313. _.each(this.displayed_gallery.get('container_ids'), function(id){
  1314. var container = this[this.displayed_gallery.get('source')].find(function(item){
  1315. return item.id == id;
  1316. }, this);
  1317. if (container) container.set('selected', true);
  1318. }, this);
  1319. }
  1320. // Pre-select display type
  1321. if (this.displayed_gallery.get('display_type')) {
  1322. var display_type = this.display_types.find(function(item){
  1323. return item.get('name') == this.displayed_gallery.get('display_type');
  1324. }, this);
  1325. if (display_type) display_type.set('selected', true);
  1326. }
  1327. }
  1328. // Bind to the 'selected' event for each of the collections, and update the displayed
  1329. // gallery object's 'container_ids' attribute when something has changed
  1330. collections = ['galleries', 'albums', 'tags'];
  1331. _.each(collections, function(collection){
  1332. this[collection].on('selected', function(){this.update_selected_containers(collection);}, this);
  1333. }, this);
  1334. // Bind to the 'selected' event for the display types collection, updating the displayed gallery
  1335. this.display_types.on('change:selected', function(){
  1336. this.displayed_gallery.set('display_type', this.display_types.selected_value());
  1337. }, this);
  1338. // Bind to the 'selected' event for the source, updating the displayed gallery
  1339. this.sources.on('selected', function(){
  1340. this.displayed_gallery.set('source', this.sources.selected_value());
  1341. // If the source changed, and it's not the set to the original value, then
  1342. // exclusions get's set to []
  1343. if (this.sources.selected_value() != this.original_displayed_gallery.get('source'))
  1344. this.displayed_gallery.set('exclusions', this.entities.excluded_ids());
  1345. // Otherwise, we revert to the original exclusions
  1346. else
  1347. this.displayed_gallery.set('exclusions', this.original_displayed_gallery.get('exclusions'));
  1348. // special exemption: these should default to a reasonable limit
  1349. if (this.sources.selected_value() == 'random_images' || this.sources.selected_value() == 'recent_images') {
  1350. this.displayed_gallery.set('maximum_entity_count', 20);
  1351. }
  1352. // Reset everything else
  1353. this.galleries.deselect_all();
  1354. this.albums.deselect_all();
  1355. this.tags.deselect_all();
  1356. // If the selected source is incompatible with the current display type, then
  1357. // display a new list
  1358. var selected_display_type = this.display_types.selected();
  1359. var selected_source = this.sources.selected();
  1360. if (selected_display_type.length > 0 && selected_source.length > 0) {
  1361. selected_display_type = selected_display_type[0];
  1362. selected_source = selected_source[0];
  1363. if (!selected_display_type.is_compatible_with_source(selected_source))
  1364. this.display_types.deselect_all();
  1365. if (this.display_type_selector) this.display_type_selector.render();
  1366. }
  1367. if (this.preview_area) this.preview_area.render();
  1368. }, this);
  1369. // Synchronize changes made to entities with the displayed gallery
  1370. this.entities.on('change:exclude finished_fetching', function(){
  1371. //this.displayed_gallery.set('sortorder', this.entities.entity_ids());
  1372. this.displayed_gallery.set('exclusions', this.entities.excluded_ids());
  1373. }, this);
  1374. // Monitor events in other tabs and respond as appropriate
  1375. if (window.Frame_Event_Publisher) {
  1376. var app = this;
  1377. // New gallery event
  1378. Frame_Event_Publisher.listen_for('attach_to_post:new_gallery', function(){
  1379. app.galleries.reset();
  1380. app.galleries.fetch();
  1381. });
  1382. // A change has been made using the "Manage Galleries" page
  1383. Frame_Event_Publisher.listen_for('attach_to_post:manage_galleries attach_to_post:manage_images', function(data){
  1384. // Refresh the list of galleries
  1385. app.galleries.reset();
  1386. app.galleries.fetch();
  1387. // If we're viewing galleries or images, then we need to refresh the entity list
  1388. var selected_source = app.sources.selected().pop();
  1389. if (selected_source) {
  1390. if (_.indexOf(selected_source.get('returns'), 'image') >= 0 ||
  1391. _.indexOf(selected_source.get('returns'), 'gallery')) {
  1392. app.entities.reset();
  1393. }
  1394. }
  1395. });
  1396. // A change has been made using the "Manage Albums" page
  1397. Frame_Event_Publisher.listen_for('attach_to_post:manage_album', function(data){
  1398. // Refresh the list of albums
  1399. app.albums.reset();
  1400. app.albums.fetch();
  1401. // If we're viewing albums, then we need to refresh the entity list
  1402. var selected_source = app.sources.selected().pop();
  1403. if (selected_source) {
  1404. if (_.indexOf(selected_source.get('returns'), 'album') >= 0) {
  1405. app.entities.reset();
  1406. }
  1407. }
  1408. });
  1409. /

Large files files are truncated, but you can click here to view the full file