I am trying not to use formset in my form. Instead of that, I'm trying to create the form dynamically and save all forms data in the DB.
I can create a dynamic form, but whenever I create multiple forms in "create order", it always saves the last forms data. For example, once I create 3 forms, and after saving the form, the table shows me only 3rd form data, which means it does not save all data together.
views.py
def create_order(request):
from django import forms
form = OrderForm()
if request.method == 'POST':
forms = OrderForm(request.POST)
if forms.is_valid():
po_id = forms.cleaned_data['po_id']
supplier = forms.cleaned_data['supplier']
product = forms.cleaned_data['product']
part = forms.cleaned_data['part']
order = Order.objects.create(
po_id=po_id,
supplier=supplier,
product=product,
part=part,
)
forms.save()
return redirect('order-list')
context = {
'form': form
}
return render(request, 'store/addOrder.html', context)
forms.py
class OrderForm(forms.ModelForm):
class Meta:
model = Order
fields = ['supplier', 'product', 'part','po_id']
widgets = {
'supplier': forms.Select(attrs={'class': 'form-control', 'id': 'supplier'}),
'product': forms.Select(attrs={'class': 'form-control', 'id': 'product'}),
'part': forms.Select(attrs={'class': 'form-control', 'id': 'part'}),
}
HTML
<form action="#" method="post" id="form-container" novalidate="novalidate">
{% csrf_token %}
<div class="form">
<div class="form-group">
<label for="po_id" class="control-label mb-1">ID</label>
{{ form.po_id }}
</div>
<div class="form-group">
<label for="supplier" class="control-label mb-1">Supplier</label>
{{ form.supplier }}
</div>
<div class="form-group">
<label for="product" class="control-label mb-1">Product</label>
{{ form.product }}
</div>
<div class="form-group">
<label for="part" class="control-label mb-1">Part Name</label>
{{ form.part }}
</div>
</div>
<button id="add-form" type="button">Add Another Order</button>
<div>
<button id="payment-button" type="submit" class="btn btn-lg btn-success btn-block">
<span id="payment-button-amount">Save</span>
</button>
</div>
</form>
<script>
let poForm = document.querySelectorAll(".form")
let container = document.querySelector("#form-container")
let addButton = document.querySelector("#add-form")
let totalForms = document.querySelector("#id_form-TOTAL_FORMS")
let formNum = poForm.length-1
addButton.addEventListener('click', addForm)
function addForm(e){
e.preventDefault()
let newForm = poForm[0].cloneNode(true)
let formRegex = RegExp(`form-(\\d){1}-`,'g')
formNum++
newForm.innerHTML = newForm.innerHTML.replace(formRegex, `form-${formNum}-`)
container.insertBefore(newForm, addButton)
totalForms.setAttribute('value', `${formNum+1}`)
}
</script>
What causes this problem? How can I fix it?
Related
I'm working on grading system and I'm currently working on the form that's deals with the user entering the students results now the form I have, has 2 drop-down list(classroom, students) that are dependent. The issue and where I'm stuck is
When the user select the classroom the second drop-down menu will only show the students in that class, I have already figure that out..the issue is I want the input fields for how much subject the student is doing to appear so that the user can enter the grades for each subject specific to that student in the class
Eg if I select classroom 1b and selected student Mary.. if Mary is doing 5 subjects then 5 input field should appear so that I can enter the mark for the subjects
Link with a video showing what I'm talking about video showing an examplehttps://drive.google.com/file/d/11FoCZyOBVdUhTcvCqA1Ke0fEgRmMVC-G/view?usp=drivesdk
Models.py
Class Classroom(models.Models): name = models.charfield()
Class marks (models.Models): classroom = models.foreignkey(Classroom) Grade = models.Floatfield()
Html form
<div class="container-fluid">
<form id="result-form" method="post">
{% csrf_token %}
<!-- Modal -->
<div class="modal-header">
<h5 class="modal-title" id="staticBackdropLabel"> {% block modal-title%} Add Result {% endblock%}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="row">
<div class="col-md-12" id="msg8" style="font-size: 2rem; color:rgb(255, 144, 47)"></div>
<div class="col-md-12 form-group p-2">
<label class="form-label">Class Name</label>
{% render_field form.room class+="form-control" %}
</div>
<div class="col-md-12 form-group p-2">
<label class="form-label">Exam Name</label>
{% render_field form.exam class+="form-control" %}
</div>
<div class="col-md-12 form-group p-2">
<label class="form-label">Student</label>
{% render_field form.student class+="form-control select2" %}
</div>
<div class="hidden" id="subject-fields"></div>
<div class="form-group mb-3 pt-2">
<button type="button" id="resBtn" class="btn btn-info" title="Add">Submit</button>
</div>
</div>
</div>
</form>
</div>
{% block script%}
{% endblock%
script
$(document).on('click', '#submit-btn', function(event){
var response_data = []
var subject_name= $('.course');
var subject_objs = $('.subject_id');
for(i=0;i<subject_name.length;i++){
var subject_id = $(subject_objs[i]).find('input').val();
var grade_input = {
"Marks": subject_id,
}
response_data.push(grade_input);
}
$.ajax({
type: "POST",
url: "{% url 'marks' %}",
data: response_data,
success: function(response){
alert("Success");
}
});
});
This is how your view should look like.
def question_choice_view(request):
if request.method == "POST":
question_choice_data = request.POST['data']
I am not a jQuery User. As far as i can see i would put a eventlistener on the student form via .addEventListener('change', (event)See here. This would fire a function every time something changes on the select option. With that you could also collect the selected option values of the classroom and student name and make a request to get the subject names for the chosen student. After successful response i would insert the subject fields via JavaScript in the DOM.
**
function createInput(item) {
// This function takes a item and creates a new input
var newLabel = ' <br><label for="$item-mark">$item:</label>'
var newInput = '<input type="text" id="$item-mark-id" name="$item-mark"><br><br>';
newLabel = newLabel.replaceAll("$item", item)
newInput = newInput.replaceAll("$item", item)
// combine into a single str
newInput = newLabel + newInput
var studInput = document.getElementById("student-id");
// insert element inputs after student
studInput.insertAdjacentHTML('afterend', newInput);
}
function cleanOldInputs(item) {
var oldELement = item + "-mark-id"
oldELement = document.getElementById(oldELement)
if (oldELement) {
// remove old label and input
oldELement.previousSibling.remove()
oldELement.remove()
} else {}
}
function getAPIcall() {
// This is what your API sends
var responsObject = ["writing", "creativity"];
// loop throug
responsObject.forEach(item => {
// if you already picked a student clean old inputs from DOM
cleanOldInputs(item)
// send to function for input creation
createInput(item)
})
}
// get the Student Input
var studentSelect = document.getElementById("student-id");
studentSelect.addEventListener("click", function() {
// Fire anything you like
getAPIcall()
});
<form action="/action_page.php">
<label for="student">Choose a student:</label>
<select name="student" id="student-id">
<option value="harry">harry</option>
<option value="ivy">ivy</option>
</select>
</form>
Quick and dirty**
I am trying to Auto-complete form fields using Ajax and Jquery.
First I used Django and the views.py function is:
def CreateWellMon(request):
if request.method == 'POST':
form = SurveillanceDesPuits_F(request.POST or None)
if form.is_valid():
form.instance.author = request.user
form.save()
return redirect('WellMonitor')
else:
try:
PUITS_id = request.GET.get('PUITS')
record = SurveillanceDesPuits.objects.filter(PUITS_id__id__exact=PUITS_id)[:1]
record2 = SurveillanceDesPuits.objects.get(id= record[0].id)
form = SurveillanceDesPuits_F(instance=record2)
return render(request, 'measure/Surveill_Wells/Add_wellMntr2.html', {'form': form})
except:
record2 = SurveillanceDesPuits.objects.all().first()
form = SurveillanceDesPuits_F(instance=record2)
return render(request, 'measure/Surveill_Wells/Add_wellMntr2.html', {'form': form})
So here I just selected the last record from the database at first. After when the user chooses a Well it reloads the last record of the element.
my HTML page code is:
{% extends 'Home/base2.html' %}
{% block content %}
{% load crispy_forms_tags %}
<div class="w3-panel w3-border w3-light-grey w3-round-large sizeA"> <h2>Well Information</h2> <h2 class="border-bottom pb-1 mb-3"><b>Add New montoring record 3</b></h2> </div>
{% if form %}
<div class="border p-3 mb-3 mt-3 w3-round-large w3-light-grey border-dark">
<form method="POST" id="SurveillanceDesPuits_F" data-record-url="{% url 'Add_wellMntr' %}">
{% csrf_token %}
<!-- form from views.py-->
<div class="border p-2 mb-3 mt-3 border-secondary">
<div class="form-row">
<div id= "PUITS" class="form-group col-md-3 mb-0">
{{form.PUITS|as_crispy_field}}
</div>
<div class="form-group col-md-3 mb-0">
{{ form.CS |as_crispy_field}}
</div>
<div class="form-group col-md-3 mb-0">
{{ form.MODE|as_crispy_field}}
</div>
<div class="form-group col-md-3 mb-0">
{{ form.SITUATION |as_crispy_field}}
</div>
</div>
<div class="form-row">
<div class="form-group col-md-3 mb-0">
{{ form.DATE_TEST|as_crispy_field }}
</div>
<div id='DUSE' class="form-group col-md-3 mb-0">
{{ form.DUSE|as_crispy_field }}
</div>
<div class="form-group col-md-3 mb-0">
{{ form.PRES_TBG|as_crispy_field }}
</div>
<div class="form-group col-md-3 mb-0">
{{ form.PRES_CSG|as_crispy_field }}
</div>
</div>
<div class="form-row">
<div class="form-group col-md-8 mb-0">
{{ form.OBSERVATION|as_crispy_field }}
</div>
</div>
</div>
<input class="btn btn-success mb-4" type="submit" value="ADD Record">
</form>
</div>
{% endif %}
<script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
<script type="text/javascript"> $(document).ready(function(){
$("#id_PUITS").change(function(){
var url = $("#SurveillanceDesPuits_F").attr("data-record-url");
var PUITSId = $(this).val();
$.ajax({
type: 'GET' ,
url: url,
data: {
'PUITS': PUITSId
},
success: function (data){
$('#SurveillanceDesPuits_F').html(data);
}
});
});
return false;
}); </script>
{% endblock content %}
The problem is that after selecting a well the AJAX duplicates some elements in the page as described in the photo.
and how I do to solve this and keep the selected well because it is a choice field?
First I made a change in models.py, I deleted to_field='WellID', so it will keep the selected well after the AJAX call.
class SurveillanceDesPuits(models.Model):
PUITS = models.ForeignKey(Surveill_Wells , on_delete=models.CASCADE)
DATE_TEST= models.DateField()
....
then I changed the views.py:
def CreateWellMon(request):
if request.method == 'POST':
form = SurveillanceDesPuits_F(request.POST or None)
if form.is_valid():
form.instance.author = request.user
form.save()
return redirect('WellMonitor')
else:
try:
PUITS_id = request.GET.get('PUITS')
record2 = SurveillanceDesPuits.objects.filter(PUITS_id__id__exact=PUITS_id)[:1]
return JsonResponse({'record2': list(record2.values())}, safe=False)
except:
form = SurveillanceDesPuits_F()
return render(request, 'measure/Surveill_Wells/Add_wellMntr2.html', {'form': form})
the last change is in the HTML page and the ajax code call will be as:
<script type="text/javascript">
$.ajax({
type: 'GET' ,
url: url,
data: {'PUITS': PUITSId },
dataType: "json",
success: function (response){
var response = JSON.parse(response);
const object = response[0]
$("#id_PUITS").val(object.fields.PUITS);
$("#id_DATE_TEST").val(object.fields.DATE_TEST);
$("#id_MODE").val(object.fields.MODE);
$("#id_CS").val(object.fields.CS);
$("#id_SITUATION").val(object.fields.SITUATION);
$("#id_DUSE").val(object.fields.DUSE);
$("#id_PRES_TBG").val(object.fields.PRES_TBG);
$("#id_PRES_CSG").val(object.fields.PRES_CSG);
$("#id_PRES_AVD").val(object.fields.PRES_AVD);
$("#id_RESEAU_GL").val(object.fields.RESEAU_GL);
$("#id_ANNULAIRE_TECH").val(object.fields.ANNULAIRE_TECH);
$("#id_OBSERVATION").val(object.fields.OBSERVATION);
$("#id_Controle_Pression_ENSP").val(object.fields.Controle_Pression_ENSP);
$("#id_Test_Puits").val(object.fields.Test_Puits);
$("#id_Controle_Pression_DP").val(object.fields.Controle_Pression_DP);
},
});
return false;
});
</script>
this will avoid the duplicated page caused by the
$("#SurveillanceDesPuits_F").html(response);
Many thanks
I have the following models.py file which has the table and modelform. I'm working with has and the HTML template and I want some JavaScript code to multiply the value of rate input and quantity input then set it dynamically into total cost input before I click on submit.
ModelForm:
class ExpenseBasedTransactionForm(ModelForm):
def __init__(self, *args, **kwargs):
super(ExpenseBasedTransactionForm, self).__init__(*args, **kwargs)
eb_client = Clientele.objects.filter(clientele_type__icontains='eb client').values_list("id", "clientele_name")
eb_main = []
for i in eb_client:
k = list(i)
k[0] = str(k[0])
l = (tuple(k))
eb_main.append(l)
self.fields['eb_client'] = ChoiceField(choices=eb_main, label='EB Client', )
class Meta:
model = ExpenseBasedTransaction
# fields = '__all__' #to include all the fields in the form
# specify what fields to be included in the form
fields = ['date_initiated', 'eb_client', 'rate',
'quantity', 'total_cost']
widgets = {
'date_initiated': AdminDateWidget(),
'rate': NumberInput(attrs={'class': 'form-control', 'id': 'rate'}),
'quantity': NumberInput(attrs={'class': 'form-control', 'id': 'quantity'}),
'total_cost': NumberInput(attrs={'class': 'form-control', 'id': 'total'}),
}
html:
{% extends "base.html" %}
{% load bootstrap3%}
{% block content %}
<div class="content-wrapper" id="tab">
<div class="content">
<div class="head">
<div class="row">
<div class="col-sm-7 title" >
<span><i class="fa fa-pencil"></i> Record An Expense</span>
</div>
</div>
</div>
<div class="content padding table-responsive" >
<div class="wrapper">
<form method="post">
{% csrf_token %}
{% bootstrap_form form %}
<br>
<button type="reset" class="btn btn-warning m-sm-right"><i class="fa fa-trash-o fa-lg
white" aria-hidden="true"></i> Clear</button>
<button id="proceed" class="btn btn-primary m-sm-right">Proceed <i class="fa fa-
arrow-circle-right fa-lg white" aria-hidden="true"></i></button>
</form>
</div>
</div>
</div> <!-- end of content -->
</div> <!--end of content-wrapper -->
<script type="text/javascript">
</script>
{% endblock content %}
please try this:
update your widgets in Modelform (note that you needn't set custom id in your modelform widget, just add onchange event:
widgets = {
'date_initiated': AdminDateWidget(),
'rate': NumberInput(attrs={'class': 'form-control', 'onchange': 'calculateTotalCost()'}),
'quantity': NumberInput(attrs={'class': 'form-control', 'onchange': 'calculateTotalCost()'}),
'total_cost': NumberInput(attrs={'class': 'form-control'}),
}
and then describe this event-function in your template (add this code to your template between script tag:
function calculateTotalCost () {
var rate = Number(document.getElementById('id_rate').value);
var quantity = Number(document.getElementById('id_quantity').value);
if (rate && quantity) {
document.getElementById('id_total_cost').value = rate * quantity
}
}
I have a multiple select2 Select field.
What I want is to add a new value to my select field. (after adding an entry to the database and bind this entry to the select field)
This is my code so far:
Blade template:
<div class="form-group {{ ($errors->first('projectTypes')) ? 'has-error' : '' }}">
<label for="projectTypes" class="col-md-2 control-label">{{ trans('project/project.fields.projectTypes') }}</label>
<div class="col-md-9">
{!! Form::select('projectTypes[]',
$projectTypes,
($project->projectTypes()->count() > 0) ? $project->projectTypes->lists('id')->toArray() : (isset($projectType)) ? $projectType->id : '',
['id' => 'projectTypes', 'class' => 'form-control', 'ng-model' => 'projectTypes', 'multiple' => 'multiple'])
!!}
<span id="helpBlock" class="help-block">{{ $errors->first('projectTypes') }}</span>
</div>
<div class="col-md-1">
<i class="fa fa-plus-square-o fa-2" data-toggle="modal" data-target="#addProjectType"></i>
</div>
The <i> tag toggles the modal. In the modal window I have an input field and a button (it works!):
<input ng-model="name" id="addProjectType" class="form-control" type="text" name="name" placeholder="Projekttyp">
<button type="button" class="btn btn-primary btn-embossed" ng-click="addProjectType(name)" data-dismiss="modal">Save changes</button>
So if I click on the button this will trigger a function in my angularJS code (this works!).
This is my angularJS Code:
$scope.projectTypes = [];
$scope.addProjectType = function(name) {
$http.post('/ajax/projecttype/addprojecttype', {
name: name
}).success(function(data, status, headers, config) {
$scope.projectTypes.push(data);
});
}
This do an ajax call to my laravel php function (this works!):
public function addProjectType(Request $request, Sentinel $sentinel) {
$name = $request->get('name');
$projectType = new ProjectType;
$projectType->name = $name;
$projectType->slug = $projectType->strSlug($name);
$this->created_by = $sentinel::getUser()->id;
$this->updated_by = $sentinel::getUser()->id;
$projectType->saveModel($request);
return Response::json($projectType, self::$OK);
}
But although I have declared my select field (ng-model="projectTypes")
and I declared the $scope.projectTypes and push the new Object to the $scope.projectTypes after the ajax call the select field won't update.
What am I doing wrong here?
I'd like to ask you how i can save my edited data when im using this table
peminjaman |id|tgl_pinjam|lama_pinjam|tgl_hrs_kembali|status_pinjam|totalBayar|diskon|jml_bayar|status_pembayaran|tgl_pengembalian|denda|ket_kembali|id_member
Then here is my route:
Route::post('staff-view-peminjaman/update/{id}', 'PeminjamanController#update');
Here is my controller
function update($id) {
$peminjaman = \peminjaman::find($id);
$peminjaman->tgl_pinjam = \Input::get('tgl_pinjam');
$peminjaman->lama_pinjam = \Input::get('lama_pinjam');
$peminjaman->tgl_hrs_kembali = \Input::get('tgl_hrs_kembali');
$peminjaman->status_pinjam = \Input::get('status_pinjam');
$peminjaman->status_pembayaran = \Input::get('status_pembayaran');
$peminjaman->totalBayar = \Input::get('totalBayar');
$peminjaman->jml_bayar = \Input::get('jumlahBayar');
$peminjaman->tgl_pengembalian = \Input::get('tgl_pengembalian');
$peminjaman->denda = \Input::get('denda');
$peminjaman->ket_kembali = \Input::get('ket_kembali');
$peminjaman->id_member = \Input::get('id_member');
$peminjaman->save();
return \Redirect::to('staff-view-peminjaman');
}
And here is my view for editing
<form method="post" role="form" action="{{ action ('Controller\Staff\PeminjamanController#update'),$peminjaman->id }}">
<div class="form-group">
<label for="exampleInputTglPinjam">Tanggal Pinjam</label>
<input type="text" class="form-control" id="exampleInputTglPinjam" placeholder="Tanggal Pinjam" name="tgl_pinjam" value="{{ $peminjaman->tgl_pinjam }}">
</div>
<div class="control-group">
<label class="control-label" for="exampleInputLamaPinjam">Lama Pinjam</label>
<input type="text" class="form-control" id="exampleInputLamaPinjam" placeholder="Lama Pinjam" name="lama_pinjam" value="{{ $peminjaman->lama_pinjam }}">
</div>
.............
<p>Bayar Pengembalian: <div id="bayar" name="bayar"></div></p>
And I have this button to save
<button type="submit" class="btn btn-primary" id="buttonSimpan">Simpan</button>
and this javascript to calculate the price
<script type="text/javascript">
$(function() {
$('#exampleInputTglPengembalian').datepicker({
format: 'yyyy/mm/dd'
});
$("#exampleInputDenda").change(function() {
var bayar = parseInt("0");
var totalBayar = parseInt($("#inputTotalBayar").val());
var jumlahBayar = parseInt($("#inputJumlahBayar").val());
var denda = parseInt($("#exampleInputDenda").val());
bayar = bayar + denda + totalBayar - jumlahBayar;
$("#bayar").html(bayar);
});
});
Somehow it doesn't work and give me this warning
Creating default object from empty value
I'd love to know how to solve it but i dunno what to do
if you know, I hope you are willing to tell me what to do...
The error is because the ID isn't getting passed through properly, so the model can't find the record. Your syntax is slightly wrong when defining the action. It should be this:
<form method="post" role="form" action="{{ action('Controller\Staff\PeminjamanController#update', array('id' => $peminjaman->id)) }}">
Also to prevent that error from happening, your code should think about using findOrFail when updating records.
$peminjaman = \peminjaman::findOrFail($id);