PDA

View Full Version : JavaScript Assistance Required



simonf
02-08-2017, 10:22 AM
What I need assistance with is the following...

I require to do is show alternative currencies based on the exchange rates of the time when the person goes to the page on each and every property listing we have.

Our Website URL : http://www.silvertreeestates.co.za if you want to take a look :rolleyes:

So I can get the actual updated info for the exchange rates by going to this URL : http://api.fixer.io/latest?base=ZAR

Now I just need assistance with the actual JavaScript to pull this info and then the HTML code to display it on my page next to each property listing as below example, as my JavaScript ability is limited, so I would need the script element and the HTML element that goes on each listing price:

Example Current :
6095

What I would like to see :
6096

HTML Code currently for that section:


<!-- Property Listing Start -->
<div><img src="img/navi.jpg" width="700" height="2" alt="">
<table style="width: 100%"><tr><td style="width: 450px" class="text-left">
<a href="http://www.property24.com/Search/RedirectToListing.aspx?listingNumber=104599615" target="_blank">
<img src="img/listing/104599615.jpg" width="450" height="253" alt="" class="bw pic tilt">&nbsp;</a>
</td></tr><tr><td>
<h1>Little Falls</h1>
<h2>ZAR 2,429,999</h2>
<h2><i class="iconsprite loungesprite"></i> 4<i class="iconsprite bedsprite"></i> 3<i class="iconsprite bathsprite"></i> 2.5
<i class="iconsprite garagesprite"></i> 2<i class="iconsprite swimsprite"></i> 1<i class="iconsprite erfsprite">
</i> 1,004m<i class="iconsprite sizesprite"></i> 390m</h2>
</td></tr></table></div>
<!-- Property Listing End -->


All help will be greatly appreciated, and many thanks in advance. rgds, Simon

jscheuer1
02-08-2017, 05:59 PM
Put this script at the end of the page, just before the closing </body> tag:


<script>
jQuery(function($){
function commatize(num){
num = Math.ceil(num).toString(10).split('').reverse();
var n = num.length, i = -1, newnum = [];
while(++i < n){
!(i%3) && i && newnum.push(',');
newnum.push(num[i]);
}
return newnum.reverse().join('');
}

jQuery.fn.currencyrates = function(rates){
var base = this.text().replace(/\D/g, '');
this.append ([' ~ <span class="usd">US$ ', commatize(base * rates.USD), '</span>',
' ~ <span class="gpb">GBP ', commatize(base * rates.GBP), '</span>',
' ~ <span class="eur">EUR ', commatize(base * rates.EUR), '</span>'].join(''));
}

$.getJSON('http://api.fixer.io/latest?base=ZAR', function(data){
$('.divborder.col-md-8 h2').not(':has(i)').each(function(i, z){
$(z).currencyrates(data.rates);
});
});
});
</script>

Any questions or problems let me know. The script can be made external (in the usual manner, by removing its script tags and placing in an external file), but should still go at the end of the page.

Demo:

http://plnkr.co/edit/ylAS8llM8hwOG0hdFUoK?p=preview

You may need to widen the column that shows the result, otherwise it might be a little horizontally squished.

simonf
02-09-2017, 09:19 AM
HI John

That is so cool... many thanks... I put icons in the script, hope I got that right.... if I want to use a imagesprite in the script, how would I do that??



jQuery(function($){
function commatize(num){
num = Math.ceil(num).toString(10).split('').reverse();
var n = num.length, i = -1, newnum = [];
while(++i < n){
!(i%3) && i && newnum.push(',');
newnum.push(num[i]);
}
return newnum.reverse().join('');
}

jQuery.fn.currencyrates = function(rates){
var base = this.text().replace(/\D/g, '');
this.append ([' , <span class="usd"><img src="img/usd-icon.png" width="20" height="20" alt=""> $ ', commatize(base * rates.USD), '</span>',
' , <span class="gpb"><img src="img/uk-icon.png" width="20" height="20" alt=""> ', commatize(base * rates.GBP), '</span>',
' , <span class="eur"><img src="img/euro-icon.png" width="20" height="20" alt=""> ', commatize(base * rates.EUR), '</span>'].join(''));
}

$.getJSON('http://api.fixer.io/latest?base=ZAR', function(data){
$('.divborder.col-md-8 h2').not(':has(i)').each(function(i, z){
$(z).currencyrates(data.rates);
});
});
});


But in the meantime I cannot thanks you enough mate....

rgds, Simon :o

jscheuer1
02-09-2017, 10:08 AM
I see that you've placed:


<script data-require="jquery@2.2.4" data-semver="2.2.4" src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script><script src="exchange.js"></script>


after every listing it looks like, or a lot of them. You don't need any of those. You only need what you already have at the end of the page.

As to sprites:

Hmm, I'm not all that up on imagesprites. I mean I know that a sprite is usually a background image that is composed of two or more images in one and that the image you see is set by the size of the element having the sprite as a background image and by the background position style on that element. As you can see, you can put any HTML you like into the currencyrates function. So you just need to put the elements in there that would have the sprite and set their background-image, background-position, and dimensions in style. One other consideration, their display style property should probably be inline-block for that because you want them to be able to have width and height but not cause a line break. So something like:


jQuery.fn.currencyrates = function(rates){
var base = this.text().replace(/\D/g, '');
this.append ([' , <span class="usd"><span class="curr-ico"></span> $ ', commatize(base * rates.USD), '</span>',
' , <span class="gpb"><span class="curr-ico"></span> ', commatize(base * rates.GBP), '</span>',
' , <span class="eur"><span class="curr-ico"></span> ', commatize(base * rates.EUR), '</span>'].join(''));
}

Then in your stylesheet you could have something like so (assuming your image sprite is named as indicated):


.curr-ico {
width: 20px;
height: 20px;
background-image: url('img/curr-ico-sprite.png');
display: inline-block;
}
.usd .curr-ico {
background-position: 0;
}
.gbp .curr-ico {
background-position: 0 20px;
}
.eur .curr-ico {
background-position: 0 40px;
}

The actual positioning would have to correspond to what works best with your image sprite, which you would have to make (or find one) to be suitable for that purpose.

simonf
02-09-2017, 12:23 PM
Many thanks again... let me work on that and revert back if required, again many thanks :)

simonf
02-10-2017, 06:40 AM
Hi John

I managed to get it working 100% to my liking with the imgsprite etc... although knowing myself I will most likely makes some small changes over the next week or so as I tweak the site ROFL :cool:

For all those interested in the final outcome here is the end result which you can see in action on our website : http://www.silvertreeestates.co.za/#littlefalls

The JavaScript is :



<script>
jQuery(function($){
function commatize(num){
num = Math.ceil(num).toString(10).split('').reverse();
var n = num.length, i = -1, newnum = [];
while(++i < n){
!(i%3) && i && newnum.push(',');
newnum.push(num[i]);
}
return newnum.reverse().join('');
}

jQuery.fn.currencyrates = function(rates){
var base = this.text().replace(/\D/g, '');
this.append ([' : <span class="usd"><span class="exchangesprite usdsprite"></span> $ ', commatize(base * rates.USD), '</span>',
' : <span class="gpb"><span class="exchangesprite gbpsprite"></span> ', commatize(base * rates.GBP), '</span>',
' : <span class="eur"><span class="exchangesprite eurosprite"></span> ', commatize(base * rates.EUR), '</span>'].join(''));
}

$.getJSON('http://api.fixer.io/latest?base=ZAR', function(data){
$('.divborder.col-md-8 h2').not(':has(i)').each(function(i, z){
$(z).currencyrates(data.rates);
});
});
});
</script>


CSS For the "imgsprite" :


.exchangesprite{background:url("../../img/exchangesprite.png") no-repeat}
.zarsprite{background:url('../../img/exchangesprite.png') no-repeat -0px -8px;width:20px;height:21px;margin-left:10px;display:inline-block}
.usdsprite{background:url('../../img/exchangesprite.png') no-repeat -0px -31px;width:20px;height:21px;margin-left:10px;display:inline-block}
.gbpsprite{background:url('../../img/exchangesprite.png') no-repeat -0px -54px;width:20px;height:21px;margin-left:10px;display:inline-block}
.eurosprite{background:url('../../img/exchangesprite.png') no-repeat -0px -77px;width:20px;height:21px;margin-left:10px;display:inline-block}


And the imgsprite I'm using for this :
6097

Many thanks again John... rgds, Simon

jscheuer1
02-10-2017, 11:22 AM
That's great! I always wonder why in the css sprites are often done that way. I suppose it might have something to do with older browsers, though I doubt that page would work very well with them anyway. But perhaps even some modern browsers might need that. My thinking though, since css is cascading, it would seem more efficient to use this css:


.exchangesprite{background:url("../../img/exchangesprite.png") no-repeat;width:20px;height:21px;margin-left:10px;display:inline-block}
.zarsprite{background-position:0 -8px}
.usdsprite{background-position:0 -31px}
.gbpsprite{background-position:0 -54px}
.eurosprite{background-position:0 -77px}

Also, with the javascript, since you don't appear to be using the spans or the classes I put in there originally, those could be dropped:


<script>
jQuery(function($){
function commatize(num){
num = Math.ceil(num).toString(10).split('').reverse();
var n = num.length, i = -1, newnum = [];
while(++i < n){
!(i%3) && i && newnum.push(',');
newnum.push(num[i]);
}
return newnum.reverse().join('');
}

jQuery.fn.currencyrates = function(rates){
var base = this.text().replace(/\D/g, '');
this.append ([' : <span class="exchangesprite usdsprite"></span> $ ', commatize(base * rates.USD),
' : <span class="exchangesprite gbpsprite"></span> ', commatize(base * rates.GBP),
' : <span class="exchangesprite eurosprite"></span> ', commatize(base * rates.EUR)].join(''));
}

$.getJSON('http://api.fixer.io/latest?base=ZAR', function(data){
$('.divborder.col-md-8 h2').not(':has(i)').each(function(i, z){
$(z).currencyrates(data.rates);
});
});
});
</script>

But, no need to mess with either of those things if it currently works as desired.

simonf
02-10-2017, 01:19 PM
HI John

With the "imgsprite", when I started using them I found the following.

width:20px;height:21px this is needed to define the size/part of the img you need. The initial position "background-position:0 -8px" defines the top left hand starting point, then your saying you want a part of the img from this starting point of 20px x 21px (or whatever you need etc) this then defines the img to display.

I use a nice website online tool called sprite___ :cool: to help me define my sprites. upload an image and choose the section you want and it provides the settings....

Remember you can have different imgs on one actual img... so that's why I define on each part needed

Sample:
6099
the the css code looks like this:


.oddsprite{background:url("../../img/oddsprite.png") no-repeat}
.qrsprite{background:url('../../img/oddsprite.png') no-repeat -234px -25px;width:126px;height:127px;display:inline-block}
.onshowsprite{background:url('../../img/oddsprite.png') no-repeat -9px -375px;width:302px;height:28px;display:inline-block}
.navi4sprite{background:url('../../img/oddsprite.png') no-repeat 0 -36px;width:189px;height:2px;display:inline-block}
.navi6sprite{background:url('../../img/oddsprite.png') no-repeat 0 0;width:374px;height:2px;display:inline-block}
.noshowsprite{background:url('../../img/oddsprite.png') no-repeat -9px -375px;width:302px;height:102px;display:inline-block}
.nolistsprite{background:url('../../img/oddsprite.png') no-repeat -8px -168px;width:301px;height:172px;display:inline-block}
.pendingsprite{background:url('../../img/oddsprite.png') no-repeat -335px -167px;width:28px;height:210px;display:inline-block}
.p24sprite{background:url('../../img/oddsprite.png') no-repeat 0 -59px;width:83px;height:27px;display:inline-block}
.emailsprite{background:url('../../img/oddsprite.png') no-repeat -125px -53px;width:48px;height:45px;display:inline-block}


The next section "display:inline-block}" is needed to actual display the imgsprite on your site....

Fixed the JS as well ;)

rgds, Simon

jscheuer1
02-10-2017, 03:36 PM
That's what I thought, it's auto-generated. Often you get inefficient code that way. The shortened css I wrote in my previous post should yield the same results. But, again, as I said, as long as it's working, no need to change it. But, for the ones that all use the same background image, why define it more than once? For the ones that all have the same width and height, why define that over and over? And the other common attributes of no-repeat on the bg and using display inline-block. It's all so repetitious.

simonf
02-11-2017, 08:41 AM
Hi John

I understand your input.. re repetition...

So I guess the question is do you have some script for me to do that to stop the repetition?? :o

If you would be so kind as always... I'm always looking for ways to improve the site... but as I said previously my JS is basically none existent mate so pretty please with a cherry on top, if you can assist me. :o

jscheuer1
02-11-2017, 04:23 PM
No, not a script, just take care of it. Or not. You seem to like all your code as slimmed down as possible, but you don't want to break your sprites, so it's really up to you. If you decide to try out sliming them down, be sure to keep a backup of your working sprites and, to be on the safe side, also a backup copy of each of your entire working css files before you start.

As far as the exchange sprites go though, you could start with my recommendations:


.exchangesprite{background:url("../../img/exchangesprite.png") no-repeat;width:20px;height:21px;margin-left:10px;display:inline-block}
.zarsprite{background-position:0 -8px}
.usdsprite{background-position:0 -31px}
.gbpsprite{background-position:0 -54px}
.eurosprite{background-position:0 -77px}

Just be sure to keep a backup. As you can see, anything that's repeated exactly in the more specific definitions can be moved to only appear in the overall definition. You can use this as a sort of template for other sprites. Also make sure not to inadvertently overwrite anything from the overall definition. Notice how in the overall definition above I use the shorthand "background" property which will set any and everything in the background* whether it's mentioned or not. When I get to the specific definitions, since all I want to redefine is "background-position", I use that more specific property name.


* Because of that, these can be condensed even a little further:


.exchangesprite{background:url("../../img/exchangesprite.png") no-repeat 0 -8px;width:20px;height:21px;margin-left:10px;display:inline-block}
.usdsprite{background-position:0 -31px}
.gbpsprite{background-position:0 -54px}
.eurosprite{background-position:0 -77px}

The zarsprite is now identical to the overall definition, so needs no further css code, the others simply redefine the background-position, since that's all that changes for them. In fact, once this change is made, you no longer need use the class name zarsprite in the HTML code, but it might be good to keep it for clarity's sake. Other sprites I see you have feature more variety in their definitions, so cannot be compressed as much, but still can be whittled down some.

simonf
02-13-2017, 11:20 AM
Hi John

Understand what you mean now, thanks again ;)

simonf
05-09-2017, 10:49 AM
Hi John

I need your help with the script again....

I did some changes to make the sprites responsive, but now I'm getting a weird effect. Please can you take a look and advise me, thanks in advance.

6170 This is what I wanted

6171 This is what I'm getting

html property code is :


<!-- Property Listing Start -->
<div class="divborder col-md-8"><div class="divTable"><div class="divTableBody"><div class="divTableRow">
<div class="divTableCell"><a href="https://www.property24.com/for-sale/little-falls-ext-2/roodepoort/gauteng/739/105075922" target="_blank"> <img class="pic feathove" src="img/listing/105075922.jpg" alt="" width="450" height="253" />&nbsp;</a></div></div>
<div class="divTableRow"><div class="divTableCell"><h1>Little Falls</h1><h2><span class="zar"><img class="zarsprite" alt="" src="data:../../img/silversprite.png;base64,iVBORw0KGgoAAAANSUhEUgAAAB8AAAAfAQMAAAAlYIR6AAAAA1BMVEX///+nxBvIAAAAAXRSTlMAQObYZgAAAAxJREFUeNpjYBi0AAAAmwABHpy5RwAAAABJRU5ErkJggg=="></span> R 2,495,000</h2>
<h2><img class="receptionsprite" alt="" src="data:../../img/silversprite.png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAhAQMAAABtKlAsAAAAA1BMVEX///+nxBvIAAAAAXRSTlMAQObYZgAAAAxJREFUeNpjYBgOAAAAxgAB/v0USgAAAABJRU5ErkJggg==">3<img class="bedsprite" alt="" src="data:../../img/silversprite.png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAhAQMAAABtKlAsAAAAA1BMVEX///+nxBvIAAAAAXRSTlMAQObYZgAAAAxJREFUeNpjYBgOAAAAxgAB/v0USgAAAABJRU5ErkJggg==">4<img class="bathsprite" alt="" src="data:../../img/silversprite.png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAhAQMAAABtKlAsAAAAA1BMVEX///+nxBvIAAAAAXRSTlMAQObYZgAAAAxJREFUeNpjYBgOAAAAxgAB/v0USgAAAABJRU5ErkJggg==">2.5<img class="studysprite" alt="" src="data:../../img/silversprite.png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAhAQMAAABtKlAsAAAAA1BMVEX///+nxBvIAAAAAXRSTlMAQObYZgAAAAxJREFUeNpjYBgOAAAAxgAB/v0USgAAAABJRU5ErkJggg==">1<img class="garagesprite" alt="" src="data:../../img/silversprite.png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAhAQMAAABtKlAsAAAAA1BMVEX///+nxBvIAAAAAXRSTlMAQObYZgAAAAxJREFUeNpjYBgOAAAAxgAB/v0USgAAAABJRU5ErkJggg==">3<img class="swimsprite" alt="" src="data:../../img/silversprite.png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAhAQMAAABtKlAsAAAAA1BMVEX///+nxBvIAAAAAXRSTlMAQObYZgAAAAxJREFUeNpjYBgOAAAAxgAB/v0USgAAAABJRU5ErkJggg==">1<img class="coveredpsprite" alt="" src="data:../../img/silversprite.png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAhAQMAAABtKlAsAAAAA1BMVEX///+nxBvIAAAAAXRSTlMAQObYZgAAAAxJREFUeNpjYBgOAAAAxgAB/v0USgAAAABJRU5ErkJggg==">1<img class="domestic" alt="" src="data:../../img/silversprite.png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAhAQMAAABtKlAsAAAAA1BMVEX///+nxBvIAAAAAXRSTlMAQObYZgAAAAxJREFUeNpjYBgOAAAAxgAB/v0USgAAAABJRU5ErkJggg==">1
<br><img class="erfsprite" alt="" src="data:../../img/silversprite.png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAhAQMAAABtKlAsAAAAA1BMVEX///+nxBvIAAAAAXRSTlMAQObYZgAAAAxJREFUeNpjYBgOAAAAxgAB/v0USgAAAABJRU5ErkJggg==">731m<img class="sizesprite" alt="" src="data:../../img/silversprite.png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAhAQMAAABtKlAsAAAAA1BMVEX///+nxBvIAAAAAXRSTlMAQObYZgAAAAxJREFUeNpjYBgOAAAAxgAB/v0USgAAAABJRU5ErkJggg==">TBA<img class="ratesprite" alt="" src="data:../../img/silversprite.png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAhAQMAAABtKlAsAAAAA1BMVEX///+nxBvIAAAAAXRSTlMAQObYZgAAAAxJREFUeNpjYBgOAAAAxgAB/v0USgAAAABJRU5ErkJggg==">TBA<img class="levysprite" alt="" src="data:../../img/silversprite.png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAhAQMAAABtKlAsAAAAA1BMVEX///+nxBvIAAAAAXRSTlMAQObYZgAAAAxJREFUeNpjYBgOAAAAxgAB/v0USgAAAABJRU5ErkJggg==">TBA
<br><img class="smdianesprite imgsprite" alt="" src="data:../../img/silversprite.png;base64,iVBORw0KGgoAAAANSUhEUgAAAIcAAABGAQMAAADcnRVYAAAAA1BMVEX///+nxBvIAAAAAXRSTlMAQObYZgAAABJJREFUeNpjYBgFo2AUjILhDwAE7AABJ87WUwAAAABJRU5ErkJggg=="></h2></div></div><div class="divTableRow"><div class="divTableCell"><div class="social"><h4>&nbsp;</h4></div></div></div></div></div></div>
<!-- Property Listing End -->


JScript Code at bottom of my htmp page:


<script>jQuery(function($){function commatize(num){num=Math.ceil(num).toString(10).split("").reverse();var n=num.length,i=-1,newnum=[];while(++i<n){!(i%3)&&i&&newnum.push(",");newnum.push(num[i])}return newnum.reverse().join("")}jQuery.fn.currencyrates=function(rates){var base=this.text().replace(/\D/g,"");this.append([' <span class="usd"><img class="usdsprite" alt="" src="data:../../img/silversprite.png;base64,iVBORw0KGgoAAAANSUhEUgAAAB8AAAAfAQMAAAAlYIR6AAAAA1BMVEX///+nxBvIAAAAAXRSTlMAQObYZgAAAAxJREFUeNpjYBi0AAAAmwABHpy5RwAAAABJRU5ErkJggg=="></span> $ ',commatize(base*rates.USD),' <span class="gbp"><img class="gbpsprite" alt="" src="data:../../img/silversprite.png;base64,iVBORw0KGgoAAAANSUhEUgAAAB8AAAAfAQMAAAAlYIR6AAAAA1BMVEX///+nxBvIAAAAAXRSTlMAQObYZgAAAAxJREFUeNpjYBi0AAAAmwABHpy5RwAAAABJRU5ErkJggg=="></span> ',commatize(base*rates.GBP),' <span class="eur"><img class="eurosprite" alt="" src="data:../../img/silversprite.png;base64,iVBORw0KGgoAAAANSUhEUgAAAB8AAAAfAQMAAAAlYIR6AAAAA1BMVEX///+nxBvIAAAAAXRSTlMAQObYZgAAAAxJREFUeNpjYBi0AAAAmwABHpy5RwAAAABJRU5ErkJggg=="></span> ',commatize(base*rates.EUR)].join(""))};$.getJSON("http://api.fixer.io/latest?base=ZAR",function(data){$(".divborder.col-md-8 h2").not(":has(i)").each(function(i,z){$(z).currencyrates(data.rates)})})});</script>

jscheuer1
05-09-2017, 04:09 PM
Change the script to:


<script>jQuery(function($){function commatize(num){num=Math.ceil(num).toString(10).split("").reverse();var n=num.length,i=-1,newnum=[];while(++i<n){!(i%3)&&i&&newnum.push(",");newnum.push(num[i])}return newnum.reverse().join("")}jQuery.fn.currencyrates=function(rates){var base=this.text().replace(/\D/g,"");this.append([' <span class="usd"><img class="usdsprite" alt="" src="data:../../img/silversprite.png;base64,iVBORw0KGgoAAAANSUhEUgAAAB8AAAAfAQMAAAAlYIR6AAAAA1BMVEX///+nxBvIAAAAAXRSTlMAQObYZgAAAAxJREFUeNpjYBi0AAAAmwABHpy5RwAAAABJRU5ErkJggg=="></span> $ ',commatize(base*rates.USD),' <span class="gbp"><img class="gbpsprite" alt="" src="data:../../img/silversprite.png;base64,iVBORw0KGgoAAAANSUhEUgAAAB8AAAAfAQMAAAAlYIR6AAAAA1BMVEX///+nxBvIAAAAAXRSTlMAQObYZgAAAAxJREFUeNpjYBi0AAAAmwABHpy5RwAAAABJRU5ErkJggg=="></span> ',commatize(base*rates.GBP),' <span class="eur"><img class="eurosprite" alt="" src="data:../../img/silversprite.png;base64,iVBORw0KGgoAAAANSUhEUgAAAB8AAAAfAQMAAAAlYIR6AAAAA1BMVEX///+nxBvIAAAAAXRSTlMAQObYZgAAAAxJREFUeNpjYBi0AAAAmwABHpy5RwAAAABJRU5ErkJggg=="></span> ',commatize(base*rates.EUR)].join(""))};$.getJSON("http://api.fixer.io/latest?base=ZAR",function(data){$(".divborder.col-md-8 h2:has(span.zar)").each(function(i,z){$(z).currencyrates(data.rates)})})});</script>

simonf
05-10-2017, 07:21 AM
Hi John

Many thanks yet again....

One small change makes all the difference I see wow

NEW

(".divborder.col-md-8 h2:has(span.zar)")
OLD

(".divborder.col-md-8 h2").not(":has(i)")

rgds, Simon :o