Passing date functions to javascript in laravel - javascript

I am getting some data using ajax but I cannot pass diffForHuman() function to get different format of date. I want date in another format. But by passing created_at to my markup then it is giving me undefined date. Below is my code. Pls help
//Javascript
$(document).ready(function () {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
});
$('select[name="class_id"]').on('change', function() {
var classID = $(this).val();
if(classID) {
$.ajax({
url: '/attendance/ajax/'+classID,
type: "GET",
dataType: "json",
success:function(data) {
var markup = '';
markup += '<tr><th style="width: 2%" class="align-middle text-center"><input type="checkbox" id="options"></th><th style="width: 2%" class="align-middle text-center">#</th> <th style="width: 15%" class="text-center">Student ID<input type="text" class="form-control" disabled></th> <th style="width: 15%" class="text-center">Student Name<input type="text" class="form-control" disabled></th> <th style="width: 15%" class="text-center">Attendance<input type="text" class="form-control" disabled></th> <th style="width: 15%" class="text-center">Date<input type="text" class="form-control" disabled></th> <th style="width: 15%;" class="align-middle text-center">Actions</th> <tr>';
$.each(data, function(key, value) {
markup += '<tr> <td><input class="checkBoxes" type="checkbox" name="checkBoxArray[]"></td> <td><input type="hidden" value="'+value.id+'" name="id[]">' + value.id + '</td> <td><input type="hidden" value="'+value.student_id+'" name="student_id[]">' + value.student_id + '</td> <td><input type="hidden" value="'+value.first_name+'" name="first_name[]"><input type="hidden" value="'+value.last_name+'" name="last_name[]">' + value.first_name+ ' ' + value.last_name + '<td><input type="hidden" value="'+value.attendance+'" name="attendance[]">' + value.attendance + '</td>' + '<td><input type="hidden" value="'+value.created_at+'" name="created_at[]">' + value.created_at + '</td>' + '<td style=" width=12%" class="text-center"> <a><button title="Edit" class="btn btn-outline-primary"><span class="fas fa-pencil-alt"></span></button></a> </td>' + '</td> <tr>';
});
$('table[id="studentsData"]').html(markup);
}
});
}
});
});
//Controller
public function student_attendance_registers() {
$attendances = StudentsAttendance::all();
$classes = StudentsClass::pluck('class_name', 'id')->all();
return view('admin.students.attendance.student_attendance_registers', compact('attendances', 'classes'));
}
//Model
class StudentsAttendance extends Model
{
protected $fillable = [
'class_id',
'student_id',
'first_name',
'last_name',
'attendance'
];
public function studentsClass() {
return $this->belongsTo('App\StudentsClass');
}
public function getdateForHumansAttribute()
{
return $this->created_at->diffForHumans();
}
public function toArray()
{
$data = parent::toArray();
$data['diffForHumans'] = $this->diffForHumans;
return $data;
}
}

The best way to do this, would be to add a getdateForHumanAttribute method:
public function getdateForHumansAttribute()
{
return $this->created_at->diffForHumans();
}
Then on your model you can use anywhere:
$model->dateForHumans;
For an easy way to always add dateForHumans attribute when you retrieve this model, add it to toArray method:
(Also on your model)
public function toArray()
{
$data = parent::toArray();
$data['diffForHumans'] = $this->diffForHumans;
return $data;
}

Related

Ajax send array of data to backend

I have table where I loop dynamic data and each of those dynamic items has input fields then I send those input fields along with dynamic items id to back-end.
Issue
Issue is that my fields in ajax giving me strange data as array.
Code
$(function() {
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
$('.newservicesSave').on('click', function(e) {
e.preventDefault();
e.stopPropagation();
var idmess = $(this).data("id");
// this array data are wrong
var newservices = [];
$(".newservices").each(function() {
newservices.push($(this).val());
});
console.log('newservices: ', newservices);
$.ajax({
url: '{{ url('
panel / addnewservices ') }}/' + encodeURI(idmess),
type: 'POST',
dataType: "JSON",
data: {
"id": idmess,
"newservices": newservices,
"_method": 'POST',
"_token": "{{ csrf_token() }}",
},
success: function(data) {
$('#servicesTable').empty();
$.each(data.data, function(key, value) {
$("#servicesTable").append('<tr><td>' + value['name'] + '</td><td><textarea name="' + services['key']['description'] + '" class="form-control" name="description"></textarea><input type="hidden" name="' + services['key']['service_id'] + '"/></td><td><input type="text" class="form-control" placeholder="Harga" name="' + services['key']['price'] + '"/></td><td><input class="form-checkbox" type="checkbox" name="' + services['key']['active'] + '" /></td></tr>');
});
}
});
});
});
<table class="table table-bordered table-striped table-hover">
<thead>
<tr>
<th>Service</th>
<th>Description</th>
<th>Harga</th>
<th>Active</th>
</tr>
</thead>
<tbody>
#foreach($services as $index => $service)
<tr>
<td>{{$service->name}}</td>
<td>
<textarea name="newservices[{{$index}}][description]" class="newservices form-control" name="description"></textarea>
<input type="hidden" class="newservices" name="newservices[{{$index}}][service_id]" />
</td>
<td>
<input type="text" class="newservices form-control" placeholder="Harga" name="newservices[{{$index}}][price]" />
</td>
<td><input class="newservices form-checkbox" type="checkbox" name="newservices[{{$index}}][active]" /></td>
</tr>
#endforeach
</tbody>
</table>
<button type="button" data-id="{{$laundry->id}}" class="newservicesSave btn btn-primary">Save changes</button>
Result
Expected data from ajax
Data should come to backend as follow structure
newservices [
0 [
active => 0,
service_id => '123456',
description => 'abc',
price => '1000'
],
1 [...],
2 [...],
// etc.
]
Any idea?
To get the structure you want you will need to loop over rows and create an object for each row
Try something like :
var newservices = $('#myTable tbody tr').map(function(){
var $row = $(this);
return {
description: $row.find('.newservices[name*="description"]').val(),
service_id : $row.find('.newservices[name*="service_id"]').val(),
// ... same for other properties
}
}).get();

How to get the values of a dynamically created table?

The above screenshot shows the actual correct form. For getting this I tried the below code. My <td> contains a heading as well as a subpoint, which are added dynamically. On click of the Submit button, I want to read the heading & subpoint corresponding to that heading. The data format is given below.
I'm adding the rows dynamically with the header and the data respectively. I'm trying to gather the data in an object before sending the data to the server via AJAX. I'm not able to read the data in the given format.
HTML CODE
<div class="container-fluid">
<h4>Scorecard Metrics</h4>
<div class="row">
<div class="col">
<div class="card">
<div class="card-body">
<div class="button-bar">
<button class="btnn btnn--pill add-point">Add Sub-Point</button>
<button class="btnn btnn--pill add-heading">Add Heading</button>
</div>
<div class="table-responsive-sm">
<table id="table-scorecard_co" class="table table-bordered">
<thead>
<tr>
<th style="width: 100px!important;" rowspan="2">Metrics</th>
<th style="width: 92px!important;" rowspan="2">Weightage</th>
<th colspan="4" scope="colgroup">Target</th>
<th style="width: 85px!important;" rowspan="2">Actions</th>
</tr>
<tr>
<th>L1</th>
<th>L2</th>
<th>L3</th>
<th>L4</th>
</tr>
</thead>
<tbody>
<tr>
<td style="display: none;">
<a class="plus" title="Plus" ><i class="material-icons"></i></a>
<a class="update" title="Update" data-toggle="tooltip"><i class="material-icons"></i></a>
<a class="destroy" title="Destroy"><i class="material-icons"></i></a>
</td>
<td style="display: none;">
<a class="add" title="Add" ><i class="material-icons"></i></a>
<a class="edit" title="Edit" data-toggle="tooltip"><i class="material-icons"></i></a>
<a class="delete" title="Delete"><i class="material-icons"></i></a>
</td>
</tr>
</tbody>
</table>
</div>
<div class="button-bar">
<button class="btnn btnn--pill submit" id="Scoresubmit">Submit</button>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- #/ container -->
</div>
JAVASCRIPT CODE
$(document).ready(function(){
$('[data-toggle="tooltip"]').tooltip();
var actions = $("table td:last-child").html();
var menubar = $("table td:nth-last-child(2)").html();
$(".add-heading").click(function(){
$(this).attr("disabled", "disabled");
var index = $("table tbody tr:last-child").index();
var row = '<tr class="heading">' +
'<td id="HeadingLabelScorecard" colspan="3"><span id="label_hide" class="heading_label">Heading</span><input id="heading_label_input" class="heading_label-box" type="text" class="form-control"></td>' +
'<td id="HeadingLabelScorecard" colspan="2"><span id="label_hide2" class="heading_weight-label">Total Weightage</span><input class="Tweightage" id="wei'+(wei) + '" type="number" ></td>' +
'<td colspan="1"><span id="label_hide3" class="heading_labelCheckbox">Divide Weightage</span><input class="heading_checkbox" name="Dividecheckbox" id="heading_checkbox" type="checkbox">' +
'<td style="text-align:center;">' + actions + '</td>' +
'</tr>';
$("table").append(row);
$("table tbody tr").eq(index + 1).find(".add, .edit").toggle();
$('[data-toggle="tooltip"]').tooltip();
wei ++;
});
$(".add-point").click(function(){
$(this).attr("disabled", "disabled");
var index = $("table tbody tr:last-child").index(); //TO ADD ROW AS LAST Child
var lastCheckBox = $('[name="Dividecheckbox"]:last').prop("checked"); //get status of last checkbox
if(lastCheckBox==false){
//Enable row
var row = '<tr class="Parameters" style="text-align: center;">' +
'<td><input class="subpoint_label-box" type="text" class="form-control"id="metrics'+(unique_id) + '"></td>' +
'<td><input disabled class="subpoint_weightage2" id="weightage'+(unique_id) + '" type="number" ></td>' +
'<td><input class="slider_min-value" type="text" id="ex0n'+i+'" value="20"><b id="percentage">%</b><input class="subpoint-sbody" style="width: 120px;" name="n'+i+'" id="ex'+(unique_id) + '" type="text" data-slider-min="0" data-slider-max="100" data-slider-value="[20,80]"/><input class="slider_max-value" type="text" id="ex1n'+(i)+'" value="80"><b id="percentageMax">%</b></td>' +
'<td><input class="slider_min-value" type="text" id="lx0n'+(i)+'" value="20"><b id="percentage">%</b><input class="subpoint-sbody" style="width: 120px;" name="n'+i+'" id="lx'+(unique_id) + '" type="text" data-slider-min="0" data-slider-max="100" data-slider-value="[20,80]"/><input class="slider_max-value" type="text" id="lx1n'+(i)+'" value="80"><b id="percentageMax">%</b></td>' +
'<td><input class="slider_min-value" type="text" id="zx0n'+(i)+'" value="20"><b id="percentage">%</b><input class="subpoint-sbody" style="width: 120px;" name="n'+i+'" id="zx'+(unique_id) + '" type="text" data-slider-min="0" data-slider-max="100" data-slider-value="[20,80]"/><input class="slider_max-value" type="text" id="zx1n'+(i)+'" value="80"><b id="percentageMax">%</b></td>' +
'<td><input class="slider_min-value" type="text" id="yx0n'+(i)+'" value="20"><b id="percentage">%</b><input class="subpoint-sbody" style="width: 120px;" name="n'+i+'" id="yx'+(unique_id) + '" type="text" data-slider-min="0" data-slider-max="100" data-slider-value="[20,80]"/><input class="slider_max-value" type="text" id="yx1n'+(i)+'" value="80"><b id="percentageMax">%</b></td>' +
'<td width="20">' + menubar + '</td>' +
'</tr>';
}
else if(lastCheckBox==true){
var row = '<tr class="Parameters" style="text-align: center;">' +
'<td width="20"height="50"><input class="subpoint_label-box" type="text" class="form-control"id="metrics'+(unique_id) + '"></td>' +
'<td width="20"><input class="subpoint_weightage" id="weightage'+(unique_id) + '" type="number" ></td>' +
'<td><input class="slider_min-value" type="text" id="ex0n'+i+'" value="20"><b id="percentage">%</b><input class="subpoint-sbody" style="width: 120px;" name="n'+i+'" id="ex'+(unique_id) + '" type="text" data-slider-min="0" data-slider-max="100" data-slider-value="[20,80]"/><input class="slider_max-value" type="text" id="ex1n'+(i)+'" value="80"><b id="percentageMax">%</b></td>' +
'<td><input class="slider_min-value" type="text" id="lx0n'+(i)+'" value="20"><b id="percentage">%</b><input class="subpoint-sbody" style="width: 120px;" name="n'+i+'" id="lx'+(unique_id) + '" type="text" data-slider-min="0" data-slider-max="100" data-slider-value="[20,80]"/><input class="slider_max-value" type="text" id="lx1n'+(i)+'" value="80"><b id="percentageMax">%</b></td>' +
'<td><input class="slider_min-value" type="text" id="zx0n'+(i)+'" value="20"><b id="percentage">%</b><input class="subpoint-sbody" style="width: 120px;" name="n'+i+'" id="zx'+(unique_id) + '" type="text" data-slider-min="0" data-slider-max="100" data-slider-value="[20,80]"/><input class="slider_max-value" type="text" id="zx1n'+(i)+'" value="80"><b id="percentageMax">%</b></td>' +
'<td><input class="slider_min-value" type="text" id="yx0n'+(i)+'" value="20"><b id="percentage">%</b><input class="subpoint-sbody" style="width: 120px;" name="n'+i+'" id="yx'+(unique_id) + '" type="text" data-slider-min="0" data-slider-max="100" data-slider-value="[20,80]"/><input class="slider_max-value" type="text" id="yx1n'+(i)+'" value="80"><b id="percentageMax">%</b></td>' +
'<td width="20">' + menubar + '</td>' +
'</tr>';
}
else{
alert("Please Add Heading!!");
}
$("table").append(row);
$("table tbody tr").eq(index + 1).find(".plus, .update").toggle();
$('[data-toggle="tooltip"]').tooltip();
$("#ex"+unique_id).slider({});
$("#ex"+unique_id).on("slide", function(slideEvt) {
var nid=$(this).attr('name');
$("#ex0"+nid).val(slideEvt.value[0]);
$("#ex1"+nid).val(slideEvt.value[1]);
});
$("#lx"+unique_id).slider({});
$("#lx"+unique_id).on("slide", function(slideEvt) {
var nid=$(this).attr('name');
$("#lx0"+nid).val(slideEvt.value[0]);
$("#lx1"+nid).val(slideEvt.value[1]);
});
$("#zx"+unique_id).slider({});
$("#zx"+unique_id).on("slide", function(slideEvt) {
var nid=$(this).attr('name');
$("#zx0"+nid).val(slideEvt.value[0]);
$("#zx1"+nid).val(slideEvt.value[1]);
});
$("#yx"+unique_id).slider({});
$("#yx"+unique_id).on("slide", function(slideEvt) {
var nid=$(this).attr('name');
$("#yx0"+nid).val(slideEvt.value[0]);
$("#yx1"+nid).val(slideEvt.value[1]);
});
unique_id++
i++
});
WHAT I TRIED TO GET THE DATA
$('#Scoresubmit').click(function () {
GetCoScoreCard();
//ajax calll
});
function GetCoScoreCard() {
$('#scorecard_co .heading').each(function () { //tr
var TotalWeightage;
var item = $(this).closest("tr").find('td');
$.each(item, function (key, value) { //Heading
if (key == 0) {
Heading1 = ($(value).text());
this.Heading1 = Heading1;
}
else if (key == 1) {
TotalWeightage = ($(value).text());
}
else if (key == 2) {
lastCheckBox = $('[name="Dividecheckbox"]:last').prop("checked");
}
});
var parametername, param_Weightage;
$('#scorecard_co .Parameters').each(function () { //td //parameters
var item2 = $(this).closest("tr").find('td');
$.each(item2, function (key, value) {
datalist = ($(value).text());
if (key == 0) {
parametername = ($(value).text());
}
if (key == 1) {
param_Weightage = ($(value).text());
}
if (key == 2 || key == 3 || key == 4 || key == 5)
{
var res = datalist.substring(1, 3);
var res2 = datalist.substring(6, 8);
var key1 = 'L' + i;
MyLevels[key1] = res + "," + res2;
i++;
}
});
parameters = {
"Name": parametername,
"Weightage": param_Weightage,
"Levels": MyLevels, //array
}
paramarray.push(parameters); //paramNewArray
MyLevels = {};
i = 0;
});
metrics={
'Heading':Heading1,
'TotalWeitage': TotalWeightage, //metrics heading and parameters
'DivideWeightage': lastCheckBox,
'parameters': paramarray // paramNewArray
//work in process
}
var stringyfydata = JSON.stringify(metrics);
data1.push(stringyfydata); alert("Title=" + data1);
console.log(data1);
data = {};
parameters = {};
i = 0;
});
}
EXPECTED DATA OUTPUT
[
{"Heading":"SchduleAdherence","TotalWeitage":"20","DivideWeightage":true,"parameters":{"Name":"Scrunity","Weightage":"30","Levels":{"L1":"20,80","L2":"20,80","L3":"20,80","L4":"20,80"}}]},
{"Heading":"Attendence","TotalWeitage":"30","DivideWeightage":true,"parameters":{"Name":"self","Weightage":"30","Levels":{"L1":"20,80","L2":"20,80","L3":"20,80","L4":"20,80"}}]}
]
There are two classes (.Heading = to read the heading, e.g. attendance & another is .Parameter = to read the sub-points), my issue is that every time I try to loop through the data, all the parameters are getting added repeatedly in my object.
you need to re initialize your variable in go score code;
function GetCoScoreCard() {
paramArray = [];
data1 = [];
.....
.....
}

I want to add new data from second table to main table

I want to add new data to the main table using the checkbox option, but the data added is not the same as the selected data. this is my code ...
<table border="1" id="table2">
<tr>
<td>Raka</td>
<input type="hidden" id="fname" value="Raka">
<td>Gilbert</td>
<input type="hidden" id="lname" value="Gilbert">
<td><input type="checkbox" name="chk"></td>
</tr>
<tr>
<td>Achyar</td>
<input type="hidden" id="fname" value="Achyar">
<td>Lucas</td>
<input type="hidden" id="lname" value="Lucas">
<td><input type="checkbox" name="chk"></td>
</tr>
</table>
<script>
$(document).on('click', '#Add', function() {
$("table").find('input[name="chk"]').each(function(){
if($(this).is(":checked")){
var fname = $('#fname').val();
var lname = $('#lname').val();
var newData = '<tr>'+
'<td>'+fname+'</td>'+
'<td>'+lname+'</td>'+
'<tr>';
$('table').append(newData);
}
});
})
</script>
You need to change your id="fname" to class="fname" and get the input value closest to checkbox. Currently you are getting data from the first inputs as they have the same id's.
function valueExists(value) {
if (!value) {
return true;
}
let exists = false;
$("#main-table").find('tr').each(function() {
let fname = $(this).find("td:nth-child(1)").text(),
lname = $(this).find("td:nth-child(2)").text();
const fullName = `${fname}${lname}`;
if (value.toLowerCase() === fullName.toLowerCase()) {
exists = true;
}
});
return exists;
}
$(document).on('click', '#add', function() {
$("table").find('input[name="chk"]').each(function(e) {
if ($(this).is(":checked")) {
var fname = $(this).parents('tr').find('.fname').val();
var lname = $(this).parents('tr').find('.lname').val();
if (valueExists(`${fname}${lname}`)) return;
var newData = '<tr>' +
'<td>' + fname + '</td>' +
'<td>' + lname + '</td>' +
'<tr>';
$('#main-table').append(newData);
}
});
})
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<h1>Main Table</h1>
<table class="table table-dark" border="1" id="main-table">
</table>
<hr>
<h1>Second table</h1>
<table border="1" id="table2">
<tr>
<td class="name">Raka</td>
<input type="hidden" class="fname" value="Raka">
<td class="last">Gilbert</td>
<input type="hidden" class="lname" value="Gilbert">
<td><input class="check" type="checkbox" name="chk"></td>
</tr>
<tr>
<td class="name">Achyar</td>
<input type="hidden" class="fname" value="Achyar">
<td class="last">Lucas</td>
<input type="hidden" class="lname" value="Lucas">
<td><input class="check" type="checkbox" name="chk"></td>
</tr>
</table>
<button type="button" id="add" name="button">Add</button>
Try this. I have used plain javascript
document.addEventListener("click", function() {
[...document.querySelectorAll("input[name='chk']")].forEach(data => {
console.log(data);
if (data.checked) {
const fname = document.getElementById("fname").value;
const lname = document.getElementById("lname").value;
const newData = `<tr><td>${ fname }</td><td>${ lname }</td</tr>`;
// "<tr>" + "<td>" + fname + "</td>" + "<td>" + lname + "</td>" + "<tr>";
document.getElementById("table2").innerHTML += newData;
}
});
});
Hope was useful. If any flaws please update
Here is a neater solution, using 2 tables as requested, without hidden inputs and a better use of 'tables' and 'trs' in jquery
$(function(){
$("#btnAdd").click(function(){
let table1 = $("#table1");
table2 = $("#table2");
$.each(table2.find('tr'), function(i, tr){
tr = $(tr);
let new_tr = $('<tr>');
if (tr.find("td input").is(":checked")) {
let fname = tr.find("td:nth-child(1)").html(),
lname = tr.find("td:nth-child(2)").html();
new_tr.append(
'<td>' + fname + '</td>' +
'<td>' + lname + '</td>' +
'<td><input type="checkbox" name="chk"></td>'
);
table1.append(new_tr)
}
})
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
TABLE 1
<table border="1" id="table1">
</table>
<hr/>
TABLE 2
<table border="1" id="table2">
<tr>
<td>Raka</td>
<td>Gilbert</td>
<td><input type="checkbox" name="chk"></td>
</tr>
<tr>
<td>Achyar</td>
<td>Lucas</td>
<td><input type="checkbox" name="chk"></td>
</tr>
</table>
<button type="button" id="btnAdd">Add</button>

dynamic form not submitting when display goes from none to block

I have created a script that sends a form that sends a form, a form that is dynamic depending on users choices.
The form in the html side looks fine, the code in the jQuery side executes fine until the actual form submits, and nothing in the console log tells me there is anything wrong at all.
The only thing I can think of is that this form starts being a display:none; in the css and then becomes available ones the person clicks a button saying add new payments.
Here is the html side of things:
<div class="section-9">
<form action="#" id="addform" method="post">
<div class="row">
<div class="col-sm-12">
<div class="table-responsive" id="addsection">
<table class="table table-responsive table-hover table-striped">
<thead>
<th>Number</th>
<th>Price</th>
<th class="text-center">Installments</th>
<th>Contact Name</th>
</thead>
<tbody>
<tr>
<td><input type="text" class="form-control" id="addnumber" value="" placeholder="Enter CPO Number"></td>
<td><input type="text" class="form-control" id="addprice" value="" placeholder="Enter CPO Number"></td>
<td class="text-center">Installments</td>
<td><input type="text" class="form-control" id="addcontactname" value="" placeholder="Enter Contact Name"></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="col-sm-12" id="addformajax"></div>
<div class="col-sm-12 margin-top-15">
<p><button class="btn btn-danger btn-block" type="button">SUBMIT</button></p>
</div>
</div>
</form>
</div>
No need to show css as its only display none in the section-9 class.
$('#addnew').on('click', function(e) {
e.preventDefault();
$('.section-9').show();
//do the click button for cpo installments
$('.addi').on('click', function(event) {
event.preventDefault();
var installmentAmount = '<p><select class="form-control" id="installment-ammount"><option value="0">Please Select How Many Installments Are Required</option>';
for (var i = 1; i <= 60; i++) {
if (i === 1) {
installmentAmount += '<option value="' + i + '">' + i + ' Month</option>';
} else {
installmentAmount += '<option value="' + i + '">' + i + ' Months</option>';
}
}
installmentAmount += '</select></p><div class="showinstallmentdates margin-top-20"></div>';
$('#addformajax').html(installmentAmount);
$('#installment-ammount').bind('input', function() {
var buildDateForms = '<p class="red padding-top-20"><i class="fa fa-star"></i> <em>If all amounts are left empty the price will be distributed evenly across all dates</em></p>';
var howManyInstallments = $(this).val();
var addingIdNames = '';
for (var hmi = 1; hmi <= howManyInstallments; hmi++) {
buildDateForms += '<div class="form-group row"><div class="col-xs-6"><input type="text" class="form-control" id="adddate-' + hmi + '" placeholder="Enter Date To Be Paid" value=""></div><div class="col-xs-6"><input type="text" class="form-control" id="addprice-' + hmi + '" placeholder="Amount To Be Paid" value=""></div></div>';
if (hmi == 1) {
addingIdNames += '#adddate-' + hmi;
} else {
addingIdNames += ', #adddate-' + hmi;
}
}
buildDateForms += '<input type="hidden" value="' + howManyInstallments + '" name="totalinstallments" id="totalinstallments">';
buildDateForms += '<script>jQuery(document).ready(function($){ $("';
buildDateForms += addingIdNames;
buildDateForms += '").datepicker({});});<\/script>';
if (howManyInstallments != 0) {
$('.showinstallmentdates').html(buildDateForms);
} else {
$('.showinstallmentdates').html('');
}
});
});
$("#addform").on('submit', function() {
$.ajax({
url: "/Applications/Controllers/Quotes/ajax-add-sin.php",
type: "POST",
data: new FormData(this),
contentType: false,
cache: false,
processData: false,
success: function(sinData) {
$('body').html(sinData);
}
});
});
});
Granted I am not amazing at jQuery as its not what I use a lot and I am sure a wiz would be able to chop this down to be more efficient and streamline but according to the console I have no issues, and the html looks good also when its all displayed so I can not see a reason why the form is not submitted.
Thanks
Add id to button
<button id="btn-add-form" class="btn btn-danger btn-block" type="button">SUBMIT</button>
Put script to document.ready function
Change ajax function to
$("#btn-add-form").on('click', function () {
$.ajax({
url: "/Applications/Controllers/Quotes/ajax-add-sin.php",
type: "POST",
data: new FormData(this),
contentType: false,
cache: false,
processData: false,
success: function (sinData) {
$('body').html(sinData);
}
});
});
complete code:
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<title>New Page 1</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.0/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
$('#addnew').on('click', function (e) {
e.preventDefault();
$('.section-9').show();
//do the click button for cpo installments
$('.addi').on('click', function (event) {
event.preventDefault();
var installmentAmount = '<p><select class="form-control" id="installment-ammount"><option value="0">Please Select How Many Installments Are Required</option>';
for (var i = 1; i <= 60; i++) {
if (i === 1) {
installmentAmount += '<option value="' + i + '">' + i + ' Month</option>';
} else {
installmentAmount += '<option value="' + i + '">' + i + ' Months</option>';
}
}
installmentAmount += '</select></p><div class="showinstallmentdates margin-top-20"></div>';
$('#addformajax').html(installmentAmount);
$('#installment-ammount').bind('input', function () {
var buildDateForms = '<p class="red padding-top-20"><i class="fa fa-star"></i> <em>If all amounts are left empty the price will be distributed evenly across all dates</em></p>';
var howManyInstallments = $(this).val();
var addingIdNames = '';
for (var hmi = 1; hmi <= howManyInstallments; hmi++) {
buildDateForms += '<div class="form-group row"><div class="col-xs-6"><input type="text" class="form-control" id="adddate-' + hmi + '" placeholder="Enter Date To Be Paid" value=""></div><div class="col-xs-6"><input type="text" class="form-control" id="addprice-' + hmi + '" placeholder="Amount To Be Paid" value=""></div></div>';
if (hmi == 1) {
addingIdNames += '#adddate-' + hmi;
} else {
addingIdNames += ', #adddate-' + hmi;
}
}
buildDateForms += '<input type="hidden" value="' + howManyInstallments + '" name="totalinstallments" id="totalinstallments">';
buildDateForms += '<script>jQuery(document).ready(function($){ $("';
buildDateForms += addingIdNames;
buildDateForms += '").datepicker({});});<\/script>';
if (howManyInstallments != 0) {
$('.showinstallmentdates').html(buildDateForms);
} else {
$('.showinstallmentdates').html('');
}
});
});
});
$("#btn-add-form").on('click', function () {
$.ajax({
url: "/Applications/Controllers/Quotes/ajax-add-sin.php",
type: "POST",
data: $('#addform').serialize(),
contentType: false,
cache: false,
processData: false,
success: function (sinData) {
$('body').html(sinData);
}
});
});
});
</script>
</head>
<body>
<div class="section-9">
<form id="addform" method="post">
<div class="row">
<div class="col-sm-12">
<div class="table-responsive" id="addsection">
<table class="table table-responsive table-hover table-striped">
<thead>
<th>Number</th>
<th>Price</th>
<th class="text-center">Installments</th>
<th>Contact Name</th>
</thead>
<tbody>
<tr>
<td><input name="addnumber" type="text" class="form-control" id="addnumber" value="" placeholder="Enter CPO Number"></td>
<td><input name="addprice" type="text" class="form-control" id="addprice" value="" placeholder="Enter CPO Number"></td>
<td class="text-center">Installments</td>
<td><input name="addcontactname" type="text" class="form-control" id="addcontactname" value="" placeholder="Enter Contact Name"></td>
</tr>
</tbody>
</table>
</div>
</div>
<div class="col-sm-12" id="addformajax"></div>
<div class="col-sm-12 margin-top-15">
<p><button id="btn-add-form" class="btn btn-danger btn-block" type="button">SUBMIT</button></p>
</div>
</div>
</form>
</body>
</html>

Jquery .on(change) event on <select> input only changes first row.

I have a table whereby people can add rows.
There is a select input in the table that when changed, changes the values in a second select field via ajax.
The problem I have is that if a person adds an additional row to the table, the .on(change) event alters the second field in the first row, not the subsequent row.
I've been racking my brain, trying to figure out if I need to (and if so how to) dynamically change the div id that the event binds to and the div that it affects. Is this the solution? If so, could someone please demonstrate how I'd achieve this?
The HTML form is
<form action="assets.php" method="post">
<button type="button" id="add">Add Row</button>
<button type="button" id="delete">Remove Row</button>
<table id="myassettable">
<tbody>
<tr>
<th>Asset Type</th>
<th>Manufacturer</th>
<th>Serial #</th>
<th>MAC Address</th>
<th>Description</th>
<th>Site</th>
<th>Location</th>
</tr>
<tr class="removable">
<!--<td><input type="text" placeholder="First Name" name="contact[0][contact_first]"></td>
<td><input type="text" placeholder="Surname" name="contact[0][contact_surname]"></td>-->
<td><select name="asset[0][type]">
<option><?php echo $typeoption ?></option>
</select></td>
<td><select class="manuf_name" name="asset[0][manuf]">
<option><?php echo $manufoption ?></option>
</select></td>
<td><input type="text" placeholder="Serial #" name="asset[0][serial_num]"></td>
<td><input type="text" placeholder="Mac Address" name="asset[0][mac_address]"></td>
<td><input type="text" placeholder="Name or Description" name="asset[0][description]"></td>
<td><select id="site" name="asset[0][site]">
<option><?php echo $siteoption ?></option>
</select></td>
<td><input type="text" placeholder="e.g Level 3 Utility Room" name="asset[0][location]"></td>
<td><select id="new_select" name="asset[0][contact]"></select></td>
<!--<td><input type="email" placeholder="Email" name="contact[0][email]"></td>
<td><input type="phone" placeholder="Phone No." name="contact[0][phone]"></td>
<td><input type="text" placeholder="Extension" name="contact[0][extension]"></td>
<td><input type="phone" placeholder="Mobile" name="contact[0][mobile]"></td>-->
</tr>
</tbody>
</table>
<input type="submit" value="Submit">
<input type="hidden" name="submitted" value="TRUE" />
</form>
The script I have is
<script type="text/javascript">
$(document).ready(function() {
$("#add").click(function() {
var newgroup = $('#myassettable tbody>tr:last');
newgroup
.clone(true)
.find("input").val("").end()
.insertAfter('#myassettable tbody>tr:last')
.find(':input')
.each(function(){
this.name = this.name.replace(/\[(\d+)\]/,
function(str,p1) {
return '[' + (parseInt(p1,10)+1)+ ']'
})
})
return false;
});
});
$(document).ready(function() {
$("#delete").click(function() {
var $last = $('#myassettable tbody').find('tr:last')
if ($last.is(':nth-child(2)')) {
alert('This is the only one')
} else {
$last.remove()
}
});
});
$(document).ready(function() {
$("#myassettable").on("change","#site",function(event) {
$.ajax ({
type : 'post',
url : 'assetprocess.php',
data: {
get_option : $(this).val()
},
success: function (response) {
document.getElementById("new_select").innerHTML=response;
}
})
});
});
</script>
and the assetprocess.php page is
<?php
if(isset($_POST['get_option'])) {
//Get the Site Contacts
$site = $_POST['get_option'];
$contact = "SELECT site_id, contact_id, AES_DECRYPT(contact_first,'" .$kresult."'),AES_DECRYPT(contact_surname,'" .$kresult."') FROM contact WHERE site_id = '$site' ORDER BY contact_surname ASC";
$contactq = mysqli_query($dbc,$contact) or trigger_error("Query: $contact\n<br />MySQL Error: " .mysqli_errno($dbc));
if ($contactq){
//$contactoption = '';
echo '<option>Select a Contact (Optional)</option>';
while ($contactrow = mysqli_fetch_assoc($contactq)) {
$contactid = $contactrow['contact_id'];
$contactfirst = $contactrow["AES_DECRYPT(contact_first,'" .$kresult."')"];
$contactsurname = $contactrow["AES_DECRYPT(contact_surname,'" .$kresult."')"];
$contactoption .= '<option value="'.$contactid.'">'.$contactsurname.', '.$contactfirst.'</option>';
echo $contactoption;
}
}
exit;
}
?>
The code is ugly as sin, but this is only a self-interest project at this stage.
Any assistance would be greatly appreciated.
Cheers,
J.
Working Example: https://jsfiddle.net/Twisty/1c98Ladh/3/
A few minor HTML changes:
<form action="assets.php" method="post">
<button type="button" id="add">Add Row</button>
<button type="button" id="delete">Remove Row</button>
<table id="myassettable">
<tbody>
<tr>
<th>Asset Type</th>
<th>Manufacturer</th>
<th>Serial #</th>
<th>MAC Address</th>
<th>Description</th>
<th>Site</th>
<th>Location</th>
</tr>
<tr class="removable">
<td>
<select name="asset[0][type]">
<option>---</option>
<option>Type Option</option>
</select>
</td>
<td>
<select class="manuf_name" name="asset[0][manuf]">
<option>---</option>
<option>
Manuf Option
</option>
</select>
</td>
<td>
<input type="text" placeholder="Serial #" name="asset[0][serial_num]">
</td>
<td>
<input type="text" placeholder="Mac Address" name="asset[0][mac_address]">
</td>
<td>
<input type="text" placeholder="Name or Description" name="asset[0][description]">
</td>
<td>
<select id="site-0" class="chooseSite" name="asset[0][site]">
<option>---</option>
<option>
Site Option
</option>
</select>
</td>
<td>
<input type="text" placeholder="e.g Level 3 Utility Room" name="asset[0][location]">
</td>
<td>
<select id="new-site-0" name="asset[0][contact]">
</select>
</td>
</tr>
</tbody>
</table>
<input type="submit" value="Submit">
<input type="hidden" name="submitted" value="TRUE" />
</form>
This prepares the id to be incrementd as we add on new elements. Making use of the class, we can bind a .change() to each of them.
$(document).ready(function() {
$("#add").click(function() {
var newgroup = $('#myassettable tbody>tr:last');
newgroup
.clone(true)
.find("input").val("").end()
.insertAfter('#myassettable tbody>tr:last')
.find(':input')
.each(function() {
this.name = this.name.replace(/\[(\d+)\]/,
function(str, p1) {
return '[' + (parseInt(p1, 10) + 1) + ']';
});
});
var lastId = parseInt(newgroup.find(".chooseSite").attr("id").substring(5), 10);
newId = lastId + 1;
$("#myassettable tbody>tr:last .chooseSite").attr("id", "site-" + newId);
$("#myassettable tbody>tr:last select[id='new-site-" + lastId + "']").attr("id", "new-site-" + newId);
return false;
});
$("#delete").click(function() {
var $last = $('#myassettable tbody').find('tr:last');
if ($last.is(':nth-child(2)')) {
alert('This is the only one');
} else {
$last.remove();
}
});
$(".chooseSite").change(function(event) {
console.log($(this).attr("id") + " changed to " + $(this).val());
var target = "new-" + $(this).attr('id');
/*$.ajax({
type: 'post',
url: 'assetprocess.php',
data: {
get_option: $(this).val()
},
success: function(response) {
$("#" + target).html(response);
}
});*/
var response = "<option>New</option>";
$("#" + target).html(response);
});
});
Can save some time by setting a counter in global space for the number of Rows, something like var trCount = 1; and use that to set array indexes and IDs. Cloning is fast and easy, but it also means we have to go back and append various attributes. Could also make a function to draw up the HTML for you. Like: https://jsfiddle.net/Twisty/1c98Ladh/10/
function cloneRow(n) {
if (n - 1 < 0) return false;
var html = "";
html += "<tr class='removable' data-row=" + n + ">";
html += "<td><select name='asset[" + n + "][type]' id='type-" + n + "'>";
html += $("#type-" + (n - 1)).html();
html += "<select></td>";
html += "<td><select name='asset[" + n + "][manuf]' id='manuf-" + n + "'>";
html += $("#manuf-" + (n - 1)).html();
html += "<select></td>";
html += "<td><input type='text' placeholder='Serial #' name='asset[" + n + "][serial_num]' id='serial-" + n + "' /></td>";
html += "<td><input type='text' placeholder='MAC Address' name='asset[" + n + "][mac_address]' id='mac-" + n + "' /></td>";
html += "<td><input type='text' placeholder='Name or Desc.' name='asset[" + n + "][description]' id='desc-" + n + "' /></td>";
html += "<td><select name='asset[" + n + "][site]' class='chooseSite' id='site-" + n + "'>";
html += $("#site-" + (n - 1)).html();
html += "<select></td>";
html += "<td><input type='text' placeholder='E.G. Level 3 Utility Room' name='asset[" + n + "][location]' id='loc-" + n + "' /></td>";
html += "<td><select name='asset[" + n + "][contact]' id='contact-" + n + "'><select></td>";
html += "</tr>";
return html;
}
It's more work up front, yet offers a lot more control of each part. And much easier to use later.

Categories

Resources