I have some code similar to this:
var glyph = isApple ? '<span class="glyphicon glyphicon-apple"></span>' : '<span class="glyphicon glyphicon-banana"></span>';
var newFruit = '<li class="list-group-item">' + glyph + '<span class="badge">' + score + '</span>' + name + '</li>'
$('#fruitList').append(newFruit);
Just a lot of gross concatenation that is hard to read and follow. Is there a way to functionally create these elements, and if so, how? Also, I'm curious of the speed of doing so, because if it is much slower than what I'm doing then I just won't bother.
I'm looking for something like this, for example:
var newElement = li().class("list-group-item").value(name);
newElement.span().class(isApple ? "glyphicon glyphicon-apple" : "glyphicon glyphicon-user");
newElement.span().class('badge').value(score);
$('#fruitList').append(newElement);
Now obviously the above is not good or probably even right but hopefully it gets the idea across. Basically a way of chaining functions to create new elements that avoids the mess of concatentations for creating custom HTML to insert.
Something like this?
$('<li>', {
html: $('<a>', {
href: item.href,
text: item.title
})
});
This puts an a tag within an li tag. You can modify this as per your needs
This structure should help, the trick is making sure the parent element is appended before the child:
var newElement = document.createElement('li');
$(newElement).addClass('list-group-item');
$(newElement).html(name);
$('#fruitList').append(newElement);
var newSpan = document.createElement('span');
var apple = isApple ? "glyphicon glyphicon-apple" : "glyphicon glyphicon-user";
$(newSpan).addClass(apple);
$(newSpan).addClass('badge');
$(newSpan).html(score)
$(newElement).append(newSpan);
var $li = $("<li/>",{title:"woot"}).addClass("list-group-item").value(name);
$li.append( $("<span/>").addClass(isApple ? "glyphicon glyphicon-apple" : "glyphicon glyphicon-user") );
$("<span/>").addClass('badge').value(score).appendTo( $li );
$('#fruitList').append($li);
Generally speaking, arrays are faster than string concatenation which is faster than DOM manipulation.
function getNewItemString(glyph,score,name){
return [
'<li class="list-group-item">',
'<span class="glyphicon ',
glyph,
'"></span>',
'<span class="badge">',
score,
'</span>',
name,
'</li>'
].join('');
}
$('#fruitList').append(getNewItemString('glyphicon-apple', 20, 'player1'));
$('#fruitList').append(getNewItemString('glyphicon-banana', 0, 'player2'));
There is an overload of the jQuery function that allows you to do create an element and specify its properties. The following would replicate your example:
$('<li>', {
class: "list-group-item",
html: $('<span>', {
class: isApple ? "glyphicon glyphicon-apple" : "glyphicon glyphicon-user"
})
.after($('<span>', {
class: "badge",
text: score
}))
.after(name)
});
Related
I made a forEach case for text loop,
and this moment, I;m facing a problem that I cannot put span tag in return result of innerText.
data.forEach(item => {
const dataTitle = document.createElement('p');
dataTitle.innerText = data.title + '<span class="p-90">' + data.subTitle + '</span>'
viewContainer.appendChild(dataTitle);
});
this is my code, but the < span class =".... is exposed to the site in raw.
how can I fix it?
Try this. use innerHTML instead of innerText and replace data.title with item.title. same for data.subTitle.
data.forEach((item) => {
const dataTitle = document.createElement("p");
dataTitle.innerHTML =
item.title + '<span class="p-90">' + item.subTitle + "</span>";
viewContainer.appendChild(dataTitle);
});
var cssClass ;
cssClass = "fa-leaf green-icon";
var textValue = '<span class=' + cssClass + '>' + nodeName + '</span>';
later I've used this text value to in column header in grid panel in Extjs 6.
When page is played green-icon class is removed from class, it becomes like this
<span class="fa-leaf" green-icon>name</span>, but it should have been like this:
<span class="fa-leaf green-icon">name</span>
Your code suggest that you start off with '<span class=fa-leaf green-icon>name</span>, since you do not include the " quotes when creating the html string.
Try that first. When constructing HTML with string concatenation, you have to write the quotes around attributes yourself.
The browser can interpret attributes not wrapped between ", but as you see that leads to issues when the value contains spaces, since <span class="fa-leaf" green-icon> basically means the span has a class attribute with the value fa-leaf and a green-icon attribute without a value that the browser will ignore.
So try: var textValue = '<span class="' + cssClass + '">' + nodeName + '</span>'; first and see how extjs reacts to it.
I have a Javascript / JQuery problem.
I get unterminated string literal when I use this code:
var newInfo = '<div><span class="testClass"><a title="edit" href="'+link+'">'+oldVal+'</a></span></div>';
If I delete the </div>
tag, it works... But I need this.
I am totally out of ideas.
Maybe you can help, thanks.
Escape your slashes.
var newInfo = '<div><span class="testClass"><a title="edit" href="' + link + '">' + oldVal + '<\/a><\/span><\/div>';
You could also just build your html as actual DOM elements instead of a string (which avoids a lot of pitfalls, including this one).
var div = $('<div />'),
span = $('<span />').addClass('testClass'),
a = $('<a />').text(oldVal).attr({
"href": link,
"title": "edit"
}),
newInfo = div.append(span.append(a));
Try to use
var newInfo = '<di'+'v><span class="testClass"><a title="edit" href="'+link+'">'+oldVal+'</a></span></di'+'v>';
Seperating the div tags helped me on a similar problem
I am wondering if there is a better way to write this JavaScript (Jquery) code.
This snippet dynamically created a H3 with a link.
My designer is going nuts trying to style this as its in JavaScript.
I am trying to re-write / refactor this into to smaller chunks to allow my designer to style without looking at all this code on one single line.
var dvClassContainer = $(document.createElement('div')).attr("id", 'dvclassconatiner_' + classVal).attr("classifname", classifname).attr("memclassnumber", memclassnumber).html('<h3>' + classifname + '<a id="ancclassremove_'+ classVal +'" classVal="' + classVal + '" onclick="RemoveClassificationUponConfirm(\'' + classVal + '\');" class="buttons delete btnSmall">Delete</a></h3><img style="display:none;" id="imgloadRemClass_' + classVal + '" alt="loading" src="../Images/application/smallUploading.gif" />');
I was thinking of creating more variables and combining them together.
Is there a 'cleaner' way of writing this?
If you utilize more of jQuery's features, the code becomes more readable and more easily maintained:
var dvClassContainer = $('<div>');
dvClassContainer.attr({
id: 'dvclasscontainer_'+classVal,
classifname: classifname,
memclassnumber: memclassnumber
});
var dvHeader = $('<h3>');
var dvHeaderLink = $('<a>Delete</a>');
dvHeaderLink.attr({
id: 'ancclassremove_'+classVal,
classVal: 'classVal',
class: 'buttons delete btnSmall'
}).on('click',function(){
RemoveClassificationUponConfirm(classVal);
});
var dvImg = $('<img>');
dvImg.attr({
id: 'imgloadRemClass_'+classVal,
alt: 'loading',
src: '../Images/application/smallUploading.gif'
});
dvClassContainer.append(dvHeader.append(dvHeaderLink.append(dvImg)));
Ideally, you would also want to move all those non-standard attributes (classifname, memclassnumber, classVal) to data- attributes, which would be accessible via jQuery's data() function.
var dvClassContainer = $(document.createElement('div'))
.attr("id", 'dvclassconatiner_' + classVal)
.attr("classifname", classifname)
.attr("memclassnumber", memclassnumber)
.html('<h3>' + classifname + '<a id="ancclassremove_'+ classVal +'" classVal="' + classVal + '" onclick="RemoveClassificationUponConfirm(\'' + classVal + '\');" class="buttons delete btnSmall">Delete</a></h3><img style="display:none;" id="imgloadRemClass_' + classVal + '" alt="loading" src="../Images/application/smallUploading.gif" />');
The last line still needs fixing. I would create elements and then set their attributes and then append them to the h3. You can do that using var h3 = $("<h3></h3>"); (as an example) and set attributes using .attr() and finally .append() to put it all together.
I'm going to go a different way with this, after acknowledging that this one line of code is nasty.
It's not the JavaScript that's giving your designer headaches. If they can't style this with CSS, they're not trying hard enough. Surely that h3 and anchor are inside other elements that they can grab for some styling:
.someContainer h3 { color: chartreuse; }
However, if they HAVE tried everything possible, you still just need to add a new class or two (to the h3 and the anchor). Where you have .html('<h3>'... you would change it to .html('<h3 class="someClass">'...
As much as we have fun optimizing and downright fixing bad JS in poor implementations, if we assume that this is "working", the problem is the designer's ability to style. This is therefore not really a JavaScript issue.
Use Douglas Crockford's Supplant method. It tokenizes a string so you can dynamically build strings out. Here is a fiddle example: http://jsfiddle.net/mmeah/F23rk/
// http://javascript.crockford.com/remedial.html
if (!String.prototype.supplant) {
String.prototype.supplant = function (o) {
return this.replace(/{([^{}]*)}/g,
function (a, b) {
var r = o[b];
return typeof r === 'string' || typeof r === 'number' ? r : a;
}
);
};
}
var classVal="x", classifname="y", memclassnumber="z"; //predefined
var dvClassHtml = $("#someDiv").html();
$("#someDiv").html("");
var params ={
"classVal":classVal,
"classifname":classifname,
"memclassnumber":memclassnumber
};
dvClassHtml=dvClassHtml.supplant(params);
var dvClassContainer =
$(document.createElement('div'))
.attr("id", 'dvclassconatiner_' + classVal)
.attr("classifname", classifname)
.attr("memclassnumber", memclassnumber)
.html(dvClassHtml);
var dvClassContainer = $('<div/>')
.attr({'id': 'dvclassconatiner_' + classVal,
'classifname': classifname,
'memclassnumber': memclassnumber
})
.html(
function() {
var $title = $('<h3>' + classifname + '</h3>');
var $link = $('<a>Delete</a>').attr({
'id': 'ancclassremove_' + classVal,
'classVal': classVal,
'class': 'buttons delete btnSmall'
})
.on('click', function() {
RemoveClassificationUponConfirm(classVal);
});
var $img = $('<img/>').attr({
'id': 'imgloadRemClass_' + classVal,
'alt': 'loading',
'src': '../Images/application/smallUploading.gif'
})
.css('display', 'none');
return $title.append($link).add($img);
});
Demo
I'm looking to customize the default date header in blogger with jQuery.
The original output is:
<h2 class='date-header'>2011-01-20</h2>
I want to wrap the YYYY, MM, and DD in spans so I can manipulate them as child nodes.
The result would be:
<h2 class='date-header'><span class="dhy">2011</span><span class="dhm">01</span><span class="dhd">20</span></h2>
Each attempt of mine adds extra tags so it's a nested mess.
Anybody have a good solution?
Here's a nice functional solution:
$('.date-header').html(function() {
var txt = $(this).text();
var classes = ['dhy', 'dhm', 'dhd'];
$(this).html($.map(txt.split(/-/), function(val) {
return $('<span/>', {'class': classes.shift()}).text(val)[0];
}));
});
http://jsfiddle.net/ThiefMaster/WdRAw/
If it always has the same format of YYYY-MM-DD then you could use split to get the elements, loop through them, create your output HTML then add that as the HTML of the h2.
$(function()
{
$(".date-header").each(function()
{
var arrDate = $(this).text().split("-");
var strOut = '<span class="dhy">'+arrDate[0]+'</span>-';
strOut+= '<span class="dhm">'+arrDate[1]+'</span>-';
strOut+= '<span class="dhd">'+arrDate[2]+'</span>';
$(this).html(strOut);
});
});
And a fiddle: http://jsfiddle.net/ahallicks/xGa2J/2/
I think this should do it:
var header = $('.date-header');
var d = header.text().split('-');
header.html('<span class="dhy">' + d[0] + '</span><span class="dhm">' + d[1] + '</span><span class="dhd">' + d[2] + '</span>');