jQuery detect if document contains an id matching the href of a link - javascript

I've written a function that adds hrefs to an alphabetical navigation bar. I made it so each letter section gives itself an ID. I want to make it so in the event there isn't for example a "C" section, I could add a class to the link linking to #c that would disable it. Here's what I have so far:
<ul class="no-bullet inline">
<li><a class="scroller"><strong>A</strong></a></li>
<li><a class="scroller"><strong>B</strong></a></li>
<li><a class="scroller"><strong>C</strong></a></li>
</ul>
<div class="space-above space-below letter-section">
<h4 class="alpha-heading"><strong>A</strong></h4>
<ul class="no-bullet">
<li><a class="naming" href="#">Benny Goodman</a></li>
<li><a class="naming" href="#">Benny Goodman</a></li>
<li><a class="naming" href="#">Benny Goodman</a></li>
</ul>
</div>
<div class="space-above space-below letter-section">
<h4 class="alpha-heading"><strong>A</strong></h4>
<ul class="no-bullet">
<li><a class="naming" href="#">Benny Goodman</a></li>
<li><a class="naming" href="#">Benny Goodman</a></li>
<li><a class="naming" href="#">Benny Goodman</a></li>
</ul>
</div>
<script>
function alphaLink() {
var alphaLink = $(this);
var alphaLinkRef = "#" + alphaLink.text().toLowerCase();
$(alphaLink).attr("href", alphaLinkRef);
};
$('.scroller').each(alphaLink);
//assigns each content section an ID
function alphaID() {
var section = $(this);
var sectionID = section.text().toLowerCase();
$(section).attr("ID", sectionID);
};
$('.alpha-heading').each(alphaID);
linkMatch function(){
var link = $(this);
if(link.length <= 0) {
$(this).addclass("disabled");
}
$("scroller").each(linkMatch);
</script>

If the HREF is something like '#C', take a look at this:
$(document).ready(function(){
$('a').each(function(i,e){
var href = $(this).attr('href')
if(!findID(href)){
// Doesn't exist
$(this).addClass('disabled');
}
})
function findID(ID){
var exists = false;
if($(ID).length > 0){
exists = true;
}
return exists;
}
})
Hope this helps!
UPDATED! Sorry I overlooked that you wanted to disable the link, not on click. Here is a JsFiddle if you inspect the link with href="$find-someting-else" you'll see it has the class disabled whereas the other one does not.

I took Jeremiah's code and altered it slightly to do what I needed it to do. Thanks so much for all the answers- here was the final product:
function findID(ID) {
var exists = false;
if ($(ID).length > 0) {
exists = true;
}
return exists;
}
function matchLink() {
var href = $(this).attr('href');
if (!findID(href)) {
// Doesn't exist
$(this).addClass('alpha-disabled');
}
};
$('.scroller').each(matchLink);

You can do it like this. Here is an example:
function linkMatch(index, elem){
var link = elem,
heading = $(".alpha-heading");
var linkHref = link.attr("href").substring(1, link.attr("href").length);
if(typeof(heading[index]) != "undefined") {
if(linkHref != heading[index].getAttribute("id")) {
link.addClass("disabled");
}
}
}
$(".scroller").each(function(index) {
linkMatch(index, $(this));
});
Edit
I've just edited my code, because I forgot to write length inside linkHref variable

Related

How to make links added from JSON clickable?

I am trying to append links from a JSON file but their onClick is not working.
HTML:
<li class="nav-item dropdown" id = "views">
<a class="nav-link dropdown-toggle" id="view-type" data-toggle="dropdown" data-selected="high_level" aria-haspopup="true" aria-expanded="false">High Level View</a>
<div class="dropdown-menu" aria-labelledby="view-type" style="height: 35vh; overflow: auto;">
<h7 class="dropdown-header">View Type</h7>
<a class="dropdown-item filter-option active" href="javascript:void(0);" id="high_level">High Level View</a>
</div>
</li>
Javascript:
d3.json(theURL, function(error, data) {
if (error) throw error;
var unique = [];
data.forEach(function(e){
if(unique.indexOf(e.segment) == -1){
unique.push(e.segment);
}
});
unique.forEach(d =>
$('#views .dropdown-menu').append(`<a class="dropdown-item filter-option ecodes" href="javascript:void(0);" id="${d.substring(0, 4)}">${d}</a>`)
)
if($('#all').hasClass('active') == true) {
$('.ecodes').remove();
}
});
$('.filter-option').on('click', function() {
let text = $(this).text();
let selected = $(this).prop('id');
$(this).parent().parent().children('a').text(text);
$(this).parent().parent().children('a').data().selected = selected;
filters[$(this).parent().parent().children('a').prop('id').replace('-','_')] = selected;
$.each($(this).parent().children('a'), function(i,d)
$(d).removeClass('active'); });
$(this).addClass('active');
});
Is there something wrong with my code? I cant seem to figure out why my links aren't working. I need onClick for them to have the class active.
You should use the static element as a starter then delegating the dynamic node(child node) inside the on method
$('dropdown-menu').on('click','.filter-option', function() {
let text = $(this).text();
let selected = $(this).prop('id');
$(this).parent().parent().children('a').text(text);
$(this).parent().parent().children('a').data().selected = selected;
filters[$(this).parent().parent().children('a').prop('id').replace('-','_')] = selected;
$.each($(this).parent().children('a'), function(i,d)
$(d).removeClass('active'); });
$(this).addClass('active');
});
You have to delegate the click to the parent element that exists in the page before you inject new links.
jQuery's on method accepts a selector as the second argument so you can update the following line:
$('.dropdown-menu').on('click', '.filter-option', function() {
let text = $(this).text();
let selected = $(this).prop('id');
$(this).parent().parent().children('a').text(text);
$(this).parent().parent().children('a').data().selected = selected;
filters[$(this).parent().parent().children('a').prop('id').replace('-','_')] = selected;
$.each($(this).parent().children('a'), function(i,d)
$(d).removeClass('active'); });
$(this).addClass('active');
});
Read more: http://api.jquery.com/on/#direct-and-delegated-events

Using an active 'li' element to determine a video's source file

I tried creating a small video library where one div is split into two parts: 1) a menu on the left with the titles of the movies and 2) the rest of the div on the right being a video window that changes it's video source according to the selected title on the menu. I gave the li elements that housed the titles id's and used jQuery/JavaScript to retrieve the title and to assign a new video source based on that title, but it isn't working and I also can't claim to completely understand what I've done. The code is as follows:
HTML
<div class="miyazaki">
<div class="menu">
<ul>
<li><a id="Gulliver">Gulliver's Travels</a></li>
<li><a id="Howl">Howl's Moving Castle</a></li>
<li><a id="Kiki">Kiki's Delivery Service</a></li>
<li><a id="Castle">Castle of Cagoliostro</a></li>
<li><a id="Totoro">"My Neighbor Totoro</a></li>
<li><a id="Ponyo">Ponyo</a></li>
<li><a id="Mononoke">"Princess Mononoke</a></li>
<li><a id="Spirited">Spirited Away</a></li>
<li><a id="Sky">The Sky's Castle Laputa</a></li>
<li><a id="Nausicaa">Nausicaa Valley of the Wind</a></li>
<li><a id="Cat">"The Cat Returns</a></li>
</ul>
</div>
</div>
JavaScript
function Hayato() {
var movie = $("ul.menu li a.active");
if (movie.id == Gulliver || movie.id == null || movie.id == "") {
document.getElementsByClassName('window').video.source.src = Gulliver.mkv
}
else if (movie.id == Howl) {
document.getElementsByClassName('window').video.source.src = Howl.mkv
}
else if (movie.id == Kiki) {
document.getElementsByClassName('window').video.source.src = Kiki.mkv
}
else if (movie.id == Castle) {
document.getElementsByClassName('window').video.source.src = Castle.mkv
}
else if (movie.id == Totoro) {
document.getElementsByClassName('window').video.source.src = Totoro.mkv
}
else if (movie.id == Ponyo) {
document.getElementsByClassName('window').video.source.src = Ponyo.mkv
}
else if (movie.id == Mononoke) {
document.getElementsByClassName('window').video.source.src = Mononoke.mkv
}
else if (movie.id == Spirited) {
document.getElementsByClassName('window').video.source.src = Spirited.mkv
}
else if (movie.id == Sky) {
document.getElementsByClassName('window').video.source.src = Sky.mkv
}
else if (movie.id == Nausicaa) {
document.getElementsByClassName('window').video.source.src = Nausicaa.mkv
}
else (movie.id == Cat) {
document.getElementsByClassName('window').video.source.src = Cat.mkv
}
}
I'm not entirely sure this code is the best way to go about solving my problem, but it's the most logical progression I can think of.
This can all be condensed down considerably since most of the code stays the same in all cases. Also, your closing <ul> isn't a close tag and you are missing a closing <div>.
// Get all the <a> elements
var anchors = document.querySelectorAll(".menu a");
// Get a reference to the video element
var v = document.querySelector("video");
// Set up click event handlers for each
Array.prototype.slice.call(anchors).forEach(function(anchor){
anchor.addEventListener("click", function(evt){
// default video when no id is present
var d = "Gulliver.mkv";
// Use the default or the id
v.source = (!anchor.id) ? d : anchor.id + ".mkv";
console.log("video source is: " + v.source);
});
});
<div class="miyazaki">
<div class="menu">
<ul>
<li><a id="Gulliver">Gulliver's Travels</a></li>
<li><a id="Howl">Howl's Moving Castle</a></li>
<li><a id="Kiki">Kiki's Delivery Service</a></li>
<li><a id="Castle">Castle of Cagoliostro</a></li>
<li><a id="Totoro">"My Neighbor Totoro</a></li>
<li><a id="Ponyo">Ponyo</a></li>
<li><a>Porco Rosso</a></li>
<li><a id="Mononoke">"Princess Mononoke</a></li>
<li><a id="Spirited">Spirited Away</a></li>
<li><a id="Sky">The Sky's Castle Laputa</a></li>
<li><a id="Nausicaa">Nausicaa Valley of the Wind</a></li>
<li><a id="Cat">"The Cat Returns</a></li>
</ul>
</div>
</div>
<video></video>
As you also tagged jQuery here a working example for that:
$('.menu li a').on('click', function() {
var id = $(this).attr('id');
$('.window video source').attr('src', id + '.mkv');
});
Example
Note: Your html is invalid too. The ul is never closed
There's no need to use all these if blocks, you can do it in a one line statement.
You could just do it this way:
function Hayato() {
var movie = $("ul.menu li a.active").attr("id");
if(movie && movie !== "#")
document.getElementsByClassName('window')[0].video.source.src = movie + ".mkv";
}
Note:
In the code you used all the Strings are inavlid Strings, you should wrap them between two " or '.

jQuery target next() html item

hi I have a list of items which is generated like so:
<li class="panel-title">Item 1<i class="fa pull-right fa-plus"></i></li>
<ul class="panel-body">...</ul>
<li class="panel-title">Item 2<i class="fa pull-right fa-plus"></i></li>
<ul class="panel-body">...</ul>
<li class="panel-title">Item 3<i class="fa pull-right fa-plus"></i></li>
<ul class="panel-body">...</ul>
Upon clicking an 'li' item I need only the next 'ul' to expand. Unsure how to solve this & whether next() is the right action
Heres my code
$('li.panel-title > .fa').on("click",function() {
var $currIcon = $(this);
var $contents = $('ul.panel-body');
if($currIcon.hasClass('fa-plus')) {
$currIcon.$contents.next().slideDown();
$currIcon.removeClass('fa-plus');
$currIcon.addClass('fa-minus');
} else if($currIcon.hasClass('fa-minus')) {
$currIcon.$contents.next().slideUp();
$currIcon.removeClass('fa-minus');
$currIcon.addClass('fa-plus');
}
});
Try this
$('li.panel-title > .fa').on("click",function() {
var $currIcon = $(this);
var $contents = $('ul.panel-body');
if($currIcon.hasClass('fa-plus')) {
$currIcon.parent().next().slideDown();
$currIcon.removeClass('fa-plus');
$currIcon.addClass('fa-minus');
} else if($currIcon.hasClass('fa-minus')) {
$currIcon.parent().next().slideUp();
$currIcon.removeClass('fa-minus');
$currIcon.addClass('fa-plus');
}
});
Below is jQuery Code:
$('li.panel-title > .fa').on("click", function() {
var $currIcon = $(this);
var $contents = $($(this).closest('li').next().children('ul'));
if ($currIcon.hasClass('fa-plus')) {
$contents.slideDown();
$currIcon.removeClass('fa-plus');
$currIcon.addClass('fa-minus');
} else if ($currIcon.hasClass('fa-minus')) {
$contents.slideUp();
$currIcon.removeClass('fa-minus');
$currIcon.addClass('fa-plus');
}
});
I appended a codepen. I modified HTML markup a little bit, since ul is directly beneath its parent node ul.
http://codepen.io/wooljs/pen/pEgbkB

How to get which link has been clicked in jquery

Good day...
I have multiple links as below:
<li>Save</li>
<li>Save As</li>
<li>Save And Exit</li>
I wanna know which link has been clicked
I tried something like this:
if ($("#mmSaveForm").click() == "true") {
//do something
}
else if ($("mmSaveAs").click() == "true") {
//Do something
}
else if ($("#mmSaveExit").click() == "true") {
//Do something
}
I tried these links, questions & answers but they are not helping:
How can I get the button that caused the submit from the form submit event?
jQuery: how to get which button was clicked upon form submission?
how to detect which button is clicked using jQuery
jQuery - how to determine which link was clicked
I've been trying this the whole night, please help...
Thank you in advanced...
Why don't you target the class instead, grab the id and then use a switch statement.
$('.itemDisabled').on('click', function () {
var id = this.id;
switch(id) {
case 'mmSaveForm':
// code
break;
case 'mmSaveAs':
// code
break;
case 'mmSaveExit':
// code
break;
}
});
Try to use .is(selector) to identify the element which has been clicked,
$('a.noTxtSelect1').click(function(e){
e.preventDefault();
if($(this).is("#mmSaveForm")){
} else if($(this).is("#mmSaveAs")) {
} else if($(this).is("#mmSaveExit")) {
}
});
If your links have id attributes all starting with 'mm' you could use:
$('a[id^=mm]').on('click', function(){
console.log(this.id);
});
Or on one or more classes:
$('a.itemDisabled').on('click', function(){
-or-
$('a.itemDisabled.noTxtSelect1').on('click', function(){
In the click event, you can use switch to determine the link clicked, which you can fetch using this or $(this)
e.g.:
Demo Fiddle
$('a[id^=mm]').on('click', function () {
switch (this.id) {
case "mmSaveForm":
alert(this.id);
break;
case "mmSaveAs":
alert(this.id);
break;
case "mmSaveExit":
alert(this.id);
break;
}
});
You can use the [attr^="value"] ["starts with"] selector:
$('[id^="mmSave"]').click(function(event){
event.preventDefault();
var action = this.id;
// do your business
});
You're thinking about this the wrong way. In your
$(document).ready(function() {})
you register for click events. So something like
$(document).ready(function() {
$("#mmSaveForm").click(function() {
// handle the click
});
});
may be you can try this
$(function(){
$('.linkclass').click(function(){
var link_text = $(this).text();
alert('the clicked link text is '+ link_text);
});
});
Use common class like a itemDisabled for click event and get id ,
$(".itemDisabled").click(function (e) {
e.preventDefault();
var id = this.id;
if (id === "mmSaveForm") {
} else if (id === "mmSaveExit") {
} else {}
});
No need jquery please look this code
<!DOCTYPE html >
<html >
<head>
<script>
function clickbtn(t)
{
alert(t.id);
/*if(t.id==...)
{
dosomething();
}
else
{
dootherthing();
}
*/
}
</script>
</head>
<ul>
<li>Save</li>
<li>Save As</li>
<li>Save And Exit</li>
</ul>
<body>
</body>
</html>
It work ok .
Hope this help!
This is my html page (Django template):
<div class="col">
{% for blog in blogs %}
<div class="post">
<h3>{{ blog.title }}</h3>
<div class="date">
<p>Created: {{blog.date_created|date:'d M Y'}}</p>
</div>
<p>{{ blog.brief|safe }}</p>
<ul class="nav justify-content-end">
<li class="nav-item">
<a class="nav-link active" href="{% url 'blog:edit' pk=blog.pk %}">Edit</a>
</li>
<li class="nav-item">
<a class="nav-link" id="publish" href="{{blog.pk}}">Publish</a>
</li>
<li class="nav-item">
<a class="btn btn-danger" id="remove" href="{{blog.pk}}">Remove</a>
</li>
</ul>
<br>
</div>
{% endfor %}
</div>
In my javascript file, this is what have and it works.
$(document).ready(function() {
console.log("document is ready!!!")
$('#id_bloglist').on("click", 'a#publish,a#remove', function(e) {
e.preventDefault()
var pk = $(this).attr("href")
if ($(this)[0].id == 'remove'){
console.log("remove link clicked, calling deleteBlog with pk = " + pk)
}
else if ($(this)[0].id == 'publish'){
console.log("publish link clicked, calling publishBlog with pk = " + pk)
}
return false;
});
});

push replaces the old value in the array

Maybe its because I have been working all day and I can't see the problem. But in the following code the alert only shows the last added value and doesn't push the value in the array. :(
window.sortControl = {
sortControlPanel: $('div.sortControl'),
simpleSortCriteriaList: $('div.sortControl .simple'),
advancedSortCriteriaList: $('div.sortControl .advanced'),
dropDownExpander: $('div.sortControl .dropDownExpand.primary'),
dropDownContent: $('div.sortControl .dropdownContent.primary'),
simpleSortCriteria: $('div.sortControl .sortcriteria.simple a'),
simpleSortCheckboxes: $('.simple .checkbox'),
openAdvancedButton: $('.openAdvanced'),
backtoSimpleButton: $('.backtoSimple'),
advancedDropdownContent: $('div.sortControl .advanced .dropdownContent'),
advancedDropdownExpander: $('div.sortControl .advanced .dropDownExpand')
};
$.each(sortControl.advancedDropdownContent.parent(), function () {
var dropdownContent = $(this).find('.dropdownContent');
var input = $(this).find('input');
$(this).find('.dropDownExpand').live('click', function (event) {
sortControl.advancedDropdownContent.not(dropdownContent).hide('fast');
dropdownContent.toggle('fast');
event.preventDefault();
});
var currentSelectedGroups = [];
$(this).find('li a').bind('click', function (event) {
var criteria = $(this).text();
//if (!currentSelectedGroups.inArray($(this).attr('class'), true)) {
input.attr('value', criteria);
currentSelectedGroups.push($(this).attr('class'));
//}
dropdownContent.toggle('fast');
event.preventDefault();
alert(currentSelectedGroups);
});
});
Some of the html:
<div class='sortcriteria advanced'>
<label>Sort by: </label>
<div class='controlWrapper'>
<input type="text" placeholder='Any' value='Any' class='dropDownExpand'>
<span class='icon dropDownExpand' title='Select property type'></span>
<ul class='dropdownContent'>
<li><a href='#' class='price'>Price ascending</a></li>
<li><a href='#' class='price'>Price descending</a></li>
<li><a href='#' class='party'>Party size ascending</a></li>
<li><a href='#' class='party'>Party size descending</a></li>
<li><a href='#' class='bedrooms'>Number of bedrooms ascending</a></li>
<li><a href='#' class='bedrooms'>Number of bedrooms descending</a></li>
<li><a href='#' class='star'>Star rating ascending</a></li>
<li><a href='#' class='star'>Star rating descending</a></li>
</ul>
</div> ...
There are no JavaScript errors.
Content and this script get loaded via ajax
All other statements do what they are supposed to
You need to move var currentSelectedGroups = []; outside the each loop. You declare it once for every instance - they all work on their own version of the variable because it lives in the local scope of the each function.
Remember in javascript functions = scope
As I asked you (and suspected) in my earlier comment, you need to move:
var currentSelectedGroups = [];
outside the .each() loop. As it is you are re-initializing it to an empty array in each iteration of the loop so it never has more than one value in it. You can do that like this:
var currentSelectedGroups = [];
$.each(sortControl.advancedDropdownContent.parent(), function () {
var dropdownContent = $(this).find('.dropdownContent');
var input = $(this).find('input');
$(this).find('.dropDownExpand').live('click', function (event) {
sortControl.advancedDropdownContent.not(dropdownContent).hide('fast');
dropdownContent.toggle('fast');
event.preventDefault();
});
$(this).find('li a').bind('click', function (event) {
var criteria = $(this).text();
//if (!currentSelectedGroups.inArray($(this).attr('class'), true)) {
input.attr('value', criteria);
currentSelectedGroups.push($(this).attr('class'));
//}
dropdownContent.toggle('fast');
event.preventDefault();
alert(currentSelectedGroups);
});
});

Categories