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>');
Related
I basically just want to display each entry of local storage on a new line inside a list element.
Here is my JS:
if ( counter == 1 ){
var json = JSON.parse(localStorage.getItem( localStorage.key( i )))
var textm = 'Entry:'+json.Entry+'\n Exercise: '+json.Exercise+'\n Date:'+json.Date+'\n Start: ' +json.Start+'\n End: '+json.End+'\n Calories: '+json.Calories;
var ul = document.getElementById("list");
var li = document.createElement("li");
li.appendChild(document.createTextNode(textm));
ul.appendChild(li);
};
Very long i know, but this is the output I receive:
What is the reasoning for this? Do I not use line breaks right? or could it potentially be my CSS?
Unless you are using <pre> elements, or the equivalent CSS formatting, browsers treat newline characters as spaces, and condense multiple whitespace characters down to a single space. To have your fields appear on separate lines you need to insert <br> line break elements rather than newline characters. (Or use a nested list, or wrap each "line" in a <p> element, or whatever. But just using <br> elements is simplest.)
Except that because you are setting the text with .createTextNode() simply including "<br>" in your string would display those characters rather than creating an element. The simplest solution to this is to set the .innerHTML of your <li> element rather than using .createTextNode():
if (counter == 1) {
var json = JSON.parse(localStorage.getItem(localStorage.key(i)))
var textm = 'Entry:' + json.Entry + '<br> Exercise: ' + json.Exercise + '<br> Date:' + json.Date
+ '<br> Start: ' + json.Start + '<br> End: ' + json.End + '<br> Calories: ' + json.Calories;
var ul = document.getElementById("list");
var li = document.createElement("li");
li.innerHTML = textm;
ul.appendChild(li);
}
As an aside, you don't need a semicolon after the closing } of an if block. Also, assuming the above code is contained in a loop, it would be more efficient to move the line with var ul = document.getElementById("list"); to before the loop, so that you only have to lookup that element once instead of doing it on every loop iteration.
In html as W3Schools says,for breaking line we must use <br> instead of \n(or any other character).
I hope this helps :)
Here is your soultion
You need to create element. you can't pass it as a string
Example : document.createElement("br");
if ( counter == 1 ){
var json = JSON.parse(localStorage.getItem( localStorage.key( i )))
var textm = 'Entry:'+json.Entry+document.createElement("br")+' Exercise: '+json.Exercise+'\n Date:'+json.Date+'\n Start: ' +json.Start+'\n End: '+json.End+'\n Calories: '+json.Calories;
var ul = document.getElementById("list");
var li = document.createElement("li");
li.appendChild(document.createTextNode(textm));
ul.appendChild(li);
};
Update your text concatenation with <br/> instead of \n like below.
var textm = 'Entry:'+json.Entry+'<br/> Exercise: '+json.Exercise+'<br/> Date:'+json.Date+'<br/> Start: ' +json.Start+'<br/> End: '+json.End+'<br/> Calories: '+json.Calories;
li.innerHTML = textm;
I'm trying to give a HTML element a markup but it outputs in a string.
My code:
var inputString = tweet.text;
var findme = screen_name;
tweet.text = inputString.replace(screen_name, "<span class='searched'>" + screen_name + "</span>")
You're likely experiencing this issue because you're setting the string on the UI as text, not HTML. Elements have an innerHTML property which will create child elements if necessary.
DEMO
var inputString = "Hello Daniel!";
var findme = "Daniel";
var replacedString = inputString.replace(findme, "<span class='searched'>" +
findme + "</span>");
document.querySelector('#output').innerHTML = replacedString;
Try
.innerHTML
.replace outputs strings, not html
EDIT
var inputString = tweet.text;
var findme = screen_name;
tweet.text = inputString.replace(screen_name, "<span class='searched'>" + screen_name + "</span>")
SomeHTMLObject.innerHTML=tweet.text;
Found out the solution myself:
In the HTML page, you can should use HTML-escape. So you have to use {{{ variable }}} instead of {{ variable }}
Simple solution, should have thought about that..
I have a string with multiple elements with id's like below:
var data = "<div id='1'></div><input type='text' id='2'/>";
Now I'm using this regex to find all the id's in the string:
var reg = /id="([^"]+)"/g;
Afterwards I want to replace all those id's with a new id. Something like this:
data = data.replace(reg, + 'id="' + reg2 + '_' + numCompare + '"');
I want reg2, as seen above, to return the value of the id's.
I'm not too familiar with Regular Expressions, so how can I go about doing this?
Instead of using regex, parse it and loop through elements. Try:
var data = "<div id='1'></div><div id='asdf'><input type='text' id='2'/></div>",
numCompare = 23,
div = document.createElement("div"),
i, cur;
div.innerHTML = data;
function updateId(parent) {
var children = parent.children;
for (i = 0; i < children.length; i++) {
cur = children[i];
if (cur.nodeType === 1 && cur.id) {
cur.id = cur.id + "_" + numCompare;
}
updateId(cur);
}
}
updateId(div);
DEMO: http://jsfiddle.net/RbuaG/3/
This checks to see if the id is set in the first place, and only then will it modify it.
Also, it is safe in case the HTML contains a comment node (where IE 6-8 does include comment nodes in .children).
Also, it walks through all children of all elements. In your example, you only had one level of elements (no nested). But in my fiddle, I nest the <input /> and it is still modified.
To get the get the updated HTML, use div.innerHTML.
With jQuery, you can try:
var data = "<div id='1'></div><div id='asdf'><input type='text' id='2'/></div>",
numCompare = 23,
div = $("<div>"),
i, cur;
div.append(data);
div.find("[id]").each(function () {
$(this).attr("id", function (index, attr) {
return attr + "_" + numCompare;
});
});
DEMO: http://jsfiddle.net/tXFwh/5/
While it's valid to have the id start with and/or be a number, you should change the id of the elements to be a normal identifier.
References:
.children: https://developer.mozilla.org/en-US/docs/DOM/Element.children
.nodeType: https://developer.mozilla.org/en-US/docs/DOM/Node.nodeType
jQuery.find(): http://api.jquery.com/find/
jQuery.attr(): http://api.jquery.com/attr/
jQuery.each(): http://api.jquery.com/each/
Try using
.replace(/id='(.*?)'/g, 'id="$1_' + numCompare + '"');
Regex probably isn't the right way to do this, here is an example that uses jQuery:
var htmlstring = "<div id='1'></div><input type='text' id='2'/>";
var $dom = $('<div>').html(htmlstring);
$('[id]', $dom).each(function() {
$(this).attr('id', $(this).attr('id') + '_' + numCompare);
});
htmlstring = $dom.html();
Example: http://jsfiddle.net/fYb3U/
Using jQuery (further to your commments).
var data = "<div id='1'></div><input type='text' id='2'/>";
var output = $("<div></div>").html(data); // Convert string to jQuery object
output.find("[id]").each(function() { // Select all elements with an ID
var target = $(this);
var id = target.attr("id"); // Get the ID
target.attr("id", id + "_" + numCompare); // Set the id
});
console.log(output.html());
This is much better than using regex on HTML (Using regular expressions to parse HTML: why not?), is faster (although can be further improved by having a more direct selector than $("[id]") such as giving the elements a class).
Fiddle: http://jsfiddle.net/georeith/E6Hn7/10/
var text_source="<a href='c:/exam_file.xls' target='_blank'>file downdload</a>";
text_search="file";
text_source.replace(new RegExp(text_search, 'gi'),
"<span style='font-weight:bold'>" +
text.toLowerCase() + "</span>");
The "a tag" link address has also changed:
<span style='font-weight:bold'>file</span> download
But, It should look like this. I have to change the text value in the "a tag".
<span style='font-weight:bold'>file</span> download
I will address what I said in a second, but you can do this without a loop with just pure regex. Below is how I accomplished this:
var text_source = "<a href='c:/bilmem_ne_dosyasi.xls' target='_blank'>Dosya Downdload</a>";
text_search = "dosya";
var patt = new RegExp("(<a .*?>)(" + text_search + ")(.*?</a>)","gi");
var text_source = text_source.replace(patt, function(match, $1, $2, $3) {
return $1 + "<span style='font-weight:bold'>" + $2.toLowerCase() + "</span>" + $3;
});
document.write(text_source);
DEMO
Getting back to what I said earlier, however, html can be a very, very complex language, and although regex can be used to parse it, partially, it should not be used for large quantities of data. Some patterns are too intricate to match against.
To ensure that your RegExp runs only against the content of the elements, you will need to select all of the elements that you want to manipulate and check their contents.
As an example:
var regExp = /dosya/ig;
[].slice.call(document.getElementsByTagName('a'), 0).forEach(function(element) {
if(regExp.test(element.textContent)) {
element.innerHTML = element.textContent.replace(regExp, function(text) {
return '<span style="font-weight: bold">' + text.toLowerCase() + '</span>';
})
}
});
There is also a jQuery pseudo selector :contains that does a similar thing.
Whilst the replies about not using regexes with HTML or XML are on the whole, correct, you could use the following for simple cases where you don't have too many nested tags:
var text_source="<a href='c:/bilmem_ne_dosyasi.xls' target='_blank'>Dosya Downdload</a>";
text_search="(<[^>]*>[^<]*)(dosya)([^<]*<[^>]*>)";
var replaced = text_source.replace(new RegExp(text_search, 'gi'), "$1<span style='font-weight:bold'>$2</span>$3");
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