Get id of child div within contenteditable div - javascript

<div class="pad" id="test" contenteditable="true" spellcheck="false">
<div id="a0" class="fif" > text0</div>
<div id="a1" class="fif" >text1</div>
<div id="a2" class="fif" >text2</div>
</div>
As in above code there is a contenteditable div with some child divs inside it. I need a jQuery to return the id of the child div over which I am typing. e.g. if I am editing text1 it should give me (return) "a1".
It works as desired if I use
var clicked;
$('#test').click(function(event){
clicked = $(event.target);
alert(clicked.attr('id'));
});`
as shown here
http://jsfiddle.net/bernie1227/cK69Q/ (i.e. on clicking it returns id="a1") but it doesn't work in similar manner if I use
var clicked;
$('#test').keypress(function(event){
clicked = $(event.target);
alert(clicked.attr('id'));
});
as shown here http://jsfiddle.net/hari_OM/bLgkv/ i.e. on typing it returns "id=test" and not "id=a1"
I tried using event.target.id and $(this).attr("id") but they return id="test" and not id="a1" , but I need to get "a1". I also tried injecting onkeypress="funcname(this.id)" within child divs and retriving it from defined function, but it doesn't work.

I have written a solution which relies on tracking the target of the event, using event.target:
http://jsfiddle.net/bernie1227/cK69Q/

Ever looked into this? DOMCharacterDataModified
$(document).on('DOMCharacterDataModified', function( event ) {
if($(event.target).parent().attr('id') === 'parentid') {
console.log(
'target',$(event.target),"\r"
);
}
});

Related

unable to find the item that got user input with dynamically created items

Hi there I am encountering the following problem I have 3 div's dynamically loaded by ajax like so:
<div class="item" id="item1"> // Dynamically loaded
<input>
<input>
</div>
<div class="item" id="item2"> // Dynamically loaded
<input>
<input>
</div>
<div class="item" id="item3"> // Dynamically loaded
<input>
<input>
</div>
$(document).on('change', '.item', function() {
});
What I want to achieve is when I make a change on the input of one of the three div's, I wanna know where the input was provided. Because the elements are dynamically loaded I can't use a direct selector but I have to use $(document).on and because I dont make use of the direct selector I can't make use of (this). How do I find out in what item changes have been made?
Thanks in advance!
The first argument of the handler - for instance e - would receive the event if it is declared. Then the e argument is having target property which gives you the HTML element on which the event originated. So this would give you a reference to the changed input:
$(document).on('change', '.item', function(e) {
var targetInput = e.target;
var parent = $(targetInput).closest("div.item");
// Do something ...
});
According to your HTML, each div is having different id, Hence you can get the div Id on change of the input. Please test this piece of code and test.
$("input").on('keyup', function(){
//Get the parent div id,
var changeDivID = $(this).parents('div').attr("id");
alert(changeDivID);
});

How do I use jQuery to click and option and have it populate a field

I'm using the following code to have jQuery handle the click of an option and put that value in a field.
The code works except for the part I have in the tag.
I can't figure out why the part within the bold tag isn't doing anything when clicked, while the text after it does.
Here's the HTML:
<div id="result" style="display: block;">
<div class="show" align="left">
<b>This text doesn't work when clicked</b>
This text works when clicked
<span class="name" align="left">113096G</span>
</div>
And Here's the jQuery:
// When clicking an option, the value populates the #projectsearchid field
jQuery("#result").live("click",function(e){
var $clicked = $(e.target);
var $name = $clicked.find('.name').html();
$('#projectsearchid').val($name);
});
Possibly there's a simpler way to accomplish this?
var $name = $clicked.parent().find('.name').html();
find(): Description: Get the descendants of each element in the current set of
matched elements, filtered by a selector, jQuery object, or element.
Thus the method will look inside <b></b> for an element with the class name of name.. which of course it won't find anything, because in this case the element with the class name of name is a sibling and not a child. You'll notice that it will find something if you add .parent()
DEMO
$('#result').on('click',function(e){
var $clicked = $(e.target);
var $name = $clicked.parent().find('.name').html();
//$('#projectsearchid').val($name);
alert($name);
});
firstly, jquery.live is deprecated you should use jquery.on. the reason your code doesn't work is because when you click on the b element, the e.target is associated with and not div#result. when you call:
$clicked.find('.name').html();
it can't find the span.name because the element has no children with that class. the same happens when you click on as well. instead do
$clicked.parent('#result').find('.name').html();
that should get you what you need.

When a Div class is clicked, alert it's inner content's Div Class

How do i even put these, let me try. In the following sets of codes, i want to click 'parentclass' and have an alert value of 'child1' and when i click the class below it which is 'Parent 2' have an alert fire with a value of 'child2'
So this must alert the content of that class only and not the entire class.
Here's some Javascript in Jquery.
var childclass = $('.childclass').html();
$('.parentclass').click(function(e) {
alert (childclass)
});
$('.childclass').click(function(e) {
e.stopPropagation()
e.preventDefault()
});
And HTML
<a href="" onClick="return false">
<div class='parentclass'>
Parent 1
<div style="display:none" class="childclass">child1</div>
</div>
</a>
<a href="" onClick="return false">
<div class='parentclass'>
Parent 2
<div style="display:none" class="childclass">child2</div>
</div>
</a>
This line var childclass = $('.childclass').html(); doesnt make sense as it doesn't know which element in particular you mean. The result of that will just be child1child2 which is just a concatenation of the .html() of all the elements with class childclass. This is obviously not what you want.
Therefore you should dynamically find the child with a class of childclass upon receiving the click event.
$('.parentclass').click(function(e) {
alert($(this).find('.childclass').html())
});
Also, you should know that your child class event handler is useless as we don't care if the event gets propogated downwards. If you DID care, then your e.stopPropagation() and e.preventDefault() should be in the event handler of the parent class.
You need to fetch the html of the clicked parent element within the click handler
$('.parentclass').click(function (e) {
alert($(this).find('.childclass').html())
});
$('.childclass').click(function (e) {
e.stopPropagation()
e.preventDefault()
});
Demo: Fiddle
Several ways you can go about this.
First, if your HTML will not be dynamic (elements already exist when page loads), then you can select elements by the parent class name and assign click event as so:
$('.parentclass').click(function(e) {
// the first variable here is selecting the inner elements having class 'childclass'
// keep in mind, if more than one child having that class is present within this parent, it will select all of them
var child = $(this).find('.childclass');
// here we alert the text of the inner child found
// if it is more than one, you will have undesired results. you may want to specify `.first()`
alert(child.text())
})
For newer jQuery you can also use $('.parentclass').on('click', function(e) {.
If you expect any pieces of parentclass to be dynamic, then you'll want to delegate the event based on either a static parent to the parents or document. This can be like so:
$(document).on('click', '.parentclass', function(e) {
alert($(this).find('.childclass').text())
})
Or, if you have a static (already there when page loads) wrapping element, give it an ID like `parentClassWrapper' and assign the click event dynamically as:
$('#parentClassWrapper').on('click', '.parentclass', function(e) {
alert($(this).find('.childclass').text())
})
Some helpful links:
jQuery API
jQuery Selectors
.click()
.on()
Some info on Event Delegation
jquery on vs click methods
jQuery .on('click') vs. .click() and .delegate('click')
jquery .live('click') vs .click()
I made several adjustments to your html that are worth noting. There's no need for the <a> tag. Don't use inline js - onlick in your html. Note that I wrapped the text inside of the div in the <a> tag instead. This markup is more semantic. Also, move your styles to css rather than in the html.
<div class="parent">
<a>Parent 1</a>
<a class="child">child of parent 1 contents</a>
</div>
<div class="parent">
<a>Parent 2</a>
<a class="child">child of parent 2 contents</a>
</div>
css:
.parent > .child { /* good practice: only select an immediate child of the parent */
display: none;
}
The other answers here are using find() to select the child, but I recommend children() instead. For example, if you had additional nested .childs, find() will select them all, but children() will only select direct .childs of the parent, so it is better in this case. I also recommend using the console for debugging rather than alert.
Live demo here (click).
$('.parent').click(function() {
var $child = $(this).children('.child');
var cls = $child.attr('class');
console.log(cls);
$child.show(); //added so that you can click the child
});
$('.child').click(function() {
var html = $(this).html();
console.log(html);
//if you just want the text, use this instead:
var text = $(this).text();
console.log(text);
});

How to select element relative to 'this' in javascript

I have the following:
<div class="tab-pane" id="message">
<textarea rows="4" cols="50" id="send_message" placeholder="Enter text ..."> </textarea>
OK
Cancel
I want to bind the click method to the 'div' element , and when one of the child 'a' elements is clicked do separate things. I am trying to distinguish between them using the button text, but the following is not working:
$(function(){
$('#message').click(function(){
if($(this + ">a").is(":contains(OK)")) {
console.log("OK!!");
How can I fix this?
Okay there are two ways of doing this:
.find(selector)
if(this).find("a").is(":contains(OK)")) {
console.log("OK!!");
OR
$(selector,context)
if("a",this).is(":contains(OK)")) {
console.log("OK!!");
In javascript, this is essentially the context of the current function. In jQuery event callbacks, this is set to be the source element of the event - not the selector string, which is what you are treating it as.
Instead, you want to do a test like: if($("a", this).is(":contains(OK)")) {
This works because the second parameter to the jQuery selector is the context to search in, so you are only searching for the a tags under the source element of the click.
Binding the click element to the Div, then checking the text string of the A tags will make both events happen on every click. You want to bind 2 separate click events on each A tag. Add an ID to each A tag, then try this code
$('#okLinkID').click(function(){
console.log("OK!!");
});
$('#cancelLinkID').click(function(){
console.log("Cancel!!");
});
//Attaches only one listener to the #message div and listens for any 'a' element within it to be clicked.
$('a','#message').on('click',function(){
var $this = $(this),
btnText = $this.text();
console.log(btnText);
});
http://jsfiddle.net/YA7Ds/

Use JQuery to listen for all clicks on the html body Except a specific div and its children

I am trying to use a jQuery listener to listen for a users clicks on the html body and perform a specific function if anywhere on the body has been clicked except for a specific div and the children within that div.
The idea is that the div is a popup type element and instead of having to have a close button that the user can click, they should just be able to click anywhere on the page besides that div and it will automatically close.
I have been using this listener:
var initialClick = false;
$('body').on('click.addPhoneListeners', function(event) {
var target = EventUtility.getTarget(event);
if(initialClick) {
if(target.parentNode.id != clone.id && target.id != '') {
finish();
};
}
initialClick = true;
});
Which listens for all clicks on the body and unless the click comes from within the element I want the user to be able to interact with, it closes. Unfortunately this only works with a div that has only one level of children. As soon as I start getting multiple hierarchies such as this:
<div id="addressContainer">
<div id="address" class="hidden row">
<div class="row">
<div id="address.primary" class="hidden">P</div>
<div id="address.type"></div>
<div id="address.street"></div>
<div id="address.editButton" class="hidden"><a id="addressEditButton">Edit</a></div>
<div id="address.deleteButton" class="hidden"><a id="addressDeleteButton">Delete</a></div>
</div>
<div class="row">
<div id="address.city"></div>
<div id="address.state"></div>
<div id="address.zip"></div>
</div>
<input type="hidden" id="address.id"></input>
</div>
</div>
The target.parentNode.id gives me the objects parent element as opposed to the addressContainer id and thus does not work. Is use the top level parent from within nested elements? Other elements will be using this same code, so it has to work on both divs with just one level and div's with multiple.
UPDATE: Found a few excellent solutions, thanks guys. I do however have one other question. Refer to my code above where I set an initialClick boolean to false, then set it to true. I am doing this because for some reason if I don't, when I go to add the popup div, the initial click from the button used to set that popup fires the listener and closes the popup before I have a chance to do anything. This has been my solution around the problem, but is that the only way? Or am I just setting the listener slightly incorrect?
I usually do something like this:
$(document).click(function(e) {
// hide popup
});
$('#popup_div').click(function(e) {
e.stopPropagation();
});
That way the clicks from your popup never propagate to the document, so the close function never fires.
Replace
if(target.parentNode.id != clone.id)
with
if ($(target).closest("#" + clone.id).length === 0)
(I left the second clause alone since it didn't seem related to your question.)
This tries to find the closest ancestor with ID equal to clone.id. If none is found, an empty jQuery object is returned (i.e. one with length === 0), which is what we test for.
Incidentally: jQuery normalizes event.target, so you can just use that instead of whatever custom monstrosity EventUtility.getTarget(event) embodies.

Categories