jQuery attr() failing - javascript

In the following code, on the line commented "PROBLEM LINE", attr causes the console.log to print out "undefined" when you click on one of the s. I can't seem to figure out why:
test.js
var html = '';
// number of panels in the carousel
var panelCount = 0;
// panel that is to the forefront of the carousel
var currentPanel = 0;
$(document).ready(function(){
for (var i=0; i < 5; i++) {
html += '<div class="team-member" id="' + panelCount + '">' + panelCount + '</div>';
html += '<div class="reflection" id="' + panelCount + '"></div>';
panelCount++;
}
$('#carousel').html(html);
$(".container-carousel").on('click', '.team-member', function(e) {
var target = $(e.currentTarget);
var targetId = parseInt(target.attr('id'));
var frontRotation = currentPanel * (360/panelCount);
$("#" + targetId + ".reflection").css("transform", "rotateY( " + frontRotation + "deg ) translateZ( 288px ) translateY( 175px ) translateZ( 175px ) rotateX( 90deg )");
var targetIdString = '' + targetId;
/* PROBLEM LINE: */
$("#" + currentPanel + ".reflection").attr('id', targetId);
console.log($("#" + currentPanel + ".reflection").attr('id'));
$("#" + targetId + ".reflection").attr('id', currentPanel);
});
});
test.html
<!DOCTYPE html>
<!-- JQuery-->
<script type = "text/javascript" src = "http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script type = "text/javascript" src = "test.js"></script>
<section class="container-carousel">
<div id="carousel" style="transform: translateZ(-288px) rotateY(-360deg);"></div>
</section>
</html>
Any ideas why?

This is because immediately after you change the id of the element, you try logging by selecting with the old id.
$("#" + currentPanel + ".reflection").attr('id', targetId);
/*The id is now targetId*/
console.log($("#" + currentPanel + ".reflection").attr('id'));
/*currentPanel will not work because an element with that id no longer exists*/
Change your console.log to
console.log($("#" + targetId + ".reflection").attr('id'));
See it working here

The main problem in your code is, you have duplicate IDs in your page. So the id selector will always fetch the first element with the id, the tries to apply the .refelection class selector which does not match thus your selector $("#" + currentPanel + ".reflection") does not return any result.
So use 2 different ids for the team-member and reflection elements, I think you can use a suffix as shown below for 1 element
for (var i = 0; i < 5; i++) {
html += '<div class="team-member" id="' + panelCount + '">' + panelCount + '</div>';
html += '<div class="reflection" id="' + panelCount + '-reflection"></div>';
panelCount++;
}
then
$("#" + targetId + "-reflection").css("transform", "rotateY( " + frontRotation + "deg ) translateZ( 288px ) translateY( 175px ) translateZ( 175px ) rotateX( 90deg )");

As of jQuery 1.6, the .attr() method returns undefined for attributes that have not been set. To retrieve and change DOM properties such as the checked, selected, or disabled state of form elements, use the .prop() method.

Related

HTML - JavaScript - Adding and Deleting/Hiding Elements

In my website the user is going to select an image, that image will then be inserted into a div tag. I need it so when the user clicks the image that was inserted into the div then it will be removed (deleted or hidden) from the div. I've tried:
document.getElementById("elementId").style.display = "none";
and other similar things. I really just cant get this to work please help!
HTML + JavaScript code:
<html>
<head>
<link rel="stylesheet" type="text/css" href="test.css">
<script>
var cardNumber = 1;
var deck = [];
var addCard = function(cardName)
{
if("undefined" != document.getElementById("card" + cardNumber).value)
{
if(deck.indexOf(cardName) > -1)
{
}
else
{
if(deck.length != 1)
{
deck.push(cardName);
document.getElementById("card" + cardNumber).innerHTML = '<img id = "' + cardName + '" class = "deckCardSize" onclick = updateCards(' + cardName + ') src = "Images/Cards/' + cardName + '.png">';
cardNumber += 1;
}
if(deck.length >= 1)
{
cardNumber = 1;
}
}
}
}
</script>
</head>
<body>
<div id = "card1" class = "cards"></div>
<div id = "1">
<img class = "cardSize" onclick = "addCard('Archer')" src = "Images/Cards/Archer.png">
</div>
</body>
CSS Code:
.cards
{
height:150px;
width:125px;
float:left;
margin-left:6.2%;
margin-bottom:30px;
border:5px solid #ff6666;
background-color:#ff6666;
}
.cardSize
{
height:150px;
width:125px;
float:left;
margin-left:7%;
margin-top:30px;
}
You can delete the img by id.
Also fix the issue with the updateCards function:
document.getElementById("card" + cardNumber).innerHTML = '<img id = "' + cardName + '" class = "deckCardSize" onclick = "updateCards(\'' + cardName + '\')" src = "' + cardName + '.png">';
For example,
<div id="card1" class="cards">
<img id="Archer" class="deckCardSize" onclick="updateCards('Archer')" src="Archer.png">
</div>
Then just remove the div with id="Archer":
document.getElementById("Archer").remove();
FYI, I added a simple updateCards function that just hides the img instead of removing it entirely :
var updateCards = function(cardName) {
document.getElementById(cardName).style.display = 'none';
}
You need to attach a click event listener to a class that is applied to all inserted images. the function that the listener fires would then apply css.style.display = "none" to this
First, remove all spaces between attributes and its values (I mean everywhere in your code), that is:
<div id="card1" class="cards"></div><!-- correct -->
<div id = "card1" class = "cards"></div><!-- incorrect -->
Second, you have an error in your code here:
document.getElementById("card" + cardNumber).innerHTML = '<img id = "' + cardName + '" class = "deckCardSize" onclick = updateCards(' + cardName + ') src = "Images/Cards/' + cardName + '.png">';
You have missed double quotes around onclick's value. Replace it with this:
document.getElementById("card" + cardNumber).innerHTML = '<img id="' + cardName + '" class="deckCardSize" onclick="updateCards(' + cardName + ')" src="Images/Cards/' + cardName + '.png">';
Also, you have to define function updateCards(name), it maybe empty, but it must exists. If it doesn't exists, than any javascript code will stops running after you clicked on that image.
Third, <div id = "1"> has an error too. id attribute must starts from a letter.
here is working code:
<html>
<head>
<link rel="stylesheet" type="text/css" href="test.css">
<script>
var cardNumber = 1;
var deck = [];
function addCard(cardName) {
if ("undefined" != document.getElementById("card" + cardNumber).value) {
if (deck.indexOf(cardName) > -1) {
} else {
if (deck.length != 1) {
deck.push(cardName);
document.getElementById("card" + cardNumber).innerHTML = '<img id="img' + cardName + '" class="deckCardSize" onclick="updateCards(\'' + cardName + '\')" src="Images/Cards/' + cardName + '.png">';
cardNumber += 1;
}
if (deck.length >= 1) {
cardNumber = 1;
}
}
}
}
function updateCards(cardName) {
//some work
document.getElementById("img" + cardName).remove();
}
</script>
</head>
<body>
<div id="card1" class="cards"></div>
<div id="main1">
<img class="cardSize" onclick="addCard('Archer')" src="Images/Cards/Archer.png">
</div>
</body>
Tested and worked!

Jquery to toggle one div of same class on click

function demo(){
$('.box').slideToggle('fast');
}
$(document).ready(function(){
$.getJSON( "js/JobOpenings.json", function( data ) {
var glrScrlImg = [];
$.each( data.getJobOpeningsResult, function( key, val ) {
var st = "",id,st2= "",st3="",id;
st +="<h4>" + val.JobTitle + "</h4>";
st3 += "<div class='box'>" + val.JobDetails + "</div>";
$("#newsDetails").append("<li onclick='demo()'>" + st+val.JobSector + "<br>" + st3 + "</li>");
$('.box').hide();
});
});
});
I am reading data from a json file. The div with 'box' class is hidden. Currently this code is displaying all div on click of the li. What changes should I make to display only the div corresponding to the clicked li?
Here what we need to do is to find the .box element within the clicked li, so we need to get a reference to the clicked element.
I would use a delegated jQuery event handler with css to initially hide the element
$(document).ready(function () {
$('#newsDetails').on('click', 'li', function () {
$(this).find('.box').toggleClass('hidden');
})
$.getJSON("js/JobOpenings.json", function (data) {
var glrScrlImg = [];
$.each(data.getJobOpeningsResult, function (key, val) {
var st = "",
id, st2 = "",
st3 = "",
id;
st += "<h4>" + val.JobTitle + "</h4>";
st3 += "<div class='box hidden'>" + val.JobDetails + "</div>";
$("#newsDetails").append("<li>" + st + val.JobSector + "<br>" + st3 + "</li>");
});
});
});
with css
.hidden {
display: none;
}
Pass the control to the function and then based on your control slideToggle its respective .box
function demo(ctrl){
$(ctrl).find('.box').slideToggle('fast');
}
$(document).ready(function(){
$.getJSON( "js/JobOpenings.json", function( data ) {
var glrScrlImg = [];
$.each( data.getJobOpeningsResult, function( key, val ) {
var st = "",id,st2= "",st3="",id;
st +="<h4>" + val.JobTitle + "</h4>";
st3 += "<div class='box'>" + val.JobDetails + "</div>";
$("#newsDetails").append("<li onclick='demo(this)'>" + st+val.JobSector + "<br>" + st3 + "</li>");
$('.box').hide();
});
});
});
Or add a class to li and attach an event handler like below instead of writing inline onclick as below:
$("#newsDetails").append("<li class="someclass"'>" + st+val.JobSector + "<br>" + st3 + "</li>");
and then instead of function demo() write this
$('#newsDetails').on('click','.someclass',function(){
$(this).find('.box').slideToggle('fast');
});
UPDATE
Method 1:
function demo(ctrl){
$('#newsDetails').find('li.box').hide('fast'); //hide all the .box
$(ctrl).find('.box').slideToggle('fast');
}
Method 2:
$('#newsDetails').on('click','.someclass',function(){
$('#newsDetails').find('li.box').hide('fast'); //hide all the .box
$(this).find('.box').slideToggle('fast');
});
UPDATE 2:
Method 1:
function demo(ctrl){
$('#newsDetails').find('li.box').not($(ctrl).find('.box')).hide('fast'); //hide all the .box
$(ctrl).find('.box').slideToggle('fast');
}
Method 2:
$('#newsDetails').on('click','.someclass',function(){
$('#newsDetails').find('li.box').not($(ctrl).find('.box')).hide('fast'); //hide all the .box except this
$(this).find('.box').slideToggle('fast');
});
You should structure your html (which is missing from the question!) so that the div and li are "connected" in some way (maybe the div is child of li, or they have same class, ecc).
Right now the line
$('.box').slideToggle('fast');
is applied to all element with class '.box' in your page. You want to be more selective there, that's where the way you structure the html comes into play.
Here's an example: http://jsfiddle.net/owe0faLs/1/

Textarea not generating from jQuery

I'm trying to make a website using jquery-1.11.1 where I want a <textarea> to be spawned whenever I click on the link which only shows on mouseenter on a div. But I'm getting an error in my console,
Uncaught ReferenceError: inputdivEditor is not defined (Please ignore JSFiddle errors)
I've absolutely no idea why I'm getting this. Here are my codes,
$(document).ready(function () {
$("[id^=divEditor-]").each(function () {
var content = $(this).html();
var targetID = $(this).attr('id');
var txtID = 'input' + targetID;
$('<textarea id="input' + targetID + '" name="' + txtID + '" >' + content + '</textarea>').insertBefore(this).css('display', 'none');
var button = "<a onclick='activateDivEditor(this, " + txtID + ")' class='custom-edit-button editDiv' id='active" + targetID + "'>Embed Code</a>";
$(this).on('mouseenter', function () {
$(this).prepend($(button));
$(this).css('position', 'relative');
});
$(this).on('mouseleave', function () {
$('.editDiv').remove();
});
});
});
function activateDivEditor(btn, txtId) {
var targetID = $(btn).parent().get(0).id;
var update = "<a onclick='deactivateDivEditor(this, " + txtId + ")' class='custom-edit-button updatediv' id='deactive" + targetID + "'>Update</a>";
var cancel = "<a onclick='cancelactivateDivEditor(this)' class='custom-edit-button cancel' id='cancelactive" + targetID + "'>Cancel</a>";
var targetClass = $('#' + targetID).attr('class');
var targetWidth = $('#' + targetID).width();
$('#' + targetID).css('display', 'none');
$('#input' + targetID).css('display', 'block').css('width', targetWidth - 2).css('height', '125px');
$('#input' + targetID).parent().css('position', 'relative');
$(update).prependTo($('#input' + targetID).parent());
$(cancel).prependTo($('#input' + targetID).parent());
}
JSFiddle Demo
How can I generate a textarea whenever I click on the button link? Need this help badly. Thanks.

Why are my rendered elements outside the select tag?

I am trying to append html to a Content Holder in a dialogue box and as you can see by the image, Mile, Meter and Kilometer are outside the select dropdown. Why is this?
var rows = $('#jqxUOMRelatedUnitsDropdownGrid').jqxGrid('getrows');
$("#divNewUnitOfMeasureDefaultUnitsPurchasePlaceHolder").html('<select id="listNewUnitOfMeasureDefaultUnitsPurchasePlaceHolder">');
for (var i = 0; i < rows.length; i++) {
var row = rows[i];
if (row.UOMRelatedUnit_AddItem) {
$("#divNewUnitOfMeasureDefaultUnitsPurchasePlaceHolder").append("<option value='" + row.UOMRelatedUnit_Name + "'>" + row.UOMRelatedUnit_Name + "</option>");
}
}
$("#divNewUnitOfMeasureDefaultUnitsPurchasePlaceHolder").append("</select>");
<div id="divNewUnitOfMeasureDefaultUnitsPurchasePlaceHolder"></div>
Because you are appending into the <div> and not the <select>. Do this way:
$("#divNewUnitOfMeasureDefaultUnitsPurchasePlaceHolder select").append("<option value='" + row.UOMRelatedUnit_Name + "'>" + row.UOMRelatedUnit_Name + "</option>");
// --------------------------------------------------- ^^^^^^
And you cannot do:
$("#divNewUnitOfMeasureDefaultUnitsPurchasePlaceHolder").append("</select>");
That's invalid! Either store everything in a tempAppend string and then use:
$("#divNewUnitOfMeasureDefaultUnitsPurchasePlaceHolder").append(tempAppend);

why wont jQuery remove() work in this case?

Im trying to cause a canvas element to be added to the DOM and then removed after a set time. The killbox() function gets called, but the element is not removed. I believe I have the syntax right, and that there is some underlying issue with removing dynamically added DOM elements.
//con is short for console.log()
function spawnCanvas(e) {
con(e);
var boxheight=50;
var boxwidth=50;
var xpos = e.clientX - boxwidth/2;
var ypos = e.clientY - boxheight/2;
var id = xpos.toString() + ypos.toString();
con("id:" + id);
var tag = "<canvas width='" + boxwidth +
"' height='" + boxheight +
"' style='position:absolute; border:1px solid #000; left:" +
xpos + "px; top:" + ypos + "px;' id='" + id + "'></canvas>";
con(tag);
var t = $(tag);
$("body").append(t);
var p = setTimeout("killbox(" + id + ")", 1500);
}
function killbox(id){
con("in killbox. id:" + id);
$('#id').remove();
}
Within killbox you are removing the element with the literal id id. Instead try;
$('#' + id).remove();
The above will remove the element that has the id that the "id" variable is set to.
Are you sure you don't want $("#" + id).remove();?
because you are searching with an element with the ID id, but you rather wanted to pass the parameter from the function
function killbox(id){
con("in killbox. id:" + id);
$('#'+id).remove();
}

Categories