Showing selected item - javascript

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');
}

Related

Get href attribute on click event with Javascript and Framework7

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

Dropdown menu flashes and disappeared on mobile only

I have a sub-menu inside the navbar under the Services nav-item.
The expected behavior is once the Service is clicked, the sub-menu shows up. The actual behavior is: once the Service is clicked, the sub-menu flashes and disappears.
<nav id="main-menu">
<ul class="sf-navbar">
<li>
<a href="#home">
<div data-i18n="nav.home">Home</div>
</a>
</li>
<li>
<a href="#">
<div data-i18n="nav.services.title">Title</div>
</a>
<ul>
<li>
<a href="#service">
<div data-i18n="nav.services.ourservices">Our Services</div>
</a>
</li>
<li>
<a href="#how">
<div data-i18n="nav.services.howwework">How We Work</div>
</a>
</li>
<li>
<a href="#areascontainer">
<div data-i18n="servicearea.title">Service Area</div>
</a>
</li>
<li>
<a href="#why">
<div data-i18n="why.title">Why Choose Us</div>
</a>
</li>
</ul>
</li>
.....
</nav>
JS code:
wei.header = {
init: function(){
wei.header.superfish();
},
superfish: function() {
$( main_menu ).superfish({
popUpSelector : 'ul',
delay : 250,
speed : 350
});
},
...
I have tried to debug it, but have no clue where to start.
Here is the code that I am working on.
http://weistudio.com.au/
For some reason, SuperFish fails here on touchEnd event and only for the menu shown when you at the very top of the page (it works if you scroll page a bit - there is a clone of this menu).
To prevent it you could use something like <a href="#" onTouchEnd="(function (e) {e.preventDefault()})(event)">.
Or move it to an external method and use like this (as you using jQuery already):
$('.header-container').on('touchend', '.sf-with-ul', function (e) {e.preventDefault()})

How should I populate nested elements using jquery?

I want to display NEWS headines on my website. I want to populate it using Jquery. I have written the code but nothing is displayed on webpage.
HTML code:
<div class="col-md-4">
<div id="sidebar-wrapper">
<ul class="sidebar-nav">
<strong>Latest Headines</strong>
<li>
<a href="" class="title">
<h2> </h2>
</a>
</li>
<li>
<a href="" class="title">
<h2> </h2>
</a>
</li>
<li>
<a href="" class="title">
<h2> </h2>
</a>
</li>
<li>
<a href="" class="title">
<h2> </h2>
</a>
</li>
<li>
<a href="" class="title">
<h2> </h2>
</a>
</li>
</ul>
</div>
</div>
JS code:
$(document).ready(function() {
$.getJSON('https://newsapi.org/v1/articles?source=techcrunch&sortBy=top&apiKey=my-api-key',function(json) {
console.log(json);
console.log(json.articles.length);
function headlines (json) {
for(var i=0;i<5;i++){
$('.sidebar-nav li a h2').eq(i).html(json.articles[i].title);
}
}
});
});
I have made a class called sidebar then inside class I have placed list and anchor followed by <h2></h2> tag. I want to populate h2 tag with NEWS headlines but nothing is displayed on my webpage.
$('.sidebar-nav li').eq(i).find('h2').html(...)
li is the Nth element you're looking for, not h2.
For that matter, you should cache the nav element or the lis, to avoid hammering the DOM :
var $lis = $('.sidebar-nav li')
for(var i=0;i<5;i++){
$lis[i].find('h2').html(json.articles[i].title);
}
First of all: You don't call your function headlines so nothing goes to output ;)
Second one:
$('.sidebar-nav li a h2').eq(i)
will only work for the first item i think, because there is only 1 H2-Tag within the a-Tag.
I suggest giving all H"-Tag a class like ".headline" and itterating over them.
I hope this helps ;)

How do I hijack just one specific link within an LI and not ALL links?

I have a menu that in each li, it will have multiple <a> tags. The main one being the name of the item. When that one is clicked, I want a Dropdown event to happen. But on the items within the <li> I want those clicks to function normally.
My HTML looks like this:
<li class="tree-item-name">Aunts & Uncles
<span class = "bootstrap-styles">
<ul>
<li>
<img alt="Default" class="img-circle" height="48" src="/assets/default.jpg" width="48" />
Jackie Lynn <a data-confirm="Are you sure?" data-method="delete" href="/family_trees/3" rel="nofollow"><i class="fa fa-thumbs-o-down"></i></a>
</li>
</ul>
</span>
</li>
The JS looks like this:
jQuery(document).ready(function(){
jQuery('LI.tree-item-name').click(function(){
if (jQuery(this).hasClass('opened')) {
jQuery(this).find('UL').slideUp();
jQuery(this).removeClass('opened');
} else {
jQuery(this).find('UL').slideDown();
jQuery(this).addClass('opened');
}
return false;
});
});
But right now, when you click on either the img tag or Jackie Lynn....neither work - because both are being hijacked by the JS.
How do I set this up so only li.tree-item-name is affected?
You need to stop event propagation and target only lis which has a ul inside it
jQuery(function($) {
$('LI.tree-item-name').has('ul').click(function() {
if ($(this).hasClass('opened')) {
$(this).find('UL').slideUp();
$(this).removeClass('opened');
} else {
$(this).find('UL').slideDown();
$(this).addClass('opened');
}
return false;
});
$('LI.tree-item-name li').click(function(e) {
e.stopPropagation();
})
});
.tree-item-name ul {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<ul>
<li class="tree-item-name">
Aunts & Uncles
<span class="bootstrap-styles">
<ul>
<li>
<img alt="Default" class="img-circle" height="48" src="/assets/default.jpg" width="48" />
Jackie Lynn <a data-confirm="Are you sure?" data-method="delete" href="/family_trees/3" rel="nofollow"><i class="fa fa-thumbs-o-down"></i></a>
</li>
</ul>
</span>
</li>
</ul>
Give your a tag (Aunts & Uncles) a class, and use that class as the jQuery click event trigger.
jsFiddle Demo
<li class="tree-item-name"><a class="rels" href="#">Aunts & Uncles</a>
<span class = "bootstrap-styles">
<ul>
<li>
<img alt="Default" class="img-circle" height="48" src="http://placekitten.com/g/48/48" width="48" />
Jackie Lynn <a data-confirm="Are you sure?" data-method="delete" href="/family_trees/3" rel="nofollow"><i class="fa fa-thumbs-o-down"></i></a>
</li>
</ul>
</span>
</li>
jQuery('.rels').click(function(){
if (jQuery(this).parent().hasClass('opened')) {
jQuery(this).parent().find('UL').slideUp();
jQuery(this).parent().removeClass('opened');
} else {
jQuery(this).parent().find('UL').slideDown();
jQuery(this).parent().addClass('opened');
}
return false;
});
That's because you are using (this) which takes care of the link you click on but then select the entire unordered list.
You need to put the url's on separate list item for it to work the way you have it.

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