I need my javascript code to retrieve id by block of code - javascript

So I have a Javscript that can retrieve the id from onClick, but it only selects the first div with an id. The problem is that I have multiple unique id's that are generated in php and then saved in mysql database. The id's are unique but I need my onClick to retrieve the id in the div block.
function postFunction() {
var i;
var x;
for (i = 0; i< x.length; i++)
x = document.getElementsByClassName("post")[0].getAttribute("id");
//alert(this.id);
alert(x);
}
Is there a way to select id per code block?

I see you have the jQuery tag in your question. Try this:
function postFunction() {
var ids = []; //in case you need to have all ids;
$('.post').each(function() {
var id = $(this).attr('id');
ids.push(id); //Store the id in the array
alert(id);
});
console.log(ids); //Show all ids.
}

Using Jquery will make life easier.
var h=[];
$("div").each(function(){
h.push($(this).attr('id'));
});
alert(h);
You will get a array of all div ID's.

You need to get the elements, and then loop over them (currently your loop code doesn't do anything)
function postFunction() {
var postEls = document.getElementsByClassName('post'),
postElsCount = postEls.length;
for (var i = 0; i < postElsCount; i++) {
alert(postEls[i].id);
}
}
Here's a fiddle

jQuery will always ease such operations but you can also achieve the same using vanilla javascript. It takes effort & time because of cross browser support for javascript varies much but it's worth to give a try.
function postFunction() {
var ids = [];
var x = document.getElementByClassName('post');
for (var i = 0; i < x.length; i++) {
var temp = x[i].getAttribute("id");
ids.push(temp);
}
console.log(ids)
}

Without jQuery:
function postFunction() {
var ids = Array.prototype.map.call(document.getElementsByClassName("post"), function(elem) {
return elem.id
});
console.log(ids.join(", "));
}

getElementsByClassName() returns a list of all HTML elements with the provided class name. In your loop, you are only ever alerting the first element returned at index [0].
Try:
var x = document.getElementsByClassName("post");
for (var i = 0; i < x.length; i = i + 1) {
alert(x[i].getAttribute("id"));
}
<!DOCTYPE html>
<html lang="en">
<div id="blah1" class="post"></div>
<div id="blah2" class="post"></div>
<div id="blah3" class="post"></div>
<div id="blah4" class="post"></div>
<div id="blah5" class="post"></div>
</html>

Related

Add Different Data Attribute to Anchors

I'm attempting to add data-webpart attributes to all the anchors within a document, but populate their values with the data attributes of their containing divs.
However the code I wrote appears to be populating all of the anchors with only one of the data attributes (or rather, adding the first one to all, then adding the second).
Any help would be much appreciated!
HTML
<body>
<div data-webpart="form">
Test Link
Test Link
Test Link
</div>
<div data-webpart="icon-grid">
Test Link
Test Link
Test Link
</div>
</body>
JavaScript
// data attributer
var webParts = document.querySelectorAll("[data-webpart]");
var webPartAnchors = document.querySelectorAll("[data-webpart] > a");
function addDataAttr() {
var closestWebPartAttr;
for (i = 0; i < webPartAnchors.length; i++) {
for (e = 0; e < webParts.length; e++) {
closestWebPartAttr = webParts[e].getAttribute("data-webpart");
webPartAnchors[i].setAttribute("data-web-part", closestWebPartAttr);
}
}
}
window.onload = function() {
if (webParts !== null) { addDataAttr(); }
};
Your nested loops are copying the data attribute from every DIV to every anchor, because there's nothing that relates each anchor to just their parent. At the end they all have the last data attribute.
Since the anchors are direct children of the DIV, you don't need to use querySelectorAll() to get them, you can just use .children() within the loop.
function addDataAttr() {
for (var i = 0; i < webParts.length; i++) {
var webpart = webParts[i].dataset.webpart;
var children = webParts[i].children;
for (var j = 0; j < children.length; j++) {
children[j].dataset.webpart = webpart;
}
}
}

Smarter way to getElementsByClassName with function

I was wondering if there isn't a smarter way to work with classes between javascript and css. As I understander the "only" / most common way to select all elements with the same class is by making a for loop:
jsfiddle.net/JoshuaChronstedt/obk92sh6/2/
var elems = document.getElementsByClassName("helloClass");
for (var i = 0; i < elems.length; i++) {
elems[i].style.background = "red";
}
Wouldn't it be possible to create a function to hold the for loop? I'm a noob to js and can't seem to make it work:
jsfiddle.net/JoshuaChronstedt/obk92sh6/6/
function getClass(getClassName) {
var elems = document.getElementsByClassName("getClassName");
for (var i = 0; i < elems.length; i++) {
elems[i];
}
}
getClass("helloClass").style.background = "red";
getClass("helloClassTwo").style.background = "blue";
I guess what I am ultimately trying to do is find a more readable and more DRY way of editing elements by class names.
edit:
Thanks for the snippets. I have tried using some of the code that has been sugested. But it still doesn't seem to work:
function getClass(getClassName) {
Array.from(document.querySelectorAll('.' + '\'' + getClassName + '\'')).forEach(e => e);
}
getClass(helloClass).style.background = 'yellow';
getClass(helloClassTwo).style.color = 'red';
<div class="helloClass">
hello class
</div>
<div class="helloClass">
hello class
</div>
<div class="helloClassTwo">
hello class Two
</div>
<div class="helloClassTwo">
hello class Two
</div>
You can implement map function to iterate.map function iterates elements in array.
Hence here you need to change normal object to array first using Array.from() method
var elems;
function getClass(getClassfuncCont) {
return document.getElementsByClassName(getClassfuncCont);
}
elems = getClass("helloClass");
Array.from(elems).map(element=>element.style.background = "red");
Please refer working snippet.
var elems;
function getClass(getClassfuncCont) {
return document.getElementsByClassName(getClassfuncCont);
}
elems = getClass("helloClass");
Array.from(elems).map(element=>element.style.background = "red");
<div class="helloClass">
hello class
</div>
<div class="helloClass">
hello class
</div>
<div class="helloClass">
hello class
</div>
As mentioned in one of the comments, you're passing getClassName as string when you're supposed to pass it as variable. Taking away the double quote should make it work.
However, you won't be able to modify the style property the way you're doing it right now, because your function does not return the elements. If what you're trying to do is batch-changing the background color based on class name, I suggest adding the color name as a second variable:
//renaming the function so it's more representative
function colorBackgroundByClass(getClassName,color) {
var elems = document.getElementsByClassName(getClassName);
for (var i = 0; i < elems.length; i++) {
elems[i].style.background = color;
}
}
colorBackgroundByClass("helloClass","red");
colorBackgroundByClass("helloClassTwo","blue");

jQuery Replace With only works once for an object reference

I'm having a strange issue with replaceWith (or more likely with object referencing).
I am trying to create a kind of table of rows that either have empty slots or full slots. As a demonstration I made this simple fiddle. http://jsfiddle.net/Ltxtvyn3/3/ In this fiddle 4 empty slots are initialized. Then one is filled. Then the same one should be emptied. But instead it is remaining filled. It is as if I can only use replaceWith once, or I am not understanding something about my object references.
HTML
<div class = "slot empty">Empty</div>
<div class = "slot full">Full</div>
<div class = "wrapper"></div>
CSS
.slot{
width:50px;
height:50px;
display:none;
}
.empty{
background-color:red;
}
.full{
background-color:blue;
}
Javascript
var wrapper = $('.wrapper');
var empty = $('.slot.empty');
var full = $('.slot.full');
var slots = {};
for(var i = 0; i < 4; i++){
slots[i] = empty.clone().show();
wrapper.append(slots[i]);
}
function fillSlot(id){
slots[id].replaceWith(full.clone().show());
}
function emptySlot(id){
slots[id].replaceWith(empty.clone().show());
}
fillSlot(1);
emptySlot(1);
I am hoping that the object var slots maintains a reference to the divs and I'm not sure if it is doing that or not.
No, it's not keeping a reference, but you can fix this pretty easily.
Here's some running code:
var wrapper = $('.wrapper');
var empty = $('.slot.empty');
var full = $('.slot.full');
for(var i = 0; i < 4; i++){
wrapper.append(empty.clone().show());
}
function fillSlot(id){
$(".wrapper .slot").eq(id).replaceWith(full.clone().show());
}
function emptySlot(id){
$(".wrapper .slot").eq(id).replaceWith(empty.clone().show());
}
fillSlot(1);
setTimeout(function() {
emptySlot(1);
}, 2000);
.slot{
width:50px;
height:50px;
display:none;
}
.empty{
background-color:red;
}
.full{
background-color:blue;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class = "slot empty">Empty</div>
<div class = "slot full">Full</div>
<div class = "wrapper"></div>
Thanks for the answers. I know understand why the object doesn't keep a reference, and I really wanted that to be the case. I simply added a wrapper slot and then I will affect the contents of the wrapper. That way I always have a reference to the slot.
HTML
<div class="slot-content empty">Empty</div>
<div class="slot-content full">Full</div>
<div class = "slot"></div>
<div id="wrapper"></div>
Javascript
var wrapper = $('#wrapper');
var slot = $('.slot');
var empty = $('.slot-content.empty');
var full = $('.slot-content.full');
var slots = {};
for(var i = 0; i < 4; i++){
slots[i] = slot.clone().show();
slots[i].html(empty.clone().show());
wrapper.append(slots[i]);
}
function fillSlot(id){
slots[id].html(full.clone().show());
slots[id].find('.slot-content').html('hello');
}
function emptySlot(id){
slots[id].html(empty.clone().show());
}
fillSlot(1);
emptySlot(1);
fillSlot(2);
UPDATED
Your code work fine just if you change the selection method and you don't want slots list no more.
Replace :
function fillSlot(id){
slots[id].replaceWith(full.clone().show());
}
function emptySlot(id){
slots[id].replaceWith(empty.clone().show());
}
BY :
function fillSlot(id){
wrapper.children().eq(id).replaceWith(full.clone().show());
}
function emptySlot(id){
wrapper.children().eq(id).replaceWith(empty.clone().show());
}
Selecting directly from wrapper what means selecting from fresh DOM. that will fix the problem, take a look at updated fiddle bellow.
Updated JSFiddle
The problem is slots[i] isn't pointing to the div - so replaceWith won't pick the right item. Update the loop as follows (adding slots[i] = wrapper.find(':last-child') ):
for(var i = 0; i < 4; i++){
slots[i] = empty.clone().show();
wrapper.append(slots[i]);
slots[i] = wrapper.find(':last-child')
}
Actually this may make the code a little easier to understand (replace loop with this instead)
for(var i = 0; i < 4; i++){
wrapper.append(empty.clone().show());
slots[i] = wrapper.find(':last-child')
}
Tested and works on FF..
It's not keeping a reference to the DOM element. If you still want to use the array, then you can just repopulate the list every time you update one of its elements. Not terribly efficient, but I suppose it saves you from keeping state in the DOM.
function redraw() {
$('.wrapper').empty();
for(var i = 0; i < 4; i++){
wrapper.append(slots[i]);
}
}
JSFiddle

Dynamical Calculator Javascript

It is a calculator which has spans from which I want to take a values(1,2,3, etc.) and two fields: First for displaying what user is typing and the second is for result of calculation.
The question how to get values so when I click on spans it will show it in the second field
Here is the code.
http://jsfiddle.net/ovesyan19/vb394983/2/
<span>(</span>
<span>)</span>
<span class="delete">←</span>
<span class="clear">C</span>
<span>7</span>
<span>8</span>
<span>9</span>
<span class="operator">÷</span>
....
JS:
var keys = document.querySelectorAll(".keys span");
keys.onclick = function(){
for (var i = 0; i < keys.length; i++) {
alert(keys[i].innerHTML);
};
}
var keys = document.querySelectorAll(".keys span");
for (var i = 0; i < keys.length; i++) {
keys[i].onclick = function(){
alert(this.innerHTML);
}
}
keys is a NodeList so you cannot attach the onclick on that. You need to attach it to each element in that list by doing the loop. To get the value you can then simple use this.innerHTML.
Fiddle
This should get you started.. you need to get the value of the span you are clicking and then append it into your result field. Lots more to get this calculator to work but this should get you pointed in the right direction.
Fiddle Update: http://jsfiddle.net/vb394983/3/
JavaScript (jQuery):
$(".keys").on("click","span",function(){
var clickedVal = $(this).text();
$(".display.result").append(clickedVal);
});
You can set a click event on the span elements if you use JQuery.
Eg:
$("span").click(
function(){
$("#calc").val($("#calc").val() + $(this).text());
});
See:
http://jsfiddle.net/vb394983/6/
That's just to answer your question but you should really give the numbers a class such as "valueSpan" and the operators a class such as "operatorSpan" and apply the events based on these classes so that the buttons behave as you'd expect a calculator to.
http://jsfiddle.net/vb394983/7/
var v="",
max_length=8,
register=document.getElementById("register");
// attach key events for numbers
var keys = document.querySelectorAll(".keys span");
for (var i = 0; l = keys.length, i < l; i++) {
keys[i].onclick = function(){
cal(this);
}
};
// magic display number and decimal, this formats like a cash register, modify for your own needs.
cal = function(e){
if (v.length === self.max_length) return;
v += e.innerHTML;
register.innerHTML = (parseInt(v) / 100).toFixed(2);
}
Using JQuery will make your life much easier:
$('.keys span').click(function() {
alert(this.innerHTML);
});

Hide content inside brackets using pure JavaScript

I want to use pure JavaScript to hide all content inside brackets in a document. For example, this:
Sometext [info]
would be replaced with this:
Sometext
With jQuery I can do this with:
<script type="text/javascript">
jQuery(document).ready(function(){
var replaced = jQuery("body").html().replace(/\[.*\]/g,'');
jQuery("body").html(replaced);
});
</script>
The document's DOMContentLoaded event will fire at the same time as the callback you pass to jQuery(document).ready(...).
You can access the body of the page through document.body instead of jQuery("body"), and modify the HTML using the .innerHTML property instead of jQuery's .html() method.
document.addEventListener("DOMContentLoaded", function(event) {
var replaced = document.body.innerHTML.replace(/\[.*\]/g,'');
document.body.innerHTML = replaced;
});
If you use, document.body.innerHTML to replace, it is going to replace everything between [], even valid ones like input names. So I think what you need is to grab all of the textnodes and then run the regex on them. This question looks like it will do the trick.
function recurse(element)
{
if (element.childNodes.length > 0)
for (var i = 0; i < element.childNodes.length; i++)
recurse(element.childNodes[i]);
if (element.nodeType == Node.TEXT_NODE && /\S/.test(element.nodeValue)){
element.nodeValue = element.nodeValue.replace(/\[.*\]/g,'');
}
}
document.addEventListener('DOMContentLoaded', function() {
// This hits the entire document.
// var html = document.getElementsByTagName('html')[0];
// recurse(html);
// This touches only the elements with a class of 'scanME'
var nodes = document.getElementsByClassName('scanME');
for( var i = 0; i < nodes.length; i++) {
recurse(nodes[i]);
}
});
You already have the solution, try "Sometext [info]".replace(/\[.*\]/g,'');
Basically what your doing is this
document.addEventListener('DOMContentLoaded', function() {
var replaced = document.body.innerHTML.replace(/\[.*\]/g,'');
document.body.innerHTML = replaced
});
That would be a silly idea though (speaking for myself)
Make your life easier & your site better by doing something like this
<p> Sometext <span class="tag-variable"> [info] </span> </p>
document.addEventListener('DOMContentLoaded', function(){
var tags = document.getElementsByClassName('tag-variable');
for( var i = 0; i < tags.length; i++) {
var current = tags[i]; // Work with tag here or something
current.parentNode.removeChild( current );
}
});

Categories

Resources