change span content inside div with dynamic id - javascript

I need to change the content of span tag inside of div tag with div id dynamically. I tried this code but it's not working. I think the problem with $('#'+ids[i]). Even I'm getting the information correctly to each id. Any suggestions please.
JavaScript:
var ids = ["Of0UWpK5bEo","1qYMJjTxJnM","8aAab7gxbEg","ZEd6aKdeC8g","qQcFvamzdno","yovbI8DOMpk"];
for (i = 0; i < ids.length; i++) {
$.get("https://www.googleapis.com/youtube/v3/videos?part=snippet,statistics&id="+ ids[i] + "&key=AIzaSyDEm5wGLsWi2G3WG40re-DAJcWioQSpJ6o", function(data){
$('#'+ids[i]).parent().find('.caption').text(data.items[0].snippet.title);
});
}
HTML:
<div id="Of0UWpK5bEo" class="status">
<img src="http://img.youtube.com/vi/Of0UWpK5bEo/0.jpg" height="100px" width="100px"/>
<span class="caption">Text below the image</span>
</div>

I found it to be the problem of variable scope.
This can be solved by using a anonymous function.
Pass the loop variable i to the anonymous function so that ii will be accessible inside the function.
Check out this fiddle.
Here is the snippet.
var ids = ["Of0UWpK5bEo", "1qYMJjTxJnM", "8aAab7gxbEg", "ZEd6aKdeC8g", "qQcFvamzdno", "yovbI8DOMpk"];
var i;
for (i = 0; i < ids.length; i++) {
(function(ii) { // collect into 'ii' here
$.get("https://www.googleapis.com/youtube/v3/videos?part=snippet,statistics&id=" + ids[ii] + "&key=AIzaSyDEm5wGLsWi2G3WG40re-DAJcWioQSpJ6o", function(data) {
$('#' + ids[ii]).html(data.items[0].snippet.title);
});
}(i)); //pass 'i' here
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="Of0UWpK5bEo" class="status">
<img src="http://img.youtube.com/vi/Of0UWpK5bEo/0.jpg" height="100px" width="100px" />
<span class="caption">Text below the image</span>
</div>

What you need is:
$('#'+ids[i]).find('.caption').text(...);
as .caption is the child of the ID in question itself. Hence, .parent() is not required.
A Demo
Also, use var in your loop as below. You'd create a global for no reason, otherwise.
for (var i = 0; i < ids.length; i++) {
As it turned out, it's due to the async behaviour of $.get() and loop being synchronous. So, your loop has already finshed running whereas you may be at your 1st or 2nd ajax request. What you need to do is scope the id value (based in i) into the ajax request, probably by creating a closure, like below.
var ids = ["Of0UWpK5bEo","1qYMJjTxJnM","8aAab7gxbEg"];
for (var i = 0; i < ids.length; i++) {
(function(id) {
$.get("https://www.googleapis.com/youtube/v3/videos?part=snippet,statistics&id="+ id + "&key=AIzaSyDEm5wGLsWi2G3WG40re-DAJcWioQSpJ6o", function(data) {
$('#' + id).find('.caption').text(id); //use data.items[0].snippet.title instead of id
});
}(ids[i]));
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="Of0UWpK5bEo" class="status">
<span class="caption">Text below the image</span>
</div>
<div id="1qYMJjTxJnM" class="status">
<span class="caption">Text below the image</span>
</div>
<div id="8aAab7gxbEg" class="status">
<span class="caption">Text below the image</span>
</div>
Here is a working demo using fiddle echo apis.

This code isn't the best written, but I can explain what is going on.
Your fundamental problem is that the value for "i" is no longer what you expect it to be. By the time the results of the AJAX function have completed, it's an undefined value. The correct way to do this is with an iterator:
$.each(ids, function(index, id) {
$.get("..." + id + "...", function(data) {
$("#" + id).parent().find('.caption').text(data.items[0].snippet.title);
});
});
Also, make sure your code is in a "document.ready()" block or you may not be able to find the elements:
$(document).ready(function() {
$.each(ids, function(index, id) {
$.get("..." + id + "...", function(data) {
$("#" + id).parent().find('.caption').text(data.items[0].snippet.title);
});
});
});
That being said, this looks like the interface should be dynamically created in Javascript. That would allow you to avoid many of the issues with matching IDs in tags and searching for sibling tags since you'd already have the reference.
Working fiddle: https://jsfiddle.net/85jeaoqq/
Here's a slightly better version that dynamically creates the images and caption. It includes code to limit the text to 20 characters: https://jsfiddle.net/x7v2zt6f/

Related

how to i get access to my remove button using javascript [duplicate]

I have a page with anchor tags throughout the body like this:
<a id="test" name="Name 1"></a>
<a id="test" name="Name 2"></a>
<a id="test" name="Name 3"></a>
The ID is always the same but the name changes.
I need to populate a list of the names of these anchor tags, for example; Name 1, Name 2, Name 3. This is where I've got to so far:
document.write(document.getElementById("readme").name);
This writes out the name of the first anchor tag. I'm in need of a way to get multiple elements by Id.
Any help is greatly appreciated.
If you can change the markup, you might want to use class instead.
HTML
<a class="test" name="Name 1"></a>
<a class="test" name="Name 2"></a>
<a class="test" name="Name 3"></a>
JS
var elements = document.getElementsByClassName("test");
var names = '';
for(var i = 0; i < elements.length; i++) {
names += elements[i].name;
}
document.write(names);
jsfiddle demo
Today you can select elements with the same id attribute this way:
document.querySelectorAll('[id=test]');
Or this way with jQuery:
$('[id=test]');
CSS selector #test { ... } should work also for all elements with id = "test". Вut the only thing: document.querySelectorAll('#test') (or $('#test') ) - will return only a first element with this id.
Is it good, or not - I can't tell . But sometimes it is difficult to follow unique id standart .
For example you have the comment widget, with HTML-ids, and JS-code, working with these HTML-ids. Sooner or later you'll need to render this widget many times, to comment a different objects into a single page: and here the standart will broken (often there is no time or not allow - to rewrite built-in code).
As oppose to what others might say, using the same Id for multiple elements will not stop the page from being loaded, but when trying to select an element by Id, the only element returned is the first element with the id specified. Not to mention using the same id is not even valid HTML.
That being so, never use duplicate id attributes. If you are thinking you need to, then you are looking for class instead. For example:
<div id="div1" class="mydiv">Content here</div>
<div id="div2" class="mydiv">Content here</div>
<div id="div3" class="mydiv">Content here</div>
Notice how each given element has a different id, but the same class. As oppose to what you did above, this is legal HTML syntax. Any CSS styles you use for '.mydiv' (the dot means class) will correctly work for each individual element with the same class.
With a little help from Snipplr, you may use this to get every element by specifiying a certain class name:
function getAllByClass(classname, node) {
if (!document.getElementsByClassName) {
if (!node) {
node = document.body;
}
var a = [],
re = new RegExp('\\b' + classname + '\\b'),
els = node.getElementsByTagName("*");
for (var i = 0, j = els.length; i < j; i++) {
if (re.test(els[i].className)) {
a.push(els[i]);
}
}
} else {
return document.getElementsByClassName(classname);
}
return a;
}
The above script will return an Array, so make sure you adjust properly for that.
Here is a function I came up with
function getElementsById(elementID){
var elementCollection = new Array();
var allElements = document.getElementsByTagName("*");
for(i = 0; i < allElements.length; i++){
if(allElements[i].id == elementID)
elementCollection.push(allElements[i]);
}
return elementCollection;
}
Apparently there is a convention supported by prototype, and probably other major JavaScript libraries.
However, I have come to discover that dollar sign function has become
the more-or-less de facto shortcut to document.getElementById(). Let’s
face it, we all use document.getElementById() a lot. Not only does it
take time to type, but it adds bytes to your code as well.
here is the function from prototype:
function $(element) {
if (arguments.length > 1) {
for (var i = 0, elements = [], length = arguments.length; i < length; i++)
elements.push($(arguments[i]));
return elements;
}
if (Object.isString(element))
element = document.getElementById(element);
return Element.extend(element);
}
[Source]
You can't have duplicate ids. Ids are supposed to be unique. You might want to use a specialized class instead.
You should use querySelectorAll, this writes every occurrence in an array and it allows you to use forEach to get individual element.
document.querySelectorAll('[id=test]').forEach(element=>
document.write(element);
});
More than one Element with the same ID is not allowed, getElementById Returns the Element whose ID is given by elementId. If no such element exists, returns null. Behavior is not defined if more than one element has this ID.
If you're not religious about keeping your HTML valid then I can see use cases where having the same ID on multiple elements may be useful.
One example is testing. Often we identify elements to test against by finding all elements with a particular class. However, if we find ourselves adding classes purely for testing purposes, then I would contend that that's wrong. Classes are for styling, not identification.
If IDs are for identification, why must it be that only one element can have a particular identifier? Particularly in today's frontend world, with reusable components, if we don't want to use classes for identification, then we need to use IDs. But, if we use multiples of a component, we'll have multiple elements with the same ID.
I'm saying that's OK. If that's anathema to you, that's fine, I understand your view. Let's agree to disagree and move on.
If you want a solution that actually finds all IDs of the same name though, then it's this:
function getElementsById(id) {
const elementsWithId = []
const allElements = document.getElementsByTagName('*')
for(let key in allElements) {
if(allElements.hasOwnProperty(key)) {
const element = allElements[key]
if(element.id === id) {
elementsWithId.push(element)
}
}
}
return elementsWithId
}
EDIT, ES6 FTW:
function getElementsById(id) {
return [...document.getElementsByTagName('*')].filter(element => element.id === id)
}
With querySelectorAll you can select the elements you want without the same id using css selector:
var elems = document.querySelectorAll("#id1, #id1, #id3");
You can get the multiple element by id by identifying what element it is. For example
<div id='id'></div>
<div id='id'></div>
<div id='id'></div>
I assume if you are using jQuery you can select all them all by
$("div#id")
. This will get you array of elements you loop them based on your logic.
No duplicate ids, it's the basis. If you have an html structure as
<a id="test1" name="Name_1">a1</a>
<a id="test2" name="Name_2">a2</a>
<a id="test3" name="Name_3">a3</a>
Nowadays, with ES6, you can select multiple elements with different id's using the map() method:
const elements = ['test1', 'test2', 'test3'].map(id => document.getElementById(id));
console.log(elements);
// (3) [a#test1, a#test2, a#test3]
Of course, it's easier to select them if they have a same class.
The elements with the different ids are in an array.
You can, for example, remove them from the DOM with the forEach() method:
elements.forEach(el => el.remove());
An "id" Specifies a unique id for an element & a class Specifies one or more classnames for an element . So its better to use "Class" instead of "id".
Below is the work around to submit Multi values, in case of converting the application from ASP to PHP
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML>
<HEAD>
<TITLE> New Document </TITLE>
<META NAME="Generator" CONTENT="EditPlus">
<META NAME="Author" CONTENT="">
<META NAME="Keywords" CONTENT="">
<META NAME="Description" CONTENT="">
</HEAD>
<script language="javascript">
function SetValuesOfSameElements() {
var Arr_Elements = [];
Arr_Elements = document.getElementsByClassName("MultiElements");
for(var i=0; i<Arr_Elements.length; i++) {
Arr_Elements[i].value = '';
var Element_Name = Arr_Elements[i].name;
var Main_Element_Type = Arr_Elements[i].getAttribute("MainElementType");
var Multi_Elements = [];
Multi_Elements = document.getElementsByName(Element_Name);
var Multi_Elements_Values = '';
//alert(Element_Name + " > " + Main_Element_Type + " > " + Multi_Elements_Values);
if (Main_Element_Type == "CheckBox") {
for(var j=0; j<Multi_Elements.length; j++) {
if (Multi_Elements[j].checked == true) {
if (Multi_Elements_Values == '') {
Multi_Elements_Values = Multi_Elements[j].value;
}
else {
Multi_Elements_Values += ', '+ Multi_Elements[j].value;
}
}
}
}
if (Main_Element_Type == "Hidden" || Main_Element_Type == "TextBox") {
for(var j=0; j<Multi_Elements.length; j++) {
if (Multi_Elements_Values == '') {
Multi_Elements_Values = Multi_Elements[j].value;
}
else {
if (Multi_Elements[j].value != '') {
Multi_Elements_Values += ', '+ Multi_Elements[j].value;
}
}
}
}
Arr_Elements[i].value = Multi_Elements_Values;
}
}
</script>
<BODY>
<form name="Training" action="TestCB.php" method="get" onsubmit="SetValuesOfSameElements()"/>
<table>
<tr>
<td>Check Box</td>
<td>
<input type="CheckBox" name="TestCB" id="TestCB" value="123">123</input>
<input type="CheckBox" name="TestCB" id="TestCB" value="234">234</input>
<input type="CheckBox" name="TestCB" id="TestCB" value="345">345</input>
</td>
<td>
<input type="hidden" name="SdPart" id="SdPart" value="1231"></input>
<input type="hidden" name="SdPart" id="SdPart" value="2341"></input>
<input type="hidden" name="SdPart" id="SdPart" value="3451"></input>
<input type="textbox" name="Test11" id="Test11" value="345111"></input>
<!-- Define hidden Elements with Class name 'MultiElements' for all the Form Elements that used the Same Name (Check Boxes, Multi Select, Text Elements with the Same Name, Hidden Elements with the Same Name, etc
-->
<input type="hidden" MainElementType="CheckBox" name="TestCB" class="MultiElements" value=""></input>
<input type="hidden" MainElementType="Hidden" name="SdPart" class="MultiElements" value=""></input>
<input type="hidden" MainElementType="TextBox" name="Test11" class="MultiElements" value=""></input>
</td>
</tr>
<tr>
<td colspan="2">
<input type="Submit" name="Submit" id="Submit" value="Submit" />
</td>
</tr>
</table>
</form>
</BODY>
</HTML>
testCB.php
<?php
echo $_GET["TestCB"];
echo "<br/>";
echo $_GET["SdPart"];
echo "<br/>";
echo $_GET["Test11"];
?>
Use jquery multiple selector.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>multiple demo</title>
<style>
div,span,p {
width: 126px;
height: 60px;
float:left;
padding: 3px;
margin: 2px;
background-color: #EEEEEE;
font-size:14px;
}
</style>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
</head>
<body>
<div>div</div>
<p class="myClass">p class="myClass"</p>
<p class="notMyClass">p class="notMyClass"</p>
<span>span</span>
<script>$("div,span,p.myClass").css("border","3px solid red");</script>
</body>
</html>
Link : http://api.jquery.com/multiple-selector/
selector should like this : $("#id1,#id2,#id3")

How to split the text retrieved from `div` elements

I have this HTML:
<div class="chip">java<span class="material-icons close">×</span></div>
<div class="chip">spring<span class="material-icons close">×</span></div>
<div class="chip">python<span class="material-icons close">×</span></div>
With the following script I try to retrieve the texts without the x. I get the values of the div elements using their class name, but when passed to split it, the same string returns without any split:
var skills = $('.chip').text();
var arr = skills.split('x');
for(var i=0;i<arr.length;i++){
alert(arr[i]);
}
For example:
var skills = 'javaxspringxpython';
The output remains the same. I know this is because of the .text() method, but not sure how to solve this. I tried using .val(), but that didn't work.
How can I resolve this?
Your HTML has already three separate elements.
Instead of splitting the combined text, you could get the individual contents of the tags, and kick out any other tags from that content (the span elements in your case). Then you will have three matching text nodes, which you then need to map to array items:
var skills = $('.chip').contents().filter(function() {
return this.nodeType === 3; // only immediate text in div, not in span
}).map(function() {
return $(this).text();
}).get();
console.log(skills);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="chip">java<span class="material-icons close">×</span></div>
<div class="chip">spring<span class="material-icons close">×</span></div>
<div class="chip">python<span class="material-icons close">×</span></div>
Its Work For Me..
$(document).ready(function() {
var skills = $('.chip').text();
var arr = skills.split('x');
for(var i=0;i<arr.length;i++){
// alert(arr[i]);
console.log(arr[i]);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='chip'>javaxspringxpython</div>
Hope Its Work !!!
Happy Coding !!

change label foreach element in html using javascript

I am using both html and velocity and came up with this code. The names and images are stored in an array and this is the code I used to display each of the contents of this array to the page.
#foreach($starter in $starter)
<div class="product">
<div class="color"><img src= "$starter.img" width="100" height="100"></div>
<span class="product-name">$starter.name</span>
<div class="compare-wrap">
<input type="checkbox" id="">
<label id="view">Compare</label>
</div>
</div>
#end
I wanted the label to change from "Compare" to "View Compare" while at the same time storing its id in the array upon checking their correspondng check box. I eventually came up with this code:
var checkedArray = [];
$(":checkbox").change(function(){
if((this).checked){
checkedArray.push(this.id);
document.getElementById('view').innerHTML = "<a href='/compare'>View Compare</a>";
}
else{
checkedArray.splice(checkedArray.indexOf(this.id), 1);
document.getElementById('view').innerHTML = 'Compare';
}
var str = checkedArray.join(', ');
alert(str);
});
but it seems it is only applicable to the first content of the array. Any idea how I can use a foreach code at this point?
document.getElementById() only supports one name at a time and only returns a single node not an array of nodes. You should use a class:
var views = document.getElementsByClassName('view');
var i = views.length;
while(i--) {
views[i].innerHTML = "Compare";
}
HTML
<label class="view">Compare</label>
Element ID must be unique.
Hope it helps.

Find an element that contains id of selector + text

I'm confused as to how I should go about doing this.
My page is using PHP to take product codes off a database and using them to generate ids for elements. For example: $("#touch-'.$productcode.'") and $("#popup-'.$productcode.'")
I need to make it so when an element is clicked on, jQuery will find an element in the document which contains the last 11 characters of the selector's id plus additional text.
e.g. the selector $(this) (which has a generated id of #touch-123-456-789) would get its own id, remove everything but the last 11 characters (the product code), append popup- to the beginning, and then find the element $("#popup-123-456-789") and perform an action.
How about some thing like this..
<div class='touch' id='touch-123-456-789'> bla bla </div>
on your jquery
$('.touch').click(function(){
var id = $(this).attr('id');
id = id.substring(5);
$('#popup' + id).doSomething();
});
This is your Html
<div class="pop-up" value= "123-456-789">one</div>
<div class="pop-up" value="123-123-123">two</div>
This is your jQuery
$(".pop-up").click(function(){
var value = $(this).attr("value");
var yourElement = "popup-"+value;
$("#"+yourElement).doSomething(function () {
});
});
Try to break your id like:
$('.touch').click(function () {
var id = $(this).attr('id');
id = id.split(/-(.+)?/)[1];
$('#popup-' + id).html("Hello changed");
});
The .split() here will split the on the first occurrence of "-". So you can do anything with this.
Lets suppose you have two elements in your html code:
<div class='touch' id='touch-123-456-789'> Touch me </div>
<div class="popup" id="popup-123-456-789"></div>
This might help. http://jsfiddle.net/79yut/
HTML:
<div class="element" id="#touch-123-456-790">Sample element1</div>
<div class="element" id="#touch-123-456-791">Sample element2</div>
<div class="element" id="#touch-123-456-792">Sample element3</div>
<div class="element" id="#touch-123-456-793">Sample element4</div>
<div class="element" id="#touch-123-456-794">Sample element5</div>
JS:
for (i = 0; i <= $(".element").length; i++) {
if (i < $(".element").length) {
var id = $(".element").eq(i).attr("id");
id = "popup-" + id.substring(7);
$(".element").eq(i).attr("id", id);
} else {
$("#popup-123-456-792").css('color','blue');
}
}

Dynamically populate markup with XML data using javascript variables

I'm on a .NET 4.0 environment using jQuery and Visual Studio to write everything, but neither of these facts should matter that much except how to populate the XML data.
I'm starting out with this script which has a lot of markup in it. My task is to get the markup out of the script and to populate the the XML data into the markup in its proper place. I'm trying to keep the presentation and behavior layers as separate as possible by doing this.
function addIcons(IconType) {
var li ="";
var onclickMethod="";
for (var item in hashObject) {
var thumbNail = item.split("_");
if (thumbNail[0] == IconType +"ThumbNail") {
var imagePath = baseUrlThumbNailImages + hashObject[item];
li = li + "<li onclick=IconClick('" + IconType +"',"+ thumbNail[1] + ")><img src=\"" + imagePath + "\" alt=\"" + IconType + " shape\"></li>\n";
}
}
$("#" + IconType + "ThumbNailShapes").append(li);
}
Here's example markup I want as final result:
<ul>
<li onclick="IconClick('Item',1)">
<img src="/images/image_1.png" alt="Item shape" />
</li>
<li onclick="IconClick('Item',2)">
<img src="/images/image_2.png" alt="Item shape" />
</li>
<li onclick="IconClick('Item',3)">
<img src="/images/image_3.png" alt="Item shape" />
</li>
</ul>
While I know I need to take out the line of code that starts li = li + ..., I'm also not familiar enough with OOP to understand how to write a for loop to populate the markup.
So there's two factors that I am not sure how to code:
The blank markup - does the markup need variables to populate it or should javascript do this automatically?
The javascript - I don't know how to recode the javascript to find each list item and image tag to populate the various data.
Do I need the markup to be blank like this, where all the variable data is not there yet?
<ul id="IconThumbnailShapes">
<li onclick="">
<img src="" alt="shape" />
</li>
<li onclick="">
<img src="" alt="shape" />
</li>
<li onclick="">
<img src="" alt="shape" />
</li>
</ul>
I appreciate the insight and help.
I would do it like this.
Let's suppose we have a container DIV#foo where all this code has to reside.
<div id="foo"></div>
We then do this:
$(function() {
// DOM ready
$('#foo').on('click', '#IconThumbnailShapes li', function() {
// Do whatever you have to do with icon
// Second argument there '#IconThu... li' means the event will be trigerred
// as soon as you add your icons, but they don't have to be there
// right now.
});
function addIcons(iconType) {
var s = '<ul id="IconThumbnailShapes">'
var l = '<li><img src="$SRC" alt="$ICON shape" /></li>'
var data = [{...}, {...}, {...}];
var len = data.length;
var datum;
for (var i = len; i; i--) {
datum = data[len - i];
s += l.replace('$SRC', datum.src).replace('$ICON', iconType);
}
s += '</ul>';
$('#foo').html(s);
}
});
So, we do it like this, because we don't want to fire jQuery stuff in the for loop. That kills performance. Instead we set up a deferred even handler for click on the conainer DIV#foo, and we shove the whole bunch of markup into the container as a string.

Categories

Resources