Get element attributes - javascript

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.

Related

Search data from specific DOM part

I have a search input field, and I want to get the user's input dynamically and update a list contained in a <div>
I'm setting up a search solution for a catalogue where you can display a list of items.
Right now all the items are shown at once.
the html
<input type="search" id="search-field" placeholder="Search...">
</div>
<div class="container">
<p id="guide">Select a category from the menu</p>
<ul id="product-list">
</ul>
<script src="./preload.js"></script>
</div>
the js code
var fileList = document.getElementById('product-list');
var title = document.getElementById('guide');
title.innerHTML = `You are looking at the ${products} catalog.`;
for(var i = 0; i < thumbFiles.length; i++){
var pathName = thumbFiles[i];
var finalName = pathName.split('/').pop();
fileList.innerHTML = document.getElementById('product-list').innerHTML +
`<li class="product-container">
<div class="new-thumb">
<a href="${(items[i])}" id='product-placeholder' target="_blank">
<img src="${(thumbFiles[i])}" alt="thumb" class="thumbnail">
</a>
<h4>${(path.parse(finalName).name)}</h4>
</li>`
};
}
I expect to update the <ul> with the search input text matching element from the catalogue.
You can attach an oninput listener to your element, like this :
In your js script
const myInput = document.querySelector(‘#search-field’);
const fileList = document.querySelector('#product-list');
myInput.addEventListener(‘input’, () => {
// Don’t forget to clean your results on each new input
fileList.innerHTML = ‘’;
for(const index in thumbFiles) {
const pathName = thumbFiles[index];
const finalName = pathName.split('/').pop();
// Here is the function that will check if your current item match user input
if (match(finalName, myInput.value)) {
fileList.innerHTML += [your stuff]
}
}
});
this will trigger a function each time your input is changing value. Here, it calls our arrow function in which we pack all the actions we want to execute when user input some text.
EDIT
Forgot to compare with current input. You can get input value by calling myInput.value
An example of what match() can be :
function match(name, userInput) {
return name.includes(userInput);
}
This will just check if the finalName contains the user input.

I am trying to remove Items from a list with an on-click, what am I missing?

I am trying to remove an item every time it is clicked on but only a single item at a time (the item that was clicked on) when trying to make a 'to-do' list. I can easily remove all simultaneously but I am having a lot of issues trying to do it at an individual level. I thought this would work but hoping to get a second set of eyes on it.
var toDoCount = 0;
var todoarray = [];
window.onload = function() {
//user clicked on the add button in the to-do field add that text into the to-do text
$('#add-to-do').on('click', function(event) {
event.preventDefault();
//assign variable to the value entered into the textbox
var value = document.getElementById('to-do').value;
//test value
console.log(value);
var todoitem = $("#to-dos");
todoitem.attr("item-");
//prepend values into the html and add checkmark, checkbox, and line break to make list
var linebreak = "<br/>";
var todoclose = $("<button>");
todoclose.attr("data-to-do", toDoCount);
todoclose.addClass("checkbox");
todoclose.text("☑");
//prepend values to html
$("#to-dos").prepend(linebreak);
$("#to-dos").prepend(value);
$("#to-dos").prepend(todoclose);
toDoCount++;
todoarray.push(value);
console.log(todoarray);
//to remove item from checklist
$(document.body).on("click", ".checkbox", function() {
var toDoNumber = $(this).attr("data-to-do");
$("#item-" + toDoNumber).remove();
});
});
}
HTML is below
<div class ="col-4">
<!-- To Do List -->
<form onsubmit= "return false;">
<span id = "todo-item" type = "text">
<h4>Add your Agenda Here</h4>
<input id ="to-do" type = "text">
<input id ="add-to-do" value = "Add Item" type = "submit">
</span>
</form>
<div id="to-dos"></div>
</div>
don't need the number, just the element.
change...
$("#item-" + toDoNumber).remove();
to...
$(this).remove();
e.g.
$(document.body).on("click", ".checkbox", function() {
$(this).remove();
});

Removing from a list

I have an add user and a remove user button. I have functions that take whatever is in a text-input and add or remove it from a select. This is my js code:
var addedUsers = [];
function add(){
var form = document.getElementById('form')
var emailInput = form.elements.typer
let email = emailInput.value
emailInput.value = ""
var select = document.getElementById('users')
var option = document.createElement("option")
option.text = email
emailInput.focus()
if (addedUsers.indexOf(email) == -1){
addedUsers.push(email)
select.add(option)
} else {
alert("This user is already one of your recipients!");
}
}
function rem(){
var form = document.getElementById('form')
var emailInput = form.elements.typer
let email = emailInput.value
emailInput.value = ""
var select = document.getElementById('users')
var options = select.options
emailInput.focus()
if (addedUsers.indexOf(email) != -1){
for (var i = 2; i < options.length; i++){
if(email === options[i].innerHTML){
select.remove(i)
addedUsers.splice(email, 1)
break
}
}
} else {
alert("This user is not already one of your recipients!")
}
}
<form id="form">
<div class="recipients">
<input type="text" class="typer" name="typer">
<br><br>
<button onclick="add()" type="button" class="ar">Add User</button>
<button onclick="rem()" type="button" class="ur">Remove User</button>
<br><br><br>
<select id="users" name="users" class="userlist" size="24">
<option class="listhead">__________*Recipents*__________</option>
<option class="listhead">-------------------------------</option>
</select>
</div>
<div class="content">
<button onclick="mail()" class="send">Send</button>
<br><br>
<textarea type:"content" name="content" class="typec" cols="113" rows="12"></textarea>
</div>
</form>
I noticed that I can add nothing at all and remove nothing at all, until an alert comes up. How can I prevent this? Also, if I hit one of the added options in the select, how do I make it show up in the text-input? Thanks!
I would say that you don't use the good methods to add and remove options to the select.
You should use appendChild to add the option to the select and removeChild to remove an option to the select.
example:
// in the add() function
select.appendChild(option)
// in the rem() function
select.removeChild(options[i])
Documentation:
element.appendChild - Reference Web API | MDN
element.removeChild - Reference Web API | MDN
As Chocolord correctly pointed out, you need to use valid methods, like appendChild and removeChild, respectively, instead of add and remove, respectively.
The reason why your program mistakenly thought the users were correctly added was that you actually added them to the array before the actual DOM operation:
addedUsers.push(email)
select.add(option)
respectively. Make sure you you invert the operation to
select.add(option)
addedUsers.push(email)

Cannot set property 'nodeValue' of null

I'm going through a book and it seems to be right, but the following code keeps giving me the error: Cannot set property 'nodeValue' of null. The code makes sense to me, but I don't understand why it can't clear the text value when clicking the clear button.
var clear = function(){
$("miles").firstChild.nodeValue = "";
$("gallons").firstChild.nodeValue = "";
$("mpg").firstChild.nodeValue = "";
}
window.onload = function () {
$("calculate").onclick = calculateMpg;
$("miles").focus();
$("clear").onclick = clear;
}
Html
<section>
<h1>Calculate Miles Per Gallon</h1>
<label for="miles">Miles Driven:</label>
<input type="text" id="miles"><br>
<label for="gallons">Gallons of Gas Used:</label>
<input type="text" id="gallons"><br>
<label for="mpg">Miles Per Gallon</label>
<input type="text" id="mpg" disabled><br>
<label> </label>
<input type="button" id="calculate" value="Calculate MPG"><br>
<input type="button" id="clear" value="clear"><br>
</section>
I think what you want is this where you use the .value property on the input fields directly:
var clear = function() {
$("miles").value = "";
$("gallons").value = "";
$("mpg").value = "";
}
Here's an explanation of what was going on. Now that we can see your full page and see that $ is document.getElementById(), the issue is that you are some of those nodes don't have a firstChild.
For example the object with an id="miles" is an input tag and it has no children so .firstChild is null.
In this line:
$("miles").firstChild.nodeValue = "";
$("miles") gets you the DOM object.
$("miles").firstChild returns null because there are no children of that DOM object.
$("miles").firstChild.nodeValue = ""; is an error because $("miles").firstChild is null and null doesn't have a property .nodeValue.
Input elements do not have child nodes so firstChild gives you null, further more if you're trying to clear the value of the input fields use the value property.
var clear = function(){
$("miles").value = "";
$("gallons").value = "";
$("mpg").value = "";
}
Looking at the code you posted in the comments, the problem is that $("miles") and the other elements don't have any children.
It seems like you're trying to do something like this:
var clear = function() {
$("miles").value = "";
$("gallons").value = "";
$("mpg").value = "";
}

Javascript obtain outer parent id DIV

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/

Categories