I have a javascript function that extracts data from a database, puts it into an html table, and puts that table into an HTML page via a document.getElementById command. Everything works fine except when I load the HTML page, the data is not in the table. I am using the innerHTML property to put the table on the page. My question is, is this a valid way of populating a table to an HTML page? I have posted the relevant code below.
<div class="content mt-3">
<div class="animated fadeIn">
<div class="row">
<div class="col-md-12">
<div class="card">
<div class="card-header">
<strong class="card-title">Data Table</strong>
</div>
<div class="card-body">
<table id="results-data-table" class="table table-striped table-bordered">
<!-- I am trying to put the html here from javascript
</table>
</div>
</div>
</div>
</div>
</div><!-- .animated -->
</div><!-- .content -->
<script src="../controllers/query.js">getData()</script>
<script src="assets/js/vendor/jquery-2.1.4.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.3/umd/popper.min.js"></script>
<script src="assets/js/plugins.js"></script>
<script src="assets/js/main.js"></script>
Javascript:
function getData() {
var sql = require("mssql");
var dbConfig={
server:"server",
database: "db",
user:"user",
password: "pw"
}
var conn = new sql.Connection(dbConfig);
var req = new sql.Request(conn);
conn.connect(function (err){
if (err) {
console.log(err);
return;
}
req.query("SELECT * FROM table",resultsCallback)
conn.close();
});
}
function resultsCallback (err, recordset) {
var tableify = require('tableify');
if (err) {
console.log(err);
}
else {
var html = tableify(recordset);
html = html.replace('<table>','');
html = html.replace('</table>','');
document.getElementById("results-data-table").innerHTML=html;
}
};
I can't comment to posts yet but i think you have a typo at the end of the select:
req.query("SELECT * FROM table,resultsCallback)
it should be:
req.query("SELECT * FROM table",resultsCallback)
Based on the statements you’ve written to strip out the table tags in the html variable, it looks as though that html variable is of type string. I ran some tests on the npm module you're using 'Tableify', and it's primary method does not return the elements in the form of DOM nodes. Therefore, you can't just inject the elements using .innerHTML in string form. That's mainly because the DOM expects the thing you're setting to the innerHTML isn't going to be other DOM nodes. JS expects you to use appendChild, or others means, to insert nodes as children of other DOM nodes.
Doing the few lines below should get you what you want. Firstly, don't strip out the table tag like you're doing, or the node will become invalid. Then run a createContextualFragment on the html variable. The result will be a document fragment, of which then you can run a querySelector on it to retrieve the first element, usually a tbody element, and then finally do an appendChild of that to your already existing table... for example
// create a DOM fragment from the string
var frag = document.createRange().createContextualFragment(html);
//get the first element from inside the table. This is usually a tbody, but you might want to make sure your Tableify is generating a tbody in yours.
var tableBody = frag.querySelector('tbody');
// append that node to the table DOM element
document.querySelector("#results-data-table").appendChild(tableBody);
Related
Each time a new message is sent, it is automatically displayed for each user. The message consists of the message, a timestamp, and the sender's profile picture. Using the HTML template, the message and timestamp displays but not the image.
HTML
<!--template for javascript incoming-->
<template id="incoming_template">
<div class="incoming_msg_img" data-template="temp_img">
</div>
<div class="received_msg">
<div class="received_withd_msg" aria-describedby="name">
<small id="name" data-template="sender">User</small>
<p data-template="temp_message"></p>
<span class="time_date" data-template="temp_time"></span></div>
</div>
</template>
JavaScript
$(function () {
// Get template
var template = $("#incoming_template").html();
var template_dom = $('<div/>').append(template);
// Create a new row from the template
var $row = $(template);
var img = "<img src=../static/avatars/beard.png>";
// Add data to the row
$row.find("p[data-template='temp_message']").text(data.msg);
$row.find("span[data-template='temp_time']").text(data.timestamp);
$row.find("small[data-template='sender']").text(data.sender);
$row.find("div[data-template='temp_img']").html(img);
// Add the row to the table
$("#newmsg").append($row);
updateScroll();
});
Currently, you are wrapping some HTML string in a jQuery object. You need to temporarily create a DOM object out of your template HTML so that the jquery find function can properly find the elements inside a DOM tree. See revisions below:
// Get template
var template = $("#incoming_template").html();
// Add this line to your code
var template_dom = $('<div/>').append(template);
// Create a new row from the template
var $row = $(template_dom);
Then change this line:
$row.find("div[data-template='temp_img']").text(img);
To this:
$row.find("div[data-template='temp_img']").html(img);
Since you are appending a markup and not some text.
Read more here: What is the difference between jQuery: text() and html() ?
I'v got a question about LiveFilter. Or how to make it in another way without LiveFilter it is not so important. So iv got the page and got divs which are making from JSON file. And my filter is not working. So i got my page like this Before And when im start searching by the name or number it should be like this AfterShouldBe
So im using jquery.livefilter.js
<script> // Reading DATA from JSON
$(document).ready(function(){
$.getJSON("accounts.json", function(data){
$.each(data, function(key, value){
$("#main_list").append(
buildRow(value.name
,value.number
,value.city,value.amount,value.currency,value.rate)
);
});
});
});
</script>
<script>
$(function(){
$('#livefilter-list').liveFilter('#livefilter-input', 'li', {
filterChildSelector: 'a'
});
});
</script>
<script> // Making divs from JSON
function buildRow(a,b,c,d,e,f){
return '<ul id="livefilter-list"><div class="deposit-small-block first-block size-small-block tt" onclick="view(\'t1\'); return false">\
<div class="button_block">\
<div class="div-for-button">\
<input type="radio" name="on">\
</div>\
</div>\
<div class="deposit-form-block-name">\
<div class="deposit-form-block-name-first white-text"><name><li>'+a+'</li></name></div>\
<div class="deposit-form-block-name-second white-text"><number><li>'+b+'</li></number></div>\
<div class="deposit-form-block-name-third white-text"><city>'+c+'</city></div>\
</div>\
<div class="deposit-form-block-sum">\
<div class="deposit-form-block-sum-text white-text">\
<amount>'+d+'</amount><br><currency>'+e+'</currency>\
</div>\
</div>\
<div class="deposit-form-block-perc">\
<div class="deposit-form-block-sum-text white-text"><rate>'+f+'</rate></div>\
</div>\
</div>\
</ul>'
}
</script>
So could someone tell me where is the problem
And here is my rar with files (html, css, js, json)
Forget about liveFilter.js...
Your HTML is too complex for it.
I made a pretty small script for you.... Customized for your web page.
How it works:
On the input event, hide all rows.
Then search the inputted value within <name>, <number> and <city> content... For each rows, using the JavaScript method .indexOf().
If the search term is found, this row must be displayed.
// Custom search
$("#livefilter-input").on("input",function(){
//console.log("Searching...");
// Set ALL rows to display none.
$(".deposit-small-block").css("display","none");
// Loop to check the content of all custom tags: <name> <number> and <city>
$(".tt").find(".deposit-form-block-name .white-text").children().each(function(){
// If a matching text is found within name, account # or city
if( $(this).html().indexOf( $("#livefilter-input").val() ) != -1 ){
//console.log("FOUND a match!");
// Set this row to display block.
$(this).closest(".deposit-small-block").css("display","block");
}
});
});
Place it inside the document ready wrapper, just below the $.getJSON function.
Live link!
EDIT:
For case insensitive search:
Only one line to change:
if( $(this).html().toLowerCase().indexOf( $("#livefilter-input").val().toLowerCase() ) != -1 ){
Using purejs, i want to create dynamic id to each rendering element.
In this code i need to set id for each a tag. This 'a' tag will create depends on the jsonData.
<!-- HTML template -->
<div id="template" class="template">
Hello <a></a>
</div>
<!-- result place -->
<div id="display" class="result"></div>
<script>
var jsonData = {data:[{who:'Google!',site:'http://www.google.com/'},{who:'Yahoo!',site:'http://www.yahoo.com/'}]};
//select the template
$('#template')
//map the HTML with the JSON data
.directives({
'div a':{
'd<-data':{
'.':'d.who',
'#href':'d.site'
}
}
})
//generate the new HTML
.render(jsonData)
//place the result in the DOM, using any jQuery command
.appendTo('#display');
</script>
To set dynamic id use ".pos" tag. This ".pos" will having the position of the data in an array.
//select the template
$('#template')
//map the HTML with the JSON data
.directives({
'div a':{
'd<-data':{
'#id':'xyz_#{d.pos}',
'.':'d.who',
'#href':'d.site'
}
}
})
//generate the new HTML
.render(jsonData)
//place the result in the DOM, using any jQuery command
.appendTo('#display');
I have an array that contains a bunch of Widget Ids[s1,s2,s3...etc]. This array can vary as in sometimes it can have 5 ids and other times it can have 2 ids etc.So basically as i am looping through this array I want to be able to create pages dynamically for every id in the array.
This is the basic format of the page that i want to be able to create dynamically for every id.
<!--id should eqqual id# like s1,s2,s3,etc -->
<div data-role="page" id="page5">
<div data-role="header" data-position="fixed">
<a data-iconpos="notext" href="#" data-role="button" data-icon="flat-menu"></a>
<h1>BasketBall Fanatico</h1>
<a data-iconpos="notext" href ="#page2" data-role="button" data-icon="home" title="Home">Home</a>
</div>
<div data-role="content">
<ul data-role="listview" data-inset="true">
<li data-role="list-divider" data-theme="b">Raptors Score</li>
<li><h2>0</h2></li>
</ul>
</div>
</div>
This is the loop where i am iterating through the ids in the array and trying to add pages dynamically.This is what i have attempted in order to achieve my result but have failed.
for(var i=0; i<widgetId.length; i++){
var makePage = $("<div data-role='page' id="+widgetId[i]+">
<div data-role='header' data-position='fixed'><a data-iconpos='notext' href='#' data-role='button' data-icon='flat-menu'></a>
<h1>BasketBall Fanatico</h1><a data-iconpos='notext' href='#page2' data-role='button' data-icon='home' title='Home'>Home</a></div>
<div data-role='content'><ul data-role='listview'data-insert='true'><li data-role='list-divider' data-theme='b'>Raptors Score</li>
<li><h2>0</h2></li></ul></div></div>");
makePage.appendTo($mobile.pageContainer);
}
I am using the chrome console window and its telling me: Uncaught SyntaxError: Unexpected token< . However upon looking at my code i don't see where the error could be. Also is my approach correct for creating pages dynamically? All answers are highly appreciated .
I am new to jquery and web dev in general so apologize in advance.
I had to dynamically add products to an auction page and I used the following code. The issue was that I didn't know exactly how many products I was going to display on the page.
/* takes element type and all options for element returns html string for the element
* Arg1 is the type of element to create
* Options is an array/list of key-value pairs. The even numbered objects in the array
* will represent the attribute name, the odd elements will be the value of the attribute*/
function addElement(ELEMENT, options)
{
var element = document.createElement(ELEMENT); //create the element
var i = 0;//iterate through the array and set each element
while(i < options.length)
element.setAttribute(options[i++], options[i++]);
return element;
}
Then in my index file I do this 'fullProductList' is a div that will hold all divs containing products:
//get the html for each item and write it to the page
for( var i = 0; i < productList.length; i++)
$("#fullProductList").append(getProductHTML(productList[i], i));
Here is getProductHTML:
/* creates a parent div for each product that will be displayed on the page
* a picture is displayed in the parent div then a child div is created
* in order to display product info and a bid button which happens in another function*/
function getProductHTML(prod, id)
{//create the parent div
var html = document.createElement('div');
html.className = 'singleProduct';
html.id = id;
//append the picture to the parent div
html.appendChild(addElement('img', ['SRC', prod.pic, 'ALT', prod.name, "height", "400px", 'class', 'pic']));
//create div for product title
var title = document.createElement('div');
title.className = 'prodTitle';
title.innerHTML = '<b>'+prod.name + "<b><BR>" ;
html.appendChild(title);
html.appendChild(writeProductInfo(prod));//this creates another child div for the product data
return html;
}
Instead of numbering the div's myself I used an ID from the DB which was provided with each product. I didn't include the code for writeProductInfo because I think with this you should be able to see how I made it work. I know that your situation will be different from the situation I encountered but I hope this helps.
I have figured out the error after several trial and error. It seems that the cause of the error was that i had the page structure on different lines . so for instance if everything is on the same line it works fine like this.
for(var i=0; i<widgetId.length; i++){
var makePage = $("<div data-role='page' id="+widgetId[i]+"><div data-role='header' data-position='fixed'><a data-iconpos='notext' href='#' data-role='button'data-icon='flat-menu'></a> <h1>BasketBall Fanatico</h1><a data-iconpos='notext' href='#page2' data-role='button' data-icon='home' title='Home'>Home</a></div> <div data-role='content'><ul data-role='listview'data-insert='true'><li data-role='list-divider' data-theme='b'>Raptors Score</li><li><h2>0</h2></li></ul></div></div>");
makePage.appendTo($.mobile.pageContainer);
}
I don't know what it is but when everything is in on line it seems to be working fine. I hope this can help someone in the future with a similar error or someone who is looking to create pages dynamically in general.
On my web page, I output jQuery for each record that is rendered on the page like this:
if ($.trim($('#attachment<%# Eval("Id")%> .content').html()) == '') {
$('#attachmentClick<%# Eval("Id")%>').hide();
}
Notice there is server binding on the element ID to make sure each record has the jQuery processed. Is there a way to do this only once on the page by embedding the conditional statement, such as "for all $(this.ID + ' .attachmentsClick'), hide only if $('.attachments.content').html() trimmed is blank"?
You could use jQuery's filter function to reduce the set of potential elements to those with empty content, and then hide them:
$('.attachmentsClick').filter(function(){
return $.trim($(this).find('.content').html()) == '';
}).hide();
This assumes that you give the class of "attachmentsClick" to all of your row elements. It does not need the ID of the row elements. Just run this after your content has loaded, and it will hide all elements with a class of "attachmentsClick" that have a child with a class of "content" which is empty when trimmed.
Your HTML might look something like:
<div class="attachmentsClick"><!-- this one will be hidden -->
<div class="content"></div>
</div>
<div class="attachmentsClick"><!-- this one will be hidden too -->
<div class="content"> </div>
</div>
<div class="attachmentsClick"><!-- this one will NOT be hidden -->
<div class="content"><p>some content<p></div>
</div>
You can use .each(). .someCommonClass should be on each one that has the ID.
$('.someCommonClass').each(function(i, e) {
var $e = $(e);
if ($.trim($('.content', $e).html()) == '')
$e.hide();
});