Added search bar

This commit is contained in:
Fergal Moran
2013-06-30 15:42:47 +01:00
parent 1453720c9d
commit c519f16fc6
21 changed files with 2585 additions and 66 deletions

View File

@@ -3,6 +3,7 @@ import logging
from django.conf.urls import url from django.conf.urls import url
from django.contrib.auth.decorators import login_required from django.contrib.auth.decorators import login_required
from django.core import serializers
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from django.db.models import get_model from django.db.models import get_model
from django.http import HttpResponse, HttpResponseNotFound from django.http import HttpResponse, HttpResponseNotFound
@@ -52,6 +53,7 @@ class AjaxHandler(object):
name='ajax_upload_release_image'), name='ajax_upload_release_image'),
url(r'^upload_avatar_image/$', 'spa.ajax.upload_avatar_image', name='ajax_upload_avatar_image'), url(r'^upload_avatar_image/$', 'spa.ajax.upload_avatar_image', name='ajax_upload_avatar_image'),
url(r'^upload_mix_file_handler/$', 'spa.ajax.upload_mix_file_handler', name='ajax_upload_mix_file_handler'), url(r'^upload_mix_file_handler/$', 'spa.ajax.upload_mix_file_handler', name='ajax_upload_mix_file_handler'),
url(r'^lookup/search/$', 'spa.ajax.lookup_search', name='ajax_lookup'),
url(r'^lookup/(?P<source>\w+)/$', 'spa.ajax.lookup', name='ajax_lookup'), url(r'^lookup/(?P<source>\w+)/$', 'spa.ajax.lookup', name='ajax_lookup'),
] ]
return pattern_list return pattern_list
@@ -138,6 +140,7 @@ def live_now_playing(request):
return None return None
@render_to('inc/release_player.html') @render_to('inc/release_player.html')
def release_player(request, release_id): def release_player(request, release_id):
return HttpResponse('Hello Sailor') return HttpResponse('Hello Sailor')
@@ -311,6 +314,19 @@ def upload_mix_file_handler(request):
return HttpResponse(_get_json("Failed"), mimetype='application/json') return HttpResponse(_get_json("Failed"), mimetype='application/json')
@csrf_exempt
def lookup_search(request):
query = request.GET['query'] if 'query' in request.GET else request.GET['q'] if 'q' in request.GET else ''
if query != '':
filter_field = Mix.get_lookup_filter_field()
kwargs = {
'{0}__{1}'.format(filter_field, 'icontains'): query,
}
rows = Mix.objects.values("title").filter(**kwargs)
#results = serializers.serialize("json", rows, fields="title",)
results = json.dumps(rows)
return HttpResponse(results, mimetype='application/json')
@csrf_exempt @csrf_exempt
def lookup(request, source): def lookup(request, source):
query = request.GET['query'] if 'query' in request.GET else request.GET['q'] if 'q' in request.GET else '' query = request.GET['query'] if 'query' in request.GET else request.GET['q'] if 'q' in request.GET else ''

View File

@@ -1,6 +1,8 @@
from django.conf.urls import url from django.conf.urls import url
from django.core.exceptions import ObjectDoesNotExist from django.core.exceptions import ObjectDoesNotExist
from django.core.paginator import Paginator, InvalidPage
from django.db.models import Count from django.db.models import Count
from django.http import Http404
from django.template.loader import render_to_string from django.template.loader import render_to_string
from tastypie import fields from tastypie import fields
from tastypie.authorization import Authorization from tastypie.authorization import Authorization
@@ -52,6 +54,9 @@ class MixResource(BackboneCompatibleResource):
def prepend_urls(self): def prepend_urls(self):
return [ return [
url(r"^(?P<resource_name>%s)/search%s$" % (self._meta.resource_name, trailing_slash()),
self.wrap_view('get_search'),
name="api_get_search"),
url(r"^(?P<resource_name>%s)/(?P<id>[\d]+)/$" % self._meta.resource_name, self.wrap_view('dispatch_detail'), url(r"^(?P<resource_name>%s)/(?P<id>[\d]+)/$" % self._meta.resource_name, self.wrap_view('dispatch_detail'),
name="api_dispatch_detail"), name="api_dispatch_detail"),
url(r"^(?P<resource_name>%s)/(?P<slug>[\w\d-]+)/$" % self._meta.resource_name, url(r"^(?P<resource_name>%s)/(?P<slug>[\w\d-]+)/$" % self._meta.resource_name,
@@ -137,7 +142,6 @@ class MixResource(BackboneCompatibleResource):
if user is not None: if user is not None:
semi_filtered = semi_filtered.filter(user__slug=user) semi_filtered = semi_filtered.filter(user__slug=user)
return semi_filtered return semi_filtered
def hydrate_favourited(self, bundle): def hydrate_favourited(self, bundle):
@@ -166,3 +170,30 @@ class MixResource(BackboneCompatibleResource):
return bundle return bundle
def get_search(self, request, **kwargs):
self.method_check(request, allowed=['get'])
self.is_authenticated(request)
self.throttle_check(request)
# Do the query.
sqs = Mix.objects.filter(title__icontains=request.GET.get('q', ''))
paginator = Paginator(sqs, 20)
try:
page = paginator.page(int(request.GET.get('page', 1)))
except InvalidPage:
raise Http404("Sorry, no results on that page.")
objects = []
for result in page.object_list:
bundle = self.build_bundle(obj=result, request=request)
bundle = self.full_dehydrate(bundle)
objects.append(bundle)
object_list = {
'objects': objects,
}
self.log_throttled_access(request)
return self.create_response(request, object_list)

View File

@@ -41,7 +41,7 @@ class _BaseModel(models.Model):
def get_lookup_filter_field(cls): def get_lookup_filter_field(cls):
field_list = cls._meta.get_all_field_names() field_list = cls._meta.get_all_field_names()
for field in field_list: for field in field_list:
if field.endswith("name") or field.endswith("description"): if field.endswith("title") or field.endswith("name") or field.endswith("description"):
return field return field
return "description" return "description"

View File

@@ -451,15 +451,17 @@ div.event-content td {
.now-playing-play { .now-playing-play {
background-position: -90px 0px; background-position: -90px 0px;
} }
.now-playing-pause{
.now-playing-pause {
background-position: -210px 0px; background-position: -210px 0px;
} }
.now-playing-bio p { .now-playing-bio p {
display: inline-block; display: inline-block;
margin-left: 5px; margin-left: 5px;
} }
#aaaa{ #aaaa {
border: 1px solid #802c59; border: 1px solid #802c59;
-webkit-border-radius: 15px; -webkit-border-radius: 15px;
@@ -476,13 +478,111 @@ div.event-content td {
padding: 8px; padding: 8px;
} }
.div-small-heading{ .div-small-heading {
width: 98%; width: 98%;
text-align: center; text-align: center;
margin-bottom: 8px; margin-bottom: 8px;
} }
dss-datatable{
dss-datatable {
cellpadding: 0; cellpadding: 0;
cellspacing: 0; cellspacing: 0;
border: 0; border: 0;
} }
img.flag {
height: 10px;
width: 15px;
padding-right: 10px;
}
.search-result td {
vertical-align: top
}
.search-result-image img {
height: 48px;
width: 48px;
}
.search-result-info {
padding-left: 10px;
vertical-align: top;
}
.search-result-synopsis {
font-size: .8em;
color: #888;
}
.navbar-search .search-query {
padding-left: 29px !important;
}
.twitter-typeahead .tt-query,
.twitter-typeahead .tt-hint {
margin-bottom: 0;
}
.tt-dropdown-menu {
width: 280px;
margin-top: 2px;
background-color: #fff;
border: 1px solid #ccc;
border: 1px solid rgba(0, 0, 0, .2);
*border-right-width: 2px;
*border-bottom-width: 2px;
-webkit-border-radius: 6px;
-moz-border-radius: 6px;
border-radius: 6px;
-webkit-box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
-moz-box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
box-shadow: 0 5px 10px rgba(0, 0, 0, .2);
-webkit-background-clip: padding-box;
-moz-background-clip: padding;
background-clip: padding-box;
}
.tt-suggestion {
display: block;
padding: 3px 20px;
}
.tt-suggestion.tt-is-under-cursor {
color: #fff;
background-color: #0081c2;
background-image: -moz-linear-gradient(top, #0088cc, #0077b3);
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3));
background-image: -webkit-linear-gradient(top, #0088cc, #0077b3);
background-image: -o-linear-gradient(top, #0088cc, #0077b3);
background-image: linear-gradient(to bottom, #0088cc, #0077b3);
background-repeat: repeat-x;
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0)
}
.tt-suggestion.tt-is-under-cursor a {
color: #fff;
}
.tt-suggestion p {
margin: 0;
}
.navbar-search {
position: relative;
}
.navbar-search .search-query {
padding-left: 29px;
}
.navbar-search .icon-search {
position: absolute;
top: 7px;
left: 11px;
background-image: url("../img/glyphicons-halflings.png");
}
.tt-hint {
font-size: 0 !important;
}

1093
static/data/repos.json Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,14 +1,8 @@
define ['backbone', 'marionette', 'vent', define ['backbone', 'marionette', 'vent',
'app.lib/router', 'app.lib/panningRegion', 'app.lib/realtimeController', 'app.lib/audioController', 'views/header', 'app.lib/router', 'app.lib/panningRegion', 'app.lib/realtimeController', 'app.lib/audioController', 'views/widgets/headerView',
'views/sidebar/sidebarView', 'views/sidebar/sidebarView',
'models/mix/mixCollection'], 'models/mix/mixCollection'],
(Backbone, Marionette, vent, DssRouter, PanningRegion, RealtimeController, AudioController, HeaderView, SidebarView, MixCollection) -> (Backbone, Marionette, vent, DssRouter, PanningRegion, RealtimeController, AudioController, HeaderView, SidebarView, MixCollection) ->
Marionette.Region.prototype.open = (view) ->
@.$el.hide();
@.$el.html(view.el);
@.$el.slideDown("fast");
true
App = new Marionette.Application(); App = new Marionette.Application();
App.audioController = new AudioController(); App.audioController = new AudioController();
App.realtimeController = new RealtimeController(); App.realtimeController = new RealtimeController();
@@ -32,7 +26,6 @@ define ['backbone', 'marionette', 'vent',
footerRegion: "#footer" footerRegion: "#footer"
sidebarRegion: "#sidebar" sidebarRegion: "#sidebar"
App.addInitializer -> App.addInitializer ->
console.log("App: routing starting"); console.log("App: routing starting");
App.Router = new DssRouter(); App.Router = new DssRouter();
@@ -69,7 +62,7 @@ define ['backbone', 'marionette', 'vent',
true true
App.headerRegion.show(new HeaderView()); App.headerRegion.show(new HeaderView());
sidebarView = new SidebarView(); #sidebarView = new SidebarView();
App.sidebarRegion.show(sidebarView) #App.sidebarRegion.show(sidebarView)
return App; return App;

View File

@@ -1,21 +1,14 @@
// Generated by CoffeeScript 1.6.2 // Generated by CoffeeScript 1.3.3
(function() { (function() {
define(['backbone', 'marionette', 'vent', 'app.lib/router', 'app.lib/panningRegion', 'app.lib/realtimeController', 'app.lib/audioController', 'views/header', 'views/sidebar/sidebarView', 'models/mix/mixCollection'], function(Backbone, Marionette, vent, DssRouter, PanningRegion, RealtimeController, AudioController, HeaderView, SidebarView, MixCollection) {
var App, sidebarView;
Marionette.Region.prototype.open = function(view) { define(['backbone', 'marionette', 'vent', 'app.lib/router', 'app.lib/panningRegion', 'app.lib/realtimeController', 'app.lib/audioController', 'views/widgets/headerView', 'views/sidebar/sidebarView', 'models/mix/mixCollection'], function(Backbone, Marionette, vent, DssRouter, PanningRegion, RealtimeController, AudioController, HeaderView, SidebarView, MixCollection) {
this.$el.hide(); var App;
this.$el.html(view.el);
this.$el.slideDown("fast");
return true;
};
App = new Marionette.Application(); App = new Marionette.Application();
App.audioController = new AudioController(); App.audioController = new AudioController();
App.realtimeController = new RealtimeController(); App.realtimeController = new RealtimeController();
App.realtimeController.startSocketIO(); App.realtimeController.startSocketIO();
App.vent.on("routing:started", function() { App.vent.on("routing:started", function() {
var enablePushState, pushState; var enablePushState, pushState;
console.log("App(vent): routing:started"); console.log("App(vent): routing:started");
enablePushState = true; enablePushState = true;
pushState = !!(enablePushState && window.history && window.history.pushState); pushState = !!(enablePushState && window.history && window.history.pushState);
@@ -41,7 +34,6 @@
App.addInitializer(function() { App.addInitializer(function() {
$(document).on("click", "a[href]:not([data-bypass])", function(evt) { $(document).on("click", "a[href]:not([data-bypass])", function(evt) {
var href, root; var href, root;
href = { href = {
prop: $(this).prop("href"), prop: $(this).prop("href"),
attr: $(this).attr("href") attr: $(this).attr("href")
@@ -81,8 +73,6 @@
}); });
}); });
App.headerRegion.show(new HeaderView()); App.headerRegion.show(new HeaderView());
sidebarView = new SidebarView();
App.sidebarRegion.show(sidebarView);
return App; return App;
}); });

View File

@@ -1,12 +1,13 @@
define ['app', 'marionette', define ['app', 'marionette', 'vent',
'views/chat/chatView', 'views/chat/chatView',
'models/mix/mixItem', 'views/mix/mixListView', 'views/mix/mixDetailView', 'views/mix/mixEditView', 'models/mix/mixItem', 'views/mix/mixListView', 'views/mix/mixDetailView', 'views/mix/mixEditView',
'models/user/userItem', 'views/user/userListView', 'views/user/userEditView'], 'models/user/userItem', 'views/user/userListView', 'views/user/userEditView'],
(App, Marionette, ChatView, MixItem, MixListView, MixDetailView, MixEditView, UserItem, UserListView, UserEditView)-> (App, Marionette, vent, ChatView, MixItem, MixListView, MixDetailView, MixEditView, UserItem, UserListView, UserEditView)->
class DssController extends Marionette.Controller class DssController extends Marionette.Controller
home: -> home: ->
console.log "Controller: home" console.log "Controller: home"
@showMixList() #@showMixList()
true true
_showMixList: (options) -> _showMixList: (options) ->

View File

@@ -1,28 +1,25 @@
// Generated by CoffeeScript 1.6.2 // Generated by CoffeeScript 1.3.3
(function() { (function() {
var __hasProp = {}.hasOwnProperty, var __hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
define(['app', 'marionette', 'views/chat/chatView', 'models/mix/mixItem', 'views/mix/mixListView', 'views/mix/mixDetailView', 'views/mix/mixEditView', 'models/user/userItem', 'views/user/userListView', 'views/user/userEditView'], function(App, Marionette, ChatView, MixItem, MixListView, MixDetailView, MixEditView, UserItem, UserListView, UserEditView) { define(['app', 'marionette', 'vent', 'views/chat/chatView', 'models/mix/mixItem', 'views/mix/mixListView', 'views/mix/mixDetailView', 'views/mix/mixEditView', 'models/user/userItem', 'views/user/userListView', 'views/user/userEditView'], function(App, Marionette, vent, ChatView, MixItem, MixListView, MixDetailView, MixEditView, UserItem, UserListView, UserEditView) {
var DssController, _ref; var DssController;
DssController = (function(_super) { DssController = (function(_super) {
__extends(DssController, _super); __extends(DssController, _super);
function DssController() { function DssController() {
_ref = DssController.__super__.constructor.apply(this, arguments); return DssController.__super__.constructor.apply(this, arguments);
return _ref;
} }
DssController.prototype.home = function() { DssController.prototype.home = function() {
console.log("Controller: home"); console.log("Controller: home");
this.showMixList();
return true; return true;
}; };
DssController.prototype._showMixList = function(options) { DssController.prototype._showMixList = function(options) {
var app; var app;
console.log("Controller: _showMixList"); console.log("Controller: _showMixList");
app = require('app'); app = require('app');
app.contentRegion.show(new MixListView(options)); app.contentRegion.show(new MixListView(options));
@@ -38,7 +35,6 @@
DssController.prototype.showMix = function(slug) { DssController.prototype.showMix = function(slug) {
var app, mix; var app, mix;
console.log("Controller: showMix"); console.log("Controller: showMix");
app = require('app'); app = require('app');
mix = new MixItem({ mix = new MixItem({
@@ -57,7 +53,6 @@
DssController.prototype.uploadMix = function() { DssController.prototype.uploadMix = function() {
var app, mix; var app, mix;
console.log("Controller: mixUpload"); console.log("Controller: mixUpload");
app = require('app'); app = require('app');
mix = new MixItem({ mix = new MixItem({
@@ -74,7 +69,6 @@
DssController.prototype.editMix = function(slug) { DssController.prototype.editMix = function(slug) {
var app, mix; var app, mix;
console.log("Controller: mixEdit"); console.log("Controller: mixEdit");
app = require('app'); app = require('app');
mix = new MixItem({ mix = new MixItem({
@@ -92,7 +86,6 @@
DssController.prototype.showChat = function() { DssController.prototype.showChat = function() {
var app; var app;
console.log("Controller: showChat"); console.log("Controller: showChat");
app = require('app'); app = require('app');
return app.contentRegion.show(new ChatView()); return app.contentRegion.show(new ChatView());
@@ -100,7 +93,6 @@
DssController.prototype.showUserList = function(type) { DssController.prototype.showUserList = function(type) {
var app; var app;
console.log("Controller: showUserList"); console.log("Controller: showUserList");
app = require('app'); app = require('app');
return app.contentRegion.show(new UserListView()); return app.contentRegion.show(new UserListView());
@@ -152,7 +144,6 @@
DssController.prototype.editUser = function() { DssController.prototype.editUser = function() {
var app, user; var app, user;
console.log("Controller: editUser"); console.log("Controller: editUser");
app = require('app'); app = require('app');
user = new UserItem({ user = new UserItem({

View File

@@ -1,5 +1,5 @@
define ['marionette', 'app.lib/controller'], define ['marionette', 'vent', 'app.lib/controller'],
(Marionette, Controller) -> (Marionette, vent, Controller) ->
class DssRouter extends Marionette.AppRouter class DssRouter extends Marionette.AppRouter
controller: new Controller, controller: new Controller,
appRoutes: appRoutes:
@@ -22,5 +22,10 @@ define ['marionette', 'app.lib/controller'],
"user/:slug": "showUserDetail" "user/:slug": "showUserDetail"
"me": "editUser" "me": "editUser"
initialize: ->
console.log "Router: initializing"
@listenTo vent, "navigate:mix", (slug)->
@navigate 'mix/' + slug, true

View File

@@ -1,17 +1,16 @@
// Generated by CoffeeScript 1.6.2 // Generated by CoffeeScript 1.3.3
(function() { (function() {
var __hasProp = {}.hasOwnProperty, var __hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
define(['marionette', 'app.lib/controller'], function(Marionette, Controller) { define(['marionette', 'vent', 'app.lib/controller'], function(Marionette, vent, Controller) {
var DssRouter, _ref; var DssRouter;
return DssRouter = (function(_super) { return DssRouter = (function(_super) {
__extends(DssRouter, _super); __extends(DssRouter, _super);
function DssRouter() { function DssRouter() {
_ref = DssRouter.__super__.constructor.apply(this, arguments); return DssRouter.__super__.constructor.apply(this, arguments);
return _ref;
} }
DssRouter.prototype.controller = new Controller; DssRouter.prototype.controller = new Controller;
@@ -34,6 +33,13 @@
"me": "editUser" "me": "editUser"
}; };
DssRouter.prototype.initialize = function() {
console.log("Router: initializing");
return this.listenTo(vent, "navigate:mix", function(slug) {
return this.navigate('mix/' + slug, true);
});
};
return DssRouter; return DssRouter;
})(Marionette.AppRouter); })(Marionette.AppRouter);

View File

@@ -58,10 +58,8 @@ $(document).ajaxSend(function (event, xhr, settings) {
if (com.podnoms.settings.isDebug) { if (com.podnoms.settings.isDebug) {
$(document).on({ $(document).on({
ajaxStart: function () { ajaxStart: function () {
console.log("Site: ajax request starting");
}, },
ajaxStop: function () { ajaxStop: function () {
console.log("Site: ajax request finished");
} }
}); });
} else { } else {

View File

@@ -6,9 +6,9 @@
Copyright (c) 2012, Fergal Moran. All rights reserved. Copyright (c) 2012, Fergal Moran. All rights reserved.
Code provided under the BSD License: Code provided under the BSD License:
### ###
define ["underscore", "backbone", "vent", "utils", "text!/tpl/HeaderView"], define ["underscore", "marionette", "vent", "utils", "views/widgets/searchView", "text!/tpl/HeaderView"],
(_, Backbone, vent, utils, Template) -> (_, Marionette, vent, utils, SearchView, Template) ->
class HeaderView extends Backbone.View class HeaderView extends Marionette.Layout
template: _.template(Template) template: _.template(Template)
events: events:
"click #header-play-pause-button": "togglePlayState" "click #header-play-pause-button": "togglePlayState"
@@ -18,11 +18,18 @@ define ["underscore", "backbone", "vent", "utils", "text!/tpl/HeaderView"],
ui: ui:
liveButton: "#header-live-button" liveButton: "#header-live-button"
regions:
searchRegion: "#header-search"
initialize: -> initialize: ->
@render() @render()
@listenTo vent, "mix:play", @trackPlaying @listenTo vent, "mix:play", @trackPlaying
@listenTo vent, "mix:pause", @trackPaused @listenTo vent, "mix:pause", @trackPaused
onShow: ->
@searchRegion.show(new SearchView())
login: -> login: ->
utils.modal "/dlg/LoginView" utils.modal "/dlg/LoginView"

View File

@@ -14,7 +14,7 @@ Code provided under the BSD License:
var __hasProp = {}.hasOwnProperty, var __hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
define(["underscore", "backbone", "vent", "utils", "text!/tpl/HeaderView"], function(_, Backbone, vent, utils, Template) { define(["underscore", "marionette", "vent", "utils", "views/widgets/searchView", "text!/tpl/HeaderView"], function(_, Marionette, vent, utils, SearchView, Template) {
var HeaderView; var HeaderView;
HeaderView = (function(_super) { HeaderView = (function(_super) {
@@ -37,12 +37,20 @@ Code provided under the BSD License:
liveButton: "#header-live-button" liveButton: "#header-live-button"
}; };
HeaderView.prototype.regions = {
searchRegion: "#header-search"
};
HeaderView.prototype.initialize = function() { HeaderView.prototype.initialize = function() {
this.render(); this.render();
this.listenTo(vent, "mix:play", this.trackPlaying); this.listenTo(vent, "mix:play", this.trackPlaying);
return this.listenTo(vent, "mix:pause", this.trackPaused); return this.listenTo(vent, "mix:pause", this.trackPaused);
}; };
HeaderView.prototype.onShow = function() {
return this.searchRegion.show(new SearchView());
};
HeaderView.prototype.login = function() { HeaderView.prototype.login = function() {
return utils.modal("/dlg/LoginView"); return utils.modal("/dlg/LoginView");
}; };
@@ -85,7 +93,7 @@ Code provided under the BSD License:
return HeaderView; return HeaderView;
})(Backbone.View); })(Marionette.Layout);
return HeaderView; return HeaderView;
}); });

View File

@@ -0,0 +1,37 @@
define ['jquery', 'underscore', 'libs/bootstrap/bootstrap-typeahead', 'marionette', 'vent', 'text!/tpl/SearchView',
'text!/tpl/SearchResultView'],
($, _, Typeahead, Marionette, vent, Template, SearchResultView) ->
class SearchView extends Marionette.CompositeView
template: _.template(Template)
ui:
searchText: '#search-text'
engine:
compile: (template) ->
compiled = _.template(template)
render: (context) ->
compiled context
onShow: ->
console.log("SearchView: onShow")
t = $('#search-text', @el).typeahead
name: "search"
engine: @engine
valueKey: "title"
template: SearchResultView
remote:
url: "/api/v1/mix/search?q=%QUERY"
dataType: "json"
filter: (parsedResponse)->
parsedResponse.objects
$('.tt-hint', @el).addClass('search-query');
$('.tt-hint', @el).addClass('span3');
t.on 'typeahead:selected': (event, datum, dataset_name) ->
console.log("SearchView: Selected")
vent.trigger 'navigate:mix', datum.slug
$('#search-text', @el).blur()
$('.tt-hint', @el).blur()
SearchView

View File

@@ -0,0 +1,68 @@
// Generated by CoffeeScript 1.3.3
(function() {
var __hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
define(['jquery', 'underscore', 'libs/bootstrap/bootstrap-typeahead', 'marionette', 'vent', 'text!/tpl/SearchView', 'text!/tpl/SearchResultView'], function($, _, Typeahead, Marionette, vent, Template, SearchResultView) {
var SearchView;
SearchView = (function(_super) {
__extends(SearchView, _super);
function SearchView() {
return SearchView.__super__.constructor.apply(this, arguments);
}
SearchView.prototype.template = _.template(Template);
SearchView.prototype.ui = {
searchText: '#search-text'
};
SearchView.prototype.engine = {
compile: function(template) {
var compiled;
compiled = _.template(template);
return {
render: function(context) {
return compiled(context);
}
};
}
};
SearchView.prototype.onShow = function() {
var t;
console.log("SearchView: onShow");
t = $('#search-text', this.el).typeahead({
name: "search",
engine: this.engine,
valueKey: "title",
template: SearchResultView,
remote: {
url: "/api/v1/mix/search?q=%QUERY",
dataType: "json",
filter: function(parsedResponse) {
return parsedResponse.objects;
}
}
});
$('.tt-hint', this.el).addClass('search-query');
$('.tt-hint', this.el).addClass('span3');
return t.on({
'typeahead:selected': function(event, datum, dataset_name) {
console.log("SearchView: Selected");
vent.trigger('navigate:mix', datum.slug);
$('#search-text', this.el).blur();
return $('.tt-hint', this.el).blur();
}
});
};
return SearchView;
})(Marionette.CompositeView);
return SearchView;
});
}).call(this);

File diff suppressed because it is too large Load Diff

View File

@@ -41,7 +41,9 @@
<a class="pull-right btn btn-primary" href="/mix/upload" id='upload'> <a class="pull-right btn btn-primary" href="/mix/upload" id='upload'>
<i class="icon-hand-up icon-white"></i>Upload</a> <i class="icon-hand-up icon-white"></i>Upload</a>
{% endif %} {% endif %}
<ul class="nav pull-right"> <ul class="nav pull-right">
<li id="header-search"></li>
<li> <li>
<a class="volume-button" data-mode="volume" id="header-volume-button"> <a class="volume-button" data-mode="volume" id="header-volume-button">
<i class="icon-volume-up icon-white" id="header-volume-icon"></i> <i class="icon-volume-up icon-white" id="header-volume-icon"></i>
@@ -51,11 +53,11 @@
<a id="header-profile-edit" href="/me">{{ user|nice_name }}</a> <a id="header-profile-edit" href="/me">{{ user|nice_name }}</a>
</li> </li>
</ul> </ul>
{% comment %} {% comment %}
<form class="navbar-search pull-right" action=""> <form class="navbar-search pull-right" action="">
<input type="text" class="search-query span2" placeholder="Search"> <input type="text" class="search-query span2" placeholder="Search">
</form> </form>
{% endcomment %} {% endcomment %}
</div> </div>
</div> </div>
</div> </div>

View File

@@ -0,0 +1,10 @@
<table class="search-result">
<tbody>
<tr>
<td class="search-result-image"><img src="<%= mix_image %>"></td>
<td class="search-result-info">
<div class="search-result-title"><%= title %></div>
</td>
</tr>
</tbody>
</table>

View File

@@ -0,0 +1,4 @@
<form class="navbar-search">
<input id="search-text" type="text" class="search-query span3" placeholder="Search">
<div class="icon-search"></div>
</form>