How to get string representation of dynamically created element - javascript

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>';

Related

Finding and replacing html tags conditionally from an html string

I have access to an html string in which I want to search for a specific set of values. So lets say I want to match something from an array...
var array1 = [value1, value2, value3]
If I find value1 in the html string, i want to add a highlight class to that value so it gets highlighted.
var str = htmlString
var res = str.replace('<thead>','<thead class="highlight">');
htmlString = res
Using this i can highlight all the theads, but how could I write it so that I only highlight the theads that contain one of those array values inside of it?
Here's a solution for browser that parses the HTML string into a DOM element, query the DOM tree and manipulate the classList of each selected element, then returns the HTML as a string.
function addClassToElementsByTagName(html, tagName, className) {
var tempElement = document.createElement('div');
tempElement.innerHTML = html;
var elements = tempElement.querySelectorAll(tagName);
elements.forEach(function(element) {
element.classList.add(className);
});
return tempElement.innerHTML;
}
var htmlString = '<table>\n\t<thead>\n\t<tr>\n\t\t<th>Column 1</th>\n\t\t<th>Column 2</th>\n\t\t<th>Column 3</th>\n\t</tr>\n\t</thead>\n</table>';
var result = addClassToElementsByTagName(htmlString, 'thead', 'highlight');
console.log(result);
Gotchas
Keep in mind that element.querySelectorAll() and element.classList.add() are not universally supported. Check out caniuse.com for information regarding each feature.
Also, this is completely dependent on how the browser parses your HTML. If the HTML fails to parse or parses incorrectly, you will experience problems. The .innerHTML property also makes no guarantee that the whitespace provided in the original string will be preserved in the result.

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

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

Is there a way to convert HTML into normal text without actually write it to a selector with Jquery?

I understand so far that in Jquery, with html() function, we can convert HTML into text, for example,
$("#myDiv").html(result);
converts "result" (which is the html code) into normal text and display it in myDiv.
Now, my question is, is there a way I can simply convert the html and put it into a variable?
for example:
var temp;
temp = html(result);
something like this, of course this does not work, but how can I put the converted into a variable without write it to the screen? Since I'm checking the converted in a loop, thought it's quite and waste of resource if keep writing it to the screen for every single loop.
Edit:
Sorry for the confusion, for example, if result is " <p>abc</p> " then $(#mydiv).html(result) makes mydiv display "abc", which "converts" html into normal text by removing the <p> tags. So how can I put "abc" into a variable without doing something like var temp=$(#mydiv).text()?
Here is no-jQuery solution:
function htmlToText(html) {
var temp = document.createElement('div');
temp.innerHTML = html;
return temp.textContent; // Or return temp.innerText if you need to return only visible text. It's slower.
}
Works great in IE ≥9.
No, the html method doesn't turn HTML code into text, it turns HTML code into DOM elements. The browser will parse the HTML code and create elements from it.
You don't have to put the HTML code into the page to have it parsed into elements, you can do that in an independent element:
var d = $('<div>').html(result);
Now you have a jQuery object that contains a div element that has the elements from the parsed HTML code as children. Or:
var d = $(result);
Now you have a jQuery object that contains the elements from the parsed HTML code.
You could simply strip all HTML tags:
var text = html.replace(/(<([^>]+)>)/g, "");
Why not use .text()
$("#myDiv").html($(result).text());
you can try:
var tmp = $("<div>").attr("style","display:none");
var html_text = tmp.html(result).text();
tmp.remove();
But the way with modifying string with regular expression is simpler, because it doesn't use DOM traversal.
You may replace html to text string with regexp like in answer of user Crozin.
P.S.
Also you may like the way when <br> is replacing with newline-symbols:
var text = html.replace(/<\s*br[^>]?>/,'\n')
.replace(/(<([^>]+)>)/g, "");
var temp = $(your_selector).html();
the variable temp is a string containing the HTML
$("#myDiv").html(result); is not formatting text into html code. You can use .html() to do a couple of things.
if you say $("#myDiv").html(); where you are not passing in parameters to the `html()' function then you are "GETTING" the html that is currently in that div element.
so you could say,
var whatsInThisDiv = $("#myDiv").html();
console.log(whatsInThisDiv); //will print whatever is nested inside of <div id="myDiv"></div>
if you pass in a parameter with your .html() call you will be setting the html to what is stored inside the variable or string you pass. For instance
var htmlToReplaceCurrent = '<div id="childOfmyDiv">Hi! Im a child.</div>';
$("#myDiv").html(htmlToReplaceCurrent);
That will leave your dom looking like this...
<div id="myDiv">
<div id="childOfmyDiv">Hi! Im a child.</div>
</div>
Easiest, safe solution - use Dom Parser
For more advanced usage - I suggest you try Dompurify
It's cross-browser (and supports Node js). only 19kb gziped
Here is a fiddle I've created that converts HTML to text
const dirty = "Hello <script>in script<\/script> <b>world</b><p> Many other <br/>tags are stripped</p>";
const config = { ALLOWED_TAGS: [''], KEEP_CONTENT: true, USE_PROFILES: { html: true } };
// Clean HTML string and write into the div
const clean = DOMPurify.sanitize(dirty, config);
document.getElementById('sanitized').innerText = clean;
Input: Hello <script>in script<\/script> <b>world</b><p> Many other <br/>tags are stripped</p>
Output: Hello world Many other tags are stripped
Using the dom has several disadvantages. The one not mentioned in the other answers: Media will be loaded, causing network traffic.
I recommend using a regular expression to remove the tags after replacing certain tags like br, p, ol, ul, and headers into \n newlines.

Two tables from one String variable of HTML

An AJAX query returns an HTML string that has 2 tables.
I want to put table1 into div1 and table2 into div2
If the HTML representing both tables (they're sequential, not nested or anything funny like that) is stored in variable twoTables, how can I use jQuery selectors (or any other method, although I am trying to avoid direct string manipulation) to split up the variable?
edit: data looks like
<table id="table1"> ... </table><table id="table2"> ... </table>
You can split the two tables into an array. Check out the following:
var s = "<table>Dude!</table><table>What?</table>";
var a = s.match(/<table>.*?<\/table>/gi);
alert(a);
So table one will be in a[0], and table two in a[1].
var $tables = $(twoTables);
$('#div1').append( $tables[0] );
$('#div2').append( $tables[1] );
Example: http://jsfiddle.net/VhAzV/
Since twoTables represents an HTML string of 2 sequential tables, just send the string to a jQuery object, then select each table DOM element by its zero based index.
Or you could use .eq() to get the table wrapped in a jQuery object.
var $tables = $(twoTables);
$tables.eq(0).appendTo('#div1');
$tables.eq(1).appendTo('#div2');
Here's a no jQuery version that still uses the browser's native HTML parser:
Example: http://jsfiddle.net/patrick_dw/VhAzV/2/
var twoTables = '<table><tr><td>table one</td></tr></table><table><tr><td>table two</td></tr></table>';
var $tables = document.createElement('div');
$tables.innerHTML = twoTables;
document.getElementById('div1').appendChild($tables.firstChild);
document.getElementById('div2').appendChild($tables.firstChild);
EDIT: Made it truly no-jQuery in the DOM insertion.
As per http://api.jquery.com/load/
$('#result').load('ajax/test.html #container');
You can do this twice for two tables.
If you have a string that looks something like this:
var foo = "<table><tr><td>1</td></tr></table><table><tr><td>2</td></tr></table>";
First make it a jQuery object:
foo = $(foo);
Then you can get each table and insert them wherever you'd like:
$("#div1").append(foo[0]); // First table
$("#div2").append(foo[1]); // Second table
This might be ugly but it's the first thing that comes to my mind, hopefully others will find a more elegant solution:
var tableEnd = '</table>';
var arr = twoTables.split(tableEnd);
var t1 = arr[0].concat(tableEnd), t2 = arr[1].concat(tableEnd);
div1.innerHTML = t1;
div2.innerHTML = t2;
bonus: no jQuery overhead! :)

Is any complete example for merge or split table cells in javascript?

I am working on a web project, one of the features include user can design a html table and allow user split or merge cells feel free, (I am using jQuery for my project). Can anyone help me?
I just found a jquery plugin to merge and split table cells.
Here is the link :
http://www.redips.net/javascript/table-td-merge-split/
I would use a small class to keep the attributes of the table in question and then as required rewrite the InnerHTML of it. While it sounds simple to adjust the colspan attribute of a td element this does not allow you to add columns or rows. it only allows you to extend the column or row you have.
I'm not sure what you need help with. You need to set or remove the colspan attribute on a TD element.
The TinyMCE table plugin does exactly what you need. In case you don't know, it's a full-featured wysiwyg html/text editor which outputs html code.
It's open source and you can take a look at it:
http://www.tinymce.com/download/download.php
I am in need of the same functionality and was hoping to be able to scrap it from there, maybe implement a jQuery version, but unfortunately the code is too complex for me.
There are other similar wysiwyg editors but, to my knowledge, none of them offers the same functionality joining or splitting cells, adding, deleting and resizing rows, and that all.
I've written the below to split multiple cells and to merge them together again, it's basic but it works well enough for me. I've used a comma to separate the cell values, and so it knows where to split the data back into separate cells if needed...
Javascript:
function mergeCells(cells, separator) {
var data = [];
$.each(cells, function(i, item) {
data.push(item[0].innerHTML);
});
var result = $('<td/>', {
'html': data.join(separator)
});
return result;
}
function splitCell(cell, separator) {
var result = "";
var data = (cell[0].innerHTML).split(separator);
$.each(data, function(i, item) {
result = result + "<td>{0}</td>".format(item);
});
return result;
}
Usage:
var merged = $('table').find('td:eq(1)');
var splitHtml = splitCell(merged, ", ");
var cell1 = $('table').find('td:eq(1)');
var cell2 = $('table').find('td:eq(2)');
var merged = mergeCells({
1: cell1,
2: cell2
}, ", ");
$(cell1).replaceWith(merged);
$(cell2).remove();

Categories