用户必须能够提交并保存范围滑块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>
答案 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)