Backbone: Different views for different tab content - javascript

I have a generic view and 4 other views. I am using bootstrap tabs (nav-tabs) in the generic view. I want the other 4 views to be the content of 4 tabs in the generic view.
As I am new to backbone and bootstrap I am not able to figure out how to do that. Also, I am using only views in backbone for now (which means, there is no model or controller).
Would sure appreciate the idea of how to do this.
Thank you.

I would suggest breaking things down.
1st you build your bootstrap HTML for your tabs and give a unique selector to each one of them. For instance, on this file here https://gist.github.com/mnewt/4228037 :
<ul id="tabs" class="nav nav-tabs" data-tabs="tabs">
<li class="active">Red</li>
<li>Orange</li>
<li>Yellow</li>
<li>Green</li>
<li>Blue</li>
</ul>
<div id="my-tab-content" class="tab-content">
<div class="tab-pane active" id="red">
<h1>Red</h1>
<p>red red red red red red</p>
</div>
<div class="tab-pane" id="orange">
<h1>Orange</h1>
<p>orange orange orange orange orange</p>
</div>
<div class="tab-pane" id="yellow">
<h1>Yellow</h1>
<p>yellow yellow yellow yellow yellow</p>
</div>
<div class="tab-pane" id="green">
<h1>Green</h1>
<p>green green green green green</p>
</div>
<div class="tab-pane" id="blue">
<h1>Blue</h1>
<p>blue blue blue blue blue</p>
</div>
</div>
2nd now you can create your 4 content views passing el as the id for each content tab:
var tab1 = new ContentView({
el: '#red'
});
var tab2 = new ContentView({
el: '#orange'
});
var tab3 = new ContentView({
el: '#yellow'
});
var tab4 = new ContentView({
el: '#green'
});

I approached this differently using css driven tabs based on this.
The idea is to have it so that the css will handle the hiding and displaying of tabs. The js just simply listens for which tab is clicked and renders the view accordingly.
For example, the following could be the html which defines the tab structure and the containers which will hold each view. Html:
<div>
<ul id="profileMainView" class="tabs">
<li class="labels" >
<label class="profile-selectTab selectedTab" for="tab0" id="profile-label0">
Tab 0
</label>
<label class="profile-selectTab" for="tab1" id="profile-label1">
Tab 1
</label>
<label class="profile-selectTab" for="tab2" id="profile-label2">
Tab 2
</label>
</li>
</ul>
</div>
<ul class="tabs">
<li>
<input type="radio" checked name="tabs" id="tab0">
<div id="tab-content0" class="tab-content">
Tab 1 Content
</div>
</li>
<li>
<input type="radio" name="tabs" id="tab1">
<div id="tab-content1" class="tab-content">
Tab 2 Content
</div>
</li>
<li>
<input type="radio" name="tabs" id="tab2">
<div id="tab-content2" class="tab-content">
Tab 3 Content
</div>
</li>
</ul>
This css can handle hiding and showing the tabs:
.tabs input[type=radio] {
display:none;
}
.tabs {
float: none;
list-style: none;
padding: 0;
}
.tabs li {
display: block;
}
.labels{
border-bottom: 1px solid #DDD;
height: 55px;
}
.labels:after {
content: '';
display: table;
clear: both;
}
[id^=tab]:checked ~ div[id^=tab-content] {
display: block;
}
[id^=tab]:checked ~ div[id^=tab-content] {
display: block;
}
Finally the js can just listen for which tab is selected and then render the view by passing in the id of the selected tab:
var mainView = Backbone.View.extend({
events: {
'click .profile-selectTab' : function(e) {
this.renderTab(e.currentTarget.id);
},
renderTab: function(id){
if(id == 'profile-label0'){
yourView1.render('tab-content0');
} else if(id == 'profile-label1'){
yourView2.render('tab-content1');
} else if(id == 'profile-label2'){
yourView3.render('tab-content2');
}
}
});
Each view would just render and append to the correct tab's div. For example:
var yourView1 = Backbone.View.extend({
render : function(targetDiv){
$('#' + targetDiv).append(...);
}
});

Related

Menu bar Malfunctioning with AngularJs

I am bit new to AngularJs so I have got stuck into the problem.
Let me explain what I want to achieve.
I have design two div with child and parent relation.
// first parent div
<div>
<div>
child div // show/hide content of this div
</div>
</div>
// second parent div
<div>
<div>
child div // show/hide content of this div
</div>
</div>
When I hover or move the mouse over parent div it should hide/show the respective child div.
But with my code on hover it hides/shows the content of both the child div.What changes do I have to do in code?
See complete code
<body ng-app="app">
<div ng-app="headermain" ng-controller="headerController">
<div class="top-menu col-xs-36 ">
// parent div one
<div class="menu-item col-xs-6" ng-mouseover="hoverIn()" style="background-color:pink">
<span >Parent one</span>
// child div, want to hide/show content of this div
<div class="drop-down;col-xs-10" ng-show="showMe" ng-mouseleave="hoverOut()" style="background-color:pink">
<ul>
<li>child one details</li>
<li>parent one detail</li>
</ul>
</div>
</div>
// parent div two
<div class="menu-item col-xs-6" ng-mouseover="hoverIn()">
<span >Parent two</span>
// child div, want to hide/show content of this div
<div class="drop-down;col-xs-10" ng-show="showMe" ng-mouseleave="hoverOut()">
<ul>
<li>child two Details</li>
<li>parent two detail</li>
</ul>
</div>
</div>
</div>
</div>
Controller for this code, see below
var app = angular.module("app", []);
app.controller("headerController",function($scope){
$scope.hoverIn = function(){
this.showMe = true;
};
$scope.hoverOut = function(){
this.showMe = false;
};
});
Css file
.top-menu {
overflow: hidden;
}
.top-menu .drop-down {
position: absolute;
top: 20px;
z-index: 10000;
background-color: white;
box-shadow: 0px 0px 3px rgb(241, 241, 241);
border: 1px solid #d1d1d1;
}
.top-menu .drop-down ul {
padding: 0px;
margin: 0px;
list-style-type: none;
min-width: 180px;
}
You have to change the name of your functions since both div's are using the same function and changing the same attribute showMe.
HTML:
<body ng-app="app">
<div ng-app="headermain" ng-controller="headerController">
<div class="top-menu col-xs-36 ">
// parent div one
<div class="menu-item col-xs-6" ng-mouseover="hoverIn(1)" style="background-color:pink">
<span>Parent one</span> // child div, want to hide/show content of this div
<div class="drop-down;col-xs-10" ng-show="showMe[1]" ng-mouseleave="hoverOut(1)" style="background-color:pink">
<ul>
<li>child one details</li>
<li>parent one detail</li>
</ul>
</div>
</div>
// parent div two
<div class="menu-item col-xs-6" ng-mouseover="hoverIn(2)">
<span>Parent two</span> // child div, want to hide/show content of this div
<div class="drop-down;col-xs-10" ng-show="showMe[2]" ng-mouseleave="hoverOut(2)">
<ul>
<li>child two Details</li>
<li>parent two detail</li>
</ul>
</div>
</div>
</div>
</div>
JS:
$scope.showMe=[];
$scope.hoverIn = function(id) {
$scope.showMe[id] = true;
};
$scope.hoverOut = function() {
$scope.showMe[id] = false;
};

Toggle list items after button click using jQuery

So i managed to get my buttons to show the list items in the unordered list. But now every time i click a button all the list items nested in unordered list appears and disappears when the button is clicked again.
This is my updated HTML:
<div class="container-fluid text-center bg-black" id="services">
<div class="services">
<h2>SERVICES</h2>
<br>
<div class="row">
<div class="col-sm-3 iconpad-even">
<img src="img/icons/icon_data_edit.png" alt="data"/>
<button class="icon-btn" data-button="btnData">DATA</button>
<ul class="showData">
<li>Design</li>
<li>Cable Installation</li>
<li>Testing</li>
<li>CAT5e, CAT6, CAT6A</li>
</ul>
</div>
<div class="col-sm-3 iconpad-odd">
<img src="img/icons/fiber-icon-edit.png" alt="fiber-icon" />
<button class="icon-btn" data-button="btnFiber">FIBER</button>
<ul class="showData">
<li>Consultancy</li>
<li>Building to Building</li>
<li>Network Backbone</li>
<li>Testing</li>
</ul>
</div>
Basically i have 6 div's that are structured the exact same way, only difference is the content on the list items.
I've removed the display:none on the services ul li and added it to the css .showData class as suggested by #Mohammed-Yusef
Here's the current jQuery:
$(function() {
$('.icon-btn').on('click', function() {
$('.showData').toggle();
});
});
The jquery syntax of the click function should be as given below and also in your css you are hiding all the li elements. So you have to toggle them back with the selector $('.showData li') instead of $('.showData'). Also use .icon-btn instead of .icon-button as you don't have such a class mentioned in your html.
$('.icon-btn').on('click', function() {
$('.showData li').toggle();
});
Working snippet,
$(function() {
$('.icon-btn').on('click', function() {
//$('.showData li').toggle();
$(this).next('.showData').find('li').toggle();
});
});
.services ul li {
display: none;
margin-left: -1.8em;
/*color: #fff;*/
list-style: none;
margin-bottom: 1em;
font-size: 20px;
font-weight: bold;
font-family: 'Oswald', 'open-sans';
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="container-fluid text-center bg-black" id="services">
<div class="services">
<h2>SERVICES</h2>
<br>
<div class="row">
<div class="col-sm-3 iconpad-even">
<img src="img/icons/icon_data_edit.png" alt="data"/>
<button class="icon-btn" data-button="btnData">DATA</button>
<ul class="showData">
<li>Design</li>
<li>Cable Installation</li>
<li>Testing</li>
<li>CAT5e, CAT6, CAT6A</li>
</ul>
</div>
<div class="col-sm-3 iconpad-odd">
<img src="img/icons/fiber-icon-edit.png" alt="fiber-icon" />
<button class="icon-btn" data-button="btnFiber">FIBER</button>
<ul class="showData">
<li>Consultancy</li>
<li>Building to Building</li>
<li>Network Backbone</li>
<li>Testing</li>
</ul>
</div>
Please try it
$( "body" ).on( "click", ".icon-button", function(){
$('.showData').toggle();
});
The problem is that you don't have an element with a class icon-button your button has a class icon-btn so use $('.icon-btn') instead of $('.icon-button')
and you can use
$(function() {
$('.icon-btn').on('click', function() {
$('.showData').toggle();
});
});
and in css use
.showData{
display: none;
}
and remove display:none from .services ul li
Note: be sure to include jquery

jQuery switch active class depending on which section is showing

I have several sections within a document as follows:
<section id="step1">
</section>
<section id="step2" style="display:none">
</section>
<section id="step3" style="display:none">
</section>
I am showing and hiding these depending on user interaction. I wanted to have some kind of circular heading to indicate the user is on section 2 of 3 for example like so:
<div id="indicators" class="clearfix">
<div class="center-div">
<ul>
<li id="step1-circle" class="circle active"></li>
<li id="step2-circle" class="circle"></li>
<li id="step3-circle" class="circle"></li>
</ul>
</div>
</div>
How would I switch the active class depending on which section is showing?
You can use the addClass() method in tandem with the removeClass() method like:
function makeIndicatorCircleActive(id){
// Remove active state of current circle
$('#indicators .active').removeClass('active');
// Add active state to desired element
$(id).addClass('active');
}
// Somewhere else in the code...
makeIndicatorCircleActive('#step2-circle);
I've added a button for the animation. You'd need to show more example code of your implementation, but you may be able to get away with let $section = $('section:visible') and instead of putting this in a click function, create a generic function name, which is triggered whenever your event occurs.
$('button').click(function() {
// context used for jQuery
let $section = $(this).closest('section');
// get next circle, if current circle is last, then get first circle
var $next = $('.circle.active', $section).next('.circle'),
$next = ($next.length && $next) || $('.circle', $section).first();
$('.circle.active', $section).removeClass('active'); // remove all actives
$next.addClass('active'); // add new active
});
.circle {
background: black;
border-radius: 25px;
display: inline-block;
list-style-type: none;
width: 50px;
height: 50px;
-moz-border-radius: 25px;
-webkit-border-radius: 25px;
}
.active {
background: red;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<section>
<div class="clearfix">
<div class="center-div">
<ul>
<li class="circle active"></li>
<li class="circle"></li>
<li class="circle"></li>
</ul>
</div>
<button>Next</button>
</div>
</section>
<section>
<div class="clearfix">
<div class="center-div">
<ul>
<li class="circle active"></li>
<li class="circle"></li>
<li class="circle"></li>
</ul>
</div>
<button>Next</button>
</div>
</section>

Appended content do not get the proper CSS effect

I want append an HTML element into a DIV, but this one do not get the proper CSS like the original ones.
I have a dropdown menu, and want append on it new <li> rows.
My HTML code:
<br/><br/>
Append it
<div class="container">
<div class="row">
<div class="col-sm-3">
<h5>Normal Dropdown Button</h5>
<div class="panel panel-default">
<div class="panel-body">
<div class="btn-group">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
<span data-bind="label">Select One</span> <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<div id="append">
</div>
<li>Item 1</li>
<li>Another item</li>
<li>This is a longer item that will not fit properly</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<br/><br/>
My Javascript code:
$( document.body ).on( 'click', '.append', function( event ) {
$("#append").append("<li>Item 1</li>");
return false;
});
Here a live example: http://jsfiddle.net/dJDHd/2136/
EDITED WITH MY MAIN PROBLEM:
https://jsfiddle.net/Lr7gn020/1/
Click on APPEND IT, and then check the appended element by clicking on Select One button (Dropdown menu), and you will see that it do not get the proper CSS like the others (Item Test).
You've nested a div in the ul and the styles target .dropdown-menu>li>a so the div is breaking that. A div can't be a direct child of a ul and li can't be a direct child of a div. Instead of nesting a div in the ul, then appending li's to the div, you can $.prepend() li's directly to the menu, if you want them to appear at the beginning of the menu when you add them. If you don't care where they appear, you can $.append() them to the bottom instead.
$(document.body).on('click', '.append', function(event) {
$(".dropdown-menu").prepend("<li>Item Test</li>");
return false;
});
.btn-input {
display: block;
}
.btn-input .btn.form-control {
text-align: left;
}
.btn-input .btn.form-control span:first-child {
left: 10px;
overflow: hidden;
position: absolute;
right: 25px;
}
.btn-input .btn.form-control .caret {
margin-top: -1px;
position: absolute;
right: 10px;
top: 50%;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<br/><br/>
Append it
<div class="container">
<div class="row">
<div class="col-sm-3">
<h5>Normal Dropdown Button</h5>
<div class="panel panel-default">
<div class="panel-body">
<div class="btn-group">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
<span data-bind="label">Select One</span> <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li>Item 1</li>
<li>Another item</li>
<li>This is a longer item that will not fit properly</li>
</ul>
</div>
</div>
</div>
</div>
</div>
</div>
<br/><br/>
The reason behind the appended option having different css is due to the fact that you are appending it inside a div element.
The current CSS of the li elements comes from the bootstrap css with this selector.
dropdown-menu>li>a
Since you have a div node inside ul (which is wrong and make html invalid) and you are appending a new li inside this div with JS, the above selector will not reach this node and CSS will not be applied.
You should add the li node directly under the ul node.
Fiddle : http://jsfiddle.net/9med3Lou/
Change your jquery part.
$( document.body ).on( 'click', '.append', function( event ) {
$(".dropdown-menu").append("<li>Item 1</li>"); //append with ul, not div
return false;
});

accordion vertical menu bar on page refresh sub menu hides

I've created a accordion vertical menu bar with reference to http://www.w3schools.com/howto/tryit.asp?filename=tryhow_js_accordion_symbol
I am facing a problem that on button click the submenu appears but since it is a click event the page refreshes and on page refresh the submenu hides again. This problem is annoying me very much, please help. This menu bar is for the project ASP.NET , C#.
<div id="aside">
<button class="accordion">Registration</button>
<div class="panel">
<ul class="submenu">
<li>Register</li>
<li>Old Register</li>
</ul>
</div>
<button class="accordion">Configuration</button>
<div class="panel">
<ul class="submenu">
<li>Register</li>
<li>Old Register</li>
</ul>
</div>
<button class="accordion">Reports</button>
<div id="foo" class="panel">
<ul class="submenu">
<li>Register</li>
<li>Old Register</li>
</ul>
</div>
<!-- cd-accordion-menu -->
</div>
<script type="text/javascript">
var acc = document.getElementsByClassName("accordion");
var i;
for (i = 0; i < acc.length; i++) {
acc[i].onclick = function () {
this.classList.toggle("active");
var panel = this.nextElementSibling;
if (panel.style.maxHeight) {
panel.style.maxHeight = null;
} else {
panel.style.maxHeight = panel.scrollHeight + 'px';
}
}
}
</script>
Change your button's to div's and remove the width:100% from the accordion. Here is a fiddle: https://jsfiddle.net/062ut3oL/
HTML
<div id="aside">
<div class="accordion">Registration</div>
<div class="panel">
<ul class="submenu">
<li>Register</li>
<li>Old Register</li>
</ul>
</div>
...
CSS
.accordion {
background-color: #eee;
color: #444;
cursor: pointer;
padding: 18px;
border: none;
text-align: left;
outline: none;
font-size: 15px;
transition: 0.4s;
}
Explanation
Using buttons in a ASP.NET page can be troublesome as they tend to cause a postback under some circumstances.
Try to save in localStorage the current page and on load page in javascript read this info and add a class (ex. selected) to the voice in menu.

Categories