jQuery post with ajax from variable number of input boxes - javascript

I am trying to pass user input for a variable number of inputs for two different fields back to the controller using jQuery post with ajax. I am having trouble getting more than just the first inputs. For example, if an employee is assigned multiple pieces of equipment, only the first one is passed to the controller.
In the View I am displaying each employee in a table with a button for each to open a modal where their individual equipment can be assigned. In each modal there are two text boxes (vehicles & tools) with the option for the user to add more of each using jQuery.
I am new to JS, and can't figure out how to determine how many inputs there are, and I don't know how to put these into an array to pass to the controller. Any help is very appreciated!
View:
#int count = 0;
#foreach (var item in Model)
{
<tr>
<td>
<button class="btn btn-default" data-toggle="modal" data-target="#modal-#count">
Assign Resources
</button>
<div class="modal fade" id="modal-#count" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
<h4 class="modal-title" id="myModalLabel">#item.Rank #item.FirstName #item.LastName</h4>
</div>
<div class="modal-body">
<input type="hidden" value="#item.assignedRosterID" id="assignedRosterID-#count" />
<div class="table">
<table>
<thead>
<tr>
<th class="text-center">
Vehicles
</th>
<th class="text-center">
Equipment
</th>
</tr>
</thead>
<tbody>
<tr>
<td valign="middle">
<div class=”addV” id=”addV-#count”>
<p>
<input type="text" size="20" class="text-center" value="" id="vehicleNumber-#count" name=”vehicle” placeholder="Vehicle Number" />
</p>
</div>
</td>
<td valign="middle">
<div class="addEquip" id="addEquip-#count">
<p>
<input type="text" id="equipmentLabel-#count" size="20" class="text-center" name="equipment" value="" placeholder="Equipment Label" />
</p>
</div>
</td>
</tr>
<tr>
<td></td>
<td>
Add Additional Vehicle
</td>
<td>
Add Additional Equipment
</td>
</tr>
</tbody>
</table>
<span style="color: red"></span>
</div>
<div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal" id="closeModal-#count">Close</button>
<button type="button" class="btn btn-primary" id="saveModal-#count">Save changes</button>
</div>
</div>
</div>
</div>
</td>
<td style="font-weight:bold">
#Html.DisplayFor(modelItem => item.LastName)
</td>
<td style="font-weight:bold">
#Html.DisplayFor(modelItem => item.FirstName)
</td>
</tr>
count++;
}
JS
for (var i = 0; i < $('#count').val() ; i++) {
(function (i) {
i
$('#saveModal-' + i).click(function () {
var DetailsVM = {
arID: $('#assignedRosterID-' + i).val(),
vehicleNumber: $('#vehicleNumber-' + i).val(),
equipmentLabel: $('#equipmentLabel-' + i).val()
}
$.ajax({
type: 'POST',
url: '/Rosters/SaveResources',
contentType: "application/json; charset=utf-8",
dataType: "json",
data: JSON.stringify(DetailsVM),
traditional: true,
success: function (response) {
alert("Data Inserted Successfully!");
},
error: function (xhr, err) { alert(xhr.responseText) }
});
});
})(i);
};
for (var i = 0; i < $('#count').val() ; i++) {
(function (i) {
$(function () {
var addDiv = $('#addV-' + i);
var j = $('#addV-' + i + 'p').size() + 1;
$(document).on('click', '#addVehicle + i, function () {
$('<p><input type="text" id="vehicle + i + '-' + j + '" size="20" name="vehicle + j + '" value="" placeholder=" Vehicle Number" /> Remove </p>').appendTo(addDiv);
j++;
return false;
});
$(document).on('click', '#remNew', function () {
if (j > 1) {
$(this).parents('p').remove();
j--;
//$("span").text("There are " + j + " equipment input boxes. ");
}
return false;
});
});
})(i);
};
for (var i = 0; i < $('#count').val() ; i++) {
(function (i) {
$(function () {
var addDiv = $('#addEquip-' + i);
var j = $('#addEquip-' + i + 'p').size() + 1;
$(document).on('click', '#addEquipment-' + i, function () {
$('<p><input type="text" id="equipment-' + i + '-' + j + '" size="20" name="equipment_' + j + '" value="" placeholder=" Equipment Label " /> Remove </p>').appendTo(addDiv);
j++;
return false;
});
$(document).on('click', '#remNew', function () {
if (j > 1) {
$(this).parents('p').remove();
j--;
//$("span").text("There are " + j + " equipment input boxes. ");
}
return false;
});
});
})(i);
};
Model:
public class DetailsVM
{
public string arID { get; set; }
public string vehicleNumber { get; set; }
public string equipmentLabel { get; set; }
}
The logic for this is only setup to save one of each type since multiple is not working. When I put a break point on this and inspect VM it only contains the first values.
Controller:
public ActionResult SaveResources(DetailsVM VM)
{
int assignedRosterID = Int32.Parse(VM.arID);
int equipmentID = db.Equipments.Where(x => x.EquipmentLabel == VM.equipmentLabel).Select(x => x.EquipmentID).FirstOrDefault();
int vehicleID = db.Vehicles.Where(x => x.VehicleNumber == VM.vehicleNumber).Select(x => x.VehicleID).FirstOrDefault();
var tempEquipments = new TempEquipment();
tempEquipments.AssignedRosterID = assignedRosterID;
tempEquipments.EquipmentID = equipmentID;
db.TempEquipments.Add(tempEquipments);
var tempVehicles = new TempVehicle();
tempVehicles.AssignedRosterID = assignedRosterID;
tempVehicles.VehicleID = vehicleID;
db.TempVehicles.Add(tempVehicles);
db.SaveChanges();
return Json(1, JsonRequestBehavior.AllowGet);
}

you can set a class on the save-buttons and get the parent tr by
var tr = $(this).closest('tr')
so ... the arID would be like
tr.find('[name="arID"]')
wrap your first for in a function and make it global.
to make it globale, decline it above the for like
function bindClick() {}
then you will not need your for due to your class on the button.
in your bindClick you can go
$('.saveModal').each(function( ){
$(this).unbind('click').on('click, function(e){
e.preventDefault(); // do this if you dont want to do default action for this button .. like to submit a form
var tr = $(this).closest('tr') // get the parent of all inputs to search in this container
[native code] // var DetailsVM = {...
}
});
then change $('#assignedRosterID-' + i).val() to tr.find('.assignedRosterID').val()
Don't forget to add classes to the inputs! or find them by attribute name : tr.find('[name="your-field-name"]').val()
do the same with your other functions and trigger the bindClick in your function, where you add the new fields ;)

Related

How to use (assign & manipulate) Razor variables in Javascript

I am trying to create a simple counter for a dynamic table I am creating. Essentially, every time I add a row to the table I want the counter to increase by 1. I'm trying to avoid adding some arbitrary property to the model if I can avoid it but I am really scratching my head at how to get this to work.
My table starts with 2 rows and is model-bound to a list. The intent here is to allow every new row after that to be given a new index so it can be submitted with the form and create the list as I go (one submit action further down in the view, the addRow() function is called with a button that does not submit the form)
Essentially here's what I have in my view
#model AddUsers
#{
ViewData["Title"] = "Add Users";
var Counter = 2;
}
#section Scripts{
<script>
function addCount() {
var count = #Counter;
console.log('count: ' + count + 'counter: ' + '#Counter');
count = count + 1;
#Counter = count;
console.log('count: ' + count + 'counter: ' + '#Counter');
}
</script>
<script>
function addRow() {
var counter = #Counter;
var table = document.getElementById("AddUsersTable");
var row = table.insertRow(-1);
var cell1 = row.insertCell(0);
cell1.innerHTML = '<input type="text" asp-for="Users[' + counter + '].FirstName"/><br /><span asp-validation-for="Users[' + counter + '].FirstName class="text-danger"></span>';
var cell2 = row.insertCell(1);
cell2.innerHTML = '<input type="text" />';
var cell3 = row.insertCell(2);
cell3.innerHTML = '<input type="text" />';
var cell4 = row.insertCell(3);
cell4.innerHTML = '<input type="text" />';
addCount();
}
</script>
}
When I debug this and view the log and elements in the browser, I see the following.
I am clearly missing something crucial as none of this is working as expected.
What should have been a simple counter is turning out to be a bigger headache than I anticipated. I tried some of the answers and comments from here as well as my own tinkering to no avail.
It seems you want to add the count to number the name.
Change like below:
#model AddUsers
<button onclick="addRow()">Add Row</button>
<table id="AddUsersTable">
<tr>
<th>UserName</th>
<th>1</th>
<th>2</th>
<th>3</th>
</tr>
<tr>
<td>Candy</td>
<td>aaa1</td>
<td>bbb1</td>
<td>ccc1</td>
</tr>
</table>
#section Scripts{
<script>
var counter = 2;//it must define outside the function
function addRow() {
var table = document.getElementById("AddUsersTable");
var row = table.insertRow(-1);
var cell1 = row.insertCell(0);
cell1.innerHTML = '<input type="text" asp-for="Users[' + counter + '].FirstName"/><br /><span asp-validation-for="Users[' + counter + '].FirstName class="text-danger"></span>';
var cell2 = row.insertCell(1);
cell2.innerHTML = '<input type="text" />';
var cell3 = row.insertCell(2);
cell3.innerHTML = '<input type="text" />';
var cell4 = row.insertCell(3);
cell4.innerHTML = '<input type="text" />';
counter++;
}
</script>
}
Result:
UPDATE:
1.Model:
public class AddUsers
{
public int Id { get; set; }
[Required]
public string Name { get; set; }
[Required]
public int Age { get; set; }
}
2.Index.cshtml:
I suggest that you could add _ValidationScriptsPartial,it exists in your template by default and it contains jquery-validate and jquery-validation-unobtrusive.This makes you can validate on client side instead of validating ModelState on server side.
#model IEnumerable<AddUsers>
#{
ViewData["Title"] = "Index";
}
<button onclick="ShowPartial()">Add Row</button>
<table class="table">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.Name)
</th>
<th>
#Html.DisplayNameFor(model => model.Age)
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.Name)
</td>
<td>
#Html.DisplayFor(modelItem => item.Age)
</td>
</tr>
}
</tbody>
</table>
<div id="CreateUserPartial" hidden>
#await Html.PartialAsync("PartialView", new AddUsers())
</div>
#section Scripts
{
#{await Html.RenderPartialAsync("_ValidationScriptsPartial");}
<script>
function ShowPartial() {
$('#CreateUserPartial').removeAttr('hidden');
}
</script>
}
3.Partial View(Located at Views/Shared/PartialView.cshtml):
#model AddUsers
<form asp-action="Create">
<div class="form-group">
<label asp-for="Name" class="control-label"></label>
<input asp-for="Name" class="form-control" />
<span asp-validation-for="Name" class="text-danger"></span>
</div>
<div class="form-group">
<label asp-for="Age" class="control-label"></label>
<input asp-for="Age" class="form-control" />
<span asp-validation-for="Age" class="text-danger"></span>
</div>
<div class="form-group">
<input type="submit" value="Create" class="btn btn-primary" />
</div>
</form>
4.Controller:
public class AddUsersController : Controller
{
private readonly YourContext _context;
public AddUsersController(YourContext context)
{
_context = context;
}
// GET: AddUsers
public async Task<IActionResult> Index()
{
return View(await _context.Users.ToListAsync());
}
[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create([Bind("Id,Name,Age")] AddUsers addUsers)
{
if (ModelState.IsValid)
{
_context.Add(addUsers);
await _context.SaveChangesAsync();
return RedirectToAction(nameof(Index));
}
return View(addUsers);
}
}
Result:

Make a table row editable on click with Javascript

I want to make the row of my list editable after clicking on edit button. I set editablecontent= true for every row I want to change and added focus with onclick event but this works only for the first item. Could you suggest other ways of making the content of every row editable? I started recently to learn javascript so vanilla javascript would be better. Thanks!
Storedcontact = []
// Represent a contact
function convertToEntry(name, surname, phone, email) {
var obj = {
name: name,
surname: surname,
phone: phone,
email: email
};
return obj;
}
// add contacts
var form = document.getElementById("btn-submit");
form.addEventListener("click", function(ev) {
ev.preventDefault();
var name = document.getElementById("name").value;
var surname = document.getElementById("surname").value;
var number = document.getElementById("phone").value;
var mail = document.getElementById("email").value;
var duplicateFlag = false;
var entry = convertToEntry(name, surname, number, mail);
for (var i = 0; i < Storedcontact.length; i++) {
let entry = Storedcontact[i];
// this is duplicate
if (entry.name === name) {
alert("Duplicate") ;
duplicateFlag = true;
} else {
duplicateFlag = false;
}
}
// store and update ui onlz if name is not duplicate
if (duplicateFlag === false) {
Storedcontact.push(entry);
updateUI();
}
});
// showing contacts
function updateUI() {
var tbody = document.getElementById('entry-table');
// clearing the table
tbody.innerHTML = '';
var newHtml = '';
// looping the stored contacts
for (var i = 0; i < Storedcontact.length; i++) {
var entry = Storedcontact[i];
// printing loop results
//console.log(JSON.stringify(entry));
// creating rows with entry
var row = document.createElement("tr");
row.innerHTML = `
<td contenteditable="true" id="editable">${entry.name}</td>
<td contenteditable="true" id="editable">${entry.surname}</td>
<td contenteditable="true" id="editable">${entry.phone}</td>
<td contenteditable="true" id="editable">${entry.email}</td>
<td><button class="btn btn-danger btn-sm delete" onClick="document.getElementById('entry-table').deleteRow(${i});">Delete</button></td>
<td><button class="btn btn-danger btn-sm edit" onClick="editHtmlTableRow();">Edit</button></td>
`;
tbody.appendChild(row);
function clearFields() {
document.getElementById("name").value = "";
document.getElementById("surname").value = "";
document.getElementById("phone").value = "";
document.getElementById("email").value = "";
}
clearFields();
}
}
function checkDuplicate (name) {
for (var i = 0; i < Storedcontact.length; i++) {
var entry = Storedcontact[i];
if (entry.name === name) {
alert("Duplicate")
} else {
}
}
}
function editHtmlTableRow (){
document.getElementById("editable").focus();
};
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width-device-width, initial-scale=1.0">
<link rel="stylesheet" href="bootstrap.min (3).css">
<title>MyAddressBook</title>
</head>
<body>
<div class="container mt-4">
<h1 class="display-4 text-center">
My<span class="text-primary">Address</span>Book</h1>
<form id="address-form">
<div class="form-group"></div>
<label for="Name">Name</label>
<input type="text" id="name" class="form-control">
<div class="form-group"></div>
<label for="Surname">Surname</label>
<input type="text" id="surname" class="form-control">
<div class="form-group"></div>
<label for="Number">Number</label>
<input type="text" id="phone" class="form-control">
<div class="form-group"></div>
<label for="mail">E-mail</label>
<input type="text" id="email" class="form-control">
</div>
<br>
</br>
<input type="submit" value="Add contact" id="btn-submit" class="btn btn-primary btn-block container mt-4">
</form>
<table class="table table-striped">
<thread>
<tr>
<th>Name</th>
<th>Surname</th>
<th>Number</th>
<th>E-mail</th>
<th></th>
</tr>
</thread>
<tbody id="entry-table"></tbody>
</table>
</div>
<script src="app.js"></script>
</body>
</html>
Assign a unique identifier such as your for loop counter to the Rows
for (var i = 0; i < Storedcontact.length; i++) {
var entry = Storedcontact[i];
// printing loop results
//console.log(JSON.stringify(entry));
// creating rows with entry
var row = document.createElement("tr");
row.innerHTML = `
<td contenteditable="true" id="editable"+i>${entry.name}</td>
<td contenteditable="true" id="editable"+i>${entry.surname}</td>
<td contenteditable="true" id="editable"+i>${entry.phone}</td>
<td contenteditable="true" id="editable"+i>${entry.email}</td>
<td><button class="btn btn-danger btn-sm delete" onClick="document.getElementById('entry-table').deleteRow(${i});">Delete</button></td>
<td><button class="btn btn-danger btn-sm edit" onClick="editHtmlTableRow(${i});">Edit</button></td>
`;
tbody.appendChild(row);
}
and in your function
function editHtmlTableRow (i){
document.getElementById("editable"+i).focus();
}

How to find the closest table row using jQuery?

I have problem getting the value of the replace new table row, I will let you show the codes for the replacing new table row.
The is the Table B, Where this code use for replacing new table row to the Table A
$('#edit_chainingBuild').on('click','tr.clickable-row',function(e){
$('table#edit_chainingBuild tr').removeClass('selected');
$(this).addClass('selected');
var find_each_id_will_update = $(this).find('.data-attribute-chain-id').attr('data-attribute-chain-id');
$('.id_to_update_chain').val(find_each_id_will_update);
var find_each_id_condiments = $(this).find('.data-attribute-chain-id').attr('data-attribute-condiments-section-id');
$.ajax({
url:'/get_each_id_section_condiments',
type:'get',
data:{find_each_id_condiments:find_each_id_condiments},
success:function(response){
var get_each_section = response[0].condiments_table;
$.each(get_each_section, function (index, el) {
var stringify = jQuery.parseJSON(JSON.stringify(el));
var cat_condi_screen_name = stringify['cat_condi_screen_name'];
var cat_condi_price = stringify['cat_condi_price'];
var cat_condi_image = stringify['cat_condi_image'];
var condiment_section_name = stringify['condiment_section_name'];
var image = '<img src=/storage/' + cat_condi_image + ' class="responsive-img" style="width:100px;">';
// $('#edit_chainingBuild').append("<tr class='clickable-row'><td>" + Qty + "</td><td class='clickable-row-condiments'>" + Condiments + "</td><td>" + Price + "</td><td style='display:none;' data-attribute-chain-id="+menu_builder_details_id +" class='data-attribute-chain-id'>"+menu_builder_details_id+"</td></tr>");
$('table#edit_table_chaining_condiments').append("<tr class='edit_condimentsClicked' style='font-size:14px; border:none;'><td>"+condiment_section_name +"</td><td class='edit_condimentsScreenNameClicked'>" + cat_condi_screen_name + "</td><td class='edit_condimentsScreenPriced'>" + cat_condi_price + "</td><td>"+image+"</td></tr>");
});
$("table#edit_table_chaining_condiments tr").click(function(e){
var tableBhtml = $(this).closest('tr').html();
var condiments_name = $(this).closest("tr").find(".edit_condimentsScreenNameClicked").text();
var condimentsScreenPriced = $(this).closest("tr").find(".edit_condimentsScreenPriced").text();
// var input = '<input type="number" id="qty" name="qty" class="form-control changeQuantity" value="1" min="1">';
var id_to_edit_build = $('.id_to_update_chain').val();
$("#edit_chainingBuild tr.selected").html('');
var id_to_edit_builders = $('.id_to_update_chain').val();
$("#edit_chainingBuild tr.selected").replaceWith("<tr data-attribute-chain-id=" + id_to_edit_build + " class='clickable-row'><td class='new_condiments_name'>"+condiments_name+"</td><td>"+condimentsScreenPriced+"</td><td style='display:none;' data-attribute-chain-id="+id_to_edit_builders +" class='data-attribute-chain-id'>"+id_to_edit_builders+"</td></tr>");
$('#EditcondimentsBuilderModal').modal('hide');
});
},
error:function(response){
console.log(response);
}
});
$('#EditcondimentsBuilderModal').modal('show');
});
Looking forward if the table row already replace, I want to get the value of the class of new_condiments_name. So I create a variable to find the class of new_condiments_name. It look like this.
var new_condiments_name = $(this).closest("tr").find(".new_condiments_name").text();
So now when I try alert the variable new_condiments_name using the click function it shows null only.
$('.edit_build_success_insert').click(function(){
var new_condiments_name = $(this).closest("tr").find(".new_condiments_name").text();
alert(new_condiments_name);
});
My Html Table:
<div class="modal-body">
<div class="container">
<div class="header" style="text-align: center;">
<br>
<h3 style="color:#007BFF;">Build Your Chain Button</h3>
<label>This button will be served as customers menu.</label><br>
<i class="fab fa-creative-commons-remix" style="font-size:70px;"></i>
<br><br>
<input type="hidden" value="" class="edit_hidden_noun_id" name="">
<table class="table table-hover" id="edit_chainingBuild">
<thead>
<tr style="font-size: 15px;">
<!-- <th scope="col">Qty</th> -->
<th scope="col">Condiments</th>
<th scope="col">Price</th>
</tr>
</thead>
<tbody style="font-size:14px;">
</tbody>
</table>
</div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="edit_build_success_insert btn btn-primary">Build Done</button>
</div>
I have here the image to proof that the value that i get always null.
$('table .edit_build_success_insert').click(function(){
var new_condiments_name = $(this).closest("tr").find(".new_condiments_name").text();
alert(new_condiments_name);
});

Unable to read table td valued from HTML through jQuery selector

For creating table I am using ng-repeat to render table row. onchange of dropdown I am calling a function which will run have some conditions on basis of that condition I am pushing an object to an array which bind to a scope variable.
My HTML
<div class="col-md-12" >
<div class="portlet light" >
<div class="portlet-title">
<div class="caption">Installment Structure </div>
</div>
<div class="portlet-body">
<div class="row">
<div class="col-md-12">
<table id="instalmentStructure" class="table table-bordered">
<tbody>
<tr>
<th style="width:20%;">From Installment
</th>
<th style="width:20%;">To Installment</th>
<th style="width:20%;">Installment Amount
</th>
<th style="width:20%;"></th>
</tr>
<tr class="quoteVal" ng-repeat="item in installmentLists">
<td >{{item.fromInst}}</td>
<td >{{item.toInst}}</td>
<td contenteditable="true" class="quoteVal">{{item.amtInst}}</td>
<td>
<span class="col-md-6">
<center>
<a ng-click="editRecord(item,$index)">
<i class="fa fa-pencil"></i>
</a>
</center>
</span>
<span class="col-md-6">
<center>
<a ng-click="deleteRecord(item,$index)">
<i class="fa fa-trash"></i>
</a>
</center>
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
My Controller Code:
$scope.createInstallments = function () {
console.log("will create installments");
if (trialCalculCntrl.emiCalQde.bulletFreq == 12) {
console.log("Bullet Frequency is Yearly");
var bulletFreq = trialCalculCntrl.emiCalQde.bulletFreq;
$scope.installmentLists = [];
$scope.installmentObj = {
'fromInst': "",
'toInst': "",
'amtInst': ""
};
var remainder = tenure % 12;
if (remainder == 0) {
var numofrows = ((tenure * 2) / 12).toFixed(0);
for (var i = 1; i <= numofrows; i++) {
if (i == 1) {
$scope.installmentObj = {
'fromInst': i,
'toInst': bulletFreq - 1,
'amtInst': ""
};
$scope.installmentLists.push($scope.installmentObj);
} else if (i % 2 == 0) {
console.log("EVEN i: ", i);
var preval = $('tr.quoteVal').eq(i - 2).find('td:eq(1)').text();
console.log("Previous Val ", preval);
} else {
console.log("ODD i: ", i);
// var preval = $('tr.quoteVal').eq(i-1).find('td:eq(2)').text();
// console.log("Previous Val ",preval);
}
}
console.log("Instalment list : ", $scope.installmentLists);
} else {
var numofrows = (((tenure * 2) / 12) + 1).toFixed(0);
for (var i = 0; i < numofrows; i++) {
$scope.installmentObj = {
'fromInst': "",
'toInst': "",
'amtInst': ""
};
$scope.installmentLists.push($scope.installmentObj);
}
console.log("Instalment list : ", $scope.installmentLists);
}
}
};
Inside for loop after first run I am pushing the object to $scope.installmentLists array but it is not showing in to HTML so I am not able to read the array object in second run of for loop. I am using jQuery selectors to read, so console.log("Previous Val ", preval); gives me an empty string.
Place your jquery about console.log in setTimeout when changed $scope. Otherwise the jquery selector does not return expected because the HTML has not been rendered.
setTimeout(function() {
onsole.log("EVEN i: ", i);
var preval = $('tr.quoteVal').eq(i - 2).find('td:eq(1)').text();
console.log("Previous Val ", preval);
}, 500);

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>

Categories

Resources