Find a character and insert line break - javascript

How might I go about finding a specific character and inserting a line break using jQuery?
The character I need to find is a hyphen - and its always within a product title on an ecommerce site and takes the following format:
This is a title - This is the colour
How can I find the dash for every product title and insert a line break to for the colour name on to a separate line?
The exact HTML markup I'm using is as follows:
<a href="#" class="product c-3">
<div class="product-thumb">
<!-- Other code is in here / Removed for brevity -->
<div class="product-title">
This is a title - This is the colour
</div>
</div>
</a>

You can use replace to find a - in the element's HTML and replace it with -<br />. Try this:
$('.product-title').html(function(i, v) {
return v.replace('-', '-<br />');
});
You can replace with simply '<br />' if you want to remove the hyphen completely.
Example fiddle
Update: This can now be made even more succinct by using an arrow function:
$('.product-title').html((i, v) => v.replace('-', '-<br />'));

Try:
$('.product-title').each(function() {
var self = $(this);
self.html(self.html().replace(/-/, '-<br/>'));
});

Related

Search DOM for elements based on part of the class name [duplicate]

If I have the following:
<div class="apple-monkey"></div>
<div class="apple-horse"></div>
<div class="cow-apple-brick"></div>
I can use the following selector to find the first two DIVs:
$("div[class^='apple-']")
However, if I have this:
<div class="some-other-class apple-monkey"></div>
<div class="apple-horse"></div>
<div class="cow-apple-brick"></div>
It will only find the second DIV, since the first div's class is returned as a string (I think) and doesn't actually start with 'apple-' but rather 'some-'
One way around that is to not use starts with, but instead contains:
$("div[class*='apple-']")
The problem with that is it will also select the 3rd DIV in my example.
Question: Via jQuery, what is the proper way to use predicate selectors on individual class names, rather than the entire class attribute as a string? Is it just a matter of grabbing the CLASS, then splitting it into an array and then looping through each individual one with regex? Or is there a more elegant/less verbose solution?
Classes that start with "apple-" plus classes that contain " apple-"
$("div[class^='apple-'],div[class*=' apple-']")
I'd recommend making "apple" its own class. You should avoid the starts-with/ends-with if you can because being able to select using div.apple would be a lot faster. That's the more elegant solution. Don't be afraid to split things out into separate classes if it makes the task simpler/faster.
While the top answer here is a workaround for the asker's particular case, if you're looking for a solution to actually using 'starts with' on individual class names:
You can use this custom jQuery selector, which I call :acp() for "A Class Prefix." Code is at the bottom of this post.
var test = $('div:acp("starting_text")');
This will select any and all <div> elements that have at least one class name beginning with the given string ("starting_text" in this example), regardless of whether that class is at the beginning or elsewhere in the class attribute strings.
<div id="1" class="apple orange lemon" />
<div id="2" class="orange applelemon banana" />
<div id="3" class="orange lemon apple" />
<div id="4" class="lemon orangeapple" />
<div id="5" class="lemon orange" />
var startsWithapp = $('div:acp("app")');
This will return elements 1, 2, and 3, but not 4 or 5.
Here's the declaration for the :acp custom selector, which you can put anywhere:
$(function(){
$.expr[":"].acp = function(elem, index, m){
var regString = '\\b' + m[3];
var reg = new RegExp(regString, "g");
return elem.className.match(reg);
}
});
I made this because I do a lot of GreaseMonkey hacking of websites on which I have no backend control, so I often need to find elements with class names that have dynamic suffixes. It's been very useful.
this is for prefix with
$("div[class^='apple-']")
this is for starts with so you dont need to have the '-' char in there
$("div[class|='apple']")
you can find a bunch of other cool variations of the jQuery selector here
https://api.jquery.com/category/selectors/
<div class="apple-monkey"></div>
<div class="apple-horse"></div>
<div class="cow-apple-brick"></div>
in this case as question Josh Stodola answer is correct
Classes that start with "apple-" plus classes that contain " apple-"
$("div[class^='apple-'],div[class*=' apple-']")
but if element have multiple classes like this
<div class="some-class apple-monkey"></div>
<div class="some-class apple-horse"></div>
<div class="some-class cow-apple-brick"></div>
then Josh Stodola's solution will do not work
for this have to do some thing like this
$('.some-parent-class div').filter(function () {
return this.className.match(/\bapple-/);// this is for start with
//return this.className.match(/apple-/g);// this is for contain selector
}).css("color","red");
may be it helps some one else thanks
Try this:
$("div[class]").filter(function() {
var classNames = this.className.split(/\s+/);
for (var i=0; i<classNames.length; ++i) {
if (classNames[i].substr(0, 6) === "apple-") {
return true;
}
}
return false;
})

Find all #tagnames inside element then insert a link on it

I have my html
<div class="comment-details">Hello #samplename This is my comment</div>
...
...
More .comment-details elements
On page load, I wanted to find this #samplename inside .comment-details class using .each() loop and insert it on tag in jQuery or Javascript
I wanted something like this after page load:
<div class="comment-details">Hello #samplename This is my comment</div>
jQuery implementation:
$('.comment-details').each(function(){
$(this).html($(this).html().replace(/\#.+?\b/g, `<a href=profile/${$(this).html().match(/\#.+?\b/g)[0].replace('#','')}>${$(this).html().match(/\#.+?\b/g)}</a>`));
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="comment-details">Hello #samplename This is my comment</div>
<div class="comment-details">Hello #JG This is my comment</div>
In raw JS you can do
[...document.querySelectorAll('.comment-details')]
.forEach(tag => {
tag.innerHTML = tag.innerHTML
.replace(/\s?#(\w+)\s?/g, ' #$1 ')
})
<div class="comment-details">Wow #m0meni great answer</div>
<div class="comment-details">#m0meni a little self-congratulatory though</div>
Explaining each step:
querySelectorAll grabs all the comment details divs
[...] is because of In Javascript, what is the best way to convert a NodeList to an array
then you use the string replace function with a regular expression to do what you want
/\s?#(\w+)\s?/g grabs all the characters after #, and only does it if there's a space/nothing on either side i.e. hi#potoato wouldn't be matched
the $1 in the second argument uses the match from the replace

add <a> tag dynamically using javascript or jquery

index.html
<p class="feed-text" style="word-wrap:break-word;margin-top:10px;">testing Ist part <a style="text-decoration:underline;color:blue" href="http://www.youtube.com/watch?v=aqveRU1eAmA" target="_blank">http://www.youtube.com/watch?v=aqveRU1eAmA</a> testing 2nd part</p>
I want to add an <a> tag for "testing 2nd part" dynamically using java-script or iquery.
Is it possible.
Looks like you want to wrap text: http://jsfiddle.net/h9rxq/
$('p').contents().filter(function(){
return this.nodeType === 3;
}).wrap(function(){
return $('<a/>', {href: "anyURL"});
});
A solution in jQuery using split and join to find the text testing 2nd part in all <p> tags and replace them with <a>testing 2nd part</a>
$("p:contains('testing 2nd part')").html(function(_, html) {
return html.split('testing 2nd part').join("<a>testing 2nd part</a>");
});
In your question you do not have a starting <p> tag add it like so:
<p>
testing Ist part
<a style="text-decoration:underline color:blue" href="http://www.youtube.com/watch?v=aqveRU1eAmA" target="_blank">http://www.youtube.com/watch?v=aqveRU1eAmA</a>
testing 2nd part
</p>

How do I write the following as a regular expression to replace multiple occurances?

Background:
I have string of html with about 10 image tags that passes through some JavaScript as a string at runtime before being injected into a containing element. The data-thumb tag of each image is slightly incorrect and needs to be altered before making it into the DOM. Here is an example:
<img src="foo_lg_db.jpg" data-large="foo_lg_db.jpg" />
<img src="bar_lg_db.jpg" data-large="bar_lg_db.jpg" />
<img src="fizz_lg_db.jpg" data-large="fizz_lg_db.jpg" />
Needs to become:
<img src="foo_tn_db.jpg" data-large="foo_lg_db.jpg" />
<img src="bar_tn_db.jpg" data-large="bar_lg_db.jpg" />
<img src="fizz_tn_db.jpg" data-large="fizz_lg_db.jpg" />
Question:
In JavaScript (jQuery is OK), how do I achieve this search and replace?
THE ANSWER:
Thanks to Mark's answer I learned that it is possible to instantiate a jQuery object before it hits the DOM so, rather than using regex, I did something like this:
var stringHtml = "<img . . .";
var div = $("<div>").html(stringHtml );
$.each(div.find('img[src]'), function () {
$(this).attr('src', $(this).attr('src').replace('_lg', ''));
});
return div.html();
$('img[data-thumb]').each(function() {
$(this).attr('data-thumb', $(this).attr('data-thumb').replace('_lg_','_tn_'));
});
Something like that in jQuery.
Sounds like a problem you should be fixing server-side if possible though.
If you give jQuery an HTML element like $('<div>') it will essentially create the HTML element for you and then you can manipulate it before inserting it into your DOM. I don't know if it will handle multiple elements, but you can create a container first (like above) and then set the content like so
$('<div>').html(yourHtml).find('img[data-thumb'])./* code above */

How to pick out classes that start with a particular string

This might be hard to explain, but I need a way to loop through a bunch of elements I've already selected and for each one find classes that start with the word "icon". So for example I might have the following elements
<div class="button iconStar"></div>
<div class="button iconPlus"></div>
<div class="button iconLeft"></div>
<div class="button iconRight"></div>
<div class="button iconUp"></div>
<div class="button iconDown"></div>
So, I begin by selecting the elements and looping through them....
$(".button").each(function(){
// Some code here
});
Now, I could put the following code in the loop...
if ($(this).hasClass("iconStar")){
$(this).append("<IMG SRC='Images/star.gif'>");
}
I would then have to repeat that for each possible icon, which seems very inefficient.
What I'd like to do in the "each" loop is just cycle through all the classes that $(this) has and pick out the one that begins with ICON and then use that to append the image.
Can anyone help?
I recommend against using classes if you're not going to associate the class with the image. (which would be the most correct way) What I would do instead is put a link to the image in the rel tag.
This does what you want, and will still validate as valid css.
<div class="button" rel="images/star.jpg">iconStar</div>
<div class="button" rel="images/plus.jpg">iconPlus</div>
<div class="button" rel="images/left.jpg">iconLeft</div>
<div class="button" rel="images/right.jpg">iconRight</div>
<div class="button" rel="images/up.jpg">iconUp</div>
<div class="button" rel="images/down.jpg">iconDown</div>
<script>
$('.button').each(function() {
$(this).append("<img src='"+$(this).attr('rel')+"'>");
});
</script>
See the example here: http://jsbin.com/acasu
Note, if you're using a lot of tiny images, you're going to want to use CSS Sprites. As it will greatly improve the performance of your page.
If you absolute had to do it the way you are suggesting, you could do the following:
$(".button[class^='button icon']").each(function() {
var iconSrc = $(this).attr('class').substr("button icon".length)
$(this).append("<img src='/images/"+iconSrc+".jpg'>");
});
For each element, get the value of the class attribute, split it by ' ', take the second part and call the image.
From the top of my head
$(".button[class^='button icon']").each(function (el) {
classStr = el.className;
classes = classStr.split(' ');
image = 'images/' + classes[1] + '.jpg';
});
Not entirely sure of the syntax, bit rusty!
Try using this selector:
$(".button[class^='button icon']")
This should select only elements that have the class button, and also have a class that start with 'icon'.
Of course, this selector also assumes that your CSS class always begins with "button" first and not "icon".

Categories