Added functionality for the user to filter their review items based on item level.
This commit is contained in:
parent
b3efe16e3c
commit
3bcdbd621e
@ -1,18 +1,4 @@
|
|||||||
refreshQuestion = () ->
|
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'))
|
if(sessionStorage.getItem('user_items'))
|
||||||
items = JSON.parse(sessionStorage.getItem('user_items'))
|
items = JSON.parse(sessionStorage.getItem('user_items'))
|
||||||
selection = items[Math.floor(Math.random() * items.length)]
|
selection = items[Math.floor(Math.random() * items.length)]
|
||||||
@ -45,6 +31,58 @@ refreshQuestion = () ->
|
|||||||
$("#kana").attr("placeholder", "かな")
|
$("#kana").attr("placeholder", "かな")
|
||||||
wanakana.bind(input_element);
|
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) ->
|
$(document).keypress (e) ->
|
||||||
if(e.which == 13)
|
if(e.which == 13)
|
||||||
$("#submit-answer").click();
|
$("#submit-answer").click();
|
||||||
@ -72,6 +110,7 @@ $("#api-refresh").click (e) ->
|
|||||||
$('#success-area').show();
|
$('#success-area').show();
|
||||||
).fail(() ->
|
).fail(() ->
|
||||||
$('#error-area').show();
|
$('#error-area').show();
|
||||||
|
$('#error-text').text("Cannot refresh API. Try again later.")
|
||||||
$("#api-refresh").find('span').removeClass('glyphicon-spin');
|
$("#api-refresh").find('span').removeClass('glyphicon-spin');
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -84,4 +123,4 @@ $('#success-area').find('button').click () ->
|
|||||||
$ ->
|
$ ->
|
||||||
$(document).ready ->
|
$(document).ready ->
|
||||||
$('[data-toggle="tooltip"]').tooltip();
|
$('[data-toggle="tooltip"]').tooltip();
|
||||||
refreshQuestion();
|
filterQuestions()
|
||||||
|
@ -1,27 +1,9 @@
|
|||||||
// Generated by CoffeeScript 1.10.0
|
// Generated by CoffeeScript 1.10.0
|
||||||
(function() {
|
(function() {
|
||||||
var refreshQuestion;
|
var filterQuestions, refreshQuestion, updateQuizItemStats;
|
||||||
|
|
||||||
refreshQuestion = function() {
|
refreshQuestion = function() {
|
||||||
var input_element, items, selection;
|
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')) {
|
if (sessionStorage.getItem('user_items')) {
|
||||||
items = JSON.parse(sessionStorage.getItem('user_items'));
|
items = JSON.parse(sessionStorage.getItem('user_items'));
|
||||||
selection = items[Math.floor(Math.random() * items.length)];
|
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) {
|
$(document).keypress(function(e) {
|
||||||
if (e.which === 13) {
|
if (e.which === 13) {
|
||||||
return $("#submit-answer").click();
|
return $("#submit-answer").click();
|
||||||
@ -95,6 +138,7 @@
|
|||||||
return $('#success-area').show();
|
return $('#success-area').show();
|
||||||
}).fail(function() {
|
}).fail(function() {
|
||||||
$('#error-area').show();
|
$('#error-area').show();
|
||||||
|
$('#error-text').text("Cannot refresh API. Try again later.");
|
||||||
return $("#api-refresh").find('span').removeClass('glyphicon-spin');
|
return $("#api-refresh").find('span').removeClass('glyphicon-spin');
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
@ -110,7 +154,7 @@
|
|||||||
$(function() {
|
$(function() {
|
||||||
return $(document).ready(function() {
|
return $(document).ready(function() {
|
||||||
$('[data-toggle="tooltip"]').tooltip();
|
$('[data-toggle="tooltip"]').tooltip();
|
||||||
return refreshQuestion();
|
return filterQuestions();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -1,5 +1,24 @@
|
|||||||
{% extends "layout.html" %}
|
{% extends "layout.html" %}
|
||||||
{% block content %}
|
{% 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">×</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">
|
<nav class="navbar navbar-default">
|
||||||
<div class="container-fluid">
|
<div class="container-fluid">
|
||||||
<div class="navbar-header">
|
<div class="navbar-header">
|
||||||
@ -8,8 +27,13 @@
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<ul class="nav navbar-nav navbar-right">
|
<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">
|
<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">
|
<ul class="dropdown-menu" aria-labelledby="dLabel">
|
||||||
<li><span id="radical-num"></span> Radicals</li>
|
<li><span id="radical-num"></span> Radicals</li>
|
||||||
<li><span id="kanji-num"></span> Kanji</li>
|
<li><span id="kanji-num"></span> Kanji</li>
|
||||||
@ -30,7 +54,7 @@
|
|||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-12 text-center">
|
<div class="col-md-12 text-center">
|
||||||
<div id="error-area" class="alert alert-danger alert-dismissible collapse" role="alert">
|
<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">×</span></button>Cannot refresh API. Try again later.
|
<button type="button" class="close" aria-label="Close"><span aria-hidden="true">×</span></button><div id="error-text"></div>
|
||||||
</div>
|
</div>
|
||||||
<div id="success-area" class="alert alert-success alert-dismissible collapse" role="alert">
|
<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">×</span></button>API Refreshed!
|
<button type="button" class="close" aria-label="Close"><span aria-hidden="true">×</span></button>API Refreshed!
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import json
|
import json, re
|
||||||
from flask import Flask, render_template, redirect, url_for, jsonify, flash
|
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.login import LoginManager, login_user, login_required, current_user, logout_user, login_fresh
|
||||||
from flask.ext.sqlalchemy import SQLAlchemy
|
from flask.ext.sqlalchemy import SQLAlchemy
|
||||||
@ -13,6 +13,7 @@ app.config.from_pyfile('config.py')
|
|||||||
login_manager = LoginManager()
|
login_manager = LoginManager()
|
||||||
login_manager.init_app(app)
|
login_manager.init_app(app)
|
||||||
db = SQLAlchemy(app)
|
db = SQLAlchemy(app)
|
||||||
|
filter_regex = re.compile('\d+([,-]\d+)*')
|
||||||
|
|
||||||
|
|
||||||
class LoginForm(Form):
|
class LoginForm(Form):
|
||||||
@ -91,12 +92,12 @@ class User(db.Model):
|
|||||||
|
|
||||||
|
|
||||||
def parse_range(input_range):
|
def parse_range(input_range):
|
||||||
if input_range.match('\d+([,-]\d+)*'):
|
if filter_regex.match(input_range):
|
||||||
result = []
|
result = []
|
||||||
components = input_range.split(',')
|
components = input_range.split(',')
|
||||||
for item in components:
|
for item in components:
|
||||||
if item.isdigit():
|
if item.isdigit():
|
||||||
result.append(item)
|
result.append(int(item))
|
||||||
else:
|
else:
|
||||||
range_ends = item.split('-')
|
range_ends = item.split('-')
|
||||||
result.extend(list(range(range_ends[0], range_ends[1])))
|
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']})
|
items.append({'item_type': 'radical', 'question': item['character'], 'answer': item['meaning']})
|
||||||
kanji_count = 0
|
kanji_count = 0
|
||||||
for item in json.loads(current_user.kanji):
|
for item in json.loads(current_user.kanji):
|
||||||
kanji_count += 1
|
|
||||||
made_answer = ""
|
made_answer = ""
|
||||||
if item['user_specific'] and item['user_specific']['burned'] and item['level'] in level_range:
|
if item['user_specific'] and item['user_specific']['burned'] and item['level'] in level_range:
|
||||||
|
kanji_count += 1
|
||||||
if item['onyomi'] and item['kunyomi']:
|
if item['onyomi'] and item['kunyomi']:
|
||||||
made_answer = item['onyomi'] + ',' + item['kunyomi'].replace('.*', '')
|
made_answer = item['onyomi'] + ',' + item['kunyomi'].replace('.*', '')
|
||||||
elif item['onyomi']:
|
elif item['onyomi']:
|
||||||
@ -132,8 +133,11 @@ def get_items_with_level_restriction(level_range):
|
|||||||
vocabulary_count += 1
|
vocabulary_count += 1
|
||||||
items.append({'item_type': 'vocabulary', 'question': item['character'], 'answer': item['kana'],
|
items.append({'item_type': 'vocabulary', 'question': item['character'], 'answer': item['kana'],
|
||||||
'answer_meaning': item['meaning']})
|
'answer_meaning': item['meaning']})
|
||||||
return jsonify(radical_count=radical_count, kanji_count=kanji_count, vocabulary_count=vocabulary_count,
|
if not items:
|
||||||
item_list=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
|
@login_manager.user_loader
|
||||||
@ -177,7 +181,7 @@ def show_quiz():
|
|||||||
@app.route('/user_items')
|
@app.route('/user_items')
|
||||||
@login_required
|
@login_required
|
||||||
def get_items():
|
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>')
|
@app.route('/user_items/<level_range>')
|
||||||
|
Loading…
Reference in New Issue
Block a user