Reputation: 1242
I would like to know how to add input to each field in a table once I press edit using jquery. So basically I have 7 columns with 7 headings in the table for html and I want to be able to edit each field after pressing edit button which will be at the right side of the table for each row. After I add the input field in each column for that specific row and once the input is in, I want to call my update api using ajax. This is my html code.
<div id="table-wrapper">
<div id="table-scroll">
<table id="results" class="hidden" cellspacing=10px>
<thead>
<tr class = "spacing">
<th>SAM ID</th>
<th>Item Description</th>
<th>Issued QTY</th>
<th>Opening QTY</th>
<th>Closing QTY</th>
<th>Corrupted QTY</th>
<th>Remarks</th>
</tr>
</thead>
<tbody id="bResults">
</tbody>
</table>
</div>
</div>
This is my js code connected to the html.
function search(){
var samId = $('#samId').val();
var postData = { "samId": samId };
var postJSON = JSON.stringify(postData);
$.ajax({
url: "http://localhost:3000/api/queryRecord", // server url
type: "POST", //POST or GET
contentType: "application/json",
data: postJSON, // data to send in ajax format or querystring format
dataType : "JSON", //dataType is you telling jQuery what kind of
response to expect
success: function(response) {
alert('success');
if(response){
var len = response.length;
var txt = "";
if(len > 0){
for(var i=0;i<len;i++){
if(response[i].samID && response[i].itemDescription){
txt += "<tr class='rowdata'><td>"+response[i].samID
+"</td><td>"+response[i].itemDescription+"</td><td>"
+response[i].issuedQTY + "</td>
<td>"+response[i].openingQTY + "</td>
<td>"+response[i].closingQTY
+"</td><td>"+response[i].corruptedQTY+"</td>
<td>"+response[i].Remarks+"</td><td>"
+ "<input class='button-edit' type='submit'
value='Edit' onclick = 'edit()' />"
+"</td></tr>";
}
}
$("#bResults").empty();
if(txt != ""){
$("#results").removeClass("hidden");
$("#bResults").append(txt);
}
}
}
},
error: function(response) {
alert('error');
}
});
event.preventDefault();
}
function edit(){
var currentTD = $(this).parents('tr').find('td');
if ($(this).html() == 'Edit') {
$.each(currentTD, function () {
$(this).prop('contenteditable', true)
});
} else {
$.each(currentTD, function () {
$(this).prop('contenteditable', false)
});
}
$(this).html($(this).html() == 'Edit' ? 'Save' : 'Edit')
}
My search()
works fine but just wanted to show how my response is being coded. This edit()
is what I have basically but I don't really know how to use as the code is from another question Making row editable when hit row edit button due to not having any clue about the way to do this edit and adding a input field for people to edit in that particular row. I am using mongodb as the database as well. Do explain it in a simpler way for me to understand better. Thanks!
UPDATE Following according to Mohamed-Yousef
function search(){
var samId = $('#samId').val();
var postData = { "samId": samId };
var postJSON = JSON.stringify(postData);
$.ajax({
url: "http://localhost:3000/api/queryRecord", // server url
type: "POST", //POST or GET
contentType: "application/json",
data: postJSON, // data to send in ajax format or querystring format
dataType : "JSON", //dataType is you telling jQuery what kind of
response to expect
success: function(response) {
alert('success');
if(response){
var len = response.length;
var txt = "";
if(len > 0){
for(var i=0;i<len;i++){
if(response[i].samID && response[i].itemDescription){
txt +="<tr class='rowdata'><td>"+response[i].samID+
"</td>"+<td>"+response[i].itemDescription+
"</td>"+"<td>"+response[i].issuedQTY +
"</td>"+"<td>"+response[i].openingQTY +
"</td>"+"<td>"+response[i].closingQTY+
"</td>"+"<td>"+response[i].corruptedQTY+
"</td>"+"<td>"+response[i].Remarks+"</td>"
+"<td><input class='button-edit'
type='submit' value='Edit' onclick = 'edit()'
/></td>"+"</tr>";
}
}
$("#bResults").empty();
if(txt !== ""){
$("#results").removeClass("hidden");
$("#bResults").append(txt);
}
}
}
},
error: function(response) {
alert('error');
}
});
event.preventDefault();
}
function edit(el){
var currentTD = $(el).closest('tr').find('td').not($(el).closest('td'));
if ($(this).html() == 'Edit') {
$.each(currentTD, function () {
$(this).prop('contenteditable', true)
});
} else {
$.each(currentTD, function () {
$(this).prop('contenteditable', false)
});
}
$(el).val($(el).val() == 'Edit' ? 'Save' : 'Edit')
}
Does not seem to work and still gives the error Uncaught TypeError: Cannot read property 'createDocumentFragment' of undefined
Another answer I did according to Bryan Dellinger was using knockout.js
<table id="results" class="hidden" cellspacing=10px>
<thead>
<tr class = "spacing">
<th>SAM ID</th>
<th>Item Description</th>
<th>Issued QTY</th>
<th>Opening QTY</th>
<th>Closing QTY</th>
<th>Corrupted QTY</th>
<th>Remarks</th>
</tr>
</thead>
<tbody id="bResults" data-bind="foreach: txt">
<tr>
<td>
<!-- ko if: buttonText() === 'Save' -->
<input data-bind="textInput: samID">
<!-- /ko -->
<!-- ko if: buttonText() === 'Edit' -->
<span data-bind="text: samID"></span>
<!-- /ko -->
</td>
<td>
<!-- ko if: buttonText() === 'Save' -->
<input data-bind="textInput: itemDescription">
<!-- /ko -->
<!-- ko if: buttonText() === 'Edit' -->
<span data-bind="text: itemDescription"></span>
<!-- /ko -->
</td>
<td>
<!-- ko if: buttonText() === 'Save' -->
<input data-bind="textInput: issuedQTY">
<!-- /ko -->
<!-- ko if: buttonText() === 'Edit' -->
<span data-bind="text: issuedQTY"></span>
<!-- /ko -->
</td>
<td>
<!-- ko if: buttonText() === 'Save' -->
<input data-bind="textInput: openingQTY">
<!-- /ko -->
<!-- ko if: buttonText() === 'Edit' -->
<span data-bind="text: openingQTY"></span>
<!-- /ko -->
</td>
<td>
<!-- ko if: buttonText() === 'Save' -->
<input data-bind="textInput: closingQTY">
<!-- /ko -->
<!-- ko if: buttonText() === 'Edit' -->
<span data-bind="text: closingQTY"></span>
<!-- /ko -->
</td>
<td>
<!-- ko if: buttonText() === 'Save' -->
<input data-bind="textInput: corruptedQTY">
<!-- /ko -->
<!-- ko if: buttonText() === 'Edit' -->
<span data-bind="text: corruptedQTY"></span>
<!-- /ko -->
</td>
<td>
<!-- ko if: buttonText() === 'Save' -->
<input data-bind="textInput: corruptedQTY">
<!-- /ko -->
<!-- ko if: buttonText() === 'Edit' -->
<span data-bind="text: corruptedQTY"></span>
<!-- /ko -->
</td>
<td>
<!-- ko if: buttonText() === 'Save' -->
<input data-bind="textInput: Remarks">
<!-- /ko -->
<!-- ko if: buttonText() === 'Edit' -->
<span data-bind="text: Remarks"></span>
<!-- /ko -->
</td>
<td><button data-bind="text: buttonText, click: $parent.click">
</button></td>
</tr>
</tbody>
</table>
<script src="js/jquery-3.2.1.min.js"></script>
<script src="js/mainpage.js"></script>
<script
src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-
min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1
/knockout.mapping.min.js"></script>
This is the js
function search(){
var samId = $('#samId').val();
var postData = { "samId": samId };
var postJSON = JSON.stringify(postData);
$.ajax({
url: "http://localhost:3000/api/queryRecord", // server url
type: "POST", //POST or GET
contentType: "application/json",
data: postJSON, // data to send in ajax format or querystring format
dataType : "JSON", //dataType is you telling jQuery what kind of response to expect
success: function(response) {
alert('success');
if(response){
var len = response.length;
var txt = "";
if(len > 0){
for(var i=0;i<len;i++){
if(response[i].samID && response[i].itemDescription){
txt = [{
"samID": response[i].samID,
"itemDescription":response[i].itemDescription,
"issuedQTY": response[i].issuedQTY,
"openingQTY": response[i].openingQTY,
"closingQTY": response[i].closingQTY,
"corruptedQTY": response[i].corruptedQTY,
"editMode" : false,
"Remarks": response[i].Remarks,
"buttonText": "Edit"
}]
}
}
$("#bResults").empty();
if(txt != ""){
$("#results").removeClass("hidden");
$("#bResults").append(txt);
}
}
}
},
error: function(response) {
alert('error');
}
});
event.preventDefault();
}
Upvotes: 0
Views: 2215
Reputation: 24001
I think The problem is : by using $(this)
inside your edit()
function its refer to object I don't know for window or something but its not for an edit button .. so you can pass edit(element)
as an argument and on html use onclick="edit(this)"
And while you use input
.. use .val()
instead of .html()
And to avoid the td
which has your edit input you can use .not()
so your code should looks like
function edit(el){
var currentTD = $(el).closest('tr').find('td').not($(el).closest('td')); // tds except the td which closest to the edit button
if ($(el).val() == 'Edit') {
$.each(currentTD, function () {
$(this).prop('contenteditable', true)
});
} else {
$.each(currentTD, function () {
$(this).prop('contenteditable', false)
});
}
$(el).val($(el).val() == 'Edit' ? 'Save' : 'Edit')
}
And on html use type="button" no need to use submit
<input class='button-edit' type='button' value='Edit' onclick = 'edit(this)' />
//--------------------------------^-------------------------------------^--------
And the row HTML structure should be like
txt += "<tr class='rowdata'><td>"+response[i].samID+"</td>"
+"<td>"+response[i].itemDescription+"</td>"
+"<td>"+response[i].issuedQTY + "</td>"
+"<td>"+response[i].openingQTY + "</td>"
+"<td>"+response[i].closingQTY+"</td>"
+"<td>"+response[i].corruptedQTY+"</td>"
+"<td>"+response[i].Remarks+"</td>"
+"<td><input class='button-edit' type='submit' value='Edit' onclick = 'edit()' /></td>"
+"</tr>";
And use !==
instead of !=
in if(txt != ""){
Upvotes: 1