Skip to content

Instantly share code, notes, and snippets.

@dstibrany
Created August 4, 2012 21:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dstibrany/3259917 to your computer and use it in GitHub Desktop.
Save dstibrany/3259917 to your computer and use it in GitHub Desktop.
Search View
define([
"app",
"modules/search/searchmodels"
],
function(app, SearchModels) {
var Views = {};
// Utilities
// ----------------
Views.util = {
resizeInput: function (input) {
var $input = $(input);
var length = $input.val().length;
var font_size = parseInt($input.css('fontSize'), 10);
var denominator = 1.3;
$input.css('width', ( length * (font_size / denominator) ) + 10 + 'px');
}
};
// Search View
// -----------
Views.Search = Backbone.View.extend({
template: 'search/search',
id: 'search',
className: 'input-append',
initialize: function() {
this.collection.on('add', function() {
this.render();
}, this);
this.collection.on('destroy', function(model) {
this.render();
this.search();
}, this);
app.on('search:init', this.init, this);
// listen for change to folder/tag names so that the search bar can be updated
app.on('search:rename', this.rename, this);
// listen for deletions of folder/tags so that the search bar can be updated
app.on('search:destroy', this.destroy, this);
},
beforeRender: function(manage) {
var type;
var self = this;
var text;
// helper function to allow us to set or append
function setView(type, model, append) {
var insert_mode = append ? 'insertView' : 'setView';
var view;
if (type === 'text') {
view = new Views.SearchItemText({
model: model,
collection: self.collection
});
} else {
view = new Views.SearchItem({
model: model
});
}
self[insert_mode]('#' + type + '-search', view);
}
this.collection.each(function(model) {
type = model.get('type');
// insert in a different DOM location, depending on whether the model is a tag or a folder
if (type === 'tid') {
setView('tags', model, true);
} else if (type === 'fid') {
setView('folders', model);
} else if (type === 'text') {
setView('text', model);
}
});
},
afterRender: function() {
// resize the text box on re-render of the search view
Views.util.resizeInput(self.$('input'));
},
init: function(search_data) {
var model;
// convert search data into a model if it's not already a model
if (search_data && !(search_data instanceof Backbone.Model)) {
model = new SearchModels.Models.Model(search_data);
// a model of type textSearchModel was passed in
} else {
model = search_data;
}
// if no model exists then pass null to access all documents
if (!model) {
this.search(null);
// if the root folder was clicked then clear the search bar, trigger a search for all docs
} else if (model.get('id') === 'root') {
this.destroy(this.collection.where({type: 'fid'})[0]);
// if they are clicking on a non-selected item, continue the search
} else if (this.collection.add(model) !== false) {
this.search();
// else they are clicking on an already selected tag/folder, so just remove the item from search bar
} else {
this.destroy(model);
}
},
rename: function(id, name) {
var model = this.collection.get(id);
if (model) model.set('name', name);
},
// destroy can take a model or an id - this.collection.get can handle both cases
destroy: function(id) {
var model = this.collection.get(id);
if (model) model.trigger('destroy', model);
// pass null to folder tree event listener to deselect the currently selected folder
app.trigger('deselect:folder', id);
},
// perform the actual search by sending an event to the document list module
search: function(query) {
query = query !== null ? this.collection.toString() : null;
app.trigger('search:getDocuments', query);
}
});
// Search Item View
// ----------------
Views.SearchItem = Backbone.View.extend({
template: 'search/searchitem',
className: 'searchitem',
events: {
"click": "removeItem"
},
initialize: function() {
this.model.on('change', this.render, this);
},
serialize: function() {
return this.model.toJSON();
},
removeItem: function(e) {
var model = this.model;
var type = this.model.get('type');
var id = this.model.get('id');
model.trigger('destroy', model);
// signal folder/tag tree event listener to deselect the currently selected folder.
if (type === 'tid') {
app.trigger('deselect:tag', id);
} else if (type === 'fid') {
app.trigger('deselect:folder', id);
}
}
});
Views.SearchItemText = Backbone.View.extend({
template: 'search/searchitemtext',
className: 'searchitemtext',
events: {
'keydown': 'handleKeydown',
'keyup': 'handleKeyup'
},
serialize: function() {
return this.model.toJSON();
},
handleKeyup: function(e) {
// add the current value to the model
this.collection.textSearchModel.set('text', this.$('input').val());
},
handleKeydown: function(e) {
// resize the text box on re-render of the search view
Views.util.resizeInput(this.$('input'));
if (e.which === 13 || e.keyCode === 13) {
// user hit enter key, so perform a search
app.trigger('search:init', this.collection.textSearchModel);
}
}
});
return Views;
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment