How do I display the resuls of my ajax DB query? - javascript

I am querying my DB with some query which returns 2 fields. I'm just wondering what's the better/best way of displaying the search results.
in the old days, I would have been using string concatenation.
example:
var html="";
$.each(data, function () {
var html = html + "<div><span>" + this.field1 + "</span><br /><span>" + this.field2 + "</span><br /></div>";
});
I'm hoping things would've have improved and something better like jquery can be used? I did search the net but can't find anything useful.
Thanks a lot.

String concatenation is still quite popular. But with jQuery you can create elements using object syntax:
$.each(data, function() {
var field1 = $("<span>", { text: this.field1 });
var field2 = $("<span>", { text: this.field2 });
$("<div>").append(field1, "<br>", field2).appendTo("#results");
});
However, it's quite possible that this will be slower than the concatenation version. This makes lots of calls to DOM functions to create elements and append them to the DOM, one at a time. String concatenation, on the other hand, is relatively efficient. If you do all the concatenation, and then finally do $("#results").html(html) at the end, it will make use of the browser's internal HTML parser to construct all the elements in one fell swoop. This is optimized very heavily in all browsers.

You could use the append function in JQuery.
$(document).ready(function () {
var div = $("<div></div>");
var span1 = $("<span></span>");
span1.append("value 1");
var span2 = $("<span></span>");
span2.append("value 2");
div.append(span1).append("<br>").append(span2).append("<br>");
$("body").append(div);
});
Replace the text values with the values you are returning from your query.
See my JSFiddle

Related

Javascript: How to count number of instances of a phrase in a larger string?

I need to create a javacript function that downloads the html source code of a web page and returns the number of times a CSS class is mentioned.
var str = document.body.innerHTML;
function getFrequency(str) {
var freq = {};
for (var i=0; i<string.length;i++) {
var css_class = "ENTER CLASS HERE";
if (freq[css_class]) {
freq[css_class]++;
} else {
freq[css_class] = 1;
}
}
return freq;
};
What am I doing wrong here?
What am I doing wrong here?
I hate to say it, but fundamentally... everything. Getting information about HTML does not involve string functions or regular expressions. HTML cannot be dealt with this way, its rules are way too complex.
HTML needs to be parsed by an HTML parser.
In the browser there are two possible scenarios:
If you work with the current document (as you seem to do), then the parsing is already done by the browser.
Counting the number of times a CSS class is used actually is the same thing as finding out how many HTML elements have that class. And that is easily done via document.querySelectorAll() and a CSS selector.
var elements = document.querySelectorAll(".my-css-class");
alert("There are " + elements.length + " occurrences of the class.");
If you have an HTML string that you loaded from somewhere, you need to parse it first. In JavaScript you can make the browser parse the HTML for you very easily:
var html = '<div class="my-css-class">some random HTML</div>';
var div = document.createElement("div");
div.innerHTML = html; // parsing happens here
Now you can employ the same strategy as above, only with div as your selector context:
var elements = div.querySelectorAll(".my-css-class");
alert("There are " + elements.length + " occurrences of the class.");

How to get string representation of dynamically created element

So I have some javascript code that creates a table row by generating a string and appending it to the table. Something like this:
var str = '<tr><td>Column</td><!--More columns--></tr>';
$('#my-table').append(str);
There is one element (an input) in the row that has a LOT of attributes. This is hard to read as a long string so I want to create this one particular element a different way - using $() and passing in attributes as an object as documented here - and then concatenating it with the string above. So I tried to do something like this:
var el = $('<input>', {
type: 'text',
name: 'some_name'
});
var str = '<tr><td>test</td><td>'+el.html()+'</td></tr>';
$('#my-table').append(str);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table id="my-table">
</table>
This should (I thought) create a textbox as the second column in the table but it doesn't work. I just get a empty cell and no errors. What am I doing wrong? Or what should I do?
var $input = $('<input>', {
type: 'text',
name: 'some_name',
/* ... more attributes ... */
});
var $tr = $("<tr>").appendTo('#my-table');
var $td = $("<td>").append($input).appendTo($tr);
// possibly do other things with $input, $tr, and $td
That being said, you really should not build complex HTML with jQuery. It's cumbersome, leads to unreadable and ultimately buggy, hard-to-maintain code. (Even more than that, you really should not build HTML by concatenating strings.)
Build a data structure (an array of objects) and then let an HTML templating library do the work. There are quite a few mature libraries to choose from, handlebars.js being a prominent one. It will pay in the form of much cleaner Javascript code to use one of them.
jQuery html() is the innerHTML not the outerHTML. You want the latter.
var el = $('<input>', { type: 'text', name: 'some_name' });
var str = '<tr><td>test</td><td>'+ el[0].outerHTML +'</td></tr>';
$('#my-table').append(str);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<table id="my-table"></table>
you want the Value from input, not the inner html. Try this:
var str = '<tr><td>test</td><td>'+el.val()+'</td></tr>';

Sanitizing user input when creating HTML elements

I am trying to make a to-do application in pure HTML5 and Javascript and I have come across the problem of sanitizing the input.
For eg: If user enters <script>alert("XSS")</script>, the code is executed on the page.
Code for adding an element is:
if ($('#TextArea').val() !== "") {
var taskID = new Date().getTime();
var taskMessage = $('#textArea').val();
localStorage.setItem(taskID, taskMessage);
}
while the code for displaying the elements is:
var i = 0;
for (i = localStorage.length; i != 0; i--) {
var taskID = localStorage.key(i - 1);
$('#task').append("<li id='" + taskID + "'>" + localStorage.getItem(taskID) + "</li>");
}
Is there any way to sanitize the data using only HTML5 and Javascript properties?
As with any and all XSS prevention: Don't build HTML from strings, especially not when those strings contain user-supplied values.
jQuery has a convenient facility to build elements safely - you can pass in an object with properties:
$("<li>", {
id: taskID,
text: localStorage.getItem(taskID)
}).appendTo('#task');
In fact, I recommend that you absolutely never use string concatenation to build HTML. For more complex situations than the above, use a well-tested HTML templating library like Mustache or Handlebars.

How does JQuery empty() method work?

I know that the empty method removes all children in the DOM element.
In this example however, why does removing the empty method result in duplicate entries:
and putting it in results in a normal page:
var renderNotesList = function()
{
var dummyNotesCount = 10, note, i;
var view = $(notesListSelector);
view.empty();
var ul = $("<ul id =\"notes-list\" data-role=\"listview\"></ul>").appendTo(view);
for (i=0; i<dummyNotesCount; i++)
{
$("<li>"+ "" + "<div>Note title " + i + "</div>" + "<div class=\"list-item-narrative\">Note Narrative " + i + "</div>" + "" + "</li>").appendTo(ul);
}
ul.listview();
};
I don't know why empty() doesn't work but I found this
... so until this is sorted everyone should just use:
el.children().remove(); instead of el.empty();
( jQuery.empty() does not destroy UI widgets, whereas jQuery.remove() does (using UI 1.8.4) )
Without seeing how your JavaScript is being used in your page, I suspect that you must be calling the renderNotesList() function twice and thus generating to unordered lists.
When you use the .empty() method, you are removing the first ul list, so you only see one instance. Without the call to .empty(), you retain both.
However, I can't say where or how this is happening in you web page without seeing more, but at least you now have some idea of what to look for.
Demo Fiddle
I built a demo using your JavaScript, but I was sort of guessing as to how you are using it.
Fiddle: http://jsfiddle.net/audetwebdesign/UVymE/
Footnote
It occurred to me that the function ul.listview() may actually be appending a second copy of the ul to the DOM. You need to check the code or post it for further review.

Append to a webpage in javascript

What I want to do is that: a webpage with continuously updating content. (In my case is updating every 2s) New content is appended to the old one instead of overwriting.
Here is the code I have:
var msg_list = new Array(
"<message>Hello, Clare</message>", "<message>Hello,Lily</message>",
"<message>Hello, Kevin</message>", "<message>Hello, Bill</message>"
);
var number = 0;
function send_msg()
{
document.write(number + " " + msg_list[number%4]+'<br/>');
number = number + 1;
}
var my_interval = setInterval('send_msg()', 2000);
However, in both IE and Firefox, only one line is printed out, and the page will not be updated anymore. Interestingly in Chrome, the lines are being printed out continuously, which is what I am looking for.
I know that document.write() is called when the page is loaded according to this link. So it's definitely not the way to update the webpage continuously. What will be the best way to achieve what I want to do?
Totally newbie in Javascript. Thank you.
Lily
I would have a div or some other container, like this:
<div id="msgDiv"></div>
Then write to it like using .innerHTML, like this:
var msg_list = new Array(
"<message>Hello, Clare</message>", "<message>Hello,Lily</message>",
"<message>Hello, Kevin</message>", "<message>Hello, Bill</message>"
);
var number = 0;
function send_msg()
{
document.getElementById("msgDiv").innerHTML += number + " " + msg_list[number%4]+'<br/>';
number++;
}
var my_interval = setInterval(send_msg, 2000);
You can see a working example of this here
You can append to the innerHTML property:
var number = 0;
function send_msg()
{
document.getElementById('console').innerHTML += (number + " " + msg_list[number%4]+'<br/>');
number = number + 1;
}
This code will append the message to an element with an id of console, such as
<div id="console"></div>
By the way, it is bad practice to call setInterval with a string.
Instead, pass the function itself, like this:
var my_interval = setInterval(send_msg, 2000);
I would start by looking at the jQuery library. This will save you a lot of pain.
What you want to do is keep inserted lines into a table, using eg:
$('table tbody').append('<tr><td>some value</td></tr>');
This would be an excellent opportunity for you to learn a little DOM programming.
Using the DOM to update the page should result in less overhead than simply concatenating more HTML into it. Find the node you want to put the updates into, and do an appendChild on each subsequent addition.
The answers to this question may be helpful: What's a simple way to web-ify my command-line daemon?

Categories