Getting Twitter Bootstrap's "Tabs" Javascript to Work on Rails App - javascript

A javascript problem on a rails app.
Twitter docs keep things very straightforward, however I'm still unable to get tabs to work dynamically (tab switching and dropdown). I straight up copied their source code and downloaded their javascript and included that in my application.js file on my rails app. Not sure what I'm missing.
The HTML file:
<script>
$(function () {
$('#.tabs').bind('change', function (e) {
e.target // activated tab
e.relatedTarget // previous tab
})
</script>
<h3>Demo</h3>
<ul class="tabs" data-tabs="tabs">
<li class="active">Home</li>
<li>Profile</li>
<li>Messages</li>
<li>Settings</li>
<li class="dropdown" data-dropdown="dropdown">
Dropdown
<ul class="dropdown-menu">
<li>#fat</li>
<li>#mdo</li>
</ul>
</li>
</ul>
<div id="my-tab-content" class="tab-content">
<div class="active tab-pane" id="home">
<p>Lorem Ipsum.</p>
The Application.js file:
// Place your application-specific JavaScript functions and classes here
// This file is automatically included by javascript_include_tag :defaults
$(document).ready(function(){
!function( $ ){
"use strict"
function activate ( element, container ) {
container
.find('> .active')
.removeClass('active')
.find('> .dropdown-menu > .active')
.removeClass('active')
element.addClass('active')
if ( element.parent('.dropdown-menu') ) {
element.closest('li.dropdown').addClass('active')
}
}
function tab( e ) {
var $this = $(this)
, $ul = $this.closest('ul:not(.dropdown-menu)')
, href = $this.attr('href')
, previous
, $href
if ( /^#\w+/.test(href) ) {
e.preventDefault()
if ( $this.parent('li').hasClass('active') ) {
return
}
previous = $ul.find('.active a').last()[0]
$href = $(href)
activate($this.parent('li'), $ul)
activate($href, $href.parent())
$this.trigger({
type: 'change'
, relatedTarget: previous
})
}
}
/* TABS/PILLS PLUGIN DEFINITION
* ============================ */
$.fn.tabs = $.fn.pills = function ( selector ) {
return this.each(function () {
$(this).delegate(selector || '.tabs li > a, .pills > li > a', 'click', tab)
})
}
$(document).ready(function () {
$('body').tabs('ul[data-tabs] li > a, ul[data-pills] > li > a')
})
}( window.jQuery || window.ender );
});

you don't need the first script (it's included in the documentation as an example only, in case you want more than what comes in the box)
what you do need is a link to the bootstrap stylesheet:
<link rel="stylesheet" href="your_bootstrap_folder/bootstrap.min.css">
and two scripts (assuming you have jquery otherwise include that first):
<script type="text/javascript" src="your_bootstrap_folder/js/bootstrap-tabs.js"></script>
<script type="text/javascript" src="your_bootstrap_folder/js/bootstrap-dropdown.js"></script>
and finally the function call
<script>
$(function () {
$('.tabs').tabs()
})
</script>
that should do the trick.
EDIT: just to make sure you've got the sequence right, here's a full example:
<!DOCTYPE html>
<html>
<head>
<title>bootstrap tabs test</title>
<link rel="stylesheet" href="path_to_bootstrap/bootstrap.min.css">
</head>
<body>
<ul class="tabs">
<li class="active">Home</li>
<li>Profile</li>
<li>Messages</li>
<li>Settings</li>
<li>Contact</li>
<li data-dropdown="dropdown" class="dropdown">
<a class="dropdown-toggle" href="#">Dropdown</a>
<ul class="dropdown-menu">
<li>Secondary link</li>
<li>Something else here</li>
<li class="divider"></li>
<li>Another link</li>
</ul>
</li>
</ul>
<script type="text/javascript" src="path_to_jquery/jquery-1.6.1.min.js"></script>
<script type="text/javascript" src="path_to_bootstrap/js/bootstrap-tabs.js"></script>
<script type="text/javascript" src="path_to_bootstrap/js/bootstrap-dropdown.js"></script>
<script>
$(function () {
$('.tabs').tabs()
})
</script>
</body>
</html>

I fired up the javascript console on Chrome and realized that my scripts weren't being loaded. This is because on rails, you don't need to include the "public" file in your path to load the javascript; only is needed.
In addition, in the application.hmtl.erb file, <%= javascript_include_tag 'bootstrap-dropdown.js' %> must be included as :default does not load these js files.

Related

How to make angular load jquery inside ng-include?

I am trying to apply some jquery in my code, but it's not working because i am using with ng-include, how can i solve this?
html:
<html lang="" ng-app="">
<head></head>
<body>
<div class="menu">
<nav class="sidebar">
<nav class="sidebar">
<div ng-include="'app/client.html'"></div>
</nav>
</nav>
</div>
<script type="text/javascript">
$(function() {
$( "ul.sidebar-nav li:eq(1)" ).addClass('tech');
});
</script>
</body>
</html>
client.html
<div class="client">
<div class="client-open">
<ul class="sidebar-nav">
<li>link1</li>
<li>link</li>
</ul>
</div>
</div>
js:
$(function() {
$( "ul.sidebar-nav li:eq(1)" ).addClass('tech');
});
Code to alter the DOM directly should go into directive.
Create a directive and attach it to the element you are trying to modify.
Plunkr - https://plnkr.co/edit/AIRb3egGSMkWfd2gpekL?p=preview
index.html
<!DOCTYPE html>
<html ng-app="app">
<head>
<script data-require="angular.js#1.5.8" data-semver="1.5.8" src="https://code.angularjs.org/1.5.8/angular.js"></script>
<script data-require="jquery#3.0.0" data-semver="3.0.0" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.js"></script>
<script>
angular.module('app', [])
.directive('attachJquery', function() {
return {
restrict: 'A',
link: function (scope, element) {
$( "ul.sidebar-nav li:eq(1)" ).addClass('tech');
}
};
})
</script>
<style>
.tech {
color: red;
}
</style>
</head>
<body>
<div class="menu">
<nav class="sidebar">
<nav class="sidebar">
<div ng-include="'client.html'"></div>
</nav>
</nav>
</div>
</body>
</html>
client.html
<div class="client" attach-jquery>
<div class="client-open">
<ul class="sidebar-nav">
<li>link1</li>
<li>link</li>
</ul>
</div>
</div>
First proposed solution
Make sure that Jquery is loaded in your application before AngularJs.
Move the script inside client.html
Second proposed solution
Make sure that Jquery is loaded in your application before AngularJs.
Move your script into the controller as in the following example
app.controller("myCtrl", function($scope, $rootScope,$timeout) {
$scope.firstName = "John";
$scope.lastName = "Doe";
$rootScope.$on('$includeContentLoaded', function() {
$timeout(function(){
load();
});
});
});
And then enter your function as in the following example
var load = function() {
$( "ul.sidebar-nav li:eq(1)" ).addClass('tech');
}
You can refer to this SO question for more info.
Angular: ng-include, jQuery not working unless in HTML file
One way of solving this is by creating a custom directive and adding it to div.client , then you can add your jquery code in the compile or link function of that directive.
HTML
<div class="client" load-evt>
...
</div>
Angular Directive
app.directive("loadEvt", function(){
return {
restrict: "A",
compile: function(elem){
//write your code in compile phase
},
link: function(elem, scope){
//or write your code in link phase
}
}
})
Why would you want to use jQuery and angular together?
These are 2 libraries that help you write a webapp, but go about it a VERY different way.
If you need jQuery to modify classes, you should simply use ng-class, as #fissio suggested. But in the usecase you provided, just add class="tech" to the second li. (I presume this isn't really what you wanted to know)
<div class="client">
<div class="client-open">
<ul class="sidebar-nav">
<li>link 1</li>
<li class="tech">link 2</li>
</ul>
</div>
</div>

Trying to load html pages onto page

Once an li is clicked I want to load a separate html page with content on the main index page.
HTML
<nav>
<ul>
<li>Planet 1</li>
<li>Planet 2</li>
<li>Planet 3</li>
<li>Planet 4</li>
</ul>
</nav>
So once one of the links is clicked I want the jquery to load the content on the same page.
$(document).ready(function(){
// load("location-to-your-file", function(){})
//var indexCatch = $('ul li').click(function(){ alert($(this).index()); });
$("li").click(function(){
$("main").load("tab-1.html", function(){
// Instead of creating another selector combining it from $(this).hide()
// $($(this).hide()).fadeIn(1000);
// you can chain the methods:
$(this).hide().fadeIn(1000);
});
});
Its working for me,
save this file example.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Include</title>
</head>
<body>
<input type="text" id="txt_name">
<a id="link" href="#">Click Test Link</a>
<script type="text/javascript" src="jquery-2.1.1.min.js"></script>
<script type="text/javascript">
$("#link").on('click',function(){
value=$("#txt_name").val();
window.location = "tab-1.php?txt_value="+value;
});
</script>
</body>
</html>
save this file tab-1.php
<b><i>Hello : <?php echo $_GET['txt_value']; ?></i></b>
You're problem is probably the fact that you are using <a> tags
you don't need them
<nav>
<ul>
<li data-href="tab-1.html">Planet 1</li>
<li data-href="tab-2.html">Planet 2</li>
<li data-href="tab-3.html">Planet 3</li>
<li data-href="tab-4.html">Planet 4</li>
</ul>
</nav>
$(document).ready(function(){
$("li").click(function () {
$("main").load(this.dataset.href, function(){
$(this).hide().fadeIn(1000);
});
});
});
Here we get the value of that specific link href attribute, and inject it into the load function
NOTE: As I can't show a demo of it using fiddle or S.O code panel, here is a DEMO showing how this code works
$(document).ready(function () {
$("nav a").each(function () {
$(this).click(function (e) {
e.preventDefault();
var href = $(this).attr("href");
$("main").load(href).hide().fadeIn(1000);
});
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
<nav>
<ul>
<li>Planet 1
</li>
<li>Planet 2
</li>
<li>Planet 3
</li>
<li>Planet 4
</li>
</ul>
</nav>
<main></main>

How to highlight active nav tab in specific case

I am using this as a template for JS which selects proper nav using JQuery, with this API reference.
My current code:
index.php
<html>
<head>
<title>ChillSpot Alpha 1.2.3</title>
<link rel="stylesheet" type="text/css" href="common/style.css">
<script type="text/javascript" src="common/jquery-1.11.2.min.js"></script>
<script type="text/javascript" src="background.js"></script>
<script type="text/javascript" src="common/navHighlight.js"></script>
<script type="text/javascript"> $( document ).ready( getImage );</script>
<script type="text/javascript"> $( document ).ready( setNavigation );</script>
</head>
<?php
include 'common/header.html';
?>
//More code, snipped from example: not relevant
common/navHighlight.js
<!--
function setNavigation() {
var path = window.location.pathname;
path = path.replace(/\/$/, "");
path = decodeURIComponent(path);
$(".menuList a").each(function () {
var href = $(this).attr('href');
if (path.substring(0, href.length) === href) {
$(this).closest('li').removeClass('tab');
$(this).closest('li').addClass('tab selected');
}
});
}
//-->
common/header.html
<div class="menu">
<ul class = "menuList">
<li class="tab">Home</li>
<li class="tab">Communications</li>
<li class="tab">ChillCraft</li>
<li class="tab">Forum</li>
<li class="tab">Updates</li>
<li class="tab">About</li>
</ul>
</div>
<div class="content">
... this isnt working. What is different in my situation that causes the example to fail? All "li" elements end up with class "tab", none have "tab selected".
I'm not sure if this is actually what's wrong, but I do notice that the href's in their example all start with / while yours do not. Relative pathing could be why yours isn't working.
So if you change your html to this you might be fine:
<div class="menu">
<ul class = "menuList">
<li class="tab">Home</li>
<li class="tab">Communications</li>
<li class="tab">ChillCraft</li>
<li class="tab">Forum</li>
<li class="tab">Updates</li>
<li class="tab">About</li>
</ul>
</div>
My approach on these cases is as follows:
Add a unique id to each of your tabs (in addition to the class you already have)
On each specific file (index.php, common.php, forum.php, etc) create an object with your selected tab:
var selected = $('#forumTab');
Execute a function where you ensure to be removing the active class from all tabs and add it only to your current tab:
$('.tab').removeClass('active');
selected.addClass('active');

How to call a Javascript function onselection of menuitem?

How can I call a Javascript function test() as below for the onselect event (upon selection of menu item) of a menu item as for my below code?
I have always worked on OnClick event in button but I have no idea about OnSelect events for the menuitems, how to call a function onselection of menuitem.
Can anyone suggest how can my code below work and call my function test() (code 1) on selection of menu item named Log Report as in code-2?
<ul>
<li>Log Report</li>
</ul>
Code-1
<script>
function test() {
window.open("www.google.com");
}
</script>
Code-2
<html lang="en">
<head>
<meta charset="utf-8">
<title>Test screen</title>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.11.0/themes/smoothness/jquery-ui.css">
<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://code.jquery.com/ui/1.11.0/jquery-ui.js"></script>
<link href="style.css" rel="stylesheet" type="text/css">
<script>
$(function() {
$( "#menu" ).menu();
});
</script>
<style>
.ui-menu { width: 230px; }
</style>
</head>
<body>
<ul id="menu">
<li>Database</li>
<li>Log
<ul>
<li>Log Report</li>
</ul>
</li>
</html>
To not create a function for every li, suggest the use of data attribute
<ul id="menu">
<li>Database</li>
<li>Log
<ul>
<li data-page="www.google.com">Log Report</li>
</ul>
</li>
</ul>
Then pass it in the function
$('#menu li').click(function(){
test($(this).data('page'));// which will give "www.google.com" if clicked on the Log Report
}
function test(url){
window.open = url;
}
I think you looking for this
$("#menu").on("click", "li", function(event){
test();
console.log('clicked');
});
Hope this helps...
More info DEMO JSFiddle
As you are using jQuery UI Menu Widget, Use select event, it is triggered when a menu item is selected.
$('#menu').menu({
select: function (event, ui) {
test();
}
});
Another way is
$("#menu").on("menuselect", function (event, ui) {
test();
});
Use click event
$("#menu li").click(function(){
test();
});

When i click on child menu parent menu should highlight

when we click on sub menu parent menu should highlight. Please check my Javascript code. I am unable to get the result.Here i got the results only main menu highlighted. Please help me.Thanks in advance
<html>
<script type="text/javascript" src="jquery-1.3.2.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$('#cssmenu a').each(function(index) {
if(this.href.trim() == window.location)
{
//check if 1st level, then below condition
//if(this.class() != "has-parent")
//{
// $(this).addClass("active");
//}
//if not first level, assign active to parent of this
//if(this.class()= "has-parent")
//{
$(this).addClass("active");
//}
}
});
});
</script>
<style>
.active{
background: #4FA9E4; color:#FFF;
}
<ul id="id">
<body>
<div id="cssmenu">
<ul>
<li class="has-sub">Company
<ul><li class="has-parent">a</li>
<li>b</li>
</ul>
</li>
<li class="has-sub">Patners
<ul><li>c</li>
<li>d</li></ul>
</li>
<li>Contact Us</li>
</ul>
</div>
</body>
</html>
You forgot to close the style tag which is what caused the problem. Also I added some other tags you forgot like doctype and head tags. Validate your document http://validator.w3.org/ and you won't get problems like these anymore.
<!doctype html><html><head><title>test</title>
<script type="text/javascript" src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$('#cssmenu a').each(function(index) {console.log(this.href);
if(this.href.trim() == window.location)
{
//check if 1st level, then below condition
//if(this.class() != "has-parent")
//{
// $(this).addClass("active");
//}
//if not first level, assign active to parent of this
//if(this.class()= "has-parent")
//{
$(this).addClass("active");
//}
}
});
});
</script>
<style>
.active{
background: #4FA9E4; color:#FFF;display:block;
}
</style>
</head><body>
<div id="cssmenu">
<ul>
<li class="has-sub">Company
<ul><li class="has-parent">a</li>
<li>b</li>
</ul>
</li>
<li class="has-sub">Patners
<ul><li>c</li>
<li>d</li></ul>
</li>
<li>Contact Us</li>
</ul>
</div>
</body></html>
Something like this?
HTML:
<div id="cssmenu">
<ul>
<li class="has-sub">Company
<ul><li class="has-parent">a</li>
<li>b</li>
</ul>
</li>
<li class="has-sub">Patners
<ul><li>c</li>
<li>d</li></ul>
</li>
<li>Contact Us</li>
</ul>
</div>
JS:
$(function(){
$('#cssmenu li').click(function() {
if ($(this).hasClass('has-parent')){
var parent = $(this).closest('.has-sub');
parent.attr('class', 'active');
}
});
});
Styles:
.active{
background: #4FA9E4; color:#FFF;
}
Please see this fiddle.
add click function
$('#cssmenu a').unbind('click').click(function(){
$(this).addClass("active");
return false;
});
Sample here

Categories

Resources