如何将jQuery范围滑块值转换为表格以存储在Django

时间:2018-02-14 07:39:32

标签: javascript python django django-models django-forms

用户必须能够提交并保存范围滑块1的值。目的是用户猜测物体在现实生活中的充实程度,然后可以作为游戏的一部分报告填充百分比。用户界面如下图所示。

目前,我可以从POST表单(在slider.html中)检索数据作为预设值'但不是范围滑块值。我看了很多,问题是我不熟悉Javascript来实现解决方案。我认为可以从javascript函数中获取值并直接输入POST html表单?任何人都可以帮助建议如何做到这一点或任何其他建议?到目前为止,这是代码,由于许多尝试和错误,它有点混乱

Models.py

from django.db import models
from django.forms import ModelForm
from django import forms


class Measurements(models.Model):
    DeviceId            = models.IntegerField(blank=True, null=True)
    TimeStamp           = models.DateTimeField(auto_now=True)
    Metadata            = models.IntegerField(blank=True, null=True)
    Sensor              = models.IntegerField(default=False)
    Button              = models.IntegerField(default=False)
    QrUser              = models.IntegerField(default=True)
    FillingPercentage   = models.DecimalField(max_digits=4, decimal_places=2, blank=True, null=True)
    slider_value        = models.IntegerField(default=False, null=True, blank=True)



def __str__(self):
    return str(self.DeviceId)

class Meta:
    verbose_name_plural = "Measurements"     

Forms.py

from django.forms import ModelForm
from django import forms

from .models import Measurements

class MeasurementsForm(ModelForm):
    class Meta:
        model = Measurements
        fields = ('FillingPercentage','slider_value')
        widgets = {'slider_value' : forms.HiddenInput()}    

def clean_FillingPercentage(self):
    print("fUNCTION CALLED")
    value = self.cleaned_data.get('something_else')
    print(value)


class IntegerFieldForm(forms.Form):
    field5 = forms.IntegerField(
        help_text="Filling percentage", widget=forms.NumberInput(attrs={'type': 'range', 'min': '0', 'max': '100'}))

Views.py

from django.shortcuts import render
from django.shortcuts import render_to_response
from django.http import HttpResponseRedirect
from django.views.generic import FormView, TemplateView, CreateView
import floppyforms as forms


from .forms import MeasurementsForm


class QRView(CreateView):
    form_class = MeasurementsForm
    template_name = 'QrFill/slider.html'
    success_url = '/guess/'

    def form_valid(self, form):
        instance = form.save(commit=False)
        # instance.FillingPercentage = self.request
        return super(QRView, self).form_valid(form)

    def get_context_data(self, **kwargs):
        context = super().get_context_data(**kwargs)
        context ['FillingPercentage'] = 'Add Fill Level'
        return context

    def read_value():
        FillingPercentage = self.request.POST.get('FillingPercentage')
        if FillingPercentage is not None:                
            instruction_task_values.insert(0, FillingPercentage) 
        print('\n\n\nThis is your instruction_task_values in 1 %s', instruction_task_values)




def my_view(request):
# if this is a POST request we need to process the form data
    if request.method == 'POST':
        # create a form instance and populate it with data from the request:
        form = MeasurementsForm(request.POST)
        # check whether it's valid:
        if form.is_valid():
            # process the data in form.cleaned_data as required
            slider_value = form.cleaned_data['slider_value']
            if slider_value is not None:    
                instruction_task_values.insert(0, slider_value)

            # redirect to a new URL:
            return HttpResponseRedirect('/thanks/')

    # if a GET (or any other method) we'll create a blank form
    else:
        form = MeasurementsForm()

    return render(request, 'QrFill/slider.html', {'form': form})

slider.html

{% load staticfiles %}

{% load bootstrap4 %}

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <title>rangeslider.js</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <link rel="stylesheet" href="{% static 'css/rangeslider.css' %}"/>
    <style>
        *,
        *:before,
        *:after {
            -webkit-box-sizing: border-box;
               -moz-box-sizing: border-box;
                    box-sizing: border-box;
        }
        html {
            color: #404040;
            font-family: Helvetica, arial, sans-serif;
        }
        body {
            padding: 50px 20px;
            margin: 0 auto;
            max-width: 800px;
        }
        output {
            display: block;
            font-size: 30px;
            font-weight: bold;
            text-align: center;
            margin: 30px 0;
            width: 100%;
        }
        .u-left {
            float: left;
        }
        .u-cf:before,
        .u-cf:after {
            content: "";
            display: table;
        }
        .u-cf:after {
            clear: both;
        }
        .u-text-left {
            text-align: left;
        }
    </style>
</head>
<body>



    <div>

        <div>

             <form method='POST' class='form'> 
            {% csrf_token %}

                <input type="hidden" name="slider_value" id="myVar" value="50" id="hidden1"/> 




                <input type="range" min="0" max="100" step="0.01" value="50" data-rangeslider>

                <output id='output'> </output>

                <button type="submit" name="_submit" class="btn btn-primary btn-lg">Submit</button>

        </div>


    </div>



    <script src="//localhost:8080"></script>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>

    <script src="{% static 'js/rangeslider.js' %}"></script>


    <script >
        var myVar = document.getElementById("myVar").value;


    $(function() {


        var $document = $(document);
        var selector = '[data-rangeslider]';
        var $element = $(selector);
        var textContent = ('textContent' in document) ? 'textContent' : 'innerText';
        function valueOutput(element) {
            var value = element.value + "%";
            var output = element.parentNode.getElementsByTagName('output')[0] || element.parentNode.parentNode.getElementsByTagName('output')[0];
            output[textContent] = value;
        }
        $document.on('input', 'input[type="range"], ' + selector, function(e) {
            valueOutput(e.target);
        });



        $element.rangeslider({
            polyfill: false,
            onInit: function() {
                valueOutput(this.$element[0]);
            },
            onSlide: function(position, value) {
            },
            onSlideEnd: function(position, value) {

                $("#amount").text(value);
                console.log("Value: " + value.toString())
                FillingPercentage = value.toString()



            }
        });
    });
    </script>
</body>
</html>

2 个答案:

答案 0 :(得分:1)

我会告诉你如何做到这一点。

您应该创建一个看起来像save_progress(request)的新简单视图。

def save_progress(request):
    progress = request.POST.get('progress')
    ...do with it what you want...

以相同的方式创建网址path('app_name/..path../save-progress/', views.save_progress, name='save-progress')。所以现在你将定义url和视图,你可以编写javascript控制器

var timeout = null;
function saveProgress() {
    clearTimeout(timeout);
    timeout = setTimeout(function() {
        $.ajax({
            method: 'POST',
            url: '{% url "save-progress" %}'
            data: {progress: $('#slider-id-to-be-saved').val()},
            success: function(response) {
                console.log('Yeah! Your data were sent and saved!');
            }
        })
    }, 500); // so it will wait 500ms until it actually sends the POST 
}

并将onchange侦听器添加到输入范围

<input type="range" min="0" max="100" step="0.01" value="50" data-rangeslider onchange="saveProgress">

这是它的想法。注意超时,因此您的数据会在一段时间内没有发生变化后实际发送。

答案 1 :(得分:0)

非常感谢您的投入。

我解决了它,就像下面发布的代码一样,但是,用户点击提交按钮发布帖子会更理想..有关如何改进的建议吗?

在slide.html中

$(function() {
var $document = $(document);
var selector = '[data-rangeslider]';
var $element = $(selector);
var timeout = null;
var textContent = ('textContent' in document) ? 'textContent' : 'innerText';

function valueOutput(element) {
    var value = element.value + "%";
    var output = element.parentNode.getElementsByTagName('output')[0] || element.parentNode.parentNode.getElementsByTagName('output')[0];
    output[textContent] = value;
    clearTimeout(timeout);
    timeout = setTimeout(function() {
        $.ajax({
        method: 'POST',
        url: '{% url "QrFill:save-progress" %}',
        data: {progress: element.value
        },
        success: function(response){
            console.log('Yeah! Your data were sent and saved!');
        }, timeout: 2000
    })
    }, 3000);     
}

views.py

@csrf_exempt
def edit_favorites(request):
    if request.is_ajax():
        post_text = request.POST.get('progress')
        post = Measurements(FillingPercentage=post_text)
        post.save()
    else:
        message = "Not Ajax"
    return HttpResponse(message)