Created
April 25, 2013 18:28
-
-
Save lmccart/5461957 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Defines common functionality for toggleable components and components that | |
// may require the selection of files and folders. | |
// | |
// This view is intended to be extended (`ComponentBaseView.extend({...})`) | |
// rather than used directly. | |
define(['underscore', 'jquery', 'backbone', 'views/modal', | |
'collections/folders', 'collections/files', 'models/file', | |
'text!templates/component-toggle.html', | |
'text!templates/component-manage-files.html', | |
'text!templates/component-folder-modal.html', | |
'text!templates/component-file-modal.html'], | |
function (_, $, Backbone, ModalView, | |
Folders, Files, File, | |
componentToggleTmpl, | |
componentManageFilesTmpl, | |
componentFolderModalTmpl, | |
componentFileModalTmpl) { | |
return Backbone.View.extend({ | |
initialize: function () { | |
// Add a default set of templates to the view. | |
this.templates = _.extend({}, this.templates, { | |
// Renders a toggle button for enabling or disabling the component. | |
toggle: _.bind(function () { | |
var templateVars = _.extend({ | |
component: this.model.get(this.component.field) | |
}, this.component); | |
return _.template(componentToggleTmpl, templateVars); | |
}, this), | |
// Renders buttons to select folders/files for the component, and the | |
// current selected folders/files. | |
manageFiles: _.bind(function () { | |
var templateVars = _.extend({ | |
component: this.model.get(this.component.field), | |
files: this.model.get(this.component.field).files | |
}, this.component); | |
return _.template(componentManageFilesTmpl, templateVars); | |
}, this), | |
// Renders a modal dialog for selecting a folder for the component. | |
folderModal: _.template(componentFolderModalTmpl), | |
// Renders a modal dialog for selecting files for the component from | |
// the current active folder. | |
selectFileModal: _.template(componentFileModalTmpl) | |
}); | |
// Add a default set of events corresponding to the above templates. | |
this.events = _.extend({}, this.events, { | |
'click .btn.disable': 'disable', | |
'click .btn.enable': 'enable', | |
'click .btn.choose-folder': 'chooseFolder', | |
'click .btn.choose-files': 'chooseFiles', | |
// Make buttons disable & show "Saving..." when clicked. | |
'click .btn.saves': function (e) { | |
var button = $(e.currentTarget); | |
button.data('loading-text', 'Saving...').button('loading'); | |
}, | |
// Make buttons disable & show "Saving..." when clicked. | |
'click .btn.loads': function (e) { | |
var button = $(e.currentTarget); | |
button.data('loading-text', 'Loading...').button('loading'); | |
} | |
}); | |
}, | |
// Returns true if this view's component is currently enabled for this | |
// view's model. | |
isEnabled: function () { | |
return this.model.get(this.component.field).enabled; | |
}, | |
// Enables this view's component of this view's model. | |
enable: function () { | |
this.model.setEnabled(this.component.field, true); | |
}, | |
// Disables this view's component of this view's model. | |
disable: function () { | |
this.model.setEnabled(this.component.field, false); | |
}, | |
// Displays the "Select a Folder" modal. | |
// | |
// - `trigger` is the event that triggered the modal | |
// - `folders` is the folders collection to use for listing folders | |
showFolderModal: function (trigger, folders) { | |
// Create the modal. | |
var modal = new ModalView({ | |
title: 'Choose a Folder', | |
content: this.templates.folderModal({folders: folders}) | |
}); | |
// Persist the checked folder item to the preset model on save. | |
modal.on('save', _.bind(function (el) { | |
var selected = el.find('input[name="folder"]:checked').val(); | |
this.model.transform(this.component.field, function (component) { | |
return _.extend({}, component, { | |
folder: selected | |
}); | |
}); | |
this.model.setEnabled(this.component.field, selected); | |
this.model.save(); | |
this.syncFiles(); | |
}, this)); | |
// Reset the text of the button that triggered the modal, when the modal | |
// is closed. | |
modal.on('close', function () { | |
$(trigger.currentTarget).button('reset'); | |
}); | |
modal.show(); | |
}, | |
// Triggers the "Select a Folder" modal. | |
chooseFolder: function (e) { | |
// Fetch folders, and show the modal when they're synced. | |
var folders = new Folders(); | |
folders.once('sync', function () { | |
this.showFolderModal(e, folders); | |
}, this); | |
folders.fetch(); | |
}, | |
syncFiles: function() { | |
var files = new Files(this.model, this.component.field); | |
files.once('sync', function () { | |
// Get the current set of active files for this preset/component. | |
var activeFiles = this.model.getActiveFiles(this.component.field); | |
activeFiles.reset(); | |
console.log(files); | |
// For each file in selected folder, add it to the collection of active (selected) files. | |
files.each(function (item) { | |
if (activeFiles.get(item) === undefined) { | |
console.log(item); | |
activeFiles.add(item); | |
} | |
}); | |
// Overwrite the "files" property for the preset's component with | |
// the files from the active collection we just built. | |
this.model.transform(this.component.field, function (component) { | |
return _.extend({}, component, { | |
files: activeFiles.map(function (item) { | |
return item.attributes; | |
}) | |
}); | |
}); | |
this.model.save(); | |
}, this); | |
files.fetch(); | |
}, | |
// Displays the "Select Files" modal. | |
// | |
// - `trigger` is the event that triggered the modal | |
// - `files` is the files collection to use for listing files | |
showFilesModal: function (trigger, files) { | |
// Get the current set of active files for this preset/component. | |
var activeFiles = this.model.getActiveFiles(this.component.field); | |
// Create the modal. | |
var modal = new ModalView({ | |
title: 'Select Files', | |
content: this.templates.selectFileModal({ | |
activeFiles: activeFiles, | |
files: files | |
}) | |
}); | |
modal.on('save', _.bind(function (el) { | |
// For each file in the list of available files, if the file is | |
// checked, add it to the collection of active (selected) files if | |
// necessary, otherwise add it if necessary. | |
files.each(function (item) { | |
console.log(item); | |
// Determine whether the corresponding checkbox was checked. | |
var fileCheck = el.find('input[value="' + item.get('name') + '"]'); | |
var checked = fileCheck.is(':checked'); | |
if (checked && activeFiles.get(item) === undefined) { | |
activeFiles.add(item); | |
} else if (!checked && activeFiles.get(item) !== undefined) { | |
activeFiles.remove(item); | |
} | |
}); | |
// Overwrite the "files" property for the preset's component with | |
// the files from the active collection we just built. | |
this.model.transform(this.component.field, function (component) { | |
return _.extend({}, component, { | |
files: activeFiles.map(function (item) { | |
return item.attributes; | |
}) | |
}); | |
}); | |
this.model.save(); | |
}, this)); | |
// Reset the text of the button that triggered the modal, when the modal | |
// is closed. | |
modal.on('close', function () { | |
$(trigger.currentTarget).button('reset'); | |
}); | |
modal.show(); | |
}, | |
// Triggers the "Select Files" modal. | |
chooseFiles: function (e) { | |
// Fetch files for the current preset and component, and show the modal | |
// when they're synced. | |
var files = new Files(this.model, this.component.field); | |
files.once('sync', function () { | |
this.showFilesModal(e, files); | |
}, this); | |
files.fetch(); | |
} | |
}); | |
}); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment