Added functionality for the user to filter their review items based on item level.

This commit is contained in:
neviyn 2015-10-19 23:33:26 +01:00
parent b3efe16e3c
commit 3bcdbd621e
4 changed files with 155 additions and 44 deletions

View File

@ -1,18 +1,4 @@
refreshQuestion = () ->
if(not sessionStorage.getItem('user_items'))
$.ajax
url: "/user_items",
dataType: 'json',
success: (e) ->
sessionStorage.setItem('user_items', JSON.stringify(e['item_list']))
sessionStorage.setItem('radical_count', e['radical_count'])
sessionStorage.setItem('kanji_count', e['kanji_count'])
sessionStorage.setItem('vocabulary_count', e['vocabulary_count'])
refreshQuestion()
if($('#radical-num').text() == '')
$('#radical-num').text(sessionStorage.getItem('radical_count'));
$('#kanji-num').text(sessionStorage.getItem('kanji_count'));
$('#vocab-num').text(sessionStorage.getItem('vocabulary_count'));
if(sessionStorage.getItem('user_items'))
items = JSON.parse(sessionStorage.getItem('user_items'))
selection = items[Math.floor(Math.random() * items.length)]
@ -45,6 +31,58 @@ refreshQuestion = () ->
$("#kana").attr("placeholder", "かな")
wanakana.bind(input_element);
updateQuizItemStats = () ->
$('#radical-num').text(sessionStorage.getItem('radical_count'));
$('#kanji-num').text(sessionStorage.getItem('kanji_count'));
$('#vocab-num').text(sessionStorage.getItem('vocabulary_count'));
filterQuestions = () ->
input_data = $('#filter-input').val()
if(input_data)
sessionStorage.removeItem('user_items')
sessionStorage.removeItem('radical_count')
sessionStorage.removeItem('kanji_count')
sessionStorage.removeItem('vocabulary_count')
target_url = "/user_items/" + input_data
$.ajax
url: target_url,
dataType: 'json',
success: (e) ->
if(e.hasOwnProperty('error'))
document.getElementById('filter-input').value = ''
$('#error-text').text(e['error'])
$('#error-area').show();
filterQuestions()
else
sessionStorage.setItem('user_items', JSON.stringify(e['item_list']))
sessionStorage.setItem('radical_count', e['radical_count'])
sessionStorage.setItem('kanji_count', e['kanji_count'])
sessionStorage.setItem('vocabulary_count', e['vocabulary_count'])
updateQuizItemStats()
refreshQuestion()
else
sessionStorage.removeItem('user_items')
sessionStorage.removeItem('radical_count')
sessionStorage.removeItem('kanji_count')
sessionStorage.removeItem('vocabulary_count')
$.ajax
url: "/user_items",
dataType: 'json',
success: (e) ->
sessionStorage.setItem('user_items', JSON.stringify(e['item_list']))
sessionStorage.setItem('radical_count', e['radical_count'])
sessionStorage.setItem('kanji_count', e['kanji_count'])
sessionStorage.setItem('vocabulary_count', e['vocabulary_count'])
updateQuizItemStats()
refreshQuestion()
$('#filter-form').submit( (e) ->
e.preventDefault()
filterQuestions()
refreshQuestion()
$('#modal-filter').modal('hide')
)
$(document).keypress (e) ->
if(e.which == 13)
$("#submit-answer").click();
@ -72,6 +110,7 @@ $("#api-refresh").click (e) ->
$('#success-area').show();
).fail(() ->
$('#error-area').show();
$('#error-text').text("Cannot refresh API. Try again later.")
$("#api-refresh").find('span').removeClass('glyphicon-spin');
);
@ -84,4 +123,4 @@ $('#success-area').find('button').click () ->
$ ->
$(document).ready ->
$('[data-toggle="tooltip"]').tooltip();
refreshQuestion();
filterQuestions()

View File

@ -1,27 +1,9 @@
// Generated by CoffeeScript 1.10.0
(function() {
var refreshQuestion;
var filterQuestions, refreshQuestion, updateQuizItemStats;
refreshQuestion = function() {
var input_element, items, selection;
if (!sessionStorage.getItem('user_items')) {
$.ajax({
url: "/user_items",
dataType: 'json',
success: function(e) {
sessionStorage.setItem('user_items', JSON.stringify(e['item_list']));
sessionStorage.setItem('radical_count', e['radical_count']);
sessionStorage.setItem('kanji_count', e['kanji_count']);
sessionStorage.setItem('vocabulary_count', e['vocabulary_count']);
return refreshQuestion();
}
});
}
if ($('#radical-num').text() === '') {
$('#radical-num').text(sessionStorage.getItem('radical_count'));
$('#kanji-num').text(sessionStorage.getItem('kanji_count'));
$('#vocab-num').text(sessionStorage.getItem('vocabulary_count'));
}
if (sessionStorage.getItem('user_items')) {
items = JSON.parse(sessionStorage.getItem('user_items'));
selection = items[Math.floor(Math.random() * items.length)];
@ -60,6 +42,67 @@
}
};
updateQuizItemStats = function() {
$('#radical-num').text(sessionStorage.getItem('radical_count'));
$('#kanji-num').text(sessionStorage.getItem('kanji_count'));
return $('#vocab-num').text(sessionStorage.getItem('vocabulary_count'));
};
filterQuestions = function() {
var input_data, target_url;
input_data = $('#filter-input').val();
if (input_data) {
sessionStorage.removeItem('user_items');
sessionStorage.removeItem('radical_count');
sessionStorage.removeItem('kanji_count');
sessionStorage.removeItem('vocabulary_count');
target_url = "/user_items/" + input_data;
return $.ajax({
url: target_url,
dataType: 'json',
success: function(e) {
if (e.hasOwnProperty('error')) {
document.getElementById('filter-input').value = '';
$('#error-text').text(e['error']);
$('#error-area').show();
return filterQuestions();
} else {
sessionStorage.setItem('user_items', JSON.stringify(e['item_list']));
sessionStorage.setItem('radical_count', e['radical_count']);
sessionStorage.setItem('kanji_count', e['kanji_count']);
sessionStorage.setItem('vocabulary_count', e['vocabulary_count']);
updateQuizItemStats();
return refreshQuestion();
}
}
});
} else {
sessionStorage.removeItem('user_items');
sessionStorage.removeItem('radical_count');
sessionStorage.removeItem('kanji_count');
sessionStorage.removeItem('vocabulary_count');
return $.ajax({
url: "/user_items",
dataType: 'json',
success: function(e) {
sessionStorage.setItem('user_items', JSON.stringify(e['item_list']));
sessionStorage.setItem('radical_count', e['radical_count']);
sessionStorage.setItem('kanji_count', e['kanji_count']);
sessionStorage.setItem('vocabulary_count', e['vocabulary_count']);
updateQuizItemStats();
return refreshQuestion();
}
});
}
};
$('#filter-form').submit(function(e) {
e.preventDefault();
filterQuestions();
refreshQuestion();
return $('#modal-filter').modal('hide');
});
$(document).keypress(function(e) {
if (e.which === 13) {
return $("#submit-answer").click();
@ -95,6 +138,7 @@
return $('#success-area').show();
}).fail(function() {
$('#error-area').show();
$('#error-text').text("Cannot refresh API. Try again later.");
return $("#api-refresh").find('span').removeClass('glyphicon-spin');
});
});
@ -110,7 +154,7 @@
$(function() {
return $(document).ready(function() {
$('[data-toggle="tooltip"]').tooltip();
return refreshQuestion();
return filterQuestions();
});
});

View File

@ -1,5 +1,24 @@
{% extends "layout.html" %}
{% block content %}
<div class="modal fade" id="modal-filter" tabindex="-1" role="dialog" aria-labelledby="mySmallModalLabel">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
<h4 class="modal-title">Filter</h4>
</div>
<form id="filter-form">
<div class="modal-body">
<input type="text" pattern="\d[\d-,]*\d*" class="form-control" id="filter-input" placeholder="e.g. 1-3,5,8">
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
<button class="btn btn-primary" type="submit">Save changes</button>
</div>
</form>
</div>
</div>
</div>
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
@ -8,8 +27,13 @@
</a>
</div>
<ul class="nav navbar-nav navbar-right">
<li>
<button type="button" id="itemfilter" class="btn btn-default navbar-btn" data-toggle="modal" data-target="#modal-filter">
Filter
</button>
</li>
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown"><span class="glyphicon glyphicon-option-horizontal"></span></a>
<button class="btn btn-default navbar-btn dropdown-toggle" data-toggle="dropdown">Stats</button>
<ul class="dropdown-menu" aria-labelledby="dLabel">
<li><span id="radical-num"></span> Radicals</li>
<li><span id="kanji-num"></span> Kanji</li>
@ -30,7 +54,7 @@
<div class="row">
<div class="col-md-12 text-center">
<div id="error-area" class="alert alert-danger alert-dismissible collapse" role="alert">
<button type="button" class="close" aria-label="Close"><span aria-hidden="true">&times;</span></button>Cannot refresh API. Try again later.
<button type="button" class="close" aria-label="Close"><span aria-hidden="true">&times;</span></button><div id="error-text"></div>
</div>
<div id="success-area" class="alert alert-success alert-dismissible collapse" role="alert">
<button type="button" class="close" aria-label="Close"><span aria-hidden="true">&times;</span></button>API Refreshed!

View File

@ -1,4 +1,4 @@
import json
import json, re
from flask import Flask, render_template, redirect, url_for, jsonify, flash
from flask.ext.login import LoginManager, login_user, login_required, current_user, logout_user, login_fresh
from flask.ext.sqlalchemy import SQLAlchemy
@ -13,6 +13,7 @@ app.config.from_pyfile('config.py')
login_manager = LoginManager()
login_manager.init_app(app)
db = SQLAlchemy(app)
filter_regex = re.compile('\d+([,-]\d+)*')
class LoginForm(Form):
@ -91,12 +92,12 @@ class User(db.Model):
def parse_range(input_range):
if input_range.match('\d+([,-]\d+)*'):
if filter_regex.match(input_range):
result = []
components = input_range.split(',')
for item in components:
if item.isdigit():
result.append(item)
result.append(int(item))
else:
range_ends = item.split('-')
result.extend(list(range(range_ends[0], range_ends[1])))
@ -115,9 +116,9 @@ def get_items_with_level_restriction(level_range):
items.append({'item_type': 'radical', 'question': item['character'], 'answer': item['meaning']})
kanji_count = 0
for item in json.loads(current_user.kanji):
kanji_count += 1
made_answer = ""
if item['user_specific'] and item['user_specific']['burned'] and item['level'] in level_range:
kanji_count += 1
if item['onyomi'] and item['kunyomi']:
made_answer = item['onyomi'] + ',' + item['kunyomi'].replace('.*', '')
elif item['onyomi']:
@ -132,8 +133,11 @@ def get_items_with_level_restriction(level_range):
vocabulary_count += 1
items.append({'item_type': 'vocabulary', 'question': item['character'], 'answer': item['kana'],
'answer_meaning': item['meaning']})
return jsonify(radical_count=radical_count, kanji_count=kanji_count, vocabulary_count=vocabulary_count,
item_list=items)
if not items:
return jsonify(error="No items within these filter parameters")
else:
return jsonify(radical_count=radical_count, kanji_count=kanji_count, vocabulary_count=vocabulary_count,
item_list=items)
@login_manager.user_loader
@ -177,7 +181,7 @@ def show_quiz():
@app.route('/user_items')
@login_required
def get_items():
return get_items_with_level_restriction(list(range(0, 60)))
return get_items_with_level_restriction(list(range(0, 61)))
@app.route('/user_items/<level_range>')