Adding autocomplete to add feed. Includes feed title, address, and link.

This commit is contained in:
Samuel Clay 2010-12-23 16:02:17 -05:00
parent 8decf4dd80
commit 3a2f294746
6 changed files with 131 additions and 33 deletions

View file

@ -2,6 +2,7 @@ from django.conf.urls.defaults import *
from apps.rss_feeds import views
urlpatterns = patterns('',
url(r'^feed_autocomplete', views.feed_autocomplete, name='feed-autocomplete'),
url(r'^statistics', views.load_feed_statistics, name='statistics'),
url(r'^exception_retry', views.exception_retry, name='exception-retry'),
url(r'^exception_change_feed_address', views.exception_change_feed_address, name='exception-change-feed-address'),

View file

@ -2,13 +2,31 @@ import datetime
from utils import log as logging
from django.shortcuts import get_object_or_404
from django.http import HttpResponseForbidden
from django.db import IntegrityError
# from django.db import IntegrityError
from apps.rss_feeds.models import Feed, merge_feeds
from apps.reader.models import UserSubscription
from utils.user_functions import ajax_login_required
from utils import json_functions as json, feedfinder
from utils.feed_functions import relative_timeuntil, relative_timesince
@json.json_view
def feed_autocomplete(request):
query = request.GET['term']
feeds = Feed.objects.filter(feed_address__icontains=query)
if not feeds:
feeds = Feed.objects.filter(feed_link__icontains=query)
if not feeds:
feeds = Feed.objects.filter(feed_title__icontains=query)
feeds = feeds.order_by('-num_subscribers').only('feed_address', 'feed_title', 'num_subscribers')[:5]
feeds = [{
'value': feed.feed_address,
'label': feed.feed_title,
'num_subscribers': feed.num_subscribers,
} for feed in feeds]
return feeds
@json.json_view
def load_feed_statistics(request):
stats = dict()

View file

@ -2594,6 +2594,59 @@ a.NB-splash-link:hover {
display: block;
}
.ui-autocomplete {
width: 344px;
padding: 0;
margin: 0;
}
.ui-autocomplete li {
padding: 0;
list-style: none;
margin: 0;
border-bottom: 1px solid #B0B0B0;
}
.ui-autocomplete li:last-child {
border-bottom: none;
}
.ui-autocomplete li a {
padding: 2px;
display: block;
cursor: pointer;
}
.ui-autocomplete li a.ui-state-hover {
border: none;
font-weight: normal;
}
.ui-autocomplete li a .NB-add-autocomplete-subscribers {
float: right;
font-size: 10px;
color: #909090;
font-weight: bold;
text-transform: uppercase;
line-height: 16px;
padding: 2px 4px 0 0;
}
.ui-autocomplete li a .NB-add-autocomplete-title {
line-height: 16px;
color: #202020;
font-weight: bold;
font-size: 13px;
height: 16px;
overflow: hidden;
padding: 2px 0 0 4px;
}
.ui-autocomplete li a .NB-add-autocomplete-address {
display: block;
clear: both;
color: #3F3D6E;
font-size: 10px;
font-weight: normal;
height: 12px;
padding: 4px 0 4px 4px;
overflow: hidden;
}
/* ================ */
/* = Manage Feeds = */
/* ================ */

View file

@ -229,7 +229,7 @@ NEWSBLUR.log = function(msg) {
// Second argument can be TextNode or Attributes
// $.make('div', 'inner text') || $.make('div', { className: 'etc' })
if (args[1]) {
if (typeof args[1] == 'string') {
if (typeof args[1] == 'string' || typeof args[1] == 'number') {
text = args[1];
} else if (typeof args[1] == 'object' && args[1].push) {
children = args[1];
@ -240,40 +240,36 @@ NEWSBLUR.log = function(msg) {
// Third argument can be TextNode or an array of additional $.make
if (args[2]) {
if (typeof args[2] == 'string') {
if (typeof args[2] == 'string' || typeof args[2] == 'number') {
text = args[2];
} else if (typeof args[1] == 'object' && args[2].push) {
children = args[2];
}
}
if (tagname == 'text' && text) {
return document.createTextNode(text);
} else {
$elem = $(document.createElement(tagname));
if (props) {
for (var propname in props) {
if (props.hasOwnProperty(propname)) {
if ($elem.is(':input') && propname == 'value') {
$elem.val(props[propname]);
} else {
$elem.attr(propname, props[propname]);
}
$elem = $(document.createElement(tagname));
if (props) {
for (var propname in props) {
if (props.hasOwnProperty(propname)) {
if ($elem.is(':input') && propname == 'value') {
$elem.val(props[propname]);
} else {
$elem.attr(propname, props[propname]);
}
}
}
if (children) {
for (var i = 0; i < children.length; i++) {
if (children[i]) {
$elem.append(children[i]);
}
}
}
if (text) {
$elem.html(text);
}
return $elem;
}
if (children) {
for (var i = 0; i < children.length; i++) {
if (children[i]) {
$elem.append(children[i]);
}
}
}
if (text) {
$elem.html(text);
}
return $elem;
},
rescope: function(func, thisArg){

View file

@ -13,14 +13,15 @@ NEWSBLUR.ReaderAddFeed.prototype = {
this.handle_cancel();
this.open_modal();
this.handle_keystrokes();
this.setup_autocomplete();
this.$add.bind('click', $.rescope(this.handle_click, this));
this.$modal.bind('click', $.rescope(this.handle_click, this));
},
make_modal: function() {
var self = this;
this.$add = $.make('div', { className: 'NB-add NB-modal' }, [
this.$modal = $.make('div', { className: 'NB-add NB-modal' }, [
$.make('h2', { className: 'NB-modal-title' }, 'Add feeds and folders'),
$.make('div', { className: 'NB-add-form' }, [
$.make('div', { className: 'NB-fieldset NB-add-add-url NB-modal-submit' }, [
@ -93,7 +94,7 @@ NEWSBLUR.ReaderAddFeed.prototype = {
]);
if (NEWSBLUR.Globals.is_anonymous) {
this.$add.addClass('NB-signed-out');
this.$modal.addClass('NB-signed-out');
}
},
@ -128,7 +129,7 @@ NEWSBLUR.ReaderAddFeed.prototype = {
open_modal: function() {
var self = this;
this.$add.modal({
this.$modal.modal({
'minWidth': 600,
'maxWidth': 600,
'overlayClose': true,
@ -155,7 +156,7 @@ NEWSBLUR.ReaderAddFeed.prototype = {
},
handle_cancel: function() {
var $cancel = $('.NB-modal-cancel', this.$add);
var $cancel = $('.NB-modal-cancel', this.$modal);
$cancel.click(function(e) {
e.preventDefault();
@ -163,15 +164,43 @@ NEWSBLUR.ReaderAddFeed.prototype = {
});
},
setup_autocomplete: function() {
var self = this;
var $add = $('.NB-add-url', this.$modal);
$add.autocomplete({
minLength: 0,
source: '/rss_feeds/feed_autocomplete',
focus: function(e, ui) {
$add.val(ui.item.value);
return false;
},
select: function(e, ui) {
$add.val(ui.item.value);
NEWSBLUR.log(['select', e, ui, ui.item, ui.item.value]);
self.save_add_url();
return false;
}
}).data("autocomplete")._renderItem = function(ul, item) {
return $.make('li', [
$.make('a', [
$.make('div', { className: 'NB-add-autocomplete-subscribers'}, item.num_subscribers + Inflector.pluralize(' subscriber', item.num_subscribers)),
$.make('div', { className: 'NB-add-autocomplete-title'}, item.label),
$.make('div', { className: 'NB-add-autocomplete-address'}, item.value)
])
]).data("item.autocomplete", item).appendTo(ul);
};
},
handle_keystrokes: function() {
var self = this;
$('.NB-add-url', this.$add).bind('keyup', 'return', function(e) {
$('.NB-add-url', this.$modal).bind('keyup', 'return', function(e) {
e.preventDefault();
self.save_add_url();
});
$('.NB-add-folder', this.$add).bind('keyup', 'return', function(e) {
$('.NB-add-folder', this.$modal).bind('keyup', 'return', function(e) {
e.preventDefault();
self.save_add_folder();
});

View file

@ -105,6 +105,7 @@ COMPRESS_JS = {
'js/jquery.ui.draggable.js',
'js/jquery.ui.sortable.js',
'js/jquery.ui.slider.js',
'js/jquery.ui.autocomplete.js',
'js/jquery.ui.progressbar.js',
'js/jquery.layout.js',
'js/jquery.tinysort.js',