Find and replace HTML string with jQuery - javascript

Links from the database are website titles and render on the page "Interesting Article: Author" - but occasionally the link is a question "Where's China?: GoogleMaps". The ?: looks silly so I wanted to replace the HTML ?</span>: with ?</span>.
Here is the jQuery I worked out:
$('#relatedinfo ul li a').html().replace('?</span>:','?</span>');
But this doesn't actually replace it in the DOM. How do I get that string to actually change the page?

I'd suggest:
$('#relatedinfo ul li a').html(function(index,html){
return html.replace(/<\/span>(\:)/,'');
});
JS Fiddle demo.
Or even:
$('#relatedinfo ul li a').text(function(index,text){
return text.replace(':','');
});
JS Fiddle demo.
An updated approach is to check that the last character in the span is in the array of ['?','!','.'] and, if it is, then to remove the : from the nextSibling's nodeValue:
$('#relatedinfo ul li a span').text(function(index,text){
var lastchar = text.split('').pop();
if (['?','!','.'].indexOf(lastchar) > -1) {
this.nextSibling.nodeValue = this.nextSibling.nodeValue.replace(':','');
}
});
JS Fiddle demo.
References:
html().
String.replace().
text().

You can also use regex :
var rx = new RegExp('(?![^<&]+[>;])' + searchString, 'gi');
$('#relatedinfo').html(function (i, html) {
return html.replace(rx, '<b>$&</b>')
});
source : jQuery to Find/Replace html text when not inside an html tag other than P, DIV, SPAN, TD

Related

JQuery: how to make a list of words in html element <b></b>?

Given a HTML DOM element with b elements such :
<div>
My <b>text</b> have some <b>words</b> or <b>groups of words</b> in <b>bold</b>. How to do a variable <b>list</b> with these texts ?
</div>
Given we attack this with JS or JQuery.
How to get the list of all bold words, something like such :
var list = [ "text", "have some ", "words", "groups of words", "in","bold", "list" ,...];
I tried .text() and .html() but it doesn't work, see http://jsfiddle.net/LF5dX/1/
JSfiddle demo appreciate since more relevant for all future readers / users.
You can use .map() along with .text() and .get()
var list = $('div b').map(function(){
return $.trim($(this).text());
}).get()
Demo: Fiddle
Try this,
var arr=[];
$('div b').each(function(){
arr.push($(this).text());
});
console.log(arr);
Demo
EDIT: Oh, ok, I see OP has edited the answer, so this answer is no longer on-topic. Leaving it here though.
Not sure how you'd do it in jQuery, but here's how to do it in plain JavaScript:
var div = document.getElementsByTagName('div')[0];
var textContents = [].map.call(div.childNodes, function(node) {
return node.textContent.trim();
});
console.log(textContents);
http://jsfiddle.net/RGaQp/1/

Select characters and wrap

I'm looking to wrap the last 2 characters in a piece of text in a <sup> using jQuery. I can do a console.log that returns the text I want to wrap, but it never gets wrapped. The code I have is really simple:
// get text of heading
var plansBlockHeading = $('.first .sub .one h4').text();
// filter to last 2 chars
var sup = plansBlockHeading.substr(plansBlockHeading.length-2);
// Wrap in a <sup></sup>
$(sup).wrap("<sup />");
I'm obviously missing something simple, but I'm not sure what. Any pointers?
I would use a regexp
var text = $('.first .sub .one h4').text();
text = text.replace(/^(.*)(.{2,2})$/, "$1<sup>$2</sup>");
$('.first .sub .one h4').html(text);
http://jsfiddle.net/evPhf/
var elem = $('.first .sub .one h4'),
text = elem.text(),
html = text.slice(0,-2) + '<sup>' + text.slice(-2) + '</sup>';
elem.html(html);​
FIDDLE
An idiomatic jQuery solution could look like this:
$('.first .sub .one h4').html(function(i, html) {
// make sure there's no whitespace issues
html = $.trim(html);
return html.slice(0, -2) + "<sup>" + html.slice(-2) + "</sup>";
});
This assumes there's no HTML markup inside the h4 (really just at the end would be an issue).
This also handles properly if you have more than one h4.

Apply ligature with jquery to link text only, not link href

I am using ligatures.js to replace text within my site with the ligature of some character combinations. For instance, the 'fi' in 'five'.
Here is my example: http://jsfiddle.net/vinmassaro/GquVy/
When you run it, you can select the output text and see that the 'fi' in 'five' has become one character as intended. If you copy the link address and paste it, you will see that the href portion has been replaced as well:
/news/here-is-a-url-with-%EF%AC%81ve-ligature
This is unintended and breaks the link. How can I make the replacement on JUST the text of the link but not the href portion? I've tried using .text() and .not() with no luck. Thanks in advance.
I think you can solve it using the appropiate jQuery selectors
$('h3 a, h3:not(:has(a))')
.ligature('ffi', 'ffi')
.ligature('ffl', 'ffl')
.ligature('ff', 'ff')
.ligature('fi', 'fi')
.ligature('fl', 'fl');
See http://jsfiddle.net/GquVy/7/
You are applying the function to the whole heading's innerHTML, which includes the anchor's href attribute. This should work for your fiddle example:
$('h1 a, h2 a, h3 a, h4 a').ligature( //...
However, it will only work on links inside the headings, and I'm not sure that's what you're looking for. If you want something that works for any contents inside a certain element (with any level of tag nesting), then you'll need a recursive approach. Here is an idea, which is basically plain JavaScript since jQuery does not provide a way to target DOM text nodes:
$.fn.ligature = function(str, lig) {
return this.each(function() {
recursiveLigatures(this, lig);
});
function recursiveLigatures(el, lig) {
if(el.childNodes.length) {
for(var i=0, len=el.childNodes.length; i<len; i++) {
if(el.childNodes[i].childNodes.length > 0) {
recursiveLigatures(el.childNodes[i], lig);
} else {
el.childNodes[i].nodeValue = htmlDecode(el.childNodes[i].nodeValue.replace(new RegExp(str, 'g'), lig));
}
}
} else {
el.nodeValue = htmlDecode(el.nodeValue.replace(new RegExp(str, 'g'), lig));
}
}
// http://stackoverflow.com/a/1912522/825789
function htmlDecode(input){
var e = document.createElement('div');
e.innerHTML = input;
return e.childNodes.length === 0 ? "" : e.childNodes[0].nodeValue;
}
};
// call this from the document.ready handler
$(function(){
$('h3').ligature('ffi', 'ffi')
.ligature('ffl', 'ffl')
.ligature('ff', 'ff')
.ligature('fi', 'fi')
.ligature('fl', 'fl');
});
That should work on contents like this:
<h3>
mixed ffi content
<span>this is another tag ffi <span>(and this is nested ffi</span></span>
Here is a ffi ligature
</h3>
http://jsfiddle.net/JjLZR/

make parent menu item bold when visiting child page

I have the following code which gives the menu item a class of 'current'. I then style that with font-weight:Bold;
$(document).ready(function () {
var loc = window.location.href;
$("ul a").each(function() {
if (loc.indexOf($(this).attr("href")) != -1) {
$(this).addClass("current");
}
});
});
If the user is on a page which is within the sub menu ul li a how do i add a class called Bold to the parent UL/LI at the root level?
here is the structure, if i am on Q&Z Group then About us needs to be bold. - http://jsfiddle.net/zZQy3/
var loc = window.location.href;
$("ul a").each(function() {
if (loc.indexOf($(this).attr("href")) != -1) {
$(this).addClass("current");
$(this).parent('li').parent('ul').addClass("Bold");
}
});
You are looking for the parent:
$(this).parent("li").parent("li").addClass("bold");
Note there are two parents above - this is because your a element is within an li, which is not what you want bold. You want the li parent of THAT to be bold.
if you have the current node as a jquery variable, you can access its parent by using parent. So, you could use $(this).parent().addClass(...);
If you wanted to, rather than using javascript for this logic, you could use the selector:
$('ul li:has(a[href=' + window.location.href + '])').addclass(...);
This is looking for any LI that has a descendant with an href matching the current url by way of the Has and Attribute Equals selectors.

Full selector string or this.find and selector string

Both work, but is there any advantage / dis-advantage of using one over the other ?
$("#" + this.id + " > ul > li.active:first")
vs
$(this).find(" > ul > li.active:first")
The second selector works, I'd go with that instead of concatenating the ID into the first selector (looks ugly) and making jQuery look for that same element ID again (redundant).
You could also do this... I think.
$(" > ul li.active:first", this);

Categories

Resources