I have a structure that looks like the one below, I'm trying to get the id foo. It is the only DIV with id if we bubble up from the onclick func(), which means that there wont be other DIVs that contain an id inside foo. However, there can be other tags inside foo that contain an id (such as bye, hello).
No frameworks are being used.
<div id="bar"></div>
<div id="foo">
<p><p>
<div class="bye">
<input id="bye" type="text" value="test" />
<input id="hello" type="text" value="test" />
<table>
<tr><td onclick="func(event)">1</td></tr>
<tr><td onclick="func(event)">2</td></tr>
</table>
</div>
</div>
function findIdOfParent(obj) {
var o = obj;
while(!o.id) {
o = o.parentNode;
}
alert(o.id); // 'foo'
}
The function findIdOfParent takes a DOM node. You could call it with onclick="findIdOfParent(this);", but if you only want to pass event, as in your example, you'd have to extract the DOM node from event.target or whatever you're currently doing.
This should do it:
<div id="bar"></div>
<div id="foo">
<p><p>
<div class="bye">
<input id="bye" type="text" value="test" />
<input id="hello" type="text" value="test" />
<table>
<tr><td onclick="func(this)">1</td></tr>
<tr><td onclick="func(this)">2</td></tr>
</table>
</div>
</div>
<script type="text/javascript">
function func(elt) {
// Traverse up until root hit or DIV with ID found
while (elt && (elt.tagName != "DIV" || !elt.id))
elt = elt.parentNode;
if (elt) // Check we found a DIV with an ID
alert(elt.id);
}
</script>
You could use the parentNode property of the clicked element to iterate up through the DOM tree.
ie:
<td onclick="func(this)">
function func(item)
{
var parent = item.parentNode;
// and so on, or something similar
var divId = div.id;
}
elem is the element that call the function on click
var found = false;
var myId = "";
while (elem &&!found) {
if (elem.id){
found = true;
myId = elem.id;
}
elem = elem.parentNode;
}
Can't you apply a simpler pattern? Instead of having onclick properties in your cells, attach a single click handler to your outermost div(s), then you just need to refer to this:
document.getElementById("foo").onclick = function(event) {
if(e.target.tagName.toLowerCase() == "td") {
alert(this.id);
}
};
http://jsfiddle.net/fRxYB/
Or am I completely missing the point?
To have a somewhat more generic version, I'd suggest this:
function func(event) {
var par = findTop(event.target);
console.log(par);
};
function findTop(node) {
while(node.parentNode && node.parentNode.nodeName !== 'BODY') {
node = node.parentNode;
}
return node;
}
example: http://www.jsfiddle.net/4yUqL/37/
Related
I have an HTML file. I need to get the element attributes and but it's not happening as I am getting var elementType = target.getAttribute('data-type');
Uncaught TypeError: Cannot read property 'getAttribute' of null
I just don't know how I can get the element attribute. Please help.
var setAllEvents = $("[my-noteEvent]");
for (var i = 0; i < setAllEvents.length; i++) {
//call function to work with
this.bindingAllEvents(setAllEvents[i]);
}
bindingAllEvents: function(setElements) {
var element = document.getElementById(setElements.getAttribute('data-element')); // Get Element the event is set on
var target = document.getElementById(setElements.getAttribute('data-target')); // Get Element that is the target of the event
var event = setElements.getAttribute('data-event'); // What type of event to run
var action = setElements.getAttribute('data-action'); // Action to take on event
var elementType = target.getAttribute('data-type');
if (elementType === 'dropdown-label') {
target = target.parentelement;
}
element.addEventListener(event, function(e) {
e.preventDefault();
//do something here when all is good
});
}
<div class="form--input form--input-container form--select hasPlaceholder" data-type="dropdown-label" data-required="true">
<label for="countries">Dropdown</label>
<input type="hidden" id="countries" name="maritalStatus">
<input class="input--main" type="button" data-element="select" value="">
<span class="placeholder">A Dropdown with stuff</span>
<span class="selectChoice"></span>
<div class="framework dropdown dropdown--select-container">
<div id="" class="framework dropdown--select-item" data-value="UK" data-option="0">
<p class="framework text--paragraph ">
UK
</p>
<span class="dropdown--item-line"></span>
</div>
<div id="" class="framework dropdown--select-item" data-value="Russia" data-option="1">
<p class="atom text--paragraph ">
Russia
</p>
<span class="dropdown--item-line"></span>
</div>
</div>
</div>
<div my-noteEvent="" data-element="maritalStatus" data-target="myTarget" data-event="onchange" data-action="[{'Single':{'show':'#div1 #div3'}, {'married':{'show':'#div1 #div3'}}]">
</div>
I quote
<div my-noteEvent="" data-element="#maritalStatus" data-target="myTarget" data-event="onchange"
data-action="[{'Single':{'show':'#div1 #div3'},
{'married':{'show':'#div1 #div3'}}]">
In your html, your attributes are named data-element="#maritalStatus" data-target="myTarget" respectively, yet you add an s at both in your code:
var element =
document.getElementById(setElements.getAttribute('data-elements')); //
Get Element the event is set on
var target = document.getElementById(setElements.getAttribute('data-targets'));
remove the s at the end.
Furthermore if you are going to fetch by id using document.getElementById(variable), variable shouldn't start with a pound sign.
remove # in #maritalStatus
You are getting an error because target is null since you can't find it.
I have an issue with jsviews. I want to bind an array of elements. Each element is an object. Elements are added dynamicaly. Value of one field of each element computes base on another field. How is it posiible to do without refreshing array every time?
js:
model = {
elements: []
};
$(function() {
$.when($.templates('#tmpl').link('#container', model)
.on('click', '#addElement', function () {
$.observable(model.elements).insert({});
})
).done(function() {
$.observe(model, 'elements', function(e, eventArgs) {
if (eventArgs.change === 'insert') {
eventArgs.items.forEach(function(addedElement) {
$.observe(addedElement, 'value1', function(e) {
var element = e.target;
element.value2 = 'Value1 is ' + element.value1;
$.observable(element).setProperty('value2', element.value2);
$.observable(model).setProperty('recent', element.value1);
});
});
}
});
});
});
html:
<div id="container"></div>
<script id="tmpl" type="text/x-jsrender">
<input id="addElement" type="button" value="add new element"/>
<div id="box">
{^{for elements tmpl="#elementTmpl"/}}
</div>
<input type="text" data-link="recent" />
</script>
<script id="elementTmpl" type="text/x-jsrender">
<div>
<input name="input1" data-link="value1" />
<input name="input2" data-link="value2" />
</div>
</script>
I created jsfiddle that illustrates the problem.
You can use ObserveAll(): http://www.jsviews.com/#observeAll.
Every time the element.value1 changes, you update the calculated properties element.value2 and model.recent.
I updated your fiddle here https://jsfiddle.net/1rjgh2sn/2/ with the following:
$.templates('#tmpl').link('#container', model)
.on('click', '#addElement', function () {
$.observable(model.elements).insert({});
});
$.observable(model).observeAll(function(e, eventArgs) {
if (eventArgs.change === "set" && eventArgs.path === "value1") {
var element = e.target;
$.observable(element).setProperty('value2', 'Value1 is ' + element.value1);
$.observable(model).setProperty('recent', element.value1);
}
});
i want to add element to div in angularjs. so write this code but not work correctly. thanks for your help :)
function TestController($scope) {
$scope.addElement = function(){
var myElements = angular.element(document.querySelector('#form'));
console.log(myElements);
if(myElements.length == 0)
alert("Not Find");
else
myElements.prepend( myElements[0].children[1]);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app ng-controller="TestController" id="form">
<input type="button" ng-click="addElement()" value="add"></input>
<div id="div">
<input type="text" name="name">
</div>
</div>
Here is what I have tried.
$scope.addElement = function(){
var myElements = angular.element(document.querySelector('#form'));
console.log(myElements)
console.log(myElements[0].children[1])
if(myElements.length == 0)
alert("Not Find");
else{
html = angular.element(myElements[0].children[1]).clone();
myElements.append( html);
}
You should use angular clone method.
EDIT.
Here it the Plunker
If I understood your question correctly, you want to append an input element to div on each ng-click?
You just need to target the div with jquery and append the element with it.
See example: http://jsbin.com/seyawemijo/edit?html,js,output
Often than not when you want to modify the DOM directly, there is a way to do it without.
"Thinking in Angular way"
function TestController($scope) {
$scope.textArr = [];
var count = 1;
$scope.addElement = function() {
var ele = {
model: 'hello ' + count++
}
$scope.textArr.push(ele);
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app ng-controller="TestController" id="form">
<input type="button" ng-click="addElement()" value="add" />
<div ng-repeat="text in textArr">
<input type="text" ng-model="text.model">
</div>
<div>{{textArr}}</div>
</div>
Try this one
myElements.prepend(myElements[0].children[1].value);
I have altered the above solution to add other attributes(including id) to the input text element
var globalCntr = 0;
function TestController($scope) {
$scope.addElement = function() {
globalCntr ++;
$('<input>',{
type:'text',
id:('inputText'+globalCntr)
}).appendTo($('#target'));
};
}
I have two input, textarea (name + comment) and Submit button. Onclick should post text from input and textarea. I use appendchild(), but need to call textarea.
1. How should I do it?
2. Button "Delete" remove all post, but I need delete just the last one. So how it is possible?
Thank you for any tips.
There is the code:
<script type="text/javascript">
function append(form) {
if (form.input.value) {
var newItem = document.createElement("div");
newItem.appendChild(document.createTextNode(form.input.value));
document.getElementById("myDiv").appendChild(newItem);
}
}
function restore() {
var oneChild;
var mainObj = document.getElementById("myDiv");
while (mainObj.childNodes.length > 0) {
oneChild = mainObj.lastChild;
mainObj.removeChild(oneChild);
}
}
</script>
<form>Name:
<br>
<input type="text" name="input" />
<br />Comment:
<br>
<textarea type="text" name="textarea"></textarea>
<br />
<input type="button" value="Submit" onclick="append(this.form)" />
<input type="button" value="Delete" onclick="restore()" />
</form>
<div id="myDiv"></div>
Problem is because you are saying while there are posts delete last one.
Put just this code in restore. It will remove last child once.
function restore() {
var oneChild;
var mainObj = document.getElementById("myDiv");
oneChild = mainObj.lastChild;
mainObj.removeChild(oneChild);
}
To solve your append issue:
function append(form) {
if (form.input.value) {
var newItem = document.createElement("div");
newItem.appendChild(document.createTextNode(form.input.value));
//add a line break and the text from textarea
newItem.appendChild(document.createElement("br"));
newItem.appendChild(document.createTextNode(form.textarea.value));
document.getElementById("myDiv").appendChild(newItem);
}
}
If you want to delete the last item only, you have to convert the while loop to an if condition:
function restore() {
var oneChild;
var mainObj = document.getElementById("myDiv");
if (mainObj.childNodes.length > 0) {
oneChild = mainObj.lastChild;
mainObj.removeChild(oneChild);
}
}
In Javascript how can I tell if a checkbox has focus or not?
I thought there would be a method or property called isfocused. But apparently not.
By in focus I mean they've tabbed to it using the keyboard and at this point pressing space would check the box.
Create an event handler that is wired to the onfocus event. When it's called, set a global var to remember that it's got the focus. Write another one on the onblur event which clears the variable.
There is a onfocus event that fires when an element receives focus.
<script type="text/javascript">
var isFocused = false;
</script>
<input type="checkbox" name="team" value="team" onfocus="javascript:isFocused = true;">Spurs<br>
You might have to just hook into the onfocus and onblur events for the checkbox to keep track of when it gets and loses focus.
Here's an example of the basics of an implementation that might help you. Note: the output stuff is just for demonstration purposes and not part of the actual solution.
<html>
<head>
<script type="text/javascript">
onload = function()
{
var f = document.forms.test;
f.focusedElem = null;
updateOutput( f );
for ( var i = 0, l = f.elements.length, elem; i < l; i++ )
{
elem = f.elements[i];
elem.onfocus = function( elem )
{
return function()
{
elem.form.focusedElem = elem;
updateOutput( elem.form );
}
}( elem )
elem.onblur = function()
{
f.focusedElem = null;
updateOutput( f )
}
}
}
function updateOutput( f )
{
document.getElementById( 'output' ).innerHTML = ( null == f.focusedElem ) ? 'Nothing!' : f.focusedElem.id;
}
</script>
</head>
<body>
<form name="test">
<input type="checkbox" name="foo" id="foo1">
<input type="checkbox" name="foo" id="foo2">
<input type="checkbox" name="foo" id="foo3">
<input type="checkbox" name="foo" id="foo4">
</form>
What has focus? <span id="output"></span>
</body>
</html>