mirror of
https://github.com/fergalmoran/dss.git
synced 2025-12-22 17:48:51 +00:00
Added search bar
This commit is contained in:
16
spa/ajax.py
16
spa/ajax.py
@@ -3,6 +3,7 @@ import logging
|
||||
|
||||
from django.conf.urls import url
|
||||
from django.contrib.auth.decorators import login_required
|
||||
from django.core import serializers
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.db.models import get_model
|
||||
from django.http import HttpResponse, HttpResponseNotFound
|
||||
@@ -52,6 +53,7 @@ class AjaxHandler(object):
|
||||
name='ajax_upload_release_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'^lookup/search/$', 'spa.ajax.lookup_search', name='ajax_lookup'),
|
||||
url(r'^lookup/(?P<source>\w+)/$', 'spa.ajax.lookup', name='ajax_lookup'),
|
||||
]
|
||||
return pattern_list
|
||||
@@ -138,6 +140,7 @@ def live_now_playing(request):
|
||||
|
||||
return None
|
||||
|
||||
|
||||
@render_to('inc/release_player.html')
|
||||
def release_player(request, release_id):
|
||||
return HttpResponse('Hello Sailor')
|
||||
@@ -311,6 +314,19 @@ def upload_mix_file_handler(request):
|
||||
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
|
||||
def lookup(request, source):
|
||||
query = request.GET['query'] if 'query' in request.GET else request.GET['q'] if 'q' in request.GET else ''
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
from django.conf.urls import url
|
||||
from django.core.exceptions import ObjectDoesNotExist
|
||||
from django.core.paginator import Paginator, InvalidPage
|
||||
from django.db.models import Count
|
||||
from django.http import Http404
|
||||
from django.template.loader import render_to_string
|
||||
from tastypie import fields
|
||||
from tastypie.authorization import Authorization
|
||||
@@ -52,6 +54,9 @@ class MixResource(BackboneCompatibleResource):
|
||||
|
||||
def prepend_urls(self):
|
||||
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'),
|
||||
name="api_dispatch_detail"),
|
||||
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:
|
||||
semi_filtered = semi_filtered.filter(user__slug=user)
|
||||
|
||||
|
||||
return semi_filtered
|
||||
|
||||
def hydrate_favourited(self, bundle):
|
||||
@@ -166,3 +170,30 @@ class MixResource(BackboneCompatibleResource):
|
||||
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)
|
||||
|
||||
@@ -41,7 +41,7 @@ class _BaseModel(models.Model):
|
||||
def get_lookup_filter_field(cls):
|
||||
field_list = cls._meta.get_all_field_names()
|
||||
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 "description"
|
||||
|
||||
|
||||
@@ -451,9 +451,11 @@ div.event-content td {
|
||||
.now-playing-play {
|
||||
background-position: -90px 0px;
|
||||
}
|
||||
|
||||
.now-playing-pause {
|
||||
background-position: -210px 0px;
|
||||
}
|
||||
|
||||
.now-playing-bio p {
|
||||
display: inline-block;
|
||||
margin-left: 5px;
|
||||
@@ -481,8 +483,106 @@ div.event-content td {
|
||||
text-align: center;
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
dss-datatable {
|
||||
cellpadding: 0;
|
||||
cellspacing: 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
1093
static/data/repos.json
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,14 +1,8 @@
|
||||
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',
|
||||
'models/mix/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.audioController = new AudioController();
|
||||
App.realtimeController = new RealtimeController();
|
||||
@@ -32,7 +26,6 @@ define ['backbone', 'marionette', 'vent',
|
||||
footerRegion: "#footer"
|
||||
sidebarRegion: "#sidebar"
|
||||
|
||||
|
||||
App.addInitializer ->
|
||||
console.log("App: routing starting");
|
||||
App.Router = new DssRouter();
|
||||
@@ -69,7 +62,7 @@ define ['backbone', 'marionette', 'vent',
|
||||
true
|
||||
|
||||
App.headerRegion.show(new HeaderView());
|
||||
sidebarView = new SidebarView();
|
||||
App.sidebarRegion.show(sidebarView)
|
||||
#sidebarView = new SidebarView();
|
||||
#App.sidebarRegion.show(sidebarView)
|
||||
|
||||
return App;
|
||||
|
||||
@@ -1,21 +1,14 @@
|
||||
// Generated by CoffeeScript 1.6.2
|
||||
// Generated by CoffeeScript 1.3.3
|
||||
(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) {
|
||||
this.$el.hide();
|
||||
this.$el.html(view.el);
|
||||
this.$el.slideDown("fast");
|
||||
return true;
|
||||
};
|
||||
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) {
|
||||
var App;
|
||||
App = new Marionette.Application();
|
||||
App.audioController = new AudioController();
|
||||
App.realtimeController = new RealtimeController();
|
||||
App.realtimeController.startSocketIO();
|
||||
App.vent.on("routing:started", function() {
|
||||
var enablePushState, pushState;
|
||||
|
||||
console.log("App(vent): routing:started");
|
||||
enablePushState = true;
|
||||
pushState = !!(enablePushState && window.history && window.history.pushState);
|
||||
@@ -41,7 +34,6 @@
|
||||
App.addInitializer(function() {
|
||||
$(document).on("click", "a[href]:not([data-bypass])", function(evt) {
|
||||
var href, root;
|
||||
|
||||
href = {
|
||||
prop: $(this).prop("href"),
|
||||
attr: $(this).attr("href")
|
||||
@@ -81,8 +73,6 @@
|
||||
});
|
||||
});
|
||||
App.headerRegion.show(new HeaderView());
|
||||
sidebarView = new SidebarView();
|
||||
App.sidebarRegion.show(sidebarView);
|
||||
return App;
|
||||
});
|
||||
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
define ['app', 'marionette',
|
||||
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'],
|
||||
(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
|
||||
|
||||
home: ->
|
||||
console.log "Controller: home"
|
||||
@showMixList()
|
||||
#@showMixList()
|
||||
true
|
||||
|
||||
_showMixList: (options) ->
|
||||
|
||||
@@ -1,28 +1,25 @@
|
||||
// Generated by CoffeeScript 1.6.2
|
||||
// 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(['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) {
|
||||
var DssController, _ref;
|
||||
|
||||
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;
|
||||
DssController = (function(_super) {
|
||||
|
||||
__extends(DssController, _super);
|
||||
|
||||
function DssController() {
|
||||
_ref = DssController.__super__.constructor.apply(this, arguments);
|
||||
return _ref;
|
||||
return DssController.__super__.constructor.apply(this, arguments);
|
||||
}
|
||||
|
||||
DssController.prototype.home = function() {
|
||||
console.log("Controller: home");
|
||||
this.showMixList();
|
||||
return true;
|
||||
};
|
||||
|
||||
DssController.prototype._showMixList = function(options) {
|
||||
var app;
|
||||
|
||||
console.log("Controller: _showMixList");
|
||||
app = require('app');
|
||||
app.contentRegion.show(new MixListView(options));
|
||||
@@ -38,7 +35,6 @@
|
||||
|
||||
DssController.prototype.showMix = function(slug) {
|
||||
var app, mix;
|
||||
|
||||
console.log("Controller: showMix");
|
||||
app = require('app');
|
||||
mix = new MixItem({
|
||||
@@ -57,7 +53,6 @@
|
||||
|
||||
DssController.prototype.uploadMix = function() {
|
||||
var app, mix;
|
||||
|
||||
console.log("Controller: mixUpload");
|
||||
app = require('app');
|
||||
mix = new MixItem({
|
||||
@@ -74,7 +69,6 @@
|
||||
|
||||
DssController.prototype.editMix = function(slug) {
|
||||
var app, mix;
|
||||
|
||||
console.log("Controller: mixEdit");
|
||||
app = require('app');
|
||||
mix = new MixItem({
|
||||
@@ -92,7 +86,6 @@
|
||||
|
||||
DssController.prototype.showChat = function() {
|
||||
var app;
|
||||
|
||||
console.log("Controller: showChat");
|
||||
app = require('app');
|
||||
return app.contentRegion.show(new ChatView());
|
||||
@@ -100,7 +93,6 @@
|
||||
|
||||
DssController.prototype.showUserList = function(type) {
|
||||
var app;
|
||||
|
||||
console.log("Controller: showUserList");
|
||||
app = require('app');
|
||||
return app.contentRegion.show(new UserListView());
|
||||
@@ -152,7 +144,6 @@
|
||||
|
||||
DssController.prototype.editUser = function() {
|
||||
var app, user;
|
||||
|
||||
console.log("Controller: editUser");
|
||||
app = require('app');
|
||||
user = new UserItem({
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
define ['marionette', 'app.lib/controller'],
|
||||
(Marionette, Controller) ->
|
||||
define ['marionette', 'vent', 'app.lib/controller'],
|
||||
(Marionette, vent, Controller) ->
|
||||
class DssRouter extends Marionette.AppRouter
|
||||
controller: new Controller,
|
||||
appRoutes:
|
||||
@@ -22,5 +22,10 @@ define ['marionette', 'app.lib/controller'],
|
||||
"user/:slug": "showUserDetail"
|
||||
"me": "editUser"
|
||||
|
||||
initialize: ->
|
||||
console.log "Router: initializing"
|
||||
@listenTo vent, "navigate:mix", (slug)->
|
||||
@navigate 'mix/' + slug, true
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,17 +1,16 @@
|
||||
// Generated by CoffeeScript 1.6.2
|
||||
// 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(['marionette', 'app.lib/controller'], function(Marionette, Controller) {
|
||||
var DssRouter, _ref;
|
||||
|
||||
define(['marionette', 'vent', 'app.lib/controller'], function(Marionette, vent, Controller) {
|
||||
var DssRouter;
|
||||
return DssRouter = (function(_super) {
|
||||
|
||||
__extends(DssRouter, _super);
|
||||
|
||||
function DssRouter() {
|
||||
_ref = DssRouter.__super__.constructor.apply(this, arguments);
|
||||
return _ref;
|
||||
return DssRouter.__super__.constructor.apply(this, arguments);
|
||||
}
|
||||
|
||||
DssRouter.prototype.controller = new Controller;
|
||||
@@ -34,6 +33,13 @@
|
||||
"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;
|
||||
|
||||
})(Marionette.AppRouter);
|
||||
|
||||
@@ -58,10 +58,8 @@ $(document).ajaxSend(function (event, xhr, settings) {
|
||||
if (com.podnoms.settings.isDebug) {
|
||||
$(document).on({
|
||||
ajaxStart: function () {
|
||||
console.log("Site: ajax request starting");
|
||||
},
|
||||
ajaxStop: function () {
|
||||
console.log("Site: ajax request finished");
|
||||
}
|
||||
});
|
||||
} else {
|
||||
|
||||
@@ -6,9 +6,9 @@
|
||||
Copyright (c) 2012, Fergal Moran. All rights reserved.
|
||||
Code provided under the BSD License:
|
||||
###
|
||||
define ["underscore", "backbone", "vent", "utils", "text!/tpl/HeaderView"],
|
||||
(_, Backbone, vent, utils, Template) ->
|
||||
class HeaderView extends Backbone.View
|
||||
define ["underscore", "marionette", "vent", "utils", "views/widgets/searchView", "text!/tpl/HeaderView"],
|
||||
(_, Marionette, vent, utils, SearchView, Template) ->
|
||||
class HeaderView extends Marionette.Layout
|
||||
template: _.template(Template)
|
||||
events:
|
||||
"click #header-play-pause-button": "togglePlayState"
|
||||
@@ -18,11 +18,18 @@ define ["underscore", "backbone", "vent", "utils", "text!/tpl/HeaderView"],
|
||||
ui:
|
||||
liveButton: "#header-live-button"
|
||||
|
||||
regions:
|
||||
searchRegion: "#header-search"
|
||||
|
||||
initialize: ->
|
||||
@render()
|
||||
|
||||
@listenTo vent, "mix:play", @trackPlaying
|
||||
@listenTo vent, "mix:pause", @trackPaused
|
||||
|
||||
onShow: ->
|
||||
@searchRegion.show(new SearchView())
|
||||
|
||||
login: ->
|
||||
utils.modal "/dlg/LoginView"
|
||||
|
||||
12
static/js/app/views/header.js → static/js/app/views/widgets/headerView.js
Executable file → Normal file
12
static/js/app/views/header.js → static/js/app/views/widgets/headerView.js
Executable file → Normal file
@@ -14,7 +14,7 @@ Code provided under the BSD License:
|
||||
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(["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;
|
||||
HeaderView = (function(_super) {
|
||||
|
||||
@@ -37,12 +37,20 @@ Code provided under the BSD License:
|
||||
liveButton: "#header-live-button"
|
||||
};
|
||||
|
||||
HeaderView.prototype.regions = {
|
||||
searchRegion: "#header-search"
|
||||
};
|
||||
|
||||
HeaderView.prototype.initialize = function() {
|
||||
this.render();
|
||||
this.listenTo(vent, "mix:play", this.trackPlaying);
|
||||
return this.listenTo(vent, "mix:pause", this.trackPaused);
|
||||
};
|
||||
|
||||
HeaderView.prototype.onShow = function() {
|
||||
return this.searchRegion.show(new SearchView());
|
||||
};
|
||||
|
||||
HeaderView.prototype.login = function() {
|
||||
return utils.modal("/dlg/LoginView");
|
||||
};
|
||||
@@ -85,7 +93,7 @@ Code provided under the BSD License:
|
||||
|
||||
return HeaderView;
|
||||
|
||||
})(Backbone.View);
|
||||
})(Marionette.Layout);
|
||||
return HeaderView;
|
||||
});
|
||||
|
||||
37
static/js/app/views/widgets/searchView.coffee
Normal file
37
static/js/app/views/widgets/searchView.coffee
Normal 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
|
||||
68
static/js/app/views/widgets/searchView.js
Normal file
68
static/js/app/views/widgets/searchView.js
Normal 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);
|
||||
1159
static/js/libs/bootstrap/bootstrap-typeahead.js
vendored
Normal file
1159
static/js/libs/bootstrap/bootstrap-typeahead.js
vendored
Normal file
File diff suppressed because it is too large
Load Diff
@@ -41,7 +41,9 @@
|
||||
<a class="pull-right btn btn-primary" href="/mix/upload" id='upload'>
|
||||
<i class="icon-hand-up icon-white"></i>Upload</a>
|
||||
{% endif %}
|
||||
|
||||
<ul class="nav pull-right">
|
||||
<li id="header-search"></li>
|
||||
<li>
|
||||
<a class="volume-button" data-mode="volume" id="header-volume-button">
|
||||
<i class="icon-volume-up icon-white" id="header-volume-icon"></i>
|
||||
|
||||
10
templates/views/SearchResultView.html
Normal file
10
templates/views/SearchResultView.html
Normal 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>
|
||||
4
templates/views/SearchView.html
Normal file
4
templates/views/SearchView.html
Normal 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>
|
||||
Reference in New Issue
Block a user