diff options
-rw-r--r-- | static/website/css/main.css | 35 | ||||
-rw-r--r-- | static/website/images/bg-stripes.png | bin | 0 -> 119 bytes | |||
-rw-r--r-- | static/website/js/search.js | 91 | ||||
-rw-r--r-- | static/website/templates/ajax-keyword-search.html | 55 | ||||
-rw-r--r-- | static/website/templates/ajax-time-search.html | 55 | ||||
-rw-r--r-- | static/website/templates/base.html | 11 | ||||
-rw-r--r-- | static/website/templates/search.html | 73 | ||||
-rw-r--r-- | website/urls.py | 5 | ||||
-rw-r--r-- | website/views.py | 56 |
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 Binary files differnew file mode 100644 index 0000000..4390d95 --- /dev/null +++ b/static/website/images/bg-stripes.png 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) |