Make :focus change css of another class - javascript

Let's say i have the following code:
HTML
<div class="container">
<input class="myAwesomeInputBox">
</div>
CSS
.input [type=text]:focus > .//ANY CLASS SOMEWHERE ON THE WEBSITE{
//Some sweet CSS.
}
Obviously this code doesnt work. I want some specific css to get executed when there is focus on my inputbox. Is this at all possible?
I'm not specificly looking for html/css only solutions. Any solution that can achieve this is welcome.
My code above is just an extremely simple example. My question is really simple. Is it possible to change styling on ANY element on your website using the :focus on an input box.

Using pseudo-classes (such as :hover or :focus) to modify other elements can only be done if the other elements are siblings or children of the element which has the pseudo-class. That's because CSS child/sibling selectors are fairly restrictive.
You can use the > selector to select a direct child, and the + selector to select a direct sibling. For example, if you have the following HTML:
<form>
<input type="text" />
<input type="submit" />
</form>
<p class="arbitrary">
This is an arbitrary element. It is neither a child nor sibling of
the text field. It cannot be selected as a result of a pseudo-class
action on the textfield using CSS, but can be selected using
client-side scripting such as JavaScript.
</p>
You could style the button when the text field has focus (because it is a direct sibling of the text field), but there is no possible way to style the arbitrary paragraph as a result of the text field receiving focus (because it is neither a child nor sibling, it is the sibling of a parent) without using client-side scripting (JavaScript, jQuery, etc.).
This CSS would style the submit button, and can be altered to select any direct or indirect child or sibling:
input[type="text"]:focus + input[type="submit"] {
/* some sweet CSS */
background-color:green;
}
Using Javascript, of course, you have much greater flexibility. The focusin and focusout events can be used to toggle CSS classes. Here's an example that demonstrates both the CSS and JavaScript techniques of achieving this.
function setFocused() {
document.querySelectorAll('.arbitrary').forEach((result) => {
result.classList.add('focused');
});
}
function unsetFocused() {
document.querySelectorAll('.arbitrary').forEach((result) => {
result.classList.remove('focused');
});
}
document.querySelectorAll('input[type="text"]').forEach((result) => {
result.addEventListener("focusin", setFocused);
result.addEventListener("focusout", unsetFocused);
});
input[type="text"]:focus + input[type="submit"] {
/* some sweet CSS */
background-color: green;
}
.arbitrary.focused {
/* even more sweet CSS */
color: red;
}
<form>
<input type="text" />
<input type="submit" />
</form>
<p class="arbitrary">
This is an arbitrary element. It is neither a child nor sibling of
the text field. It cannot be selected as a result of a pseudo-class
action on the textfield using CSS, but can be selected using
client-side scripting such as JavaScript.
</p>
Here's the jQuery equivalent of the above code, if that's your jam.
$('input[type="text"]').on('focus', function() {
$('.arbitrary').addClass('focused');
});
$('input[type="text"]').off('focus', function() {
$('.arbitrary').removeClass('focused');
});
Note that if you decide you want to do something similar, except using a "hover" trigger rather than "focus", you can use the JavaScript mouseover and mouseout functions, or the jQuery .hover() function which takes two arguments (a handler for entering the hover and another for leaving the hover).

Maybe add a ID
<div class="container">
<input class="myAwesomeInputBox" id='myAwesomeId' type="text">
</div>
and add and remove a class like this.
Wont that solve your problem.
$('#myAwesomeId').on({
focus: function () {
$(this).addClass('focused');
},
blur: function () {
$(this).removeClass('focused');
}
});
CSS
input.focused {
border:3px solid blue;
}
FIDDLE

If the element css which you want to change is sibling, you can use like this,
<div class="container">
<input class="myAwesomeInputBox">
<div className="dls-sibling">
</div>
.myAwesomeInputBox:focus ~.dls-sibling {
&::before {
transform: scale(1);
border-color:red;
}
}

Related

How to Target This Sibling CSS via Javascript

How to target via Javascript where the original HTML will have additional .checkmark-disabled class like the desire output.
Original HTML 1
<div>
<input type="checkbox" disabled>
<span class="checkmark">
</div>
Original HTML 2
<div>
<input type="checkbox">
<span class="checkmark">
</div>
Desire Output
<div>
<input type="checkbox" disabled>
<span class="checkmark checkmark-disabled">
</div>
Means it's only target disabled input, then add .checkmark-disabled to span class.
Additional Info: I need to target sibling css not entire div.
Refer to W3School to look for what scenario you want to target. If you are referring to the sibling that right after the targeted element, then you can use the + sign in your css.
input + span Means selects all <span> elements that are placed immediately after <input> elements
To make it more advance, which based on the input status to change the sibling style, you can add:checked or :disabled in your input + span css.
input:disabled + span Means selects all <span> elements that are placed immediately after <input disabled> elements.
There are more way to do the CSS selector but better refer to the W3School.
If you want to use javascript or jquery to do the DOM, then you have to be more specific and provide the code you are using but failed to work.
You should consider applying styles to sibling element with CSS using :checked and :disabled pseudo-selectors and their compound:
input + .checkmark {}
input:checked + .checkmark {}
input:disabled + .checkmark {}
input:checked:disabled + .checkmark {}
Note that with such approach you will need to overwrite styles applied to the base selector (which is completely OK, but you may be confused). To apply different styles without overwriting you can use :not() pseudo-selector like this:
input:not(:checked) + .checkmark {}
For IE8 and less you can use such syntax:
input[disabled] + .checkmark {}
More information on pseudo-class selectors

Cannot get button click to toggle class

No matter what I try to do, I cannot get classes to toggle on a button click. I have tried many different ways and no matter what I do I cannot get it to work. I think I am making a very simple mistake but I haven't been able to figure it out. I am trying to figure this out so that I can build a navigation that goes in and out of view after you click a button.
document.querySelector("btn-toggle").addEventListener("click",
function() {
document.getElementById("myDIV").classList.toggle("style");
});
.style {
background: green;
font-size: 40px;
}
<button class="btn-toggle">Try it</button>
<div id="myDIV">
This is a DIV element.
</div>
.btn-toggle is the class name of the button, so you need to select the class appropriately - with querySelector, that would be ".btn-toggle". (The . in front indicates to search for a class with that name)
document.querySelector(".btn-toggle").addEventListener("click",
function() {
document.getElementById("myDIV").classList.toggle("style");
});
.style {
background: green;
font-size: 40px;
}
<button class="btn-toggle">Try it</button>
<div id="myDIV">
This is a DIV element.
</div>
Using querySelector("btn-toggle") indicates that you're searching for an element whose tag name is btn-toggle, which is not what you want.
You should add a dot to your selector to make it a class selector.
For example ".btn-toggle" would match your button. With code you have shown us querySelector will search for a tag named btn-toggle.

jQuery selector to find inputs inside a div

I have HTML like this:
<div class="s-item s-question">
<label>label text</label>
<div>
<input name="s1" type="checkbox" class="switch-indeterminate k-input"
data-indeterminate="true"
data-on-text="Yes"
data-off-text="No" />
</div>
</div>
Dynamically with jQuery, how can I select that input? I want to determine when a change occurs.
The highest level div will always have class s-item but instead of a checkbox, sometimes I might have a button or a select box, etc.
So I thought maybe $('.s-item').find('select, input, button').change(function() { ... }); would work? But it didn't.
What should I do?
The "change" event is only valid on input, select, and textarea elements. It doesn't work because you are attempting to assign it to a button element.
$('.s-item').find('select, input, textarea').change(function() { ... });
should work.
It would be cleaner simply to assign a class to the items you care about, so you could just do
$(".s-change-watch").change(function() { ... });
which better separates the semantics of markup (like what element type it is) from functionality.
You can simply do the following to get the checkbox then check the value
$('.s-item div input')
or just give the input an id or class and select that.

Change CSS for parent div when child element (input field) is selected

I'm looking to change the class of a parent div when a child input text field is selected or the mouse moves over any of the other elements in the container. I've tried using both jQuery and some of the pseudo classes in CSS to no avail.
Javascript:
$("input").focus(function () {
$(this).parent().parent("div").css('background-color','#666');
});
HTML:
<div class="container_to_change">
<div class="box1">
</div>
<div class="box2">
<input type="text" class="data-entry">
</div>
<div class="box3">
</div>
</div>
As #Ibu suggests, in his comment to the question, you could simply use the :hover pseudo-class to effect a change in the container_to_change element (depending on what change you wish to apply):
.container_to_change:hover {
background-color: #ffa;
}
JS Fiddle demo
If, however, you really want to use jQuery for this:
$('.container_to_change').hover(
function(){
$(this).addClass('newClassName');
},
function(){
$(this).removeClass('newClassName');
});
JS Fiddle demo.
Edited in response to question, in comments, from wishIdidntsquishthatfish:
How do you keep the different state though when the user is interacting with the input element inside?
$('.container_to_change').hover(
function(){
$(this).addClass('newClassName');
},
function(){
if ($(this).find('input').is(':focus')){
return false; // if the input has focus, prevent the removal of the class-name.
}
$(this).removeClass('newClassName');
}).find('input').focus(
function(){
// ensures that the class-name is added in response to keyboard-navigation focus
$(this).closest('.container_to_change').addClass('newClassName');
}).blur(
function(){
// ensures that the class-name is removed in response to keyboard-navigation focus
$(this).closest('.container_to_change').removeClass('newClassName');
});
JS Fiddle demo.
References:
:hover pseudo-class.
hover().
addClass().
removeClass().
:focus.
focus().
blur().
I don't think you need to specify "div" when trying to get the parent of a parent.
$('input').focus(function(){
$(this).parent().parent().css('background-color', '#666');
});
But why do you care about parents? You can easily just say:
$('input').focus(function(){
$('.container_to_change').css('background-color','#666');
});
And if you're worried about specific input classes, just use:
$('.data-entry').focus(function(){
$('.container_to_change').css('background-color','#666');
});

Open/Close Icons

I'm doing some shennanigans with jQuery to put little plus/minus icons next to my expanders. Its similar to the windows file trees, or firebugs code expanders.
It works, but its not specific enough.
Hopefully this makes sense...
$('div.toggle').hide();//hide all divs that are part of the expand/collapse
$('ul.product-info li a').toggle(function(event){
event.preventDefault();
$(this).next('div').slideToggle(200);//find the next div and sliiiide it
$('img.expander').attr('src','img/content/info-close.gif');//this is the part thats not specific enough!!!
},function(event) { // opposite here
event.preventDefault();
$(this).next('div').slideToggle(200);
$('img.expander').attr('src','img/content/info-open.gif');
});
<ul class="product-info">
<li>
<a class="img-link" href="#"><img class="expander" src="img/content/info-open.gif" alt="Click to exand this section" /> <span>How it compares to the other options</span>
</a>
<div class="toggle"><p>Content viewable when expanded!</p></div>
</li>
</ul>
There are loads of $('img.expander') tags on the page, but I need to be specific. I've tried the next() functionality ( like I've used to find the next div), but it says that its undefined. How can I locate my specific img.expander tag? Thanks.
EDIT, updated code as per Douglas' solution:
$('div.toggle').hide();
$('ul.product-info li a').toggle(function(event){
//$('#faq-copy .answer').hide();
event.preventDefault();
$(this).next('div').slideToggle(200);
$(this).contents('img.expander').attr('src','img/content/info-close.gif');
//alert('on');
},function(event) { // same here
event.preventDefault();
$(this).next('div').slideToggle(200);
$(this).contents('img.expander').attr('src','img/content/info-open.gif');
});
$(this).contents('img.expander')
This is what you want. It will select all of the nodes that are children of your list. In your case, all of your images are nested inside of the list element, so this will filter out only what you want.
How about making your click event toggle a CSS class on a parent item (in your case, perhaps the ul.product-info). Then you can use CSS background properties to change the background image for a <span> instead of using a literal <img> and trying to fiddle with the src. You would also be able to accomplish a showing and hiding on your div.toggle's.
ul.product-info.open span.toggler {
background-image: url( "open-toggler.png" );
}
ul.product-info.closed span.toggler {
background-image: url( "closed-toggler.png" );
}
ul.product-info.open div.toggle {
display: block;
}
ul.product-info.closed div.toggle {
display: hidden;
}
Using jQuery navigation/spidering functions can be slow when the DOM has many items and deep nesting. With CSS, your browser will render and change things more quickly.
Have you tried the .siblings() method?
$(this).siblings('img.expander').attr('src','img/content/info-close.gif');

Categories