variable undefined when using alert() - javascript

I have this script:
<script>
var prop = document.getElementById('div1').firstChild.getAttribute("id");
function aler()
{
alert(prop);
}
</script>
and out of the script tag:
<div id="div1">some content</div>
<button onclick="aler()"></button>
Can someone explain to me why when I click the button it says: "undefined"
Correction:
in the div i drag a picture:
<img id="C" src="C.png" draggable="true" ondragstart="drag(event)" width="91px" height="91px">
for example.

The first child of div1 is a text node. It has no id.
EDIT
As to your correction, if the resulting HTML looks anything like this, then the first child is still a text node:
<div id="div1">
<img id="C" etc.>
</div>
because text includes tabs, spaces, and returns. I'm not sure how drag/drop affects that.

In the DOM, there are various kinds of "nodes." Your <div id="div1">some content</div> markup defines two nodes: An Element that's a div, and its first (and only) child, a Text node containing the text you have within the div. The Text node has no id. The div element has an id, but the text node does not.

document.getElementById('div1').firstChild is the text some content. When you call getAttribute("id") on that, since plain text had no id, you're going to get undefined.

Related

Get Only Tag ChildNodes Not TextNodes

I have been programming with JavaScript for a while now but today I just knew that element.childNodes returns an array of nodes including the text!!!
I probably have never run with trouble because I used to create the element and append text in paragraphs; but now that I think about it, things could get really messy with text as nodes!
my question is: how can I get only the child nodes that are tags not text nodes.
For example:
<div id="e">
I don't want to include this text right here.
<p>I want to get this paragraph child</p>
I also want to <em>exclude</em> this text...
<img src="image.jpg" alt=" " />
Google
Exclude this text too..
</div>
Therefore, I want to get the p, img, a and maybe em objects only..
Here is a simple example of using .children to target only the elements. childNodes returns textNodes by default and at times that is very useful, but not appropriate for your example usage.
[].forEach.call(document.querySelector('#e').children,function(el){ el.style.color = 'red'; });
<div id="e">
I don't want to include this text right here.
<p>I want to get this paragraph child</p>
I also want to <em>exclude</em> this text...
<img src="image.jpg" alt=" " />
Google
Exclude this text too..
</div>

Temporarily store text from a dynamic location in the DOM in a javascript variable

I'm building a website for a school assignment, so it's kind of simple. Please excuse or correct any incorrect terminology.
I have multiple identical div's , all sharing the same class, each of these has two paragraph elements in them with some some text in each.
Triggered by a click, I want the specific div I clicked on to be assigned an id for reference in a variable, which should store some text from a child paragraph. I am trying to make a div appear, and the text to be pulled in from the variable.
This is the Javascript I have written:
$(document).ready(function(){
//Hide the overlay.
$('#overlay_align').hide()
//Fade in the overlay and change the title.
$('.object').click(function(){
//Sets the clicked item to have an id "active", for use in the variable "title".
$(this).attr("id", "active")
//Gets the text from this item's title section.
var title = $('#active:nth-child(2)').text()
//Sets the title printed in the overlay to whatever the title of the clicked item was.
$('#overlay_title').html(title)
console.log( title )
$('#overlay_align').fadeIn("fast");
})
//Fade out the overlay.
$('#close').click(function(){
$('#overlay_align').fadeOut("fast")
//remove the id for reuse when another item is clicked.
$('#active').removeAttr("id");
});
});
And the relevant part of the HTML document:
<head>
<link rel="stylesheet" type="text/css" href="Stylesheet.css"/>
<!--jQuery 1.4.2-->
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
<!--Overlay on click-->
<script type="text/javascript" src="../Overlay.js"></script>
</head>
<body>
<div id="overlay_align">
<div id="overlay">
<div id="overlay_left">
<img id="overlay_img" src=""/>
<img id="loading" src="../Loading.gif" width="50" height="50" style="margin-top:50%"/>
</div>
<div id="overlay_right">
<p id="overlay_title"></p>
<img id="close" src="../Close%20Button.png" width="20" height="20"/>
<p id="overlay_description"></p>
</div>
<div id="overlay_footer">
</div>
</div>
</div>
<div class="object">
<div class="display"></div>
<p class="title">Ttile</p>
<p class="category">Category</p>
</div>
<div class="object">
<div class="display"></div>
<p class="title">Ttile</p>
<p class="category">Category</p>
</div>
<div class="object">
<div class="display"></div>
<p class="title">Ttile</p>
<p class="category">Category</p>
</div>
The issue I have is that currently, the variable stores the content of both the paragraphs instead of just the second one, (so it appears as "Title Category", and even that only works with the first div. I'm not fixed on this way of doing it, so I'm open to any other ways of doing this too.
Reputation is preventing me from posting individual links, so heres an imgur album showing the different states it's appearing in: https://imgur.com/a/bB7XQ
PS: Is there any way to not have to manually indent every line with four spaces?
You are looking at the wrong element. The selector #active:nth-child(2) isn't looking for the second child in the element with id="active", it looks for an element with that id that is the second child. You would use #active p:nth-child(2) to look for the paragraph inside the element.
However, you will run into a problem as you are adding an id to the element. The second time that you click something you will have that id on two elements, so you will get the text from that element and the text from the previous element. Also, as an id should be unique in the page, you may even get some unexpected behaviour in some browsers.
You don't need to set the id on the element to find it, you already have a reference to it in this that you can use. Specify this as context, and use the selector p:nth-child(2):
$('.object').click(function(){
//Gets the text from this item's title section.
var title = $('p:nth-child(2)', this).text()
//Sets the title printed in the overlay to whatever the title of the clicked item was.
$('#overlay_title').html(title)
console.log( title )
$('#overlay_align').fadeIn("fast");
})
Demo: http://jsfiddle.net/6D9JD/
I am not sure if I am answering the question correctly. As per my understanding the problem you are facing is
var title = $('#active:nth-child(2)').text()
Instead of looking for the second last child you can find the class title in the corresponding div.
var title = $('#active').find('.title'); //Assuming that you have only one title in a single div
you need to use
$('#active:nth-child(2)').children().last().text()
instead of
$('#active:nth-child(2)').text()

Javascript InsertBefore - in a different div both within a parent div

I would like to insert an hr element in a different child div (2 child divs within a parent div), as per the set-up below. The insertbefore method works fine for an element within the same div but not for elements in the other child div (see code below). Is there a different method I can use to achieve this or do I want the impossible?
<body>
<div id="whole section">
<div id="group_a">
<h3 id="event_1">Heading 1</h3>
<p> some text </p>
**// I would like to insert an hr element here**
<h3 id="event_2">Heading 2</h3>
<p> more text </p>
</div>
<div id="group_b">
**// I can only insert code here though**
<script type="text/javascript">
function add_hr(){
var new_hr = document.createElement('hr');
var reference = document.getElementById('event_2');
document.body.insertBefore(new_hr, reference);
}
window.onload = function(){add_hr();};
</script>
</div>
</div>
</body>
insertBefore requires that the reference element be a direct child of the element on which you call it. Your line
document.body.insertBefore(new_hr, reference);
...tells the browser to insert new_hr before the reference element directly contained by document.body. But document.body doesn't directly contain the reference element, it's inside a div. So you get an error, because the reference element can't be found directly inside the element you're inserting into.
You can fix that by using the reference element's parent:
reference.parentNode.insertBefore(new_hr, reference);
Live Example | Source

How to get a div which is removed from the DOM when it's parent has been made .empty()?

I have a div in a HTML file
"<div id="abc" hidden="hidden">
<div id="statIndicator">
<span id="imgInd" class="status-indicator-border">
<img src="../../LibSrc/SharedResources/IMG/loading-trace.gif" />
</span><span id="messageIndicator">Updating Plots...</span>
</div>
</div>"
I insert the statIndicator div in another div using append.
so that div becomes
<div id="parentDiv">
<div id="statIndicator">
<span id="imgInd" class="status-indicator-border">
<img src="../../LibSrc/SharedResources/IMG/loading-trace.gif" />
</span><span id="messageIndicator">Updating Plots...</span>
</div>
</div>
On refresh I write $('#parentDiv').empty() it deletes whatever is inside the 'parentDiv'.
But when I try to append statIndicator using $('#statIndicator'), it return "[]", though I have the 'statIndicator' div in Html.
Is there a way in which I can get the 'statIndicator' div?
No. $.empty() deletes the contents, so your "statIndicator" div no longer exists at all.
Just remove it from "parentDiv" before you call $.empty(). Either store it in a variable or put it back where it started, in "abc".
I think jquery.append() moves the selected elements without making a copy. So you can explicitly create a copy using the .clone() method and append it's result. Something like:
$('#abc #statIndicator').clone().appendTo('#parentDiv');
This is creating a copy and then appending it at the new location.
Once you do this there will be two divs with the same id, so it will be a good idea to always reference the statIndicator's parent container in your selectors.
You can use .detach() function if you want only parentDiv to be removed

How to make a template content non editable in tinymce

I've crated html template file, I put some elements inside that template are non editable.
template.html contains
<body>
<div>This is a sample template </div>
<div contenteditable="false" style="color:red">Read Only Text</div>
</body>
on inserting this template file into the textarea the second div is editable, while inspecting over that div I've seen that the attribute contenteditable="false" is not there on insert, but its there on the preview before the insert of template.
Any help gratefully received!
From this page: http://www.tinymce.com/tryit/noneditable_content.php
Its using a textarea:
<textarea name="content" style="width:100%">
<p>Text with a <span class="mceNonEditable">[non editable]</span> inline element.</p>
<p class="mceNonEditable">Noneditable text block with <span class="mceEditable">[editable]</span> items within.</p>
<p>Text with tokens that isn't [[editable]] since they match the noneditabe_regexp.</p>
</textarea>
The key here is putting a class of mceNonEditable in your element:
span class="mceNonEditable"
Then whatever non-editable content you have, wrap it in greater than and less than:
>You cannot edit me<
Then finally close the element:
/span
I think you can also change the mode (in the example they're using textareas, so I guess you can also use divs or spans) when initializing tinymce:
tinyMCE.init({
mode : "textareas",
noneditable_regexp: /\[\[[^\]]+\]\]/g
});
There's also noneditable_regexp which lets you specify a regular expression of non-editable contents.
I think this is easier than using html entities.
I haven't actually tried it but that's the way I interpret the example in the page.

Categories

Resources