Search code examples
javascriptjqueryhtmlonkeyup

Fire onkeyup in generated table with contenteditable


I've got a small problem in my javascript which i am stuck on for a while now. What i did is :

  1. Create an empty table.
  2. Generate the tr/td tags and values inside the table(from JSON-object).

    for (var i = 0 ; i < myList.length ; i++) {
        var row$ = $('<tr/>');
        for (var colIndex = 0 ; colIndex < columns.length ; colIndex++) {
            var cellValue = myList[i][columns[colIndex]];
    
            if(colIndex == columns.indexOf("type")) 
            {
    
                var box$ = $('<td/>');
                if(cellValue == "Organisation")
                box$.addClass( "uk-badge uk-badge-danger" );
                else
                box$.addClass( "uk-badge uk-badge-primary" );
                box$.html(cellValue);
                row$.append(box$);
    
            } 
            else 
            { 
                var box$ = $('<td/>');
                box$.html(cellValue);
                box$.attr('contenteditable','true');
                box$.attr('onkeyup','updateJSON('+colIndex+','+i+')');
                row$.append(box$);
            }
    
    
        }
        $(selector).append(row$);
    
    }
    
  3. table looks fine:

td contenteditable="true" onkeyup="updateJSON(3,0)">Timmy/td>

The problem occurs when the table is generated and i edit a field. the 'onkeyup' does not 'fire' while it should. Replacing the 'onkeyup' with an 'onclick' works just fine. I have no clue why this does not work, can anybody help?

var myList = [
  {
    "id": 1,
    "name": "arnold"
  },
  {
    "id": 2,
    "name": "hans"
  },
  {
    "id": 3,
    "name": "jack"
  },
  {
    "id": 4,
    "name": "Peter"
  }];

	function loadDoc3() {
				$("#RelationDataTable tr").remove();
				buildHtmlTable('#RelationDataTable');
	}

	// Builds the HTML Table out of myList.
	function buildHtmlTable(selector) {
		var columns = addAllColumnHeaders(myList, selector);

		for (var i = 0 ; i < myList.length ; i++) {
			var row$ = $('<tr/>');
			for (var colIndex = 0 ; colIndex < columns.length ; colIndex++) {
				var cellValue = myList[i][columns[colIndex]];

				if(colIndex == columns.indexOf("type")) 
				{
					
					var box$ = $('<td/>');
					if(cellValue == "Organisation")
					box$.addClass( "uk-badge uk-badge-danger" );
					else
					box$.addClass( "uk-badge uk-badge-primary" );
					box$.html(cellValue);
					row$.append(box$);
					
				} 
				else 
				{ 
					var box$ = $('<td/>');
					box$.html(cellValue);
                    box$.attr('contenteditable','true');
					box$.attr('onkeyup','updateJSON('+colIndex+','+i+')');
					//box$.click(function() {
//  alert( "Handler for .keyup() called." );
//});
					row$.append(box$);
				}

				
			}
			$(selector).append(row$);
		
		}
	}
	var currentcolumns = [];


	// Adds a header row to the table and returns the set of columns.
	// Need to do union of keys from all records as some records may not contain
	// all records
	function addAllColumnHeaders(myList) {
		var columnSet = [];
		var headerTr$ = $('<tr/>');

		for (var i = 0 ; i < myList.length ; i++) {
			var rowHash = myList[i];
			for (var key in rowHash) {
				if ($.inArray(key, columnSet) == -1 && key != "id") {
					columnSet.push(key);
					headerTr$.append($('<th/>').html(key));
				}
			}
		}
		$("#RelationDataTable").append(headerTr$);
		currentcolumns = columnSet;
		return columnSet;
	}
	function updateJSON(xx,y)
	{
		var cellValue = myList[y][currentcolumns[xx]];
		alert(document.getElementById("RelationDataTable").rows[y+1].cells[xx].firstChild.nodeValue);
		myList[y][currentcolumns[xx]] = document.getElementById("RelationDataTable").rows[y+1].cells[xx].firstChild.nodeValue;
		x = 2;
	}
<head>
	<script src="//ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js"></script>
  </head>
<body>
<input id="searchname" type="text" name="InsertSearchname" onkeyup="loadDoc3()"><h2>Search Contact</h2>
<table id="RelationDataTable">
						<thead>
                            </thead>
                            <tbody>
                            </tbody>
						</table>
  </body>


Solution

  • contenteditable="true" should be set for your <td> elements, not on the <table>.

    Otherwise the td will not trigger an event.

    So add box$.attr('contenteditable','true'); in your loop.