I have a main view which has a "Comments" link on each row that when clicked it opens up a partial view. The partial view displays a table and textboxes, and an "Add" button that when clicked it adds the data entered in the textboxes to the table.
The first time I click on comments, I add data to the textboxes and hit the Add button and everything works.
The problem is: when I open the partial view from another record(by clicking on Comments) and add data to the textboxes, after I click on add it adds an extra blank row. It is as if the add button is clicked twice. Could you please help me solve this issue? The code I am using is below. I also attached pics.
Thank you very much.
PARTIAL VIEW:
#model IEnumerable<HelpDeskSupport.Models.Comment>
<html>
<body>
<table class="table table-striped table-bordered" cellpadding="0" cellspacing="0" border="0" width="1500" id="tblComments">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.TicketNumber)
</th>
<th>
#Html.DisplayNameFor(model => model.Comment1)
</th>
<th>
#Html.DisplayNameFor(model => model.AssignedTo)
</th>
<th>
#Html.DisplayNameFor(model => model.CreatedBy)
</th>
<th>
#Html.DisplayNameFor(model => model.Date)
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.TicketNumber)
</td>
<td>
#Html.DisplayFor(modelItem => item.Comment1)
</td>
<td>
#Html.DisplayFor(modelItem => item.AssignedTo)
</td>
<td>
#Html.DisplayFor(modelItem => item.CreatedBy)
</td>
<td>
#Html.DisplayFor(modelItem => item.Date)
</td>
</tr>
}
</tbody>
<tfoot>
<tr>
<td><input type="text" id="txtTicketNumber" value=#ViewData["NumberFromViewAll"] readonly /></td>
<td><input type="text" id="txtComment" /></td>
<td><input type="text" id="txtAssignedTo" /></td>
<td><input type="text" id="txtCreatedBy" /></td>
<td><input type="text" id="txtDate" /></td>
<td><input type="button" id="btnAddComment" value="Add" /></td>
</tr>
</tfoot>
</table>
<br />
<input type="button" id="btnSave" value="Save All" />
#*<script type="text/javascript" src="http://ajax.cdnjs.com/ajax/libs/json2/20110223/json2.js"></script>*#
<script src="~/Scripts/json2.js"></script>
<script type="text/javascript">
$("body").on("click", "#btnAddComment", function () {
//Reference the TextBoxes
var txtTicketNumber = $("#txtTicketNumber");
var txtComment = $("#txtComment");
var txtAssignedTo = $("#txtAssignedTo");
var txtCreatedBy = $("#txtCreatedBy");
var txtDate = $("#txtDate");
//Get the reference of the Table's TBODY element
var tableBody = $("#tblComments > TBODY")[0];
//Add Row
var row = tableBody.insertRow(-1);
//Add TicketNumber cell
var cell = $(row.insertCell(-1));
cell.html(txtTicketNumber.val());
//Add Comment cell
cell = $(row.insertCell(-1));
cell.html(txtComment.val());
//Add AssignedTo cell
cell = $(row.insertCell(-1));
cell.html(txtAssignedTo.val());
//Add CreatedBy cell
cell = $(row.insertCell(-1));
cell.html(txtCreatedBy.val());
//Add Date cell
cell = $(row.insertCell(-1));
cell.html(txtDate.val());
//Clear the TextBoxes
txtComment.val("");
txtAssignedTo.val("");
txtCreatedBy.val("");
txtDate.val("");
});
$("body").on("click", "#btnSave", function () {
//Loop through the Table rows and build a JSON array
var commentsArray = new Array();
$("#tblComments TBODY TR").each(function () {
var row = $(this);
var commentLine = {};
commentLine.TicketNumber = row.find("TD").eq(0).html();
commentLine.Comment1 = row.find("TD").eq(1).html();
commentLine.AssignedTo = row.find("TD").eq(2).html();
commentLine.CreatedBy = row.find("TD").eq(3).html();
commentLine.Date = row.find("TD").eq(4).html();
commentsArray.push(commentLine);
});
//Send the JSON array to Controller using AJAX
$.ajax({
type: "POST",
url: "/Tickets/InsertComments",
data: JSON.stringify(commentsArray),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function () {
alert("Comment(s) inserted.");
}
});
});
</script>
CONTROLLER:
//VIEW ALL COMMENTS AND DISPLAY IN PARTIAL
[HttpPost]
public ActionResult ViewComments(int ticketNum)
{
List<Comment> AllComments = new List<Comment>();
using (DBModel db = new DBModel())
AllComments = db.Comments.Where(x => x.TicketNumber == ticketNum).ToList();
//get iNumber from ViewAll to display in the ticket number textbox of the comments partial view
ViewData["NumberFromViewAll"] = ticketNum;
return PartialView("ViewComments", AllComments);
}
public JsonResult InsertComments(List<Comment> commentsArray)
{
using (DBModel db = new DBModel())
{
if (commentsArray != null)
{
var lastColumnComments = commentsArray.Last();
var ticketNumberToDelete = lastColumnComments.TicketNumber;
var sqlQuery = "Delete [Comments] where TicketNumber = " + ticketNumberToDelete;
//Delete all comments from comments table. Previous comments are copied in javascript and re-populated
db.Database.ExecuteSqlCommand(sqlQuery);
}
//Check for NULL
//if (commentsArray == null)
//{
// commentsArray = new List<Comment>();
//}
foreach (Comment c in commentsArray)
{
db.Comments.Add(c);
}
int insertedRecords = db.SaveChanges();
return Json(insertedRecords);
}
}
IN CASE YOU WANT TO SEE HOW THE VIEWCOMMENTS IS DISPLAYED FROM THE MAIN VIEW:
#section modalComments
{
<script type="text/javascript">
function showComments() {
$("#dialog").dialog({
autoOpen: false,
modal: true,
title: "View Details"
});
$("#ticketTable .details").click(function () {
var ticketNum = $(this).closest("tr").find("td").eq(0).html();
$.ajax({
type: "POST",
url: "/Tickets/ViewComments",
data: '{ticketNum: "' + ticketNum + '" }',
contentType: "application/json; charset=utf-8",
dataType: "html",
success: function (response) {
$('#dialog').html(response);
$('#dialog').dialog('open');
},
failure: function (response) {
alert(response.responseText);
},
error: function (response) {
alert(response.responseText);
}
});
});
};
$(function () {
showComments();
});
Related
This is my table, and I want to add a column to the right where a user will be able to enter a value and save. (It needs to save the value to a sql table)
Code in my View:
<tbody>
#foreach (var items in Model.tbl_Stuff)
{
<tr>
<td>#items.ID</td>
<td>#items.Description</td>
<td><input type="text" id="txtAmount" /></td>
</tr>
}
</tbody>
This is the Javascript: In the function is where I should be able to update each row, how do I loop though a table row, and update the inserted value on the new column to the sql table via the controller action?
EDIT: this is my edited script according to the suggestion below, it sends the value to controller.
<script type="text/javascript">
$("body").on("click", "#btnSave", function () {
var stuffarray= new Array();
var txtEmployeeBidAmount = $("#txtEmployeeBidAmount");
$("#tblStuff TBODY TR").each(function () {
var row = $(this);
var stuf= {};
stuf.Amount = row.find("TD").eq(4).html();
stuffarray.push(stuf);
});
//Send the JSON array to Controller using AJAX.
$.ajax({
type: "POST",
url: "#Url.Action("UpdateStuff","Home")",
data: JSON.stringify(stuffarray),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (r) {
alert(r + " record(s) saved.");
}
});
});
As you have a table, you require to loop the table using the following sample to get text box value from each row:
HTML:
<table>
<tbody>
<tr>
<td>63</td>
<td>Computer</td>
<td>3434</td>
<td><input type='text' class='val' value='100' /></td>
</tr>
<tr>
<td>64</td>
<td>Stationary</td>
<td>111</td>
<td><input type='text' class='val' value='200' /></td>
</tr>
<tr>
<td>64</td>
<td>Stationary</td>
<td>11</td>
<td><input type='text' class='val' value='400' /></td>
</tr>
</tbody>
</table>
jQuery:
var table = $("table tbody");
table.find('tr').each(function (i) {
var $tds = $(this).find('td'),
Id = $tds.eq(0).text(),
Product = $tds.eq(1).text(),
Quantity = $tds.eq(2).text();
Val = $tds.find('.val').val();
alert('Row ' + (i + 1) + ':\nId: ' + Id
+ '\nProduct: ' + Product
+ '\nQuantity: ' + Quantity
+ '\nVal: ' + Val);
});
Finally add them to an JavaScript array object to update in the controller.
Here's a sample in JSFiddle
I have a main form displaying data. Then I have a "Comments" link on each row and on the click of it a partial view with a table opens up. The partial view is to view/add comments and other data. In this partial view, after the table, there are textboxes I can fill with data. After adding data I click on "Add" and when I am done I would click on "Save" and whatever I typed in the textboxes is entered in the database. This all works and gives you an idea of what I am working with(see attached pics as well).
What I am looking for now is a way to fill the Ticket Number textbox(on the partial view) with the number from the Number field(on main form). Also, this number should not be edited on the partial. How can I achieve that?
I have been unable to find a solution. Please help. Thank you.
THIS IS THE CODE IN THE CONTROLLER:
//VIEW ALL COMMENTS AND DISPLAY IN PARTIAL
[HttpPost]
public ActionResult ViewComments(int ticketNum)
{
List<Comment> AllComments = new List<Comment>();
using (DBModel db = new DBModel())
AllComments = db.Comments.Where(x => x.TicketNumber == ticketNum).ToList();
return PartialView("ViewComments", AllComments);
}
//INSERT COMMENT
public JsonResult InsertComments(List<Comment> commentsArray)
{
using (DBModel db = new DBModel())
{
//Truncate Table to delete all comments. Previous comments are copied in javascript and re-populated
db.Database.ExecuteSqlCommand("TRUNCATE TABLE [Comments]");
//Check for NULL
if (commentsArray == null)
{
commentsArray = new List<Comment>();
}
foreach (Comment comment in commentsArray)
{
db.Comments.Add(comment);
}
int insertedRecords = db.SaveChanges();
return Json(insertedRecords);
}
}
THIS IS HOW THE PARTIAL VIEW IS DISPLAYED FROM THE MAIN VIEW:
#section modalComments
{
<script type="text/javascript">
function showComments() {
$("#dialog").dialog({
autoOpen: false,
modal: true,
title: "View Details"
});
$("#ticketTable .details").click(function () {
var ticketNum = $(this).closest("tr").find("td").eq(0).html();
$.ajax({
type: "POST",
url: "/Tickets/ViewComments",
data: '{ticketNum: "' + ticketNum + '" }',
contentType: "application/json; charset=utf-8",
dataType: "html",
success: function (response) {
$('#dialog').html(response);
$('#dialog').dialog('open');
},
failure: function (response) {
alert(response.responseText);
},
error: function (response) {
alert(response.responseText);
}
});
});
};
$(function () {
showComments();
});
</script>
}
THIS IS THE PARTIAL VIEW:
#model IEnumerable<HelpDeskSupport.Models.Comment>
<html>
<body>
<table class="table table-striped table-bordered" cellpadding="0" cellspacing="0" border="0" width="1500" id="tblComments">
<thead>
<tr>
<th>
#Html.DisplayNameFor(model => model.TicketNumber)
</th>
<th>
#Html.DisplayNameFor(model => model.Comment1)
</th>
<th>
#Html.DisplayNameFor(model => model.AssignedTo)
</th>
<th>
#Html.DisplayNameFor(model => model.CreatedBy)
</th>
<th>
#Html.DisplayNameFor(model => model.Date)
</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.TicketNumber)
</td>
<td>
#Html.DisplayFor(modelItem => item.Comment1)
</td>
<td>
#Html.DisplayFor(modelItem => item.AssignedTo)
</td>
<td>
#Html.DisplayFor(modelItem => item.CreatedBy)
</td>
<td>
#Html.DisplayFor(modelItem => item.Date)
</td>
</tr>
}
</tbody>
<tfoot>
<tr>
<td><input type="text" id="txtTicketNumber" value=""/></td>
<td><input type="text" id="txtComment" /></td>
<td><input type="text" id="txtAssignedTo" /></td>
<td><input type="text" id="txtCreatedBy" /></td>
<td><input type="text" id="txtDate" /></td>
<td><input type="button" id="btnAddComment" value="Add" /></td>
</tr>
</tfoot>
</table>
<br />
<input type="button" id="btnSave" value="Save All" />
<script src="~/Scripts/json2.js"></script>
<script type="text/javascript">
$("body").on("click", "#btnAddComment", function () {
//Reference the TextBoxes
var txtTicketNumber = $("#txtTicketNumber");
var txtComment = $("#txtComment");
var txtAssignedTo = $("#txtAssignedTo");
var txtCreatedBy = $("#txtCreatedBy");
var txtDate = $("#txtDate");
//Get the reference of the Table's TBODY element
var tBody = $("#tblComments > TBODY")[0];
//Add Row
var row = tBody.insertRow(-1);
//Add TicketNumber cell
var cell = $(row.insertCell(-1));
cell.html(txtTicketNumber.val());
//Add Comment cell
cell = $(row.insertCell(-1));
cell.html(txtComment.val());
//Add AssignedTo cell
cell = $(row.insertCell(-1));
cell.html(txtAssignedTo.val());
//Add CreatedBy cell
cell = $(row.insertCell(-1));
cell.html(txtCreatedBy.val());
//Add Date cell
cell = $(row.insertCell(-1));
cell.html(txtDate.val());
//Clear the TextBoxes
txtTicketNumber.val("");
txtComment.val("");
txtAssignedTo.val("");
txtCreatedBy.val("");
txtDate.val("");
});
$("body").on("click", "#btnSave", function () {
//Loop through the Table rows and build a JSON array
var commentsArray = new Array();
$("#tblComments TBODY TR").each(function () {
var row = $(this);
var commentLine = {};
commentLine.TicketNumber = row.find("TD").eq(0).html();
commentLine.Comment1 = row.find("TD").eq(1).html();
commentLine.AssignedTo = row.find("TD").eq(2).html();
commentLine.CreatedBy = row.find("TD").eq(3).html();
commentLine.Date = row.find("TD").eq(4).html();
commentsArray.push(commentLine);
});
//Send the JSON array to Controller using AJAX
$.ajax({
type: "POST",
url: "/Tickets/InsertComments",
data: JSON.stringify(commentsArray),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function () {
alert("Comment(s) inserted.");
}
});
});
</script>
This was solved by using the following line of code:
<td><input type="text" id="txtTicketNumber" value=#ViewData["NumberFromViewAll"] readonly /></td>
I have an annoying, somewhat odd bug. I have a grid in knockout that has several columns, of which one is editable. This column generates a textbox input for each row.
When the user edits one row and then tabs onto the next one, the focus will jump back to the row that was just edited. This will only happen once, so if you tab again, you can tab on to the next boxes.
If you do not edit a textbox, the jump back behaviour will not occur. I am having a hard time seeing what exactly is causing this behaviour.
Code for the knockout grid in the view:
<table class="table table-responsive table-striped center table-hover" style="clear: both; margin-bottom: 10px;" id="resultsTable">
<thead>
<tr>
<th class="col-md-2"><b>Culture</b></th>
<th class="col-md-2"><b>Section</b></th>
<th class="col-md-2"><b>Name</b></th>
<th class="col-md-2"><b>Value</b></th>
<th class="col-md-2"><b>LastChangeOn</b></th>
<th class="col-md-2"></th>
</tr>
</thead>
<tbody data-bind='foreach: Items'>
<tr>
<td class="col-md-2">
<span data-bind="text: Culture"></span>
</td>
<td class="col-md-2">
<span data-bind="text: Section"></span>
</td>
<td class="col-md-2">
<span data-bind="text: Name"></span>
</td>
<td class="col-md-2">
<input type="text" data-bind="value: Value" />
</td>
<td class="col-md-2">
<span data-bind="text: LastChangeOn"></span>
</td>
<td class="col-md-2">
<span data-bind="text: Id, visible: false"></span>
</td>
</tr>
</tbody>
</table>
Code for the javascript:
<script type="text/javascript">
var _VM;
var initialLoad = true;
$(function () {
LoadKnockoutContent(true);
});
$("#SearchButton").on("click", function (e) {
_VM.moveToFirstPage();
});
IndexModel = function (initialData) {
var _self = this;
PagedViewModel.call(_self);
_self.Items = ko.observableArray();
_self.CurrentPage.subscribe(function (value) {
$("#SearchCriteria_HiddenPage").val(value);
LoadKnockoutContent(false, _self.Release);
});
_self.loadModelData = function (data) {
_self.CurrentPage(data.CurrentPage);
_self.PageSize = data.PageSize;
_self.MaxPageIndex(data.PageCount);
_self.Items(ToResourcesArray(data.Resources, _self));
}
_self.loadModelData(initialData);
};
ResourceModel = function (item, parent) {
var _self = this;
_self.Parent = parent;
_self.Id = item.Id;
_self.Culture = ko.observable(item.Culture);
_self.Section = ko.observable(item.Section);
_self.Name = ko.observable(item.Name);
_self.Value = ko.observable(item.Value);
_self.Value.subscribe(function (newValue) {
// Send the new value to the backend
SaveResource(newValue, item.Id);
});
if (!item.LastChangeOn == "") {
_self.LastChangeOn = ko.observable(parseJsonDate(item.LastChangeOn).toPaddedDateTimeString());
}
else {
_self.LastChangeOn = ko.observable(item.LastChangeOn);
}
}
function ToResourcesArray(data, parent) {
var items = ko.utils.arrayMap(data, function (item) {
return new ResourceModel(item, parent);
});
return items;
}
function LoadKnockoutContent(initialLoad, callback, callback2) {
// Call to the back end, passing along the search criteria
}
function SaveResource(newValue, Id) {
$.ajax({
url: '#Url.Action("UpdateResource", "Resource")',
data: JSON.stringify({ id: Id, newValue: newValue }),
type: 'POST',
cache: false,
contentType: 'application/json;',
dataType: 'json',
success: function (data) {
if (data.isSuccess) {
// Success, we need to reload here as well else the last changed on field is not updated in the grid overview
LoadKnockoutContent(false);
} else {
alertify.error(data.message);
// Refresh the view else the value field will stay empty while it is not saved.
// A reload will show the grid again with the previous value.
LoadKnockoutContent(false);
}
},
error: function (request, status, error) {
alert(request.responseText);
}
});
}
</script>
dd
I have solved the issue.
The issue was that the Grid was reloaded after ever call to the save function. This should only occur when the save failed. If the grid is reloaded after every save, then when you tab, you will start at the first row of the Grid again.
I'm fairly new to coding. I have a jQuery datatable, and when I select a row, the tds of that row fill out html textboxes above the table. I'm trying to make it so whatever is entered into those textboxes (and upon pressing the save button), is then saved into the row.
Currently I have it so it saves 1 field/td. If I press on column 0, fill out the Name textbox and press save, it saves. But it works on any column. It should only be editing the correct td. Plus I want to edit the entire row, not just one td. I'm not sure how to accomplish this. Thanks for any help!
JSFiddle
Javascript:
var table = $('#example').DataTable();
(function () {
var table = document.querySelector('#example');
var name = document.querySelector('#nameinput');
var format = document.querySelector('#formatinput');
var address = document.querySelector('#addressinput');
var report = document.querySelector('#reportinput');
var alarm = document.querySelector('#alarminput');
table.addEventListener('click', onTableClick);
function onTableClick (e) {
var tr = e.target.parentElement;
var data = [];
for (var td of tr.children) {
data.push(td.innerHTML);
}
name.value = data[0];
address.value = data[1];
format.value = data[2];
report.value = data[3];
alarm.value = data[4];
console.log(alarm.value);
}
$("#saverow").click(function() {
var table1 = $('#data-table').DataTable();
var data = [];
data[0] = name.value;
data[4] = alarm.value;
console.log(name.value);
console.log(alarm.value);
table1.draw(true);
});
})();`
I've updated my code with what I've tried so far. Currently, what I type in the textboxes, correctly is displayed in the console (upon hitting the saverow button), now I cant figure out how to save that into the table.
i think it is mor responsive to edit data right in the table.
HTML:
<table id="example" class="display" cellspacing="0" width="100%">
<thead>
<tr>
<th>Name</th>
<th>Address</th>
<th>Format</th>
<th>Report Time</th>
<th>Alarms</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>Tiger Nixon</td>
<td>Tiger#gmail.com</td>
<td>email</td>
<td>1PM</td>
<td>Master</td>
<td class="td-button"></td>
</tr>
<tr>
<td>Bill Gates</td>
<td>111-111-1111</td>
<td>sms</td>
<td></td>
<td>Master</td>
<td class="td-button"></td>
</tr>
</tbody>
</table>
JS:
var table = $('#example').DataTable();
$("#example tbody tr").click(function(){
if (! $(this).find("button").length)
{
$(this).find("td").each(function(){
if (!$(this).hasClass("td-button"))
{
var text = $(this).text();
$(this).html ('<input type="text" value="' + text + '">')
} else
$(this).html ('<button class="button-save">Save</button>')
})
}
})
$(document).on("click", ".button-save",function(){
var tr = $(this).parent().parent();
tr.find("td").each(function(){
if (!$(this).hasClass("td-button"))
{
var text = $(this).find("input").val();
$(this).text(text)
} else
$(this).html('');
})
})
https://jsfiddle.net/91wvw619/
I have dynamic input fields generated from a jquery function. There is the ability to add or delete through button clicks these input fields. The fields are populated with data from mysql table. Each populated input has a unique ID fetched from the DB. When adding a new field I am getting the next AUTO_INCREMENT from an ajax request. I am then able to increment +1 but for all fields. I only want to do this for the new fields. If by some reason an insert query transaction is made from another app it will update start increment from field and then update the rest with the correct values (check to see what I mean jsFiddle(http://jsfiddle.net/f9XP8/2/).
The problems is how to put it all together. I just want to follow to able to add a new field and assign it the appropriate next person_id for db insert. LIVE EXAMPLE
<script>
$(document).ready(function () {
var $increment_num = $('#increment_num');
var interval = 100; //3000 = 3 seconds
function doAjax() {
$.ajax({
type: 'POST',
url: 'personAutoIncrement.php',
data: $(this).serialize(),
dataType: 'json',
success: function (data) {
var $cloned = $('#input_table tr');
var num = parseInt(data);
$increment_num.val(num);
$cloned.each(function(i){
$(this).find('[name^="increment_id"]').first().val(num+i);
})
},
complete: function (data) {
// Schedule the next
setTimeout(doAjax, interval);
}
});
}
setTimeout(doAjax, interval);
var click_count = 0;
$('#btnAdd').click(function () {
click_count++;
var $clones = $('#input_table tr'),
num = $clones.size() + 1,
next_num = parseInt($clones.last().find('input[name^="increment_id"]').val()) + 1,
$template = $clones.first(),
newSection = $template.clone().attr('id', 'pq_entry_'+num),
ident = 'increment_id_'+num;
person_id = 'person_id_'+num;
person_fname = 'person_fname_'+num;
person_lname = 'person_lname_'+num;
// clear out all sections of new input
newSection.find('input').not('[name^="increment_id"]').val('');
newSection.find('input[name^="increment_id"]').attr({
'id': ident,
'name': ident
}).val(/*next_num*/);
newSection.find('input[name^="person_id"]').attr({
'id': person_id,
'name': person_id
}).val(/*next_num*/);
newSection.find('input[name^="person_fname"]').attr({
'id': person_fname,
'name': person_fname
}).val(/*next_num*/);
$('#input_table').append(newSection);
$('#btnDel').prop('disabled', '');
if (num == 100) $('#btnAdd').prop('disabled', 'disabled');
});
$('#btnDel').click(function () {
var num = $('.clonedSection').length; // how many duplicate input fields we currently have
$('#pq_entry_' + num).remove(); // remove the last element
// enable the "add" button
$('#btnAdd').prop('disabled', '');
// if only one element remains, disable the "remove" button
if (num - 1 == 1) $('#btnDel').prop('disabled', 'disabled');
});
$('#btnDel').prop('disabled', 'disabled');
});
</script>
html
<table>
<thead>
<tr>
<th>ID from DB</th>
<th>First Name</th>
</tr>
</thead>
<tbody id="input_table">
<tr id="pq_entry_1">
<td><input type="text" id="increment_id_1" name="increment_id_1" readonly value="5" /></td>
<td><input type="text" name="first_name" placeholder="First Name" /></td>
</tr>
</tbody>
</table>
<input type='button' id='btnAdd' value='add text box' />
<input type='button' id='btnDel' value='Delete' /></br>
</table>
If I'm not mistaken, you are wanting to know how to increment certain rows, but allow others to be "frozen" (because they are saved to the database). I have changed your code a bit more, here are the important notes:
I removed the dynamic name attributes. You don't need to dynamically generate field names, you can just assign data-* attributes to hold the id or refer to tr.find('input[name="person_id"]')
Added a data-saved attribute to the tr to know whether or not it should be included in the updated auto increment id or if it should just stay as it is
Added a save button next to each row, which as it is just sets the data-saved attribute on the row, you can add an AJAX call to save the record if you want
Updated Fiddle
The Javascript:
$(document).ready(function () {
var $increment_num = $('#increment_num');
var interval = 5000; //3000 = 3 seconds
function doAjax() {
$.ajax({
type: 'POST',
url: 'personAutoIncrement.php',
data: $(this).serialize(),
dataType: 'json',
success: function (data) {
var $cloned = $('#input_table tr').not('[data-saved]');
var num = parseInt(data);
$increment_num.val(num);
$cloned.each(function(i){
var $this = $(this);
$this.find('[name^="person_id"]').first().val(num+i);
})
},
complete: function (data) {
// Schedule the next
setTimeout(doAjax, interval);
}
});
}
setTimeout(doAjax, interval);
var click_count = 0;
$('#btnAdd').click(function () {
click_count++;
var $clones = $('#input_table tr'),
num = $clones.size() + 1,
next_num = parseInt($clones.last().find('input[name^="person_id"]').val()) + 1,
$template = $clones.first(),
newSection = $template.clone().attr('id', 'pq_entry_'+num),
person_id = 'person_id_'+num;
person_fname = 'person_fname_'+num;
person_lname = 'person_lname_'+num;
newSection.removeAttr('data-saved');
// clear out all sections of new input
newSection.find('input[type="text"]').val('');
newSection.find('input[name^="person_id"]').attr({
'id': person_id
}).val(next_num);
newSection.find('input[name^="person_fname"]').attr({
'id': person_fname
});
newSection.find('input[type="button"]').attr('data-ident', next_num);
$('#input_table').append(newSection);
$('#btnDel').prop('disabled', '');
if (num == 100) $('#btnAdd').prop('disabled', 'disabled');
});
$('.save-button').click(function(){
var $parent = $(this).parents('.clonedSection')
var id = $parent.find('input[name="person_id"]').val();
// do whatever else here, save to db
$parent.attr('data-saved', '1');
})
$('#btnDel').click(function () {
var num = $('.clonedSection').length; // how many duplicate input fields we currently have
$('#pq_entry_' + num).remove(); // remove the last element
// enable the "add" button
$('#btnAdd').prop('disabled', '');
// if only one element remains, disable the "remove" button
if (num - 1 == 1) $('#btnDel').prop('disabled', 'disabled');
});
$('#btnDel').prop('disabled', 'disabled');
});
The HTML:
<form>
<strong>Start Increment from Next ID to be inserted in the DB:</strong><input id="increment_num" name="increment_num" type="text" /></br>
<table>
<thead>
<tr><th>ID from DB</th><th></th>
<th>First Name</th></tr>
</thead>
<tbody id="input_table" >
<tr id="pq_entry_1" class="clonedSection" data-saved="1">
<td><input type="text" name="person_id" value='1' readonly /></td>
<td><input id="person_fname_1" name="person_fname" placeholder=" First Name" type="text" value='James'/></td>
<td><input type="button" class="save-button" value="Save" />
</tr>
<tr id="pq_entry_2" class="clonedSection" >
<td><input type="text" name="person_id" value='2' readonly /></td>
<td><input id="person_fname_2" name="person_fname" placeholder=" First Name" type="text" value='Cynthia'/></td>
<td><input type="button" class="save-button" value="Save" />
</tr>
</tbody>
</table>
<input type='button' id='btnAdd' value='add another Person' />
<input type='button' id='btnDel' value='Delete' /></br>
</form>
Having said all of that, I probably would approach this differently by having a hidden element:
<input type="hidden" name="person_id" value="1" />
That when a new row was generated was nullified:
<input type="hidden" name="person_id" value="" />
Then in my PHP, I would allow MySQL to handle auto incrementing the id in a manner like this:
<?php
$params = $_POST;
if(is_numeric($params['person_id'])){
$sql = sprintf('UPDATE person SET fname = "%s", lname = "%s" WHERE person_id = %u LIMIT 1',
mysql_real_escape_string($params['fname']),
mysql_real_escape_string($params['lname']),
intval($params['person_id'])
);
} else {
// the NULL tells MySQL to select the correct next increment id automatically
$sql = sprintf('INSERT INTO person (id, fname, lname) VALUES (NULL, "%s", "%s")',
mysql_real_escape_string($params['fname']),
mysql_real_escape_string($params['lname']);
);
}
?>