oTree/django中的强制滑块 [英] Mandatory slider in oTree/django

查看:87
本文介绍了oTree/django中的强制滑块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想使用oTree作为进行实验的替代方法.为此,我正在寻找一种在表格中包含强制性滑块问题的可能性,即e.您必须先移动滑块才能继续下一个问题.首先,我尝试修改oTrees 调查模板,以实现针对将来的使用,但无法将像fieldtracker这样的常见方法集成到项目中.

I want to use oTree as an alternative for conducting experiments. For this purpose I am looking for a possibility to include mandatory slider questions in forms, i. e. sliders you are required to move before you are able to proceed to the next question. As a start I tried to modify oTrees survey template to achieve a solution for future usage but wasn't able to integrate common approaches like a fieldtracker into the project.

以下是models.py和views.py文件的两个修改版本(目前,在一些失败的尝试无法真正发挥作用之后),它们提示了我要去的方向.有办法使它工作吗?

Here are two modified (yet currently after a number of unsuccessful try-outs not really functioning) versions of the models.py and views.py files which give a hint in which direction I want to go. Is there a way to get this to work?

# -*- coding: utf-8 -*-   
## models.py
# <standard imports>
from __future__ import division

from django.db import models
from django_countries.fields import CountryField
from model_utils import FieldTracker,

from otree import widgets
from otree.constants import BaseConstants
from otree.db import models
from 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, which is zero for the survey"""
        self.payoff = 0

    q_country = CountryField(
        verbose_name='What is your country of citizenship?')

    q_age = IntegerFielder(verbose_name='What is your age?',
                                        min=13, max=125,
                                        initial=25,
                                        widget=widgets.SliderInput())

    q_gender = models.CharField(initial=None,
                                choices=['Male', 'Female'],
                                verbose_name='What is your gender?',
                                widget=widgets.RadioSelect())

    tracker = FieldTracker()


    crt_bat = models.PositiveIntegerField()
    crt_widget = models.PositiveIntegerField()
    crt_lake = models.PositiveIntegerField()

这是第二个文件:

# -*- coding: utf-8 -*-
##views.py
from __future__ import division
from . import models
from ._builtin import Page, WaitPage
from otree.common import Currency as c, currency_range
from .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 the slider before you 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
]

提前谢谢!

推荐答案

有两种方法:仅在客户端使用JS,在服务器使用Django.

There are two ways of doing it: by using JS only, on the client's side, and by using Django at the server side.

简单的JS解决方案:在模板中添加:

The simple JS solution: in the 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 %}

因此,在用户触发 change 事件之前,将 SliderTOuched 变量设置为 False ,这将阻止提交表单.这是一种紧凑的方法,但是您必须自己向用户显示错误消息.

So until the user triggers change event, the SliderTOuched var is set to False which prevents a form to be submitted. It is a compact way, but you have to deal with showing an error message to the user yourself.

=================

=================

更长的服务器端解决方案如下:

The longer server-side solution is the following:

定义一个附加字段:

    class Player(BasePlayer):
        checkslider = models.IntegerField(blank=True)

views.py 中的

除了您的滑块字段之外,还传递了此额外字段来检查滑块是否已更改:

in views.py in addition to your slider field pass also this extra field that will check that the slider was 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 your decision using slider'

在模板中将此隐藏的额外字段插入html:

in template insert this hidden extra field to html:

  <input type="hidden" name="checkslider" value="" id="id_checkslider"/>

并在更改滑块后立即将此字段设置为当前滑块值:

and set this field to current slider value as soon as slider is changed:

  {% block scripts %}
    <script>
      var selector = $('[data-slider] input[type="range"]');
      selector.change(function() {
        $('#id_checkslider').val(selector.val());
      });
    </script>
  {% endblock %}

这篇关于oTree/django中的强制滑块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆