Get href attribute on click event with Javascript and Framework7 - javascript

I'm struggling with a very simple problem that I can't solve.
I'm using Framework7 (JS Framework for mobile application) and I have two list in my page:
First list:
<ul>
<li>
<a id="android" class="link external" target="_blank" href="android_link"></a>
</li>
<li>
<a id="iOS" class="link external" target="_blank" href="ios_link"></a>
</li>
<li>
<a id="windows" class="link external" target="_blank" href="windows_link"></a>
</li>
</ul>
Second list:
<ul>
<li>
<a href="fb_link" target="_blank" class="item-link item-content link external" id="facebook">
<div class="item-media">
<i class="f7-icons">logo_facebook</i>
</div>
<div class="item-inner">
<div class="item-title">Facebook</div>
</div>
</a>
</li>
<li>
<a href=instagram_link" target="_blank" class="item-link item-content link external" id="instagram">
<div class="item-media">
<i class="f7-icons">logo_instagram</i>
</div>
<div class="item-inner">
<div class="item-title">Instagram</div>
</div>
</a>
</li>
</ul>
So, I need to take the href attribute on click event. I wrote this:
Dom7('.link.external').on('click', (event) => {
// First try
href = event.target.getAttribute('href')
console.log(href)
// Second trye
console.log(event.srcElement.href)
// Third try
var href = Dom7('a.link.external').attr('href');
var id = Dom7('a.link.external').attr('id');
console.log(href)
console.log(id)
})
I've tried three different solutions, but none of them work.
The first one and second one works only for the first list, I think because the <a> tag doesn't contains html inside.
The third one always return me the href and id of the first elements of the first list (android), even if I click in the second list.
Can you help me to solve this problem?

Solution 1
<ul>
<li>
<a id="android" class="link external" target="_blank" href="android_link" onclick="linkClicked(this); return false;"></a>
</li>
</ul>
<script>
function linkClicked(object) {
consile.log(object.getAttribute("href"));
return false;
}
</script>
Solution 2
var elements = document.getElementsByClassName('link');
for (var i = 0; i < elements.length; i++) {
elements[i].addEventListener('click', linkClicked, false);
}
function linkClicked() {
console.log(this.getAttribute("href"));
};

if you can use jquery, use this working code :
$('.link.external').on('click', (event) => {
href = event.target.getAttribute('href');
alert(href);
});
jsfiddle

Related

how do I prevent anchor tag from redirecting in javascript when a validation fails

I have HTML with 5 tabs with form fields and button at the bottoms to navigate to next tab. I want to prevent tab switching if validation fails on the click of Next button. Presently when validation fails tab switches to next tab. I have tried both event.preventDefault() and return false individually and combined but none of these worked in chrome browser. Any suggestions would be helpful.
<div class="row">
<ul class="nav nav-pills">
<li class="active" id="libdet">
<a data-toggle="tab" href="#bdetails">1. Service Basic details</a>
</li>
<li>
<a data-toggle="tab" href="#soptions">2. Service Options</a>
</li>
<li>
<a data-toggle="tab" href="#addInfor">3. Service Add. info</a>
</li>
<li>
<a data-toggle="tab" href="#addImgs">4. Images</a>
</li>
<li>
<a data-toggle="tab" href="#tandc">5. Terms & Conditions</a
</li>
</ul>
</div>
<div class="col-xs-4">
<a data-toggle="tab" href="#soptions">
<button name="next" id="nextSB" onclick="validatefirsttab()">NEXT</button>
</a>
</div>
function validatefirsttab() {
if (document.form.productTitle.value == "") {
alert("Please provide Service title!");
document.form.productTitle.focus();
event.preventDefault();
return false;
}
You can use click function directly in jQuery. Your button have an ID that you can use, so:
$("#nextSB").click(function(e){
if (document.form.productTitle.value == "") {
alert("Please provide Service title!");
document.form.productTitle.focus();
e.preventDefault();
return false;
}
}
Then your button will be:
<button name="next" id="nextSB">NEXT</button>
In my opinion, this solution is cleaner than use onclick attribute.
Are you using Bootstrap.js? It is likely that another jQuery listener is triggering the tabs to change.
If this is the case, you'd want to remove the <a data-toggle="tab" href="#soptions"> (which is triggering the tab switch) and create a new jQuery listener for your 'Next' button. You'd place your validatefirsttab() function inside of the bootstrap tab function:
<div class="row">
<ul class="nav nav-pills">
<li class="active" id="libdet">
<a data-toggle="tab" href="#bdetails">1. Service Basic details</a>
</li>
<li>
<a data-toggle="tab" href="#soptions">2. Service Options</a>
</li>
<li>
<a data-toggle="tab" href="#addInfor">3. Service Add. info</a>
</li>
<li>
<a data-toggle="tab" href="#addImgs">4. Images</a>
</li>
<li>
<a data-toggle="tab" href="#tandc">5. Terms & Conditions</a
</li>
</ul>
</div>
<div class="col-xs-4">
<button name="next" id="nextSB">NEXT</button>
</div>
<script>
$('#nextSB').on('click',function() {
if (document.form.productTitle.value == "") {
alert("Please provide Service title!");
} else {
$('a[href="#soptions"]').tab('show') // Select tab by name
}
})
</script>
Not tested, and again I'm assuming you're using bootstrap.js togglable tabs
Hash tag links (href="#foo") won't trigger a page refresh, so e.preventDefault and the like aren't useful here. It is common practice to use hash tag links with jQuery or javascript for precisely that reason.
Thank you Guys! I found an answer.
Here is the modified code:
Added event as parameter on function.
And 1 more call to event.stopImmediatePropagation();
Javascript:
function validatefirsttab(event)
{
if( document.form.productTitle.value == "" )
{
alert( "Please provide Service title!" );
document.form.productTitle.focus() ;
event.preventDefault();
event.stopImmediatePropagation(); // Added now
}
}
HTML:
<a data-toggle="tab" href="#soptions">
<button name="next" id="nextSB" onclick="return validatefirsttab(event);" >NEXT
</button>
</a>

Need an element's parent index using jquery or javascript

I have three <ul>s that expand when their buttons are clicked. Not all three <ul>s will show up - only when there is a notification to show. I hard-coded the values for now, but I can instantiate them on an as-needed basis.
Right now, they cover each other when they expand. I would like the others to move when a list is expanded so they don't cover each other. I was thinking of getting the index of the one whose button is clicked and then resetting the bottom style of the others. I need to get the index of the <ul> parent of the button that was clicked, probably using jQuery but straight JavaScript is fine as well. Can anyone help?
Here is my code:
<div id="NotificationDiv">
<ul id="noticeLead" class="notification_base notification_Lead"><button id="notification_button">Lead Notice</button>
<div>
<li id="urlLead" class="notification_urlNotice notification_notice">
<a target="_blank" >Check Lead #1</a>
</li>
<li id="urlLead" class="notification_urlNotice notification_notice">
<a target="_blank" >Check Lead #2</a>
</li>
</div>
</ul>
<ul id="noticeTask" class="notification_base notification_Task"><button id="notification_button">Task Notice</button>
<div>
<li id="urlTask" class="notification_urlNotice notification_notice">
<a target="_blank" >Check Task #5</a>
</li>
<li id="urlTask" class="notification_urlNotice notification_notice">
<a target="_blank" >Check Task #6</a>
</li>
<div>
</ul>
<ul id="noticePolicy" class="notification_base notification_Policy"><button id="notification_button">Policy Notice</button>
<div>
<li id="urlPolicy" class="notification_urlNotice notification_notice">
<a target="_blank" >Check Policy #3</a>
</li>
<li id="urlPolicy" class="notification_urlNotice notification_notice">
<a target="_blank" >Check Policy #4</a>
</li>
</div>
</ul>
</div>
And in the $(document).ready, I have:
$('.notification_base').on('click', 'button', function(){
$(this).closest('.notification_base').find('.notification_urlNotice').slideToggle();
});
Try this:
var myParentId; //Here you'll store the id of the clicked element
$('.notification_base').on('click', 'button', function(){
$(this).closest('.notification_base').find('.notification_urlNotice').slideToggle();
myParentId = $(this).attr("id");
});
Thank you everyone for your input. I changed my structure to a table assigning .parent class to the header row and .child class to the data row and put this code in the jQuery ready function and it works great.
function getChildren($row) {
var children = [];
while($row.next().hasClass('child')) {
children.push($row.next());
$row = $row.next();
}
return children;
}
$('.parent').on('click', function() {
var children = getChildren($(this));
$.each(children, function() {
$(this).toggle();
})
});

Showing selected item

I am trying to learn web development and I wrote a simple HTML code like
<div class="r" id="header-status">
<a href="#" class="trigger" style="display: block; padding: 10px;">
<span>
<img src="{{STATIC_URL}}img/online.png">
</span>
ONLINE
<span class="icon-down-dir">
</span>
</a>
<ul class="dd-menu">
<li>
<span><img src="{{STATIC_URL}}img/away.png"></span> AWAY
</li>
<li>
<a href="#">
<span>
<img src="{{STATIC_URL}}img/offline.png">
</span> OFFLINE
</a>
</li>
</ul>
</div>
Now I am trying to write a javascript code that I use Backbone to get what I select in the dropdown list. I mean when I clicked "away", I want to write "away" in the dropdown list.
The simplest solution would be to create a listener for click event. It can be done like this:
Your view:
// ...
View1.prototype.events = {
"click .item": "menuClick"
};
View1.prototype.menuClick = function() {
Backbone.trigger('menuItemSelected');
};
And a consumer on the click event (another view):
View2.prototype.initialize = function() {
this.listenTo(Backbone, 'menuItemSelected', this.selectMenuItem);
};
View2.prototype.selectMenuItem = function() {
console.log('item selected');
}

How to add a submenu after X number of <li> with Javascript or Jquery?

I have in HTML
<div class="ktmsg">
<ul>
<li class="a1">
<a title="Link Tools" href="#"> … </a>
</li>
<li class="a2">
<a title="Link Tools" href="#"> … </a>
</li>
<li class="a3">
<a title="Link Tools" href="#"> … </a>
</li>
</ul>
</div>
What i want to do is to add after the second </li> an <ul>More</ul>
Final expected output should be
<div class="ktmsg">
<ul>
<li class="a1">
<a title="Link Tools" href="#"> … </a>
</li>
<li class="a2">
<a title="Link Tools" href="#"> … </a>
</li>
<ul> //Starting the sub-menu
More // The link that after i hover it will start showing the <li> starting from the third one
<li class="a3">
<a title="Link Tools" href="#"> … </a>
</li>
</ul>
</ul>
</div>
I am thinking that the javascript would look smth like this:
limenu = document.selectAll(.ktmsg)('<li>');
for(var i=1, i<2, i++)
remove.limenu
add.
.... And i am quite stuck, Please help, would be much appreciated.
Using jQuery
jQuery(function ($) {
var $lis = $('.ktmsg > ul > li');
var $a = $('<li>More</li>').insertAfter($lis.eq(1));
var $lefts = $lis.slice(2).hide();
$a.hover(function () {
clearTimeout($a.data('hoverTimer'));
$lefts.show();
}, function () {
var timer = setTimeout(function () {
$lefts.hide();
}, 200);
$a.data('hoverTimer', timer);
});
$lefts.hover(function () {
clearTimeout($a.data('hoverTimer'));
}, function () {
var timer = setTimeout(function () {
$lefts.hide();
}, 200);
$a.data('hoverTimer', timer);
});
})
Demo: Fiddle
With jQuery to add this:
<ul>More</ul>
after second li you need:
$( 'li:eq(1)' ).after( '<ul>More</ul>' );
I've created a fiddle of how this could work using jQuery. Pretty simple really, you just hide the sub menu using CSS and then show/hide it as needed using jQuery when "More" is being hovered over. I've used fadeIn() and fadeOut() but you could just as easily use hide() and show() if you don't need the animations. I've restructured your HTML slightly so if you use my solution use my new HTML.

duplicate functions, how may I combine them?

I have a function that remains pretty much constant except for the changing class names. I was hoping to make the code a little less text heavy. How may I go about making it just a small function instead of repeating it n times. My concern is also about removing the active class for the last li that was clicked. I've provided only 2 instances here, but this code is repeated n number of times.Any ideas would be much appreciated.
$('a.app1-preview').click(function() {
//remove last active classes
$(".app2").removeClass('active');
$(".app2-preview").removeClass('active');
//Add active class for this
$(this).parent().addClass('active');
$(this).addClass('active');
$('.app-preview-2').fadeOut("slow", function () {
$('.app-preview-1').fadeIn("slow");
});
});
$('a.app2-preview').click(function() {
//remove last active classes
$(".app1").removeClass('active');
$(".app1-preview").removeClass('active');
//Add active class for this
$(this).parent().addClass('active');
$(this).addClass('active');
$('.app-preview-1').fadeOut("slow", function () {
$('.app-preview-2').fadeIn("slow");
});
});
HTML code:
<div class="app-container">
<ul class="apps">
<li class="app1">
<a title href="#" class="app1-preview blocklink">
<span>ANOTHER<br /> APP</span>
</a>
</li>
<li class="app2">
<a title href="#" class="app2-preview blocklink">
<span>SECOND<br /> APP</span>
</a>
</li>
</div>
Try to exploit the fact that you have .active class. ;) Preview - http://jsfiddle.net/evSqF/1/
js:
<script>
$('a.blocklink').click(function() {
var self = $(this);
$('.active').fadeOut('slow', function(){
$(this).removeClass('active');
self.fadeIn('slow');
self.addClass('active');
});
});
</script>
html:
<div class="app-container">
<ul class="apps">
<li class="app1">
<a title href="#" class="app1-preview blocklink">
<span>ANOTHER<br /> APP</span>
</a>
<div class="app-preview active">App1 preview</div>
</li>
<li class="app2">
<a title href="#" class="app2-preview blocklink">
<span>SECOND<br /> APP</span>
</a>
<div class="app-preview">App2 preview</div>
</li>
</ul>
</div>
Edit: After I got some caffeine, I noticed the problems with the setup. I've created a demo at JSFiddle. The markup will display a "header" for an app which will display the child description when clicked on, and hide the descriptions of other sibling's descriptions.
In this case, you can show the current element, and hide the siblings, which would be a cleaner solution as it scales as you at more app elements.
$(".app").click(function() {
var $self = $(this);
var $apps = $self.closest(".apps");
var $selfSiblings = $apps.children(".app").not($self);
$self.addClass(".active");
$self.find(".app-preview").addClass("active");
$selfSiblings.removeClass(".active");
$selfSiblings.find(".app-preview").removeClass("active").fadeOut("slow", function() {
$self.find(".app-preview").fadeIn("slow");
});
});​
I would also recommend rewriting your HTML as such:
<div class="app-container">
<ul class="apps">
<li class="app">
App 1<br />
<a title href="#" class="app-preview blocklink">
<span>PREVIEW 1</span>
</a>
</li>
<li class="app">
App 2<br />
<a title href="#" class="app-preview blocklink">
<span>PREVIEW 2</span>
</a>
</li>
<li class="app">
App 3<br />
<a title href="#" class="app-preview blocklink">
<span>PREVIEW 3</span>
</a>
</li>
</div>​
Write a function to make the functions for you:
function makeHandler(deactivate, fadeOut, fadeIn) {
return function() {
//remove last active classes
$(deactivate).removeClass('active');
//Add active class for this
$(this).parent().addClass('active');
$(this).addClass('active');
$(fadeOut).fadeOut("slow", function () {
$(fadeIn).fadeIn("slow");
});
});
Then:
$('a.app1-preview').click(makeHandler('.app2, .app2-preview', '.app-preview-2', '.app-preview-1'));
$('a.app2-preview').click(makeHandler('.app1, .app1-preview', '.app-preview-1', '.app-preview-2'));
You could probably simplify things further by re-thinking the naming conventions you've got.
I would suggest to define a single function:
function single(index_main, index_aux) {
// Does all your magic
}
$('a.app1-preview').click(function() {
single("1", "2");
});
$('a.app2-preview').click(function() {
single("2", "1");
});
And that does the trick.
I made a jsfiddle example for you. Have a look at it here, it uses as much code that you wrote as possible, so nothing that should surprise you will be there :)
http://jsfiddle.net/2ZPxx/
Basically I ended up with this HTML:
<div class="app-container">
<ul class="apps">
<li class="app1">
<a title href="#" class="app1-preview blocklink" id="app1">
<span>ANOTHER<br /> APP</span>
</a>
</li>
<li class="app2">
<a title href="#" class="app2-preview blocklink" id="app2">
<span>SECOND<br /> APP</span>
</a>
</li>
</div>
<div class="app-preview-app1 app-preview">App1 preview</div>
<div class="app-preview-app2 app-preview">App2 preview</div>
And this javascript:
$('.apps li a').click(function() {
var id = $(this).attr('id');
$('.apps li').removeClass('active');
//Add active class for this
$(this).parent().addClass('active');
$(this).addClass('active');
$('.app-preview').fadeOut("slow", function () {
$('.app-preview-'+id).fadeIn("slow");
});
});

Categories