I have the following HTML code where onclick of .spot-info I want to get the value of data-test.
<div class="spot" id="spot-1" data-test="12345">
<div class="spot-main">
<span>Test</span>
view
</div>
</div>
<div class="spot" id="spot-2" data-test="67891">
<div class="spot-main">
<span>Test</span>
view
</div>
</div>
Please see my js attempt below:
$('.spot-info').click(function ( e ) {
e.preventDefault();
var test = $(this).parent().parent().data('data-test');
console.log(test);
});
This test is logging undefined in the console. I thought this would work checking the parent of the parent of .spot-info.
Also, is there way chaining a lot of parent(0) methods together rather than using jQuery.
try attr instead. Also, try 'closest' instead of referring to the parent twice:
$('.spot-info').click(function ( e ) {
e.preventDefault();
var test = $(this).closest('.spot').attr('data-test');
console.log(test);
});
Better if you could use closest() or parents() ,so instead of :
$(this).parent().parent().data('test');
Use :
$(this).closest('.spot').data('test');
$(this).parents('.spot').data('test');
NOTE : The main problem come from .data('data-test'); When you use data() function you shouldn't add the string data- at the start.
Hopet his helps.
Working snippet
$('.spot-info').click(function ( e ) {
e.preventDefault();
var test = $(this).closest('.spot').data('test');
console.log(test);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="spot" id="spot-1" data-test="12345">
<div class="spot-main">
<span>Test</span>
view
</div>
</div>
<div class="spot" id="spot-2" data-test="67891">
<div class="spot-main">
<span>Test</span>
view
</div>
</div>
Not sure - but I think it's this:
$('.spot-info').click(function ( e ) {
e.preventDefault();
var test = $(this).parent().parent().data('test');
console.log(test);
});
You don't need the data- prefix when fetching the data with .data()
Related
I would like to change the style, if there is a specific class on the page,
but it doesn't work. what is wrong with below code snippet?
https://jsfiddle.net/1wc0xdor/
<html>
<body>
<div id='category'>
<div id="search_filters_wrapper">
Filter
</div>
<div class="st_banner_row" style="">
There is Banner
</div>
</div>
</body>
</html>
<script>
var elementExists = document.getElementById('category').getElementsByClassName('st_banner_row');
if (typeof(elementExists) != 'undefined' && elementExists != null)
{
$("#search_filters_wrapper").css({
margin-top: 40,
});
}
</script>
document.getElementsByClassName returns a NodeList. If the class isn't found, it will return an empty list, not null.
Check the length rather than whether it's null.
Also, margin-top is not a valid identifier, you need to quote it to use it as an object key (or you can change to camelCase marginTop:)
if (elementExists.length != 0) {
$("#search_filters_wrapper").css({
"margin-top": 40,
});
}
getElementsByClassName always returns a NodeList (think, array), so elementExists always... exists. So you really only need to check if the array isn't empty to be sure that your target class exists. Further, rather than calling getElementById first, you really only need to call getElementsByClassName, unless you're specifically looking for this class within the scope of the parent element with that id.
If you do need to search within the scope of the parent element with that id, consider using querySelectorAll with an appropriate CSS selector
const elements = document.querySelectorAll('#category .st_banner_row');
if (elements.length) {
$('#search_filters_wrapper').css({
'margin-top': 40
});
}
Also, consider setting a CSS class here rather than programmatically setting the css attribute directly, as the latter is bad practice unless it can't be helped.
Answer:
When you check if the element exists you are actually looking at an Array. To determine if the Array is not empty, and therefore, the class exists within the category element, you just need to test the length property.
If the Array length is 0 and nothing is in it, it will return false. If the Array length is greater than 0, something is in it, and it will return true.
Secondly when you utilize properties that have a hyphen( - ) you need to pass that property as a String within the object you're passing to the css method of JQuery's element wrapper.
var elementExists = document.getElementById('category')
.getElementsByClassName('st_banner_row')
.length;
if (elementExists)
{
$("#search_filters_wrapper").css({"margin-top": 40});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='category'>
<span>Below is 40px</span>
<div id="search_filters_wrapper">
Filter
</div>
<div class="st_banner_row" style="">
There is Banner
</div>
</div>
Aside:
It's odd that you're using JQuery for this one aspect of code. It would be easier and more maintainable to use either all Vanilla JavaScript or all JQuery.
JQuery:
var elementExists = $("#category").find(".st_banner_row").length;
if (elementExists)
{
$("#search_filters_wrapper").css({"margin-top": 40});
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='category'>
<span>Below is 40px</span>
<div id="search_filters_wrapper">
Filter
</div>
<div class="st_banner_row" style="">
There is Banner
</div>
</div>
JavaScript:
var elementExists = document.getElementById('category')
.getElementsByClassName('st_banner_row')
.length;
if (elementExists)
{
document.getElementById("search_filters_wrapper").style.marginTop = "40px";
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='category'>
<span>Below is 40px</span>
<div id="search_filters_wrapper">
Filter
</div>
<div class="st_banner_row" style="">
There is Banner
</div>
</div>
Alternative Vanilla JS using querySelector:
var elementExists = document.querySelector('#category .st_banner_row');
if (elementExists)
{
document.querySelector("#search_filters_wrapper").style.marginTop = "40px";
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='category'>
<span>Below is 40px</span>
<div id="search_filters_wrapper">
Filter
</div>
<div class="st_banner_row" style="">
There is Banner
</div>
</div>
Note In this version we don't need to check the length because if category does not have a child with a class of st_banner_row the selector will return undefined.
Alternative Vanilla JavaScript Functional example:
// helper functions
const el = ( query, context = document ) => context.querySelector( query ),
elementExists = query => Boolean( el( query ) ),
ifElementExists = ( query, fn = () => undefined ) => elementExists( query ) && fn(),
elStyle = query => ( prop, value ) => el( query ).style[ prop ] = value,
changeStyle = query => ( prop, value ) => () => elStyle( query )( prop, value );
// execution
ifElementExists( "#category .st_banner_row",
changeStyle( "#search_filters_wrapper" )( "margin-top", "40px" )
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id='category'>
<span>Below is 40px</span>
<div id="search_filters_wrapper">
Filter
</div>
<div class="st_banner_row" style="">
There is Banner
</div>
</div>
I have a problem with localStorage that will remember all saves even if one section is closed but the other is suppose to remain. Example: There's two banners on a page. If one person clicks to close a banner, it will close that banner but will also remember that the other banner has been closed as well.
Code:
<section class="alert-notice-contain status-alerts">
<div id ="1561524897" class="type-notice relative">
<div class="close-notice-alert"></div>
<div class="status-contain">
<div class="status-msg">
<p>This is a test. This is a long test.</p>
</div>
</div>
</div>
<div id ="1561524873" class="type-notice relative">
<div class="close-notice-alert"></div>
<div class="status-contain">
<div class="status-msg">
<p>This is notice 1</p>
</div>
</div>
</div>
<script> // JS code (inline to get the dynamic #ID
( function( $ ) {
'use strict';
$( document ).on( 'ready', function() {
// Status
if(localStorage.getItem('isHide'))
$('#1561524897').hide();
$('#1561524897 .close-notice-alert').click(function(){
$('#1561524897').hide();localStorage.setItem('isHide',true);
});
} );
} ( jQuery ) );
</script>
<script>
( function( $ ) {
'use strict';
$( document ).on( 'ready', function() {
// Status
if(localStorage.getItem('isHide'))
$('#1561524873').hide();
$('#1561524873 .close-notice-alert').click(function(){
$('#1561524873').hide(); localStorage.setItem('isHide',true);});
} );
} ( jQuery ) );
</script>
</section>
You should store with the id instead of simply set the same variable 'isHide' to true or not.
For example, set to store: localStorage.setItem('isHide-1561524897', true);
and read it: localStorage.getItem('isHide-1561524897');
Use an object to store in localstorage.
JSON.stringify() to convert your object to string form and JSON.parse() to convert string to object form after getting from localstorage.
For ex.
obj = { visibility : 'hidden' }
// set the localstorage
localstorage.setItem('isHide', JSON.stringify(obj));
// get the localstorage
let storageValue = JSON.parse(localstorage.getItem('isHide'));
// use storageValue accordingly
I am using JQUERY in my angularjs project since in some special conditions(AMP).
<div data-ng-repeat = "comment in blog.comments">
<i class="icon-edit font20 edit-faq-icon pointer" id="edit-comment" data-ng-click="editComment(comment);"></i>
</div>
Previously I had ng-click and now I can only find event by jquery.
$('#edit-comment').click(function(){
alert('hi');
})
But I want to access the parameter passed(comment) in the function editComment(comment).
Write a scope function in your angular controller like the below function. You will get the comment as parameter.
$scope.editComment=function(comment)
{
$scope.comment=comment;
};
Set an html content like this.
<div ng-model="comment" id="Comment"></div>
Now you can use
$('#Comment').val() to get the value in click
you can use .text() method to get the value of div.
also you can refer the following link http://api.jquery.com/text/
You can get the comment by passing the comment as a parameter to ng-click function.
var app = angular.module("myApp", []);
app.controller("myCntrlr",function($scope){
$scope.blog=
{
name:"Naresh",
comments:["test comment 1","test comment 2","test comment 3"]
}
$scope.editComment = function(comm){
alert(comm);
};
});
<script src='https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0/angular.js'></script>
<div ng-app="myApp" ng-controller="myCntrlr">
<div ng-repeat = "comment in blog.comments">
<button ng-click="editComment(comment);">get Comment</button>
</div>
</div>
Here is a simplified version of my HTML
<div class="post-title-div">
Link
</div>
<div></div>
<div>
<img class="eye-icon" src="link.jpg"/>
</div>
JavaScript:
$(".eye-icon").click(function(){
var link = $(this).parent('.post-title-div').find(".post-title").attr("href");
})
alert(link) returns undefined, why?
$(this).parent('.post-title-div').find(".post-title") by itself returns [object Object]
Parent/Parents/Closest is not what you're after :
$(".eye-icon").click(function(){
var link = $(this).parent().prev().prev().find(".post-title").attr("href");
alert(link)
})
You don't have a common parent there.
http://jsbin.com/tupeta/edit?html,js,output
However , I suggest that you add a new container which will contain them all . something like :
<div class='wrapper'>
<div class="post-title-div">
Link
</div>
<div></div>
<div>
<img class="eye-icon" src="link.jpg"/>
</div>
</div>
So now you can do :
$(".eye-icon").click(function(){
var link = $(this).closest('.wrapper').find(".post-title").attr("href");
alert(link)
})
The parent of the <img> is the nondescript <div> which surrounds it. jQuery then looks in that div for '.post-title-div', doesn't find anything and returns an empty selector object. In that empty selector it then looks for .post-title and - naturally - doesn't find anything either. It then tries to read an attribute on the new, also empty, selector, which of course can't return anything useful.
The reason why $(this).parent('.post-title-div').find(".post-title") returns an [object Object] is because jQuery selectors never return undefined, they always return another selector, which can be an empty selector.
I am trying to build a function for inserting the number of Facebook Likes into a Div tag. So far, I have a script that can get the URL from a Div tag which is inside of another Div tag called 'entry' and then have the .getJSON() method retrieve the number of Facebook likes for each entry.However, I can't get each retrieved value of Facebook Likes to insert into a Div tag for each entry. Please note, I simplified my code to where it alerts each Facebook Like value. This is what I have so far:
<div class="entry">
<div class="fburl">https://graph.facebook.com/zombies</div>
<div class="facebook-likes"></div>
</div>
<div class="entry">
<div class="fburl">https://graph.facebook.com/starwars</div>
<div class="facebook-likes"></div>
</div>
And here's my jQuery:
$(document).ready(function(){
$(".entry").each(function() {
var fbURL = $(this).find(".fburl").html();
$.getJSON(fbURL, function(fbData) {
var fbArr = fbData['likes'];
alert(fbArr);
});
});
});
​So what I am trying to do is iterate through each entry, get the Open Graph URL for it, retrieve the Likes value, and then insert it into the appropriate Div tag, so the code should render as:
<div class="entry">
<div class="fburl">https://graph.facebook.com/zombies</div>
<div class="facebook-likes">2,586 Likes</div>
</div>
<div class="entry">
<div class="fburl">https://graph.facebook.com/starwars</div>
<div class="facebook-likes">8,905,721 Likes</div>
</div>
​
​
$(document).ready(function() {
$('.entry').each(function() {
var $this = $(this),
fbURL = $this.children('.fburl').html();
$.getJSON(fbURL, function(fbData) {
$this.children('.facebook-likes').html(fbData['likes'] + ' Likes')
});
});
});
See: http://api.jquery.com/children
Demo: http://jsfiddle.net/9EALz/2/
Note: Using children() is going to be marginally more efficient than using find() as it limits the DOM traversal to a single level ( http://jsperf.com/find-vs-children/13 ). Cashing the jQuery object $(this) via var $this = $(this) is also slightly more efficient as it prevents unnecessary selector interpretation ( http://jsperf.com/jquery-cache-vs-no-chace ).
You may want this
$(document).ready(function(){
$(".entry").each(function() {
var entry=$(this), fbURL=$(".fburl", entry).html(),
el=$('.facebook-likes', entry);
$.getJSON(fbURL, function(fbData) {
el.html(numberWithCommas(fbData['likes'])+" Likes");
});
});
});​
A thousand separator function from here
function numberWithCommas(x) {
return x.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
DEMO.
Update:
Alternatively you can use this too (using data-attribute) without an extra div for fburl, i.e.
<div class="entry">
<div data-fburl="https://graph.facebook.com/zombies" class="facebook-likes"></div>
</div>
JS
$(".entry").each(function() {
var entry=$(this), fbURL = $(".facebook-likes", entry).attr('data-fburl'),
el=$('.facebook-likes', entry);
$.getJSON(fbURL, function(fbData) {
el.html(numberWithCommas(fbData['likes'])+" Likes");
});
});