I spent several hours trying to figure out,How to implement Adder input in django.
My probleme is in my template I implemented a javascript script that adds additional fields to a form.
those fields are key/value fields, in my model I created a JSONField.
I wanted to grab data from dynamic fields and store them as key values in my JSONField
forms.py
class MyForm(forms.ModelForm):
def __init__(self, *args, **kwargs):
form_fields = kwargs.pop("fields", {})
super(CrontabForm, self).__init__(*args, **kwargs)
for field in form_fields:
field_name = field['name']
field_label = field['label']
field_type = field['type']
self.fields[field_name] = forms.CharField(label=field_label)
print fields.name
class Meta:
model = MyModel
models.py
class MyModel(models.Model):
user = models.ForeignKey(getattr(settings, 'AUTH_USER_MODEL'), verbose_name=_('User'))
params = JSONField(_('Url params'))
views.py
class MyView(LoginRequiredMixin, SuccessMessageMixin, CreateView):
model = MyModel
form_class = MyForm
template_name = '/index.html'
success_url = '/success/'
success_message = "The instance was created successfully"
def form_valid(self, form):
form.instance.user = self.request.user
return super(MyView, self).form_valid(form)
my jquery.js:
{% block custom_js %}
{{ block.super }}
<script>
console.log('tesss');
$(document).ready(function () {
// Number of params
var index = 0;
function addParams() {
var tmp_template = $('template').clone();
var paramsDiv = $('#params');
paramsDiv.append(tmp_template.html());
$($('[class$="param-x"]')[index]).attr('name', 'param' + (index + 1));
$($('[class$="value-x"]')[index]).attr('name', 'value' + (index + 1));
index = index + 1;
}
addParams();
$('#addParam').on('click', function(){
addParams();
});
});
</script>
{% endblock %}
index.html:
<div class="col-md-12">
<form action="." method="post">
<div class="col-md-6">
{% csrf_token %}
{% for field in form %}
<div class="form-group">
<div class="row">
{{ field.errors }}
<label class="col-md-2 control-label">{{ field.label_tag }}</label>
<div class="col-md-6">
{{ field }}
</div>
{% if field.help_text %}
<p class="help">{{ field.help_text|safe }}</p>
{% endif %}
</div>
</div>
{% endfor %}
<div class="text-center">
<div class="pagination">
<i class="btn btn-success waves-input-wrapper waves-effect"
style="color:#fff ;background:#5cb85c">
<input class="waves-button-input" type="submit" value="Add"
style="background-color:rgba(0,0,0,0);"></i>
{% url 'cron:crontab-list' as cronslist %}
{# <div class="col-sm-offset-5 col-sm-2 text-center">#}
<a href="{{ cronslist }}"><i class="btn btn-primary waves-input-wrapper waves-effect"
style="color:#fff;background:#286090">
<input class="waves-button-input has-value" type="button" value="Cancel"
style="background-color:rgba(0,0,0,0);">
</i></a>
</div>
</div>
</div>
<div class="col-md-6">
<div class="row">
<div class="col-md-10">
<div style="text-align:center">
<label class="col-md-4">Param</label>
<label class="col-md-6">Value</label>
</div>
<div id="params"></div>
<!-- The template for adding new field -->
<template>
<div class="form-group">
<div class="col-md-4">
<input type="text" class="form-control param-x" placeholder="Task"/>
</div>
<div class="col-md-6">
<input type="text" class="form-control value-x" placeholder="Task"/>
</div>
</div>
<div class="col-md-10">
<hr>
</div>
</template>
</div>
<div class="col-md-2">
<label class="col-md-2">Add</label>
<button id="addParam" type="button" class="btn btn-default addButton"><i class="fa fa-plus"></i></button>
</div>
</div>
</div>
</div>
Related
I have a login, register and password reset pages both login and register pages auto focus on the username field however on my password reset page auto focus is not working. I have tried widget_tweaks within my template but to no avail like so:
{{ fieldValues.email|attr:"autofocus" }} and {{ form.email|attr:"autofocus" }}
I just cannot get my head around why auto focus works on my other forms but not on password reset. My code is as follows:
View
class RequestPasswordResetEmail(View):
#method_decorator(check_recaptcha_form)
def get(self, request):
return render(request, 'password/reset-password.html')
#method_decorator(check_recaptcha_form)
def post(self, request):
email = request.POST['email']
context = {
'values': request.POST
}
current_site = get_current_site(request)
user = User.objects.filter(email=email)
user_by_email = User.objects.filter(email=email).first()
if not user.exists():
messages.error(request, 'Please supply a valid email')
return render(request, 'password/reset-password.html', context)
if user.exists() and request.recaptcha_is_valid:
uid = urlsafe_base64_encode(force_bytes(user_by_email.pk))
token = PasswordResetTokenGenerator().make_token(user_by_email)
email_subject = 'WFI Workflow System - Password Reset'
email_body = 'password/password_reset_email.html'
to_email = [user_by_email.email]
send_email(user, request, email_subject, email_body, uid, token, to_email)
messages.success(
request, mark_safe(
'We’ve emailed you instructions for setting your password, if an account exists with the email you entered. You should receive them shortly.'
'<br class="brmedium"> If you don’t receive an email, please make sure you’ve entered the address you registered with, and check your spam folder.</br>'))
return render(request, 'password/reset-password.html')
Template
{% extends 'base.html' %}
{% block title %}Password Reset{% endblock %}
{% block content %}
<div class="d-flex justify-content-center">
<h3 id="form-title">Password Reset</h3>
</div>
<span class="forgot_pass">Forgotten your password? Enter your email address below, and we’ll email instructions for setting a new one.</span>
<div class="d-flex justify-content-center form_container">
<form action="{% url 'request-password' %}" method="POST">
{% csrf_token %}
<div align="center">
<div class="input-group mb-3">
<div class="input-group-append">
<span class="input-group-text"><i class="fas fa-envelope-square"></i></span>
<input type="email" name="email" placeholder="Email" class="form-control"
value="{{ fieldValues.email }}"/>
</div>
</div>
</div>
{% include 'recaptcha.html' %}
<div class="d-flex justify-content-center mt-3 login_container">
<input class="btn login_btn" type="submit" value="Submit">
</div>
</form>
</div>
{% include 'messages.html' %}
<div class="input-group mb-1">
</div>
<div class="mt-1">
<div class="d-flex justify-content-center links">
Already have an account? Login
</div>
<div class="d-flex justify-content-center links">
Don't have an account? Sign Up
</div>
</div>
{% endblock content %}
I even tried the following javascript but again did nothing:
<script type="text/javascript">
$(function () {
// When the page has finished loading,
// autofocus on the username field
$('input#id_email').focus();
});
</script>
Just add autofocus attribute to your input field:
<input type="email" name="email" placeholder="Email" class="form-control" value="{{ fieldValues.email }}" autofocus>
I am new to JQuery and I have an Ajax function to update the select options. The Ajax is working fine on my first Div. But when I clone the div and run the Ajax call it again update the first Div element only not the element of cloned one. I new to closet... etc. Please help me so when I call the Ajax it will update the cloned div(current div) element.
this is my ajax function:
function acct_dbox() {
{#var that = $(this)#}
$.ajax(
{
type: "GET",
url: "/waccounts/getaccounts",
dataType: "json",
data: {
{#'acctlevel': $(this).val(),#}
'csrfmiddlewaretoken': '{{csrf_token}}'
},
success: function (data) {
$.each(data, function(index, item) {
if (item.length > 0){
console.log('test', item[0].AcctCode);
console.log('test', item[0].AcctName);
{#$("#id_accountcode option").remove();#}
$.each(item, function(index1, item1) {
console.log(item1.id);
console.log(item1.AcctCode);
console.log(item1.AcctName);
$("#id_accountcode").append($('<option/>',{
{#$("#id_accountcode").append($('<option/>', {#}
value: item1.AcctCode,
text: item1.AcctName
}));
})
$( document ).ready(function() {
acct_dbox();
var original_external_int_div = document.getElementById('account_list');
//Div to Clone
var clone = original_external_int_div.cloneNode(true); // "deep" clone
original_external_int_div.parentNode.append(clone);
acct_dbox(); # (it is updating the first div again - not cloned one)
});
My html is:
{% extends 'wstore_base_generic.html' %}
{% block content %}
<form action="" method="post" class="w-auto" id="new_trans_form"
xmlns:width="http://www.w3.org/1999/xhtml">
<div class="row mt-1 mb-4" >
<div class="col-md-12">
<div>
<div class="headerctr">
<h3>JV</h3>
<!-- <div> -->
<!-- <h3 > -->
<!-- </h3> -->
</div>
<div class="card-body" >
{% csrf_token %}
<div 38rem class="row style= width:18">
<div class="col">
<label>Transaction Date</label>
<input type="date" class="form-control" name="
{{form.fh_dt.name}}" value="{{current_date}}"
readonly>
{% if form.fh_dt.errors %}
{% for error in form.fh_dt.errors %}
<small class="text-danger">{{error}}</small>
{% endfor %}
{% endif %}
</div>
<div class="col-sm" >
<label>Transaction Number</label>
<input type="number" class="form-control" name="
{{form.fh_no.name}}"
value="{{transaction_number}}" readonly>
{% if form.fh_no.errors %}
{% for error in form.fh_no.errors %}
<small class="text-danger">{{error}}</small>
{% endfor %}
{% endif %}
</div>
<div class="col">
<input type="hidden" class="form-control" name="
{{form.fh_type.name}}" required readonly
value="JV">
{% if form.fh_type.errors %}
{% for error in form.fh_type.errors %}
<small class="text-danger">{{error}}</small>
{% endfor %}
{% endif %}
<label>Transaction Ref.</label>
<input type="text" class="form-control" name="
{{form.fh_ref.name}}" required
value="Ref.">
{% if form.fh_ref.errors %}
{% for error in form.fh_ref.errors %}
<small class="text-danger">{{error}}</small>
{% endfor %}
{% endif %}
</div>
</div>
<div class="row mt-0">
<div class="col">
<label>Transaction Code</label>
<input type="text" class="form-control" name="
{{form.fh_code.name}}" required readonly
value="JV">
{% if form.fh_code.errors %}
{% for error in form.fh_code.errors %}
<small class="text-danger">{{error}}</small>
{% endfor %}
{% endif %}
</div>
<div class="col">
<label>Transaction Detail</label>
<input type="text" class="form-control" name="
{{form.fh_detail.name}}" required
value="Detail">
{% if form.fh_detail.errors %}
{% for error in form.fh_detail.errors %}
<small class="text-danger">{{error}}</small>
{% endfor %}
{% endif %}
</div>
<div class="col">
<label>Transaction UserCode</label>
<input type="text" class="form-control" name="
{{form.fh_user_code.name}}" required
value="{% if form.fh_user_code.value %}
{{form.fh_user_code.value}}{% else %}{{request.user.username}}{% endif %}">
{% if form.fh_user_code.errors %}
{% for error in fh_user_code.errors %}
<small class="text-danger">{{error}}</small>
{% endfor %}
{% endif %}
</div>
</div>
</div>
</div>
</div>
<div class="col-md-12 mt-0">
<div class="card shadow">
<div class="card-header text-center">
<h3 class="headerctr">
Item Details
</h3>
</div>
<div class="card-body">
{% csrf_token %}
<table class="">
<thead class="thead-light">
<tr>
<th>Code</th>
<th class = "text-danger">Account</th>
<th class = "text-danger">Debits</th>
<th class="text-success">Credits</th>
<th class = "text-warning">Description</th>
<th class = "text-warning">Tax</th>
</tr>
</thead>
<tbody id="account_list" style="margin-bottom: 0">
<tr>
<td>
<select name="acct_code" class="form-control
fh_code" id="id_accountcode">
<option value="SELECT"
selected="selected">---SELECT---</option>
required></select>
</td>
<td>
<input type="text" name="acct_name"
class="form-control fh_name"
placeholder="Acct Code" readonly>
</td>
<td>
<input type="number" name="acct_debit"
class="form-control fh_debit"
placeholder=" " >
</td>
<td>
<input type="number" class="form-control
fh_credit" name="acct_credit"
placeholder=" ">
</td>
<td>
<input type="text" class="form-control
fh_detail" placeholder="Description"
name="acct_descript" >
</td>
<td>
<input type="number" class="form-control
fh_tax" name="acct_tax"
placeholder=" ">
</td>
<td>
<div class="btn-group">
<button type="button" id="btnadd"
class="btn add_new_row" title="Add">
<i class="fas fa-plus-square"></i>
</button>
<button type="button" class="btn
delete_row" title="Delete">
<i class="fas fa-trash"></i>
</button>
</div>
</td>
</tr>
</tbody>
<tfoot>
<tr>
<td></td>
<td></td>
<td class = "text-success">Total Quantity:
<strong id="final_quantity">0</strong></td>
<td></td>
<td class = "text-success"> Total Price: <strong
id="final_price">0</strong></td>
</tr>
</tfoot>
</table>
</div>
<div class="col-md-12 mb-1">
<div class="btn-group">
<a href="{% url 'transactions' transtype='INV'
posted='ALL' %}" class="btn btn-info mr-2" >Cancel</a>
<input type="submit" class="btn btn-info submit_form"
name="save_next" value="Save&Print">
</div>
</div>
</div>
</div>
</div>
</form>
{% endblock %}
{#$("#id_accountcode").append($('<option/>', {#}
value: item1.AcctCode,
text: item1.AcctName
I made a change like:
$("table tbody select[name=acct_code]").append($('<option/>',
the all div selects get updated with option -Thanks to swathi.
I have a form with it is own submit button and there is a button inside that form that has the attributes type=button, onclick=somefunction().. the button with the onclick runs great but the other button is not submitting at all.
I've made sure that the button with the function on click have type=button and other button have type=submit
Here is my code:
{% extends 'base/base.html' %}
{% block content %}
<!-- Page Content -->
<div id="page-wrapper">
<div class="row">
<div class="col-lg-12">
<!-- page content -->
<br><br>
<h3>إنشاء فاتورة بيع جديدة </h3>
<br><br>
{% if messages %}
<ul class="messages">
{% for message in messages %}
<li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
{% endfor %}
</ul>
{% endif %}
<form method='post' autocomplete="off" action=".">
{% csrf_token %}
<div class="autocomplete" style="width:100%">
<b>هاتف العميل </b><br>
{{ create_sell_invoice.client }}
<br>
<p style="display: none;" id="shown_name">
client name
</p>
<div id="add_new_client" style="margin:25px;padding: 25px;display: none;">
<form method='POST'>
{% csrf_token %}
<small style="color:rebeccapurple;">يمكنك إضافة عميل جديد برقم هاتف جديد</small>
<br><br>
<b>إسم الطالب</b>
{{ add_client_from_invoice_form.student_name }}
<br><br>
<b>ولى الامر</b>
{{ add_client_from_invoice_form.parent_name }}
<br><br>
<b>العنوان</b>
{{ add_client_from_invoice_form.address }}
<br><br>
<b>الهاتف</b>
{{ add_client_from_invoice_form.phone1 }}
<br><br>
<b>المستوى</b>
{{ add_client_from_invoice_form.level }}
<br><Br>
<button type="button" class="btn btn-success form-control" onclick="sendingRequest()">
إضافة
</button>
</form>
</div>
</div>
<b id="id_delivery_title">التوصيل </b><br>
{{ create_sell_invoice.delivery }}
<br><br>
<b id="id_delivery_price_title">تكلفة التوصيل </b><br>
{{ create_sell_invoice.delivery_price }}
<br><br>
<b id="id_delivery_notes_title">ملاحظات على التوصيل </b><br>
{{ create_sell_invoice.delivery_notes }}
<br><br>
<button type="submit" id='ok_button' class="btn btn-primary form-control" disabled>موافق</button>
<br><Br><Br>
</form>
<script>
function sendingRequest() {
const studentName = document.getElementById('studentName');
const parentName = document.getElementById('parentName');
const clientAddress = document.getElementById('clientAddress');
const clientPhone = document.getElementById('clientPhone');
const clientLevel = document.getElementById('clientLevel');
$.ajax({
url: '/add/new/client/from/invoice/normal/invoice_sell_add/' + studentName.value + '/' + parentName.value + '/' + clientAddress.value + '/' + clientPhone.value + '/' + clientLevel.value + '/',
type: "POST",
data: {name: 'name', age: 'age'},
success: function (response) {
const add_new_client = document.getElementById('add_new_client');
add_new_client.setAttribute('style', 'margin:25px;padding: 25px;display: none;')
window.location.reload();
},
complete: function () {
},
error: function (xhr, textStatus, thrownError) {
}
});
}
</script>
<!-- /.col-lg-12 -->
</div>
</div>
</div>
<!-- /.row -->
</div>
<!-- /#page-wrapper -->
</div>
<datalist id="mylist">
{% for item in clients %}
<option>{{ item }}</option>
{% endfor %}
</datalist>
{% for item in clients %}
{{ item }}
{% endfor %}
<!-- ajax -->
<script>
$("#id_client").change(function () {
var number = $(this).val();
$.ajax({
url: '/ajax/getting_client_name/',
data: {
'number': number
},
dataType: 'json',
success: function (data) {
const shown_name = document.getElementById('shown_name'),
ok_button = document.getElementById('ok_button'),
add_new_client = document.getElementById('add_new_client');
if (data.client_name) {
shown_name.setAttribute('style', 'display:block;color: blue;');
shown_name.innerHTML = data.client_name;
ok_button.disabled = false;
add_new_client.setAttribute('style', 'margin:25px;padding: 25px;display: none;background-color: #d3e4ec;');
$('#id_delivery').fadeIn();
$('#id_delivery_title').fadeIn();
$('#id_delivery_price').fadeIn();
$('#id_delivery_price_title').fadeIn();
$('#id_delivery_notes').fadeIn();
$('#id_delivery_notes_title').fadeIn();
if (data.client_name === 'رقم الهاتف غير صحيح') {
shown_name.setAttribute('style', 'display:block;color: red;');
ok_button.disabled = true;
add_new_client.setAttribute('style', 'margin:25px;padding: 25px;display: block;background-color: #d3e4ec;');
$('#id_delivery').fadeOut();
$('#id_delivery_title').fadeOut();
$('#id_delivery_price').fadeOut();
$('#id_delivery_price_title').fadeOut();
$('#id_delivery_notes').fadeOut();
$('#id_delivery_notes_title').fadeOut();
}
}
}
});
});
</script><!-- end of ajax -->
{% endblock %}
The problem is in this line of code
<button type="submit" id='ok_button' class="btn btn-primary form-control" disabled>موافق</button>
where the button do nothing at all when clicked
Based on #hindmose comment the problem was having nested forms, I solved it by deleting the inner form tags and moved this part before the opening form tag .. now it is like :
<div id="add_new_client" style="margin:25px;padding: 25px;display: none;">
<small style="color:rebeccapurple;">يمكنك إضافة عميل جديد برقم هاتف جديد</small>
<br><br>
<b>إسم الطالب</b>
{{ add_client_from_invoice_form.student_name }}
<br><br>
<b>ولى الامر</b>
{{ add_client_from_invoice_form.parent_name }}
<br><br>
<b>العنوان</b>
{{ add_client_from_invoice_form.address }}
<br><br>
<b>الهاتف</b>
{{ add_client_from_invoice_form.phone1 }}
<br><br>
<b>المستوى</b>
{{ add_client_from_invoice_form.level }}
<br><Br>
<button type="button" class="btn btn-success form-control" onclick="sendingRequest()">
إضافة
</button>
</div>
<form method='post' autocomplete="off" action=".">
....
I have a loop in a django template which iterates over
objects.
With every object I have an edit button which triggers a modal.
I am passing id to every edit button which triggers the modal of that
object id.
Modal is opening but problem is I'm not able to pass data of the object into the modal.
template
{% if prof %}
<table class="table">
<tbody>
{% for edu in prof.education.all %}
<tr class="divbutton" style="height: 90px;">
<td>
<div class="row">
<div style="padding-left: 40px; font-size: 20px;">{{ edu.degree }}</div>
<div style="padding-left: 40px; font-size: 20px;">{{ edu.school }}</div>
</div>
</td>
<td></td>
<td class="align-middle">
<div class="row">
<div id="button_under" style="margin-right: 20px;" class="login login-button">
{# <button class="btn btn-info js-update-book" data-url="{% url 'users:book_update' pk=edu.id %}" style="cursor:pointer;"><i class="fa fa-edit"></i> Edit</button>#}
<button class="btn btn-info" type="button" data-toggle="modal" data-target="#{{ edu.id }}" data-backdrop="false" style="cursor:pointer;"><i class="fa fa-edit"></i> Edit</button>
<!-- --------------------------- Update Modal--------------------- -->
<form action="{% url 'users:book_update' pk=edu.id %}" style="padding-left: 15px; padding-right:15px;" method="POST">
{{ form.errors }}
{% csrf_token %}
<div class="row">
<div id="{{ edu.id }}" class="modal fade" role="dialog">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Update Education</h4>
<button type="button" class="close" data-dismiss="modal">×</button>
</div>
<div class="modal-body">
<div class="row">
<div class="col-lg-12">
<div class="form-group">
<div class="field">
<label>Degree title<span class="red-txt">*</span></label>
<!-- <input class="form-control" type="text" name="degree" value="" maxlength="60" size="50"> -->
{{ form.degree }}
</div>
</div>
</div>
<div class="col-lg-12">
<div class="form-group">
<div class="field">
<label>School<span class="red-txt">*</span></label>
<!-- <input class="form-control" type="text" name="school" value="" maxlength="60" size="50"> -->
{{ form.school }}
</div>
</div>
</div>
<!-- works -->
<div class="col-lg-6">
<div class="form-group">
<div class="field">
<label>Start date</label>
<div id="datepicker1" class="datepicker input-group date" data-date-format="yyyy-mm-dd">
{{ form.edu_start_date }}
<span class="input-group-addon"><i class="fa fa-calendar"></i></span>
</div>
</div>
</div>
</div>
<!-- does not work -->
<div class="col-lg-6">
<div class="form-group">
<div class="field">
<label>End date</label>
<div id="datepicker2" class="datepicker input-group date" data-date-format="yyyy-mm-dd">
{{ form.edu_end_date }}
<span class="input-group-addon"><i class="fa fa-calendar"></i></span>
</div>
</div>
</div>
</div>
<div class="col-lg-12">
<br>
<div style="text-align:center;" class="login login-button">
<input type="submit" class="btn btn-outline-primary btn-lg" style="cursor: pointer;" value="Save">
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</form>
</div>
</div>
</td>
</tr>
{% endfor %}
{% endif %}
</tbody>
</table>
View
class ProfileSettingsView(UpdateView):
model = Profile
form_class = ProfileSettingsForm
pk_url_kwarg = 'pk'
context_object_name = 'object'
template_name = 'profile_settings.html'
def get_success_url(self):
return reverse_lazy('users:profile_settings', args = (self.object.id,))
def get_object(self):
pk = self.kwargs.get('pk')
return get_object_or_404(Profile, id=pk)
def get_context_data(self, **kwargs):
context = super(ProfileSettingsView, self).get_context_data(**kwargs)
context['prof'] = self.get_object()
return context
form
class EducationForm(forms.ModelForm):
degree = forms.CharField(max_length=40, required=False)
school = forms.CharField(max_length=40, required=False)
edu_start_date = forms.DateField(required=False,
input_formats=settings.DATE_INPUT_FORMATS,
widget=forms.DateInput(attrs={'readonly': 'readonly'}))
edu_end_date = forms.DateField(required=False,
input_formats=settings.DATE_INPUT_FORMATS,
widget=forms.DateInput(attrs={'readonly': 'readonly'}))
def __init__(self, request, *args, **kwargs):
super(EducationForm, self).__init__(*args, **kwargs)
self.request = request
def save(self, commit=True):
edu = super(EducationForm, self).save(commit=False)
edu.save()
profile = Profile.objects.get(id=self.request.user.profile.id)
profile.education.add(edu)
return edu
class Meta:
model = Education
fields = ['degree','school','edu_start_date','edu_end_date']
Update
class EducationView(CreateView):
model = Education
form_class = EducationForm
pk_url_kwarg = 'pk'
template_name = "profile_settings.html"
def get_success_url(self):
return reverse_lazy('users:profile_settings', args = (self.request.user.profile.id,))
def get_form_kwargs(self):
kwargs = super(EducationView, self).get_form_kwargs()
kwargs['request'] = self.request
return kwargs
Your view is using the ProfileSettingsForm and your EducationForm isn't used anywhere. If I understand the models correctly, you have one Profile which can be related to multiple Education instances.
So you need to have multiple EducationForms in your view, one for each object to update (plus probably an extra empty one to create a new Education).
You should use Django Formsets for this, or more specifically an inlineformset_factory as shown here
When I use bootstrap modal for my form its only show first value.
here my template.html
{% for company in companys %}
<tr>
<td>{{ company.name }}</td>
<td>{{ company.desc }}</td>
<td align="center">
<button type="button" class="btn btn-warning margin-bottom" data-toggle="modal" data-target="#modal-default2">
delete
</button>
<div class="modal fade" id="modal-default2">
<div class="modal-dialog">
<form method="post" action="{% url 'system:company_delete' pk=company.pk %}">
{% csrf_token %}
<div class="modal-content">
<div class="modal-body">
<input type="text" name="name" maxlength="100" required="" id="id_name" value="{{ company.pk }}">
<input type="submit" class="btn btn-primary" value="Delete">
</div>
</div>
</form>
</div>
</div>
</td>
</tr>
{% endfor %}
its loop all the data, when click delete confirm form will popup. but its return same value.
but if without modal-bootstrap its work fine.
example: template.html
{% for company in companys %}
<tr>
<td>{{ company.name }}</td>
<td>{{ company.desc }}</td>
<td align="center">
<form method="post" action="{% url 'system:company_delete' pk=company.pk %}">
{% csrf_token %}
<input type="text" name="name" maxlength="100" required="" id="id_name" value="{{ company.pk }}">
<input type="submit" class="btn btn-primary" value="Delete">
</form>
</td>
</tr>
{% endfor %}
it's work fine.
what I should do to make it work?...
update
views.py
# Company Crud
class CompanyListView(ListView):
context_object_name = 'companys'
model = models.Company
class CompanyCreateView(CreateView):
fields = ('name', 'desc')
model = models.Company
class CompanyUpdateView(UpdateView):
fields = ('name', 'desc')
model = models.Company
class CompanyDeleteView(DeleteView):
model = models.Company
success_url = reverse_lazy("system:company_list")
Your ajax modal will always return the same value inside modal because:
- Modal has this data-target="#modal-default2" as the target, however, your loop contains the modal body, with the id id="modal-default2", which will render modal as much as your loop goes.
So what you can do is to define a unique ID for each modal with the ID of each company modal-default{{company.id}}:
{% for company in companys %}
''' rest of codes '''
<button type="button" class="btn btn-warning margin-bottom" data-toggle="modal" data-target="#modal-default{{company.id}}">
delete
</button>
''' rest of codes '''
<div class="modal fade" id="modal-default{{company.id}}">
<div class="modal-dialog">
</div>
</div>
''' rest of codes '''
{% endfor %}
But this method is not effective if you have a lot of data, it will render lots of html codes.
Another option
With AJAX and one modal.
Your html would be:
{% for company in companys %}
<td>{{ company.name }}</td>
<td>{{ company.desc }}</td>
<button data-id="{{company.id}}" type="button" class="btn btn-warning margin-bottom delete-company" >
delete
</button> <!-- be aware of class 'delete-company' -->
{% endfor %}
{% csrf_token %}
<div class="modal fade" id="modal-default">
<div class="modal-dialog">
{% if company %} <!-- this company instance will come from AJAX -->
<form method="post" action="{% url 'system:company_delete' pk=company.pk %}">
{% csrf_token %}
<div class="modal-content">
<div class="modal-body">
<input type="text" name="name" maxlength="100" required="" id="id_name" value="{{ company.pk }}">
<input type="submit" class="btn btn-primary" value="Delete">
</div>
</div>
</form>
{% endif %}
</div>
</div>
AJAX
$(document).on('click','.delete-company',function(){
var id = $(this).data('id');
$.ajax({
url:'',
type:'POST',
data:{
'id':id,
'csrfmiddlewaretoken': $('input[name=csrfmiddlewaretoken]').val(),
},
success:function(data){
$('#modal-default .modal-dialog').html($('#modal-default .modal-dialog',data));
$('#modal-default').modal('show');
},
error:function(){
console.log('error')
},
});
});
And your views would be:
change your url from CompanyListView.as_view() to companyListView
def companyListView(request):
context = {}
companys = models.Company.objects.all()
if request.method == 'POST' and request.is_ajax():
ID = request.POST.get('id')
company = companys.get(id=ID) # So we send the company instance
context['company'] = company
context['companys'] = companys
return render(request,'template.html',context)