Reputation: 639
I'm having app that using ajax to submit model form.
ISSUE: the submit works fine and edit the database. but the response renders in manage_user
("users/manage"
in another wod), not the same page I'm working on "users/"
in urls.py:
path('users/', views.users, name = 'users'),
path('users/manage', views.manage_users, name = 'manage_users'),
in views.py:
@login_required(login_url="/login/")
def users(request):
#Defining Needed variables
context = {}
crud = CRUDHandler()
queryset = Q() #if filters applied to crud or formset
#Getting data for view
crud.fields=['username','first_name','last_name','email','id']
dataset=crud.r_user()
#Adding data to context
context['dataset']=dataset
context['dataset_title']= 'User'
context['handle_url']='manage_users'
return TemplateResponse(request,'table-view.html',context)
@login_required(login_url="/login/")
def manage_users(request):
done = []
fail = []
form = None
context = {}
template_path = ""
if 'edit'in request.POST:
instance_id = request.POST.get('instance_id')
user = get_object_or_404(User,pk=instance_id)
form = UserInfoForm(request.POST or None,instance=user)
if form.is_valid():
exsisting_user = form.save()
if isinstance(exsisting_user,User):
done.append("User "+exsisting_user.first_name+" updated successfully!")
else:
fail.append(exsisting_user) # returning errors
else:
fail.append("Somthing went wrong, check your input!")
template_path = "components/forms/instance_edit_form.html"
# reload users
crud.fields=['username','first_name','last_name','email','id']
dataset=crud.r_user()
# construct the context
context['done'] = done
context['fail'] = fail
context['dataset'] = dataset
context['form'] = form
context['handle_url'] = 'manage_users'
# load form template
html_form = loader.render_to_string(template_path, context, request)
# load table template
html_table = loader.render_to_string( "components/tables/model-table-view.html", context, request )
return JsonResponse({'form':html_form,'table':html_table,'done':done,'fail':fail})
in handler.js:
$(document).ready(function(){
/* load form */
var loadForm = function () {
var btn = $(this);
$.ajax({
url: btn.attr("data-url"),
type: 'POST',
data: btn.parents("form").serialize(),
dataType: 'json',
beforeSend: function () {
$("#modal_form .modal-content").html("");
$("#modal_form").modal("show");
},
success: function (data) {
$("#modal_form .modal-content").html(data.form);
},
error : function(xhr,errmsg,err) {
$("#modal_form .modal-content").html(xhr.status + ": " + xhr.responseText); // provide a bit more info about the error to the console
},
});
return false;
};
/* save form */
var saveForm = function () {
var form = $(this);
$.ajax({
url: form.attr("action"),
data: form.serialize(),
type: 'POST',
dataType: 'json',
success: function (data) {
if (data.done) {
$("#modal_form").modal("hide");
$("#datatable_feature").parent().html(data.table);
}
else {
// $("#modal_form").modal("show");
$("#modal_form .modal-content").html(data.form);
}
},
error : function(xhr,errmsg,err) {
$("#modal_form .modal-content").html(xhr.status + ": " + xhr.responseText); // provide a bit more info about the error to the console
},
});
return false;
};
/* Binding */
// View instance
$(".js-view-inst-btn").on("click", loadForm);
// Create instance
$(".js-add-inst-btn").on("click", loadForm);
$("#modal_form form").on("submit", ".js-instance-create-form", saveForm);
// Update instance
$(".js-edit-inst-btn").on("click", loadForm);
$("#modal_form form").on("submit", ".js-instance-update-form", saveForm);
// Delete instance
$(".js-del-inst-btn").on("click", loadForm);
$("#modal_form form").on("submit", ".js-instance-delete-form", saveForm);
});
the table view /components/tables/model-table-view.html
:
{% if done %}
<div class="card bg-success text-white shadow">
<ul>
{% for success_msg in done %}
<li> {{success_msg}} </li>
{% endfor %}
</ul>
</div>
{% endif %}
<table id="datatable_feature" class="table table-bordered table-striped">
<thead>
{% for row in dataset|slice:":1" %}
<tr>
{% for field in row %}
{% ifequal field 'id' %}
<td>Options</td>
{% else %}
<td>{{field}}</td>
{% endifequal %}
{% endfor %}
</tr>
{% endfor %}
</thead>
<tbody>
{% for row in dataset %}
<tr>
{% for key,value in row.items %}
{% ifequal key 'id' %}
<td>
<form method="POST" action="{% url handle_url %}">
{% csrf_token %}
<input type="hidden" name="instance_id" value="{{ row.id }}"></input>
<input type="hidden" name="get_edit" value="{{ row.id }}"></input>
<button type="button" class="btn btn-warning btn-sm js-edit-inst-btn" data-url="{% url handle_url %}">
<i class="fas fa-edit"></i> Edit
</button>
</form>
<form method="POST" action="{% url handle_url %}">
{% csrf_token %}
<input type="hidden" name="instance_id" value="{{ row.id }}"></input>
<input type="hidden" name="get_view" value="{{ row.id }}"></input>
<button type="button" class="btn btn-primary btn-sm js-view-inst-btn" data-url="{% url handle_url %}">
<i class="fas fa-eye"></i> View
</button>
</form>
<form method="POST" action="{% url handle_url %}">
{% csrf_token %}
<input type="hidden" name="instance_id" value="{{ row.id }}"></input>
<input type="hidden" name="get_delete" value="{{ row.id }}"></input>
<button type="button" class="btn btn-danger btn-sm js-del-inst-btn" data-url="{% url handle_url %}">
<i class="fas fa-trash-alt"></i> Delete
</button>
</form>
</td>
{% else %}
<td>{{value}}</td>
{% endifequal %}
{% endfor %}
</tr>
{% endfor %}
</tbody>
<tfoot>
{% for row in dataset|slice:":1" %}
<tr>
{% for field in row %}
{% ifequal field 'id' %}
<td>Options</td>
{% else %}
<td>{{field}}</td>
{% endifequal %}
{% endfor %}
</tr>
{% endfor %}
</tfoot>
</table>
the form view /components/forms/instance_edit_form.html
:
<form method="POST" action="{% url handle_url %}">
{% csrf_token %}
<div class="modal-header">
<h4 class="modal-title">{{ dataset_title }} Edit Info</h4>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
{% if fail %}
<div class="card bg-danger text-white shadow">
<ul>
{% for fail_msg in fail %}
<li> {{fail_msg}} </li>
{% endfor %}
</ul>
</div>
{% endif %}
{%comment%}
render form here
{%endcomment%}
<table>
{{form.as_table}}
</table>
</div>
<div class="modal-footer justify-content-between">
<input type="hidden" name="instance_id" value="{{form.instance.id}}"/>
<button type="submitt" name="edit" class="btn btn-primary">Save changes</button>
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</form>
Table View table-view.html
:
{% extends "layouts/base.html" %}
{% block title %} Edu Portal {% endblock %}
<!-- Element injected in the BODY element -->
{% block body_class %} {{dataset_title}} {% endblock body_class %}
<!-- Specific Page CSS goes HERE -->
{% block stylesheets %}
<!-- Google Font: Source Sans Pro -->
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Source+Sans+Pro:300,400,400i,700&display=fallback">
<!-- Font Awesome -->
<link rel="stylesheet" href="/static/assets/plugins/fontawesome-free/css/all.min.css">
<!-- DataTables -->
<link rel="stylesheet" href="/static/assets/plugins/datatables-bs4/css/dataTables.bootstrap4.min.css">
<link rel="stylesheet" href="/static/assets/plugins/datatables-responsive/css/responsive.bootstrap4.min.css">
<!-- Theme style -->
<link rel="stylesheet" href="/static/assets/css/adminlte.min.css">
{% endblock stylesheets %}
{% block content %}
<div class="content-wrapper">
<!-- Content Header (Page header) -->
<section class="content-header">
<div class="card">
<div class="card-header">
<h3 class="card-title">{{dataset_title}}s Table Management</h3>
</div>
<!-- /.card-header -->
<div class="card-body">
{% if done %}
<div class="card bg-success text-white shadow">
<ul>
{% for success_msg in done %}
<li> {{success_msg}} </li>
{% endfor %}
</ul>
</div>
{% endif %}
<table id="datatable_feature" class="table table-bordered table-striped">
<thead>
{% for row in dataset|slice:":1" %}
<tr>
{% for field in row %}
{% ifequal field 'id' %}
<td>Options</td>
{% else %}
<td>{{field}}</td>
{% endifequal %}
{% endfor %}
</tr>
{% endfor %}
</thead>
<tbody>
{% for row in dataset %}
<tr>
{% for key,value in row.items %}
{% ifequal key 'id' %}
<td>
<form method="POST" action="{% url handle_url %}">
{% csrf_token %}
<input type="hidden" name="instance_id" value="{{ row.id }}"></input>
<input type="hidden" name="get_edit" value="{{ row.id }}"></input>
<button type="button" class="btn btn-warning btn-sm js-edit-inst-btn" data-url="{% url handle_url %}">
<i class="fas fa-edit"></i> Edit
</button>
</form>
<form method="POST" action="{% url handle_url %}">
{% csrf_token %}
<input type="hidden" name="instance_id" value="{{ row.id }}"></input>
<input type="hidden" name="get_view" value="{{ row.id }}"></input>
<button type="button" class="btn btn-primary btn-sm js-view-inst-btn" data-url="{% url handle_url %}">
<i class="fas fa-eye"></i> View
</button>
</form>
<form method="POST" action="{% url handle_url %}">
{% csrf_token %}
<input type="hidden" name="instance_id" value="{{ row.id }}"></input>
<input type="hidden" name="get_delete" value="{{ row.id }}"></input>
<button type="button" class="btn btn-danger btn-sm js-del-inst-btn" data-url="{% url handle_url %}">
<i class="fas fa-trash-alt"></i> Delete
</button>
</form>
</td>
{% else %}
<td>{{value}}</td>
{% endifequal %}
{% endfor %}
</tr>
{% endfor %}
</tbody>
<tfoot>
{% for row in dataset|slice:":1" %}
<tr>
{% for field in row %}
{% ifequal field 'id' %}
<td>Options</td>
{% else %}
<td>{{field}}</td>
{% endifequal %}
{% endfor %}
</tr>
{% endfor %}
</tfoot>
</table>
</div>
<!-- /.card-body -->
<div class="card-footer">
<form method="POST" action="{% url handle_url %}">
{% csrf_token %}
<input type="hidden" name="get_add" value=""></input>
<button type="button" class="btn btn-block btn-primary js-add-inst-btn" data-url="{% url handle_url %}">
<i class="fas fa-plus"></i>
Add New
</button>
</form>
</div>
</div>
<!-- Modal for viewing instance -->
<div class="modal fade" id="modal_form">
<div class="modal-dialog modal-xl">
<div class="modal-content">
</div>
<!-- /.modal-content -->
</div>
<!-- /.modal-dialog -->
</div>
<!-- /.modal -->
</section>
<!-- /.content -->
</div>
{% endblock content %}
<!-- Specific Page JS goes HERE -->
{% block javascripts %}
<!-- jQuery -->
<script src="/static/assets/plugins/jquery/jquery.min.js"></script>
<!-- Bootstrap 4 -->
<script src="/static/assets/plugins/bootstrap/js/bootstrap.bundle.min.js"></script>
<!-- DataTables -->
<script src="/static/assets/plugins/datatables/jquery.dataTables.min.js"></script>
<script src="/static/assets/plugins/datatables-bs4/js/dataTables.bootstrap4.min.js"></script>
<script src="/static/assets/plugins/datatables-responsive/js/dataTables.responsive.min.js"></script>
<script src="/static/assets/plugins/datatables-responsive/js/responsive.bootstrap4.min.js"></script>
<!-- AdminLTE App -->
<script src="/static/assets/js/adminlte.min.js"></script>
<!-- page script -->
<script src="/static/assets/js/form_handler.js"></script>
<script>
$(function () {
$("#datatable_feature").DataTable({
"responsive": true,
"autoWidth": false,
});
});
</script>
{% endblock javascripts %}
{% comment "Usage" %}
in views.py just add queryset to context like below
<Model>.objects.values(<field_values>)
{% endcomment %}
Upvotes: 1
Views: 336
Reputation: 21807
You are not preventing the form from being submitted in your function. You do write return false;
but that won't work here as that needs to be done in a fashion like below where somefunction
will return false:
<form onsubmit="return somefunction()">
Instead you need to use the event passed to your handler and call preventDefault
:
var saveForm = function (event) {
event.preventDefault(); // prevent form submission
var form = $(this);
// Rest of your function
}
Also looking at your javascript you have only attached the on submit handler if your form has one of the classes js-instance-create-form
, js-instance-update-form
or js-instance-delete-form
. But your forms have none of these classes. Add one them to your form:
<form method="POST" action="{% url handle_url %}" class="js-instance-create-form">
Also you attach the event to the forms in this manner:
$("#modal_form form").on("submit", ".js-instance-create-form", saveForm);
But the problem is that the form
referred to here doesn't exist yet! Hence your handler never gets attached to anything. Instead simply attach the handler to #modal_form
(a parent which already exists) and it should work:
// Create instance
$(".js-add-inst-btn").on("click", loadForm);
$("#modal_form").on("submit", ".js-instance-create-form", saveForm);
// Update instance
$(".js-edit-inst-btn").on("click", loadForm);
$("#modal_form").on("submit", ".js-instance-update-form", saveForm);
// Delete instance
$(".js-del-inst-btn").on("click", loadForm);
$("#modal_form").on("submit", ".js-instance-delete-form", saveForm);
Upvotes: 1