From 7bc0c8f65c24b9d8ea7903cd9eacebc119ef7c6a Mon Sep 17 00:00:00 2001 From: Nikolai R Kristiansen Date: Tue, 7 Jul 2015 17:39:06 +0200 Subject: [PATCH] Search existing members in Inside. - Also removes some files belonging to another project --- README.md | 15 + apps/kassa/forms.py | 10 +- apps/kassa/templates/kassa/register.html | 15 +- apps/kassa/urls.py | 7 +- apps/kassa/views.py | 19 +- kassasite/settings.py | 3 + requirements.txt | 2 +- static/app/scripts/app.js | 58 + static/app/scripts/documents_edit.js | 95 -- static/app/scripts/fd-slider.js | 1341 --------------------- static/app/scripts/graphs.js | 186 --- static/app/scripts/presentation_edit.js | 121 -- static/app/scripts/presentation_list.js | 9 - static/app/scripts/product_calculator.js | 541 --------- static/app/scripts/slide_edit.js | 276 ----- static/app/scripts/slides.js | 440 ------- static/dist/scripts/app.js | 58 + static/dist/scripts/documents_edit.js | 95 -- static/dist/scripts/fd-slider.js | 1341 --------------------- static/dist/scripts/graphs.js | 186 --- static/dist/scripts/presentation_edit.js | 121 -- static/dist/scripts/presentation_list.js | 9 - static/dist/scripts/product_calculator.js | 541 --------- static/dist/scripts/slide_edit.js | 276 ----- static/dist/scripts/slides.js | 440 ------- 25 files changed, 170 insertions(+), 6035 deletions(-) delete mode 100644 static/app/scripts/documents_edit.js delete mode 100644 static/app/scripts/fd-slider.js delete mode 100644 static/app/scripts/graphs.js delete mode 100644 static/app/scripts/presentation_edit.js delete mode 100644 static/app/scripts/presentation_list.js delete mode 100644 static/app/scripts/product_calculator.js delete mode 100644 static/app/scripts/slide_edit.js delete mode 100644 static/app/scripts/slides.js delete mode 100644 static/dist/scripts/documents_edit.js delete mode 100644 static/dist/scripts/fd-slider.js delete mode 100644 static/dist/scripts/graphs.js delete mode 100644 static/dist/scripts/presentation_edit.js delete mode 100644 static/dist/scripts/presentation_list.js delete mode 100644 static/dist/scripts/product_calculator.js delete mode 100644 static/dist/scripts/slide_edit.js delete mode 100644 static/dist/scripts/slides.js diff --git a/README.md b/README.md index 4603dc8..d08fe4d 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,18 @@ +# Installation + apt install libldap2-dev # reqs + virtualenv venv + . venv/bin/activate + pip install -r requirements.txt + python manage.py migrate + + +## LDAP + sudo docker run -e LDAP_DOMAIN=neuf.no -e LDAP_ORGANISATION="Neuf" -e LDAP_ADMIN_PASSWORD="toor" -p 389:389 -d nikolaik/openldap + ldapadd -D "cn=admin,dc=neuf,dc=no" -w "toor" -f test/testdata.ldif # Testdata + # Verify import + ldapsearch -x -b dc=neuf,dc=no + # Login with test@example.com:test + ## TODO ### Form * tlf field diff --git a/apps/kassa/forms.py b/apps/kassa/forms.py index ea827d8..b672432 100644 --- a/apps/kassa/forms.py +++ b/apps/kassa/forms.py @@ -1,10 +1,10 @@ from django import forms from phonenumber_field.formfields import PhoneNumberField +from django.utils.translation import ugettext_lazy as _ +class SearchUserForm(forms.Form): + query = forms.CharField(required=False) # ,label=_('Search existing members')) class AddCardForm(forms.Form): - phone_number = PhoneNumberField(widget=forms.TextInput(attrs={ - 'type': 'tel', - 'class': 'form-control' - })) - card_number = forms.IntegerField(widget=forms.NumberInput(attrs={'class': 'form-control'})) + phone_number = PhoneNumberField(widget=forms.TextInput(attrs={'type': 'tel'})) + card_number = forms.IntegerField(widget=forms.NumberInput()) diff --git a/apps/kassa/templates/kassa/register.html b/apps/kassa/templates/kassa/register.html index 6cda36e..c89c32a 100644 --- a/apps/kassa/templates/kassa/register.html +++ b/apps/kassa/templates/kassa/register.html @@ -3,22 +3,25 @@ {% block content %}
-

Registrer kjøpt medlemskap

+

{% trans "Register membership card" %}

-

Telefonnummer som allerede er tilknyttet en bruker i Inside vil få kortnummer registrert på sin bruker.

- {{ form|bootstrap }} +

{% trans "Lookup existing user" %}

+ {{ search_user_form|bootstrap }} +

{% trans "Register card" %}

+ {{ add_card_form|bootstrap }} +

Registering a card number with a phone number already tied to an existing user, will add the card to that user.

-
Søkeresultater
-
- TODO: ... +
Results
+
+  
diff --git a/apps/kassa/urls.py b/apps/kassa/urls.py index 9914b81..d4aa1f3 100644 --- a/apps/kassa/urls.py +++ b/apps/kassa/urls.py @@ -1,6 +1,7 @@ from django.conf.urls import url -from apps.kassa.views import register +from apps.kassa.views import register, inside_user_api urlpatterns = [ - url(r'^$', register, name='register') -] \ No newline at end of file + url(r'^$', register, name='register'), + url(r'^inside/user/$', inside_user_api, name='inside-user-api') +] diff --git a/apps/kassa/views.py b/apps/kassa/views.py index a9e4d30..b682272 100644 --- a/apps/kassa/views.py +++ b/apps/kassa/views.py @@ -1,14 +1,29 @@ # coding: utf-8 from __future__ import unicode_literals +from django.conf import settings from django.contrib.auth.decorators import login_required +from django.http import JsonResponse from django.shortcuts import render -from apps.kassa.forms import AddCardForm +from apps.kassa.forms import AddCardForm, SearchUserForm +import requests @login_required def register(request): context = { - 'form': AddCardForm() + 'add_card_form': AddCardForm(), + 'search_user_form': SearchUserForm() } return render(request, 'kassa/register.html', context) + +@login_required +def inside_user_api(request): + payload = { + 'apikey': settings.INSIDE_API_KEY, + 'q': request.GET.get('q', '') + } + url = settings.INSIDE_API_URL + data = requests.get(url, params=payload).json() + + return JsonResponse(data) diff --git a/kassasite/settings.py b/kassasite/settings.py index 9e6b630..ab1cf9d 100644 --- a/kassasite/settings.py +++ b/kassasite/settings.py @@ -116,6 +116,9 @@ STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles') LOGIN_REDIRECT_URL = '/' +INSIDE_API_KEY = '' +INSIDE_API_URL = 'https://inside.studentersamfundet.no/api/user.php' + # Local settings try: from local_settings import * diff --git a/requirements.txt b/requirements.txt index 677ebac..190780a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,4 +4,4 @@ django-bootstrap-form==3.2 django-extensions==1.5.5 django-phonenumber-field==0.7.2 mysqlclient==1.3.6 - +requests==2.7.0 diff --git a/static/app/scripts/app.js b/static/app/scripts/app.js index e69de29..e7353fb 100644 --- a/static/app/scripts/app.js +++ b/static/app/scripts/app.js @@ -0,0 +1,58 @@ +function format_results(results) { + var html = '
'; + for(var i=0; i< results.length; i++) { + var res = results[i]; + + var label = ''; + var is_member = res.is_member && res.is_member === "1"; + var add_to_button = ''; + var css_classes = ''; + var expires = res.expires; + + if(is_member) { + label = ' Member '; + css_classes += 'member'; + } else if(expires === '0000-00-00') { + add_to_button = ' '; + label = ' Registered '; + } else { + add_to_button = ' '; + label = ' Expired: '+ expires +' '; + } + var q = $('#id_query').val(); + html += '' + add_to_button + res.firstname + ' ' + res.lastname + label + ''; + } + return html + '
'; +} + +$(document).ready(function(){ + var _dom = { + results: $('.results-wrap'), + query: $('#id_query'), + phoneNumber: $('#id_phone_number'), + cardNumber: $('#id_card_number') + }; + var urls = { + insideUserApi: '/inside/user/' + }; + + /* Saerch as you type */ + _dom.query.on('keyup', function() { + var val = _dom.query.val(); + $.getJSON(urls.insideUserApi, {q: val}, function(data) { + //console.log(data); + if(data.results && data.results.length > 0) { + _dom.results.html(format_results(data.results)); + } else { + _dom.results.html('No existing user with that phone number'); + } + }); + }); + + /* Click search result */ + _dom.results.on('click', '.search-result', function(e){ + e.preventDefault(); + var number = $(this).attr('data-phone-number'); + _dom.phoneNumber.val(number); + }); +}); \ No newline at end of file diff --git a/static/app/scripts/documents_edit.js b/static/app/scripts/documents_edit.js deleted file mode 100644 index eca4572..0000000 --- a/static/app/scripts/documents_edit.js +++ /dev/null @@ -1,95 +0,0 @@ - -$(function(){ - var urls = { - save_document: '/api/document/', - update_document: '/api/document/{pk}/' - }; - var _dom = { - document_table: $('.document-table'), - progress_bar: $("#progress .bar"), - }; - var csrf_token = $.cookie('csrftoken'); - - /* inplace edit */ - _dom.document_table.on('click', "[data-model-field]", function() { - var input_field = $(this).siblings("input"); - if($(this).siblings("input").length) { - input_field.val($(this).text()).css('display', 'inline-block'); - } else { - $(this).after(''); - input_field = $(this).siblings("input"); - } - input_field.css('width', $(this).width() + 30); - $(this).hide(); - $("[data-editable-field]").focus(); - }); - - /* save on blur and */ - _dom.document_table.on('blur keyup', 'input[type=text]', function(e) { - if(e.type == 'keyup' && e.keyCode != 13) { - return; - } - /* anything changed ? */ - if( $(this).siblings("[data-model-field]").text() !== $(this).val() ) { - /* update text */ - $(this).siblings("[data-model-field]").text($(this).val()); - - var document_pk = $(this).siblings("[data-model-field]").attr('data-pk'); - var model_field = $(this).siblings("[data-model-field]").attr('data-model-field'); - var field_value = $(this).val(); - - var data = {}; - data[model_field] = field_value; - - $.ajax({ - url: urls.update_document.replace('{pk}', document_pk), - method: 'PATCH', - dataType: 'json', - data: data, - headers: { - 'X-CSRFToken': csrf_token - }, - success: function(response, newValue) { - console.log('Field '+model_field+' updated with value "'+field_value+'".'); - } - }); - } - /* Back to original view */ - $("[data-model-field]").show(); - $(this).hide(); - }); - - /* Document file upload */ - $('.upload-document').fileupload({ - dataType: 'json', // TODO: why no JSON? - url: urls.save_document, - done: function(e, data) { - _dom.progress_bar.fadeOut('slow'); - var result = data.result; - /* insert document row */ - - var filename = result.filename.slice(0, 40); - console.log(result); - - $('.document-table').prepend(''+ result.name +' '+ filename +''+ result.updated +''); - }, - fail: function(e, data) { - console.log("Failed uploading file: ",e, data); - }, - headers: { - 'X-CSRFToken': csrf_token, - 'cache-control': 'no-cache' - }, - send: function(e, data) { - _dom.progress_bar.css('width', '0%'); - _dom.progress_bar.show(); - }, - progressall: function (e, data) { - var progress = parseInt(data.loaded / data.total * 100, 10); - _dom.progress_bar.css( - 'width', - progress + '%' - ); - } - }); -}); diff --git a/static/app/scripts/fd-slider.js b/static/app/scripts/fd-slider.js deleted file mode 100644 index 940ee49..0000000 --- a/static/app/scripts/fd-slider.js +++ /dev/null @@ -1,1341 +0,0 @@ -/*! Unobtrusive Slider Control / HTML5 Input Range polyfill - MIT/GPL2 @freqdec */ -/*jshint sub:true, evil:true, boss:true */ -var fdSlider = (function() { - var sliders = {}, - uniqueid = 0, - mouseWheelEnabled = true, - fullARIA = true, - describedBy = "fd-slider-describedby", - varSetRules = { - onfocus:true, - onvalue:true - }, - noRangeBar = false, - html5Animation = "jump", - useDOMAttrModEvt = false, - isOpera = Object.prototype.toString.call(window.opera) === "[object Opera]", - fpRegExp = /^([\-]{0,1}[0-9]+(\.[0-9]+){0,1})$/, - stepRegExp = /^([0-9]+(\.[0-9]+){0,1})$/; - - var parseJSON = function(str) { - if(typeof str !== "string" || str === "") { - return {}; - } - try { - // Does a JSON (native or not) Object exist - if(typeof JSON === "object" && typeof(JSON.parse) === "function") { - return JSON.parse(str); - // Genious code taken from: http://kentbrewster.com/badges/ - } else if(/mousewheelenabled|fullaria|describedby|norangebar|html5animation|varsetrules/.test(str.toLowerCase())) { - var f = Function(['var document,top,self,window,parent,Number,Date,Object,Function,', - 'Array,String,Math,RegExp,Image,ActiveXObject;', - 'return (' , str.replace(/<\!--.+-->/gim,'').replace(/\bfunction\b/g,'function-') , ');'].join('')); - return f(); - } - } catch (e) { } - - return {"err":"Could not parse the JSON object"}; - }; - - var affectJSON = function(json) { - if(typeof json !== "object") { - return; - } - for(var key in json) { - value = json[key]; - switch(key.toLowerCase()) { - case "mousewheelenabled": - mouseWheelEnabled = !!value; - break; - case "fullaria": - fullARIA = !!value; - break; - case "describedby": - describedBy = String(value); - break; - case "norangebar": - noRangeBar = !!value; - break; - case "html5animation": - html5Animation = String(value).search(/^(jump|tween|timed)$/i) != -1 ? String(value).toLowerCase() : "jump"; - break; - case "watchattributes": - useDOMAttrModEvt = !!value; - break; - case "varsetrules": - if("onfocus" in value) { - varSetRules.onfocus = !!value.onfocus; - } - if("onvalue" in value) { - varSetRules.onvalue = !!value.onvalue; - } - break; - } - } - }; - var addEvent = function(obj, type, fn) { - if(obj.addEventListener) { - obj.addEventListener(type, fn, true); - } else if(obj.attachEvent) { - obj.attachEvent("on"+type, fn); - } - }; - var removeEvent = function(obj, type, fn) { - try { - if(obj.removeEventListener) { - obj.removeEventListener(type, fn, true); - } else if(obj.detachEvent) { - obj.detachEvent("on"+type, fn); - } - } catch(err) {} - }; - var stopEvent = function(e) { - e = e || window.event; - if(e.stopPropagation) { - e.stopPropagation(); - e.preventDefault(); - } - - /*@cc_on@*/ - /*@if(@_win32) - e.cancelBubble = true; - e.returnValue = false; - /*@end@*/ - - return false; - }; - var preventDefault = function(e) { - e = e || window.event; - if(e.preventDefault) { - e.preventDefault(); - return; - } - e.returnValue = false; - }; - // Add/Remove classname utility functions - var addClass = function(e,c) { - if(new RegExp("(^|\\s)" + c + "(\\s|$)").test(e.className)) { - return; - } - e.className += ( e.className ? " " : "" ) + c; - }; - var removeClass = function(e,c) { - e.className = !c ? "" : e.className.replace(new RegExp("(^|\\s)" + c + "(\\s|$)"), " ").replace(/^\s\s*/, '').replace(/\s\s*$/, ''); - }; - // Returns an Object of key value pairs indicating which sliders have values - // that have been "set" by the user. Normally used within form validation code - var getValueSet = function() { - var obj = {}; - for(var id in sliders) { - obj[id] = sliders[id].getValueSet(); - } - return obj; - }; - // Sets the valueSet variable for a specific slider - var setValueSet = function(sliderId, tf) { - sliders[sliderId].setValueSet(!!tf); - }; - // Does the slider exist in memory - var sliderExists = function(slider) { - return !!(slider in sliders && sliders.hasOwnProperty(slider)); - }; - // Javascript instantiation of a slider (input type="text|range" or select list) - var createSlider = function(options) { - if(!options || !options.inp || !options.inp.tagName || options.inp.tagName.search(/^input|select/i) == -1) { return false; } - - options.html5Shim = false; - - if(options.inp.tagName.toLowerCase() == "select") { - if(options.inp.options.length < 2) { - return false; - } - options.min = 0; - options.max = options.inp.options.length - 1; - options.step = 1; - options.precision = 0; - options.scale = false; - options.forceValue = true; - } else { - if(String(options.inp.type).search(/^(text|range)$/i) == -1) { - return false; - } - options.min = options.min && String(options.min).search(fpRegExp) != -1 ? +options.min : 0; - options.max = options.max && String(options.max).search(fpRegExp) != -1 ? +options.max : 100; - options.step = options.step && String(options.step).search(stepRegExp) != -1 ? options.step : 1; - options.precision = options.precision && String(options.precision).search(/^[0-9]+$/) != -1 ? options.precision : (String(options.step).search(/\.([0-9]+)$/) != -1 ? String(options.step).match(/\.([0-9]+)$/)[1].length : 0); - options.scale = options.scale || false; - options.forceValue = ("forceValue" in options) ? !!options.forceValue : false; - options.userSnap = ("userSnap" in options) ? !!options.userSnap : false; - } - options.ariaFormat = ("ariaFormat" in options) && typeof options.ariaFormat == "function" ? options.ariaFormat : false; - options.maxStep = options.maxStep && String(options.maxStep).search(stepRegExp) != -1 ? +options.maxStep : +options.step * 2; - options.classNames = options.classNames || ""; - options.callbacks = options.callbacks || false; - - destroySingleSlider(options.inp.id); - sliders[options.inp.id] = new fdRange(options); - return true; - }; - var getAttribute = function(elem, att) { - return elem.getAttribute(att) || ""; - }; - // HTML5 input type="range" shim - called onload or onDomReady - var init = function() { - var inputs = document.getElementsByTagName("input"), - options, - defs; - - for(var i = 0, inp; inp = inputs[i]; i++) { - - if(inp.tagName.toLowerCase() == "input" && - (getAttribute(inp,"type") && getAttribute(inp,"type").toLowerCase() == "range") && - (getAttribute(inp, "min") && getAttribute(inp, "min").search(fpRegExp) != -1 || - getAttribute(inp, "max") && getAttribute(inp, "max").search(fpRegExp) != -1 || - getAttribute(inp, "step") && getAttribute(inp, "step").search(/^(any|([0-9]+(\.[0-9]+){0,1}))$/i) != -1 - )) { - - // Skip elements that have already been created are are resident in the DOM - if(inp.id && document.getElementById("fd-slider-"+inp.id)) { - continue; - // Destroy elements that have already been created but not resident in the DOM - } else if(inp.id && !document.getElementById("fd-slider-"+inp.id)) { - destroySingleSlider(inp.id); - } - - // Create an id for the form element if necessary - if(!inp.id) { - inp.id = "fd-slider-form-elem-" + uniqueid++; - } - - // Basic option Object - options = { - inp: inp, - callbacks: [], - animation: html5Animation, - vertical: getAttribute(inp, "data-fd-slider-vertical") ? true : (inp.offsetHeight > inp.offsetWidth), - classNames: getAttribute(inp, "data-fd-slider-vertical"), - html5Shim: true - }; - - if(options.vertical && !getAttribute(inp, "data-fd-slider-vertical")) { - options.inpHeight = inp.offsetHeight; - } - - defs = getInputAttributes(inp); - - options.min = defs.min; - options.max = defs.max; - options.step = defs.step; - options.precision = String(options.step).search(/\.([0-9]+)$/) != -1 ? String(options.step).match(/\.([0-9]+)$/)[1].length : 0; - options.maxStep = options.step * 2; - - destroySingleSlider(options.inp.id); - sliders[options.inp.id] = new fdRange(options); - } - } - - return true; - }; - var getInputAttributes = function(inp) { - return { - "min":+(getAttribute(inp, "min") || 0), - "max":+(getAttribute(inp, "max") || 100), - "step":+(getAttribute(inp, "step").search(stepRegExp) != -1 ? inp.getAttribute("step") : 1) - }; - }; - var destroySingleSlider = function(id) { - if(id in sliders && sliders.hasOwnProperty(id)) { - sliders[id].destroy(); - delete sliders[id]; - return true; - } - return false; - }; - var destroyAllsliders = function(e) { - for(var slider in sliders) { - if(sliders.hasOwnProperty(slider)) { - sliders[slider].destroy(); - } - } - sliders = []; - }; - var unload = function(e) { - destroyAllsliders(); - sliders = null; - }; - var resize = function(e) { - for(var slider in sliders) { - if(sliders.hasOwnProperty(slider)) { - sliders[slider].onResize(); - } - } - }; - var rescanAttributes = function() { - for(var slider in sliders) { - if(sliders.hasOwnProperty(slider)) { - sliders[slider].rescan(); - } - } - }; - var onDomReady = function() { - removeOnLoadEvent(); - init(); - }; - var removeOnLoadEvent = function() { - removeEvent(window, "load", init); - }; - function fdRange(options) { - var inp = options.inp, - disabled = false, - tagName = inp.tagName.toLowerCase(), - min = +options.min, - max = +options.max, - rMin = +options.min, - rMax = +options.max, - range = Math.abs(max - min), - step = tagName == "select" ? 1 : +options.step, - maxStep = options.maxStep ? +options.maxStep : step * 2, - precision = options.precision || 0, - steps = Math.ceil(range / step), - scale = options.scale || false, - hideInput = !!options.hideInput, - animation = options.animation || "", - vertical = !!options.vertical, - callbacks = options.callbacks || {}, - classNames = options.classNames || "", - html5Shim = !!options.html5Shim, - defaultVal = max < min ? min : min + ((max - min) / 2), - resetDef = tagName == "select" ? inp.selectedIndex : inp.defaultValue || defaultVal, - forceValue = html5Shim || !!options.forceValue, - inpHeight = html5Shim && vertical && ("inpHeight" in options) ? options.inpHeight : false, - ariaFormat = !html5Shim && options.ariaFormat ? options.ariaFormat : false, - userSnap = !html5Shim && (tagName != "select") && ("userSnap" in options) ? !!options.userSnap : false, - userInput = false, - timer = null, - kbEnabled = true, - initialVal = tagName == "select" ? inp.selectedIndex : inp.value, - sliderH = 0, - sliderW = 0, - tweenX = 0, - tweenB = 0, - tweenC = 0, - tweenD = 0, - frame = 0, - x = 0, - y = 0, - rMaxPx = 0, - rMinPx = 0, - handlePos = 0, - destPos = 0, - mousePos = 0, - stepPx = 0, - userSet = false, - touchEvents = false, - outerWrapper, - innerWrapper, - ieBlur, - handle, - rangeBar, - bar; - - // For the reset event to work we have to set a defaultValue - if(tagName == "input" && forceValue && !inp.defaultValue) { - inp.defaultValue = getWorkingValueFromInput(); - } - - // Make sure we have a negative step if the max < min - if(max < min) { - step = -Math.abs(step); - maxStep = -Math.abs(maxStep); - } - - // Add the 100% scale mark if needs be. This is hacky. - if(scale) { - scale[100] = max; - } - - // Set the "userSet" variable programmatically for this slider - function valueSet(tf) { - tf = !!tf; - if(tf != userSet) { - userSet = tf; - valueToPixels(getWorkingValueFromInput()); - } - } - - function rescanAttrs() { - if(!useDOMAttrModEvt || tagName == "select") { - return; - } - - var defs = getInputAttributes(inp); - - if(defs.min == min && defs.max == max && defs.step == step) { - return; - } - - min = +defs.min; - max = +defs.max; - rMin = min; - rMax = max; - step = +defs.step; - range = Math.abs(max - min); - maxStep = step * 2; - steps = Math.ceil(range / step); - userSet = false; - setSliderRange(min, max); - } - - function disableSlider(noCallback) { - if(disabled && !noCallback) { - return; - } - - try { - setTabIndex(handle, -1); - removeEvent(handle, "focus", onFocus); - removeEvent(handle, "blur", onBlur); - - if(!isOpera) { - removeEvent(handle, "keydown", onKeyDown); - removeEvent(handle, "keypress", onKeyPress); - } else { - removeEvent(handle, "keypress", onKeyDown); - } - - removeEvent(outerWrapper, "mouseover", onMouseOver); - removeEvent(outerWrapper, "mouseout", onMouseOut); - removeEvent(outerWrapper, "mousedown", onMouseDown); - removeEvent(outerWrapper, "touchstart", onMouseDown); - - if(mouseWheelEnabled) { - if (window.addEventListener && !window.devicePixelRatio) window.removeEventListener('DOMMouseScroll', trackMouseWheel, false); - else { - removeEvent(document, "mousewheel", trackMouseWheel); - removeEvent(window, "mousewheel", trackMouseWheel); - } - } - } catch(err) {} - - removeClass(innerWrapper, "fd-slider-focused"); - removeClass(innerWrapper, "fd-slider-active"); - - addClass(innerWrapper, "fd-slider-disabled"); - outerWrapper.setAttribute("aria-disabled", true); - inp.disabled = disabled = true; - clearTimeout(timer); - - if(!noCallback) { - callback("disable"); - } - } - - function enableSlider(noCallback) { - if(!disabled && !noCallback) { - return; - } - - setTabIndex(handle, 0); - addEvent(handle, "focus", onFocus); - addEvent(handle, "blur", onBlur); - - if(!isOpera) { - addEvent(handle, "keydown", onKeyDown); - addEvent(handle, "keypress", onKeyPress); - } else { - addEvent(handle, "keypress", onKeyDown); - } - - addEvent(outerWrapper, "touchstart", onMouseDown); - addEvent(outerWrapper, "mousedown", onMouseDown); - addEvent(outerWrapper, "mouseover", onMouseOver); - addEvent(outerWrapper, "mouseout", onMouseOut); - - removeClass(innerWrapper, "fd-slider-disabled"); - outerWrapper.setAttribute("aria-disabled", false); - inp.disabled = disabled = touchEvents = false; - - if(!noCallback) { - callback("enable"); - } - } - - // Destroys a slider - function destroySlider() { - clearTimeout(timer); - ieBlur = bar = handle = outerWrapper = innerWrapper = timer = null; - callback("destroy"); - callbacks = null; - } - - // Calculates the pixel increment etc - function redraw() { - locate(); - // Internet Explorer requires the try catch as hidden - // elements throw errors - try { - var sW = outerWrapper.offsetWidth, - sH = outerWrapper.offsetHeight, - hW = handle.offsetWidth, - hH = handle.offsetHeight, - bH = bar.offsetHeight, - bW = bar.offsetWidth, - mPx = vertical ? sH - hH : sW - hW; - - stepPx = mPx / steps; - rMinPx = Math.max(scale ? percentToPixels(valueToPercent(rMin)) : Math.abs((rMin - min) / step) * stepPx, 0); - rMaxPx = Math.min(scale ? percentToPixels(valueToPercent(rMax)) : Math.abs((rMax - min) / step) * stepPx, Math.floor(vertical ? sH - hH : sW - hW)); - - sliderW = sW; - sliderH = sH; - - valueToPixels(forceValue ? getWorkingValueFromInput() : (tagName == "select" ? inp.selectedIndex : parseFloat(inp.value)), false); - - } catch(err) {} - callback("redraw"); - } - - // Calls a callback function - function callback(type) { - if(!html5Shim) { - if(callbacks.hasOwnProperty(type)) { - var cbObj = {"userSet":userSet, "disabled":disabled, "elem":inp, "value":tagName == "select" ? inp.options[inp.selectedIndex].value : inp.value}; - - // Call all functions in sequence - for(var i = 0, func; func = callbacks[type][i]; i++) { - func.call(inp, cbObj); - } - } - } else if(type.match(/^(blur|focus|change)$/i)) { - var e; - if(typeof(document.createEvent) != 'undefined') { - e = document.createEvent('HTMLEvents'); - e.initEvent(type, true, true); - inp.dispatchEvent(e); - } else if(typeof(document.createEventObject) != 'undefined') { - try { - e = document.createEventObject(); - inp.fireEvent('on' + type.toLowerCase(), e); - } catch(err){ } - } - } - } - - // FOCUS & BLUR events - function onFocus(e) { - addClass(innerWrapper, 'fd-slider-focused'); - - // Is the value said to have been set by the user onfocus - if(varSetRules.onfocus) { - userSet = true; - valueToPixels(getWorkingValueFromInput()); - } - - // If mousewheel events required then add them - if(mouseWheelEnabled) { - addEvent(window, 'DOMMouseScroll', trackMouseWheel); - addEvent(document, 'mousewheel', trackMouseWheel); - if(!isOpera) { - addEvent(window, 'mousewheel', trackMouseWheel); - } - } - - callback("focus"); - return true; - } - - function onBlur(e) { - removeClass(innerWrapper, 'fd-slider-focused'); - - // Remove mousewheel events if necessary - if(mouseWheelEnabled) { - removeEvent(document, 'mousewheel', trackMouseWheel); - removeEvent(window, 'DOMMouseScroll', trackMouseWheel); - if(!isOpera) { - removeEvent(window, 'mousewheel', trackMouseWheel); - } - } - - kbEnabled = true; - callback("blur"); - } - - // MOUSEWHEEL events - function trackMouseWheel(e) { - if(!kbEnabled) { - return; - } - - e = e || window.event; - var delta = 0, - value; - - if (e.wheelDelta) { - delta = e.wheelDelta/120; - // Older versions of Opera require a small hack to inverse the delta - if (isOpera && window.opera.version() < 9.2) { - delta = -delta; - } - } else if(e.detail) { - delta = -e.detail/3; - } - - if(vertical) { - delta = -delta; - } - - if(delta) { - value = getWorkingValueFromInput(); - value += (delta < 0) ? -step : step; - userSet = true; - valueToPixels(getValidValue(value)); - } - - preventDefault(e); - } - - // KEYBOARD events - function onKeyPress(e) { - e = e || window.event; - // Let all non-hijacked keyboard events pass - if((e.keyCode >= 33 && e.keyCode <= 40) || !kbEnabled || e.keyCode == 45 || e.keyCode == 46) { - return stopEvent(e); - } - return true; - } - - function onKeyDown(e) { - if(!kbEnabled) { - return true; - } - - e = e || window.event; - var kc = e.keyCode !== null ? e.keyCode : e.charCode, - value; - - if(kc < 33 || (kc > 40 && (kc != 45 && kc != 46))) { - return true; - } - - value = getWorkingValueFromInput(); - - if( kc == 37 || kc == 40 || kc == 46 || kc == 34) { - // left, down, ins, page down - value -= (e.ctrlKey || kc == 34 ? +maxStep : +step); - } else if( kc == 39 || kc == 38 || kc == 45 || kc == 33) { - // right, up, del, page up - value += (e.ctrlKey || kc == 33 ? +maxStep : +step); - } else if( kc == 35 ) { - // max - value = rMax; - } else if( kc == 36 ) { - // min - value = rMin; - } - - userSet = true; - valueToPixels(getValidValue(value)); - - callback("update"); - - // Opera doesn't let us cancel key events so the up/down arrows and home/end buttons will scroll the screen - which sucks - preventDefault(e); - } - - // MOUSE & TOUCH events - - function onMouseOver(e) { - addClass(innerWrapper, 'fd-slider-hover'); - } - - function onMouseOut(e) { - // Should really check we are not still in the slider - removeClass(innerWrapper, 'fd-slider-hover'); - } - - // Mousedown on the slider - function onMouseDown(e) { - e = e || window.event; - - // Stop page scrolling - preventDefault(e); - - // Grab the event target - var targ; - if (e.target) { - targ = e.target; - } else if (e.srcElement) { - targ = e.srcElement; - } - if(targ && targ.nodeType == 3) { - targ = targ.parentNode; - } - - // Are we using touchEvents - if(e.touches) { - // Skip gestures - if(e.targetTouches && e.targetTouches.length != 1) { - return false; - } - - e = e.touches[0]; - touchEvents = true; - } - - // Stop any animation timers - clearTimeout(timer); - timer = null; - - // Not keyboard enabled - kbEnabled = false; - - // User has set a value - userSet = true; - - // Handle mousedown - initiate drag - if(targ.className.search("fd-slider-handle") != -1) { - mousePos = vertical ? e.clientY : e.clientX; - handlePos = parseInt(vertical ? handle.offsetTop : handle.offsetLeft)||0; - - // Set a value on first click even if no movement - trackMouse(e); - - if(!touchEvents) { - addEvent(document, 'mousemove', trackMouse); - addEvent(document, 'mouseup', stopDrag); - } else { - addEvent(document, 'touchmove', trackMouse); - addEvent(document, 'touchend', stopDrag); - // Remove mouseEvents to stop them firing after the touch event - removeEvent(outerWrapper, "mousedown", onMouseDown); - } - - addClass(innerWrapper, 'fd-slider-active'); - addClass(document.body, "fd-slider-drag-" + (vertical ? "vertical" : "horizontal")); - - callback("dragstart"); - - // Wrapper mousedown - initiate animation to click point - } else { - locate(); - - var posx = 0; - - if(e.pageX || e.pageY) { - posx = vertical ? e.pageY : e.pageX; - } else if (e.clientX || e.clientY) { - posx = vertical ? e.clientY + document.body.scrollTop + document.documentElement.scrollTop : e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; - } - - posx -= vertical ? y + Math.round(handle.offsetHeight / 2) : x + Math.round(handle.offsetWidth / 2); - posx = snapToPxValue(posx); - - // Tween animation to click point - if(animation == "tween") { - addClass(innerWrapper, 'fd-slider-active'); - tweenTo(posx); - // Progressive increment to click point - } else if(animation == "timed") { - addClass(innerWrapper, 'fd-slider-active'); - addEvent(document, touchEvents ? 'touchend' : 'mouseup', onDocMouseUp); - destPos = posx; - onTimer(); - // Immediate jump to click point - } else { - pixelsToValue(posx); - //addEvent(document, touchEvents ? 'touchend' : 'mouseup', onMouseUp); - } - } - - return false; - } - - // Progressive increment to click point - clear the animation timer and remove the mouseup/touchend event - function onDocMouseUp( e ) { - e = e || window.event; - - preventDefault(e); - removeEvent(document, touchEvents ? 'touchend' : 'mouseup', onDocMouseUp); - removeClass(innerWrapper, "fd-slider-active"); - - clearTimeout(timer); - timer = null; - kbEnabled = true; - - return false; - } - - // Mouseup or touchend event on the document to stop drag - function stopDrag(e) { - e = e || window.event; - - preventDefault(e); - - if(touchEvents) { - removeEvent(document, 'touchmove', trackMouse); - removeEvent(document, 'touchend', stopDrag); - } else { - removeEvent(document, 'mousemove', trackMouse); - removeEvent(document, 'mouseup', stopDrag); - } - - kbEnabled = true; - removeClass(document.body, "fd-slider-drag-" + (vertical ? "vertical" : "horizontal")); - removeClass(innerWrapper, "fd-slider-active"); - - callback("dragend"); - - return false; - } - - // Mousemove or touchmove event on the drag handle - function trackMouse(e) { - e = e || window.event; - - preventDefault(e); - - if(e.touches) { - // Skip gestures - if(e.targetTouches && e.targetTouches.length != 1) { - return false; - } - e = e.touches[0]; - } - - pixelsToValue(snapToPxValue(handlePos + (vertical ? e.clientY - mousePos : e.clientX - mousePos))); - - return false; - } - - // Increments the slider by "inc" steps - function increment(inc) { - var value = getWorkingValueFromInput(); - userSet = true; - value += inc * step; - valueToPixels(getValidValue(value)); - } - - // Attempts to locate the on-screen position of the slider - function locate(){ - var curleft = 0, - curtop = 0, - obj = outerWrapper; - - // Try catch for IE's benefit - try { - do { - curleft += obj.offsetLeft; - curtop += obj.offsetTop; - } while(obj = obj.offsetParent); - } catch(err) {} - x = curleft; - y = curtop; - } - - // Used during the progressive animation to click point - function onTimer() { - var xtmp = parseInt(vertical ? handle.offsetTop : handle.offsetLeft, 10); - xtmp = Math.round((destPos < xtmp) ? Math.max(destPos, Math.floor(xtmp - stepPx)) : Math.min(destPos, Math.ceil(xtmp + stepPx))); - - pixelsToValue(snapToPxValue(xtmp)); - if(xtmp != destPos) { - timer = setTimeout(onTimer, steps > 20 ? 50 : 100); - } else { - kbEnabled = true; - removeClass(innerWrapper, "fd-slider-active"); - callback("finalise"); - } - } - - var tween = function(){ - frame++; - var c = tweenC, - d = 20, - t = frame, - b = tweenB, - x = Math.ceil((t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b); - - pixelsToValue(t == d ? tweenX : x); - - if(t!=d) { - // Call the "move" callback on each animation increment - callback("move"); - timer = setTimeout(tween, 20); - } else { - clearTimeout(timer); - timer = null; - kbEnabled = true; - - removeClass(innerWrapper, "fd-slider-focused"); - removeClass(innerWrapper, "fd-slider-active"); - - // Call the "finalise" callback whenever the animation is complete - callback("finalise"); - } - }; - - function tweenTo(tx){ - kbEnabled = false; - tweenX = parseInt(tx, 10); - tweenB = parseInt(vertical ? handle.offsetTop : handle.offsetLeft, 10); - tweenC = tweenX - tweenB; - tweenD = 20; - frame = 0; - - if(!timer) { - timer = setTimeout(tween, 20); - } - } - - // Returns a value within the range & sets the userSet var - // i.e. has the user entered a valid value - function checkValue(value) { - if(isNaN(value) || value === "" || typeof value == "undefined") { - userSet = false; - return defaultVal; - } else if(value < Math.min(rMin,rMax)) { - userSet = false; - return Math.min(rMin,rMax); - } else if(value > Math.max(rMin,rMax)) { - userSet = false; - return Math.max(rMin,rMax); - } - userSet = true; - return value; - } - - // Returns a value within a range - uses the form element value as base - function getWorkingValueFromInput() { - return getValidValue(tagName == "input" ? parseFloat(inp.value) : inp.selectedIndex); - } - - // Returns a value within the range - function getValidValue(value) { - return (isNaN(value) || value === "" || typeof value == "undefined") ? defaultVal : Math.min(Math.max(value, Math.min(rMin,rMax)), Math.max(rMin,rMax)); - } - - // Calculates value according to pixel position of slider handle - function pixelsToValue(px) { - var val = getValidValue(scale ? percentToValue(pixelsToPercent(px)) : vertical ? max - (Math.round(px / stepPx) * step) : min + (Math.round(px / stepPx) * step)); - - handle.style[vertical ? "top" : "left"] = (px || 0) + "px"; - redrawRange(); - setInputValue((tagName == "select" || step == 1) ? Math.round(val) : val); - } - - // Calculates pixel position according to form element value - function valueToPixels(val, updateInputValue) { - var clearVal = false, - value; - - // Allow empty values for non-polyfill sliders - if((typeof val === "undefined" || isNaN(val) || val === "") && tagName == "input" && !forceValue) { - value = defaultVal; - clearVal = true; - userSet = false; - } else { - value = checkValue(val); - } - - handle.style[vertical ? "top" : "left"] = (scale ? percentToPixels(valueToPercent(value)) : vertical ? Math.round(((max - value) / step) * stepPx) : Math.round(((value - min) / step) * stepPx)) + "px"; - redrawRange(); - if(typeof updateInputValue !== false) { - setInputValue(clearVal ? "" : value); - } - } - - // Rounds a pixel value to the nearest "snap" point on the slider scale - function snapToPxValue(px) { - if(scale) { - return Math.max(Math.min(rMaxPx, px), rMinPx); - } else { - var rem = px % stepPx; - if(rem && rem >= (stepPx / 2)) { - px += (stepPx - rem); - } else { - px -= rem; - } - - if(px < Math.min(Math.abs(rMinPx), Math.abs(rMaxPx))) { - px = Math.min(Math.abs(rMinPx), Math.abs(rMaxPx)); - } else if(px > Math.max(Math.abs(rMinPx), Math.abs(rMaxPx))) { - px = Math.max(Math.abs(rMinPx), Math.abs(rMaxPx)); - } - - return Math.min(Math.max(px, 0), rMaxPx); - } - } - - // Calculates a value according to percentage of distance handle has travelled - function percentToValue(pct) { - var st = 0, - fr = min, - value; - - for(var s in scale) { - if(!scale.hasOwnProperty(s)) { - continue; - } - - if(pct >= st && pct <= +s ) { - value = fr + ((pct - st) * (+scale[s] - fr) ) / (+s - st); - } - - st = +s; - fr = +scale[s]; - } - - return value; - } - - // Calculates the percentage handle position according to form element value - function valueToPercent(value) { - var st = 0, - fr = min, - pct = 0; - - for(var s in scale) { - if(!scale.hasOwnProperty(s)) { - continue; - } - - if(value >= fr && value <= +scale[s]){ - pct = st + (value - fr) * (+s - st) / (+scale[s] - fr); - } - - st = +s; - fr = +scale[s]; - } - - return pct; - } - - function percentToPixels(percent) { - return ((outerWrapper[vertical ? "offsetHeight" : "offsetWidth"] - handle[vertical ? "offsetHeight" : "offsetWidth"]) / 100) * percent; - } - - function pixelsToPercent(pixels) { - return pixels / ((outerWrapper[vertical ? "offsetHeight" : "offsetWidth"] - outerWrapper[handle ? "offsetHeight" : "offsetWidth"]) / 100); - } - - // Sets the form element with a valid value - function setInputValue(val) { - // The update callback doesn't mean the input value has changed - callback("update"); - - // If the user has not set this value or has entered an incorrect value then set a class - // to enable styling of the slider - if(!userSet) { - addClass(innerWrapper, "fd-slider-no-value"); - } else { - removeClass(innerWrapper, "fd-slider-no-value"); - } - - if(tagName == "select") { - try { - val = parseInt(val, 10); - if(inp.selectedIndex === val) { - updateAriaValues(); - return; - } - inp.options[val].selected = true; - } catch (err) {} - } else { - if(val !== "" && !userInput) { - val = (min + (Math.round((+val - min) / step) * step)).toFixed(precision); - } - if(inp.value === val) { - updateAriaValues(); - return; - } - inp.value = val; - } - - updateAriaValues(); - callback("change"); - } - - function checkInputValue(value) { - return !(isNaN(value) || value === "" || value < Math.min(rMin,rMax) || value > Math.max(rMin,rMax)); - } - - function setSliderRange(newMin, newMax) { - if(rMin > rMax) { - newMin = Math.min(min, Math.max(newMin, newMax)); - newMax = Math.max(max, Math.min(newMin, newMax)); - rMin = Math.max(newMin, newMax); - rMax = Math.min(newMin, newMax); - } else { - newMin = Math.max(min, Math.min(newMin, newMax)); - newMax = Math.min(max, Math.max(newMin, newMax)); - rMin = Math.min(newMin, newMax); - rMax = Math.max(newMin, newMax); - } - - if(defaultVal < Math.min(rMin, rMax)) { - defaultVal = Math.min(rMin, rMax); - } else if(defaultVal > Math.max(rMin, rMax)) { - defaultVal = Math.max(rMin, rMax); - } - - handle.setAttribute("aria-valuemin", rMin); - handle.setAttribute("aria-valuemax", rMax); - - checkValue(tagName == "input" ? parseFloat(inp.value) : inp.selectedIndex); - redraw(); - } - - function redrawRange() { - if(noRangeBar) { - return; - } - if(vertical) { - rangeBar.style["height"] = Math.max(1, (bar.offsetHeight - handle.offsetTop)) + "px"; - } else { - rangeBar.style["width"] = Math.max(1, handle.offsetLeft) + "px"; - } - } - - function findLabel() { - var label = false, - labelList = document.getElementsByTagName('label'); - // loop through label array attempting to match each 'for' attribute to the id of the current element - for(var i = 0, lbl; lbl = labelList[i]; i++) { - // Internet Explorer requires the htmlFor test - if((lbl['htmlFor'] && lbl['htmlFor'] == inp.id) || (lbl.getAttribute('for') == inp.id)) { - label = lbl; - break; - } - } - - if(label && !label.id) { - label.id = inp.id + "_label"; - } - - return label; - } - - function updateAriaValues() { - var val = tagName == "select" ? inp.options[inp.selectedIndex].value : inp.value, - valTxt = ariaFormat ? ariaFormat(val) : tagName == "select" ? (inp.options[inp.selectedIndex].text ? inp.options[inp.selectedIndex].text : val) : val; - - handle.setAttribute("aria-valuenow", val); - handle.setAttribute("aria-valuetext", valTxt); - } - - function onInputChange(e) { - userSet = true; - userInput = userSnap; - valueToPixels(tagName == "input" ? parseFloat(inp.value) : inp.selectedIndex); - updateAriaValues(); - userInput = false; - } - - function onReset(e) { - if(tagName == "input") { - inp.value = inp.defaultValue; - } else { - inp.selectedIndex = resetDef; - } - checkValue(tagName == "select" ? inp.options[inp.selectedIndex].value : inp.value); - redraw(); - updateAriaValues(); - } - - // Sets a tabindex attribute on an element, bends over for IE. - function setTabIndex(e, i) { - e.setAttribute(!/*@cc_on!@*/false ? "tabIndex" : "tabindex", i); - e.tabIndex = i; - } - - (function() { - if(html5Shim || hideInput) { - addClass(inp, "fd-form-element-hidden"); - try { - // FF21 hack to change input type to text - if(inp.type != "range" && - getAttribute(inp, "type") == "range" && - document.defaultView.getComputedStyle(inp, null).getPropertyValue("display") == "inline-block") { - inp.type="number"; - } - } catch(err){} - } else { - addEvent(inp, 'change', onInputChange); - } - - // Add stepUp & stepDown methods to input element if using the html5Shim - if(html5Shim) { - inp.setAttribute("fd-range-enabled", 1); - inp.stepUp = function(n) { increment(n||1); }; - inp.stepDown = function(n) { increment(n||-1); }; - - if(useDOMAttrModEvt) { - addEvent(inp, typeof(inp.onpropertychange) == "object" ? "propertychange" : "DOMAttrModified", rescanAttrs); - } - } - - outerWrapper = document.createElement('span'); - outerWrapper.className = "fd-slider" + (vertical ? "-vertical " : " ") + classNames; - outerWrapper.id = "fd-slider-" + inp.id; - - if(vertical && inpHeight) { - outerWrapper.style.height = inpHeight + "px"; - } - - innerWrapper = document.createElement('span'); - innerWrapper.className = "fd-slider-wrapper" + (!html5Shim ? " fd-slider-no-value" : ""); - - ieBlur = document.createElement('span'); - ieBlur.className = "fd-slider-inner"; - - bar = document.createElement('span'); - bar.className = "fd-slider-bar"; - - if(fullARIA) { - handle = document.createElement('span'); - } else { - handle = document.createElement('a'); - handle.setAttribute("href", "#"); - addEvent(handle, "click", stopEvent); - } - - setTabIndex(handle, 0); - - handle.className = "fd-slider-handle"; - handle.appendChild(document.createTextNode(String.fromCharCode(160))); - - innerWrapper.appendChild(ieBlur); - - if(!noRangeBar) { - rangeBar = document.createElement('span'); - rangeBar.className = "fd-slider-range"; - innerWrapper.appendChild(rangeBar); - } - - innerWrapper.appendChild(bar); - innerWrapper.appendChild(handle); - outerWrapper.appendChild(innerWrapper); - - inp.parentNode.insertBefore(outerWrapper, inp); - - if(isOpera || /*@cc_on!@*/!true) { - handle.unselectable = "on"; - bar.unselectable = "on"; - ieBlur.unselectable = "on"; - outerWrapper.unselectable = "on"; - innerWrapper.unselectable = "on"; - if(!noRangeBar) { - rangeBar.unselectable = "on"; - } - } - - // Add ARIA accessibility info programmatically - outerWrapper.setAttribute("role", "application"); - - handle.setAttribute("role", "slider"); - handle.setAttribute("aria-valuemin", tagName == "select" ? inp.options[0].value : min); - handle.setAttribute("aria-valuemax", tagName == "select" ? inp.options[inp.options.length - 1].value : max); - - var lbl = findLabel(); - if(lbl) { - handle.setAttribute("aria-labelledby", lbl.id); - handle.id = "fd-slider-handle-" + inp.id; - /*@cc_on@*/ - /*@if(@_win32) - lbl.setAttribute("htmlFor", handle.id); - @else @*/ - lbl.setAttribute("for", handle.id); - /*@end@*/ - } - - // Are there page instructions - if(document.getElementById(describedBy)) { - handle.setAttribute("aria-describedby", describedBy); - } - - // Is the form element initially disabled - if(inp.getAttribute("disabled") === true || inp.getAttribute("disabled") == "disabled") { - disableSlider(true); - } else { - enableSlider(true); - } - - // Does an initial form element value mean the user has set a valid value? - // Also called onload in case browsers have automatically set the input value - if(varSetRules.onvalue) { - userSet = true; - checkValue(tagName == "input" ? parseFloat(inp.value) : inp.selectedIndex); - } - - // Catch form reset events - if(inp.form) { - addEvent(inp.form, "reset", onReset); - } - - updateAriaValues(); - callback("create"); - redraw(); - })(); - - return { - onResize: function(e) { if(outerWrapper.offsetHeight != sliderH || outerWrapper.offsetWidth != sliderW) { redraw(); } }, - destroy: function() { destroySlider(); }, - reset: function() { valueToPixels(tagName == "input" ? parseFloat(inp.value) : inp.selectedIndex); }, - stepUp: function(n) { increment(Math.abs(n)||1); }, - stepDown: function(n) { increment(-Math.abs(n)||-1); }, - increment: function(n) { increment(n); }, - disable: function() { disableSlider(); }, - enable: function() { enableSlider(); }, - setRange: function(mi, mx) { setSliderRange(mi, mx); }, - getValueSet: function() { return !!userSet; }, - setValueSet: function(tf) { valueSet(tf); }, - rescan: function() { rescanAttrs(); }, - checkValue: function() { if(varSetRules.onvalue) { userSet = true; checkValue(tagName == "input" ? parseFloat(inp.value) : inp.selectedIndex); } updateAriaValues(); redraw(); } - }; - } - - addEvent(window, "load", init); - addEvent(window, "load", function() { setTimeout(function() { var slider; for(slider in sliders) { sliders[slider].checkValue(); } }, 0); }); - addEvent(window, "resize", resize); - addEvent(window, "unload", unload); - - // Have we been passed JSON within the including script tag - (function() { - var scriptFiles = document.getElementsByTagName('script'), - json = parseJSON(String(scriptFiles[scriptFiles.length - 1].innerHTML).replace(/[\n\r\s\t]+/g, " ").replace(/^\s+/, "").replace(/\s+$/, "")); - - if(typeof json === "object" && !("err" in json)) { - affectJSON(json); - } - })(); - - // Add oldie class if needed for IE < 9 - /*@cc_on@*/ - /*@if (@_jscript_version < 9) - addClass(document.documentElement, "oldie"); - /*@end@*/ - - return { - rescanDocument: init, - createSlider: function(opts) { return createSlider(opts); }, - onDomReady: function() { onDomReady(); }, - destroyAll: function() { destroyAllsliders(); }, - destroySlider: function(id) { return destroySingleSlider(id); }, - redrawAll: function() { resize(); }, - addEvent: addEvent, - removeEvent: removeEvent, - stopEvent: stopEvent, - increment: function(id, numSteps) { if(!sliderExists(id)) { return false; } sliders[id].increment(numSteps); }, - stepUp: function(id, n) { if(!sliderExists(id)) { return false; } sliders[id].stepUp(Math.abs(n)||1); }, - stepDown: function(id, n) { if(!sliderExists(id)) { return false; } sliders[id].stepDown(-Math.abs(n)||-1); }, - setRange: function(id, newMin, newMax) { if(!sliderExists(id)) { return false; } sliders[id].setRange(newMin, newMax); }, - updateSlider: function(id) { if(!sliderExists(id)) { return false; } sliders[id].onResize(); sliders[id].reset(); }, - disable: function(id) { if(!sliderExists(id)) { return false; } sliders[id].disable(); }, - enable: function(id) { if(!sliderExists(id)) { return false; } sliders[id].enable(); }, - getValueSet: function() { return getValueSet(); }, - setValueSet: function(a, tf) { if(!sliderExists(id)) { return false; } setValueSet(a, tf); }, - setGlobalVariables: function(json) { affectJSON(json); }, - removeOnload: function() { removeOnLoadEvent(); }, - rescanAttributes: rescanAttributes - }; -})(); diff --git a/static/app/scripts/graphs.js b/static/app/scripts/graphs.js deleted file mode 100644 index 7c05998..0000000 --- a/static/app/scripts/graphs.js +++ /dev/null @@ -1,186 +0,0 @@ -/* Extend jquery */ -(function ( $ ) { - $.fn.graph = function(action, options) { - // These are the defaults - var settings = $.extend({ - width: undefined, - height: undefined, - animation_duration: 1000 // ms - }, options ); - /* The slug of each Graph object map to a function in the graphs object */ - var graphs = { - treatment: function(element) { - $(element).highcharts({ - chart: { - type: 'column', - width: settings.width, - height: settings.height, - animation: { - duration: settings.animation_duration - } - }, - title: { - text: 'Antall behandlinger' - }, - xAxis: { - title: { - text: 'År' - }, - minRange : 30 * 24 * 3600 * 1000, // - minTickInterval: 12 * 30 * 24 * 3600 * 1000, // A year - type: 'datetime' - }, - yAxis: { - title: { - text: 'Antall behandlinger' - } - - }, - series: [{ - name: 'Antall behandlinger', - data: [ - [Date.UTC(2007, 1), 35000], - [Date.UTC(2008, 1), 40000], - [Date.UTC(2009, 1), 60000], - [Date.UTC(2010, 1), 67000], - [Date.UTC(2011, 1), 70000], - [Date.UTC(2012, 1), 78000], - [Date.UTC(2013, 1), 97000], - [Date.UTC(2014, 1), 109000]], - enabled: false - - }], - legend: { - enabled: false - } - }); - }, - treatment_distribution: function(element) { - var last_year = new Date().getFullYear() - 1; - $(element).highcharts({ - chart: { - type: 'column', - width: settings.width, - height: settings.height, - animation: { - duration: settings.animation_duration - } - }, - title: { - text: 'Fordeling behandlinger' - }, - xAxis: { - title: { - text: 'Måned' - }, - minRange : 30 * 24 * 3600 * 1000, // - minTickInterval: 12 * 30 * 24 * 3600 * 1000, // A year - type: 'datetime' - }, - yAxis: { - title: { - text: 'Fordeling' - } - - }, - series: [{ - name: 'Preeksisterende', - data: [ - [Date.UTC(last_year, 0), 2], - [Date.UTC(last_year, 1), 5], - [Date.UTC(last_year, 2), 10], - [Date.UTC(last_year, 3), 20], - [Date.UTC(last_year, 4), 40], - [Date.UTC(last_year, 5), 70], - [Date.UTC(last_year, 6), 40], - [Date.UTC(last_year, 7), 40], - [Date.UTC(last_year, 8), 40]] - }, - { - name: 'Nye lidelser', - data: [ - [Date.UTC(last_year, 0), 8], - [Date.UTC(last_year, 1), 10], - [Date.UTC(last_year, 2), 15], - [Date.UTC(last_year, 3), 18], - [Date.UTC(last_year, 4), 20], - [Date.UTC(last_year, 5), 30], - [Date.UTC(last_year, 6), 40], - [Date.UTC(last_year, 7), 40], - [Date.UTC(last_year, 8), 40]] - }], - plotOptions: { - column: { - stacking: 'normal' - } - } - }); - }, - num_insured: function(element) { - $(element).highcharts({ - chart: { - type: 'column', - width: settings.width, - height: settings.height, - animation: { - duration: settings.animation_duration - } - }, - title: { - text: 'Antall forsikrede (behandlingsforsikring) per 30. juni 2003-2014' - }, - xAxis: { - title: { - text: 'År' - }, - tickInterval: Date.UTC(1902, 0, 1) - Date.UTC(1901, 0, 1), // A year - year: '%Y', - type: 'datetime' - }, - yAxis: { - title: { - text: 'Antall forsikrede' - } - - }, - series: [{ - name: 'Antall forsikrede', - data: [ - [Date.UTC(2003, 0), 14587], - [Date.UTC(2004, 0), 20634], - [Date.UTC(2005, 0), 35418], - [Date.UTC(2006, 0), 42073], - [Date.UTC(2007, 0), 74435], - [Date.UTC(2008, 0), 97661], - [Date.UTC(2009, 0), 115651], - [Date.UTC(2010, 0), 141742], - [Date.UTC(2011, 0), 233739], - [Date.UTC(2012, 0), 357468], - [Date.UTC(2013, 0), 404320], - [Date.UTC(2014, 0), 437137]], - enabled: false - - }], - legend: { - enabled: false - } - }); - } - }; - - /* What do do? */ - if(action == 'load') { - /* For each element get attr and load appropriate graph */ - return this.each(function() { - var slug = $(this).attr('data-graph-slug'); - // Create a graphs[slug] of this. - graphs[slug](this); - }); - } else if(action == 'get') { - /* Not used - return Highcharts.charts[loaded_graphs[slug].data('highchartsChart')]; - */ - } - }; - -}( jQuery )); diff --git a/static/app/scripts/presentation_edit.js b/static/app/scripts/presentation_edit.js deleted file mode 100644 index 4ce5f7a..0000000 --- a/static/app/scripts/presentation_edit.js +++ /dev/null @@ -1,121 +0,0 @@ -function get_offset(col, grid_height, min_widget_height) { - var num_slides = $('.slide[data-col="'+ col +'"]').length; - return (grid_height - (num_slides * min_widget_height)) * -1; -} - -/* Push add buttons up x px, close to the lowest slide in its section */ -function reposition_add_buttons(min_widget_height) { - var max_rows = _.max($(".slide"), function(slide){ return parseInt($(slide).attr('data-row')); }); - var grid_height = $(max_rows).attr('data-row') * min_widget_height; - - $(".slide-add").each(function() { - var offset = get_offset($(this).attr('data-col'), grid_height, min_widget_height); - $(this).css({ top: offset }); - }); -} -$(function(){ - // TODO: on document ready, to load: loading icon - var margin_x = 8; - var margin_y = 4; - var csrf_token = $.cookie('csrftoken'); - var grid = $(".gridster ul").gridster({ - widget_selector: "li.slide", - widget_margins: [margin_x, margin_y], - widget_base_dimensions: [113, 80], - min_cols: 6, - serialize_params: function($w, wgd) { - return { - slide: $w.attr('data-slide'), - section: $('.sections li[data-col="'+ wgd.col +'"]').attr('data-section'), - order: wgd.row - }; - }, - draggable: { - // https://github.com/ducksboard/gridster.js/issues/161 - handle: 'img', // FIXME: Edit link is not working on touch - stop: function() { - /* reposition add buttons */ - reposition_add_buttons(this.min_widget_height); - - /* Save grid order */ - var grid = this.serialize_changed(); - - var slides = []; - for(var i in grid ) { - slides.push({ name: "slide-order-"+grid[i].slide, value: grid[i].order }); - slides.push({ name: "slide-section-"+grid[i].slide, value: grid[i].section }); - } - /* Prepare data */ - var data = $("#presentation-form").serializeArray(); - data = data.concat(slides); - /* http post json */ - var url = $("#presentation").attr('data-save-url'); - $.ajax({ - type: "POST", - url: url, - data: data, - async: false, // FIXME: Make async - headers: { - 'X-CSRFToken': csrf_token - }, - success: function (result,l,o) { - if(result !== undefined && result.success) { - /* redirect to edit url */ - window.location = "/slideshow/" + result.presentation_id + "/edit/"; - } else { - //console.log("Saved"); //FIXME notify - } - }, - error: function (request, text_status, error_thrown) { - console.log("uffda..."); //FIXME notify - } - }); - } - } - }); - /* Note: gridster api add, remove, serialize */ - var gridster = grid.data('gridster'); - - /* reposition add buttons */ - reposition_add_buttons(gridster.min_widget_height); - - /* Datepicker */ - $("#id_datetime").datepicker({ - dateFormat: "yy-mm-dd" - }); - /* Disable slide controls */ - $(".slide-toggle").on('click', function(e) { - /* Set slide.active=false */ - var that = $(this); - var current_slide = $(this).parent().parent(); - var new_state = current_slide.hasClass("disabled"); - var url = $(this).attr('data-save-url'); - $.ajax({ - type: "PATCH", - url: url, - data: { - active: new_state - }, - headers: { - 'X-CSRFToken': csrf_token - }, - success: function (result,l,o) { - - /* toggle 'disabled' class */ - current_slide.toggleClass("disabled"); - /* switch icons class */ - var icon = that.find("i"); - if(icon.hasClass("fa-square-o")) { - icon.removeClass("fa-square-o").addClass("fa-check-square-o"); - } else { - icon.removeClass("fa-check-square-o").addClass("fa-square-o"); - } - }, - error: function (request, text_status, error_thrown) { - console.log("uffda..."); //FIXME notify - } - }); - - }); - -}); \ No newline at end of file diff --git a/static/app/scripts/presentation_list.js b/static/app/scripts/presentation_list.js deleted file mode 100644 index 5edc624..0000000 --- a/static/app/scripts/presentation_list.js +++ /dev/null @@ -1,9 +0,0 @@ - -$(function(){ - //var options = { -    // valueNames: [ 'region', 'hospital', 'city', 'diagnose', 'waittime' ] -    //}; - -    //var featureList = new List('presentation-table-sortable', options); - //featureList.sort('waittime', { asc: false }); -}); diff --git a/static/app/scripts/product_calculator.js b/static/app/scripts/product_calculator.js deleted file mode 100644 index 1036188..0000000 --- a/static/app/scripts/product_calculator.js +++ /dev/null @@ -1,541 +0,0 @@ -$(document).ready( function() { - /* Slide: Product calculator */ - /* - * TODO: set discount based on url or user/session data - * - * */ - function set_progress(percent) { - if( percent < 1 || percent > 100 ) { - return; - } - $(".stb-progress .meter").css('width', percent+"%"); - } - function product_select(products, treatments, counceling) { - /* Searches products and returns the correct price */ - //console.log(products, treatments, counceling); - var selected = products; - if(counceling !== undefined) { - selected = _.filter(selected, function(product) { - return product.counceling_service == counceling; - }); - } - if(selected.length == 1) { - return selected[0]; - } - if(treatments !== undefined) { - selected = _.filter(selected, function(product) { - return product.treatments == treatments; - }); - } - if(selected.length == 1) { - return selected[0]; - } - //console.log("Fant ingen produkter, returnerer siste"); - return products[products.length-1]; - } - //function filter_product_risk(documents, product_order) { - // /* filter based on product risk variables */ - // var product_risk_variable_attrs = [ - // 'eligible_industry_discount', - // 'has_existing_insurance', - // 'employees', - // 'addon_psychiatric_treatment']; - - // /* which variables are set? */ - // var product_risk_variables = _.filter(product_risk_variable_attrs, function(attr) { - // return product_order[attr] !== undefined; - // }); - // //console.log("product risk variables: ", product_risk_variables); - - // /* filter based on vars in product_risk_variables and product_order - // * all must match */ - // documents = _.filter(documents, function(doc){ - // //console.log("looking at: ", doc.name, "(", doc.id, ")"); - // // filter when not specified - // if(!doc.product_risk_variables.length) { - // return false; - // } - - // /* Loop over the product_risks attached to this document */ - // var doc_matches = _.map(doc.product_risk_variables, function(variables, index, list) { - // /* Loop over each variable in the list of risks */ - // var var_matches = _.map(product_risk_variables, function(element) { - // //console.log("looping document risk vars: ", element, product_order[element], variables[element], variables); - // // num employees special case - // if(element == 'employees' && (product_order[element] > variables['employees_max'] || product_order[element] < variables['employees_min'])) { - // return false - // } - // else if(product_order[element] != variables[element] && element != 'employees') { - // return false; // drop document - // } - // return true; - // }); - // // All attributes in the product_order must match with variables - // return _.every(var_matches); - // }); - // // Need just one match to keep the document - // return _.some(doc_matches); - // }); - // return documents; - //} - //function filter_individual_risk(documents, product_order) { - // //console.log("individual risk variables: ", product_order.individual_term_employees); - // /* Filter based on age ranges */ - // var ages = _.map(product_order.individual_term_employees, function(employee) { - // return employee.age; - // }); - // /* Filter documents not referencing at least one individual risk variable matching the specified ages */ - // documents = _.filter(documents, function(doc) { - // // filter when not specified - // // Note: Unsure if this is correct - // if(!doc.employee_risk_variables.length) { - // return false; - // } - // var matches = _.map(doc.employee_risk_variables, function(variables, index, list) { - // var age_matches = _.map(ages, function(age) { - // return age >= variables.age_min && age <= variables.age_max; - // }); - // return _.some(age_matches); // matching at least one age - // }); - // return _.some(matches); //matching at least one risk variable - // }); - // return documents; - //} - //function filter_documents(documents, product_order) { - // /* Filter based on product selection - // * Note: only filters by product if below 100 employees */ - // if(product_order.employees < 100) { - // var documents = _.filter(documents, function(doc){ - // var product_ids = _.map(doc.products, function(product) { return product.id; }); - // return _.contains(product_ids, product_order.product.id); - // }); - - // if(product_order.employees >=1 && product_order.employees <= 4 && !product_order.eligible_industry_discount) { - // documents = filter_individual_risk(documents, product_order); - // } - // else { - // documents = filter_product_risk(documents, product_order); - // } - // } else { - // /* Filter based on dummy no-product */ - // documents = _.filter(documents, function(doc){ - // var product_slugs = _.map(doc.products, function(product) { return product.slug; }); - // return _.contains(product_slugs, 'no-product'); - // }); - // - // } - // return documents; - // - //} - //function update_document_list(documents) { - // if(documents.length == 0) { - // $(".product-calculator .documents-table").html("Fillern, det er ingen dokumenter knyttet til dette produktet og valgte variable :'("); - // return; - // } - // var html = ""; - // _.each(documents, function(doc) { - // html += ''; - // }); - // html += "
NavnType
'+ doc.name +''+ doc.category +'
"; - // $(".product-calculator .documents-table").html(html); - //} - function get_price_individual(product, product_order) { - /* Need a valid product */ - if(product === undefined || product.employee_risk_variables.length === 0) { - return -1; - } - /* Invidual risk */ - var has_existing_insurance = false; - if( product_order.has_existing_insurance !== undefined) { - has_existing_insurance = product_order.has_existing_insurance; - } - /* Get list of prices for each employee */ - var prices = _.map(product_order.individual_term_employees, function(employee) { - /* Filter by employee-age */ - var variation = _.find(product.employee_risk_variables, function(variation) { - if(employee.age >= variation.age_min && employee.age <= variation.age_max) { - return true; - } - return false; - }); - return variation.price; - }); - return prices; - } - - function get_price(product, product_order) { - /* Group risk */ - var price = 0; - var has_existing_insurance = false; - if( product_order.has_existing_insurance !== undefined) { - has_existing_insurance = product_order.has_existing_insurance; - } - - /* Filter by boolean values */ - var variations = _.where(product.product_risk_variables, { - eligible_industry_discount: product_order.eligible_industry_discount, - has_existing_insurance: has_existing_insurance, - }); - /* Filter by num employees */ - variation = _.filter(variations, function(variation) { - if(variation.employees_max == product_order.employees ) { - return true; - } - }); - if(variation.length >= 1) { - price = parseInt(variation[0].price); - } else { - /* Error: Missing product data in db */ - price = -1; - } - /* include price for psychiatric treatment addon */ - // FIXME price is static. - if(product_order.addon_psychiatric_treatment !== undefined && product_order.addon_psychiatric_treatment) { - price += 204; - } - - return price; - } - function product_recalc(products, product_order) { - var product = product_select( - products, - product_order.treatments, - product_order.counceling); - - /* calculate price based in product and current risk data */ - var price_formatted; - - if(product_order.employees <= 4 && ! product_order.eligible_industry_discount) { - var prices = get_price_individual(product, product_order); - var sum = _.reduce(prices, function(memo, num) { return memo + parseInt(num); }, 0); - if(sum === 0) { - price_formatted = "Prøv andre valg, ingen pris funnet."; - } else { - if(prices.length == 1) { - price_formatted = "NOK " + sum + ",- per måned"; - } else { - price_formatted = prices.join(" + ")+" = NOK " + sum + ",- per måned"; - } - } - } else { - price = get_price(product, product_order); - if(price == -1) { - price_formatted = "Prøv andre valg, ingen pris funnet."; - } else { - price_formatted = "NOK " + price + ",- per år"; - } - } - product_order.product = product; - $("[data-prodcalc-product]").text(product.name); - $("[data-prodcalc-product-price]").text(price_formatted); - } - //function update_relevant_documents(product_order) { - - // var url = $(".product-calculator[data-documents-url]").attr('data-documents-url'); - // $.ajax({ - // url: url, - // method: 'GET', - // dataType: 'json', - // headers: { - // 'X-CSRFToken': $("[name=csrfmiddlewaretoken]").val() - // }, - // success: function(documents) { - // /* Present only the right documents, ordered by category */ - // //console.log("fetched the following documents:", documents); - // //console.log("filtering based on product_order", product_order); - - // var less_documents = filter_documents(documents, product_order); - // //console.log("returned these documents:", less_documents); - // update_document_list(less_documents); - // } - // }); - //} - - if($(".product-calculator").length) { - /* product_order stores the state of the order */ - var product_order = {}; - var product_order_steps = {}; - var num_product_order_steps = 6; - - /* Is the industry discount disabled? */ - if ( $('.product-calculator[data-disable-industry-discount]').length ) { - product_order.eligible_industry_discount = false; - $("[data-key=treatments][data-value=5]").show(); - } - - /* General layout of steps when user interacts with page: - * - update product_order state - * - update progress based on state - * - update the dom with the correct display state (button state, step description) - * - find product based on selection - * - calculate price based on discounts, selection and product - */ - - $.getJSON('/products.json', function(products) { - /* Attach to buttons and fields */ - - /* On every answer change */ - $("[data-answer]").on('click', function(e) { - var key = $(this).attr('data-key'); - var value = $(this).attr('data-value'); - - /* to_javascript */ - if (value == "no") { - value = false; - } - else if(value == "yes") { - value = true; - } - if(key == "treatments" || key == "employees") { - value = parseInt(value); - } - - /* limit options and change display */ - /* based on employees */ - if(key == "employees") { - if( value >= 20) { - if(product_order.has_exisiting_insurance === undefined) { - $(".modal-has-existing-insurance").foundation('reveal', 'open'); - } - } else { - /* Reset answer */ - delete product_order.has_exisiting_insurance; - $(".modal-has-existing-insurance button").removeClass("selected disabled"); - } - - var min_value = $(this).attr('data-min'); - /* if between 1 and 4 then.. */ - if( value <= 4 && min_value >= 1 && !product_order.eligible_industry_discount) { - /* display individual employee risk container */ - $(".individual-pricing-container").fadeIn('fast'); - /* Note: Fetching employee ages before anyone have been selected */ - update_employee_ages(); - } else { - $(".individual-pricing-container").fadeOut('fast'); - $("[data-key=treatments][data-value=12]").show(); - } - /* Next button */ - $("[data-goto-part=part-two]").fadeIn('fast'); - } - /* based on industry deal */ - if(key == "eligible_industry_discount") { - if(value) { - /* limit num treatments*/ - $("[data-key=treatments][data-value=5]").hide(); - } else { - $("[data-key=treatments][data-value=5]").show(); - } - if( !value && product_order.employees <= 4 && product_order.employees >= 1) { - $(".individual-pricing-container").fadeIn('fast'); - } else { - $(".individual-pricing-container").fadeOut('fast'); - } - - $(".prod-num-staff").fadeIn('fast'); - $(".part-one-zero").fadeOut('fast'); - setTimeout(function() { - $(".part-one-one").fadeIn('fast'); - }, 400); - } - /* based on counceling */ - if(key == "counceling") { - $(".prod-num-treatments").fadeIn('fast'); - $(".about-num-treatments").fadeIn('fast'); - if(value) { - /* limit num treatments and auto-select 24 */ - $("[data-key=treatments][data-value=5], [data-key=treatments][data-value=0]").hide(); - product_order.treatments = 24; - product_order_steps.treatments = 24; - $("[data-key=treatments]").removeClass("selected disabled"); - $("[data-key=treatments][data-value=24]").addClass("selected"); - /* update coverage */ - $(".coverage-treatments").text(product_order.treatments); - $(".selected-coverage .topp, .selected-coverage .treatments").fadeIn('fast'); - } else { - /* show all treatments, except 0 if industry deal */ - if( !product_order.eligible_industry_discount ) { - $("[data-key=treatments][data-value=5]").show(); - } - // FIXME: missing pricing data, just hide this option for now - if(product_order.employees <= 4) { - $("[data-key=treatments][data-value=0]").hide(); - } else { - $("[data-key=treatments][data-value=0]").show(); - } - $(".selected-coverage .topp").fadeOut('fast'); - } - } - /* based on addon_psychiatric_treatment */ - if(key == "addon_psychiatric_treatment") { - $(".prod-num-treatments").fadeIn('fast'); - $(".about-num-treatments").fadeIn('fast'); - $(".selected-coverage .counceling").fadeOut('fast'); - if(value) { - /* limit num treatments and auto-select 24 */ - $("[data-key=treatments][data-value=0]").hide(); - product_order.treatments = 24; - product_order_steps.treatments = 24; - $("[data-key=treatments]").removeClass("selected disabled"); - $("[data-key=treatments][data-value=24]").addClass("selected"); - /* update coverage */ - $(".coverage-treatments").text(product_order.treatments); - $("[data-prodcalc-addon]").text("med psykologi"); - $(".selected-coverage .treatments").fadeIn('fast'); - $(".selected-coverage .topp, .selected-coverage .psychology").fadeIn('fast'); - } else { - $(".selected-coverage .topp").fadeOut('fast'); - $("[data-prodcalc-addon]").text(""); - $("[data-key=treatments][data-value=0]").show(); - } - } - /* based on num treatments */ - if(key == "treatments") { - /* update coverage */ - if(value > 0) { - $(".selected-coverage .treatments").fadeIn('fast'); - $(".coverage-treatments").text(value); - } else if(value === 0) { - $(".selected-coverage .topp").fadeOut('fast'); - $(".selected-coverage .treatments").fadeOut('fast'); - $(".coverage-treatments").text(value); - } else { - $(".selected-coverage .treatments:visible").fadeOut('fast'); - } - } - - /* Update current answers. - * ie. industry discount, number of treatments, counceling and addon_psychiatric_treatment - */ - product_order[key] = value; - product_order_steps[key] = value; - - $(this).addClass("selected").removeClass("disabled"); - $("[data-key="+ key +"]").not(this).removeClass("selected").addClass("disabled"); - product_recalc(products, product_order); - /* total questions by number by answered questions */ - var current_progress = _.size(product_order_steps) / parseFloat(num_product_order_steps) * 100; - set_progress(current_progress); - }); - - /* Go on to the section after this one */ - $("[data-goto-part]").on('click', function(e) { - product_recalc(products, product_order); - var part = $(this).attr('data-goto-part'); - - - /* Product tailoring */ - if(part == 'part-two' && product_order.employees < 100) { - //console.log(product_order); - $(".part-zero, .part-one-right-container").fadeOut('fast'); - setTimeout(function() { - if(product_order.eligible_industry_discount) { - /* Don't ask for counceling, and set it to false */ - product_order.counceling = false; - $(".addon_psychiatric_treatment").fadeIn('fast'); - $(".about-addon-psychiatric-treatment").fadeIn('fast'); - $(".about-counceling").hide(); - } else { - $(".part-two .counceling").fadeIn('fast'); - // FIXME remove this if business rules are valid - //if(product_order.employees >= 20 && product_order.employees <= 99) { - // $(".about-num-treatments").fadeIn('fast'); - // $(".prod-num-treatments").fadeIn('fast'); - //} else { - // $(".part-two .counceling").fadeIn('fast'); - //} - } - $(".part-two-and-a-half-container").fadeIn('fast'); - $(".part-two").fadeIn('fast'); - if(product_order.has_exisiting_insurance) { - $(".part-two-right .need-stats").show(); - } else { - $(".part-two-right .need-stats").hide(); - } - }, 500); - } - /* Skip product tailoring */ - if( part == 'part-two' && product_order.employees >= 100) { - set_progress(100); - /* Get relevant product documents */ - //update_relevant_documents(product_order); - /* Show documents tab */ - $(".part-zero, .part-one-right-container").fadeOut('fast'); - setTimeout(function() { - if(product_order.has_exisiting_insurance) { - $(".part-three-special .need-stats").show(); - } else { - $(".part-three-special .need-stats").hide(); - } - $(".part-three-special").fadeIn('fast'); - }, 500); - } - - - /* "We recommend the product..." */ - if(part == 'part-two-and-a-half') { - $(".part-two-right").fadeOut('fast'); - $(".select-product-btn").fadeIn('fast'); - setTimeout(function() { - $(".part-two-and-a-half").fadeIn('fast'); - }, 500); - } - - - - /* Document "checkout" - fancy schmancy */ - if( part == 'part-three') { - set_progress(100); - /* Get relevant product documents */ - //update_relevant_documents(product_order); - - /* Show documents tab */ - $(".part-two, .part-one").fadeOut('fast'); - setTimeout(function() { - $(".part-two-and-a-half").parent().removeClass("small-7").addClass("small-12"); - $(".eula-container").removeClass("small-7").addClass("small-4"); - $(".product-description-inner").removeClass("small-5").addClass("small-3"); - $(".part-three").fadeIn('fast'); - }, 300); - $('[data-goto-part="part-three"]').fadeOut('fast'); - } - }); - - /* Update the product_order with individual employee ages */ - function update_employee_ages() { - var employees = []; - var i = 1; - $(".individual-pricing-container select.age-select-dropdown:visible").each(function(j, el) { - age = parseInt($(el).val().split(" -")[0]); - employees.push({ id: i, age: age }); - i++; - }); - product_order.individual_term_employees = employees; - } - $(".individual-pricing-container select.age-select-dropdown").on('change', update_employee_ages); - - /* add html for individual employee risk */ - $(".individual-pricing-container").on('click', "[data-add-new-employee]", function(e) { - e.preventDefault(); - /* No more than set amount */ - if( $(".person:visible").length == 4) { - return; - } - $(this).parent().next().fadeIn({ complete: update_employee_ages }); - }); - /* remove html for individual employee risk */ - $(".individual-pricing-container").on('click', "[data-remove-employee]", function(e) { - e.preventDefault(); - /* At least 1 */ - if( $(".person:visible").length == 1) { - return; - } - $(this).parent().fadeOut({ complete: update_employee_ages }); - }); - - /* Close modal on answer */ - $('[data-key="has_exisiting_insurance"]').on('click', function() { - $("#modal-has-existing-insurance").foundation('reveal', 'close'); - }); - }); - } -}); diff --git a/static/app/scripts/slide_edit.js b/static/app/scripts/slide_edit.js deleted file mode 100644 index de812fd..0000000 --- a/static/app/scripts/slide_edit.js +++ /dev/null @@ -1,276 +0,0 @@ -$(function() { - /* Save part urls - * Ref: urls.py */ - var urls = { - slide_part_save: '/api/slide/part/', - slide_title_save: '/api/slide/{slide_id}/title/', - slide_part_update: '/api/slide/part/{part_id}/', - slide_part_remove: '/api/slide/part/{part_id}/', - image_save: '/api/image/' - }; - var slide_id = $("#slide").attr('data-slide-id'); - var csrf_token = $.cookie('csrftoken'); - - /* Editor fields */ - var elements = document.querySelectorAll('[data-type="text"], [data-type="html"], [data-type="wysihtml5"]'); - var mediumOptions = { - buttons: ['bold', 'italic', 'header1', 'header2', 'quote', 'anchor', 'unorderedlist', 'orderedlist', 'removeFormat'] - }; - var editor = new MediumEditor(elements, mediumOptions); - editor.subscribe('blur', function(event, el) { - var type = $(el).attr('data-type'); - var name = $(el).attr('data-name'); - var url = $(el).attr('data-url'); - var pk = $(el).attr('data-pk'); - var method = 'POST'; - - if (pk.length > 0 && name != 'slide-title') { - url = urls.slide_part_update.replace('{part_id}', pk); - method = 'PUT'; - } - - var value = el.innerHTML; - if(type == 'text') { - value = el.textContent; - } - var data = { - slide_id: slide_id, - pk: pk, - name: name, - value: value - }; - $.ajax({ - method: method, - headers: { - 'X-CSRFToken': csrf_token - }, - type: 'POST', - url: url, - data: JSON.stringify(data), - contentType : 'application/json' - }).done(function() { - // TODO set pk on part - // $('[data-name="part-' + response.part_created_name + '"]').attr('data-pk', response.part_created_pk); - }).fail(function() { - console.log("boo"); - }); - - }); - $('[data-type="dynamic"]').on('changed', function(e) { - /* Delete part */ - if($(this).attr('data-part-remove')) { - var that = this; - $.ajax({ - url: urls.slide_part_remove.replace('{part_id}', $(this).attr('data-pk')), - method: 'DELETE', - headers: { - 'X-CSRFToken': csrf_token - }, - success: function(response, newValue) { - $(that).removeAttr('data-part-remove'); - $(that).attr('data-pk', ''); - } - }); - return; - } - /* Create or update part */ - var value = ''; - var type = ''; - - if($(this).find('img').length) { - value = $($(this).find('img')[0]).attr('data-pk'); - type = 'image'; - } - else if($(this).find('[data-graph-pk]').length) { - value = $($(this).find('[data-graph-pk]')[0]).attr('data-graph-pk'); - type = 'graph'; - } - else { - console.log("Could not determine Part-type."); - return; - } - - var slide_pk = $(this).attr('data-pk'); - var url = urls.slide_part_save; - var method = 'POST'; - - if (slide_pk.length > 0) { - url = urls.slide_part_update.replace('{part_id}', slide_pk); - method = 'PUT'; - } - - $.ajax({ - url: url, - method: method, - dataType: 'json', - data: { - name: $(this).attr('data-name'), - value: value, - type: type, - slide_id: $("#slide").attr('data-slide-id'), - href: $(this).find('a').attr('href') - }, - headers: { - 'X-CSRFToken': csrf_token - }, - success: function(response, newValue) { - if(response !== undefined && response.part_name && response.part_pk) { - $('[data-name="part-' + response.part_name + '"]').attr('data-pk', response.part_pk); - } - } - }); - }); - - /* - * Gallery - */ - // Ref: https://github.com/blueimp/jQuery-File-Upload - // https://github.com/blueimp/jQuery-File-Upload/wiki/Options - $('#id_file').fileupload({ - dataType: 'json', - url: urls.image_save, - done: function(e, data) { - // add image in gallery - $(".gallery ul").prepend('
  • '+ data.result.name +'
  • '); - // click event - $(".gallery ul li:first-child").click(function (e) { - $(this).siblings().removeClass("selected"); - $(this).toggleClass("selected"); - }); - $("#progress .bar").fadeOut('slow'); - }, - fail: function(e, data) { - console.log("Failed uploading file: ",e, data); - }, - headers: { - 'X-CSRFToken': csrf_token, - 'cache-control': 'no-cache' - }, - send: function(e, data) { - $('#progress .bar').css('width', '0%'); - $("#progress .bar").show(); - }, - progressall: function (e, data) { - var progress = parseInt(data.loaded / data.total * 100, 10); - $('#progress .bar').css( - 'width', - progress + '%' - ); - } - }); - /* Green select */ - $(".image-select").not(".placeholder").click(function (e) { - $(this).siblings().removeClass("selected"); - $(this).toggleClass("selected"); - - }); - /* Insert image */ - $('[data-type="dynamic"]').each(function(i, el) { - /* Insert image-button */ - var button_area = '
    '; - var image_button = ''; - $(el).wrap('
    '); - $(el).after(button_area); - $('[data-buttons-for="'+ $(el).attr('data-name') +'"]').append(image_button); - }); - - $('[data-reveal-id="gallery-modal"]').click( function(e) { - /* Store where to but the image from the modal in the modal */ - var replacing = $(this).attr('data-replace'); - $(".image-insert-btn").attr('data-replacing', replacing); - }); - $(".image-insert-btn").click(function(e) { - var img = $(".gallery .selected img"); - if(!img.length) { - // nothing selected - return; - } - var replacing = $(this).attr('data-replacing'); - var part = $('[data-name="'+ replacing +'"]'); - part.html(''); - part.find('img').attr('data-pk', img.attr('data-pk')); - part.trigger('changed'); - $("#gallery-modal").foundation('reveal', 'close'); - $('.image-select').removeClass("selected"); - }); - /* DELETE image part */ - $("[data-remove-image]").click(function(e) { - var replacing = $('.image-insert-btn').attr('data-replacing'); - var part = $('[data-name="'+ replacing +'"]'); - part.attr('data-part-remove','1'); - part.html(''); - part.trigger('changed'); - $('.image-select').removeClass("selected"); - $("#gallery-modal").foundation('reveal', 'close'); - }); - - /* Link between slides */ - /* ...for "dynamic" areas */ - $('[data-type="dynamic"]').each(function(i, el) { - /* Insert link-button on images */ - var last_button = $(el).siblings().find("a:last-child"); - last_button.after(''); - }); - - /* Set element target on modal */ - $('[data-url-target]').click( function(e) { - var target = $(this).attr('data-url-target'); - if(!$('[data-name="' + target + '"]').find('img').length) { - /* if there is no image, dont link to nothing */ - e.stopPropagation(); - return; - } - $(".modal-links").attr('data-wrapping', target); - }); - - $("[data-is-slide-link]").click(function(e) { - e.preventDefault(); - if($(this).attr('data-get-value-from-id')) { - /* Insert own link via input-field */ - var input_id = $(this).attr('data-get-value-from-id'); - $(this).attr('href', $("#"+input_id).val()); - } - var link = $(this).attr('href'); - var wrapping = $(".modal-links").attr('data-wrapping'); - var el_target = $('[data-name="'+ wrapping +'"]'); - // replace href in targets children if it exists - var potential_link = el_target.children(); - if(potential_link.is('a')) { - potential_link.attr('href',link); - } else { - el_target.find('img').wrap(''); - } - el_target.trigger('changed'); - $(".modal-links").foundation('reveal', 'close'); - }); - - /* Graphs - sticks in divs with data-type=dynamic */ - $('[data-type="dynamic"]').each(function(i, el) { - /* Insert link-button on images */ - var last_button = $(el).siblings().find("a:last-child"); - last_button.after(''); - - /* Set element target on modal */ - $('[data-target="'+ $(el).attr('data-name') +'"]').click( function(e) { - var target = $(this).attr('data-target'); - $(".modal-graph").attr('data-graph-target', target); - }); - }); - - $("[data-is-graph] a").click(function(e) { - e.preventDefault(); - var part_name = $('[data-graph-target]').attr('data-graph-target'); - var graph = $(this).parent(); - var part = $('[data-name="'+ part_name +'"]'); - var html = graph.find('[data-graph-html-copy]')[0].outerHTML; - part.html(html); - part.find('[data-graph-slug]').graph('load'); - part.trigger('changed'); - $(".modal-graph").foundation('reveal', 'close'); - }); - - /* Load graphs initially */ - $('.template [data-graph-slug]').graph('load'); - $('.modal-graph [data-graph-slug]').graph('load', {width: 300, height: 200}); - -}); diff --git a/static/app/scripts/slides.js b/static/app/scripts/slides.js deleted file mode 100644 index 92a10dc..0000000 --- a/static/app/scripts/slides.js +++ /dev/null @@ -1,440 +0,0 @@ -$(document).ready( function() { - var all_icons = $("[data-section-icon]").map(function() { - return $(this).attr('data-section-icon'); - }).get(); - all_icons = _.uniq(all_icons).join(" "); - - function update_title_bar( event ) { - if($(event.currentSlide).is('[data-section-title-hidden]') ) { - $(".title-bar").css('opacity', '0'); - } else { - $(".title-bar").css('opacity', '1'); - } - // event.previousSlide, event.currentSlide, event.indexh, event.indexv - var title = $(event.currentSlide).attr('data-section-title') || ""; - /* Only update when title has changed */ - if($(".title-bar .title span:first").text() !== title) { - $(""+title+"").hide().appendTo(".title-bar .title").fadeIn("normal"); - $(".title-bar .title span:not(:last)").fadeOut("normal", function() { - $(this).remove(); - }); - } - - var edit_url = $(event.currentSlide).attr('data-edit-url'); - $(".title-bar a.title").attr('href', edit_url); // Only update if a is found - - var icon = $(event.currentSlide).attr('data-section-icon') || ""; - if( !$(".title-bar .title i").hasClass(icon) ) { - $(".title-bar .title i") - .removeClass(all_icons) - .addClass(icon); -  } - } - /* Slides: with "wheel" */ - function wheel_toggle_slides(el) { - $("[data-wheel-order]").removeClass('active'); - $(el).addClass('active'); - var order = $(el).attr('data-wheel-order'); - var related = $('[data-wheel-order="' + order +'"]').not('.wheel-image'); - related.addClass('active'); - $('.wheel-text [data-type="wysihtml5"]').hide(); - related.show(); - } - $(".top-bar .links a").click(function() { - $(".top-bar.expanded .toggle-topbar").trigger("click.fndtn.topbar"); - }); - - /* Presentation? */ - if( $('.page-presentation-play').length) { - /* Initialize reveal.js */ - Reveal.initialize({ - // Display controls in the bottom right corner - controls: true, - // Display a presentation progress bar - progress: true, - // Push each slide change to the browser history - history: true, - // Enable keyboard shortcuts for navigation - keyboard: true, - // Enable the slide overview mode - overview: false, - // Vertical centering of slides - center: false, - // Enables touch navigation on devices with touch input - touch: true, - // Loop the presentation - loop: false, - // Change the presentation direction to be RTL - rtl: false, - // Number of milliseconds between automatically proceeding to the - // next slide, disabled when set to 0, this value can be overwritten - // by using a data-autoslide attribute on your slides - autoSlide: 0, - // Enable slide navigation via mouse wheel - mouseWheel: false, - // Apply a 3D roll to links on hover - rollingLinks: false, - // Transition style - transition: 'linear', // default/cube/page/concave/zoom/linear/fade/none - // Factor of the display size that should remain empty around the content - margin: 0.15, - // The "normal" size of the presentation, aspect ratio will be preserved - // when the presentation is scaled to fit different resolutions. Can be - // specified using percentage units. - //width: 960, - //height: 700, - width: 768, // Note: Could set this to 100% and make presentation content responsive instead of using zoom; - height: 576, - minScale: 0.2, - maxScale: 1 - // FIXME: use user agent / device width ? - }); - - - Reveal.addEventListener( 'ready', function(event) { - /* On small screen? disable transitions */ - var small_screen = $(window).width() < 480; - if( small_screen ) { - Reveal.configure({ transition: 'none' }); - } - - update_title_bar(event); - - /* Load chart if one exists on current slide (animate) */ - if( $(event.currentSlide).find('[class^="graph-"]').length) { - $(event.currentSlide).find('[class^="graph-"]').graph('load'); - } - - }); - - Reveal.addEventListener( 'slidechanged', function( event ) { - - /* Update title bar */ - update_title_bar(event); - - /* Chart slide - Wait until it is current to load (animate) */ - if( $(event.currentSlide).find('[class^="graph-"]').length) { - $(event.currentSlide).find('[class^="graph-"]').graph('load'); - } - - /* Disable touch on specific slides*/ - if( $(event.currentSlide).find("[data-swipe-disable]").length ) { - Reveal.configure({ touch: false }); - } else { - Reveal.configure({ touch: true }); - } - - /* Search previous slide for video elements and pause them */ - $(event.previousSlide).find("video").each(function(i, el) { - el.pause(); - }); - - /* Setup/Reset wheel state on wheel-slide enter */ - if( $(event.currentSlide).find('.wheel').length) { - $('.wheel-text [data-wheel-order]').hide(); - $('[data-wheel-order]').removeClass('active'); - $('[data-wheel-order="1"]').addClass('active').show(); - } - } ); - - - $(".wheel-images .wheel-image .trigger, .wheel-head .trigger").on('mousedown', function(e) { - wheel_toggle_slides(this); - }); - /* Hover fix for touch: Only bind on hover for non-touch devices */ - $(".no-touch .wheel-images .wheel-image .trigger, .no-touch .wheel-head .trigger").on('mouseenter', function(e) { - wheel_toggle_slides(this); - }); - } - - /* Swipebox */ - $('a.fancybox').swipebox(); - - /* Video */ - $('video').mediaelementplayer({ - success: function (mediaElement, domObject) { - /* Track video plays */ - mediaElement.addEventListener( - 'play', - function(e) { - mixpanel.track("Played video."); - }, - false); - } - }); - - /* Skip home if you are on the play-slide */ - $("[data-goto-first-slide]").on('click', function(e) { - e.preventDefault(); - $(".top-bar.expanded .toggle-topbar").trigger("click.fndtn.topbar"); - Reveal.slide(0, 0); - }); - - - /* Slide: Sick cost calculator */ - function get_salary() { - var industry_pk = parseInt($("#id_calc_industry").val(), 10); - /* Note: stb_industries is defined in the calculator.html-template */ - var industry = _.findWhere(stb_industries, {pk: industry_pk}); - - if(industry === undefined) { - return 0; - } - return industry.fields.yearly_salary; - } - function calc_cost(sick_rate, num_staff) { - var salary = get_salary(); - sick_rate = sick_rate / 100.0; // percent - return sick_rate * num_staff * salary; - } - /* Format norwegian */ - function format_number_norwegian(num) { - num = num.toString(); - var formatted_str = ""; - /* Add spaces backwards every third char */ - for(var i=0; i< num.length; i++){ - if(i % 3 === 0) { - formatted_str += " "; - } - formatted_str += num.charAt(num.length-i-1); - } - /* reverse the string */ - return formatted_str.split("").reverse().join(""); - } - function calc_savings(sick_rate, goal_sick_rate, num_staff) { - var current = calc_cost(sick_rate, num_staff); - var goal = calc_cost(goal_sick_rate, num_staff); - return current - goal; //total savings per year - } - function recalc() { - /* Get data */ - var num_staff = parseInt($(".num-staff").slider('value'), 10); - var sick_rate = $(".sick-rate").slider('value'); - var sick_rate_float = parseFloat(sick_rate); - var goal_sick_rate = $(".goal-sick-rate").slider('value'); - var goal_sick_rate_float = parseFloat(goal_sick_rate); - /* Calculate */ - var cost = calc_cost(sick_rate_float, num_staff); - cost = parseInt(Math.round( cost / 100), 10) * 100; - var savings = calc_savings(sick_rate_float, goal_sick_rate, num_staff); - savings = parseInt(Math.round( savings / 1000), 10) * 1000; - /* Output data */ - $("[data-calc-staff]").text(num_staff); - $("[data-calc-rate]").text(Math.round(sick_rate_float * 10) / 10); - $("[data-calc-goal-rate]").text(Math.round(goal_sick_rate_float * 10) / 10); - $("[data-calc-savings]").text(format_number_norwegian(savings)); - $("[data-calc-savings-employee]").text(format_number_norwegian(Math.round(savings / num_staff))); - /* cost */ - $("[data-calc-cost]").text(format_number_norwegian(cost)); - $("[data-calc-cost-employee]").text(format_number_norwegian(Math.round(cost / num_staff))); - - } - if($(".sick-cost-calculator").length) { - $( ".num-staff" ).slider({ - animate: "fast", - value: 600, - min: 1, - max: 2000, - step: 1, - stop: recalc, - slide: recalc - }); - $( ".sick-rate" ).slider({ - animate: "fast", - value: 10.2, - min: 1, - max: 15, - step: 0.2, - stop: recalc, - slide: recalc - }); - $( ".goal-sick-rate" ).slider({ - animate: "fast", - value: 5, - min: 1, - max: 15, - step: 0.2, - stop: recalc, - slide: recalc - }); - $(".sick-cost-industry-form").on('change', function(e) { - recalc(); - }); - - recalc(); // Initial calc - - /* Workaround for slider not working on touch devices - * Click/touch and change */ - $("[data-calc-staff], [data-calc-rate], [data-calc-goal-rate]").on('click', function(e) { - $(".set-value-modal").attr('data-updating', $(this).attr('data-updating')); - var old_value = $(this).text(); - $("input[name=set-value]").val(old_value); - $(".set-value-modal").foundation('reveal', 'open'); - }); - $(".set-value-button").on('click', function(e) { - var new_value = $("input[name=set-value]").val(); - var key = "#" + $(".set-value-modal").attr('data-updating'); - $( key ).slider({ value: parseFloat(new_value)}); - $(".set-value-modal").foundation('reveal', 'close'); - recalc(); - }); - } - - /* Slide: Public treatment comparison */ - if($(".public-treatment-comparison").length) { -        var options = { -     valueNames: [ 'region', 'hospital', 'city', 'diagnose', 'waittime' ] -        }; - -        var featureList = new List('treatment-list', options); - featureList.sort('waittime', { asc: false }); - -        $('.filter-region, .filter-diagnose').change(function() { -            featureList.filter(function(item) { - var diagnose = $('.filter-diagnose').val(); - var region = $(".filter-region").val(); -                return (item.values().region == region || region == "Alle") && item.values().diagnose == diagnose; -            }); -            return false; -        }); -        $('.filter-none').click(function() { -            featureList.filter(); -            return false; -        }); - $(".filter-diagnose").trigger('change'); - } - - function init_treatment_map() { - // mapbox.com: nikolaik.map-hyrf1sef - var tile_url = 'http://{s}.tiles.mapbox.com/v3/nikolaik.map-hyrf1sef/{z}/{x}/{y}.png'; - var tiles = L.tileLayer(tile_url, {maxZoom: 17, minZoom: 4}); - var latlng = L.latLng(65.57, 12.56); - - var map = L.map('treament-network-map', {center: latlng, zoom: 4, layers: [tiles]}); - - var markers = L.markerClusterGroup({ showCoverageOnHover: false}); - /* Marker icon style */ - var static_url = $('meta[name="x-django-static-url"]').attr('content'); - var icon = L.icon({ - iconUrl: static_url + 'dist/images/storebrand_map_marker.png', - iconSize: new L.Point(35, 35), - iconAnchor: new L.Point(35, 35), - popupAnchor: new L.Point(-17.5, -35), - shadowUrl: '', - shadowSize: new L.Point(0, 0), - }); - - /* Add specialist markers */ - var _url = 'http://zeppelin.brill.no/blifrisk/data/no.json'; - $.getJSON(_url, function(data) { - _.each(data.specialists, function(s, i) { - if(s.position) { - var marker = L.marker(new L.LatLng(s.position.lat, s.position.lng), { title: s.name, icon: icon }); - marker.bindPopup("

    "+ s.name +"

    "+ s.address +"
    "+ s.postalCode +" "+ s.city +"

    "); - markers.addLayer(marker); - } - }); - map.addLayer(markers); - }); - } - /* Slide: Treatment locations map */ - if($(".treament-network-map").length) { - - /* Load the treatment map when the slide comes in to view when in presentation mode */ - if (window.Reveal && !$(".page-slide-edit").length) { - var handler = function(event) { - if($(event.currentSlide).find(".treament-network-map").length) { - init_treatment_map(); - Reveal.removeEventListener( 'slidechanged', handler, false); // run only once - } - }; - Reveal.addEventListener( 'slidechanged', handler); - Reveal.addEventListener( 'ready', function(event) { - if($(event.currentSlide).find(".treament-network-map").length) { - /* Load map */ - init_treatment_map(); - } - }); - } else { - init_treatment_map(); - } - - } - /* Placeholder polyfill for IE9 */ - placeholderSupport = ("placeholder" in document.createElement("input")); - if(!placeholderSupport){ - //This browser does not support the placeholder attribute - //use javascript instead - $('[placeholder]').focus(function() { - var input = $(this); - if (input.val() === input.attr('placeholder')) { - input.val(''); - input.removeClass('placeholder'); - } - }).blur(function() { - var input = $(this); - if (input.val() === '' || input.val() === input.attr('placeholder')) { - input.addClass('placeholder'); - input.val(input.attr('placeholder')); - } - }).blur().parents('form').submit(function() { - $(this).find('[placeholder]').each(function() { - var input = $(this); - if (input.val() === input.attr('placeholder')) { - input.val(''); - } - }); - }); - } - /* Highcarts graph theme */ - Highcharts.theme = { - colors: ['#da291c', '#425563', '#ed786f'], - chart: { - backgroundColor: null - }, - credits: { - enabled: false - }, - title: { - style: { - color: '#1e394d', - font: 'bold 16px "SignaColumn", Helvetica, Arial, sans-serif' - } - }, - subtitle: { - style: { - color: '#425563', - font: 'bold 12px "SignaColumn", Helvetica, Arial, sans-serif' - } - }, - yAxis: { - title: { - style: { - color: 'gray' - } - } - }, - xAxis: { - title: { - style: { - color: 'gray' - } - } - }, - legend: { - itemStyle: { - font: '9pt "SignaColumn", Helvetica, Arial, sans-serif', - color: 'black' - }, - itemHoverStyle:{ - color: 'gray' - } - }, - exporting: { - enabled: false - } - }; - - // Apply the theme - Highcharts.setOptions(Highcharts.theme); -}); diff --git a/static/dist/scripts/app.js b/static/dist/scripts/app.js index e69de29..e7353fb 100644 --- a/static/dist/scripts/app.js +++ b/static/dist/scripts/app.js @@ -0,0 +1,58 @@ +function format_results(results) { + var html = '
    '; + for(var i=0; i< results.length; i++) { + var res = results[i]; + + var label = ''; + var is_member = res.is_member && res.is_member === "1"; + var add_to_button = ''; + var css_classes = ''; + var expires = res.expires; + + if(is_member) { + label = ' Member '; + css_classes += 'member'; + } else if(expires === '0000-00-00') { + add_to_button = ' '; + label = ' Registered '; + } else { + add_to_button = ' '; + label = ' Expired: '+ expires +' '; + } + var q = $('#id_query').val(); + html += '' + add_to_button + res.firstname + ' ' + res.lastname + label + ''; + } + return html + '
    '; +} + +$(document).ready(function(){ + var _dom = { + results: $('.results-wrap'), + query: $('#id_query'), + phoneNumber: $('#id_phone_number'), + cardNumber: $('#id_card_number') + }; + var urls = { + insideUserApi: '/inside/user/' + }; + + /* Saerch as you type */ + _dom.query.on('keyup', function() { + var val = _dom.query.val(); + $.getJSON(urls.insideUserApi, {q: val}, function(data) { + //console.log(data); + if(data.results && data.results.length > 0) { + _dom.results.html(format_results(data.results)); + } else { + _dom.results.html('No existing user with that phone number'); + } + }); + }); + + /* Click search result */ + _dom.results.on('click', '.search-result', function(e){ + e.preventDefault(); + var number = $(this).attr('data-phone-number'); + _dom.phoneNumber.val(number); + }); +}); \ No newline at end of file diff --git a/static/dist/scripts/documents_edit.js b/static/dist/scripts/documents_edit.js deleted file mode 100644 index eca4572..0000000 --- a/static/dist/scripts/documents_edit.js +++ /dev/null @@ -1,95 +0,0 @@ - -$(function(){ - var urls = { - save_document: '/api/document/', - update_document: '/api/document/{pk}/' - }; - var _dom = { - document_table: $('.document-table'), - progress_bar: $("#progress .bar"), - }; - var csrf_token = $.cookie('csrftoken'); - - /* inplace edit */ - _dom.document_table.on('click', "[data-model-field]", function() { - var input_field = $(this).siblings("input"); - if($(this).siblings("input").length) { - input_field.val($(this).text()).css('display', 'inline-block'); - } else { - $(this).after(''); - input_field = $(this).siblings("input"); - } - input_field.css('width', $(this).width() + 30); - $(this).hide(); - $("[data-editable-field]").focus(); - }); - - /* save on blur and */ - _dom.document_table.on('blur keyup', 'input[type=text]', function(e) { - if(e.type == 'keyup' && e.keyCode != 13) { - return; - } - /* anything changed ? */ - if( $(this).siblings("[data-model-field]").text() !== $(this).val() ) { - /* update text */ - $(this).siblings("[data-model-field]").text($(this).val()); - - var document_pk = $(this).siblings("[data-model-field]").attr('data-pk'); - var model_field = $(this).siblings("[data-model-field]").attr('data-model-field'); - var field_value = $(this).val(); - - var data = {}; - data[model_field] = field_value; - - $.ajax({ - url: urls.update_document.replace('{pk}', document_pk), - method: 'PATCH', - dataType: 'json', - data: data, - headers: { - 'X-CSRFToken': csrf_token - }, - success: function(response, newValue) { - console.log('Field '+model_field+' updated with value "'+field_value+'".'); - } - }); - } - /* Back to original view */ - $("[data-model-field]").show(); - $(this).hide(); - }); - - /* Document file upload */ - $('.upload-document').fileupload({ - dataType: 'json', // TODO: why no JSON? - url: urls.save_document, - done: function(e, data) { - _dom.progress_bar.fadeOut('slow'); - var result = data.result; - /* insert document row */ - - var filename = result.filename.slice(0, 40); - console.log(result); - - $('.document-table').prepend(''+ result.name +' '+ filename +''+ result.updated +''); - }, - fail: function(e, data) { - console.log("Failed uploading file: ",e, data); - }, - headers: { - 'X-CSRFToken': csrf_token, - 'cache-control': 'no-cache' - }, - send: function(e, data) { - _dom.progress_bar.css('width', '0%'); - _dom.progress_bar.show(); - }, - progressall: function (e, data) { - var progress = parseInt(data.loaded / data.total * 100, 10); - _dom.progress_bar.css( - 'width', - progress + '%' - ); - } - }); -}); diff --git a/static/dist/scripts/fd-slider.js b/static/dist/scripts/fd-slider.js deleted file mode 100644 index 940ee49..0000000 --- a/static/dist/scripts/fd-slider.js +++ /dev/null @@ -1,1341 +0,0 @@ -/*! Unobtrusive Slider Control / HTML5 Input Range polyfill - MIT/GPL2 @freqdec */ -/*jshint sub:true, evil:true, boss:true */ -var fdSlider = (function() { - var sliders = {}, - uniqueid = 0, - mouseWheelEnabled = true, - fullARIA = true, - describedBy = "fd-slider-describedby", - varSetRules = { - onfocus:true, - onvalue:true - }, - noRangeBar = false, - html5Animation = "jump", - useDOMAttrModEvt = false, - isOpera = Object.prototype.toString.call(window.opera) === "[object Opera]", - fpRegExp = /^([\-]{0,1}[0-9]+(\.[0-9]+){0,1})$/, - stepRegExp = /^([0-9]+(\.[0-9]+){0,1})$/; - - var parseJSON = function(str) { - if(typeof str !== "string" || str === "") { - return {}; - } - try { - // Does a JSON (native or not) Object exist - if(typeof JSON === "object" && typeof(JSON.parse) === "function") { - return JSON.parse(str); - // Genious code taken from: http://kentbrewster.com/badges/ - } else if(/mousewheelenabled|fullaria|describedby|norangebar|html5animation|varsetrules/.test(str.toLowerCase())) { - var f = Function(['var document,top,self,window,parent,Number,Date,Object,Function,', - 'Array,String,Math,RegExp,Image,ActiveXObject;', - 'return (' , str.replace(/<\!--.+-->/gim,'').replace(/\bfunction\b/g,'function-') , ');'].join('')); - return f(); - } - } catch (e) { } - - return {"err":"Could not parse the JSON object"}; - }; - - var affectJSON = function(json) { - if(typeof json !== "object") { - return; - } - for(var key in json) { - value = json[key]; - switch(key.toLowerCase()) { - case "mousewheelenabled": - mouseWheelEnabled = !!value; - break; - case "fullaria": - fullARIA = !!value; - break; - case "describedby": - describedBy = String(value); - break; - case "norangebar": - noRangeBar = !!value; - break; - case "html5animation": - html5Animation = String(value).search(/^(jump|tween|timed)$/i) != -1 ? String(value).toLowerCase() : "jump"; - break; - case "watchattributes": - useDOMAttrModEvt = !!value; - break; - case "varsetrules": - if("onfocus" in value) { - varSetRules.onfocus = !!value.onfocus; - } - if("onvalue" in value) { - varSetRules.onvalue = !!value.onvalue; - } - break; - } - } - }; - var addEvent = function(obj, type, fn) { - if(obj.addEventListener) { - obj.addEventListener(type, fn, true); - } else if(obj.attachEvent) { - obj.attachEvent("on"+type, fn); - } - }; - var removeEvent = function(obj, type, fn) { - try { - if(obj.removeEventListener) { - obj.removeEventListener(type, fn, true); - } else if(obj.detachEvent) { - obj.detachEvent("on"+type, fn); - } - } catch(err) {} - }; - var stopEvent = function(e) { - e = e || window.event; - if(e.stopPropagation) { - e.stopPropagation(); - e.preventDefault(); - } - - /*@cc_on@*/ - /*@if(@_win32) - e.cancelBubble = true; - e.returnValue = false; - /*@end@*/ - - return false; - }; - var preventDefault = function(e) { - e = e || window.event; - if(e.preventDefault) { - e.preventDefault(); - return; - } - e.returnValue = false; - }; - // Add/Remove classname utility functions - var addClass = function(e,c) { - if(new RegExp("(^|\\s)" + c + "(\\s|$)").test(e.className)) { - return; - } - e.className += ( e.className ? " " : "" ) + c; - }; - var removeClass = function(e,c) { - e.className = !c ? "" : e.className.replace(new RegExp("(^|\\s)" + c + "(\\s|$)"), " ").replace(/^\s\s*/, '').replace(/\s\s*$/, ''); - }; - // Returns an Object of key value pairs indicating which sliders have values - // that have been "set" by the user. Normally used within form validation code - var getValueSet = function() { - var obj = {}; - for(var id in sliders) { - obj[id] = sliders[id].getValueSet(); - } - return obj; - }; - // Sets the valueSet variable for a specific slider - var setValueSet = function(sliderId, tf) { - sliders[sliderId].setValueSet(!!tf); - }; - // Does the slider exist in memory - var sliderExists = function(slider) { - return !!(slider in sliders && sliders.hasOwnProperty(slider)); - }; - // Javascript instantiation of a slider (input type="text|range" or select list) - var createSlider = function(options) { - if(!options || !options.inp || !options.inp.tagName || options.inp.tagName.search(/^input|select/i) == -1) { return false; } - - options.html5Shim = false; - - if(options.inp.tagName.toLowerCase() == "select") { - if(options.inp.options.length < 2) { - return false; - } - options.min = 0; - options.max = options.inp.options.length - 1; - options.step = 1; - options.precision = 0; - options.scale = false; - options.forceValue = true; - } else { - if(String(options.inp.type).search(/^(text|range)$/i) == -1) { - return false; - } - options.min = options.min && String(options.min).search(fpRegExp) != -1 ? +options.min : 0; - options.max = options.max && String(options.max).search(fpRegExp) != -1 ? +options.max : 100; - options.step = options.step && String(options.step).search(stepRegExp) != -1 ? options.step : 1; - options.precision = options.precision && String(options.precision).search(/^[0-9]+$/) != -1 ? options.precision : (String(options.step).search(/\.([0-9]+)$/) != -1 ? String(options.step).match(/\.([0-9]+)$/)[1].length : 0); - options.scale = options.scale || false; - options.forceValue = ("forceValue" in options) ? !!options.forceValue : false; - options.userSnap = ("userSnap" in options) ? !!options.userSnap : false; - } - options.ariaFormat = ("ariaFormat" in options) && typeof options.ariaFormat == "function" ? options.ariaFormat : false; - options.maxStep = options.maxStep && String(options.maxStep).search(stepRegExp) != -1 ? +options.maxStep : +options.step * 2; - options.classNames = options.classNames || ""; - options.callbacks = options.callbacks || false; - - destroySingleSlider(options.inp.id); - sliders[options.inp.id] = new fdRange(options); - return true; - }; - var getAttribute = function(elem, att) { - return elem.getAttribute(att) || ""; - }; - // HTML5 input type="range" shim - called onload or onDomReady - var init = function() { - var inputs = document.getElementsByTagName("input"), - options, - defs; - - for(var i = 0, inp; inp = inputs[i]; i++) { - - if(inp.tagName.toLowerCase() == "input" && - (getAttribute(inp,"type") && getAttribute(inp,"type").toLowerCase() == "range") && - (getAttribute(inp, "min") && getAttribute(inp, "min").search(fpRegExp) != -1 || - getAttribute(inp, "max") && getAttribute(inp, "max").search(fpRegExp) != -1 || - getAttribute(inp, "step") && getAttribute(inp, "step").search(/^(any|([0-9]+(\.[0-9]+){0,1}))$/i) != -1 - )) { - - // Skip elements that have already been created are are resident in the DOM - if(inp.id && document.getElementById("fd-slider-"+inp.id)) { - continue; - // Destroy elements that have already been created but not resident in the DOM - } else if(inp.id && !document.getElementById("fd-slider-"+inp.id)) { - destroySingleSlider(inp.id); - } - - // Create an id for the form element if necessary - if(!inp.id) { - inp.id = "fd-slider-form-elem-" + uniqueid++; - } - - // Basic option Object - options = { - inp: inp, - callbacks: [], - animation: html5Animation, - vertical: getAttribute(inp, "data-fd-slider-vertical") ? true : (inp.offsetHeight > inp.offsetWidth), - classNames: getAttribute(inp, "data-fd-slider-vertical"), - html5Shim: true - }; - - if(options.vertical && !getAttribute(inp, "data-fd-slider-vertical")) { - options.inpHeight = inp.offsetHeight; - } - - defs = getInputAttributes(inp); - - options.min = defs.min; - options.max = defs.max; - options.step = defs.step; - options.precision = String(options.step).search(/\.([0-9]+)$/) != -1 ? String(options.step).match(/\.([0-9]+)$/)[1].length : 0; - options.maxStep = options.step * 2; - - destroySingleSlider(options.inp.id); - sliders[options.inp.id] = new fdRange(options); - } - } - - return true; - }; - var getInputAttributes = function(inp) { - return { - "min":+(getAttribute(inp, "min") || 0), - "max":+(getAttribute(inp, "max") || 100), - "step":+(getAttribute(inp, "step").search(stepRegExp) != -1 ? inp.getAttribute("step") : 1) - }; - }; - var destroySingleSlider = function(id) { - if(id in sliders && sliders.hasOwnProperty(id)) { - sliders[id].destroy(); - delete sliders[id]; - return true; - } - return false; - }; - var destroyAllsliders = function(e) { - for(var slider in sliders) { - if(sliders.hasOwnProperty(slider)) { - sliders[slider].destroy(); - } - } - sliders = []; - }; - var unload = function(e) { - destroyAllsliders(); - sliders = null; - }; - var resize = function(e) { - for(var slider in sliders) { - if(sliders.hasOwnProperty(slider)) { - sliders[slider].onResize(); - } - } - }; - var rescanAttributes = function() { - for(var slider in sliders) { - if(sliders.hasOwnProperty(slider)) { - sliders[slider].rescan(); - } - } - }; - var onDomReady = function() { - removeOnLoadEvent(); - init(); - }; - var removeOnLoadEvent = function() { - removeEvent(window, "load", init); - }; - function fdRange(options) { - var inp = options.inp, - disabled = false, - tagName = inp.tagName.toLowerCase(), - min = +options.min, - max = +options.max, - rMin = +options.min, - rMax = +options.max, - range = Math.abs(max - min), - step = tagName == "select" ? 1 : +options.step, - maxStep = options.maxStep ? +options.maxStep : step * 2, - precision = options.precision || 0, - steps = Math.ceil(range / step), - scale = options.scale || false, - hideInput = !!options.hideInput, - animation = options.animation || "", - vertical = !!options.vertical, - callbacks = options.callbacks || {}, - classNames = options.classNames || "", - html5Shim = !!options.html5Shim, - defaultVal = max < min ? min : min + ((max - min) / 2), - resetDef = tagName == "select" ? inp.selectedIndex : inp.defaultValue || defaultVal, - forceValue = html5Shim || !!options.forceValue, - inpHeight = html5Shim && vertical && ("inpHeight" in options) ? options.inpHeight : false, - ariaFormat = !html5Shim && options.ariaFormat ? options.ariaFormat : false, - userSnap = !html5Shim && (tagName != "select") && ("userSnap" in options) ? !!options.userSnap : false, - userInput = false, - timer = null, - kbEnabled = true, - initialVal = tagName == "select" ? inp.selectedIndex : inp.value, - sliderH = 0, - sliderW = 0, - tweenX = 0, - tweenB = 0, - tweenC = 0, - tweenD = 0, - frame = 0, - x = 0, - y = 0, - rMaxPx = 0, - rMinPx = 0, - handlePos = 0, - destPos = 0, - mousePos = 0, - stepPx = 0, - userSet = false, - touchEvents = false, - outerWrapper, - innerWrapper, - ieBlur, - handle, - rangeBar, - bar; - - // For the reset event to work we have to set a defaultValue - if(tagName == "input" && forceValue && !inp.defaultValue) { - inp.defaultValue = getWorkingValueFromInput(); - } - - // Make sure we have a negative step if the max < min - if(max < min) { - step = -Math.abs(step); - maxStep = -Math.abs(maxStep); - } - - // Add the 100% scale mark if needs be. This is hacky. - if(scale) { - scale[100] = max; - } - - // Set the "userSet" variable programmatically for this slider - function valueSet(tf) { - tf = !!tf; - if(tf != userSet) { - userSet = tf; - valueToPixels(getWorkingValueFromInput()); - } - } - - function rescanAttrs() { - if(!useDOMAttrModEvt || tagName == "select") { - return; - } - - var defs = getInputAttributes(inp); - - if(defs.min == min && defs.max == max && defs.step == step) { - return; - } - - min = +defs.min; - max = +defs.max; - rMin = min; - rMax = max; - step = +defs.step; - range = Math.abs(max - min); - maxStep = step * 2; - steps = Math.ceil(range / step); - userSet = false; - setSliderRange(min, max); - } - - function disableSlider(noCallback) { - if(disabled && !noCallback) { - return; - } - - try { - setTabIndex(handle, -1); - removeEvent(handle, "focus", onFocus); - removeEvent(handle, "blur", onBlur); - - if(!isOpera) { - removeEvent(handle, "keydown", onKeyDown); - removeEvent(handle, "keypress", onKeyPress); - } else { - removeEvent(handle, "keypress", onKeyDown); - } - - removeEvent(outerWrapper, "mouseover", onMouseOver); - removeEvent(outerWrapper, "mouseout", onMouseOut); - removeEvent(outerWrapper, "mousedown", onMouseDown); - removeEvent(outerWrapper, "touchstart", onMouseDown); - - if(mouseWheelEnabled) { - if (window.addEventListener && !window.devicePixelRatio) window.removeEventListener('DOMMouseScroll', trackMouseWheel, false); - else { - removeEvent(document, "mousewheel", trackMouseWheel); - removeEvent(window, "mousewheel", trackMouseWheel); - } - } - } catch(err) {} - - removeClass(innerWrapper, "fd-slider-focused"); - removeClass(innerWrapper, "fd-slider-active"); - - addClass(innerWrapper, "fd-slider-disabled"); - outerWrapper.setAttribute("aria-disabled", true); - inp.disabled = disabled = true; - clearTimeout(timer); - - if(!noCallback) { - callback("disable"); - } - } - - function enableSlider(noCallback) { - if(!disabled && !noCallback) { - return; - } - - setTabIndex(handle, 0); - addEvent(handle, "focus", onFocus); - addEvent(handle, "blur", onBlur); - - if(!isOpera) { - addEvent(handle, "keydown", onKeyDown); - addEvent(handle, "keypress", onKeyPress); - } else { - addEvent(handle, "keypress", onKeyDown); - } - - addEvent(outerWrapper, "touchstart", onMouseDown); - addEvent(outerWrapper, "mousedown", onMouseDown); - addEvent(outerWrapper, "mouseover", onMouseOver); - addEvent(outerWrapper, "mouseout", onMouseOut); - - removeClass(innerWrapper, "fd-slider-disabled"); - outerWrapper.setAttribute("aria-disabled", false); - inp.disabled = disabled = touchEvents = false; - - if(!noCallback) { - callback("enable"); - } - } - - // Destroys a slider - function destroySlider() { - clearTimeout(timer); - ieBlur = bar = handle = outerWrapper = innerWrapper = timer = null; - callback("destroy"); - callbacks = null; - } - - // Calculates the pixel increment etc - function redraw() { - locate(); - // Internet Explorer requires the try catch as hidden - // elements throw errors - try { - var sW = outerWrapper.offsetWidth, - sH = outerWrapper.offsetHeight, - hW = handle.offsetWidth, - hH = handle.offsetHeight, - bH = bar.offsetHeight, - bW = bar.offsetWidth, - mPx = vertical ? sH - hH : sW - hW; - - stepPx = mPx / steps; - rMinPx = Math.max(scale ? percentToPixels(valueToPercent(rMin)) : Math.abs((rMin - min) / step) * stepPx, 0); - rMaxPx = Math.min(scale ? percentToPixels(valueToPercent(rMax)) : Math.abs((rMax - min) / step) * stepPx, Math.floor(vertical ? sH - hH : sW - hW)); - - sliderW = sW; - sliderH = sH; - - valueToPixels(forceValue ? getWorkingValueFromInput() : (tagName == "select" ? inp.selectedIndex : parseFloat(inp.value)), false); - - } catch(err) {} - callback("redraw"); - } - - // Calls a callback function - function callback(type) { - if(!html5Shim) { - if(callbacks.hasOwnProperty(type)) { - var cbObj = {"userSet":userSet, "disabled":disabled, "elem":inp, "value":tagName == "select" ? inp.options[inp.selectedIndex].value : inp.value}; - - // Call all functions in sequence - for(var i = 0, func; func = callbacks[type][i]; i++) { - func.call(inp, cbObj); - } - } - } else if(type.match(/^(blur|focus|change)$/i)) { - var e; - if(typeof(document.createEvent) != 'undefined') { - e = document.createEvent('HTMLEvents'); - e.initEvent(type, true, true); - inp.dispatchEvent(e); - } else if(typeof(document.createEventObject) != 'undefined') { - try { - e = document.createEventObject(); - inp.fireEvent('on' + type.toLowerCase(), e); - } catch(err){ } - } - } - } - - // FOCUS & BLUR events - function onFocus(e) { - addClass(innerWrapper, 'fd-slider-focused'); - - // Is the value said to have been set by the user onfocus - if(varSetRules.onfocus) { - userSet = true; - valueToPixels(getWorkingValueFromInput()); - } - - // If mousewheel events required then add them - if(mouseWheelEnabled) { - addEvent(window, 'DOMMouseScroll', trackMouseWheel); - addEvent(document, 'mousewheel', trackMouseWheel); - if(!isOpera) { - addEvent(window, 'mousewheel', trackMouseWheel); - } - } - - callback("focus"); - return true; - } - - function onBlur(e) { - removeClass(innerWrapper, 'fd-slider-focused'); - - // Remove mousewheel events if necessary - if(mouseWheelEnabled) { - removeEvent(document, 'mousewheel', trackMouseWheel); - removeEvent(window, 'DOMMouseScroll', trackMouseWheel); - if(!isOpera) { - removeEvent(window, 'mousewheel', trackMouseWheel); - } - } - - kbEnabled = true; - callback("blur"); - } - - // MOUSEWHEEL events - function trackMouseWheel(e) { - if(!kbEnabled) { - return; - } - - e = e || window.event; - var delta = 0, - value; - - if (e.wheelDelta) { - delta = e.wheelDelta/120; - // Older versions of Opera require a small hack to inverse the delta - if (isOpera && window.opera.version() < 9.2) { - delta = -delta; - } - } else if(e.detail) { - delta = -e.detail/3; - } - - if(vertical) { - delta = -delta; - } - - if(delta) { - value = getWorkingValueFromInput(); - value += (delta < 0) ? -step : step; - userSet = true; - valueToPixels(getValidValue(value)); - } - - preventDefault(e); - } - - // KEYBOARD events - function onKeyPress(e) { - e = e || window.event; - // Let all non-hijacked keyboard events pass - if((e.keyCode >= 33 && e.keyCode <= 40) || !kbEnabled || e.keyCode == 45 || e.keyCode == 46) { - return stopEvent(e); - } - return true; - } - - function onKeyDown(e) { - if(!kbEnabled) { - return true; - } - - e = e || window.event; - var kc = e.keyCode !== null ? e.keyCode : e.charCode, - value; - - if(kc < 33 || (kc > 40 && (kc != 45 && kc != 46))) { - return true; - } - - value = getWorkingValueFromInput(); - - if( kc == 37 || kc == 40 || kc == 46 || kc == 34) { - // left, down, ins, page down - value -= (e.ctrlKey || kc == 34 ? +maxStep : +step); - } else if( kc == 39 || kc == 38 || kc == 45 || kc == 33) { - // right, up, del, page up - value += (e.ctrlKey || kc == 33 ? +maxStep : +step); - } else if( kc == 35 ) { - // max - value = rMax; - } else if( kc == 36 ) { - // min - value = rMin; - } - - userSet = true; - valueToPixels(getValidValue(value)); - - callback("update"); - - // Opera doesn't let us cancel key events so the up/down arrows and home/end buttons will scroll the screen - which sucks - preventDefault(e); - } - - // MOUSE & TOUCH events - - function onMouseOver(e) { - addClass(innerWrapper, 'fd-slider-hover'); - } - - function onMouseOut(e) { - // Should really check we are not still in the slider - removeClass(innerWrapper, 'fd-slider-hover'); - } - - // Mousedown on the slider - function onMouseDown(e) { - e = e || window.event; - - // Stop page scrolling - preventDefault(e); - - // Grab the event target - var targ; - if (e.target) { - targ = e.target; - } else if (e.srcElement) { - targ = e.srcElement; - } - if(targ && targ.nodeType == 3) { - targ = targ.parentNode; - } - - // Are we using touchEvents - if(e.touches) { - // Skip gestures - if(e.targetTouches && e.targetTouches.length != 1) { - return false; - } - - e = e.touches[0]; - touchEvents = true; - } - - // Stop any animation timers - clearTimeout(timer); - timer = null; - - // Not keyboard enabled - kbEnabled = false; - - // User has set a value - userSet = true; - - // Handle mousedown - initiate drag - if(targ.className.search("fd-slider-handle") != -1) { - mousePos = vertical ? e.clientY : e.clientX; - handlePos = parseInt(vertical ? handle.offsetTop : handle.offsetLeft)||0; - - // Set a value on first click even if no movement - trackMouse(e); - - if(!touchEvents) { - addEvent(document, 'mousemove', trackMouse); - addEvent(document, 'mouseup', stopDrag); - } else { - addEvent(document, 'touchmove', trackMouse); - addEvent(document, 'touchend', stopDrag); - // Remove mouseEvents to stop them firing after the touch event - removeEvent(outerWrapper, "mousedown", onMouseDown); - } - - addClass(innerWrapper, 'fd-slider-active'); - addClass(document.body, "fd-slider-drag-" + (vertical ? "vertical" : "horizontal")); - - callback("dragstart"); - - // Wrapper mousedown - initiate animation to click point - } else { - locate(); - - var posx = 0; - - if(e.pageX || e.pageY) { - posx = vertical ? e.pageY : e.pageX; - } else if (e.clientX || e.clientY) { - posx = vertical ? e.clientY + document.body.scrollTop + document.documentElement.scrollTop : e.clientX + document.body.scrollLeft + document.documentElement.scrollLeft; - } - - posx -= vertical ? y + Math.round(handle.offsetHeight / 2) : x + Math.round(handle.offsetWidth / 2); - posx = snapToPxValue(posx); - - // Tween animation to click point - if(animation == "tween") { - addClass(innerWrapper, 'fd-slider-active'); - tweenTo(posx); - // Progressive increment to click point - } else if(animation == "timed") { - addClass(innerWrapper, 'fd-slider-active'); - addEvent(document, touchEvents ? 'touchend' : 'mouseup', onDocMouseUp); - destPos = posx; - onTimer(); - // Immediate jump to click point - } else { - pixelsToValue(posx); - //addEvent(document, touchEvents ? 'touchend' : 'mouseup', onMouseUp); - } - } - - return false; - } - - // Progressive increment to click point - clear the animation timer and remove the mouseup/touchend event - function onDocMouseUp( e ) { - e = e || window.event; - - preventDefault(e); - removeEvent(document, touchEvents ? 'touchend' : 'mouseup', onDocMouseUp); - removeClass(innerWrapper, "fd-slider-active"); - - clearTimeout(timer); - timer = null; - kbEnabled = true; - - return false; - } - - // Mouseup or touchend event on the document to stop drag - function stopDrag(e) { - e = e || window.event; - - preventDefault(e); - - if(touchEvents) { - removeEvent(document, 'touchmove', trackMouse); - removeEvent(document, 'touchend', stopDrag); - } else { - removeEvent(document, 'mousemove', trackMouse); - removeEvent(document, 'mouseup', stopDrag); - } - - kbEnabled = true; - removeClass(document.body, "fd-slider-drag-" + (vertical ? "vertical" : "horizontal")); - removeClass(innerWrapper, "fd-slider-active"); - - callback("dragend"); - - return false; - } - - // Mousemove or touchmove event on the drag handle - function trackMouse(e) { - e = e || window.event; - - preventDefault(e); - - if(e.touches) { - // Skip gestures - if(e.targetTouches && e.targetTouches.length != 1) { - return false; - } - e = e.touches[0]; - } - - pixelsToValue(snapToPxValue(handlePos + (vertical ? e.clientY - mousePos : e.clientX - mousePos))); - - return false; - } - - // Increments the slider by "inc" steps - function increment(inc) { - var value = getWorkingValueFromInput(); - userSet = true; - value += inc * step; - valueToPixels(getValidValue(value)); - } - - // Attempts to locate the on-screen position of the slider - function locate(){ - var curleft = 0, - curtop = 0, - obj = outerWrapper; - - // Try catch for IE's benefit - try { - do { - curleft += obj.offsetLeft; - curtop += obj.offsetTop; - } while(obj = obj.offsetParent); - } catch(err) {} - x = curleft; - y = curtop; - } - - // Used during the progressive animation to click point - function onTimer() { - var xtmp = parseInt(vertical ? handle.offsetTop : handle.offsetLeft, 10); - xtmp = Math.round((destPos < xtmp) ? Math.max(destPos, Math.floor(xtmp - stepPx)) : Math.min(destPos, Math.ceil(xtmp + stepPx))); - - pixelsToValue(snapToPxValue(xtmp)); - if(xtmp != destPos) { - timer = setTimeout(onTimer, steps > 20 ? 50 : 100); - } else { - kbEnabled = true; - removeClass(innerWrapper, "fd-slider-active"); - callback("finalise"); - } - } - - var tween = function(){ - frame++; - var c = tweenC, - d = 20, - t = frame, - b = tweenB, - x = Math.ceil((t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b); - - pixelsToValue(t == d ? tweenX : x); - - if(t!=d) { - // Call the "move" callback on each animation increment - callback("move"); - timer = setTimeout(tween, 20); - } else { - clearTimeout(timer); - timer = null; - kbEnabled = true; - - removeClass(innerWrapper, "fd-slider-focused"); - removeClass(innerWrapper, "fd-slider-active"); - - // Call the "finalise" callback whenever the animation is complete - callback("finalise"); - } - }; - - function tweenTo(tx){ - kbEnabled = false; - tweenX = parseInt(tx, 10); - tweenB = parseInt(vertical ? handle.offsetTop : handle.offsetLeft, 10); - tweenC = tweenX - tweenB; - tweenD = 20; - frame = 0; - - if(!timer) { - timer = setTimeout(tween, 20); - } - } - - // Returns a value within the range & sets the userSet var - // i.e. has the user entered a valid value - function checkValue(value) { - if(isNaN(value) || value === "" || typeof value == "undefined") { - userSet = false; - return defaultVal; - } else if(value < Math.min(rMin,rMax)) { - userSet = false; - return Math.min(rMin,rMax); - } else if(value > Math.max(rMin,rMax)) { - userSet = false; - return Math.max(rMin,rMax); - } - userSet = true; - return value; - } - - // Returns a value within a range - uses the form element value as base - function getWorkingValueFromInput() { - return getValidValue(tagName == "input" ? parseFloat(inp.value) : inp.selectedIndex); - } - - // Returns a value within the range - function getValidValue(value) { - return (isNaN(value) || value === "" || typeof value == "undefined") ? defaultVal : Math.min(Math.max(value, Math.min(rMin,rMax)), Math.max(rMin,rMax)); - } - - // Calculates value according to pixel position of slider handle - function pixelsToValue(px) { - var val = getValidValue(scale ? percentToValue(pixelsToPercent(px)) : vertical ? max - (Math.round(px / stepPx) * step) : min + (Math.round(px / stepPx) * step)); - - handle.style[vertical ? "top" : "left"] = (px || 0) + "px"; - redrawRange(); - setInputValue((tagName == "select" || step == 1) ? Math.round(val) : val); - } - - // Calculates pixel position according to form element value - function valueToPixels(val, updateInputValue) { - var clearVal = false, - value; - - // Allow empty values for non-polyfill sliders - if((typeof val === "undefined" || isNaN(val) || val === "") && tagName == "input" && !forceValue) { - value = defaultVal; - clearVal = true; - userSet = false; - } else { - value = checkValue(val); - } - - handle.style[vertical ? "top" : "left"] = (scale ? percentToPixels(valueToPercent(value)) : vertical ? Math.round(((max - value) / step) * stepPx) : Math.round(((value - min) / step) * stepPx)) + "px"; - redrawRange(); - if(typeof updateInputValue !== false) { - setInputValue(clearVal ? "" : value); - } - } - - // Rounds a pixel value to the nearest "snap" point on the slider scale - function snapToPxValue(px) { - if(scale) { - return Math.max(Math.min(rMaxPx, px), rMinPx); - } else { - var rem = px % stepPx; - if(rem && rem >= (stepPx / 2)) { - px += (stepPx - rem); - } else { - px -= rem; - } - - if(px < Math.min(Math.abs(rMinPx), Math.abs(rMaxPx))) { - px = Math.min(Math.abs(rMinPx), Math.abs(rMaxPx)); - } else if(px > Math.max(Math.abs(rMinPx), Math.abs(rMaxPx))) { - px = Math.max(Math.abs(rMinPx), Math.abs(rMaxPx)); - } - - return Math.min(Math.max(px, 0), rMaxPx); - } - } - - // Calculates a value according to percentage of distance handle has travelled - function percentToValue(pct) { - var st = 0, - fr = min, - value; - - for(var s in scale) { - if(!scale.hasOwnProperty(s)) { - continue; - } - - if(pct >= st && pct <= +s ) { - value = fr + ((pct - st) * (+scale[s] - fr) ) / (+s - st); - } - - st = +s; - fr = +scale[s]; - } - - return value; - } - - // Calculates the percentage handle position according to form element value - function valueToPercent(value) { - var st = 0, - fr = min, - pct = 0; - - for(var s in scale) { - if(!scale.hasOwnProperty(s)) { - continue; - } - - if(value >= fr && value <= +scale[s]){ - pct = st + (value - fr) * (+s - st) / (+scale[s] - fr); - } - - st = +s; - fr = +scale[s]; - } - - return pct; - } - - function percentToPixels(percent) { - return ((outerWrapper[vertical ? "offsetHeight" : "offsetWidth"] - handle[vertical ? "offsetHeight" : "offsetWidth"]) / 100) * percent; - } - - function pixelsToPercent(pixels) { - return pixels / ((outerWrapper[vertical ? "offsetHeight" : "offsetWidth"] - outerWrapper[handle ? "offsetHeight" : "offsetWidth"]) / 100); - } - - // Sets the form element with a valid value - function setInputValue(val) { - // The update callback doesn't mean the input value has changed - callback("update"); - - // If the user has not set this value or has entered an incorrect value then set a class - // to enable styling of the slider - if(!userSet) { - addClass(innerWrapper, "fd-slider-no-value"); - } else { - removeClass(innerWrapper, "fd-slider-no-value"); - } - - if(tagName == "select") { - try { - val = parseInt(val, 10); - if(inp.selectedIndex === val) { - updateAriaValues(); - return; - } - inp.options[val].selected = true; - } catch (err) {} - } else { - if(val !== "" && !userInput) { - val = (min + (Math.round((+val - min) / step) * step)).toFixed(precision); - } - if(inp.value === val) { - updateAriaValues(); - return; - } - inp.value = val; - } - - updateAriaValues(); - callback("change"); - } - - function checkInputValue(value) { - return !(isNaN(value) || value === "" || value < Math.min(rMin,rMax) || value > Math.max(rMin,rMax)); - } - - function setSliderRange(newMin, newMax) { - if(rMin > rMax) { - newMin = Math.min(min, Math.max(newMin, newMax)); - newMax = Math.max(max, Math.min(newMin, newMax)); - rMin = Math.max(newMin, newMax); - rMax = Math.min(newMin, newMax); - } else { - newMin = Math.max(min, Math.min(newMin, newMax)); - newMax = Math.min(max, Math.max(newMin, newMax)); - rMin = Math.min(newMin, newMax); - rMax = Math.max(newMin, newMax); - } - - if(defaultVal < Math.min(rMin, rMax)) { - defaultVal = Math.min(rMin, rMax); - } else if(defaultVal > Math.max(rMin, rMax)) { - defaultVal = Math.max(rMin, rMax); - } - - handle.setAttribute("aria-valuemin", rMin); - handle.setAttribute("aria-valuemax", rMax); - - checkValue(tagName == "input" ? parseFloat(inp.value) : inp.selectedIndex); - redraw(); - } - - function redrawRange() { - if(noRangeBar) { - return; - } - if(vertical) { - rangeBar.style["height"] = Math.max(1, (bar.offsetHeight - handle.offsetTop)) + "px"; - } else { - rangeBar.style["width"] = Math.max(1, handle.offsetLeft) + "px"; - } - } - - function findLabel() { - var label = false, - labelList = document.getElementsByTagName('label'); - // loop through label array attempting to match each 'for' attribute to the id of the current element - for(var i = 0, lbl; lbl = labelList[i]; i++) { - // Internet Explorer requires the htmlFor test - if((lbl['htmlFor'] && lbl['htmlFor'] == inp.id) || (lbl.getAttribute('for') == inp.id)) { - label = lbl; - break; - } - } - - if(label && !label.id) { - label.id = inp.id + "_label"; - } - - return label; - } - - function updateAriaValues() { - var val = tagName == "select" ? inp.options[inp.selectedIndex].value : inp.value, - valTxt = ariaFormat ? ariaFormat(val) : tagName == "select" ? (inp.options[inp.selectedIndex].text ? inp.options[inp.selectedIndex].text : val) : val; - - handle.setAttribute("aria-valuenow", val); - handle.setAttribute("aria-valuetext", valTxt); - } - - function onInputChange(e) { - userSet = true; - userInput = userSnap; - valueToPixels(tagName == "input" ? parseFloat(inp.value) : inp.selectedIndex); - updateAriaValues(); - userInput = false; - } - - function onReset(e) { - if(tagName == "input") { - inp.value = inp.defaultValue; - } else { - inp.selectedIndex = resetDef; - } - checkValue(tagName == "select" ? inp.options[inp.selectedIndex].value : inp.value); - redraw(); - updateAriaValues(); - } - - // Sets a tabindex attribute on an element, bends over for IE. - function setTabIndex(e, i) { - e.setAttribute(!/*@cc_on!@*/false ? "tabIndex" : "tabindex", i); - e.tabIndex = i; - } - - (function() { - if(html5Shim || hideInput) { - addClass(inp, "fd-form-element-hidden"); - try { - // FF21 hack to change input type to text - if(inp.type != "range" && - getAttribute(inp, "type") == "range" && - document.defaultView.getComputedStyle(inp, null).getPropertyValue("display") == "inline-block") { - inp.type="number"; - } - } catch(err){} - } else { - addEvent(inp, 'change', onInputChange); - } - - // Add stepUp & stepDown methods to input element if using the html5Shim - if(html5Shim) { - inp.setAttribute("fd-range-enabled", 1); - inp.stepUp = function(n) { increment(n||1); }; - inp.stepDown = function(n) { increment(n||-1); }; - - if(useDOMAttrModEvt) { - addEvent(inp, typeof(inp.onpropertychange) == "object" ? "propertychange" : "DOMAttrModified", rescanAttrs); - } - } - - outerWrapper = document.createElement('span'); - outerWrapper.className = "fd-slider" + (vertical ? "-vertical " : " ") + classNames; - outerWrapper.id = "fd-slider-" + inp.id; - - if(vertical && inpHeight) { - outerWrapper.style.height = inpHeight + "px"; - } - - innerWrapper = document.createElement('span'); - innerWrapper.className = "fd-slider-wrapper" + (!html5Shim ? " fd-slider-no-value" : ""); - - ieBlur = document.createElement('span'); - ieBlur.className = "fd-slider-inner"; - - bar = document.createElement('span'); - bar.className = "fd-slider-bar"; - - if(fullARIA) { - handle = document.createElement('span'); - } else { - handle = document.createElement('a'); - handle.setAttribute("href", "#"); - addEvent(handle, "click", stopEvent); - } - - setTabIndex(handle, 0); - - handle.className = "fd-slider-handle"; - handle.appendChild(document.createTextNode(String.fromCharCode(160))); - - innerWrapper.appendChild(ieBlur); - - if(!noRangeBar) { - rangeBar = document.createElement('span'); - rangeBar.className = "fd-slider-range"; - innerWrapper.appendChild(rangeBar); - } - - innerWrapper.appendChild(bar); - innerWrapper.appendChild(handle); - outerWrapper.appendChild(innerWrapper); - - inp.parentNode.insertBefore(outerWrapper, inp); - - if(isOpera || /*@cc_on!@*/!true) { - handle.unselectable = "on"; - bar.unselectable = "on"; - ieBlur.unselectable = "on"; - outerWrapper.unselectable = "on"; - innerWrapper.unselectable = "on"; - if(!noRangeBar) { - rangeBar.unselectable = "on"; - } - } - - // Add ARIA accessibility info programmatically - outerWrapper.setAttribute("role", "application"); - - handle.setAttribute("role", "slider"); - handle.setAttribute("aria-valuemin", tagName == "select" ? inp.options[0].value : min); - handle.setAttribute("aria-valuemax", tagName == "select" ? inp.options[inp.options.length - 1].value : max); - - var lbl = findLabel(); - if(lbl) { - handle.setAttribute("aria-labelledby", lbl.id); - handle.id = "fd-slider-handle-" + inp.id; - /*@cc_on@*/ - /*@if(@_win32) - lbl.setAttribute("htmlFor", handle.id); - @else @*/ - lbl.setAttribute("for", handle.id); - /*@end@*/ - } - - // Are there page instructions - if(document.getElementById(describedBy)) { - handle.setAttribute("aria-describedby", describedBy); - } - - // Is the form element initially disabled - if(inp.getAttribute("disabled") === true || inp.getAttribute("disabled") == "disabled") { - disableSlider(true); - } else { - enableSlider(true); - } - - // Does an initial form element value mean the user has set a valid value? - // Also called onload in case browsers have automatically set the input value - if(varSetRules.onvalue) { - userSet = true; - checkValue(tagName == "input" ? parseFloat(inp.value) : inp.selectedIndex); - } - - // Catch form reset events - if(inp.form) { - addEvent(inp.form, "reset", onReset); - } - - updateAriaValues(); - callback("create"); - redraw(); - })(); - - return { - onResize: function(e) { if(outerWrapper.offsetHeight != sliderH || outerWrapper.offsetWidth != sliderW) { redraw(); } }, - destroy: function() { destroySlider(); }, - reset: function() { valueToPixels(tagName == "input" ? parseFloat(inp.value) : inp.selectedIndex); }, - stepUp: function(n) { increment(Math.abs(n)||1); }, - stepDown: function(n) { increment(-Math.abs(n)||-1); }, - increment: function(n) { increment(n); }, - disable: function() { disableSlider(); }, - enable: function() { enableSlider(); }, - setRange: function(mi, mx) { setSliderRange(mi, mx); }, - getValueSet: function() { return !!userSet; }, - setValueSet: function(tf) { valueSet(tf); }, - rescan: function() { rescanAttrs(); }, - checkValue: function() { if(varSetRules.onvalue) { userSet = true; checkValue(tagName == "input" ? parseFloat(inp.value) : inp.selectedIndex); } updateAriaValues(); redraw(); } - }; - } - - addEvent(window, "load", init); - addEvent(window, "load", function() { setTimeout(function() { var slider; for(slider in sliders) { sliders[slider].checkValue(); } }, 0); }); - addEvent(window, "resize", resize); - addEvent(window, "unload", unload); - - // Have we been passed JSON within the including script tag - (function() { - var scriptFiles = document.getElementsByTagName('script'), - json = parseJSON(String(scriptFiles[scriptFiles.length - 1].innerHTML).replace(/[\n\r\s\t]+/g, " ").replace(/^\s+/, "").replace(/\s+$/, "")); - - if(typeof json === "object" && !("err" in json)) { - affectJSON(json); - } - })(); - - // Add oldie class if needed for IE < 9 - /*@cc_on@*/ - /*@if (@_jscript_version < 9) - addClass(document.documentElement, "oldie"); - /*@end@*/ - - return { - rescanDocument: init, - createSlider: function(opts) { return createSlider(opts); }, - onDomReady: function() { onDomReady(); }, - destroyAll: function() { destroyAllsliders(); }, - destroySlider: function(id) { return destroySingleSlider(id); }, - redrawAll: function() { resize(); }, - addEvent: addEvent, - removeEvent: removeEvent, - stopEvent: stopEvent, - increment: function(id, numSteps) { if(!sliderExists(id)) { return false; } sliders[id].increment(numSteps); }, - stepUp: function(id, n) { if(!sliderExists(id)) { return false; } sliders[id].stepUp(Math.abs(n)||1); }, - stepDown: function(id, n) { if(!sliderExists(id)) { return false; } sliders[id].stepDown(-Math.abs(n)||-1); }, - setRange: function(id, newMin, newMax) { if(!sliderExists(id)) { return false; } sliders[id].setRange(newMin, newMax); }, - updateSlider: function(id) { if(!sliderExists(id)) { return false; } sliders[id].onResize(); sliders[id].reset(); }, - disable: function(id) { if(!sliderExists(id)) { return false; } sliders[id].disable(); }, - enable: function(id) { if(!sliderExists(id)) { return false; } sliders[id].enable(); }, - getValueSet: function() { return getValueSet(); }, - setValueSet: function(a, tf) { if(!sliderExists(id)) { return false; } setValueSet(a, tf); }, - setGlobalVariables: function(json) { affectJSON(json); }, - removeOnload: function() { removeOnLoadEvent(); }, - rescanAttributes: rescanAttributes - }; -})(); diff --git a/static/dist/scripts/graphs.js b/static/dist/scripts/graphs.js deleted file mode 100644 index 7c05998..0000000 --- a/static/dist/scripts/graphs.js +++ /dev/null @@ -1,186 +0,0 @@ -/* Extend jquery */ -(function ( $ ) { - $.fn.graph = function(action, options) { - // These are the defaults - var settings = $.extend({ - width: undefined, - height: undefined, - animation_duration: 1000 // ms - }, options ); - /* The slug of each Graph object map to a function in the graphs object */ - var graphs = { - treatment: function(element) { - $(element).highcharts({ - chart: { - type: 'column', - width: settings.width, - height: settings.height, - animation: { - duration: settings.animation_duration - } - }, - title: { - text: 'Antall behandlinger' - }, - xAxis: { - title: { - text: 'År' - }, - minRange : 30 * 24 * 3600 * 1000, // - minTickInterval: 12 * 30 * 24 * 3600 * 1000, // A year - type: 'datetime' - }, - yAxis: { - title: { - text: 'Antall behandlinger' - } - - }, - series: [{ - name: 'Antall behandlinger', - data: [ - [Date.UTC(2007, 1), 35000], - [Date.UTC(2008, 1), 40000], - [Date.UTC(2009, 1), 60000], - [Date.UTC(2010, 1), 67000], - [Date.UTC(2011, 1), 70000], - [Date.UTC(2012, 1), 78000], - [Date.UTC(2013, 1), 97000], - [Date.UTC(2014, 1), 109000]], - enabled: false - - }], - legend: { - enabled: false - } - }); - }, - treatment_distribution: function(element) { - var last_year = new Date().getFullYear() - 1; - $(element).highcharts({ - chart: { - type: 'column', - width: settings.width, - height: settings.height, - animation: { - duration: settings.animation_duration - } - }, - title: { - text: 'Fordeling behandlinger' - }, - xAxis: { - title: { - text: 'Måned' - }, - minRange : 30 * 24 * 3600 * 1000, // - minTickInterval: 12 * 30 * 24 * 3600 * 1000, // A year - type: 'datetime' - }, - yAxis: { - title: { - text: 'Fordeling' - } - - }, - series: [{ - name: 'Preeksisterende', - data: [ - [Date.UTC(last_year, 0), 2], - [Date.UTC(last_year, 1), 5], - [Date.UTC(last_year, 2), 10], - [Date.UTC(last_year, 3), 20], - [Date.UTC(last_year, 4), 40], - [Date.UTC(last_year, 5), 70], - [Date.UTC(last_year, 6), 40], - [Date.UTC(last_year, 7), 40], - [Date.UTC(last_year, 8), 40]] - }, - { - name: 'Nye lidelser', - data: [ - [Date.UTC(last_year, 0), 8], - [Date.UTC(last_year, 1), 10], - [Date.UTC(last_year, 2), 15], - [Date.UTC(last_year, 3), 18], - [Date.UTC(last_year, 4), 20], - [Date.UTC(last_year, 5), 30], - [Date.UTC(last_year, 6), 40], - [Date.UTC(last_year, 7), 40], - [Date.UTC(last_year, 8), 40]] - }], - plotOptions: { - column: { - stacking: 'normal' - } - } - }); - }, - num_insured: function(element) { - $(element).highcharts({ - chart: { - type: 'column', - width: settings.width, - height: settings.height, - animation: { - duration: settings.animation_duration - } - }, - title: { - text: 'Antall forsikrede (behandlingsforsikring) per 30. juni 2003-2014' - }, - xAxis: { - title: { - text: 'År' - }, - tickInterval: Date.UTC(1902, 0, 1) - Date.UTC(1901, 0, 1), // A year - year: '%Y', - type: 'datetime' - }, - yAxis: { - title: { - text: 'Antall forsikrede' - } - - }, - series: [{ - name: 'Antall forsikrede', - data: [ - [Date.UTC(2003, 0), 14587], - [Date.UTC(2004, 0), 20634], - [Date.UTC(2005, 0), 35418], - [Date.UTC(2006, 0), 42073], - [Date.UTC(2007, 0), 74435], - [Date.UTC(2008, 0), 97661], - [Date.UTC(2009, 0), 115651], - [Date.UTC(2010, 0), 141742], - [Date.UTC(2011, 0), 233739], - [Date.UTC(2012, 0), 357468], - [Date.UTC(2013, 0), 404320], - [Date.UTC(2014, 0), 437137]], - enabled: false - - }], - legend: { - enabled: false - } - }); - } - }; - - /* What do do? */ - if(action == 'load') { - /* For each element get attr and load appropriate graph */ - return this.each(function() { - var slug = $(this).attr('data-graph-slug'); - // Create a graphs[slug] of this. - graphs[slug](this); - }); - } else if(action == 'get') { - /* Not used - return Highcharts.charts[loaded_graphs[slug].data('highchartsChart')]; - */ - } - }; - -}( jQuery )); diff --git a/static/dist/scripts/presentation_edit.js b/static/dist/scripts/presentation_edit.js deleted file mode 100644 index 4ce5f7a..0000000 --- a/static/dist/scripts/presentation_edit.js +++ /dev/null @@ -1,121 +0,0 @@ -function get_offset(col, grid_height, min_widget_height) { - var num_slides = $('.slide[data-col="'+ col +'"]').length; - return (grid_height - (num_slides * min_widget_height)) * -1; -} - -/* Push add buttons up x px, close to the lowest slide in its section */ -function reposition_add_buttons(min_widget_height) { - var max_rows = _.max($(".slide"), function(slide){ return parseInt($(slide).attr('data-row')); }); - var grid_height = $(max_rows).attr('data-row') * min_widget_height; - - $(".slide-add").each(function() { - var offset = get_offset($(this).attr('data-col'), grid_height, min_widget_height); - $(this).css({ top: offset }); - }); -} -$(function(){ - // TODO: on document ready, to load: loading icon - var margin_x = 8; - var margin_y = 4; - var csrf_token = $.cookie('csrftoken'); - var grid = $(".gridster ul").gridster({ - widget_selector: "li.slide", - widget_margins: [margin_x, margin_y], - widget_base_dimensions: [113, 80], - min_cols: 6, - serialize_params: function($w, wgd) { - return { - slide: $w.attr('data-slide'), - section: $('.sections li[data-col="'+ wgd.col +'"]').attr('data-section'), - order: wgd.row - }; - }, - draggable: { - // https://github.com/ducksboard/gridster.js/issues/161 - handle: 'img', // FIXME: Edit link is not working on touch - stop: function() { - /* reposition add buttons */ - reposition_add_buttons(this.min_widget_height); - - /* Save grid order */ - var grid = this.serialize_changed(); - - var slides = []; - for(var i in grid ) { - slides.push({ name: "slide-order-"+grid[i].slide, value: grid[i].order }); - slides.push({ name: "slide-section-"+grid[i].slide, value: grid[i].section }); - } - /* Prepare data */ - var data = $("#presentation-form").serializeArray(); - data = data.concat(slides); - /* http post json */ - var url = $("#presentation").attr('data-save-url'); - $.ajax({ - type: "POST", - url: url, - data: data, - async: false, // FIXME: Make async - headers: { - 'X-CSRFToken': csrf_token - }, - success: function (result,l,o) { - if(result !== undefined && result.success) { - /* redirect to edit url */ - window.location = "/slideshow/" + result.presentation_id + "/edit/"; - } else { - //console.log("Saved"); //FIXME notify - } - }, - error: function (request, text_status, error_thrown) { - console.log("uffda..."); //FIXME notify - } - }); - } - } - }); - /* Note: gridster api add, remove, serialize */ - var gridster = grid.data('gridster'); - - /* reposition add buttons */ - reposition_add_buttons(gridster.min_widget_height); - - /* Datepicker */ - $("#id_datetime").datepicker({ - dateFormat: "yy-mm-dd" - }); - /* Disable slide controls */ - $(".slide-toggle").on('click', function(e) { - /* Set slide.active=false */ - var that = $(this); - var current_slide = $(this).parent().parent(); - var new_state = current_slide.hasClass("disabled"); - var url = $(this).attr('data-save-url'); - $.ajax({ - type: "PATCH", - url: url, - data: { - active: new_state - }, - headers: { - 'X-CSRFToken': csrf_token - }, - success: function (result,l,o) { - - /* toggle 'disabled' class */ - current_slide.toggleClass("disabled"); - /* switch icons class */ - var icon = that.find("i"); - if(icon.hasClass("fa-square-o")) { - icon.removeClass("fa-square-o").addClass("fa-check-square-o"); - } else { - icon.removeClass("fa-check-square-o").addClass("fa-square-o"); - } - }, - error: function (request, text_status, error_thrown) { - console.log("uffda..."); //FIXME notify - } - }); - - }); - -}); \ No newline at end of file diff --git a/static/dist/scripts/presentation_list.js b/static/dist/scripts/presentation_list.js deleted file mode 100644 index 5edc624..0000000 --- a/static/dist/scripts/presentation_list.js +++ /dev/null @@ -1,9 +0,0 @@ - -$(function(){ - //var options = { -    // valueNames: [ 'region', 'hospital', 'city', 'diagnose', 'waittime' ] -    //}; - -    //var featureList = new List('presentation-table-sortable', options); - //featureList.sort('waittime', { asc: false }); -}); diff --git a/static/dist/scripts/product_calculator.js b/static/dist/scripts/product_calculator.js deleted file mode 100644 index 1036188..0000000 --- a/static/dist/scripts/product_calculator.js +++ /dev/null @@ -1,541 +0,0 @@ -$(document).ready( function() { - /* Slide: Product calculator */ - /* - * TODO: set discount based on url or user/session data - * - * */ - function set_progress(percent) { - if( percent < 1 || percent > 100 ) { - return; - } - $(".stb-progress .meter").css('width', percent+"%"); - } - function product_select(products, treatments, counceling) { - /* Searches products and returns the correct price */ - //console.log(products, treatments, counceling); - var selected = products; - if(counceling !== undefined) { - selected = _.filter(selected, function(product) { - return product.counceling_service == counceling; - }); - } - if(selected.length == 1) { - return selected[0]; - } - if(treatments !== undefined) { - selected = _.filter(selected, function(product) { - return product.treatments == treatments; - }); - } - if(selected.length == 1) { - return selected[0]; - } - //console.log("Fant ingen produkter, returnerer siste"); - return products[products.length-1]; - } - //function filter_product_risk(documents, product_order) { - // /* filter based on product risk variables */ - // var product_risk_variable_attrs = [ - // 'eligible_industry_discount', - // 'has_existing_insurance', - // 'employees', - // 'addon_psychiatric_treatment']; - - // /* which variables are set? */ - // var product_risk_variables = _.filter(product_risk_variable_attrs, function(attr) { - // return product_order[attr] !== undefined; - // }); - // //console.log("product risk variables: ", product_risk_variables); - - // /* filter based on vars in product_risk_variables and product_order - // * all must match */ - // documents = _.filter(documents, function(doc){ - // //console.log("looking at: ", doc.name, "(", doc.id, ")"); - // // filter when not specified - // if(!doc.product_risk_variables.length) { - // return false; - // } - - // /* Loop over the product_risks attached to this document */ - // var doc_matches = _.map(doc.product_risk_variables, function(variables, index, list) { - // /* Loop over each variable in the list of risks */ - // var var_matches = _.map(product_risk_variables, function(element) { - // //console.log("looping document risk vars: ", element, product_order[element], variables[element], variables); - // // num employees special case - // if(element == 'employees' && (product_order[element] > variables['employees_max'] || product_order[element] < variables['employees_min'])) { - // return false - // } - // else if(product_order[element] != variables[element] && element != 'employees') { - // return false; // drop document - // } - // return true; - // }); - // // All attributes in the product_order must match with variables - // return _.every(var_matches); - // }); - // // Need just one match to keep the document - // return _.some(doc_matches); - // }); - // return documents; - //} - //function filter_individual_risk(documents, product_order) { - // //console.log("individual risk variables: ", product_order.individual_term_employees); - // /* Filter based on age ranges */ - // var ages = _.map(product_order.individual_term_employees, function(employee) { - // return employee.age; - // }); - // /* Filter documents not referencing at least one individual risk variable matching the specified ages */ - // documents = _.filter(documents, function(doc) { - // // filter when not specified - // // Note: Unsure if this is correct - // if(!doc.employee_risk_variables.length) { - // return false; - // } - // var matches = _.map(doc.employee_risk_variables, function(variables, index, list) { - // var age_matches = _.map(ages, function(age) { - // return age >= variables.age_min && age <= variables.age_max; - // }); - // return _.some(age_matches); // matching at least one age - // }); - // return _.some(matches); //matching at least one risk variable - // }); - // return documents; - //} - //function filter_documents(documents, product_order) { - // /* Filter based on product selection - // * Note: only filters by product if below 100 employees */ - // if(product_order.employees < 100) { - // var documents = _.filter(documents, function(doc){ - // var product_ids = _.map(doc.products, function(product) { return product.id; }); - // return _.contains(product_ids, product_order.product.id); - // }); - - // if(product_order.employees >=1 && product_order.employees <= 4 && !product_order.eligible_industry_discount) { - // documents = filter_individual_risk(documents, product_order); - // } - // else { - // documents = filter_product_risk(documents, product_order); - // } - // } else { - // /* Filter based on dummy no-product */ - // documents = _.filter(documents, function(doc){ - // var product_slugs = _.map(doc.products, function(product) { return product.slug; }); - // return _.contains(product_slugs, 'no-product'); - // }); - // - // } - // return documents; - // - //} - //function update_document_list(documents) { - // if(documents.length == 0) { - // $(".product-calculator .documents-table").html("Fillern, det er ingen dokumenter knyttet til dette produktet og valgte variable :'("); - // return; - // } - // var html = ""; - // _.each(documents, function(doc) { - // html += ''; - // }); - // html += "
    NavnType
    '+ doc.name +''+ doc.category +'
    "; - // $(".product-calculator .documents-table").html(html); - //} - function get_price_individual(product, product_order) { - /* Need a valid product */ - if(product === undefined || product.employee_risk_variables.length === 0) { - return -1; - } - /* Invidual risk */ - var has_existing_insurance = false; - if( product_order.has_existing_insurance !== undefined) { - has_existing_insurance = product_order.has_existing_insurance; - } - /* Get list of prices for each employee */ - var prices = _.map(product_order.individual_term_employees, function(employee) { - /* Filter by employee-age */ - var variation = _.find(product.employee_risk_variables, function(variation) { - if(employee.age >= variation.age_min && employee.age <= variation.age_max) { - return true; - } - return false; - }); - return variation.price; - }); - return prices; - } - - function get_price(product, product_order) { - /* Group risk */ - var price = 0; - var has_existing_insurance = false; - if( product_order.has_existing_insurance !== undefined) { - has_existing_insurance = product_order.has_existing_insurance; - } - - /* Filter by boolean values */ - var variations = _.where(product.product_risk_variables, { - eligible_industry_discount: product_order.eligible_industry_discount, - has_existing_insurance: has_existing_insurance, - }); - /* Filter by num employees */ - variation = _.filter(variations, function(variation) { - if(variation.employees_max == product_order.employees ) { - return true; - } - }); - if(variation.length >= 1) { - price = parseInt(variation[0].price); - } else { - /* Error: Missing product data in db */ - price = -1; - } - /* include price for psychiatric treatment addon */ - // FIXME price is static. - if(product_order.addon_psychiatric_treatment !== undefined && product_order.addon_psychiatric_treatment) { - price += 204; - } - - return price; - } - function product_recalc(products, product_order) { - var product = product_select( - products, - product_order.treatments, - product_order.counceling); - - /* calculate price based in product and current risk data */ - var price_formatted; - - if(product_order.employees <= 4 && ! product_order.eligible_industry_discount) { - var prices = get_price_individual(product, product_order); - var sum = _.reduce(prices, function(memo, num) { return memo + parseInt(num); }, 0); - if(sum === 0) { - price_formatted = "Prøv andre valg, ingen pris funnet."; - } else { - if(prices.length == 1) { - price_formatted = "NOK " + sum + ",- per måned"; - } else { - price_formatted = prices.join(" + ")+" = NOK " + sum + ",- per måned"; - } - } - } else { - price = get_price(product, product_order); - if(price == -1) { - price_formatted = "Prøv andre valg, ingen pris funnet."; - } else { - price_formatted = "NOK " + price + ",- per år"; - } - } - product_order.product = product; - $("[data-prodcalc-product]").text(product.name); - $("[data-prodcalc-product-price]").text(price_formatted); - } - //function update_relevant_documents(product_order) { - - // var url = $(".product-calculator[data-documents-url]").attr('data-documents-url'); - // $.ajax({ - // url: url, - // method: 'GET', - // dataType: 'json', - // headers: { - // 'X-CSRFToken': $("[name=csrfmiddlewaretoken]").val() - // }, - // success: function(documents) { - // /* Present only the right documents, ordered by category */ - // //console.log("fetched the following documents:", documents); - // //console.log("filtering based on product_order", product_order); - - // var less_documents = filter_documents(documents, product_order); - // //console.log("returned these documents:", less_documents); - // update_document_list(less_documents); - // } - // }); - //} - - if($(".product-calculator").length) { - /* product_order stores the state of the order */ - var product_order = {}; - var product_order_steps = {}; - var num_product_order_steps = 6; - - /* Is the industry discount disabled? */ - if ( $('.product-calculator[data-disable-industry-discount]').length ) { - product_order.eligible_industry_discount = false; - $("[data-key=treatments][data-value=5]").show(); - } - - /* General layout of steps when user interacts with page: - * - update product_order state - * - update progress based on state - * - update the dom with the correct display state (button state, step description) - * - find product based on selection - * - calculate price based on discounts, selection and product - */ - - $.getJSON('/products.json', function(products) { - /* Attach to buttons and fields */ - - /* On every answer change */ - $("[data-answer]").on('click', function(e) { - var key = $(this).attr('data-key'); - var value = $(this).attr('data-value'); - - /* to_javascript */ - if (value == "no") { - value = false; - } - else if(value == "yes") { - value = true; - } - if(key == "treatments" || key == "employees") { - value = parseInt(value); - } - - /* limit options and change display */ - /* based on employees */ - if(key == "employees") { - if( value >= 20) { - if(product_order.has_exisiting_insurance === undefined) { - $(".modal-has-existing-insurance").foundation('reveal', 'open'); - } - } else { - /* Reset answer */ - delete product_order.has_exisiting_insurance; - $(".modal-has-existing-insurance button").removeClass("selected disabled"); - } - - var min_value = $(this).attr('data-min'); - /* if between 1 and 4 then.. */ - if( value <= 4 && min_value >= 1 && !product_order.eligible_industry_discount) { - /* display individual employee risk container */ - $(".individual-pricing-container").fadeIn('fast'); - /* Note: Fetching employee ages before anyone have been selected */ - update_employee_ages(); - } else { - $(".individual-pricing-container").fadeOut('fast'); - $("[data-key=treatments][data-value=12]").show(); - } - /* Next button */ - $("[data-goto-part=part-two]").fadeIn('fast'); - } - /* based on industry deal */ - if(key == "eligible_industry_discount") { - if(value) { - /* limit num treatments*/ - $("[data-key=treatments][data-value=5]").hide(); - } else { - $("[data-key=treatments][data-value=5]").show(); - } - if( !value && product_order.employees <= 4 && product_order.employees >= 1) { - $(".individual-pricing-container").fadeIn('fast'); - } else { - $(".individual-pricing-container").fadeOut('fast'); - } - - $(".prod-num-staff").fadeIn('fast'); - $(".part-one-zero").fadeOut('fast'); - setTimeout(function() { - $(".part-one-one").fadeIn('fast'); - }, 400); - } - /* based on counceling */ - if(key == "counceling") { - $(".prod-num-treatments").fadeIn('fast'); - $(".about-num-treatments").fadeIn('fast'); - if(value) { - /* limit num treatments and auto-select 24 */ - $("[data-key=treatments][data-value=5], [data-key=treatments][data-value=0]").hide(); - product_order.treatments = 24; - product_order_steps.treatments = 24; - $("[data-key=treatments]").removeClass("selected disabled"); - $("[data-key=treatments][data-value=24]").addClass("selected"); - /* update coverage */ - $(".coverage-treatments").text(product_order.treatments); - $(".selected-coverage .topp, .selected-coverage .treatments").fadeIn('fast'); - } else { - /* show all treatments, except 0 if industry deal */ - if( !product_order.eligible_industry_discount ) { - $("[data-key=treatments][data-value=5]").show(); - } - // FIXME: missing pricing data, just hide this option for now - if(product_order.employees <= 4) { - $("[data-key=treatments][data-value=0]").hide(); - } else { - $("[data-key=treatments][data-value=0]").show(); - } - $(".selected-coverage .topp").fadeOut('fast'); - } - } - /* based on addon_psychiatric_treatment */ - if(key == "addon_psychiatric_treatment") { - $(".prod-num-treatments").fadeIn('fast'); - $(".about-num-treatments").fadeIn('fast'); - $(".selected-coverage .counceling").fadeOut('fast'); - if(value) { - /* limit num treatments and auto-select 24 */ - $("[data-key=treatments][data-value=0]").hide(); - product_order.treatments = 24; - product_order_steps.treatments = 24; - $("[data-key=treatments]").removeClass("selected disabled"); - $("[data-key=treatments][data-value=24]").addClass("selected"); - /* update coverage */ - $(".coverage-treatments").text(product_order.treatments); - $("[data-prodcalc-addon]").text("med psykologi"); - $(".selected-coverage .treatments").fadeIn('fast'); - $(".selected-coverage .topp, .selected-coverage .psychology").fadeIn('fast'); - } else { - $(".selected-coverage .topp").fadeOut('fast'); - $("[data-prodcalc-addon]").text(""); - $("[data-key=treatments][data-value=0]").show(); - } - } - /* based on num treatments */ - if(key == "treatments") { - /* update coverage */ - if(value > 0) { - $(".selected-coverage .treatments").fadeIn('fast'); - $(".coverage-treatments").text(value); - } else if(value === 0) { - $(".selected-coverage .topp").fadeOut('fast'); - $(".selected-coverage .treatments").fadeOut('fast'); - $(".coverage-treatments").text(value); - } else { - $(".selected-coverage .treatments:visible").fadeOut('fast'); - } - } - - /* Update current answers. - * ie. industry discount, number of treatments, counceling and addon_psychiatric_treatment - */ - product_order[key] = value; - product_order_steps[key] = value; - - $(this).addClass("selected").removeClass("disabled"); - $("[data-key="+ key +"]").not(this).removeClass("selected").addClass("disabled"); - product_recalc(products, product_order); - /* total questions by number by answered questions */ - var current_progress = _.size(product_order_steps) / parseFloat(num_product_order_steps) * 100; - set_progress(current_progress); - }); - - /* Go on to the section after this one */ - $("[data-goto-part]").on('click', function(e) { - product_recalc(products, product_order); - var part = $(this).attr('data-goto-part'); - - - /* Product tailoring */ - if(part == 'part-two' && product_order.employees < 100) { - //console.log(product_order); - $(".part-zero, .part-one-right-container").fadeOut('fast'); - setTimeout(function() { - if(product_order.eligible_industry_discount) { - /* Don't ask for counceling, and set it to false */ - product_order.counceling = false; - $(".addon_psychiatric_treatment").fadeIn('fast'); - $(".about-addon-psychiatric-treatment").fadeIn('fast'); - $(".about-counceling").hide(); - } else { - $(".part-two .counceling").fadeIn('fast'); - // FIXME remove this if business rules are valid - //if(product_order.employees >= 20 && product_order.employees <= 99) { - // $(".about-num-treatments").fadeIn('fast'); - // $(".prod-num-treatments").fadeIn('fast'); - //} else { - // $(".part-two .counceling").fadeIn('fast'); - //} - } - $(".part-two-and-a-half-container").fadeIn('fast'); - $(".part-two").fadeIn('fast'); - if(product_order.has_exisiting_insurance) { - $(".part-two-right .need-stats").show(); - } else { - $(".part-two-right .need-stats").hide(); - } - }, 500); - } - /* Skip product tailoring */ - if( part == 'part-two' && product_order.employees >= 100) { - set_progress(100); - /* Get relevant product documents */ - //update_relevant_documents(product_order); - /* Show documents tab */ - $(".part-zero, .part-one-right-container").fadeOut('fast'); - setTimeout(function() { - if(product_order.has_exisiting_insurance) { - $(".part-three-special .need-stats").show(); - } else { - $(".part-three-special .need-stats").hide(); - } - $(".part-three-special").fadeIn('fast'); - }, 500); - } - - - /* "We recommend the product..." */ - if(part == 'part-two-and-a-half') { - $(".part-two-right").fadeOut('fast'); - $(".select-product-btn").fadeIn('fast'); - setTimeout(function() { - $(".part-two-and-a-half").fadeIn('fast'); - }, 500); - } - - - - /* Document "checkout" - fancy schmancy */ - if( part == 'part-three') { - set_progress(100); - /* Get relevant product documents */ - //update_relevant_documents(product_order); - - /* Show documents tab */ - $(".part-two, .part-one").fadeOut('fast'); - setTimeout(function() { - $(".part-two-and-a-half").parent().removeClass("small-7").addClass("small-12"); - $(".eula-container").removeClass("small-7").addClass("small-4"); - $(".product-description-inner").removeClass("small-5").addClass("small-3"); - $(".part-three").fadeIn('fast'); - }, 300); - $('[data-goto-part="part-three"]').fadeOut('fast'); - } - }); - - /* Update the product_order with individual employee ages */ - function update_employee_ages() { - var employees = []; - var i = 1; - $(".individual-pricing-container select.age-select-dropdown:visible").each(function(j, el) { - age = parseInt($(el).val().split(" -")[0]); - employees.push({ id: i, age: age }); - i++; - }); - product_order.individual_term_employees = employees; - } - $(".individual-pricing-container select.age-select-dropdown").on('change', update_employee_ages); - - /* add html for individual employee risk */ - $(".individual-pricing-container").on('click', "[data-add-new-employee]", function(e) { - e.preventDefault(); - /* No more than set amount */ - if( $(".person:visible").length == 4) { - return; - } - $(this).parent().next().fadeIn({ complete: update_employee_ages }); - }); - /* remove html for individual employee risk */ - $(".individual-pricing-container").on('click', "[data-remove-employee]", function(e) { - e.preventDefault(); - /* At least 1 */ - if( $(".person:visible").length == 1) { - return; - } - $(this).parent().fadeOut({ complete: update_employee_ages }); - }); - - /* Close modal on answer */ - $('[data-key="has_exisiting_insurance"]').on('click', function() { - $("#modal-has-existing-insurance").foundation('reveal', 'close'); - }); - }); - } -}); diff --git a/static/dist/scripts/slide_edit.js b/static/dist/scripts/slide_edit.js deleted file mode 100644 index de812fd..0000000 --- a/static/dist/scripts/slide_edit.js +++ /dev/null @@ -1,276 +0,0 @@ -$(function() { - /* Save part urls - * Ref: urls.py */ - var urls = { - slide_part_save: '/api/slide/part/', - slide_title_save: '/api/slide/{slide_id}/title/', - slide_part_update: '/api/slide/part/{part_id}/', - slide_part_remove: '/api/slide/part/{part_id}/', - image_save: '/api/image/' - }; - var slide_id = $("#slide").attr('data-slide-id'); - var csrf_token = $.cookie('csrftoken'); - - /* Editor fields */ - var elements = document.querySelectorAll('[data-type="text"], [data-type="html"], [data-type="wysihtml5"]'); - var mediumOptions = { - buttons: ['bold', 'italic', 'header1', 'header2', 'quote', 'anchor', 'unorderedlist', 'orderedlist', 'removeFormat'] - }; - var editor = new MediumEditor(elements, mediumOptions); - editor.subscribe('blur', function(event, el) { - var type = $(el).attr('data-type'); - var name = $(el).attr('data-name'); - var url = $(el).attr('data-url'); - var pk = $(el).attr('data-pk'); - var method = 'POST'; - - if (pk.length > 0 && name != 'slide-title') { - url = urls.slide_part_update.replace('{part_id}', pk); - method = 'PUT'; - } - - var value = el.innerHTML; - if(type == 'text') { - value = el.textContent; - } - var data = { - slide_id: slide_id, - pk: pk, - name: name, - value: value - }; - $.ajax({ - method: method, - headers: { - 'X-CSRFToken': csrf_token - }, - type: 'POST', - url: url, - data: JSON.stringify(data), - contentType : 'application/json' - }).done(function() { - // TODO set pk on part - // $('[data-name="part-' + response.part_created_name + '"]').attr('data-pk', response.part_created_pk); - }).fail(function() { - console.log("boo"); - }); - - }); - $('[data-type="dynamic"]').on('changed', function(e) { - /* Delete part */ - if($(this).attr('data-part-remove')) { - var that = this; - $.ajax({ - url: urls.slide_part_remove.replace('{part_id}', $(this).attr('data-pk')), - method: 'DELETE', - headers: { - 'X-CSRFToken': csrf_token - }, - success: function(response, newValue) { - $(that).removeAttr('data-part-remove'); - $(that).attr('data-pk', ''); - } - }); - return; - } - /* Create or update part */ - var value = ''; - var type = ''; - - if($(this).find('img').length) { - value = $($(this).find('img')[0]).attr('data-pk'); - type = 'image'; - } - else if($(this).find('[data-graph-pk]').length) { - value = $($(this).find('[data-graph-pk]')[0]).attr('data-graph-pk'); - type = 'graph'; - } - else { - console.log("Could not determine Part-type."); - return; - } - - var slide_pk = $(this).attr('data-pk'); - var url = urls.slide_part_save; - var method = 'POST'; - - if (slide_pk.length > 0) { - url = urls.slide_part_update.replace('{part_id}', slide_pk); - method = 'PUT'; - } - - $.ajax({ - url: url, - method: method, - dataType: 'json', - data: { - name: $(this).attr('data-name'), - value: value, - type: type, - slide_id: $("#slide").attr('data-slide-id'), - href: $(this).find('a').attr('href') - }, - headers: { - 'X-CSRFToken': csrf_token - }, - success: function(response, newValue) { - if(response !== undefined && response.part_name && response.part_pk) { - $('[data-name="part-' + response.part_name + '"]').attr('data-pk', response.part_pk); - } - } - }); - }); - - /* - * Gallery - */ - // Ref: https://github.com/blueimp/jQuery-File-Upload - // https://github.com/blueimp/jQuery-File-Upload/wiki/Options - $('#id_file').fileupload({ - dataType: 'json', - url: urls.image_save, - done: function(e, data) { - // add image in gallery - $(".gallery ul").prepend('
  • '+ data.result.name +'
  • '); - // click event - $(".gallery ul li:first-child").click(function (e) { - $(this).siblings().removeClass("selected"); - $(this).toggleClass("selected"); - }); - $("#progress .bar").fadeOut('slow'); - }, - fail: function(e, data) { - console.log("Failed uploading file: ",e, data); - }, - headers: { - 'X-CSRFToken': csrf_token, - 'cache-control': 'no-cache' - }, - send: function(e, data) { - $('#progress .bar').css('width', '0%'); - $("#progress .bar").show(); - }, - progressall: function (e, data) { - var progress = parseInt(data.loaded / data.total * 100, 10); - $('#progress .bar').css( - 'width', - progress + '%' - ); - } - }); - /* Green select */ - $(".image-select").not(".placeholder").click(function (e) { - $(this).siblings().removeClass("selected"); - $(this).toggleClass("selected"); - - }); - /* Insert image */ - $('[data-type="dynamic"]').each(function(i, el) { - /* Insert image-button */ - var button_area = '
    '; - var image_button = ''; - $(el).wrap('
    '); - $(el).after(button_area); - $('[data-buttons-for="'+ $(el).attr('data-name') +'"]').append(image_button); - }); - - $('[data-reveal-id="gallery-modal"]').click( function(e) { - /* Store where to but the image from the modal in the modal */ - var replacing = $(this).attr('data-replace'); - $(".image-insert-btn").attr('data-replacing', replacing); - }); - $(".image-insert-btn").click(function(e) { - var img = $(".gallery .selected img"); - if(!img.length) { - // nothing selected - return; - } - var replacing = $(this).attr('data-replacing'); - var part = $('[data-name="'+ replacing +'"]'); - part.html(''); - part.find('img').attr('data-pk', img.attr('data-pk')); - part.trigger('changed'); - $("#gallery-modal").foundation('reveal', 'close'); - $('.image-select').removeClass("selected"); - }); - /* DELETE image part */ - $("[data-remove-image]").click(function(e) { - var replacing = $('.image-insert-btn').attr('data-replacing'); - var part = $('[data-name="'+ replacing +'"]'); - part.attr('data-part-remove','1'); - part.html(''); - part.trigger('changed'); - $('.image-select').removeClass("selected"); - $("#gallery-modal").foundation('reveal', 'close'); - }); - - /* Link between slides */ - /* ...for "dynamic" areas */ - $('[data-type="dynamic"]').each(function(i, el) { - /* Insert link-button on images */ - var last_button = $(el).siblings().find("a:last-child"); - last_button.after(''); - }); - - /* Set element target on modal */ - $('[data-url-target]').click( function(e) { - var target = $(this).attr('data-url-target'); - if(!$('[data-name="' + target + '"]').find('img').length) { - /* if there is no image, dont link to nothing */ - e.stopPropagation(); - return; - } - $(".modal-links").attr('data-wrapping', target); - }); - - $("[data-is-slide-link]").click(function(e) { - e.preventDefault(); - if($(this).attr('data-get-value-from-id')) { - /* Insert own link via input-field */ - var input_id = $(this).attr('data-get-value-from-id'); - $(this).attr('href', $("#"+input_id).val()); - } - var link = $(this).attr('href'); - var wrapping = $(".modal-links").attr('data-wrapping'); - var el_target = $('[data-name="'+ wrapping +'"]'); - // replace href in targets children if it exists - var potential_link = el_target.children(); - if(potential_link.is('a')) { - potential_link.attr('href',link); - } else { - el_target.find('img').wrap(''); - } - el_target.trigger('changed'); - $(".modal-links").foundation('reveal', 'close'); - }); - - /* Graphs - sticks in divs with data-type=dynamic */ - $('[data-type="dynamic"]').each(function(i, el) { - /* Insert link-button on images */ - var last_button = $(el).siblings().find("a:last-child"); - last_button.after(''); - - /* Set element target on modal */ - $('[data-target="'+ $(el).attr('data-name') +'"]').click( function(e) { - var target = $(this).attr('data-target'); - $(".modal-graph").attr('data-graph-target', target); - }); - }); - - $("[data-is-graph] a").click(function(e) { - e.preventDefault(); - var part_name = $('[data-graph-target]').attr('data-graph-target'); - var graph = $(this).parent(); - var part = $('[data-name="'+ part_name +'"]'); - var html = graph.find('[data-graph-html-copy]')[0].outerHTML; - part.html(html); - part.find('[data-graph-slug]').graph('load'); - part.trigger('changed'); - $(".modal-graph").foundation('reveal', 'close'); - }); - - /* Load graphs initially */ - $('.template [data-graph-slug]').graph('load'); - $('.modal-graph [data-graph-slug]').graph('load', {width: 300, height: 200}); - -}); diff --git a/static/dist/scripts/slides.js b/static/dist/scripts/slides.js deleted file mode 100644 index 92a10dc..0000000 --- a/static/dist/scripts/slides.js +++ /dev/null @@ -1,440 +0,0 @@ -$(document).ready( function() { - var all_icons = $("[data-section-icon]").map(function() { - return $(this).attr('data-section-icon'); - }).get(); - all_icons = _.uniq(all_icons).join(" "); - - function update_title_bar( event ) { - if($(event.currentSlide).is('[data-section-title-hidden]') ) { - $(".title-bar").css('opacity', '0'); - } else { - $(".title-bar").css('opacity', '1'); - } - // event.previousSlide, event.currentSlide, event.indexh, event.indexv - var title = $(event.currentSlide).attr('data-section-title') || ""; - /* Only update when title has changed */ - if($(".title-bar .title span:first").text() !== title) { - $(""+title+"").hide().appendTo(".title-bar .title").fadeIn("normal"); - $(".title-bar .title span:not(:last)").fadeOut("normal", function() { - $(this).remove(); - }); - } - - var edit_url = $(event.currentSlide).attr('data-edit-url'); - $(".title-bar a.title").attr('href', edit_url); // Only update if a is found - - var icon = $(event.currentSlide).attr('data-section-icon') || ""; - if( !$(".title-bar .title i").hasClass(icon) ) { - $(".title-bar .title i") - .removeClass(all_icons) - .addClass(icon); -  } - } - /* Slides: with "wheel" */ - function wheel_toggle_slides(el) { - $("[data-wheel-order]").removeClass('active'); - $(el).addClass('active'); - var order = $(el).attr('data-wheel-order'); - var related = $('[data-wheel-order="' + order +'"]').not('.wheel-image'); - related.addClass('active'); - $('.wheel-text [data-type="wysihtml5"]').hide(); - related.show(); - } - $(".top-bar .links a").click(function() { - $(".top-bar.expanded .toggle-topbar").trigger("click.fndtn.topbar"); - }); - - /* Presentation? */ - if( $('.page-presentation-play').length) { - /* Initialize reveal.js */ - Reveal.initialize({ - // Display controls in the bottom right corner - controls: true, - // Display a presentation progress bar - progress: true, - // Push each slide change to the browser history - history: true, - // Enable keyboard shortcuts for navigation - keyboard: true, - // Enable the slide overview mode - overview: false, - // Vertical centering of slides - center: false, - // Enables touch navigation on devices with touch input - touch: true, - // Loop the presentation - loop: false, - // Change the presentation direction to be RTL - rtl: false, - // Number of milliseconds between automatically proceeding to the - // next slide, disabled when set to 0, this value can be overwritten - // by using a data-autoslide attribute on your slides - autoSlide: 0, - // Enable slide navigation via mouse wheel - mouseWheel: false, - // Apply a 3D roll to links on hover - rollingLinks: false, - // Transition style - transition: 'linear', // default/cube/page/concave/zoom/linear/fade/none - // Factor of the display size that should remain empty around the content - margin: 0.15, - // The "normal" size of the presentation, aspect ratio will be preserved - // when the presentation is scaled to fit different resolutions. Can be - // specified using percentage units. - //width: 960, - //height: 700, - width: 768, // Note: Could set this to 100% and make presentation content responsive instead of using zoom; - height: 576, - minScale: 0.2, - maxScale: 1 - // FIXME: use user agent / device width ? - }); - - - Reveal.addEventListener( 'ready', function(event) { - /* On small screen? disable transitions */ - var small_screen = $(window).width() < 480; - if( small_screen ) { - Reveal.configure({ transition: 'none' }); - } - - update_title_bar(event); - - /* Load chart if one exists on current slide (animate) */ - if( $(event.currentSlide).find('[class^="graph-"]').length) { - $(event.currentSlide).find('[class^="graph-"]').graph('load'); - } - - }); - - Reveal.addEventListener( 'slidechanged', function( event ) { - - /* Update title bar */ - update_title_bar(event); - - /* Chart slide - Wait until it is current to load (animate) */ - if( $(event.currentSlide).find('[class^="graph-"]').length) { - $(event.currentSlide).find('[class^="graph-"]').graph('load'); - } - - /* Disable touch on specific slides*/ - if( $(event.currentSlide).find("[data-swipe-disable]").length ) { - Reveal.configure({ touch: false }); - } else { - Reveal.configure({ touch: true }); - } - - /* Search previous slide for video elements and pause them */ - $(event.previousSlide).find("video").each(function(i, el) { - el.pause(); - }); - - /* Setup/Reset wheel state on wheel-slide enter */ - if( $(event.currentSlide).find('.wheel').length) { - $('.wheel-text [data-wheel-order]').hide(); - $('[data-wheel-order]').removeClass('active'); - $('[data-wheel-order="1"]').addClass('active').show(); - } - } ); - - - $(".wheel-images .wheel-image .trigger, .wheel-head .trigger").on('mousedown', function(e) { - wheel_toggle_slides(this); - }); - /* Hover fix for touch: Only bind on hover for non-touch devices */ - $(".no-touch .wheel-images .wheel-image .trigger, .no-touch .wheel-head .trigger").on('mouseenter', function(e) { - wheel_toggle_slides(this); - }); - } - - /* Swipebox */ - $('a.fancybox').swipebox(); - - /* Video */ - $('video').mediaelementplayer({ - success: function (mediaElement, domObject) { - /* Track video plays */ - mediaElement.addEventListener( - 'play', - function(e) { - mixpanel.track("Played video."); - }, - false); - } - }); - - /* Skip home if you are on the play-slide */ - $("[data-goto-first-slide]").on('click', function(e) { - e.preventDefault(); - $(".top-bar.expanded .toggle-topbar").trigger("click.fndtn.topbar"); - Reveal.slide(0, 0); - }); - - - /* Slide: Sick cost calculator */ - function get_salary() { - var industry_pk = parseInt($("#id_calc_industry").val(), 10); - /* Note: stb_industries is defined in the calculator.html-template */ - var industry = _.findWhere(stb_industries, {pk: industry_pk}); - - if(industry === undefined) { - return 0; - } - return industry.fields.yearly_salary; - } - function calc_cost(sick_rate, num_staff) { - var salary = get_salary(); - sick_rate = sick_rate / 100.0; // percent - return sick_rate * num_staff * salary; - } - /* Format norwegian */ - function format_number_norwegian(num) { - num = num.toString(); - var formatted_str = ""; - /* Add spaces backwards every third char */ - for(var i=0; i< num.length; i++){ - if(i % 3 === 0) { - formatted_str += " "; - } - formatted_str += num.charAt(num.length-i-1); - } - /* reverse the string */ - return formatted_str.split("").reverse().join(""); - } - function calc_savings(sick_rate, goal_sick_rate, num_staff) { - var current = calc_cost(sick_rate, num_staff); - var goal = calc_cost(goal_sick_rate, num_staff); - return current - goal; //total savings per year - } - function recalc() { - /* Get data */ - var num_staff = parseInt($(".num-staff").slider('value'), 10); - var sick_rate = $(".sick-rate").slider('value'); - var sick_rate_float = parseFloat(sick_rate); - var goal_sick_rate = $(".goal-sick-rate").slider('value'); - var goal_sick_rate_float = parseFloat(goal_sick_rate); - /* Calculate */ - var cost = calc_cost(sick_rate_float, num_staff); - cost = parseInt(Math.round( cost / 100), 10) * 100; - var savings = calc_savings(sick_rate_float, goal_sick_rate, num_staff); - savings = parseInt(Math.round( savings / 1000), 10) * 1000; - /* Output data */ - $("[data-calc-staff]").text(num_staff); - $("[data-calc-rate]").text(Math.round(sick_rate_float * 10) / 10); - $("[data-calc-goal-rate]").text(Math.round(goal_sick_rate_float * 10) / 10); - $("[data-calc-savings]").text(format_number_norwegian(savings)); - $("[data-calc-savings-employee]").text(format_number_norwegian(Math.round(savings / num_staff))); - /* cost */ - $("[data-calc-cost]").text(format_number_norwegian(cost)); - $("[data-calc-cost-employee]").text(format_number_norwegian(Math.round(cost / num_staff))); - - } - if($(".sick-cost-calculator").length) { - $( ".num-staff" ).slider({ - animate: "fast", - value: 600, - min: 1, - max: 2000, - step: 1, - stop: recalc, - slide: recalc - }); - $( ".sick-rate" ).slider({ - animate: "fast", - value: 10.2, - min: 1, - max: 15, - step: 0.2, - stop: recalc, - slide: recalc - }); - $( ".goal-sick-rate" ).slider({ - animate: "fast", - value: 5, - min: 1, - max: 15, - step: 0.2, - stop: recalc, - slide: recalc - }); - $(".sick-cost-industry-form").on('change', function(e) { - recalc(); - }); - - recalc(); // Initial calc - - /* Workaround for slider not working on touch devices - * Click/touch and change */ - $("[data-calc-staff], [data-calc-rate], [data-calc-goal-rate]").on('click', function(e) { - $(".set-value-modal").attr('data-updating', $(this).attr('data-updating')); - var old_value = $(this).text(); - $("input[name=set-value]").val(old_value); - $(".set-value-modal").foundation('reveal', 'open'); - }); - $(".set-value-button").on('click', function(e) { - var new_value = $("input[name=set-value]").val(); - var key = "#" + $(".set-value-modal").attr('data-updating'); - $( key ).slider({ value: parseFloat(new_value)}); - $(".set-value-modal").foundation('reveal', 'close'); - recalc(); - }); - } - - /* Slide: Public treatment comparison */ - if($(".public-treatment-comparison").length) { -        var options = { -     valueNames: [ 'region', 'hospital', 'city', 'diagnose', 'waittime' ] -        }; - -        var featureList = new List('treatment-list', options); - featureList.sort('waittime', { asc: false }); - -        $('.filter-region, .filter-diagnose').change(function() { -            featureList.filter(function(item) { - var diagnose = $('.filter-diagnose').val(); - var region = $(".filter-region").val(); -                return (item.values().region == region || region == "Alle") && item.values().diagnose == diagnose; -            }); -            return false; -        }); -        $('.filter-none').click(function() { -            featureList.filter(); -            return false; -        }); - $(".filter-diagnose").trigger('change'); - } - - function init_treatment_map() { - // mapbox.com: nikolaik.map-hyrf1sef - var tile_url = 'http://{s}.tiles.mapbox.com/v3/nikolaik.map-hyrf1sef/{z}/{x}/{y}.png'; - var tiles = L.tileLayer(tile_url, {maxZoom: 17, minZoom: 4}); - var latlng = L.latLng(65.57, 12.56); - - var map = L.map('treament-network-map', {center: latlng, zoom: 4, layers: [tiles]}); - - var markers = L.markerClusterGroup({ showCoverageOnHover: false}); - /* Marker icon style */ - var static_url = $('meta[name="x-django-static-url"]').attr('content'); - var icon = L.icon({ - iconUrl: static_url + 'dist/images/storebrand_map_marker.png', - iconSize: new L.Point(35, 35), - iconAnchor: new L.Point(35, 35), - popupAnchor: new L.Point(-17.5, -35), - shadowUrl: '', - shadowSize: new L.Point(0, 0), - }); - - /* Add specialist markers */ - var _url = 'http://zeppelin.brill.no/blifrisk/data/no.json'; - $.getJSON(_url, function(data) { - _.each(data.specialists, function(s, i) { - if(s.position) { - var marker = L.marker(new L.LatLng(s.position.lat, s.position.lng), { title: s.name, icon: icon }); - marker.bindPopup("

    "+ s.name +"

    "+ s.address +"
    "+ s.postalCode +" "+ s.city +"

    "); - markers.addLayer(marker); - } - }); - map.addLayer(markers); - }); - } - /* Slide: Treatment locations map */ - if($(".treament-network-map").length) { - - /* Load the treatment map when the slide comes in to view when in presentation mode */ - if (window.Reveal && !$(".page-slide-edit").length) { - var handler = function(event) { - if($(event.currentSlide).find(".treament-network-map").length) { - init_treatment_map(); - Reveal.removeEventListener( 'slidechanged', handler, false); // run only once - } - }; - Reveal.addEventListener( 'slidechanged', handler); - Reveal.addEventListener( 'ready', function(event) { - if($(event.currentSlide).find(".treament-network-map").length) { - /* Load map */ - init_treatment_map(); - } - }); - } else { - init_treatment_map(); - } - - } - /* Placeholder polyfill for IE9 */ - placeholderSupport = ("placeholder" in document.createElement("input")); - if(!placeholderSupport){ - //This browser does not support the placeholder attribute - //use javascript instead - $('[placeholder]').focus(function() { - var input = $(this); - if (input.val() === input.attr('placeholder')) { - input.val(''); - input.removeClass('placeholder'); - } - }).blur(function() { - var input = $(this); - if (input.val() === '' || input.val() === input.attr('placeholder')) { - input.addClass('placeholder'); - input.val(input.attr('placeholder')); - } - }).blur().parents('form').submit(function() { - $(this).find('[placeholder]').each(function() { - var input = $(this); - if (input.val() === input.attr('placeholder')) { - input.val(''); - } - }); - }); - } - /* Highcarts graph theme */ - Highcharts.theme = { - colors: ['#da291c', '#425563', '#ed786f'], - chart: { - backgroundColor: null - }, - credits: { - enabled: false - }, - title: { - style: { - color: '#1e394d', - font: 'bold 16px "SignaColumn", Helvetica, Arial, sans-serif' - } - }, - subtitle: { - style: { - color: '#425563', - font: 'bold 12px "SignaColumn", Helvetica, Arial, sans-serif' - } - }, - yAxis: { - title: { - style: { - color: 'gray' - } - } - }, - xAxis: { - title: { - style: { - color: 'gray' - } - } - }, - legend: { - itemStyle: { - font: '9pt "SignaColumn", Helvetica, Arial, sans-serif', - color: 'black' - }, - itemHoverStyle:{ - color: 'gray' - } - }, - exporting: { - enabled: false - } - }; - - // Apply the theme - Highcharts.setOptions(Highcharts.theme); -});