jQuery Mixing on.click with contains and exact match - javascript

Need a possibility to get the exact match of a search string in a on.click handler. This is what I have now,
$("#wrapper").on("click", "label:contains('SEARCH') ~ .material > .icon", function (e) {
Problem is, that "contains" matches all words with Label containing "SEARCH".
E.g. "Search", "Searchsting", "Searchsentence" and so on....
Any ideas?? Have spent a lot of time, to find a solution. E.g. mixing :contains(''):not(:contains). But with no success.
<div class="wrapper">
<div class="field dco-uncommon has-required required dco-enabled" id="bss_options_5283" depend-id="20652" style="display: block;">
<label class="label" for="select_5283"><span>SEARCH</span></label>
<div class="control ">
<select name="options[5283]" id="select_5283" class="product-custom-option admin__control-select required" data-selector="options[5283]" aria-required="true">
<option value="">-- Please choose --</option>
<option value="75108" price="0" depend-id="20659">Option 1</option>
<option value="75111" price="35" depend-id="20662">Option 2</option>
</select>
</div>
<div class="material">
<span class="icon" style="background-image: url(amethyst_1646165.jpg)" data-title="Amethyst 1646165" title="Amethyst 1646165"></span>
<span class="icon" style="background-image: url(apfel_1644435.jpg)" data-title="Apfel 1644435" title="Apfel 1644435"></span>
<span class="icon" style="background-image: url(auster_1644480.jpg)" data-title="Auster 1644480" title="Auster 1644480"></span>
<span class="icon" style="background-image: url(azure_1641085.jpg)" data-title="Azure 1641085" title="Azure 1641085"></span>
<span class="icon" style="background-image: url(baltic_1645155.jpg)" data-title="Baltic 1645155" data-properties="" title="Baltic 1645155"></span>
</div>
</div>
</div>

The logic you're looking for is not supported by jQuery, so I was able to get this library that extends jQuery and gives you exactly what you're looking for:
https://blog.mastykarz.nl/jquery-regex-filter/
This library allows you to use regex to filter values in your elements:
Then here we are using normal javascript regex to match the exact word: ^SEARCH$
// extend jquery
jQuery.extend(
jQuery.expr[':'], {
regex: function(a, i, m, r) {
var r = new RegExp(m[3], 'i');
return r.test(jQuery(a).text());
}
}
);
// extend jquery
$(function() {
$("#wrapper").on("click", `label:regex('^SEARCH$')`, function (e) {
console.log('This label contains the exact string "SEARCH"')
})
});
#wrapper {
height: auto;
width: 200px;
background-color: #DDDDDD;
padding: 2px;
}
label {
display: block;
background-color: white;
padding: 3px;
margin: 2px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="wrapper">
<label for="">SEARCH</label>
<label for="">SEARCHstring</label>
<label for="">stringSEARCHother</label>
<label for="">stringsearchother</label>
<label for="">SEARCH</label>
</div>

Related

How to do addEventListener click or change for select dropdown?

I have select option, but not so simple...
Anything what i try with addEventListener doesn't work
I need to addEventListener('change') on changes of select, or i need addEventListener('click') on select option in dropdown list
const material = document.querySelector('.calc_custom_select');
console.log(material)
material.addEventListener("change", () => {
console.log('yeap')
})
<select class="calc_custom_select selectized" placeholder="Choose" name="calc_slopes" data-price_per_item="625.86" data-quantity="1" tabindex="-1" style="display: none;"><option value="backlit" selected="selected">bakclit</option></select>
<option value="backlit" selected="selected">backlit</option>
<div class="selectize-control calc_custom_select single">
<div class="selectize-input items full has-options has-items">
<div class="item" data-value="banner">banner</div>
<input type="text" autocomplete="off" tabindex="" style="width: 4px;"></div><div class="selectize-dropdown single calc_custom_select" style="display: none; width: 300px; top: 50px; left: 0px;"><div class="selectize-dropdown-content"></div></div></div>

Javascript style not overwriting css

I have a simple HTML drawer that contains product recommendations. Javascript is used to toggle it open and close. In the HTML, there are 2 prices, the regular price and the discounted price. Both are visible on load. The JS is supposed to hide the discounted price(current price), if the current price is the same as the old price. Because then it's not necessary to show both(identical prices). But if there is an offer, it's supposed to show both.
The problem is, my javascript for opening and closing the drawer is working, but the code for hiding/showing both prices aren't. And I know the code is fine because it works on another product recommendation template I'm using(which isn't a drawer, but normal on-page element).
I've tried putting the price-code before the drawer-function code, but then the drawer doesn't respond to clicks and does not open anymore.
When I use Preview in the software I'm using to inject product recommendations(Dynamic Yield), the prices are shown correctly. It's only when I preview it on the website itself, that it doesn't work. Both prices are shown even if they match.
Here is the JS:
(function() {
var container = document.querySelectorAll('.dy-sliding-drawer-container')[0];
var handler = container.querySelector('.dy-sliding-handle');
function toggle() {
if (container.className.indexOf('dy-open') > -1) {
container.className = container.className.replace('dy-open','');
} else {
container.className = container.className.trim() + ' dy-open';
}
}
handler.addEventListener('click', function(e) {
e.preventDefault();
e.stopPropagation();
toggle();
});
})();
var mq = window.matchMedia( "(max-width: 599px)" );
var itemPrices = document.querySelectorAll('.price-box');
for(var i=0; i<itemPrices.length; i++){
var discount_price_element = itemPrices[i].getElementsByClassName("dynamic-price")[0];
var price_element = itemPrices[i].getElementsByClassName("regular-price")[0];
if(parseFloat(discount_price_element.innerHTML) == parseFloat(price_element.innerHTML)){
discount_price_element.style.display = "none";
if (mq.matches) {
price_element.style.fontSize = "16px";
price_element.style.paddingTop = "15px";
} else {
price_element.style.fontSize = "20px";
}
price_element.style.fontWeight = "700";
} else {
price_element.style.textDecoration = "line-through";
price_element.style.paddingLeft = "10px";
}
}
Is there anything I can do to make both codes work together? I've tried putting them in the same function, with no luck.
Here is the HTML(I guess the only relevant code here is the .price-box div, but I'm gonna paste everything in case you need it):
<div>
<div class="dy-sliding-drawer-container" data-dy-strategy-container="">
<div class="dy-sliding-handle">
<div class="dy-sliding-handle-text">
${Title}
</div>
</div>
<div class="dy-sliding-items-container dy-open">
${#Recommendation}
<a href="${Item Link}" class="dy-rv-rcom-item">
<div class="dy-rv-rcom-item-image-container item-${SKU}" style=" background-image: url(${Item Image}); background-size: cover;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;min-height: 50px;
min-width: 50px;">
</div>
<div class="dy-rv-rcom-item-name">${Item Name}</div>
<div class="dy-rv-rcom-item-price">
<div class="price-box">
<span class="dynamic-price">${product_price_dynamic},-</span>
<span class="regular-price">${price},-</span>
</div>
</div>
<!-- button -->
<div class="product-item-actions add-to-cart-button-dy">
<div class="actions-primary">
<form data-role="tocart-form" action="https://www.norli.no/checkout/cart/add/uenc/${uenc}/product/${product_id}/" method="post">
<input type="hidden" name="product" value="${product_id}" tabindex="0">
<input type="hidden" name="uenc" value="${uenc}" tabindex="0">
<input name="form_key" type="hidden" value="${formkey}" tabindex="0">
<button type="submit" title="Handlekurv" class="action tocart primary" tabindex="0">
<span class="tocart--short">Legg til</span>
</button>
</form>
</div>
</div>
<div class="product actions product-item-actions read-more-button-dy" style="display: none !important;">
<div class="actions-primary">
<div class="fieldset">
<div class="actions">
<span class="out-of-stock-view-more lesmer-button" style="color:#FFF; display: none !important;">Les mer</span>
</div>
</div>
</div>
</div>
<!-- button end -->
</a>
${/Recommendation}
</div>
</div>
</div>
And if the CSS is needed, heres is the CSS for the relevant classes(old price and new price:
.price-box{
display: flex;
align-items: flex-end;
}
.dynamic-price{
color:#dd1768;
font-size:18px;
font-weight:700;
letter-spacing:-1.5px !important;
padding-bottom:0px !important;
margin-bottom:0px !important;
}
.regular-price{
font-size:14px;
letter-spacing:-1px !important;
padding-bottom:0px !important;
margin-bottom:0px !important;
font-weight: 400;
}
Could anybody help me out? Keep in mind that the Javascript works fine for recommendation widgets which loads on-page, but not with this click-to-open drawer. Appreciate any help.
Your script does basically work - provided the variables in your template have been
replaced by actual values before the markup is rendered into the DOM. I have modified your data a little bit to demonstrate the correct behaviour on some same-price and some differing-price .price-box examples.
I also took the liberty of shortening your very verbose scripts. I have probably gone a bit too far, especially my .reduce() construct is not easy to read. But look at it as an extreme way of avoiding creating variable names.
(function(){
var container = document.querySelector('.dy-sliding-drawer-container');
container.querySelector('.dy-sliding-handle').onclick=e=>
container.classList.toggle("dy-open");
})();
// var mq = window.matchMedia( "(max-width: 599px)" );
document.querySelectorAll('.price-box').forEach(p=>{
[...p.querySelectorAll("span")].reduce((a,c)=>a.style.display=(a.textContent==c.textContent?"none":""))});
.dy-open {background-color:yellow}
.price-box{
display: flex;
align-items: flex-end;
}
.dynamic-price{
color:#dd1768;
font-size:18px;
font-weight:700;
letter-spacing:-1.5px !important;
padding-bottom:0px !important;
margin-bottom:0px !important;
}
.regular-price{
font-size:14px;
letter-spacing:-1px !important;
padding-bottom:0px !important;
margin-bottom:0px !important;
font-weight: 400;
}
<div>
<div class="dy-sliding-drawer-container" data-dy-strategy-container="">
<div class="dy-sliding-handle">
<div class="dy-sliding-handle-text">
${Title}
</div>
</div>
<div class="dy-sliding-items-container">
${#Recommendation}
<a href="#${Item Link}" class="dy-rv-rcom-item">
<div class="dy-rv-rcom-item-image-container item-${SKU}" style=" background-image: url(${Item Image}); background-size: cover;
-webkit-background-size: cover;
-moz-background-size: cover;
-o-background-size: cover;min-height: 50px;
min-width: 50px;">
</div>
<div class="dy-rv-rcom-item-name">${Item Name}</div>
<div class="dy-rv-rcom-item-price">
<div class="price-box">
<span class="dynamic-price">50,-</span>
<span class="regular-price">50,-</span>
</div>
</div>
<div class="dy-rv-rcom-item-name">${Item Name}</div>
<div class="dy-rv-rcom-item-price">
<div class="price-box">
<span class="dynamic-price">50,-</span>
<span class="regular-price">60,-</span>
</div>
</div>
<div class="dy-rv-rcom-item-name">${Item Name}</div>
<div class="dy-rv-rcom-item-price">
<div class="price-box">
<span class="dynamic-price">60,-</span>
<span class="regular-price">60,-</span>
</div>
</div>
<!-- button -->
<div class="product-item-actions add-to-cart-button-dy">
<div class="actions-primary">
<form data-role="tocart-form" action="https://www.norli.no/checkout/cart/add/uenc/${uenc}/product/${product_id}/" method="post">
<input type="hidden" name="product" value="${product_id}" tabindex="0">
<input type="hidden" name="uenc" value="${uenc}" tabindex="0">
<input name="form_key" type="hidden" value="${formkey}" tabindex="0">
<button type="submit" title="Handlekurv" class="action tocart primary" tabindex="0">
<span class="tocart--short">Legg til</span>
</button>
</form>
</div>
</div>
<div class="product actions product-item-actions read-more-button-dy" style="display: none !important;">
<div class="actions-primary">
<div class="fieldset">
<div class="actions">
<span class="out-of-stock-view-more lesmer-button" style="color:#FFF; display: none !important;">Les mer</span>
</div>
</div>
</div>
</div>
<!-- button end -->
</a>
${/Recommendation}
</div>
</div>
</div>
Explanation:
The .reduce() over all the <span>s in a .price-box div relies on the fact that the "reduced price" span always comes before the "regular price" one and that you will always have exactly two elements. When reduce() is called without the second (starting value) argument it takes the first array element (the "reduced price" span) as the starting value (a). The (only) "current" value in the iteration (c) will then be the regular price span. When the .textContent of both elements are the same the a span will be hidden, otherwise it will remain visible.

How do I toggle the background colors within a list of divs?

From a list of items, each in separate divs, the user can select and click only one. The background color should change on the selected one. If the user changes their mind, they can select another one, and the background color should change to the selected color and all the other divs on the list should change back to the default background color.
It's basically the same logic as a radio button on a form. Only one can be selected at a time.
How do I achieve this?
I have attempted to use the element.classList.toggle property. But it only handles each individually. Are there a javascript command(s) to handle this?
<style>
.teamSelected{
background-color: red;
border-radius: 4px;
}
</style>
<div onclick="toggleBackground(team1)">
<div id="team1">
</div>
</div>
<div onclick="toggleBackground(team2)">
<div id="team2">
</div>
</div>
<div onclick="toggleBackground(team3)">
<div id="team3">
</div>
</div>
<script>
function toggleBackground(teamnumber) {
var element = document.getElementById(teamnumber);
if (element) {
element.classList.toggle("teamSelected");
}
}
</script>
Thanks!
You are passing variables to the function, which don't exist. You need to put them in quotes, because the function is expecting strings.
const allDivs = document.querySelectorAll('.div');
function toggleBackground(teamnumber) {
var element = document.getElementById(teamnumber);
if (element) {
allDivs.forEach(function(el){
el.classList.remove('teamSelected');
});
element.classList.add("teamSelected");
}
}
.toggle > div {
width: 100px;
height: 100px;
border: 1px solid #000;
}
.teamSelected {
background-color: red;
border-radius: 4px;
}
<div onclick="toggleBackground('team1')" class="toggle">
<div id="team1" class="div">
</div>
</div>
<div onclick="toggleBackground('team2')" class="toggle">
<div id="team2" class="div">
</div>
</div>
<div onclick="toggleBackground('team3')" class="toggle">
<div id="team3" class="div">
</div>
</div>
seems like this is something you want?
let x = ('.something');
$(x).on('click', function(){
$(x).css('background','blue');
$(this).css('background', 'green');
});
.something{
width: 100px;
height: 100px;
background: yellow
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<div class="something">
<div id="team1">
</div>
</div>
<div class="something">
<div id="team2">
</div>
</div>
<div class="something">
<div id="team3">
</div>
</div>

Changing multiple textareas css values with javascript and dropdown?

http://jsfiddle.net/g3u7hxr6/4/
I have this following code, currently it changes all textareas css values with the dropdown boxes.
I want it so that when 1 textarea is selected and glowing green, the dropdown boxes will only change the css for the selected textarea rather than all of them.
Basically I want to be able to change each text area font individually.
I considered using another dropdown box to select which textarea to change. but there must be a way for the javascript to detect the selected textarea and make changes to it only. I would need to add a unique id field to each textarea but i'm completely lost with the javascript. please help!!!
Answered thanks to Binvention:
http://jsfiddle.net/g3u7hxr6/19/
JS:
$(function () {
$("[id^=font]").on('change', function () {
$('.address').css(this.id, /\d/.test(this.value) ? this.value + "px" : this.value);
});
});
$('.address').focus(
function(){
$(this).parent('div').css('box-shadow','0px 0px 10px green');
}).blur(
function(){
$(this).parent('div').css('box-shadow','0px 0px 0px');
});
HTML:
<div class="options">
<div class="left">Font:
<br>Size:
<br>Weight:</div>
<div class="right">
<select name="fontFamily" id="fontFamily">
<option selected value="Verdana">Verdana</option>
<option value="Arial">Arial</option>
</select>
<br>
<select name="fontSize" id="fontSize">
<option value="8">8</option>
<option selected value="16">16</option>
<option value="24">24</option>
</select>
<br>
<select name="fontWeight" id="fontWeight">
<option selected value="Bold">Bold</option>
<option value="Normal">Normal</option>
</select>
<br /> <br />
</div>
<div class="page">
<div class="left border">
<textarea class="address" tabindex="1">text area 1</textarea>
</div>
<div class="right border">
<textarea class="address" tabindex="4">text area 4</textarea>
</div>
<div class="left border">
<textarea class="address" tabindex="2">text area 2</textarea>
</div>
<div class="right border">
<textarea class="address" tabindex="5">text area 5</textarea>
</div>
<div class="left border">
<textarea class="address" tabindex="3">text area 3</textarea>
</div>
<div class="right border">
<textarea class="address" tabindex="6">text area 6</textarea>
</div>
</div>
CSS:
.left {
float: left;
}
.right {
float: right;
}
.options {
width: 200px;
}
.page {
width: 440px;
}
.border {
border:1px solid #888;
border-radius: 5px;
padding: 5px;
margin: 0 0px 0px 0;
}
textarea {
resize:none;
height: 100px;
width: 200px;
overflow: auto;
font-family: Verdana;
font-size: 16px;
}
You need to create a unique class that marks one as selected like this
$('textarea').click(function(){
$(this).toggleClass('textselected');
});
That will allow you to dynamically pick which text boxes your editing just click to edit click to deselect from editing. You'll need some css to distinguish selected from not selected though.
Then when you edit the font and text properties you use that special class not the text areas to select the property like this
$("[id^=font]").on('change', function () {
$('.textselected').css(this.id, /\d/.test(this.value) ? this.value + "px" : this.value);
});
});
I have edited your fiddle with the necessary changes here
You need to add $(this).addClass('selected'); within your focus event and change the selector to $('.address.selected') within your change event.

How to make width of <select> element proportional to <div> element

Now, I would like to make width of my select element, let's say 80% of its parent div ( div#queries). Is there anyway to do it?
<div id="flowchart-left-panel">
<div id ="queries">
<h3>Queries</h3>
<select class="query-list" size="20">
</select>
</div>
<div id="filters">
<h3>Filters</h3>
<select class="filter-list" size="10">
</select>
</div>
</div>
Of course, with CSS.
Demo here: http://codepen.io/anon/pen/JYYGvG
#queries, #filters{
width: 300px;
}
select{
width: 80%;
}

Categories

Resources