Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to save the value of a jQuery sliderbar into a Person model?

I am trying to save the value of an jQuery element I added to my SurveyWizardForm into my class Person(models.Model): and therefore my database.

All of the other elements in my form were created the normal way, by creating the necessary fields and widgets in my forms.py and the data for each question in my models.py. As a result they all automatically work and the correct data is getting saved.

However I have customized my SurveyWizardForm on certain pages to allow the user to submit a rating for an image via a jQuery slider bar.

My issue is that I cannot seem to store this value in my Person model.

Question: How do I store the value of my slider bar into slider_value in my Person model?

All my attempts so far have simply created a new entry in the model/DB that does not store the value I have in my Form/views.py. I fear that I am not linking the two pieces together correctly.

Any help is much appreciated. Thanks

My Code so far

slider_two.js

This updates the hidden form field hidden1 with the value of the my jQuery slider bar

  if($(this).attr("id") ==  "one")
      $("#hidden1").val((ui.value > 0 ? '+' : '') + ui.value);
  

wizard_form.html

value="0" gets updated when the user moves the slider created in the above slider_two.js (not shown)

<input type="hidden" name="slider_value" value="0" id="hidden1"/>                           
            
<script src="{% static "survey/js/slider_two.js" %}"></script>
             

views.py

I can read the value into views.py using

 slider_value = self.request.POST.get('slider_value')
 if slider_value is not None:                
     instruction_task_values.insert(0, slider_value) 
            
 logger.debug('\n\n\nThis is your instruction_task_values in 1 %s', instruction_task_values)

This works as the correct value is printed each time to my log

models.py

This is meant to create the field in the DB to store the value of the slider bar. all the other entries I create work and are saved correctly.

class Person(models.Model): 
    slider_value = models.IntegerField(null=True, blank=True, max_length=1000)
   

forms.py

This is where I believe my issue is.

The below is my attempt to "connect" to the existing slider_value in my form and add it to my Person model however all it does is simply create a new fiel in my form.

class SurveyFormIT1(forms.ModelForm):      
    class Meta:
        model = Person    
        fields = ['slider_value']
        widgets = {'slider_value' : forms.HiddenInput}    


    
    
like image 620
Deepend Avatar asked May 31 '15 21:05

Deepend


3 Answers

You should consider revising your code to work with forms properly.

For example, in your views.py:

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 = SurveyFormIT1(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)
            logger.debug('\n\n\nThis is your instruction_task_values in 1 %s', instruction_task_values)
            # redirect to a new URL:
            return HttpResponseRedirect('/thanks/')

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

    return render(request, 'wizard_form.html', {'form': form})

In your wizard_form.html:

{{ form.as_p }}
<script src="{% static "survey/js/slider_two.js" %}"></script>

{{ form.as_p }} will just give you something like

<input type="hidden" name="slider_value" value="" id="id_slider_value"/>
like image 156
akarilimano Avatar answered Nov 19 '22 17:11

akarilimano


you should do something like this

if request.method == 'POST':
form = SurveyFormIT1(request.POST)
if form.is_valid():
    survey=form.save(commit=False)
    survey.slider_value=form.cleaned_data['slider_value']
    survey.save()

First you should check if you get the correct value in your request, once you have it, you simply manually save it like in the sample above. You should also exclude the slider_value field from the form as it will not be valid until you pass the correct value to it.

I know there are more elegant solutions, but this one is easy to understand.

Hope this helps

like image 44
Ales Maticic Avatar answered Nov 19 '22 18:11

Ales Maticic


I eventually found a way of solving this.

The overarching problem was that I was trying to add information to my Person Model which was not 'generated/originated' from my forms.py / models.py in the traditional way but rather was being 'generated' on the page from my jQuery script.

I knew I had to create a model field and corresponding form field that would take the value. Originally I believed that I should to send this value to my views.py (as above in question). This was wrong.

When I was inspecting the outputted html pages from the SessionWizardView/form_wizard I realized that even though I had called each of form fields e.g. field = ['slider_one_value'] it was being rendered out as e.g.

<input id="id_9-slider_one_value" type="hidden" name="9-slider_one_value" value="-37"></input>

The id_9- being added as it was on the ninth page of the survey.

As a result if I modified my jQuery to update this field at the same time as the main hidden field sent to my views the value would be automatically stored to my model

The best part is that I can update as many of these fields as I want from the same script

I hope this helps someone else

My code

wizard_form.html

This calls my slider_two.js script

<script src="{% static "survey/js/slider_two.js" %}"></script>

slider_two.js

Creates a sliderbar on the page which the user is able to move. It then updates the result and the hidden field which is sent to the views

It also updates the newly created hidden fields which correspond to those created in the model after they have been rendered through the SessionWizardView

$('#submit').click(function() {
    var username = $('#hidden').val();
    if (username == "") username = 0;
    $.post('comment.php', {
        hidden: username
    }, function(return_data) {
        alert(return_data);
    });
});

$(".slider").slider({
    animate: true,
    range: "min",
    value: 0,
    min: -100,
    max: +100,
    step: 1,

    //This updates the slider-result below the slider bar so the participant can see their rating
    slide: function(event, ui) { 
      $("#slider-result").html((ui.value > 0 ? '+' : '') + ui.value);

    //This updates the hidden form field which is read by my views.py
    if($(this).attr("id") ==  "one")
        $("#hidden1").val((ui.value > 0 ? '+' : '') + ui.value);

    //This updates the id_9-slider_one_value form field which matches the name of fields = ['slider_one_value'] after it has been rendered
    if($(this).attr("id") ==  "one")
        $("#id_9-slider_one_value").val(ui.value);  

    //This updates the id_10-slider_two_value form field which matches the name of fields = ['slider_one_value'] after it has been rendered
    if($(this).attr("id") ==  "one")
        $("#id_10-slider_two_value").val(ui.value); 


    ....

    // Update as many hidden forms fields as necessary

    }
});

models.py

Creates the entries in the database to store the value

slider_one_value = models.SmallIntegerField(null=True, max_length=100, blank=True) 
slider_two_value = models.SmallIntegerField(null=True, max_length=100, blank=True) 

forms.py

Creates the hidden forms fields to take the values from the jQuery script

class SurveyFormF1(forms.ModelForm):      
    class Meta:
        model = Person       
        fields = ['slider_one_value']
        widgets = {'slider_one_value' : forms.HiddenInput}   

class SurveyFormF2(forms.ModelForm):        
    class Meta:
        model = Person        
        fields = ['slider_two_value']
        widgets = {'slider_two_value' : forms.HiddenInput}  
like image 1
Deepend Avatar answered Nov 19 '22 17:11

Deepend