javascript - Mandatory slider in oTree/django -
i want use otree alternative conducting experiments. purpose looking possibility include mandatory slider questions in forms, i. e. sliders required move before able proceed next question. start tried modify otrees survey template achieve solution future usage wasn't able integrate common approaches fieldtracker project.
here 2 modified (yet after number of unsuccessful try-outs not functioning) versions of models.py , views.py files give hint in direction want go. there way work?
# -*- coding: utf-8 -*- ## models.py # <standard imports> __future__ import division django.db import models django_countries.fields import countryfield model_utils import fieldtracker, otree import widgets otree.constants import baseconstants otree.db import models otree.models import basesubsession, basegroup, baseplayer class constants(baseconstants): name_in_url = 'survey' players_per_group = none num_rounds = 1 class subsession(basesubsession): pass class group(basegroup): pass class player(baseplayer): def set_payoff(self): """calculate payoff, 0 survey""" self.payoff = 0 q_country = countryfield( verbose_name='what country of citizenship?') q_age = integerfielder(verbose_name='what age?', min=13, max=125, initial=25, widget=widgets.sliderinput()) q_gender = models.charfield(initial=none, choices=['male', 'female'], verbose_name='what gender?', widget=widgets.radioselect()) tracker = fieldtracker() crt_bat = models.positiveintegerfield() crt_widget = models.positiveintegerfield() crt_lake = models.positiveintegerfield()
here comes second file:
# -*- coding: utf-8 -*- ##views.py __future__ import division . import models ._builtin import page, waitpage otree.common import currency c, currency_range .models import constants, integerfieldcustom class demographics(page): form_model = models.player form_fields = ['q_country', 'q_age', 'q_gender'] check_age = q_age.tracker.has_changed() def q_age_error_message(self, ): if demographics.check_age == false: return 'you must move slider before can continue' class cognitivereflectiontest(page): form_model = models.player form_fields = ['crt_bat', 'crt_widget', 'crt_lake'] def before_next_page(self): self.player.set_payoff() page_sequence = [ demographics, cognitivereflectiontest ]
thanks in advance!
there 2 ways of doing it: using js only, on client's side, , using django @ server side.
the simple js solution: in template add:
{% block scripts %} <script> var slidertouched = false; var selector = $('[data-slider] input[type="range"]'); selector.change(function() { slidertouched = true; }); $( ".form" ).submit(function( event ) { if (!slidertouched){ event.preventdefault();} }); </script> {% endblock %}
so until user triggers change
event, slidertouched
var set false
prevents form submitted. compact way, have deal showing error message user yourself.
=================
the longer server-side solution following:
in models.py
define additional field:
class player(baseplayer): checkslider = models.integerfield(blank=true)
in views.py
in addition slider field pass field check slider changed:
class mypage(page): form_model = models.player form_fields = ['q_age', 'checkslider'] def checkslider_error_message(self, value): if not value: return 'please make decision using slider'
in template insert hidden field html:
<input type="hidden" name="checkslider" value="" id="id_checkslider"/>
and set field current slider value slider changed:
{% block scripts %} <script> var selector = $('[data-slider] input[type="range"]'); selector.change(function() { $('#id_checkslider').val(selector.val()); }); </script> {% endblock %}
Comments
Post a Comment