Mandatory slider in oTree/django

吃可爱长大的小学妹 提交于 2019-12-01 12:23:55

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

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 %}

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:

in models.py define an additional field:

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

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'

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 %}

By default, Django assumes an input is required.

I think that means if you just remove the initial value, it will self-validate.

Also, you called something named "IntegerFielder()." Did you mean models.IntegerField() or is there an import that we're not seeing?

I suggest a slight modification to Philipp's answer.

The code above still triggers the error message if the participant touches the slider, but returns the slider to the default starting position.

To fix this, I used the following script:

{% block scripts %}
    <script>
        $('input[name=q_age]').on('input', function(){
            $('#id_checkslider').val(1);
        });
    </script>
{% endblock %}

The code changes checkslider from None to 1 when the slider is touched, even if the participant sets the slider to the default starting position.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!