How can insert code in createTextNode - javascript

Is there a way to insert HTML tag in 'createTextNod' or what else can I do
$.each(JSON.parse(results), function(i, field){
for(var i = 1; i < JSON.parse(results).length; i++) {
var newLi = document.createElement('li');
var textNode = document.createTextNode(field.fname + ' ' + field.lname + ((field.status == 1) ? '<span class="userChatNameOnline">online</span>' : ''));
newLi.appendChild(textNode);
var ul = document.getElementById('ulUsers');
ul.insertBefore(newLi, ul.childNodes[0]);
}
})

Issues
The following part of OP code is pretty awful:
$.each(JSON.parse(results), function(i, field){
for(var i = 1; i < JSON.parse(results).length; i++) {...
$.each() iterates through for each field in JSON which is OK. But you use another loop which is totally unnecessary since $.each() and for loop both iterate through arrays. Each of these loops is calling JSON.parse() on each iteration. Although no matter how bad this is, you'll probably never notice any lag unless you handle large amounts of data.
References
The following are links to what was used:
Template Literals
.insertAdjacentHTML()
Demo
var results = `[{"first":"Kaiser","last":"Soze","status":"1"},{"first":"Darth","last":"Vader","status":"0"},{"first":"Boba","last":"Fett","status":"0"},{"first":"Grim","last":"Reaper","status":"1"},{"first":"zer0","last":"0ne","status":"1"}]`;
var JSONData = JSON.parse(results);
var list = document.getElementById('users');
$.each(JSONData, function(idx, field) {
var name = `[${idx}]: ${field.first} ${field.last}`;
var status = `<b class='status' data-status='${field.status}'>${field.status === "1" ? 'Online' : 'Offline'}</b>`;
list.insertAdjacentHTML('beforeend', `<li class='userData'>${name} ${status}</li>`);
});
#users {
width: 50%;
list-style: none
}
.userData {
font: 400 16px/1.5 Consolas
}
.status {
float: right
}
[data-status='1'] {
color: green
}
[data-status='0'] {
color: red
}
<ul id='users'></ul>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

createTextNode is for creating a TextNode specifically, not inserting HTML. For the latter you can use innerHTML or insertAdjecentHtml

since you're using jQuery, you probably want to just create your nodes using $() and .html():
$.each(JSON.parse(results), function(i, field){
var ul = $('#ulUsers');
for (var i = 1; i < JSON.parse(results).length; i++) {
var li = $('<li></li>').html('<span>' + ... + '</span>');
ul.before(li);
}
}
If you want to streamline it, I suggest appending to a DocumentFragment and then appending the fragment's contents to #ulUsers in one go. jQuery encapsulates this if you pass an array of elements to be apppended (of course, if you want to give the dynamic effect of seeing the list grow as elements are added to the list, you wouldn't (need to) do this):
$.each(JSON.parse(results), function(i, field){
var ul = $('#ulUsers');
var li_array = [];
for (var i = 1; i < JSON.parse(results).length; i++) {
var li = $('<li></li>').html('<span>' + ... + '</span>');
li_array.push(li);
}
ul.before(li_array);
}

Related

Append string to specific div only once if same div is used throughout DOM

I'm working on building a portfolio site and I'm pulling content from a JSON file. It's working, but I'm having a hard time generating the content only one time. I'm creating a div with the project type's name, and then adding container and row inside to make it work with Bootstrap. Then, I'm going through the projects and pulling the data, and creating a new div inside row that's called port-card, and port-card will contain the data. It's working, but in my for loop I'm using jQuery's append and it's appending the data to EVERY single row, which means I'm adding the data twice (or however many rows there currently are) instead of just one time.
EDIT: Thanks to T.J. Crowder, I tried using .eq(n) and I've added a runnable snippet below. Now I'm trying to figure out how to keep the generated data in the first wordpress-plugins div rather than having the second iteration of the for loop add it to the second div.
var catList = ["WordPress Plugins", "Websites"];
var categories = [{cat: "WordPress Plugins", title: "Price Quote Plugin"}, {cat: "WordPress Plugins", title: "House Plan Search"}];
for (var i = 0; i < catList.length; i++) {
temp = catList[i];
temp = temp.replace(/\s+/g, '-').toLowerCase();
$('.projects').append('<div class="' + temp + '"><div class="container"><div class="row"></div></div></div>');
}
if ($('.wordpress-plugins')[0]) {
var rows = $(".row");
for (var i = 0; i < categories.length; i++){
var catNameTemp = categories[i].cat;
var projectTitle = categories[i].title;
if(catNameTemp == "WordPress Plugins"){
rows.eq(i).append('<div class="port-card"><h3>' + projectTitle + '</h3></div>');
}
}
}
.projects {
text-align: center;
margin-top: 5%;
}
.port-card {
background-color: #333;
width: 400px;
height: 800px;
}
h3 {
color: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="projects">
</div>
$('.row') will create a jQuery set with all elements with class row in it. If you want to access just a single element in that set, you can use .eq(n) to do so (n = the index, starting with 0).
So for instance, if you have as many rows as categories, you might do:
var rows = $(".row");
...before the loop, then rows.eq(i).append(...) within the loop.
Looking at the runnable snippet you added, you don't have a row-per-category, so the above wouldn't apply. See comments in the snippet:
var catList = ["WordPress Plugins", "Websites"];
var categories = [
{cat: "WordPress Plugins", title: "Price Quote Plugin"},
{cat: "WordPress Plugins", title: "House Plan Search"},
// Added this to show putting things in other category lists
{cat: "Websites", title: "Some Website"}
];
// A map of category names to the divs that represent them
var catDivs = Object.create(null);
// Look up the projects div once and reuse it
var projects = $(".projects");
for (var i = 0; i < catList.length; i++) {
var catName = catList[i];
var clsName = catName.replace(/\s+/g, '-').toLowerCase();
// Create and add the category div, remember it in the map
catDivs[catName] = $('<div class="' + clsName + '"><div class="container"><div class="row"></div></div></div>').appendTo(projects);
}
// Done with this
projects = null;
// Add categories to their container
for (var i = 0; i < categories.length; i++) {
var catDiv = catDivs[categories[i].cat];
if (catDiv) {
var projectTitle = categories[i].title;
catDiv.find(".row").append('<div class="port-card"><h3>' + projectTitle + '</h3></div>');
}
}
.projects {
text-align: center;
margin-top: 5%;
}
.port-card {
background-color: #333;
width: 400px;
height: 800px;
}
h3 {
color: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="projects">
</div>
Add a unique Id on the row that you want to append data in and then append data in that row only. Like shown below
for (var i = 0; i < catList.length; i++) {
temp = catList[i];
temp = temp.replace(/\s+/g, '-').toLowerCase(); //convert string to lower case and make spaces dashes to create class names
$('.projects').append('<div class="' + temp + '"><div class="container"><div class="row" id="uniqueId"></div></div></div>');
}
if ($('.wordpress-plugins')[0]) {
for (var i = 0; i < categories.length; i++){
var catNameTemp = categories[i].cat;
var projectTitle = categories[i].title;
if(catNameTemp == "WordPress Plugins"){
$('#uniqueId').append('<div class="port-card"><h3>' + projectTitle + '</h3></div>');
}
}
In this line of code $('.row').append('<div class="port-card"><h3>' + projectTitle + '</h3></div>'); notice how you wrote $('.row').append(.
This makes jQuery append your new div to the every instance of the class of "row".
What you need to do is be more specific about which row you want your new div to be appended to.

Making list from textarea value by new lines

This may be very easy to solve but my brain is dead for some reason I can't find out the right road to success :(
I have some text area where by pressing enter for each word or more words in one line I get an list item.
$(document).on('click','#addList', function(){
var lines = $('#list').val().split(/\n/);
var texts = []
for (var i=0; i < lines.length; i++) {
if (/\S/.test(lines[i])) {
texts.push($.trim(lines[i]));
}
}
var list = JSON.stringify(texts);
for(var e=0; e<list.length; e++){
var li = li+'<li class="c1_2v">'+list[e]+'</li>';
}
$('.content').append($('<ul>'+li+'</ul>'));
});
By doing this $.trim I am getting problem if I have more words in one line but it is useful if I have more empty new lines or spaces before first word.
Example:
<textarea>
this is
a
something
that
I want to add to new lists
</textarea>
By my code and first for loop I get something like: ['this','is','a','something','that','I','want','to','add','to','new','lists']
By second for loop I get into li tags every letter or character from [ to ] inside li tags
I don't understand regex I saw many websites but it is not getting into my head so even if you add it as more easier answer without explanation what is used for what I wouldn't know how it works..
And this is basically what I need to get in .content div:
<ul>
<li class="c1_2v">this is</li>
<li class="c1_2v">a</li>
<li class="c1_2v">something</li>
<li class="c1_2v">that</li>
<li class="c1_2v">I want to add to new lists</li>
</ul>
I will add snippet how it works till now:
$(document).on('click','#addList', function(){
var lines = $('#list').val().split(/\n/);
var texts = []
for (var i=0; i < lines.length; i++) {
if (/\S/.test(lines[i])) {
texts.push($.trim(lines[i]));
}
}
var list = JSON.stringify(texts);
for(var e=0; e<list.length; e++){
var li = li+'<li class="c1_2v">'+list[e]+'</li>';
}
$('.content').append($('<ul>'+li+'</ul>'));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="list"></textarea>
<button id="addList">Add</button>
<div class="content"></div>
And also there is something undefined Idk what :(
As #AlexKudryashev commented I used array as string not as array and if I add var li before for loop undefined will go away.
$(document).on('click', '#addList', function() {
var lines = $('#list').val().split(/\n/);
var texts = []
for (var i = 0; i < lines.length; i++) {
if (/\S/.test(lines[i])) {
texts.push($.trim(lines[i]));
}
}
//var list = JSON.stringify(texts);
var list = texts;
var li = "";
for (var e = 0; e < list.length; e++) {
li = li + '<li class="c1_2v">' + list[e] + '</li>';
}
$('.content').append($('<ul>' + li + '</ul>'));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea id="list"></textarea>
<button id="addList">Add</button>
<div class="content"></div>
JSON.stringify converts the value to JSON string. So you are looping every string instead of the array. Also, you were getting undefined since li is not defined. To avoid simply define li as "" empty string.
Here is a simplified solution that requires no regex. You can use array.filter and array.map to consolidate.
document.querySelector('button').onclick = () => {
var text = document.querySelector('textarea').value;
var lines = text.split('\n');
var html = lines
.filter(line => line.trim() !== '')
.map(line => `<li class="c1_2v">${line}</li>`)
.join('');
document.querySelector('ul').innerHTML = html;
}
<textarea>
this is
a
something
that
I want to add to new lists
</textarea>
<button>Click me</button>
<ul><!--output goes here--></ul>

using jQuery to iterate through an array to create links

I am attempting to loop through a very simple array in order to create a menu. I have been all around the solution, but have yet to nail it down.
Here's my script:
var json_data = [["Womens","/womens"],["Best Sellers","/best-sellers"]];
var json_length = json_data.length;
var inner_length = 0;
for (var i = 0; i<json_length; i++)
{
inner_length = json_data[i].length;
for( var j = 0; j<inner_length; j++ ){
var innerData = json_data[i][j];
var data = '' + json_data[j][0] + '<br/>';
//alert(data);
$("#content").append(data);
}
}
Basic HTML:
<div id="content">
</div>
When I move the code to append to my div within the first for loop (rather than the second), the second object's data is shown twice rather than the first then second. The current code shows both the first and second object's data, but duplicates it due to being inside the second for loop. I'm sure there is a simple solution, but I am at a loss of ideas.
You can iterate through the array more easily using forEach():
json_data.forEach(function(item) {
var data = '' + item[0] + '<br/>';
$("#content").append(data);
});
Fiddle
Updated your fiddle, removed the unnecessary loop:
https://jsfiddle.net/79k32o1j/4/
for (var i = 0; i<json_length; i++) {
var data = '' + json_data[i][0] + '<br/>';
$("#content").append(data);
}

Why isn't JavaScript for loop incrementing?

I'm trying to replace the <li> with 1. 2. 3. respectively. I managed to change the <li> to a number, but that number is 0. The loop doesn't want to work. To be honest, this method may be impossible.
Take a look at the Fiddle if you'd like.
This is my function(){...} :
function doIt(){
var input = document.getElementById("input");
var li = /<li>/; // match opening li
var liB = /<\/li>/; // match closing li
var numberOfItems = input.value.match(li).length; // number of lis that occur
for(var i = 0; i < numberOfItems; i++) {
insertNumber(i); // execute insertNumber function w/ parameter of incremented i
}
function insertNumber(number){
input.value = input.value.replace(li, number + "." + " ").replace(liB, "");
}
}
I understand the insertNumber(){...} function is not necessary.
Here's an alternative method, turning your HTML textarea contents into DOM elements that jQuery can manipulate and managing them that way:
function doIt() {
var $domElements = $.parseHTML( $('#input').val().trim() ),
output = [],
i = 1;
$.each($domElements, function(index, element) {
if($(this).text().trim() != '') {
output.push( i + '. ' + $(this).text().trim() );
i++;
}
});
$('#input').val(output.join('\n'));
}

two delimiters output formatting javascript

I thought this would be easier, but running into a weird issue.
I want to split the following:
theList = 'firstword:subwordone;subwordtwo;subwordthree;secondword:subwordone;thirdword:subwordone;subwordtwo;';
and have the output be
firstword
subwordone
subwordtwo
subwordthree
secondword
subwordone
thirdword
subwordone
subwordtwo
The caveat is sometimes the list can be
theList = 'subwordone;subwordtwo;subwordthree;subwordfour;'
ie no ':' substrings to print out, and that would look like just
subwordone
subwordtwo
subwordthree
subwordfour
I have tried variations of the following base function, trying recursion, but either get into infinite loops, or undefined output.
function getUl(theList, splitOn){
var r = '<ul>';
var items = theList.split(splitOn);
for(var li in items){
r += ('<li>'+items[li]+'</li>');
}
r += '</ul>';
return r;
}
The above function is just my starting point and obviously doesnt work, just wanted to show what path I am going down, and to be shown the correct path, if this is totally off base.
It seems you need two cases, and the difference between the two is whether there is a : in your string.
if(theList.indexOf(':') == -1){
//Handle the no sublist case
} else {
//Handle the sublist case
}
Starting with the no sublist case, we develop the simple pattern:
var elements = theList.split(';');
for(var i = 0; i < elements.length; i++){
var element = elements[i];
//Add your element to your list
}
Finally, we apply that same pattern to come up with the implementation for the sublist case:
var elements = theList.split(';');
for(var i = 0; i < elements.length; i++){
var element = elements[i];
if(element.indexOf(':') == -1){
//Add your simple element to your list
} else {
var innerElements = element.split(':');
//Add innerElements[0] as your parent element
//Add innerElements[1] as your child element
//Increment i until you hit another element with ':', adding the single elements each increment as child elements.
//Decrement i so it considers the element with the ':' as a parent element.
}
}
Keep track of the current list to add items to, and create a new list when you find a colon in an item:
var baseParent = $('ul'), parent = baseParent;
$.each(theList.split(';'), function(i, e) {
if (e.length) {
var p = e.split(':');
if (p.length > 1) {
baseParent.append($('<li>').append($('<span>').text(p[0])).append(parent = $('<ul>')));
}
parent.append($('<li>').text(p[p.length - 1]));
}
});
Demo: http://jsfiddle.net/Guffa/eWQpR/
Demo for "1;2;3;4;": http://jsfiddle.net/Guffa/eWQpR/2/
There's probably a more elegant solution but this does the trick. (See edit below)
function showLists(text) {
// Build the lists
var lists = {'': []};
for(var i = 0, listKey = ''; i < text.length; i += 2) {
if(text[i + 1] == ':') {
listKey = text[i];
lists[listKey] = [];
} else {
lists[listKey].push(text[i]);
}
}
// Show the lists
for(var listName in lists) {
if(listName) console.log(listName);
for(var j in lists[listName]) {
console.log((listName ? ' ' : '') + lists[listName][j]);
}
}
}
EDIT
Another interesting approach you could take would be to start by breaking it up into sections (assuming text equals one of the examples you gave):
var lists = text.match(/([\w]:)?([\w];)+/g);
Then you have broken down the problem into simpler segments
for(var i = 0; i < lists.length; i++) {
var listParts = lists[i].split(':');
if(listParts.length == 1) {
console.log(listParts[0].split(';').join("\n"));
} else {
console.log(listParts[0]);
console.log(' ' + listParts[1].split(';').join("\n "));
}
}
The following snippet displays the list depending on your requirements
var str = 'subwordone;subwordtwo;subwordthree;';
var a = []; var arr = [];
a = str;
var final = [];
function split_string(a){
var no_colon = true;
for(var i = 0; i < a.length; i++){
if(a[i] == ':'){
no_colon = false;
var temp;
var index = a[i-1];
var rest = a.substring(i+1);
final[index] = split_string(rest);
return a.substring(0, i-2);
}
}
if(no_colon) return a;
}
function display_list(element, index, array) {
$('#results ul').append('<li>'+element+'</li>');
}
var no_colon_string = split_string(a).split(';');
if(no_colon_string){
$('#results').append('<ul><ul>');
}
no_colon_string.forEach(display_list);
console.log(final);
working fiddle here

Categories