I cant figure out why a double <BR> is automatically being added to my newly appended table rows.
All you have to do is hit the enter key to cause the problem.
I don't want any <br> to be added, it screws up my data entry process.
The problem appears to be happening in the appenNewRow() function.
<!DOCTYPE html>
<html>
<head>
<title>jQuery Text Area Order Input</title>
<style>
.myInputClass {
width: 120px;
}
.myOutputClass {
width: 240px;
}
</style>
<script src="https://code.jquery.com/jquery-3.2.1.min.js"></script>
<script>
storeflag = true;
attribstart = "";
attribend = "";
output_result = "";
var row = 0;
var storeIndex = 0;
var productIndex = 0;
var thisstore_id=0;
function appendNewRow(inputType)
{
row++;
var markup = "<tr id='"+row+"'><td input-row='"+row+"' input-type='"+inputType+"' class='myInputClass' height='auto' contenteditable='true' placeholder='Next'></td><td output-row='"+row+"' class='myOutputClass'></td><td extra-row='"+row+"' class='extra'></td></tr>";
$("table tbody").append(markup);
myjunk = document.querySelector('[input-row="' + row + '"]').innerHTML;
document.querySelector('[input-row="' + row + '"]').innerHTML = "zzz";
document.getElementById(row).getElementsByClassName('myInputClass')[0].focus();
}
function getStore(thisstore)
{
}
function getProduct(thisstore_id, thisproduct_nickname)
{
}
$(document).ready(function(){
document.getElementById('1').getElementsByClassName('myInputClass')[0].focus();
lastKey = 13;
$("tbody").on('keypress', ".myInputClass", (function(event){
if (event.which == 13) { // Enter Key.
attribstart = "";
attribend = "";
row = Number($(this).attr('input-row'));
thishtml = $(this).html();
if ($(this).text().length > 0) {
x = $(this).text();
if (storeflag == true) {
thisstore_id = getStore(x);
} else {
getProduct(thisstore_id,x);
}
} else {
$(this).text("---");
appendNewRow('store');
storeflag = true;
//$('#YourContainer').find('br').remove();
$('[input-row="' + row + '"]').find('br').remove(); // Fixes an ajax bug.
}
} else {
} //end if
lastKey = event.which;
}));
});
</script>
</head>
<body>
<table>
<thead>
<tr>
<th>Input</th>
<th>Output</th>
<th>Extra</th>
</tr>
</thead>
<tbody>
<tr id='1'>
<td input-row='1' input-type='store' class='myInputClass' height='auto' contenteditable='true' placeholder='Just Start Typing a storename'></td>
<td output-row='1' class='myOutputClass'></td>
<td extra-row='1' class='extra'></td>
</tr>
</tbody>
</table>
</body>
</html>
I cleaned up the code you presented. It's a better practice to use all jQuery or all JavaScript. Based on the following testing, you may need to add the content and then make it Editable.
$(function() {
$("#empty").click(function() {
$("<tr>").appendTo($("table tbody"));
$("<td>").appendTo($("table tr:last")).prop("contenteditable", true);
});
$("#full").click(function() {
$("<tr>").appendTo($("table tbody"));
$("<td>").appendTo($("table tr:last")).html("Edit").prop("contenteditable", true);
});
});
table {
border: 1px solid black;
border-collapse: collapse;
padding: 0;
margin: 0;
}
table tr {
height: 1.5em;
}
table tr td {
border: 1px dashed black;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<tbody>
<tr>
<td>Non-Edit</td>
</tr>
</tbody>
</table>
<button id="empty">Add Empty Row</button>
<button id="full">Add Full Row</button>
We apply this to your code.
$(function() {
var storeflag = true,
attribstart = "",
attribend = "",
output_result = "",
row = 0,
storeIndex = 0,
productIndex = 0,
thisstore_id = 0;
function appendNewRow(inputType) {
var markRow = $("<tr>", {
id: ++row
}).appendTo($("table tbody"));
$("<td>", {
class: "myInputClass",
height: "auto",
placeholder: "Next",
"input-row": row,
"input-type": inputType
}).appendTo(markRow);
$("<td>", {
class: "myOutputClass",
"output-row": row
}).appendTo(markRow);
$("<td>", {
class: "extra",
"extra-row": row
}).appendTo(markRow);
$("td:eq(0)", markRow).html("Start").prop("contenteditable", true).focus();
}
function getStore(thisstore) {
$.ajax({
url: 'ajax_getstore',
data: "store=" + thisstore,
method: "GET",
dataType: "json",
cache: false,
success: function(data) {
var markup = "";
if (data.length > 1) {
$.each(data, function(thisname, thisvalue) {
var output = attribstart + thisvalue.fields.name + attribend;
markup += "<tr id='" + row + "'><td class='dyninput'>row:" + row + " - " + output + "</td></tr>";
});
} else {
$('[input-row="' + row + '"]').html(thisstore); // Fixes an ajax bug.
$('[output-row="' + row + '"]').attr('input-type', 'store');
$('[output-row="' + row + '"]').html(attribstart + data[0].fields.name + attribend);
}
thisstore_id = data[0].pk;
appendNewRow('product');
output_result = "";
}, // End success.
error: function() {
alert('error');
},
}); //End Ajax.
attribstart = "<b>";
attribend = "</b>";
storeflag = false; //reset storeflag.
}
function getProduct(thisstore_id, thisproduct_nickname) {
var qty = parseInt(thisproduct_nickname);
if (isNaN(qty)) {
qty = '1';
} else {
thisproduct_nickname = thisproduct_nickname.replace(qty, '');
}
$.ajax({
url: 'ajax_getproduct',
data: 'store_id=' + thisstore_id + '&qty=' + qty + '&product_nickname=' + thisproduct_nickname,
method: "GET",
dataType: "json",
cache: false,
success: function(data) {
var markup = "";
if (data.length > 1) {
$.each(data, function(thisname, thisvalue) {
var output = attribstart + thisvalue.fields.product_name + attribend;
markup = markup + "<tr id='" + row + "'><td class='dyninput'>row:" + row + " - " + output + "<br></td></tr>";
row++;
});
} else {
$('[input-row="' + row + '"]').html(thisproduct_nickname); // Fixes an ajax bug.
$('[output-row="' + row + '"]').attr('input-type', 'product');
$('[output-row="' + row + '"]').html(attribstart + qty + ' ' + data[0].fields.product_default_uom_code + ' ' + data[0].fields.product_name + attribend);
}
appendNewRow('product');
output_result = "";
}, // End success.
error: function() {
alert('error');
},
}); //End Ajax.
}
function display_result(data_output_result) {
var badjson = JSON.parse(data_output_result);
var myjson = badjson.replace("\\", "");
var goodjson = JSON.parse(myjson);
var markup = "";
$.each(goodjson, function(thisname, thisvalue) {
row = row + 1;
var output = attribstart + thisvalue.fields.name + attribend;
markup += "<tr id='" + row + "'><td class='dyninput'>row:" + row + " - " + output + "<br></td></tr>";
console.log(thisvalue.fields.id, thisvalue.fields.name);
});
$("table tbody#myOutputBodyId").append(markup);
output_result = "";
}
$('#1 .myInputClass').focus();
var lastKey = 13;
$("tbody").on('keypress', ".myInputClass", function(event) {
event.preventDefault();
if (event.which == 13) { // Enter Key.
attribstart = "";
attribend = "";
row = Number($(this).attr('input-row'));
thishtml = $(this).html();
if ($(this).text().length > 0) {
x = $(this).text();
if (storeflag == true) {
thisstore_id = getStore(x);
} else {
getProduct(thisstore_id, x);
}
} else {
$(this).text("---");
appendNewRow('store');
storeflag = true;
//$('#YourContainer').find('br').remove();
$('[input-row="' + row + '"]').find('br').remove(); // Fixes an ajax bug.
}
} //end if
lastKey = event.which;
});
});
.myInputClass {
width: 120px;
}
.myOutputClass {
width: 240px;
}
table,
td {
margin: 0px;
border-collapse: collapse;
padding: 0px;
border-spacing: 0px;
vertical-align: top;
}
table th {
border: 1px solid #6C220B;
border-spacing: 0px;
padding: 0px;
text-align: left;
}
table#myOutputTableId {
border: 0px;
padding: 0px;
margin: 0px;
align: top;
}
[xcontentEditable=true]:empty:before {
content: attr(placeholder);
opacity: 0.6;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<table>
<thead>
<tr>
<th>Input</th>
<th>Output</th>
<th>Extra</th>
</tr>
</thead>
<tbody>
<tr id='1'>
<td input-row='1' input-type='store' class='myInputClass' height='auto' contenteditable='true' placeholder='Just Start Typing a storename'></td>
<td output-row='1' class='myOutputClass'></td>
<td extra-row='1' class='extra'></td>
</tr>
</tbody>
</table>
The issue was the key capture from the Enter. This was injecting the new line in the editable and creating the <br>. We can use .preventDefault() to address this.
I am unable to test this code as it does not connect to any of the AJAX Urls.
Related
Actually in my website i'm building a timeline from AJAX and i was trying to set the onclick on each table row.
I was using class selector but the effect was nothing.
I actually read in another stackoverflow post that i had to set onclick on the closest static item but nothing.
So i've tryed
$(".timeline").on("click","table-row",function () { alert("we") ;});
and
$(".table-row").click(function () { alert("we"); });
Actually AJAX code where i create the timeline is the following
function createTavoli(salaSelect) {
$.ajax({
type: "POST",
url: "Default.aspx/getTavoli",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (r) {
data = r.d;
data = $.parseJSON(data);
var count = 0;
var time = [];
$.each(data, function (i, item) {
var tabs = [];
var numtav = item.NUM_TAV;
var desctav = item.DESC_T;
var coperti = item.COPERTI;
var sala = item.SALA;
if (sala == salaSelect) {
tabs.push('<tr id="' + numtav + '" data-salatav="' + sala + '" class="table-row">');
if (desctav != "") {
tabs.push('<th scope="row" class="noselect row-head text-left">' + desctav + '<span class="badge badge-dark ml-1">' + coperti + '</span></th>');
} else {
tabs.push('<th scope="row" class="noselect row-head text-left">' + "T. " + numtav + '<span class="badge badge-dark ml-1">' + coperti + '</span></th>');
}
for (var i = 0; i <= 95 - Range; i++) {
tabs.push('<td style="padding: 0px; position: relative; z-index: 1;"></td>');
}
tabs.push('</tr>');
count++;
$('#timeline').append(tabs.join(""));
}
});
time.push('<th scope="col" style="padding: 0px; border: 0; width: 80px;" class="row-head"></th>');
for (var i = PartenzaOra; i <= 23; i++) {
time.push('<th style="padding: 0px; border: 0; z-index: 3;" scope="colgroup" colspan="4"><p class="h noselect">' + ('0' + i).slice(-2) + '</p></th>');
}
$('#timehead').append(time.join(""));
$('#counttav').text(count);
getTavoli(new Date());
},
error: function (xhr, status, errorThrow) {
alert(xhr.status + " " + xhr.responseText);
}
});
}
So which could be the best method to set onclick on the table-row class?
Here is JSFiddle of how's build the timeline
You should set click event after rows pushed to table. So put your $(".table-row").click(function () { alert("we"); }); code to end of success function.
Did you tried
$(document).on("click", ".timeline .table-row" , function() {
alert("we");
});
you can try this
$('body').on("click", ".table-row" , function() {
alert("we");
});
I'm looping an object and expect the result as elements of a table
var db = {
"id": "8",
"user_id": "24",
"batchno": "367727",
"ht_number": "jibhbu",
"ht_taste": "uvyutvc",
"pp_flavour": "ytv,yurtcrc,urt",
"pp_fruit_batch": "cuyt,cytc,yt",
"sl_flavour": "ouihyuigytvytc",
"sl_appearance": "rtctr"
},
pp_ = '<table><tbody>';
for (var i in db) {
if (db.hasOwnProperty(i)) {
var js = db[i].split(',');
for (var x in js) {
if (i.startsWith('pp_')) {
pp_ += '<tr><td>' + i + ' ' + x + ' : ' + js[x] + '</td></tr>';
}
}
}
}
pp_ += '</tbody></table>';
document.write(pp_);
I am splitting values that have commas so that each index of an array sits on 1 row (tr)
what I can't figure out is how to place elements with the same index on the same level (row) so I can I have something like
table, td {
border: 1px solid black;
}
<table>
<tbody>
<tr>
<td> pp_flavour 0 - its value </td>
<td> pp_fruit_batch 0 - its value </td>
</tr>
<tr>
<td> pp_flavour 1 - its value </td>
<td> pp_fruit_batch 1 - its value </td>
</tr>
<tr>
<td> pp_flavour 2 - its value </td>
<td> pp_fruit_batch 2 - its value </td>
</tr>
</tbody>
</table>
<br>
<table>
<tbody>
<tr>
<td> sl_favour 0 - its value </td>
<td> sl_appearance 0 - its value </td>
</tr>
<tr>
<td> sl_favour 1 - its value </td>
<td> sl_appearance 1 - its value </td>
</tr>
</tbody>
</table>
and so on...
You could try indexing the database like this:
var db = {
"id": "8",
"user_id": "24",
"batchno": "367727",
"ht_number": "jibhbu",
"ht_taste": "uvyutvc",
"pp_flavour": "ytv,yurtcrc,urt",
"pp_fruit_batch": "cuyt,cytc,yt",
"sl_flavour": "ouihyuigytvytc",
"sl_appearance": "rtctr"
};
var prefixes = ["pp", "ht", "sl"];
var prefixedDb = {};
var result = "";
for (var i in db) {
if (db.hasOwnProperty(i)) {
var parts = i.split("_");
var prefix = parts[0];
if (prefixes.indexOf(prefix) === -1) continue;
if (prefixedDb[prefix] === undefined) {
prefixedDb[prefix] = {};
}
prefixedDb[prefix][parts.slice(1).join("_")] = db[i];
}
}
for (var k in prefixedDb) {
if (prefixedDb.hasOwnProperty(k)) {
var db = prefixedDb[k];
var dbIndexed = {};
for (var i in db) {
if (db.hasOwnProperty(i)) {
var vals = db[i].split(',');
vals.forEach(function(val, j) {
if (dbIndexed[j] === undefined) {
dbIndexed[j] = {};
}
dbIndexed[j][i] = val;
});
}
}
result += "<table><tbody>";
for (var i in dbIndexed) {
if (dbIndexed.hasOwnProperty(i)) {
result += "<tr>";
var indexVals = dbIndexed[i];
for (var j in indexVals) {
if (indexVals.hasOwnProperty(j)) {
result += "<td>" + j + " " + i + " - " + indexVals[j] + "</td>";
}
}
result += "</tr>";
}
}
result += "</tbody></table>";
}
}
document.write(result);
table, td {
border: 1px solid black;
}
Please note that this code may not be the most optimized code for this task.
You can try adding each value of the table to a 2-D array and than form the table from this 2-D array
try below solution
NOTE: this will also work with different number of rows and Column.
var db = {
"id": "8",
"user_id": "24",
"batchno": "367727",
"ht_number": "jibhbu",
"ht_taste": "uvyutvc",
"pp_flavour": "ytv,yurtcrc,urt",
"pp_fruit_batch": "cuyt,cytc,yt",
"sl_flavour": "ouihyuigytvytc",
"sl_appearance": "rtctr"
};
function createTable(myKey){
var rows = [];
for (var dbKey in db) {
if (db.hasOwnProperty(dbKey)) {
if (dbKey.startsWith(myKey)) {
var values = db[dbKey].split(',');
for (var val in values) {
if (!rows[val])
rows[val] = [];
rows[val].push('<td>' + dbKey + ' ' + val + ' : ' + values[val] + '</td>');
}
}
}
}
var myTable = '<table><tbody>';
for (var i = 0; i < rows.length; i++) {
myTable += "<tr>" + rows[i].join("") + "</tr>";
}
myTable += '</tbody></table>';
return myTable;
}
var ht_table = createTable("ht_");
document.getElementById("myTable").innerHTML +="<br/>"+ ht_table;
var pp_table = createTable("pp_");
document.getElementById("myTable").innerHTML +="<br/>"+ pp_table;
var sl_table = createTable("sl_");
document.getElementById("myTable").innerHTML += "<br/>"+ sl_table;
table, td {
border-style: solid;
}
<p id="myTable">
</p>
You could take the wanted values out of the object, split them and take the max length for iterating the rows for the table. Then assemble the table by iterating the values.
var db = { pp_flavour: "ytv,yurtcrc,urt", pp_fruit_batch: "cuyt,cytc,yt,42" },
values = Object.keys(db).filter(k => k.startsWith('pp_')).map(k => (db[k] || '').split(',')),
length = values.reduce((r, a) => Math.max(r, a.length), 0),
table = document.createElement('table'),
tr,
i;
for (i = 0; i < length; i++) {
tr = document.createElement('tr');
table.appendChild(tr);
values.forEach(function (a) {
var td = document.createElement('td');
td.appendChild(document.createTextNode(i in a ? a[i] : ''));
tr.appendChild(td);
});
}
document.body.appendChild(table);
Create a loop, incrementing a counter, which will determine if a key's split value should be output.
If there are no more values found at the index of the counter, stop looping.
var db = {
"id": "8",
"user_id": "24",
"batchno": "367727",
"ht_number": "jibhbu",
"ht_taste": "uvyutvc",
"pp_flavour": "ytv,yurtcrc,urt",
"pp_fruit_batch": "cuyt,cytc,yt",
"sl_flavour": "ouihyuigytvytc",
"sl_appearance": "rtctr"
},
s = '';
['pp_', 'ht_', 'sl_'].forEach(function(type) {
var i,
found = true;
s += '<table>';
for(i = 0 ; found ; i++) {
s += '<tr>';
found = false;
Object.keys(db).forEach(function(key) {
var js = db[key].split(',');
if(js[i] && key.startsWith(type)) {
found = true;
s += '<td>' + key + ' ' + i + ' : ' + js[i] + '</td>';
}
});
s += '</tr>';
}
s += '</table>';
});
document.write(s);
td {
border-bottom: 1px solid #bbb;
border-right: 1px solid #ddd;
padding: 0.5em;
}
table {
border: 1px solid black;
margin-bottom: 1em;
border-spacing: 0;
}
I'm trying to make a dynamic table with variable no. of rows and columns. Table is created but when i click on the cells, they are not editable as i assumed they will be.
$(document).ready(function() {
$("#createit").click(function() {
var num_rows = document.getElementById('rows').value;
var num_cols = document.getElementById('cols').value;
var tbody = '';
for (var i = 0; i < num_rows; i++) {
tbody += '<tr>';
for (var j = 0; j < num_cols; j++) {
tbody += '<td tabindex=' + j + '>';
tbody += 'Cell' + i + j;
tbody += '</td>'
}
tbody += '</tr>';
}
//document.getElementById('wrapper').innerHTML = theader + tbody + tfooter;
$('.editableTable').append(tbody);
});
});
$(".editableTable td").dblclick(function() {
console.log('clicked');
var OriginalContent = $(this).text();
$(this).addClass("cellEditing");
$(this).html("<select><option>1</option><option>2</option><option >3</option></select>");
$(this).children().first().focus();
$(this).bgColor = 'red';
$(this).children().first().keypress(function(e) {
if (e.which == 13) {
var newContent = OriginalContent;
$(this).parent().text(OriginalContent);
$(this).parent().removeClass("cellEditing");
}
});
$(this).children().first().blur(function() {
$(this).parent().text(OriginalContent);
$(this).parent().removeClass("cellEditing");
});
});
$(".editableTable td").bind('keydown', function(event) {
if (event.keyCode === 9 || event.keyCode === 13) {
var tabindex = $(this).attr('tabindex');
tabindex++; //increment tabindex
$('[tabindex=' + tabindex + ']').focus().dblclick();
return false;
}
});
.editableTable {
border: solid 0px;
width: 100%;
text-align: center
}
.editableTable td {
border: solid 0.5px;
border-color: lightblue;
min-width: 100px;
}
.editableTable .cellEditing {
padding: 0;
}
select {
border: 0px;
width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label>Rows: <input type="text" name="rows" id="rows"/></label><br />
<label>Cols: <input type="text" name="cols" id="cols"/></label><br/>
<input name="generate" type="button" value="Create Table!" id='createit' />
<div id="wrapper">
<table class="editableTable">
<tbody></tbody>
</table>
</div>
Same thing i have done before but with a static table. JSFIDDLE https://jsfiddle.net/rbrohitbisht/691rx62k/
Now i want to do the same thing with the dynamic table. What i'm doing wrong here?
The operation should be moved into the createit handler definition.
$(".editableTable td").dblclick(function() {...});
Just after the cells are created(of course after a click on Crete Table!).
Otherwise the selector $(".editableTable td") would not return anything before the dynamic table is in place.
You should add contenteditable="true" to your code
https://codepen.io/anon/pen/XgJaxE
$(document).ready(function() {
$("#createit").click(function() {
var num_rows = document.getElementById('rows').value;
var num_cols = document.getElementById('cols').value;
var tbody = '';
for (var i = 0; i < num_rows; i++) {
tbody += '<tr>';
for (var j = 0; j < num_cols; j++) {
tbody += '<td contenteditable="true" tabindex=' + j + '>';
tbody += 'Cell' + i + j;
tbody += '</td>'
}
tbody += '</tr>';
}
//document.getElementById('wrapper').innerHTML = theader + tbody + tfooter;
$('.editableTable').append(tbody);
});
});
$(".editableTable td").dblclick(function() {
console.log('clicked');
var OriginalContent = $(this).text();
$(this).addClass("cellEditing");
$(this).html("<select><option>1</option><option>2</option><option >3</option></select>");
$(this).children().first().focus();
$(this).bgColor = 'red';
$(this).children().first().keypress(function(e) {
if (e.which == 13) {
var newContent = OriginalContent;
$(this).parent().text(OriginalContent);
$(this).parent().removeClass("cellEditing");
}
});
$(this).children().first().blur(function() {
$(this).parent().text(OriginalContent);
$(this).parent().removeClass("cellEditing");
});
});
$(".editableTable td").bind('keydown', function(event) {
if (event.keyCode === 9 || event.keyCode === 13) {
var tabindex = $(this).attr('tabindex');
tabindex++; //increment tabindex
$('[tabindex=' + tabindex + ']').focus().dblclick();
return false;
}
});
$(document).ready(function () {
$("#createit").click(function () {
var num_rows = document.getElementById('rows').value;
var num_cols = document.getElementById('cols').value;
var tbody = '';
var tabindex = 0
for (var i = 0; i < num_rows; i++) {
tbody += '<tr>';
for (var j = 0; j < num_cols; j++) {
tbody += '<td tabindex=' + tabindex++ + '>';
tbody += 'Cell' + i + j;
tbody += '</td>'
}
tbody += '</tr>';
}
//document.getElementById('wrapper').innerHTML = theader + tbody + tfooter;
$('.editableTable').append(tbody);
});
});
$(document).on('dblclick', 'td', function () {
console.log('clicked');
this.contentEditable = 'true';
});
$(document).on('keydown', 'td', function (event) {
if (event.keyCode === 9 || event.keyCode === 13) {
this.contentEditable = 'false';
// $(this).next().focus().dblclick().focus();
var tabindex = $(this).attr('tabindex');
tabindex++;
var next = $('[tabindex=' + tabindex + ']').focus().dblclick();
if (next.is('td') == false)
return true;
var sel, range;
if (window.getSelection && document.createRange) {
range = document.createRange();
range.selectNodeContents(next[0]);
range.collapse(true);
sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
} else if (document.body.createTextRange) {
range = document.body.createTextRange();
range.moveToElementText(next[0]);
range.collapse(true);
range.select();
}
return false;
}
});
.editableTable {
border: solid 0px;
width: 100%;
text-align: center
}
.editableTable td {
border: solid 0.5px;
border-color: lightblue;
min-width: 100px;
}
.editableTable .cellEditing {
padding: 0;
}
select {
border: 0px;
width: 100%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<label>Rows: <input type="text" name="rows" id="rows"/></label><br />
<label>Cols: <input type="text" name="cols" id="cols"/></label><br/>
<input name="generate" type="button" value="Create Table!" id='createit' />
<div id="wrapper">
<table class="editableTable">
<tbody></tbody>
</table>
</div>
use HTML DOM "contentEditable" Property Element Object
https://stackoverflow.com/a/44380264/3615816
<input type=button value="Enable editing"
onclick="document.getElementById('t1').contentEditable = 'true';alert('You can now edit table')" />
<table id="t1" border="1">
<tr><td >c1</td><td >c2</td></tr>
<tr><td >cc1</td><td >cc2</td></tr>
</table>
<input type=button value="disable editing"
onclick="document.getElementById('t1').contentEditable = 'false'; " />
I am populating a html table using ajax call in the following manner-
$.ajax({
type: "POST",
url: "my_url",
data: JSON.stringify(result),
async: true,
dataType: "json",
contentType: "application/json; charset= Shift-JIS",
success: function (response) {
glResp = response;
populateTable(glResp);
},
error: function (error) {
console.log(error);
//alert("Error!!");
}
});
Function that I am using to populate the table is as follows -
JS -
function populateTable(finalObject) {
var obj = finalObject;
var headers1 = ['Name', 'City', 'Job', 'Salary'];
var table = $("<table id='my-table' />");
var columns = headers1;
columns.unshift('');
var columnCount = columns.length;
var row = $(table[0].insertRow(-1));
for (var i = 0; i < columnCount; i++) {
if (i == 0) {
var headerCell = $("<th><input type='button' id='sort'></th>");
row.append(headerCell);
}
else {
var headerCell = $("<th/>");
headerCell.html([columns[i]]);
row.append(headerCell);
}
}
$.each(obj, function (i, obj) {
$row = '<tr><td><input type="checkbox"></td><td>' + obj.Name + '</td><td>' + obj.City + '</td><td>' + obj.Job + '</td><td>' + obj.Salary + '</td></tr>';
table.append(row);
});
var dvTable = $("#dvCSV");
dvTable.html("");
dvTable.append(table);
}
Now I want the table headers to be fixed on top when the data is being scrolled. Any idea as to how this can be implemented?
You can use a plugin to have a fixed position to your header columns,
http://mkoryak.github.io/floatThead/
Hope this link will help you.
For fix the header you can add thead for title element (th) and tbody for the chlid tr element, with display:block for both and overflow:auto for tbody element.
var tab = '[{"Name":"check","City":"check","job":"check","Salary":"check"},{"Name":"check","City":"check","job":"check","Salary":"check"},{"Name":"check","City":"check","job":"check","Salary":"check"},{"Name":"check","City":"check","job":"check","Salary":"check"},{"Name":"check","City":"check","job":"check","Salary":"check"},{"Name":"check","City":"check","job":"check","Salary":"check"}]'
tab = JSON.parse(tab);
populateTable(tab);
function populateTable(finalObject) {
var obj = finalObject;
var headers1 = ['Name', 'City', 'Job', 'Salary'];
var table = $("<table id='my-table' />");
var columns = headers1;
columns.unshift('');
var columnCount = columns.length;
var th = ""
for (var i = 0; i < columnCount; i++) {
if (i == 0) {
var headerCell = "<th><input type='button' id='sort'></th>";
th = th + headerCell;
}
else {
var headerCell = "<th>"+[columns[i]]+"</th>";
// headerCell.html();
th = th + headerCell;
}
}
table.prepend("<thead>"+th+"</thead>")
$.each(obj, function (i, obj) {
row = '<tr><td><input type="checkbox"></td><td>' + obj.Name + '</td><td>' + obj.City + '</td><td>' + obj.job + '</td><td>' + obj.Salary + '</td></tr>';
table.append(row);
});
var dvTable = $("#dvCSV");
dvTable.html("");
dvTable.append(table);
}
table{
width:100%;
}
td, th {
min-width: 100px;
}
tbody{
overflow: auto;
display: block;
height: 100px;
}
thead{
display:block;
text-align:left;
background:green;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="dvCSV"><div>
I am new to JQuery and doesn't know how to handle errors like uncaught TypeError: undefined is not a function. I don't know how to put the jQuery code below in order. Can someone please arrange it in order....
#model Mvc4_WebGrid_CRUD.Models.PagedCustomerModel
#{
ViewBag.Title = "WebGrid CRUD Operations";
WebGrid grid = new WebGrid(rowsPerPage: Model.PageSize);
grid.Bind(Model.Customer,
autoSortAndPage: false,
rowCount: Model.TotalRows
);
}
<style type="text/css">
#grid {
clear: both;
width: 80%;
margin: 0px;
border: 1px solid #c7c5c7;
}
#grid thead, #grid tfoot td {
text-align: left;
font-weight: bold;
height: 35px;
color: #000;
background-color: #d2d0d2;
border-bottom: 1px solid #e2e2e2;
}
#grid td {
padding: 4px 6px 0px 4px;
vertical-align: top;
background-color: #f5f5f5;
border-bottom: 1px solid #e2e2e2;
}
input {
border: 1px solid #e2e2e2;
background: #fff;
color: #333;
font-size: 1.2em;
margin: 2px 0 2px 0px;
padding: 2px;
width: 170px;
}
</style>
<script src="~/Scripts/jquery-1.8.2.js"></script>
<script src="~/Scripts/jquery-ui-1.8.24.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
//Here is where I get the error
$("#results").dialog({
autoOpen: false,
title: 'Title',
draggable: false,
width: 500,
height: 400,
model: true,
success: function () {
alert('working fine');
}
});
});
function openPopup() {
$("#results").dialog("open");
}
</script>
The below code works fine
<script type="text/javascript">
$(".add").live("click", function () {
var existrow = $('.save').length;
if (existrow == 0) {
var index = $("#grid tbody tr").length + 1;
var Name = "Name_" + index;
var Address = "Address_" + index;
var ContactNo = "ContactNo_" + index;
var Save = "Save_" + index;
var Cancel = "Cancel_" + index;
var tr = '<tr class="alternate-row"><td></td><td><span> <input id="' + Name + '" type="text" /></span></td>' +
'<td><span> <input id="' + Address + '" type="text" /></span></td>' +
'<td><span> <input id="' + ContactNo + '" type="text" /></span></td>' +
'<td> SaveCancel</td>' +
'</tr>';
$("#grid tbody").append(tr);
}
else {
alert('First Save your previous record !!');
}
});
$(".icancel").live("click", function () {
var flag = confirm('Are you sure to cancel');
if (flag) {
$(this).parents("tr").remove();
}
});
$(".save").live("click", function () {
var id = $("#grid tbody tr").length;
var Name = $("#Name_" + id).val();
var Address = $("#Address_" + id).val();
var ContactNo = $("#ContactNo_" + id).val();
if (id != "") {
$.ajax({
type: "GET",
contentType: "application/json; charset=utf-8",
url: '#Url.Action("SaveRecord", "Home")',
data: { "name": Name, "address": Address, "contactno": ContactNo },
dataType: "json",
beforeSend: function () { },
success: function (data) {
if (data.result == true) {
$("#divmsg").html("Record has been saved successfully !!");
setTimeout(function () { window.location.replace("WebGridCRUD"); }, 2000);
}
else {
alert('There is some error');
}
}
});
}
});
$(".edit").live("click", function () {
var str = $(this).attr("id").split("_");
id = str[1];
var Name = "#Name_" + id;
var spanName = "#spanName_" + id;
var Address = "#Address_" + id;
var spanAddress = "#spanAddress_" + id;
var ContactNo = "#ContactNo_" + id;
var spanContactNo = "#spanContactNo_" + id;
$(Name).show();
$(spanName).hide();
$(Address).show();
$(spanAddress).hide();
$(ContactNo).show();
$(spanContactNo).hide();
$(this).hide();
$("#Update_" + id).show();
$("#Cancel_" + id).show();
});
$(".cancel").live("click", function () {
var str = $(this).attr("id").split("_");
id = str[1];
var Name = "#Name_" + id;
var spanName = "#spanName_" + id;
var Address = "#Address_" + id;
var spanAddress = "#spanAddress_" + id;
var ContactNo = "#ContactNo_" + id;
var spanContactNo = "#spanContactNo_" + id;
$(Name).hide();
$(spanName).show();
$(Address).hide();
$(spanAddress).show();
$(ContactNo).hide();
$(spanContactNo).show();
$(this).hide();
$("#Update_" + id).hide();
$("#Edit_" + id).show();
});
$(".update").live("click", function () {
var str = $(this).attr("id").split("_");
id = str[1];
var Name = $("#Name_" + id).val();
var spanName = $("#spanName_" + id).val();
var Address = $("#Address_" + id).val();
var spanAddress = $("#spanAddress_" + id).val();
var ContactNo = $("#ContactNo_" + id).val();
var spanContactNo = $("#spanContactNo_" + id).val();
if (id != "") {
$.ajax({
type: "GET",
contentType: "application/json; charset=utf-8",
url: '#Url.Action("UpdateRecord", "Home")',
data: { "id": id, "name": Name, "address": Address, "contactno": ContactNo },
dataType: "json",
beforeSend: function () {//alert(id);
},
success: function (data) {
if (data.result == true) {
$("#Update_" + id).hide();
$("#Cancel_" + id).hide();
$("#Edit_" + id).show();
var Name = "#Name_" + id;
var spanName = "#spanName_" + id;
var Address = "#Address_" + id;
var spanAddress = "#spanAddress_" + id;
var ContactNo = "#ContactNo_" + id;
var spanContactNo = "#spanContactNo_" + id;
$(Name).hide();
$(spanName).show();
$(Address).hide();
$(spanAddress).show();
$(ContactNo).hide();
$(spanContactNo).show();
$(spanName).text($(Name).val());
$(spanAddress).text($(Address).val());
$(spanContactNo).text($(ContactNo).val());
}
else {
alert('There is some error');
}
}
});
}
});
$(".delete").live("click", function () {
var str = $(this).attr("id").split("_");
id = str[1];
var flag = confirm('Are you sure to delete ??');
if (id != "" && flag) {
$.ajax({
type: "GET",
contentType: "application/json; charset=utf-8",
url: '#Url.Action("DeleteRecord", "Home")',
data: { "id": id },
dataType: "json",
beforeSend: function () { },
success: function (data) {
if (data.result == true) {
$("#Update_" + id).parents("tr").remove();
}
else {
alert('There is some error');
}
}
});
}
});
</script>
<div id="divmsg" style="color: green; font-weight: bold"></div>
Add New
<br />
<br />
#grid.GetHtml(
htmlAttributes: new { id = "grid" },
fillEmptyRows: false,
mode: WebGridPagerModes.All,
firstText: "<< First",
previousText: "< Prev",
nextText: "Next >",
lastText: "Last >>",
columns: new[] {
grid.Column("CustID",
header: "ID", canSort: false),
grid.Column(header: "Name",format: #<span> <span id="spanName_#item.CustID">#item.Name</span> #Html.TextBox("Name_"+(int)item.CustID,(string)item.Name,new{#style="display:none"})</span>),
grid.Column(header: "Address",format: #<span> <span id="spanAddress_#item.CustID">#item.Address</span> #Html.TextBox("Address_"+(int)item.CustID,(string)item.Address,new{#style="display:none"})</span>),
grid.Column(header: "Contact No",format: #<span> <span id="spanContactNo_#item.CustID">#item.ContactNo</span> #Html.TextBox("ContactNo_"+(int)item.CustID,(string)item.ContactNo,new{#style="display:none"})</span>),
grid.Column(header: "Action",format:#<text>
Edit
Update
Cancel
Delete
Details
#Ajax.ActionLink("Ajax Link","AjaxView",new{Id=#item.CustID},new AjaxOptions { HttpMethod="GET",UpdateTargetId="results",
InsertionMode= InsertionMode.Replace, OnSuccess="openPopup"})
<div id="dialog-detail" style="display: none">
</div>
</text>)
})
<div class="dialog"></div>
<div class="results" style="display:none;"></div>
I just get the error when I try to open the dialog box in above code. I can find Uncaught error. Might be because of the jQuery is not in order rest all it is fine. Can anyone put the above in order. Many thanks
You have one obvious issue that may cause problems. Your HTML has a div with class="results", but your selector says #results (i.e. find an element with id="results")
You could change the selector to .results (as #VeldMuijz suggested in comment), but you also have an Ajax ActionLink which requires an id as it specifies UpdateTargetId="results"
Instead add the id to your results div.
e.g. change this:
<div class="results" style="display:none;"></div>
to this:
<div id="results" style="display:none;"></div>
I also recommend with MVC projects that you put your JS code in separate JS files. Visual Studio can't debug both Razor and Javascript in the same view, but it can if the script is in its own file.