Add new object to list without refreshing with Django & Ajax - django

I'm searching for someone who helps me in a Django project with JS, Ajax and jquery.
I'm trying to create something like adding objects on the django-admin page. I used https://www.pluralsight.com/guides/work-with-ajax-django, and almost everything is working fine but...
On my form, I have multiple choice field with authors, when I pressed the button to add a new author, the object is properly saving in DB, but on the form, I can't see a new object. When I reload the page, the new object is on this multiple choice field.
I thought I should refresh the field to see a new object on the list, but I don't know it's the proper way to meet this goal.
[edit]
models.py
class Author(models.Model):
name = models.CharField(max_length=100)
class Book(models.Model):
book_author = models.ManyToManyField(Author,blank=True,)
...
form.py
class AuthorForm(forms.ModelForm):
class Meta:
model = Author
fields = ['name', ]
widgets = {
'name': forms.TextInput(),
}
views.py
I added class SaveAutor
def author_add_view(request):
form = AuthorForm()
return render(request,
"author/custom_create_author.html",
{"form": form})
class SaveAuthor(View):
template_name = "author/custom_create_author.html"
def get(self, request):
author_form = AuthorForm(request)
return render(request,
self.template_name,
{'form': author_form})
def post(self, request):
#assume authorForm has author_name defined
author_form = AuthorForm(data=request.POST)
if author_form.is_valid():
author = Author() #here is class name or form name?
author.name = author_form.cleaned_data['name']
author.save()
return JsonResponse({'author_id': author.id,
'author_name': author.name})
# error response or whatever you want to return
return JsonResponse({'error': 'author form is not valid'})
I had these views registered in urls.py
urls.py
# add an author
path('author/add/', views.author_add_view,
name='author_add'),
# not sure if I should add as_view() at the end
path('author/new-add/', views.SaveAuthor.as_view(),
name='new_author_add'),
When I try check if page with form is displaying properly using the SaveAuthor class based view I get error 'WSGIRequest' object has no attribute 'get', but when I use the author_add_view I got the template.
custom_create_author.html
$("#author-form").submit(function (e) {
// preventing from page reload and default actions
e.preventDefault();
// serialize the data for sending the form data.
var serializedData = $(this).serialize();
// make POST ajax call
$.ajax({
type: 'POST',
url: "{% url '.' %}", //serializer_ajax_mehit_from_vies
data: serializedData,
success: function (response) {
// on successfull creating object
// 1. clear the form.
$("#author-form").trigger('reset');
// 2. focus to nickname input
$("#id_author_name").focus();
},
error: function (response) {
// alert the error if any error occured
alert(response["responseJSON"]["error"]);
}
})
})
{% load static %}
{% load widget_tweaks %}
{% block content %}
<h4>
My author
</h4>
<form id="author-form">
{% csrf_token %}
<p>{{ form.as_p }}</p>
<button class="btn btn-outline-success" type="submit">save</button>
</form>
<br>
{% endblock %}
Here is another page where I'm trying to connect the book with multiple-choice-field author (it's typical form, but I'm enclosing only the button to pop-up the form, where I can add the new author)
add_book.html js code open pop-up windows to create new author
<script type="text/javascript">
$(function () {
$("#create-author").modalForm({
formURL: "{% url 'author_add' %}"
});
})
</script>
<button id="create-author" class="btn btn-primary" type="button" name="button">
<span class="fa fa-plus"/>
</button>
And on this page, I tried to paste your JS code
<script type="text/javascript">
// assume the add author button has an id of add_author_button
$('#create-author').click(function(event){
event.preventDefault();
// assume the text field has an id of author_name
author_name= $('#author_name').val();
create_post(event, author_name);
}
) //<-------- this closing bracket was missing?
function create_post(event, author_name) {
$.ajax({
url: "{% url '.' %}", // the endpoint I'll precise that in comment
type: "POST", // http method
data: {
author_name: author_name,
csrfmiddlewaretoken: $('[name="csrfmiddlewaretoken"]').val()
},
// handle a successful response - data will be a json object returned from your view method
success: function (data) {
if (data.error === null) {
// assume your author multiple choice select has an id of author_sel
// this will append the new author name to the list and will also
// set the value for this author to be the newly created id so you can
// perform other functions on the author like update and/or delete
$('#author_id').append($('<option/>', {
value: data.author_id,
text: data.author_name,
}));
} else {
// display the error on the page
// and/or write it to the console log
console.log(data.error);
}
},
// handle a non-successful http response
error: function (xhr, errmsg, err) {
// display the error on the page
// and/or write it to the console log
console.log(xhr.status + ": " + xhr.responseText); // provide a bit more info about the error to the console
}
});
}
</script>
One closing bracket was missing, so I added in on the JS script.
I had a problem with the endpoint, when I pass the class-based view SaveAuthor(View) (new_author_add by url name) I got the message: the author form is not valid, but when I used author_add_view (author_add by url name) undefined.

The issue is that while you are using AJAX to submit your new author, the author isn't being added to the author's multiple choice field in the current HTML page. Refreshing the page will retrieve the new value but that also does an entire post/refresh loop. Since you are submitting the post using AJAX, you can return the new author's id and name via a JsonResponse and use jQuery to add it to the author's multiple choice field.
views.py
from MyApp.forms import AuthorForm
from MyApp.models import Author
from django.shortcuts import render
from django.views import View
from django.http.response import JsonResponse
class SaveAuthor(View):
template_name = "author/author.html"
def get(self, request):
author_form = AuthorForm()
return render(request,
self.template_name,
{"form": author_form,
"authors":Author.objects.all()})
def post(self, request):
#assume authorForm has author_name defined
author_form = AuthorForm(data=request.POST)
if author_form.is_valid():
author = Author() #here is class name or form name?
author.name = author_form.cleaned_data['name']
author.save()
return JsonResponse({'author_id': author.id,
'author_name': author.name})
# error response or whatever you want to return
return JsonResponse({'error': 'author form is not valid'})Your AJAX
author.html
<!DOCTYPE html>
{% load static %}
<script src="{% static "jquery-3.4.1.min.js" %}"></script>
{% block content %}
<h4>
My author
</h4>
<select id="author_sel" name="author_sel" size="5" class="selectbox">
{% for author in authors %}
<option value="{{author.id}}">{{author.name|capfirst}}</option>
{% endfor %}
</select>
<form id="author-form">
{% csrf_token %}
<p>{{ form.as_p }}</p>
<input type="button" name="button" class="submit_button" id="add_author_button" value="Save">
</form>
<br>
{% endblock %}
<script type="text/javascript">
// assume the add author button has an id of add_author_button
$('#add_author_button').click(function(event){
event.preventDefault();
// assume the text field has an id of author_name
author_name= $('#id_name').val();
create_post(event, author_name);
}) //<-------- this closing bracket was missing?
function create_post(event, author_name) {
$.ajax({
url: ".", // the endpoint I'll precise that in comment
type: "POST", // http method
data: {
name: author_name,
csrfmiddlewaretoken: $('[name="csrfmiddlewaretoken"]').val()
},
// handle a successful response - data will be a json object returned from your view method
success: function (data) {
if (data.error === undefined) {
// assume your author multiple choice select has an id of author_sel
// this will append the new author name to the list and will also
// set the value for this author to be the newly created id so you can
// perform other functions on the author like update and/or delete
$('#author_sel').append($('<option/>', {
value: data.author_id,
text: data.author_name,
}));
} else {
// display the error on the page
// and/or write it to the console log
console.log(data.error);
}
},
// handle a non-successful http response
error: function (xhr, errmsg, err) {
// display the error on the page
// and/or write it to the console log
console.log(xhr.status + ": " + xhr.responseText); // provide a bit more info about the error to the console
}
});
}
</script>
urls.py
from django.urls import path
from . import views
app_name = 'myapp'
urlpatterns = [
# add an author
path('add/', views.SaveAuthor.as_view(), name='author_add'),
]
forms.py
from django import forms
from MyApp.models import Author
class AuthorForm(forms.ModelForm):
class Meta:
model = Author
fields = ['name', ]
widgets = {
'name': forms.TextInput(),
}
models.py
from django.db import models
# Create your models here.
class Author(models.Model):
name = models.CharField(max_length=100)
This is now a complete working example.

Related

How to re-display formset & Select2 field with selected value on form error in Django

After searching for several days and trying different options, I decided to finally post the issue and question.
I have a template that has a form and 2 different formsets.
One of the formsets uses an intermediate model with a GenericForeignKey that will reference two other models.
For the formset, I am using an inlineformset and adding a CharField which is used with Select2 to make an ajax call to check the two other models. The value returned by the ajax call will be a json/dict with 3 key/value pairs.
The issue I am having is that when the template is submitted and there are errors, how can I redisplay the value that was entered in the Select2 CharField when the template is presented again?
The value is in self.data and is sent back to the template.
However, everything I've tried so far will not redisplay the select2 field with the value selected previously or the values that were submitted.
The submitted values are returned to the template in a json/dict, key/value, format under form.fieldname.value but I am not sure how I can use that to repopulate the select2 field.
I appreciate any suggestions or links. If there is an alternate way to set this up, I am interested to hear.
Thank you.
UPDATE: 2021-03-18
Here is, hopefully all, the relevant bits from the various files.
models.py
class SiteDomain(models.Model):
website = models.ForeignKey(
WebSite,
on_delete=models.CASCADE,
)
domain_model = models.ForeignKey(
ContentType,
on_delete=models.CASCADE,
help_text=(
"The model that the website entry is related to. eg: Domain or SubDomain"
),
)
object_id = models.PositiveIntegerField(
help_text="The ID of the model object the entry is related to."
)
content_object = GenericForeignKey("domain_model", "object_id")
content_object.short_description = "Domain Name:"
views.py
class AddWebsite(View):
def get(self, request, *args, **kwargs):
domain_formset = inlineformset_factory(
WebSite,
SiteDomain,
formset=SiteDomainInlineFormSet,
fields=(),
extra=3,
)
forms.py
class SiteDomainInlineFormSet(BaseInlineFormSet):
def __init__(self, *args, **kwargs):
self.account = kwargs.pop('account', None)
super(SiteDomainInlineFormSet, self).__init__(*args, **kwargs)
def add_fields(self, form, index):
super().add_fields(form, index)
form.fields["domain_name"] = forms.CharField(
max_length=255,
widget=forms.Select(),
required=False,
)
template
<script type="text/javascript">
function s2search() {
$('.domain-lookup-ajax').select2({
width: 'style',
ajax: {
url: "{% url 'accounts_ajax:website_domain_lookup' %}",
dataType: 'json',
delay: 250,
data: function (params) {
var query = {
term: params.term,
acct_id: '{{ account.id }}',
}
return query;
},
processResults: function (data, params) {
return {
results: data,
};
},
cache: true
},
placeholder: 'Enter at least 2 characters for search.',
minimumInputLength: 2,
});
}
</script>
<form action="" method="post">
{% csrf_token %}
{{ domain_formset.management_form }}
{{ app_formset.management_form }}
{% for form in domain_formset %}
<div class="domainfieldWrapper" id="row_{{ forloop.counter0 }}">
<select id="id_dform-{{ forloop.counter0 }}-domain_name" class="domain_name domain-lookup-ajax" name="dform-{{ forloop.counter0 }}-domain_name"></select>
<button id="id_dform-{{ forloop.counter0 }}-button" class="button" type="button" onclick="clearSelect('id_dform-{{ forloop.counter0 }}-domain_name')">Clear</button>
</div>
{% endfor %}
</form>
The ajax call will return something like:
{"model_id":"74", "domain_id":"177", "name":"alfa.first-example.com"}
A side note:
I also tested the select2 field in the second formset and it does not get repopulated either when the template is reloaded if there are any form errors. Which I kind of expected since it basically uses the same setup except for the value returned by the ajax call which is for a normal ModelChoiceField.
Using a combination of https://select2.org/programmatic-control/add-select-clear-items#preselecting-options-in-an-remotely-sourced-ajax-select2, js and Django template tags I was able to get something that works for me.

Django get specific QuerySet with GET ajax Call on button click

i have a problem and i dont know if im using the good way to solve it , but their is the problem , i have a client list that i show on the client page , by getting all client with a simple
clients = client.objects.all()
so all client can have a lot of sessions, and session have a lot of clients, its like a ManytoMany relation, so what im trynna do its to show the assigned session of client one by one by clicking on a button (the button open a boostrap modal ) , so i tried to send the id of the the chosen client on click and send it into a django view with ajax GET method, and take this ID directly to find all sessions related with this client and return the query to this page , so the ajax is working correctly and i can send the id , but its like the view its not sending anything . so their is my code hope you can help me :
Html (the div im inserting on the forloop client) :
<div class="list-group list-group-me">
<ul class="list-group list-group-horizontal">
<li class="list-group-item">{{ client.name }}</li>
<li class="list-group-item">{{ client.email }}</li>
<li class="list-group-item">{{ client.created_at | date:" M Y" }}</li>
<li class="list-group-item list-group-item-success">Active</li>
<li class="list-group-item">025f55azg5</li>
<li><div class="btn-group">
<button type="button" class="btn btn-primary" data-toggle="modal" data-target="#exampleModal" id="AddSession"
data-id="{{ client.id }}">
Add
</button>
<button type="button" class="btn btn-primary" data-id="{{ client.id }}" >View</button>
</div>
</li>
</ul>
</div>
the view (tryin the .all() just to see if its working) :
class show_session(View):
def get(self, request , id):
Sclient = session.objects.all()
#Sclient = session.objects.filter(client__id=id)
context = { 'Sclient': Sclient }
return render(request, 'coach/addclient.html', { 'Sclient': Sclient })
the model.py :
class session(models.Model):
name = models.CharField(max_length=80)
client = models.ManyToManyField(client, blank=True)
coach = models.ForeignKey(User, on_delete=models.CASCADE, null=True)
created_at = models.DateTimeField(auto_now_add=True)
detail = models.CharField(max_length=256)
def __str__(self):
return self.name
the main view of the page :
def addclient(request):
form = ClientForm
clients = client.objects.filter(affiliation=request.user.id)
Csession = session.objects.filter(coach=request.user.id)
context = {'form': form ,'clients': clients , 'Csession' : Csession}
form = ClientForm()
if request.method == 'POST':
form = ClientForm(request.POST)
print(form)
if form.is_valid():
print('adding client 1133', form)
name = request.POST.get('name')
email = request.POST.get('email')
new_client = client.objects.create(name= name, email=email , affiliation=request.user)
new_client.save()
return JsonResponse({'client': model_to_dict(new_client)}, status=200)
else:
print('not adding client to the form 1333')
return redirect('addclient')
return render(request, 'coach/addclient.html', context= context)
and the ajax function :
$("#AddSession").click(function(){
var dataID = $(this).data('id');
console.log(dataID)
$.ajax({
url:'addclient/'+ dataID +'/added',
data: {
csrfmiddlewaretoken: csrfToken,
id: dataID
},
type : "get",
success: function(response) {
console.log("hey hey session over here");
}
})
});
i dont know if can use just the main view to get the data and display it , and when i try to acess the url of show_session.view , the query set is working but im still tryin to display it on the addclient url
thanks for your time and help !
so i have fixed the problem , i have just used a POST method to send the id of current user to the view then i used the action data attribute to handle multiple post on my view and use the id given by ajax to have the correct queryset and serialized the queryset into a JSON object so ajax can add the session assiciated with the choosen client on click their is the code :
View :
if request.method == 'POST' and request.POST['action'] == 'session':
print("session response")
id = request.POST.get('id')
print(id)
#Sclient = list(session.objects.filter(coach=request.user.id))
Sclient = session.objects.filter(client__id=id)
SerializedQuery = serializers.serialize('json', Sclient)
return JsonResponse(SerializedQuery, safe=False)
Ajax :
$("#AddSession").click(function(){
var dataID = $(this).data('id');
$.ajax({
url: $(this).data('url'),
data: {
csrfmiddlewaretoken: csrfToken,
id: dataID,
action: 'session',
//dataType:"json"
},
type : "post",
success: function(response) {
console.log("hey hey session over here");
console.log(response)
var obj = jQuery.parseJSON(response)
//console.log(obj[1].fields.name)
var Sarray = [];
var Selector = $("#assigned");
var count = $("#assigned span")
console.log(count.length)
//used to limit the number of element on div on first click
if(count.length < obj.length)
{
for (i = 0 ; i < obj.length ; i++) {
// console.log(obj[i].fields.name)
Sarray.push(obj[i].fields.name)
Selector.append('<span class="badge badge-success">'+ obj[i].fields.name +' x </span>')
}
console.log("yoow",Sarray.length)
}
}
})
});

How to integrate a form into a Detail View?

I would like to do:
I am trying to create a form input on a detail view that will update a particular data column ('status') of the detailed model instance. Here is a picture of what I have in mind:
The selector would display the current status and the user could change it and update from the detail view without having to access the UpdateView.
my idea here would be to have this happen:
1. On submit, get the new user entered value.
2. get the model instance of the currently detailed class
3. assign the model instance attribute as the user entered value
4. save the model instance
I've tried: I don't know if this is the best way to do this but i've been trying to create an AJAX call, mostly by looking for examples online.
Results: Terminal shows Post on submit: "[19/Nov/2019 17:50:33] "POST /task/edit/4 HTTP/1.1" 200 41256". However, the data is not saved to the db. On refresh, the selector returns to previously saved status.
The console shows: "script is connected", and "Update Status" with no errors. On submit, the alert displays success message: "127.0.0.1:8000 says status updated".
Task_detail.html
<div class="deliv-box edit">
<form id="status-update-form" method='POST' action='{% url "task_edit" task.pk %}'>
{% csrf_token %}
{{task_form.status}}
<input id="status-update-btn" type="submit" value="Update Status" />
</form>
</div>
...
<script type="text/javascript">
var frm = $('#status-update-form');
frm.submit(function () {
console.log("script is connected")
console.log($('#status-update-btn').val())
$.ajax({
type: frm.attr('method'),
url: frm.attr('action'),
data: frm.serialize(),
success: function (data) {
$("#deliv-box edit").html(data);
alert("status updated");
},
error: function(data) {
alert("error");
}
});
return false;
});
</script>
forms.py
class TaskForm(forms.ModelForm):
class Meta:
model = Task
fields = "__all__"
views.py
class TaskDetail(ModelFormMixin, DetailView):
template_name='task_detail.html'
model = Task
form_class = TaskForm
def get_context_data(self, **kwargs):
context = super(TaskDetail, self).get_context_data(**kwargs)
context['task_form'] = self.get_form
return context
def update(request):
if request.method=='POST':
task_id = request.POST.get('id')
task = Task.objects.get(pk = task_id)
status_obj = request.POST.get('status')
task.status = status_obj
task.save()
return JsonResponse({'status':'updated...'})
else:
return JsonResponse({'status':'not updated'})
thank you.
A solution:
In the unlikely event that someone stumbles across this question and who is, like me, just trying to figure it out all by themselves, here is what I've learned about how this works: When a user wants to update a form, Django pre-populates the form with the existing data related to that instance. A user can then alter the data and re-submit the form.
Here, I was attempting to alter just one field of the exiting instance, but as I was only calling that one field, Django was assuming not, as I had hoped, that the other fields would remain the same, but that I intended the other fields to be submitted as blank. Where the fields are required one cannot return that field as blank. Therefore, Django was not able to validate the form and so the form did not get updated.
A solution that works is to call all the fields as hidden and show just the one you want to alter. This way Django can return the unaltered data and validate the form, and you get an update button on your detail view:
<form method="POST">
{% csrf_token %}
<h4> STATUS: </h4>
{% for field in form %}
{{ field.as_hidden }}
{% endfor %}
{{form.status}}
<button type="submit" class="btn btn-success">submit</button>
</form>
You are overriding the method update which does not exist, so it is never called.
You need to subclass UpdateView instead of the DetailView and the mixin.
class TaskUpdateView(UpdateView):
template_name='task_detail.html'
model = Task
form_class = TaskForm
# you can use the line below instead of defining form_class to generate a model form automatically
# fields = ('status', )
def form_valid(self, form):
post = form.save(commit=False)
# do anything here before you commit the save
post.save()
# or instead of two lines above, just do post = form.save()
return JsonResponse({'status':'updated...'})
Here is how you would add readonly (disabled) fields to your form:
class TaskForm(forms.ModelForm):
# override the default form field definitions for readonly fields
other_field = forms.CharField(disabled=True)
another_field = forms.IntegerField(disabled=True)
class Meta:
model = Task
fields = ("status", "other_field", "another_field")
# you could also just do:
# fields = '__all__'

How to add information in a page without refreshing the page?

I would like to have a page in my django application that has a button that search a product and after selecting quantities gets added to the page (without reloading) in a list where the total get calculated (something like that), I am a beginner in programing and I have a week reading and investigated how to do it but I don't found anything.
Is because you need other programming language? Or could you indicate me some documentation or some example that I can read. Mostly because for my inexperience I don't know how to identify the relevant information in the documentation or even what to look for.
This can be done using Ajax call,
check this example:
forms.py
class sampleForm(forms.Form):
input = forms.CharField()
views.py
from django.http import JsonResponse
def sampleview(request):
input = request.POST.get('input', None)
#perform your logic here
#let us say your data is in variable result
result = {'product1' : 'python' ,'product2' : 'django' , 'product3' : 'ajax' }
return JsonResponse(result)
urls.py
from django.urls import path, include
from . import views
urlpatterns = [
path('sampleview',views.sampleview,name='sampleview'),
]
your HTML
<form method="POST">
{% csrf_token %}
{{form.as_p}}
<button id="sampleform-submit" type="submit">submit</button>
</form>
<div id="results"></div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script>
$("#sampleform-submt").click(function(){
e.preventDefault();
var form = $('#id_input').closest("form")
//id_input is id of input tag generated by form and above line selects the form
$.ajax({
url : "{% url 'sampleview' %}",
type: "POST",
data : form.serialize(),
dataType: 'json',
success: function(data){
#data is 'result' you return in sampleview function
$("#results").append('<p> '+ data.product1 +'</p>');
$("#results").append('<p> '+ data.product2 +'</p>');
$("#results").append('<p> '+ data.product3 +'</p>');
}
});
}
</script>
I hope this helps

Django: How to upload a file using ajax

I am using django 1.5, python 2.7 and jquery 1.9. I have a form which has precisely 2 fields i.e. title and document. When I press submit I want the users chosen document to be present in the request.FILES as shown in the view.
When I submit the regular form (without ajax), this works fine, but with ajax I do not get the file field in my request. Any suggestions on how to upload a file using ajax.
HTML:
<form enctype="multipart/form-data" action="{% url 'upload_document' %}" method="post" id="uploadForm">
{% csrf_token %}
<ul>
<li>
<div>Title</div>
<input id="title" type="text" maxlength="200"/>
<div class="error"></div>
</li>
<li>
<div>Upload File</div>
<input id="document" type="file" size="15" />
<div class="error"></div>
</li>
</ul>
<input type="submit" value="submit"/></p>
</form>
FORMS.PY:
class UploadForm( forms.Form ):
document = forms.FileField()
title = forms.CharField(max_length = 200)
def clean(self):
cleaned_data = super(UploadForm, self).clean()
return cleaned_data
def save(self, *args, **kwargs):
title = self.cleaned_data['title']
doc = self.cleaned_data['document']
document = Document(title = title, document = doc)
document.save()
return document
SCRIPT:
<script type="text/javascript">
$("#uploadForm").submit(function(event){
event.preventDefault();
$.ajax({
url : "{% url 'upload_document' %}",
type: "POST",
data : {csrfmiddlewaretoken: document.getElementsByName('csrfmiddlewaretoken')[0].value,
title: document.getElementById('title').value,
//document: document: document.getElementById('document'),
},
dataType : "json",
success: function( response ){
if(response == "True"){
// success
}
else {
//append errors
}
}
});
});
</script>
VIEWs.PY
def upload_document(request):
print request.POST
print request.FILES
if request.is_ajax():
if request.method == 'POST':
form = UploadForm(request.POST, request.FILES, user = request.user)
if form.is_valid():
form.save()
return HttpResponse(simplejson.dumps('True'), mimetype = 'application/json' )
else:
errors = form.errors
return HttpResponse(simplejson.dumps(errors), mimetype = 'application/json' )
The answer to that question is not that simple. First of all if you intend to support old browsers then indeed it gets nasty. You have to deal with hidden iframes and some JavaScript tricks. I do advice using some well-known scripts for that like jQuery-File-Upload.
But the world is evolving and new technologies arise including HTML5. There's a new File API which is available in most modern browsers ( IE10+, FireFox3.6+, Chrome13+, see: http://caniuse.com/fileapi ) which can be used for that. First you need some HTML:
<input type="file" id="file-select" />
Then you can bind to (for example) change event:
$('#file-select').change( handleFileSelect );
and finally the handler itself:
var data = {};
function createReaderHandler(name) {
return function(ev) {
data[name] = ev.target.result;
};
}
function handleFileSelect(ev) {
var files = ev.target.files; // FileList object
// Loop through the FileList
for (var i = 0; i < files.length; i++) {
var file = files[i],
name = file.name || file.fileName,
reader = new FileReader();
reader.onload = createReaderHandler(name);
reader.readAsText(file);
}
}
Once the data is loaded into JavaScript memory (note that the operation is asynchronous) you can send it via AJAX like any other data. There are more options: depending on your file you can read it as a binary data using .readAsBinaryString and so on. Google is your friend. :)
Also I think there already are good scripts for uploading files with a fallback to old methods. This one can be interesting (haven't tried it):
http://www.plupload.com/
I think the issue is in the submit button, change it into normal button
ie, <button type='button' id='submit'>submit</button>(by default all buttons in form are submit)
and the ajax as
$('#submit').on('click',function(){
frm = $(this).parents('form')
$.ajax({
type: frm.attr('method'),
dataType:'json',
url: frm.attr('action'),
data: frm.serialize(),
async: false,
success: function (data) {
console.log('success')
},
error: function(data) {
console.log("Something went wrong!");
}
})
All others will be same
Just try it will work