Doing Validation on bootstrap nav tabs on change - angularjs

Usign AngularJS and bootsrap 3.I have 3 nav-tabs and with panels on them. How do i programatically prevent the tabs from changing to the next one if the user has not selected a customer or dvd's. On bot the customerSelect and dvdSelect tab's i have panel with a list where the user selects the customer anmd also a list of dvds.
<div class="row">
<div class="panel panel-default">
<ul class="nav nav-tabs">
<li class="active in"><a data-target="#customerSelect" data-toggle="tab">Customer</a></li>
<li><a data-target="#dvdSelect" data-toggle="tab">Dvd List</a></li>
<li><a data-target="#orderDetail" data-toggle="tab">Order Details</a></li>
</ul>
</div>
</div>
<div class="row">
<div id="myTabContent" class="tab-content">
<div class="tab-pane fade active in" id="customerSelect">
</div>
</div>
<div id="myTabContent" class="tab-content">
<div class="tab-pane fade" id="dvdSelect">
</div>
</div>
<div id="myTabContent" class="tab-content">
<div class="tab-pane fade" id="orderDetail">
</div>
</div>
</div>
I have omitted much of the code within my tab content div's.

Using JQuery there are 4 different events for bootstrap tabs:
show.bs.tab // Occurs when the tab is about to be shown.
shown.bs.tab // Occurs when the tab is fully shown (after CSS transitions have completed)
hide.bs.tab // Occurs when the tab is about to be hidden
hidden.bs.tab // Occurs when the tab is fully hidden (after CSS transitions have completed)
A pseudo-example you could use:
$('.nav-tabs a').on('show.bs.tab', function(){
console.log('validation starts...');
if (correct!==true){
$('#tab1').tab('show');
}else{
$('#tab2').tab('show');
}
});

Related

keep tab open on refresh with bootstrap

I am having different html page in every tab and i want the active tab active even after refresh using bootstrap if possible
<div>
<ul class="nav nav-tabs">
<li class="active"><a data-toggle="tab" href="#TypeSettings">Type</a></li>
<li><a data-toggle="tab" href="#EvidenceSettings">Evidence</a></li>
<li><a data-toggle="tab" href="#OverallTypeSettings">Overall Type</a></li>
</ul>
<div class="tab-content">
<div id="TypeSettings" class="tab-pane fade in active">
<div ng-include src="'Templates/AdminSettings/TypeSettings.html'"></div>
</div>
<div id="EvidenceSettings" class="tab-pane fade">
<div ng-include src="'Templates/AdminSettings/EvidenceSettings.html'"></div>
</div>
<div id="OverallTypeSettings" class="tab-pane fade">
<div ng-include src="'Templates/AdminSettings/OverallTypeSettings.html'"></div>
</div>
</div>
If you want to remember last opened tab by user, then you have add some JS logic. You can store user last opened tab in a cookie for example.

How to pause or re run directive when that tab is focused?

I have an html page and I have created 3 separate tabs using Bootstrap each having their own partials, imported using ng-include. Here is the code for the view -
<ul class="nav nav-tabs" role="tablist" id="dashboard-tabs">
<li role="presentation" class="active">Opportunity
</li>
<li role="presentation">Effort
</li>
<li role="presentation">Results
</li>
</ul>
<!-- Page content -->
<div class="tab-content">
<!-- Opportunity Tab-->
<div role="tabpanel" class="tab-pane fade in active" id="opportunity" class="container" >
<div ng-include="'partials/opportunityView.html'"></div>
</div>
<!-- Efforts Tab-->
<div role="tabpanel" class="tab-pane fade" id="effort" >
<div ng-include="'partials/effortView.html'"></div>
</div>
<!-- Results Tab-->
<div role="tabpanel" class="tab-pane fade" id="results">
</div>
</div>
As you can see, Opportunity view is the default focus view and it runs just fine. I have a directive inside the partial/template for Efforts tab (second tab), and inside that directive link's function I am using jquery to compute the width of a table row in directive's template. But on page load, it shows the width as 0. I think it may be because Efforts view is hidden on page load.
So, how can I solve this problem? Can I re compile directive code on Effort's page load or can I pause it's execution untill Efforts tab is on focus?

Dealing with conflicting IDs in multiple instances of bootstrap tabs

I'd like to have multiple instances of the same bootstrap tab markup in the DOM. Unfortunately it appears that bootstrap tabs mandate the use of IDs which means the same IDs conflict as IDs should by definition only occur once in the DOM tree.
Example, see jsfiddle, the bottom Foo Bar tabs end up controlling the top tab pane since I've added multiple elements to the DOM with the same ID.
<div>
<ul class="nav nav-tabs" role="tablist">
<li role="presentation" class="active">Foo</li>
<li role="presentation">Bar</li>
</ul>
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="foo">Foo content</div>
<div role="tabpanel" class="tab-pane" id="bar">Bar content</div>
</div>
</div>
<div>
<ul class="nav nav-tabs" role="tablist">
<li role="presentation" class="active">Foo</li>
<li role="presentation">Bar</li>
</ul>
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="foo">Foo content</div>
<div role="tabpanel" class="tab-pane" id="bar">Bar content</div>
</div>
</div>
As I'm using Angular, as with any template engine, I can differentiate the IDs in the template with a scope variable and ensure that variable is unique throughout my application. Example, using {{id}} as a suffix.
<ul class="nav nav-tabs" role="tablist">
<li role="presentation" class="active">Foo</li>
<li role="presentation">Bar</li>
</ul>
<div class="tab-content">
<div role="tabpanel" class="tab-pane active" id="foo{{id}}">Foo content</div>
<div role="tabpanel" class="tab-pane" id="bar{{id}}">Bar content</div>
</div>
I'd like to know if there is a nicer way to solve this problem? Any way of configuring bootstrap to use class based selectors etc?
Check out the ui-bootstrap package. It makes dealing with tabs way easier in Angular.

Using ui-router with Kendo TabStrip

I am trying to implement a Kendo Tab Strip and that applies ui-router to display the contents of the tab. I can get the tab strip to display but not the contents using the ui-view. Anyone have an example of how to make these items work together.
Sample of my html.
<div class="main-template">
<div class="row">
<h3>Welcome to the Dashboard</h3>
<div ng-controller="Navigation">
<div kendo-tab-strip k-content-urls="[ null, null]">
<!-- tab list -->
<ul>
<li class="k-state-active" url="#/invoice">Invoice Management</li>
<li url="#/shipment">Shipment Management</li>
</ul>
</div>
<div ui-view></div>
</div>
</div>
</div>
I was not merging everything together as I should. In the li markup I should have used ui-sref instead of url.
<div class="main-template" style="margin-left: 10px;">
<div class="row">
<h3>Welcome to the Dashboard</h3>
<!--<a ui-sref="invoice">Invoice</a>
<div ui-view></div>-->
<div ng-controller="Navigation">
<div kendo-tab-strip="tabs">
<!-- tab list -->
<ul>
<li class="k-state-active" ui-sref="invoice">Invoice Management</li>
<li ui-sref="shipment">Shipment Management</li>
</ul>
</div>
<div ui-view></div>
</div>
</div>
</div>

Adding ng-click event with jQuery

Being new to Angularjs, I need a bit of help with this issue. I am attempting to add ng-click="getGallery(57)" to a modal tab. Adding via jQuery is not the issue, however I realize when I do this, Angular is not compiling the newly added ng-click. I have a simple controller
function imageGalleryCtrl ($scope, $http) {
//get gallery info on click
$scope.getGallery = function(id)
{
$http.post('/beta/images/get_images',{'id': id}).success(function(data)
{
$scope.images = data.thisGal_images;
$scope.images.galID = id;
});
};
}
I add the ng-click to the element with jQuery
//Edit image tab to use angularjs
$('#image_edit a').attr('ng-click','getGallery(' + settings.id + ')');
How do I force Angular to compile this newly added ng-click?
Thanks!
HTML Modal:
This is the modal that is called when the gallery name is clicked.
<div class="modal fade hide modal-creator" id="imageUploader" tabindex="-1" data-focus-on="input:first">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"></button>
<h3>Create New Gallery</h3>
</div>
<div class="modal-body">
<ul id="myTab" class="nav nav-tabs">
<li id="image_home" class="">
Home
</li>
<li id="image_upload" class="">
Upload Image Gallery
</li>
<li id="image_edit" class="">
Edit Image Gallery
</li>
</ul>
<div id="myTabContent" class="tab-content">
<div class="tab-pane fade in" id="home">
<?php include('create.php'); ?>
</div>
<div class="tab-pane fade" id="upload">
<?php include('upload.php'); ?>
</div>
<div class="tab-pane fade" id="edit">
<div class="span9">
<ul id="imageSort" class="gallery-container">
<li ng-repeat="image in images">
<img ng-src="http://images.onlinealbumproofing.com/imageGallery/{{image.galleryID}}/{{image.imageName}}" alt="">
{{image.orgName}}
</li>
</ul>
</div><!-- /span9 -->
</div><!-- /row -->
</div>
</div>
</div><!-- /modal-body -->
<div class="modal-footer">
Close
Next
</div>
</div>
Update
So really attempting to do this the Angular way, and after some studies here is where I am at.
The controller is the same as above and I have updated the tabs on the modal as follows.
<div class="modal-body">
<ul id="myTab" class="nav nav-tabs">
<li id="image_home" class="">
Home
</li>
<li id="image_upload" class="">
Upload Image Gallery
</li>
<li id="image_edit" class="">
<a ng-click="getGallery(57)" href="#edit" data-toggle="tab">Edit Image Gallery</a>
</li>
</ul>
If I hard code the ng-click as above, the tab updates as expected. What I am trying to make happen, is when the modal is called, (#image_edit a) gets a defined ng-click="getGallery(id). I need to tell Angular to look at the ng-click again for the id.
Although I too think that you should try and find another approach, the answer to your question
How do I force Angular to compile this newly added ng-click?
is
// remove and reinsert the element to force angular
// to forget about the current element
$('#button1').replaceWith($('#button1'));
// change ng-click
$('#button1').attr('ng-click','exec2()');
// compile the element
$compile($('#button1'))($scope);
See this working example: http://plnkr.co/edit/SgvQzaY0TyFHD1Mf0c3F?p=preview
Basically what I'm getting at is you want to probably make this happen:
<ul id="imageSort" class="gallery-container">
<li ng-repeat="image in images">
<img
ng-src="http://images.onlinealbumproofing.com/imageGallery/{{image.galleryID}}/{{image.imageName}}"
alt=""
ng-click="getGallery(image.galleryID)"
>
{{image.orgName}}
</li>
</ul>
The problem is I'm unsure of the relationship between the settings.id and the galleryID for a particular image. If you can set up this relationship in the data so it just automatically binds you're in better shape.

Resources