Created
August 4, 2012 21:03
-
-
Save dstibrany/3259917 to your computer and use it in GitHub Desktop.
Search View
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
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