Unable to validate form with single field, with ajax post - ajax

I've been unable to find a solution to my problem from searching. So I'd like to ask what might be wrong with my code. I'm trying to validate a form from forms.ModelForm but in my views function it won't pass the form.is_valid(). printing form.errors gives me:
<li>title<ul class="errorlist"><li>This field is required.</li></ul>
Model:
class Paper(models.Model):
title = models.CharField(max_length=100, help_text='Hello World!')
forms.FormModel
class eventCreateForm(forms.ModelForm):
class Meta:
Model = Paper
fields = ['title']
widgets = {
'title': forms.TextInput(attrs={'class' :'form-control', 'placeholder' : 'Place title'}),
}
Views
def create_paper(request):
context = {}
if request.method == 'POST':
form = paperCreateForm(request.POST or None, request.FILES or None)
if form.is_valid():
form_data = form.cleaned_data
t1 = form_data['title']
print(t1)
else:
context['create_paper_form'] = form
form_template = "user/paper-event-template.html"
return HttpResponse(render_to_string(form_template, {'context' : context}))
The form dosen't get validated, and in the else clause it'll pass the error when trying to retrieve it from the cleaned_data
I did try and print the form, and it shows:
<tr><th><label for="id_title">Title:</label></th><td><ul class="errorlist"><li>This field is required.</li></ul><input class="form-control" id="id_title" maxlength="100" name="title" placeholder="Place Title" type="text" required /></td></tr>
But it dosen't contain any value, which I guess it should: I use a jax method for sending the forms data:
ajax
$('#create_paper_form_id').submit(function (event) {
event.preventDefault();
$.ajax({
type: "POST",
url: "{% url 'Eapp:create_paper' %}",
data: {
csrfmiddlewaretoken : '{{ csrf_token }}',
form_data : $('#create_paper_form_id').serializeArray(),
},
success: function (data) {
console.log(data);
$('.create-paper').html(data);
},
error: function() {
console.log('err');
}
});
});
html
<div class="create-paper">
<div class="container-fluid">
<form class="form" id="create_paper_form_id" novalidate="novalidate" action="{% url 'Eapp:create_event' %}" method="POST">
{% for field in create_paper_form %}
<div class="form-group">
<div class="col-xs-12">
{{ field.label_tag }}
</div>
<div class="col-xs-12">
{{ field }}
</div>
<div class="col-xs-6">
{{ field.help_text }}
</div>
<div class="col-xs-6">
{{ field.errors }}
</div>
</div>
{% endfor %}
<div class="form-group">
<div class="col-xs-6 col-sm-6 col-md-2 col-lg-2">
<button type="submit" class="btn btn-primary">Submit</button>
</div>
</div>
</form>
</div>
</div>

That's expected behaviour, the cleaned_data is only available on a valid form when there's actually cleaned data available.
The form.data is still available though, you can use that.
To quote the manual:
A Form instance has an is_valid() method, which runs validation
routines for all its fields. When this method is called, if all fields
contain valid data, it will:
return True
place the form’s data in its cleaned_data attribute.
[edit] As #fazil-zaid mentioned, you need to include model in your Meta class for it to function as a modelform.

Related

Ajax function keeps messing up after inserting 24-25 records into the db

I have a multi select checkbox with 30-80 inputs, I wrote an Ajax code for this form, once checkbox is selected it sends records to the database.
Problem occurs after selecting 25th or 26th record, error is saying that value is duplicated, but every input's value is unique. and mentioned value in the error log is for the 1st selected checkbox.
What I want to achieve is, once a checkbox is clicked it should save it in the db, once the checkbox is unchecked, record should be removed from the database.
HTML:
<input type="checkbox" onClick="toggle(this)" /> Toggle All<br/>
#foreach ($counties as $county)
<li>
<input class="checkIt" type="checkbox" id="cnty_id" name="cnty_id"
value="{{ $county->id }}" #foreach($jct_fr_cnty as $jct) #if($jct->cnty_id == $county->id) checked #endif #endforeach>
{{ $county->county }}
</li>
#endforeach
Ajax:
$('.checkIt').bind('click', function() {
if($(this).is(":checked")) {
console.log("Checked");
$.ajax({
type: "POST",
url: '{{ url('company/assignment/interstate/cntys') }}',
data: $("#cntyselectform").serialize()
}).done(function( result ) {
console.log(result);
});
} else {
console.log("Unchecked");
$.ajax({
type: "DELETE",
url: '{{ url('company/assignment/interstate/cntysrem') }}',
data: $("#cntyselectform").serialize()
})
}
});
Controller
public function postcntyinterstate(Request $request)
{
jct_fr_cnty::create([
'cmp_id' => $request->cmp_id,
'cnty_id' => $request->cnty_id,
'svc_id' => $request->svc_id
]);
return response()->json(['success'=>'Data is successfully added']);
}
this is a code for toggle all button, which checks all the checkboxes and sends values to the db without any issue.
function toggle(source) {
checkboxes = document.getElementsByName('cnty_id');
for (var i = 0, n = checkboxes.length; i < n; i++) {
checkboxes[i].checked = source.checked;
console.log("Checked");
$.ajax({
type: "POST",
url: '{{ url('company/assignment/interstate/cntys') }}',
data: $("#cntyselectform").serialize()
}).done(function(result) {
console.log(result);
});
}
}
form code:
<form id="cntyselectform" method="POST"
action="{{ route('company.cntyinterstate', ['company' => $company->id]) }}">
#csrf
<div class="col-lg-12 mb-3 mt-3 mb-sm-0">
<h3>Please select counties</h3>
<div name="cntSelect[]" id="cntSelect">
<ul>
<input type="checkbox" onClick="toggle(this)" /> Toggle All<br />
#foreach ($counties as $county)
<li>
<input class="checkIt" type="checkbox" id="cnty_id" name="cnty_id"
value="{{ $county->id }}"
#foreach ($jct_fr_cnty as $jct) #if ($jct->cnty_id == $county->id) checked #endif #endforeach>
{{ $county->county }}
</li>
#endforeach
</ul>
</div>
<input type="hidden" value="{{ $company->id }}" name="cmp_id" id="cmp_id">
<input type="hidden" value="1" name="svc_id" id="svc_id">
{{-- <button id="cntyselect-button" type="submit" class="btn btn-primary">Submit</button> --}}
</div>
</form>
Database:
I understand the logic of. BUT it looks a little patchy. Let's fix it:
You absolutely should not have duplicate IDs. It may work, but it is semantically incorrect and you should not do it. (The id you specified in the loop in your code will be repeated in the document.) AND Get rid of unnecessary loops.
<input type="checkbox" onClick="toggle(this)" /> Toggle All<br/>
#php
$jct_fr_cnty_array = array_column($jct_fr_cnty->toArray(), 'cnty_id');
#endphp
#foreach ($counties as $county)
<li>
<input class="checkIt" type="checkbox" name="cnty_id"
value="{{ $county->id }}" #checked(in_array($county->id, $jct_fr_cnty_array))>
{{ $county->county }}
</li>
#endforeach
A few elements that could not be marked and triggered incorrectly due to repeated ids in the document and their values may have caused this error.
If you perform your deletion operation properly and if you provide correct checking/unchecking conditions in the relevant checkboxes, I think the error will be corrected when you apply this.

Populate formControlName checkbox from pre-defined data in Angular 2+

I have a dynamically created checkbox list and I'm having trouble to check the some trues according to a pre-defined list.
HTML:
<div class="row">
<div class="example-container col-md-6">
<div *ngFor="let atribuicao of atribuicoesOcorrencia" formArraylName="inputAtribuicaoOcorrencia">
<mat-checkbox [value]="atribuicao.id" (change)="onChange(atribuicao, $event)">
<div style="white-space: pre-wrap;">
{{ atribuicao.descricao }}
</div>
</mat-checkbox>
</div>
</div>
</div>
CLASS TS:
I try populate formControl name inputAtribuicaoOcorrencia in a list, in this case
the only one checekd was id 3, but nothing happens
this.atribuicoesOcorrencia.forEach(listAtibuicoes=> {
ocorrencia.atribuicoesDTO.forEach(x => {
if(listAtibuicoes.id == x.id){
this.formCadastro.get('inputAtribuicaoOcorrencia').setValue('checked');
}
});
});
CLASS TS2:
Or the code bellow for one ID checked only
this.formCadastro.patchValue({
inputAtribuicaoOcorrencia: 'checked',
});
You need to use the [checked] attribute for the mat-checkbox
// example
<mat-checkbox
[value]="atribuicao.id"
[checked]="atribuicao.id" // This is what you need to add. If id is there, it will get checked
(change)="onChange(atribuicao, $event)"
>
<div style="white-space: pre-wrap;">
{{ atribuicao.descricao }}
</div>
</mat-checkbox>

PHP doesnt read textarea content sended by ajax call

i'm dealing with this ajax call:
HTML:
A form has a textarea in which user can type some text
<div id="step-3">
<h2 class="StepTitle">Testo</h2>
<form id="text" class="form-horizontal form-label-left">
<div class="item form-group">
<label class="control-label col-md-3 col-sm-3 col-xs-12">Textarea <span class="required">*</span>
</label>
<div class="col-md-6 col-sm-6 col-xs-12">
<textarea id="textarea" name="testo" data-parsley-required="true" class="form-control col-md-7 col-xs-12"></textarea>
</div>
</div>
</form>
<ul id="error3_ul" class="list-unstyled">
<li id="error3_li"></li>
</ul>
</div>
JS:
This function is called by smartwizard. When user types some text and pushes button, an ajax call starts to do a server side check before to effectively insert text into db.
function onFinishCallback()
{
var data = $('#textarea').val();
$.ajax({
method: 'post',
data: data,
dataType: 'html',
url: "include/library/pull_sim.php",
success: function(result) {
successmessage = 'Data was succesfully captured';
$("#error3_li").text(result);
},
});
}
PHP:
Php receives the posted textarea value, check if a similar_text is already into db and if yes, it alerts that to user by the ajax call result.
if((!ISSET($_POST['testo'])))
$val='';
else
$val=$_POST['testo'];
$q_sim='select nciarfata from nciarf.nciarfata';
$s_sim=mysqli_query($conn,$q_sim);
$n_sim=mysqli_num_rows($s_sim);
if ($n_sim>0)
{
$simil=array();
for ($i=0;$i<$n_sim;$i++)
{
$rou=mysqli_fetch_row($s_sim);
similar_text($val, $rou[0], $percent);
if ($percent>=95.0)
{
array_push($simil,$rou[0]);
}
}
echo"val=$val, rou[0]=$rou[0], percent=$percent";
}
Question:
In my opinion something goes wrong in server side, probably in the 1st if.
Php doesnt recognized the posted value and then assign val="" instead of real text typed by user before..
Why?
Thanks for helping me.
I find the solution here:
Can't figure out why PHP not receiving POST data from $.ajax call
It wasn't a textarea issue but an ajax jquery one (data option).

angularUI select dropdown displays data only after entering a character

I am using AngularJS v1.2.15 and angular-ui / ui-select. My select HTML is:
<div class="form-group col-md-3">
<div class="input-group select2-bootstrap-append">
<ui-select ng-model="modelOwner.selected" theme="select2" class="form-control">
<match placeholder="Select Owner">{{$select.selected.name}}</match>
<choices repeat="item in owner | filter: $select.search">
<span ng-bind-html="item.name | highlight: $select.search"></span>
</choices>
</ui-select>
<span class="input-group-btn">
<button ng-click="modelOwner.selected = undefined" class="btn btn-danger">
<span class="glyphicon glyphicon-trash"></span>
</button>
</span>
</div>
</div>
My call in controller is:
$scope.modelOwner = {};
OwnersFactory.query({}, function (data) {
$scope.owner = data;
});
My service code:
bootstrapApp.factory('OwnersFactory', function ($http,$state,serviceUrl,$resource,$log) {
return $resource(serviceUrl + 'owner/:id', {}, {
show: { method: 'GET', params: {}, isArray: false }
})
});
Now, in my form i can view the values only after entering at least a single character. I want this select dropdown to display values just by clicking on the dropdown (not by entering any character.)
Possible Solution: if i could load my state only after all the AJAX calls have been made.
Please help me out here.
if you are using ui-router you can use resolve on each state, so that the call is resolved before initializing the controller
https://github.com/angular-ui/ui-router/wiki#resolve

Django with Ajax and jQuery

I would like after clicking on one of the many Item shown a window with his description (single item description).
How to create this using Ajax and jQuery with Django?
model:
class Item(models.Model):
name = models.CharField(max_length=50)
slug = models.SlugField()
price = models.DecimalField(max_digits=5, decimal_places=2)
desc = models.TextField()
views:
def item_list(request):
items = Item.objects.all()[:6]
return render_to_response('items.html', {'items':items}, context_instance=RequestContext(request))
def single_item(request, slug):
item = Item.objects.get(slug=slug)
return render_to_response('single.html', {'item':item}, context_instance=RequestContext(request))
template:
<!-- Single item description: -->
<div id="description">
<img src="/site_media/images/photo.png">
<div id="item_description">
<input name="add" type="button" id="add" value="Add to Cart">
<p class="title">Single Item name</p>
<p class="description"><span>Description:</span>
This is single item description
</p>
</div>
</div>
<!-- All item: -->
<div id="item">
{% for i in items %}
<div class="item">
<img src="/{{ i.image.url }}" />
<p>
<span> {{ i.name }} </span>
<span> {{i.price}} </span>
</p>
</div>
{% endfor %}
</div>
</div>
</div>
If you want to use ajax to refresh your page, you'll need to do three things:
Add an entry to urls.py for the ajax call (or add a condition to your view function to process the request if it's ajax)
Add the javascript block to make the ajax call and update the html/text with the new data
Add the code in your views.py to handle the ajax call and respond with json data
urls.py
...
url(r'/ajax-view-single/)/$', 'ajax_single_item', name='app_name_ajax_single_item'),
html/js
<script type="text/javascript" src="/js/json2.js"></script>
$("#view-single-item").click(function () {
try {
// get slug from html
var slug = "";
var data = {
slug: slug
};
$.get('{% url app_name_ajax_single_item %}', data, function(data){
// your data returned from django is in data
alert(data.item_name);
}, 'json');
//$('#error').hide();
}
catch(err) {
$('#error').html(err);
$('#error').show();
}
return false;
});
views.py
from django.http import HttpResponse
from django.utils import simplejson
from django.shortcuts import get_object_or_404
def ajax_single_item(request):
'''gets single item'''
if not request.is_ajax():
return HttpResponse(simplejson.dumps({'result': False}))
# get slug from data
slug = request.GET.get('slug', None)
# get item from slug
item = get_object_or_404(Item, slug=slug)
return HttpResponse(simplejson.dumps({
'result': True,
'item_name': item.name,
'item_price': item.price,
'item_desc': item.desc,
'item_slug': item.slug
}))

Resources