Populating HTML table with Javascript and retaining CSS style - javascript

So far I have the code below working. My only problem is the associated styles of the HTML table are not being applied when the table is inserted into its parent div. What is the best way to resolve this? I am using jQuery in tandem with jQuery mobile.
var tableBase = '<table data-role="table" id="score-table" style="margin-left: auto; margin-right: auto;" class="ui-responsive table-stroke ui-table ui-table-reflow"><thead><tr><th data-priority="1">Event</th><th data-priority="2">Score</th></tr></thead><tbody>';
function buildTable(data) {
var tableCopy = tableBase;
data.forEach(function(element, index, array) {
tableCopy = tableCopy + '<tr><td>' + element.event + '</td><td>'
+ element.points + '<td></tr>';
});
tableCopy = tableCopy + '</tbody></table>';
return tableCopy;
}
I then have have a #('#targetDiv').html(buildTable(myData)) that inserts the tables html into its div. Everything works except the styles are not applied. I am using the responsive/reflow table from jQuery mobile.

I think you have too rerun the plugin for the table after it's inserted to the DOM:
http://jquerymobile.com/demos/1.2.0-alpha.1/docs/pages/page-dynamic.html
// Pages are lazily enhanced. We call page() on the page
// element to make sure it is always enhanced before we
// attempt to enhance the listview markup we just injected.
// Subsequent calls to page() are ignored since a page/widget
// can only be enhanced once.
$page.page();
// Enhance the listview we just injected.
$content.find( ":jqmData(role=listview)" ).listview();

Related

Jquery add data to html before adding to DOM

I am building html on the fly need to add data before I add it to DOM. Since I am looping thru' lot of information, I would like to add the relevant data info along with the dom I am building instead of adding the html and then looping thru again to add the data.
result.forEach(function(record) {
html += '<div id ="' record.ID + '">test content </div> ';
//add data to above
});
I can do another loop here after adding it to DOM
$(body).append(html);
testresult.forEach(function(record) {
$("#" +record.ID).data(record);
});
Instead of concatenating strings to piece together your HTML, you may way to try something like this:
result.forEach(function(record) {
$('.selector').append(function () {
var $div = $('<div></div>');
$div.attr('id', record.testID).text('some text');
return $div;
});
});
This creates a new div jquery object for each item in result. You can use the record object to add attributes, data, text, etc to you object. It will be added the DOM when the callback passed into .append returns your new jquery DOM object.
Start trying to use jQuery to create your html elements so you can take fully advantage of jQuery and its plugins.
Ex:
var div = $("<div></div>") // create the element
.text("test content") // change the inner text
.attr("id", record.testID); // set the element id
div.appendTo("body");
You can check out [http://www.w3schools.com/jquery/] as a great source for learning jQuery.
You have quotes problem in the following line :
html += '<div id =record.testID' + '>test content </div> ';
________^______________________^___^_____________________^
You should fix that using double quotes because as it's now the string will be considered as '<div id =record.testID'.
html += '<div id="'+record.testID+'">test content </div>';
Or you could use separated definition :
$.each(result, function(index,record) {
var div = $('<div>test content</div>');
div.attr('id', record.testID);
div.data('test', record.testDATA);
$('body').append(div);
})
Hope this helps.
var result = [{testID: 1,testDATA: 'data 1'},{testID: 2,testDATA: 'data 2'},{testID: 3,testDATA: 'data 3'}]
var html='';
$.each(result, function(index,record) {
var div = $('<div>test content</div>');
div.attr('id', record.testID);
div.data('test', record.testDATA);
console.log(div.data('test'));
$('body').append(div);
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Accessing dynamically appended div elements in jQuery

I need a suggestion on below scenario.
I have an object of items and dynamically building a html object as follows:
$.each(item,function(k, iteminner) {
html += '<td><div id="outerdiv">' + iteminner.Name + '</div>';
html += '<div id="clickme"></div></td>';
});
A table is built in this format, where each box will contain a name and button in each td. When a user clicks on a button of a cell I want to show the name respectively.What is it that I am missing here?
$('#clickme").click() {
alert($("#outerdiv").iteminner.name);
}
Assuming that id is unique for both the divs, like id="outerdiv" + k , how do I access element present in second cell, when second div id="clickme" + 2 is clicked?
ID's they have to UNIQUE
// Use class instead
$.each(item, function(k, iteminner) {
html += '<td><div class="outerdiv">' + iteminner.Name + '</div>';
html += '<div class="clickme"></div></td>';
});
// You need to have event delegation here as a direct onclick wont be binded for the dynamically created .clickme
$(document).on("click", ".clickme", function(){
// You need to fetch the html of .outerdiv, so traverse to it first.
var _html = $(this).closest("td").find(".outerdiv").html();
alert(_html);
});
Firstly you are appending multiple elements with the same id to the DOM, which is invalid. You should change your HTML to use classes, like this:
$.each(item, function(k, iteminner) {
html += '<td><div class="outerdiv">' + iteminner.Name + '</div><div class="clickme"></div></td>';
});
From there you need to use a delegated event handler on the .clickme elements (as they are dynamically created after the DOM has loaded) to traverse the DOM and find their sibling .outerdiv. Try this:
$(document).on('click', '.clickme', function() {
var name = $(this).siblings('.outerdiv').text();
// do something with name here...
});
Note that I used document as the primary selector above. Ideally you should use the nearest static parent element - I would suggest you use the same selector you use to append the html variable to.

How to add footer row in a JTable

How to add footer row in Jtable,
i am using jTable 2.4.0 version js files and mvc 4.
Reference
Samir you can use the jquery.jtable.footer.js jtable extension from https://github.com/gbisheimer/jtable/tree/master/lib/extensions.
and configure you column for footer as shown below
Balance: {
title: 'Balance',
width: '70',
create:false,
edit: false,
display: function (data) {
return "£ " + data.record.Balance;
},
footer: function (data) {
var total = 0;
$.each(data.Records, function (index, record) {
total = Number(record.Balance);
});
return ("£"+total.toFixed(2));
}
}
Am using footer.js file
https://github.com/sheryever/jtable/blob/master/lib/extensions/jquery.jtable.footer.js
see more jtable extension
https://github.com/sheryever/jtable/tree/master/lib/extensions
I have implemented this for my jtable and came across an issue with hidden columns and the footer fields not lining up correctly. I specifically include the ID column as the first column within the table but set its visibility to hidden within the jtable definition.
I overcame this with a couple of minor edits (one to the class file and one to the base jtable file, I am not sure if this could be rolled into the class file to make it more complete and not be broken by base class updates)
modified class extension file:
_createFooterCellForField: function (fieldName, field) {
var style = "";
if(field.visibility == 'hidden') style = ' style="display: none;" ';
return $('<th class="jtable-column-footer" '+style+'>' +
'<div class="jtable-column-footer-container"><span class="jtable-column-footer-text"></span></div></th>');
}
This still puts a footer table cell into the DOM but hides it should the column be hidden from initial configuration
modified base class file:
changed:
.find('>thead >tr >th:nth-child(' + columnIndexInTable + '),>tbody >tr >td:nth-child(' + columnIndexInTable + ')')
to become:
.find('>thead >tr >th:nth-child(' + columnIndexInTable + '),>tbody >tr >td:nth-child(' + columnIndexInTable + '),>tfoot >tr >th:nth-child(' + columnIndexInTable + ')')
twice within the base class to hide/show the footer cell as well as the rest of the column if you select the column via the right click context menu.
These edits were done within the _changeColumnVisibilityInternal: function (columnName, visibility) { function around line 4500
Also in the example above your total formula is slightly incorrect, should be total += Number(record.Balance);

div.appendChild(div) equivalent in ExtJS4

I am transitioning my code to ExtJs4.1.1.
In one part of the code I have used Javascript's appendChild() method to add new div elements to an existing div container.
I want this to be done in ExtJs now.
Existing code:
var container = document.getElementById('treeContainer');
var nodeDiv = document.createElement("div");
// nodeDiv related code... setting properties and attributes
nodeDiv.innerHTML = "<div class='NodeContent'>" + node.displayText + "</div>";
nodeDiv.className = "Node";
//... more such code...
//add div to the container
container.appendChild(nodeDiv);
This code works perfectly fine.
But now I am using an ExtJs Panel wherein I want to display the same content.
How do I do it?
I tried doing:
xtype: 'panel',
autoScroll: true,
border: 10,
bodyStyle:{"background-color":"white"},
height: Ext.getBody().getViewSize().height *0.80,
id: 'treeContainer'
Ext.getCmp('treeContainer').update(nodeDiv); //this didnt work
Ext.getCmp('treeContainer').addChildEls(nodeDiv); //no success
I get this output on firing the below command in debugger:
Ext.getElementById('treeContainer')
<div class=​"x-panel x-panel-default" style=​"height:​553.6px;​" id=​"treeContainer">​
[object HTMLDivElement]
​</div>​
Any help!?
The panel's update function expects a HTML string instead of a DOM object:
// using a HTML string
Ext.getCmp('treeContainer').update("<div class='NodeContent'>" + node.displayText + "</div>");
// using a DOM object
Ext.getCmp('treeContainer').update(nodeDiv.outerHTML);
Note, that using this function will always replace all existing HTML content in the panel.
If you really want to append HTML (i.e. preserve existing HTML content), you need to get a target element to append your HTML/DOM node to.
This could be the panel's default render target element:
var panel = Ext.getCmp('treeContainer'),
renderEl = panel.isContainer ? panel.layout.getRenderTarget() : panel.getTargetEl();
// using a DOM node
renderEl.appendChild(nodeDiv);
// using a HTML string
renderEl.insertHtml('beforeEnd', "<div class='NodeContent'>" + node.displayText + "</div>");
Or - as this may change depending on your panel's layout - you just create a containg element in your initial html config:
{
xtype: 'panel',
id: 'treeContainer',
html: '<div class="html-content"></div>'
}
and append your content there:
Ext.getCmp('treeContainer').getEl().down('.html-content').appendChild(nodeDiv);
In any of the latter two cases, you should update the panel's layout afterwards, as you changed it's content manually:
Ext.getCmp('treeContainer').updateLayout();

Add dynamic list items to dynamically created panel with a istview

I'am using jquery mobile 1.3.2 for my web project.
The following code creates a panel for all pages:
function injectPanelIntoAllPages(){
console.log("IncetPanel");
var panel = '<div data-role="panel" id="mypanel" data-position="left" data-display="push">' +
'<div><ul data-role="listview" id="history"></ul></div> </div>';
$(document).on('pagebeforecreate', '[data-role=page]', function () {
if ($(this).find('[data-role=panel]').length === 0) {
$('[data-role=header]').before(panel);
}
$(document).on('pagebeforeshow', '[data-role=page]', function () {
$(this).trigger('pagecreate');
});
});
}
Now i want to add (dynamically) list items to the listview in the panel, but it don't works.
For adding list items i use the following method:
function addToHistory(value) {
$("#history").append(
"<li id='history-element'>" + value + "</li>");
$("#history").listview("refresh");
}
What can i do to solve this issue?
Note that you're using same Id for both panel and listview. This isn't recommended, however, it still can work as long as you specify which element to target within active page.
Another note, you don't need to call any enhancement method once you append panels dynamically, since you append them on pagebeforecreate. They will be created/initialized by jQM on that event.
$(document).on('pagebeforecreate', function () {
if ($(this).find('[data-role=panel]').length === 0) {
$('[data-role=header]').before(panel);
}
});
To append elements into listview, you need to look for it into active page's. Otherwise, new elements will be added to first element with #history ID.
var listview = $.mobile.activePage.find("#history");
listview.append("elements").listview("refresh");
Demo

Categories