summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--static/website/css/main.css35
-rw-r--r--static/website/images/bg-stripes.pngbin0 -> 119 bytes
-rw-r--r--static/website/js/search.js91
-rw-r--r--static/website/templates/ajax-keyword-search.html55
-rw-r--r--static/website/templates/ajax-time-search.html55
-rw-r--r--static/website/templates/base.html11
-rw-r--r--static/website/templates/search.html73
-rw-r--r--website/urls.py5
-rw-r--r--website/views.py56
9 files changed, 377 insertions, 4 deletions
diff --git a/static/website/css/main.css b/static/website/css/main.css
index a5f8c81..543de18 100644
--- a/static/website/css/main.css
+++ b/static/website/css/main.css
@@ -2,18 +2,36 @@
.navbar>.container .navbar-brand {
margin-left: 0;
}
+.navbar-default {
+ margin-bottom: 0;
+}
/* main styles */
+body {
+ background: #fafafa;
+ box-shadow: 4px 0 10px #cccccc, -4px 0 10px #cccccc;
+}
+#page-wrapper {
+ max-width: 970px;
+ margin:0 auto;
+ box-shadow: 0px 0px 15px #cccccc;
+}
.container {
max-width: 970px;
}
#header-wrapper {
-
+ max-width: 970px;
+ margin:0 auto;
+ background: #ffffff;
}
#header-inner {
}
#content-wrapper {
- padding: 0 0 25px 0;
+ position: relative;
+ max-width: 970px;
+ margin:0 auto;
+ padding: 15px 0 25px 0;
+ background: #ffffff;
}
#content-inner {
min-height: 600px;
@@ -113,6 +131,8 @@
background: #f5f5f5;
}
#footer-wrapper {
+ max-width: 970px;
+ margin:0 auto;
background-color: #2d2d2d;
min-height: 60px;
}
@@ -148,3 +168,14 @@
right: 5px;
bottom: 5px;
}
+#search-bar {
+ display: none;
+ min-height: 50px;
+ padding-top: 15px;
+ padding-bottom: 15px;
+ background: #ffffff;
+ border-bottom: 2px solid #f5f5f5;
+ width: 970px;
+ margin: 0 auto;
+}
+
diff --git a/static/website/images/bg-stripes.png b/static/website/images/bg-stripes.png
new file mode 100644
index 0000000..4390d95
--- /dev/null
+++ b/static/website/images/bg-stripes.png
Binary files differ
diff --git a/static/website/js/search.js b/static/website/js/search.js
new file mode 100644
index 0000000..5973e79
--- /dev/null
+++ b/static/website/js/search.js
@@ -0,0 +1,91 @@
+$(document).ready(function() {
+ $search_key = $("#search-key");
+ $search_key_submit = $("#search-key-submit");
+ $keyword_search_results = $("#keyword-search-results");
+
+ $search_key.keyup(function(e) {
+ if(e.keyCode == 13) {
+ $search_key_submit.click();
+ }
+ });
+
+ $search_key_submit.click(function() {
+ var key = $search_key.val();
+ $.ajax({
+ url: "/ajax-keyword-search/",
+ type: "POST",
+ data: {
+ key: key
+ },
+ dataType: "html",
+ success: function(data) {
+ $keyword_search_results.html(data);
+ console.log(data);
+ }
+ });
+ });
+
+ $search_time_submit = $("#search-time-submit");
+ $category = $("#search-category");
+ $tutorial = $("#search-tutorial");
+ $minute_range = $("#search-minute-range");
+ $second_range = $("#search-second-range");
+ $time_search_results = $("#time-search-results");
+
+ $category.change(function() {
+ var category = $(this).val();
+ $.ajax({
+ url: "/ajax-tutorials/",
+ type: "POST",
+ data: {
+ category: category
+ },
+ success: function(data) {
+ $tutorial.html(data);
+ $tutorial.removeAttr("disabled");
+ console.log("response = " + data);
+ }
+ });
+ });
+
+ $tutorial.change(function() {
+ console.log("tut changed");
+ var category = $category.val();
+ var tutorial = $(this).val();
+ $.ajax({
+ url: "/ajax-duration/",
+ type: "POST",
+ data: {
+ category: category,
+ tutorial: tutorial
+ },
+ success: function(data){
+ var $response = $(data);
+ console.log($response.html());
+ $minute_range.html($response.find("#minutes").html())
+ $minute_range.removeAttr("disabled");
+ $second_range.html($response.find("#seconds").html())
+ $second_range.removeAttr("disabled");
+ }
+ });
+ });
+
+ $search_time_submit.click(function() {
+ $.ajax({
+ url: "/ajax-time-search/",
+ type: "POST",
+ data: {
+ category: $category.val(),
+ tutorial: $tutorial.val(),
+ minute_range: $minute_range.val(),
+ second_range: $second_range.val()
+ },
+ dataType: "html",
+ success: function(data) {
+ console.log(data);
+ $time_search_results.html(data);
+ }
+ });
+ });
+
+});
diff --git a/static/website/templates/ajax-keyword-search.html b/static/website/templates/ajax-keyword-search.html
new file mode 100644
index 0000000..7d38a42
--- /dev/null
+++ b/static/website/templates/ajax-keyword-search.html
@@ -0,0 +1,55 @@
+{% if questions %}
+ {% for question in questions %}
+ <div class="question">
+ <div class="title">
+ <a href="{% url 'website:get_question' question.id %}">{{ question.title }}</a>
+ </div>
+ <br>
+ <span class="category">
+ <small>
+ <a href="{% url 'website:filter' question.category %}?qid={{ question.id }}">
+ {{ question.category }}
+ </a>
+ </small>
+ </span>
+
+ <span class="tutorial">
+ <small>
+ <a href="{% url 'website:filter' question.category question.tutorial %}?qid={{ question.id }}">
+ {{ question.tutorial}}
+ </a>
+ </small>
+ </span>
+
+ <span class="minute_range">
+ <small>
+ <a href="{% url 'website:filter' question.category question.tutorial question.minute_range %}?qid={{ question.id }}">
+ {{ question.minute_range }} min
+ </a>
+ </small>
+ </span>
+
+ <span class="second_range">
+ <small>
+ <a href="{% url 'website:filter' question.category question.tutorial question.minute_range question.second_range%}?qid={{ question.id }}">
+ {{ question.second_range }} sec
+ </a>
+ </small>
+ </span>
+
+ <span class="meta">
+ <small>
+ <i>
+ {{ question.date_created }}
+ </i>
+ </small>
+
+ <span class="user">
+ {{ question.user }}
+ </span>
+ </span>
+ </div> <!-- /.question -->
+ {% endfor %}
+{% else %}
+<h4>No results found . . .</h4>
+{% endif %}
diff --git a/static/website/templates/ajax-time-search.html b/static/website/templates/ajax-time-search.html
new file mode 100644
index 0000000..7d38a42
--- /dev/null
+++ b/static/website/templates/ajax-time-search.html
@@ -0,0 +1,55 @@
+{% if questions %}
+ {% for question in questions %}
+ <div class="question">
+ <div class="title">
+ <a href="{% url 'website:get_question' question.id %}">{{ question.title }}</a>
+ </div>
+ <br>
+ <span class="category">
+ <small>
+ <a href="{% url 'website:filter' question.category %}?qid={{ question.id }}">
+ {{ question.category }}
+ </a>
+ </small>
+ </span>
+
+ <span class="tutorial">
+ <small>
+ <a href="{% url 'website:filter' question.category question.tutorial %}?qid={{ question.id }}">
+ {{ question.tutorial}}
+ </a>
+ </small>
+ </span>
+
+ <span class="minute_range">
+ <small>
+ <a href="{% url 'website:filter' question.category question.tutorial question.minute_range %}?qid={{ question.id }}">
+ {{ question.minute_range }} min
+ </a>
+ </small>
+ </span>
+
+ <span class="second_range">
+ <small>
+ <a href="{% url 'website:filter' question.category question.tutorial question.minute_range question.second_range%}?qid={{ question.id }}">
+ {{ question.second_range }} sec
+ </a>
+ </small>
+ </span>
+
+ <span class="meta">
+ <small>
+ <i>
+ {{ question.date_created }}
+ </i>
+ </small>
+
+ <span class="user">
+ {{ question.user }}
+ </span>
+ </span>
+ </div> <!-- /.question -->
+ {% endfor %}
+{% else %}
+<h4>No results found . . .</h4>
+{% endif %}
diff --git a/static/website/templates/base.html b/static/website/templates/base.html
index c71e3ef..dccb556 100644
--- a/static/website/templates/base.html
+++ b/static/website/templates/base.html
@@ -6,6 +6,7 @@
<link rel="stylesheet" href="{% static 'website/css/main.css' %}" type="text/css" media="screen" charset="utf-8" />
</head>
<body>
+ <div id="page-wrapper">
<div id="header-wrapper">
<div id="header-inner">
<nav class="navbar navbar-default" role="navigation">
@@ -27,6 +28,12 @@
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav navbar-right">
<li>
+ <a href="{% url 'website:search' %}">
+ <span class="glyphicon glyphicon-search"></span>
+ Search
+ </a>
+ </li>
+ <li>
<a href="{% url 'website:new_question' %}">
<span class="glyphicon glyphicon-pencil"></span>
Ask Question
@@ -86,9 +93,11 @@
</div>
</div> <!-- /#footer-inner -->
</div> <!-- /#footer-wrapper -->
-
+ </div> <!-- /#page-wrapper -->
+
<script src="{% static 'website/js/jquery.min.js' %}"></script>
<script src="{% static 'website/js/bootstrap.min.js' %}"></script>
+
{% block javascript %}
<!-- overide with custom javascript -->
{% endblock %}
diff --git a/static/website/templates/search.html b/static/website/templates/search.html
new file mode 100644
index 0000000..8c96acb
--- /dev/null
+++ b/static/website/templates/search.html
@@ -0,0 +1,73 @@
+{% extends 'website/templates/base.html' %}
+{% load static %}
+
+{% block content %}
+
+ <!-- Nav tabs -->
+<ul class="nav nav-tabs">
+ <li><a href="#search-by-keyword" data-toggle="tab">Search by Keyword</a></li>
+ <li><a href="#search-by-time" data-toggle="tab">Search by Time</a></li>
+</ul>
+
+<!-- Tab panes -->
+<div class="tab-content">
+<br>
+ <div class="tab-pane active" id="search-by-keyword">
+ <div class="row">
+ <div class="col-lg-10">
+ <input id="search-key" class="form-control" placeholder="eg: python, scilab">
+ </div>
+ <div class="col-lg-2">
+ <a id="search-key-submit" class="btn btn-primary btn-sm btn-block" href="#">Search</a>
+ </div>
+ </div>
+
+ <div id="keyword-search-results">
+ </div>
+ </div>
+
+ <div class="tab-pane" id="search-by-time">
+ <div class="row">
+ <div class="col-lg-3 col-md-3 col-sm-3">
+ <select id="search-category" class="form-control">
+ <option value="None">Select Category</option>
+ {% for category in categories %}
+ <option value="{{ category }}">{{ category }}</option>
+ {% endfor %}
+ </select>
+ </div>
+
+ <div class="col-lg-3 col-md-3 col-sm-3">
+ <select id="search-tutorial" class="form-control" disabled="disabled">
+ <option value="None">Select Tutorial</option>
+ </select>
+ </div>
+
+ <div class="col-lg-2 col-md-2 col-sm-2">
+ <select id="search-minute-range" class="form-control" disabled="disabled">
+ <option value="None">min</option>
+ </select>
+ </div>
+
+ <div class="col-lg-2 col-md-2 col-sm-2">
+ <select id="search-second-range" class="form-control" disabled="disabled">
+ <option value="None">sec</option>
+ </select>
+ </div>
+
+ <div class="col-lg-2 col-md-2 col-sm-2">
+ <input id="search-time-submit" class="btn btn-sm btn-warning btn-block" type="button" value="Search">
+ </div>
+ <div class="clearfix"></div>
+ </div> <!-- /.row -->
+
+ <div id="time-search-results">
+ </div>
+ </div>
+</div> <!-- tab panes -->
+
+{% endblock %}
+
+{% block javascript %}
+ <script src="{% static 'website/js/search.js' %}"></script>
+{% endblock %}
diff --git a/website/urls.py b/website/urls.py
index 20f8201..bdad667 100644
--- a/website/urls.py
+++ b/website/urls.py
@@ -13,7 +13,8 @@ urlpatterns = patterns('',
url(r'^user/(?P<user_id>\d+)/questions/$', 'website.views.user_questions', name='user_questions'),
url(r'^user/(?P<user_id>\d+)/replies/$', 'website.views.user_replies', name='user_replies'),
url(r'^clear-notifications/$', 'website.views.clear_notifications', name='clear_notifications'),
-
+ url(r'^search/$', 'website.views.search', name='search'),
+
# Ajax helpers
url(r'^ajax-tutorials/$', 'website.views.ajax_tutorials', name='ajax_tutorials'),
url(r'^ajax-duration/$', 'website.views.ajax_duration', name='ajax_duration'),
@@ -21,4 +22,6 @@ urlpatterns = patterns('',
url(r'^ajax-reply-update/$', 'website.views.ajax_reply_update', name='ajax_reply_update'),
url(r'^ajax-similar-questions/$', 'website.views.ajax_similar_questions', name='ajax_similar_questions'),
url(r'^ajax-notification-remove/$', 'website.views.ajax_notification_remove', name='ajax_notification_remove'),
+ url(r'^ajax-keyword-search/$', 'website.views.ajax_keyword_search', name='ajax_keyword_search'),
+ url(r'^ajax-time-search/$', 'website.views.ajax_time_search', name='ajax_time_search'),
)
diff --git a/website/views.py b/website/views.py
index b6c6670..de4d592 100644
--- a/website/views.py
+++ b/website/views.py
@@ -1,3 +1,5 @@
+import re
+
from django.http import HttpResponse, HttpResponseRedirect
from django.shortcuts import render, get_object_or_404
from django.core.context_processors import csrf
@@ -178,6 +180,14 @@ def clear_notifications(request):
Notification.objects.filter(uid=request.user.id).delete()
return HttpResponseRedirect("/user/{}/notifications/".format(request.user.id))
+def search(request):
+ context = {
+ 'categories': categories
+ }
+ return render(request, 'website/templates/search.html', context)
+
+# Ajax Section
+# All the ajax views go below
@csrf_exempt
def ajax_tutorials(request):
if request.method == 'POST':
@@ -259,3 +269,49 @@ def ajax_notification_remove(request):
notification.delete()
return HttpResponse("removed")
return HttpResponse("failed")
+
+@csrf_exempt
+def ajax_keyword_search(request):
+ if request.method == "POST":
+ key = request.POST['key']
+ questions = Question.objects.filter(title__icontains=key)
+ context = {
+ 'questions': questions
+ }
+ return render(request, 'website/templates/ajax-keyword-search.html', context)
+
+@csrf_exempt
+def ajax_time_search(request):
+ if request.method == "POST":
+ key = request.POST['key']
+ questions = Question.objects.filter(title__icontains=key)
+ context = {
+ 'questions': questions
+ }
+ return render(request, 'website/templates/ajax-keyword-search.html', context)
+
+@csrf_exempt
+def ajax_time_search(request):
+ if request.method == "POST":
+ category = request.POST.get('category')
+ tutorial = request.POST.get('tutorial')
+ minute_range= request.POST.get('minute_range')
+ second_range = request.POST.get('second_range')
+
+ if category != 'None':
+ questions = Question.objects.filter(category=category)
+
+ if tutorial != 'None':
+ questions = questions.filter(tutorial=tutorial)
+
+ if minute_range != 'None':
+ questions = questions.filter(minute_range=minute_range)
+
+ if second_range != 'None':
+ questions = questions.filter(second_range=second_range)
+
+ context = {
+ 'questions': questions
+ }
+
+ return render(request, 'website/templates/ajax-time-search.html', context)