I'm trying to add a class to my p element when the textarea is active
This is what I've got so far with no luck.
<textarea class="text"></textarea>
<p class="someClass">
<span class="span">
TEXT
</span>
</p>
jQuery
$('textarea').focus(
$(".someClass").addClass("focused");
});
The final result I'm trying to accomplish is when the textarea is focused
<textarea class="text"></textarea>
<p class="someClass focused">
<span class="span">
TEXT
</span>
</p>
Can this be done by grabbing the set class "someClass"?
You are actually doing it wrong. You should do this way by sending an anonymous function:
$('textarea').focus(function () {
$(".someClass").addClass("focused");
});
You have missed that. I would say a better way, if the .someClass is next to the element in question, you can use CSS's sibling selector +, without using JavaScript:
textarea:focus + p {
background: #99f;
}
<textarea></textarea>
<p>Click on TextArea</p>
You should to supply an anonymous function to the focus event handler. Try this:
$('textarea').focus(function() {
$(".someClass").addClass("focused");
});
Also note that you can do this in CSS alone without the need for any JS code. Using the CSS method has the added benefit of the styles being automatically removed when the textarea loses focus.
textarea:focus + p {
/* styles in here which matched the .focused class */
}
Working example
Related
This is the code at a high level, and there are multiple such lists I have of the following structure:
<li class="wrap-input">
<p>Some sentence</p>
<select class="form-control">
...
</select>
<div class="button-in-input">
...
</div>
</li>
.
.
.
What I want to do is, whenever the user focuses on the "form-control" select, then the div with the "button-in-input" class should be shown, but only in that particular li element. i tried it with this jquery code:
$(".form-control").focusin(function() {
$(".button-in-input").show();
}).focusout(function() {
$(".button-in-input").hide();
});
But of course, this generalizes to all the li elements I have. I'm assuming there is a way to do it with the this keyword but note that the select and div elements are siblings.
Any help would be appreciated!
PS: I want to avoid using IDs otherwise there would be tons of repetetive code
You can do this with pure CSS.
.wrap-input .button-in-input {
display: none;
}
.wrap-input select.form-control:focus + .button-in-input {
disply: block;
}
The select in the second selector is not necessary, but it helps in case there's a different item with the same class.
you can simply use :focus in css to do it, no fancy javascript code needed for this
.form-control:focus + .button-in-input {
display: block;
}
I frequently create web apps that use traditional tabs at the top of the page. When doing this, I have a common problem I have been unable to find an elegant solution to.
The problem is the user can load the same content in two separate tabs on the same page. Any HTML ID's on these two different tabs then conflict, causing any JavaScript referencing one of those ID's to fail on the second tab. In addition, any JavaScript referencing a class on one of these pages will affect elements on all tabs, when I really only want it to affect the current tab.
For example, what if I included this block of code twice in the same page?
<style>
#container { margin; 20px; }
#message { background: red; }
</style>
<div id='container'>
<span id='message'>This was from an include file</span>
<button id='changeColorBtn'>Change color</button>
</div>
<script>
$('#changeColorBtn').click(() => $('#message').css('background', 'blue'))
</script>
JSFIDDLE to illustrate the problem: https://jsfiddle.net/dillydadally/2njcq9py/
I have tried or considered three approaches to solve this in the past:
I tried appending a page id to every element in the included content using PHP. This become messy quick and annoying to write out.
I tried making each tab an iframe. At first, this seemed to work well, but quickly became a management nightmare having that many iframes open on the same page that sometimes needed to communicate with each other and share data. I ran into multiple issues and decided not to attempt this approach again.
I considered wrapping each instance of included content in a single element with a unique ID, but I decided I would run into similar issues as option 1 above. Every CSS selector would have to have that element with the ID first, yet again creating messy code and possibly slowing the page down with numerous multi-depth JQuery selectors. In addition, there would still be multiple elements with the same ID on the same page (although I'm not sure that would matter since every selector should have a parent element included).
Is there an element or approach created to address this problem already in HTML/CSS that I'm missing?
You must use a class instead of an ID on an element with the same styling used more than once that you wish to affect with the same css style rule in your document.
For example:
<div id="main"><!-- / The main ID is only used once in the document / -->
<p class="par">
Here is the first paragraph with the same style as the second
</p>
<p class="par">
Here is the second paragraph with the same style as the first
</p>
</div>
Now to your issue of affecting the same type of element used multiple times in your document...
Because you have both the span (message) and button together as a pair under the same parent element, you can access the index of a loop within an event listener to identify the one being pressed using the nodelist being selected.
I use vanilla JS querySelectorAll() on the node list. You must use classes for multiple elements of the same tag name.
I targeted the elements parent class let message = document.querySelectorAll('.content span') and let btn= document.querySelectorAll('.content button'). Then you run the nodes through a forEach loop and add an eventlistener to the button element using the index in the forEach loop. Though this index is the index for the btn element, because these are paired up it will target the correct message element using the index from the btn.
let btn = document.querySelectorAll('.container button');
let message = document.querySelectorAll('.container span');
btn.forEach((button, i) => {
// in short....
// each time the loop iterates the nodelist of btn, it assigns the keyword
// `button` to that iteration of the elements nodelist, so when we click a specific
// `button` it refers to the button being pressed at that time and not all of them
button.addEventListener('click', (e) => {
message[i].style.backgroundColor = 'blue';
})
})
.container span {
background: red;
}
<div id='tab1'>
<div class='container'>
<span>This was from an include file</span>
<button>Change color</button>
</div>
</div>
<div id='tab2'>
<div class='container'>
<span>This was from an include file</span>
<button>Change color</button>
</div>
</div>
Using Jquery: Use $.each to run the list through a loop and use $(this) on a click event and target the elements previous sibling which is the grouped pair within the parents span tag (message).
let btn = $('.container button');
let message = $('.container span');
$.each((btn), function(){
$(this).click(function(){
$(this).prev().css("background-color", "blue")
})
})
.container span {
background: red;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='tab1'>
<div class='container'>
<span>This was from an include file</span>
<button>Change color</button>
</div>
</div>
<div id='tab2'>
<div class='container'>
<span>This was from an include file</span>
<button>Change color</button>
</div>
</div>
So I have a popup. You click on an "+Add Text" link and it adds a text box to the page, along with another "+Add Text link" and an "x" in a span on the right corner of each textbox. When I click an "x" within this popup, I'd like for it to delete the two siblings that immediately follow it. The HTML generated on the page looks something like this...
<div class="popup">
<div class="delete-text-box-x">X</div>
<textarea class="textbox"></textarea>
<span class="add-textbox">+Add text</span>
<div class="delete-text-box-x">X</div>
<textarea class="textbox"></textarea>
<span class="add-textbox">+Add text</span>
<div class="delete-text-box-x">X</div>
<textarea class="textbox"></textarea>
<span class="add-textbox">+Add text</span>
</div>
When I click the divs with the class "delete-text-box-x">, I'd like for the following two siblings to be deleted. That is, the following corresponding textarea and "+Add Text" span.
I almost have it. Here is my jQuery
$('.delete-text-box-x').click(_.bind(function(e){
$('.delete-text-box-x').nextUntil('.add-textbox').remove();
}, this));
}
It's obvious why this doesn't work. The nextUntil method does indeed select and remove the textboxes following the 'X' divs. But the selector selects EVERY 'X' on the page, and therefore deletes EVERY textbox on the page. It also doesn't delete the '+Add Textbox' spans...
So how do I get more specific than the current selector I'm using? So it selects ONLY the specific 'X' I click, rather than every 'X' on the page.
Firstly, you need to base the selector on the element that raised the event using the this keyword. From there you can use nextUntil(), but you should use the selector of the next X so that all the required elements are found. Finally you need to use add() to include the clicked X itself. Try this:
$('.delete-text-box-x').click(function (e) {
$(this).nextUntil('.delete-text-box-x').add(this).remove();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="popup">
<div class="delete-text-box-x">X</div>
<textarea class="textbox"></textarea>
<span class="add-textbox">+Add text</span>
<div class="delete-text-box-x">X</div>
<textarea class="textbox"></textarea>
<span class="add-textbox">+Add text</span>
<div class="delete-text-box-x">X</div>
<textarea class="textbox"></textarea>
<span class="add-textbox">+Add text</span>
</div>
I also note you're using some odd syntax around the anonymous function in the click handler which I presume this is due to another library. If not you should remove it.
This until works to find another element in the siblings, so in the above code you are selecting the next add-textbox and not the next X icon.
$('.delete-text-box-x').click(function() {
$(this).nextUntil('.delete-text-box-x')add(this).remove();
});
I have a contenteditable div fora text area, and I want to style it
<div id="reply_body{{forloop.counter}}" name="reply_body" contenteditable="true">Begin typing </div>
However, I am using {{forloop.counter}} because I am passing the information in the div to a javascript function. I.e.,
<script type="text/javascript">
function copycontent(x)
{
document.getElementById('replies'+x).value=
document.getElementById('reply_body'+x).innerHTML;
};
</script>
So, my question is, how can I style this contenteditable div if part of the id is {{forloop.counter}}?
Use a class to style it:
<div id="..." class="reply">
CSS:
.reply {
/* Your styles here */
}
ID's (denoted by # in CSS) have to be unique to an element, classes (denoted by . in CSS) can be used with multiple elements.
i have:
<span id="asdfasdf_test">
<span id="adfaf_test33">
<span id="2342_test">
<span id="34223sdf_testrr">
<span id="asdfsdsdf_test">
<span id="asdf2343sdf_test">
.red {
color: red
}
if span id ends at _test i would like add for this span class .red . how can i make this with jQuery?
LIVE EXAMPLE: http://jsfiddle.net/X6TTd/
$('span[id$="_test"]').addClass('red');
The $= attribute selector means 'ends with'. I added "span" to the jQuery selector since they are all spans in your example, but you can also select the attribute on any element:
$('[id$="_test"]')
CSS can do that for you! Why do you want to use jQuery? (besides: jQuery understands this CSS Selector)
Here you have it: http://www.w3.org/TR/selectors/#selectors