Hiding the <p> and showing the <textarea> on a <a> click - javascript

I know the title sounds quite easy but the real problem is the markup. I have a link in a div which also in another div but the textarea and the paragraph are in another div so that's why I am having problem on how to show and hide elements in a completely different markuped div from a completely different markuped div.
I saw .parent() and .children() and .siblings(). But they couldn't help me or I think that I was not able to take help of those.
Here's the fiddle.
Here is the JS I tried:
$(".no_link").click(function(e) {
e.preventDefault();
});
$(".edit_offer").on('click', function() {
$(this).parent().parent().siblings().children("textarea").toggle();
});

You can use these selectors, but it will rely on the class username being in the heirarchy as you have in your code:
$(".edit_offer").on('click', function () {
$(this).closest('.username').find("textarea").toggle();
});
jsFiddle example
.closest() will traverse up the DOM until it hits the element with class username, then .find() will go down through the children looking for the textarea.

I did it using find(). http://jsfiddle.net/SZUT8/2/ To make the script more accurate and future-proof you could consider adding a class to the paragraph and matching it, as in here: http://jsfiddle.net/SZUT8/4/

You could always assign an ID (or a class, for multiple) to each of the desired elements ("p" and "textarea" in your case). Then use your ID/class to reference them for the show() or hide() methods, rather than navigating the DOM via parent(), sibling() and children().
Then your click handler will only need the line:
$('#idOfElement).toggle();

Related

How to target a specific element without knowing it's class or id, but do have all DOM details of the element

To place an external widget without having to let non-technical people paste embed code on every desired spot on a webpage, I'm working on a visual div and p tag selector where people can just pinpoint the desired element(s).
When people hover over an element, it will show a red border to show them what's selected.
For us to place the widget, normally we would target by class or id. However, the class / id should be unique for it to work and unique classes for a random div / p tag is pretty rare.
Via a piece of jquery code:
$(document).on('mouseenter mouseleave', '.sj-highlight',
function (e) {
}
I can get the DOM details about the selected element.
Is there a way I can target the highlighted element by using some data from the DOM details and if yes how?
Tried the code above but just don't know much about DOM selecting possibilities.
To make the whole highlight per element possible, I wrote this:
$( document ).ready(function() {
$('div, p').each(function(i){
$(this).addClass('sj-highlight sjhighlight'+i+'');
$(this).attr('data-sj', 'sjhighlight'+i+'');
});
$(document).on('mouseenter mouseleave', '.sj-highlight', function (e) {
var sjhighlighter = $(this).attr("data-sj");
// hide other highlights
$('.sj-highlight').css("border","2px solid transparent");
if(e.type == 'mouseenter')
{
$('.'+sjhighlighter+'').css("border","2px solid #ff0000");
}
});
The end result would be to somehow target the selected elements with the DOM instead of a class or id.
From the pieces that i put together i think if you can get to the element using
$(document).on('mouseenter mouseleave', '.sj-highlight',
function (e) {});
that means you already have it, because $(document).on() form works for dynamically added elements (that means even if you add element dynamically it still works properly), you can use :
var elementClass = $(this).attr('class');
and you have complete control over the element from there.
And you have also all possibility over its children or it parent which returned as dom elements objects.
I think that your question need a little bit of clarification too.
Here is an option that I used when trying to target elements without the ID or Class. You first need to figure out what each of these highlighted elements have in common. Either it be a specific color, element hierarchy, etc. Then you could use the filter() jquery to find all elements with that spec. This is what I used.
/*select an element that contains this piece of code your trying to target*/
$('#Parent_container').filter(function() {
/*here you will specify what you're trying to identify or target*/
return $(this).find('div[class="sj-highlight"]').length >0;
/*optional but you can create a condition to add code or do whatever you want*/
}).find('div[class="sj-highlight"]').after('<p>some stuff</p>');
Hope that helps. It might give you some idea of what options you have.

jquery children first remove class

I have a web page that has a few elements hidden on load here is the sections html layout
As you can see their is a button that on click i need to remove the hidden class on the next child here is the jquery code.
$(document).on('click', '#find-button', function (e) {
$('#find-data').children().first('.hidden').removeClass('hidden');
});
not sure what is happening but the code does not work
The logic isn't quite right.
first() returns the very first element in the collection so as written you would have the first child.
Use the .hidden selector on children() instead to filter only the ones with that class, and get first() of that reduced set
Change to
$('#find-data').children('.hidden').first().removeClass('hidden');

JQuery not working on inserted/inject DOM element

I am still a bit new to JS & JQuery, so please excuse what may be a simple and stupid question.
Background:
I have a div on my page that holds several divs (#idle-variable). On click of the top level div, it basically shows the other divs (#addvariable). Nothing more than display: none; and .show(). Easy. On another action within that div (change of drop down), I essentially want to inject/insert that top level div (#idle-variable) underneath the first instance.
Issue:
Essentially, the .click function is not working on my newly inserted div. This may be because the two div's share the same ID, BUT I have a sneaky suspicion that it's not recognized in the DOM. A friend of mine said something about I have to "re-run" my jquery in order for it to be readable in the DOM.
Question:
How can i make this work properly? I want to be able to add a dynamic number of these idle-variables to the page and I need to make sure my .click function works for all added DIVS.
$(function(){
$('#idle-variable').click(function(event) {
$("#addvariable").show(400);
});
});
//create variable in db & show value entry
$("#variabletype").change(function() {
$("#varholder").css("display", "inline-block");
$.ajax({
type: "POST",
url: "/myphpfile.php",
data: {"variabletype": $("#variabletype").val()},
success: function(){
$( "#idle-variable" ).after("<div id="#idle-variable>content</div>");
}
});
});
Well to make the code work it would need to use on and ids are only supposed to be on one element. If it can be on the page multiple times you need to use classes.
$(document).on("click,'#idle-variable', function(event) {
$("#addvariable").show(400);
});
you should be using classes
$(document).on("click,'.idle-variable', function(event) {
//$("#addvariable").show(400); //not sure how this relates to the clicked element.
$(this).find(".addvariable").show(400); //if it is a child
});
You also have a typo in your code with quotes.
The ID based selector will be applied to the first element only.
See the example here http://jsfiddle.net/9GN2P/2/
If you are looking to bind same event handler to multiple elements, definitely go with the class based approach, instead of ID based approach.
And, you are expecting event handler to work with dynamically created elements as well. If you are using older versions of jquery, use the live method like
$('yourselector').live('click',function(){
});
Since live is deprecated and if you are in a new version, use the 'on' method
$('containerselector').on('click','yourselector',function(){
});
Editing to answer your comment:
To create dynamic element and append to DOM, you can follow the bellow pattern. Here, I will create a DIV with id "newID", class "newClass", content "NEW DIV!!" and a click event handler for it. And it will be pushed into another div with id 'containerID'
$('<div />',{
id:'newID',
'class':'newClass',
text:'NEW DIV!!',
click:function(){alert('hi');}
})
.appendTo('div#containerID');
This is just a demo.

How to set jQuery mouseleave function for multiple divs with same id

I have a site that has multiple divs with the same id name. I want to set a mouseleave function for all of the divs that have this id. In my $(document).ready function I have this code...
$('#my_post_container').mouseleave(function(e)
{
hideSnippet();
});
My hideSnippet() function is correct, but doing this only set the mouseleave function for the first time that a div comes up of id my_post_container. Is there a way to set the mouseleave function to all divs with this id?
I have a site that has multiple divs with the same id name.
Then you need to fix that. You must not have more than one element with the same id. id values must be unique on the page.
You probably want to use class instead, at which point your code is basically fine:
$('.my_post_container').mouseleave(function(e)
{
hideSnippet();
});
...although it coudl be shortened a bit if hideSnippet doesn't care what arguments it gets, doesn't care about this, and doesn't return false:
$('.my_post_container').mouseleave(hideSnippet);
It is invalid HTML to have multiple objects with the same id. As such, you cannot use normal selectors to find them all and you should fix your HTML to not do that.
The #1 suggestion is to fix the HTML so it does not have multiple objects with the same ID. Use a class name and you can then select them all with getElementsByClassName() or querySelectorAll() or with jQuery selectors as in:
$('.my_post_container')
If you insist on having multiple objects with the same id (a bad choice), then you will have to somewhat manually iterate over all possible objects that could have that id.
$("div[id='my_post_container']");
But, this is pretty darn inefficient because the browser can't use any of the built-in selector engine logic and it could break in the future if jQuery decides to optimize this. You really ought to switch to using class names.
You can not have multiple elements on the same page with the same id. Use a class instead, as shown here:
HTML:
<div class="my_post_container">...</div>
<div class="my_post_container">...</div>
<div class="my_post_container">...</div>
jQuery:
$('.my_post_container').mouseleave(function(e)
{
hideSnippet();
});
First of all there should not be any div elements with same ID name.. first we should solve that by keeping class name same.
then on mouse leave and enter part..
$(".testClass").on({
mouseenter : function() {
$(this).css({"background-color" : "blue"});
},
mouseleave : function() {
$(this).css({"background-color" : "green"});
}
});
this should work.. will add a js sample http://jsfiddle.net/meVc6/
and the same thing can be achived using css too..
just add css .testClass:hover { background-color:blue}

jquery .after deleting entire li or table element

I'm seeing a problem using jquery .after to insert a div into an li. Essentially, the action is deleting the entire li...and I'm not sure why. I also saw this kind of problem using .after on different table elements which makes more sense to me because I can see that would break a table.
Take a look at this jsfiddle: http://jsfiddle.net/XrUtq/
The reason I have to do it this way is because I have to come up with a generic way to be able to put a div as CLOSE in the dom as possible to another element which I don't have control over (could be any kind of element). The div will then be relatively/absolutely positioned on the page to go over top the element which it is going after. I'm doing this because we need a solution instead of appending the div to the body, because if the view is changed then that appended element will stay on the page instead of dissapearing with the content which it is supposed to.
I hope I have made the problem clear enough. I've tried approaches like this:
if (nodeName === 'td' || nodeName === 'tr' || nodeName === 'th' || nodeName === 'tbody'){
popover.appendTo(editable.closest(':visible:not(tr):not(td):not(table):not(tbody)'));
}
else if(editable.is(':visible')){
popover.after(editable);
}
else{
$('body').append(popover);
}
but this is not accounting for the current problem with li.
Thanks for help/suggestions!
You're using slightly incorrect syntax (sort of backwards), use this instead:
Change this:
$('<div>Blabablabla</div>').after($('.editable'));
To this:
$('.editable').after('<div>Blabablabla</div>');
Working fixed example
jQuery .after(CONTENT) inserts the supplied content after the element you have selected. The after method should be appended to your jQuery selector. In your code you were placing the selector inside the after method.
I think you were intending to use .insertAfter() which would have worked with your original syntax.
http://jsfiddle.net/XrUtq/1/
$('li').click(function(){
$('.editable').after('<div>Blabablabla</div>');
});
jQuery .after() inserts a target element (the div) after each element in the matched set (the .editable items). The syntax you were using is for jQuery .insertAfter(), an alternative method for doing a similar thing.
$('li').click(function(){
$('<div>Blabablabla</div>').insertAfter('.editable');
});

Categories