Why an unexpected <br> being inserted by replace() function? - javascript

I'm seeing some very unexpected behavior with the replace() javascript function that I'm using. Essentially, if the user inputs [Hi there] into a text form, I want to replace the brackets [ and ] with tags that will add margin to the text for e.g. [Hi there] to <div>Hi there</div>. In addition to the desired tags, a <br> tag is also added after the closing div.
Here is my code:
javascript
$('.servicebody').each(function() {
var string = $(this).html();
$(this).html(string.replace(/\[/g, '<div class="marginme">')); // to replace opening square bracket
});
$('.servicebody').each(function() {
var string = $(this).html();
$(this).html(string.replace(/\]/g, '</div>')); // to replace closing square bracket
});
css
.marginme {
margin: 10px auto;
}
Any thoughts on why a <br> tag is being inserted by this replace() function?

I think it's because you insert the HTML below you close the tags. Try the following code, instead:
$('.servicebody').each(function() {
var string = $(this).html();
$(this).html(string.replace(/\[/g , '<div class="bulletflex"><div class="bullet"></div><div class="bullet2">').replace(/\]/g, '</div></div>'));
});

Here is my answer:
I would recommend you to use one single function instead of two. Using two functions, as you did in your sample code, only makes unnecessarily calculations.
As best practice I would reccomend you to store this into a variable. Otherwise this could lead to unexpected behavior.
Avoid multiple calls of the jquery functions: make $(lorem).ipsum();$(lorem).xyz() to var $lorem = $(lorem);$lorem.ipsum();$lorem.xyz();
Here is my version of your code:
$('.servicebody').each(function() {
var self = this;
var $self = $(self);
var html = $self.html();
html = html.replace(/\[/g, '<div class="marginme">');
html = html.replace(/\]/g, '</div>');
$self.html(html);
});

i think you might try another syntax
$('.servicebody').empty().add($('</div></div>'));

Related

Manipulate var in jquery by doing find and text

I use a WYSIWYG editor in my page. I collect the HTML in a callback function. I would like now change the content with jQuery. For that I do a find() to select the text I want to replace. Then I want to replace it, but I'm stuck!
$('.save').click(function() {
var html = $('#edit').editor('get_html');
console.log(html)
var ma_societe_OLD = $(html).find('.ma_societe').attr('data');
var ma_societe = $(html).find('.ma_societe').text();
if (ma_societe === ma_societe_OLD) {
$(html).find('.ma_societe').text('dfdsfsdfds');
}
console.log(html);
});
As you can see, I want to replace the content of the span with my own text. But it's not working.
The issue is because you're making amendments to the jQuery object, but you never store those changes anywhere. You either create a new jQuery object containing the original, unchanged html, or return the html string directly.
Instead, create $(html) in a variable, make your changes to it, then work with it as needed. Something like this:
$('.save').click(function() {
var html = $('#edit').editor('get_html');
var $html = $(html);
var $maSociete = $html.find('.ma_societe')
if ($maSociete.text() === $maSociete.attr('data')) {
$maSociete.text('dfdsfsdfds');
}
var result = $html[0].outerHTML
console.log(result);
});

How to replace only the text of this element with jQuery?

I'm trying to make a kind of simple search engine, where
the user enters a string and if it's equal to the text inside
an element, that portion of text must be highlighted some way.
This is the html:
<input type="text">
<input type="button" value="Change text"><br>
Click here to get more info!
this is the css:
.smallcaps{
color:red;
}
and this is the jquery function that makes the search and replace:
$("input[type='button']").click(function(){
var textValue = $("input[type=text]").val();
$("a").html(function(_, html) {
return html.replace(new RegExp(textValue,"ig"), '<span class="smallcaps">'+textValue+'</span>');
});
});
This is an example of how it looks like:
Everything works fine, until the search string is equals to the name of a node element, so for example if the search string is a, the html will be broken.
How can I avoid the replace of the html itself?. I just want to work over the text.
This is the codepen:
http://codepen.io/anon/pen/mefkb
Thanks in advance!
I assume that you want to only highlight the last search and not store the ones from before.
With this assumption, you can store the old value if it is the first call and use the stored value in the calls afterwards:
$("input[type='button']").click(function(){
// Escape the html of the input to be able to search for < or >
var textValue = $('<div/>').text($("input[type=text]").val()).html();
if(textValue === '') return;
$("a").html(function(_, html) {
var old = $(this).data('content');
if(!old) {
old = html;
$(this).data('content', old);
}
var replacer = function(match) {
return match.replace(new RegExp(textValue, "ig"), '<span class="smallcaps">'+textValue+'</span>');
};
if(/[<>]/.test(old)) {
return old.replace(/^[^<>]*</gi, replacer).replace(/>[^<>]*</gi, replacer).replace(/>[^<>]*$/gi, replacer);
}
return replacer(old);
});
});
Also i fixed two bugs I found when testing:
if you search for an empty string, everything is broken.
If you search for html characters like < or > nothing is found as in the text they are converted to < or >.
One thing is not solved, as it is not possible to easily implement it without destroying the subelement structure: It is not possible to search in different subelements, as you have to remove the tags, search then and insert the tags at the right position afterwards.
Working fiddle: http://codepen.io/anon/pen/KlxEB
Updated Demo
A workaround would be to restore <a> to original text, instead of complicating the regex.
Your problem is a form the <span> tag is getting replaced.
var init = $("a").text(); //save initial value
$("input[type='button']").click(function(){
$('a').text(init); //replace with initial value
var textValue = $("input[type=text]").val();
$("a").html(function(_, html) {
return html.replace(new RegExp(textValue,"ig"), '<span class="smallcaps">'+textValue+'</span>');
});
});

jQuery remove certain tags from a string

I have a string where I want to remove all figure tags. I have tried the following:
var s = '<html><body>report content<figure id="fig2" data-contenttype="chart"><img src="chart.jpg"/><div>chart 1</div></figure><div>body content</div><figure id="fig2"><img src="chart2.jpg"/><div>chart 2</div></figure></body></html>';
var result = $(s).find('figure').remove();
The reason this does not work is that find does not find the figure elements because they have children. Does anyone know how I can remove all figure nodes (and everything inside them) and leave the rest of the html in tact?
Note the html is not in the DOM I need to do this via string manipulation. I don't want to touch the DOM.
You can wrap your string in a jQuery object and do some sort of a manipulation like this:
var removeElements = function(text, selector) {
var wrapped = $("<div>" + text + "</div>");
wrapped.find(selector).remove();
return wrapped.html();
}
USAGE
var removedString = removeElements('<html><body>report content<figure id="fig2" data-contenttype="chart"><img src="chart.jpg"/><div>chart 1</div></figure><div>body content</div><figure id="fig2"><img src="chart2.jpg"/><div>chart 2</div></figure></body></html>','figure');
The beauty of this approach is that you can specify a jquery selector which to remove.
Another approach for keeping html and body tag:
var s = '<html><body>report content<figure id="fig2" data-contenttype="chart"><img src="chart.jpg"/><div>chart 1</div></figure><div>body content</div><figure id="fig2"><img src="chart2.jpg"/><div>chart 2</div></figure></body></html>';
var $s = s.replace(/<figure>(.*)<\/figure>/g, "");
console.log($s)

Find Characters and wrap with HTML

I am trying to find // (slashes) in the document and wrap it with a span.
I've tried
var slashes = "//";
/slashes+/
So output should be:
Hello There! I Am <span class="slashes">//</span> An Alien
With jQuery .replace() and :contains but nothing happens, and I am new to reguler expressions to do this correctly. How would I do this?
Edit: What have I tried:
Solution for this question didn't work:
function slashes($el) {
$el.contents().each(function () {
dlbSlash = "//";
if (this.nodeType == 3) { // Text only
$(this).replaceWith($(this).text()
.replace(/(dlbSlash)/gi, '<span class="slashes">$1</span>'));
} else { // Child element
slashes($(this));
}
});
}
slashes($("body"));
You need to escape the slashes in your regex. Try
var mystring = "adjfadfafdas//dsagdsg//dsafda"
mystring.replace(/\/\//g,'<span class="slashes">\/\/</span>');
Should output
"adjfadfafdas<span class="slashes">//</span>dsagdsg<span class="slashes">//</span>dsafda"
If you want to replace the slashes in h2 and p tags, you can loop through them like so:
$('h2, p').each(function(i, elem) {
$(elem).text(
$(elem).text().replace(/\/\//g,'<span class="slashes">\/\/</span>'));
});
This will blow away any additional html tags you may have had in your p and h2 tags, though.
This is one more way of doing this
//Find html inside element with id content
var html = $('#content').html();
//Replace // with <span style='color:red'>//</span>
html = html.replace(/\/{2}/g,"<span style='color:red'>$&</span>");
//Return updated html back to DOM
$('#content').html(html);​
and here is the demo
I think you were looking in the right place. The only thing to fix is your regular expression:
.replace(/\/\//g, '<span class="slashes">$1</span>'));
Focusing on text nodes (type 3) is important, instead of doing a global replace of the body innerHTML that might break your page.
If you want to apply such replacement for single // only, go with
mystring = mystring.replace(/(\/{2})/g, "<span class=\"slashes\">$1</span>");
However if you want to apply that for 2 or more slashes, then use
mystring = mystring.replace(/(\/{2,})/g, "<span class=\"slashes\">$1</span>");
But if you want to apply it for any even quantity of slashes (e.g. //, ////, etc.) then you need to use
mystring = mystring.replace(/((?:\/{2})+)/g, "<span class=\"slashes\">$1</span>");
Test the code here.

Replace text with HTML element

How can I replace a specific text with HTML objects?
example:
var text = "some text to replace here.... text text text";
var element = $('<img src="image">').event().something...
function ReplaceWithObject(textSource, textToReplace, objectToReplace);
So I want to get this:
"some text to replace < img src...etc >.... text text text"
And I would like manipulate the object element without call again $() method.
UPDATE:
I solved.
thanx #kasdega, i made a new script based in your script, because in your script i can't modify the "element" after replace.
This is the script:
$(document).ready(function() {
var text = "some text to replace here.... text text text";
var element = $('<img />');
text = text.split('here');
$('.result').append(text[0],element,text[1]);
$(element).attr('src','http://bit.ly/mtUXZZ');
$(element).width(100);
});
I didnt know that append method accept multiples elements.
That is the idea, only need to automate for multiple replacements
thanx to all, and here the jsfiddle
do a split on the text you want to replace then use the array indexes 0 and 1...something like:
function ReplaceWithObject(textSource, textToReplace, objectToReplace) {
var strings = textSource.split(textToReplace);
if(strings.length >= 2) {
return strings[0] + objectToReplace.outerHTML() + strings[1];
}
return "";
}
UPDATE: I found another SO post Get selected element's outer HTML that pointed me to a tiny jquery plugin that helps here.
I believe this jsfiddle has what you want. outerHTML is the tiny jquery plugin I included in the JSFiddle.
You can also use replace which will reduce some code: http://jsfiddle.net/kasdega/MxRma/1/
function ReplaceWithObject(textSource, textToReplace, objectToReplace) {
return textSource.replace(textToReplace, objectToReplace.outerHTML());
}
function textToObj (text,obj,$src){
var className = "placeholder-"+text;
$src.html($src.html().replace(text,"<div class='"+className+"'></div>"));
$("."+className).replace(obj);
}
you can use $(selector).outerHtml to get the html string of an element
You can replace the html directly: http://jsfiddle.net/rkw79/qNFKF/
$(selector).html(function(i,o) {
return o.replace('old_html','new_html');
})

Categories

Resources