Bootstrap collapse not working when using dynamic id - javascript

I have an issue when creating dynamic id for bootstrap collapse.
First when I click on any topic which is in ng-repeat it should collapse and give me the question list.
The problem here is when I click on the first topic it collapse but when i click on second topic the first topic collapse is getting the second topic question list data
Html:
<div class="topic-div">
<p class="topic-heading">Topics</p>
</div>
<div class="arrow-down"></div>
<ul>
<li ng-repeat="topics in oJdDetails.topics" class="topic-li" ng-click="fngetQList(topics,$index)">
<p class="topics-p"> {{topics}}</p>
<ul uib-collapse="isCollapsed">
<li ng-repeat="value in aQuestionList">{{value.quesList.quesListName}}</li>
</ul>
</li>
</ul>
Js:
$scope.fngetQList = function(topics, index) {
debugger;
$scope.isCollapsed = true;
$scope.displayQList = true;
$scope.sTopics = topics;
$scope.index = index;
getCandidateInterviewListService.fnGetQList(topics).then(function(response) {
$scope.aQuestionList = response;
console.log($scope.aQuestionList);
});
};
I don't understand how to make it work. Any help would be highly appreciated.

It seems you are using plain bootstrap library which will not work with angularjs.
Try with https://angular-ui.github.io/bootstrap/#/collapse

Try avoid using jQuery with Angular especially for Bootstrap. Angular's UI team has written the Angular wrapper for Bootstrap.
http://angular-ui.github.io/bootstrap/
Use this library instead. You don't need the jQuery for this. http://angular-ui.github.io/bootstrap/#/collapse
This uses the Bootstrap's CSS file and the Javascript part is provided by the Angular so you don't need to use jQuery for it.
Angular in itself is a big enough Javascript library so don't bloat your application by installing jQuery as well.

Related

Detect which tab is selected with jquery

I am using materializecss to create tabs. So I am at point where I want to detect which tab is opened and then configure the UI using Javascript or Jquery.
E.g
if (tab.index == 0 || 'brands'){
//Configure some UI
}else if(tab.index == 1 || 'products'){
//Configure some UI
}
The HTML part looks like this:
<ul class="tabs blue-grey darken-2">
<li class="tab col s6"><a class="active" href="#brands" style="color: white;">Brands</a></li>
<li class="tab col s6"><a style="color: white;" href="#products">Products</a></li>
</ul>
I already did manually change tab on button click like this:
$('ul.tabs').tabs('select_tab', 'products');
but do not know how to achieve the question part. I hope to get some help :) I went through many similar questions but didn't find solution. If the question is somehow dublicate please comment.
There is an onShow callback. See http://materializecss.com/tabs.html
This code is untested and there is no simple example of how to use onShow at the vendor website but I hope it will show you the way. 'some_param' is where you need to know the attributes of the tab object - maybe it has an index. If not then maybe you could add differentiating classes to the first and other tabs and use jquery .hasClass(classname') to decide what happens next.
$(document).ready(function(){
$('ul.tabs').tabs('select_tab', 'tab_id').onShow(function(selectedTab){
if (selectedTab.some_param === some_val){
...do something
}
});
});

angular.js app with linked panels

I am learning Angular and i am ok with the basics however i have a situation where i have 3 interlinking panels or panes. You select the category from the first pane, it populates a list of products in the second pane then choosing one of these populates the third pane with the product details.
I have mocked up the structure here: https://jsfiddle.net/pbpxexsa/1/
Whats the best approach for constructing this?
I added some routing to have a meaningfull url, but i can only have one ng-view.
I have looked at ui.router and this looks like it might fit
Could i just have a separate controller on each pane and an observer to watch for changes but i have read this is to be avoided.
I like the aspect of directives and understand i could provide <product-pane></product-pane> and <product-details></product-details> directives but again not sure how to link them.
The books i am reading don't seem to cover this kind of architecture, am i missing something obvious?
Thanks in advance.
I think you might be over-thinking this slightly. You have 3 panels which are all viewing a single data group, but you are trying to engineer a solution that would only be necessary when each panel is showing different data. You can easily do this design with a single controller.
Just a generic mockup (not working or tested, but should give you an idea):
<div class="category-pane">
<ul>
<li ng-repeat="category in categories"
ng-click="setSelectedCategory(category)">{{category.name}}</li>
</ul>
</div>
<div class="products-pane">
<ul>
<li ng-repeat="product in selectedCategory.products"
ng-click="setSelectedProduct(product)">{{product.name}}</li>
</ul>
</div>
<div class="product-details-pane>
{{selectedProduct.name}}
{{selectedProduct.info}}
....
</div>
In controller:
$scope.setSelectedCategory= function(category){
$scope.selectedCategory = category;
$scope.selectedProduct = null; //remove whatever was in the product pane
};
$scope.setSelectedProduct= function(product){
$scope.selectedProduct = product;
};

angularjs vs twitter bootstrap tabs javascript

I'm making my first steps with angularJS. In the "code school" video (http://campus.codeschool.com/courses/shaping-up-with-angular-js/level/2/section/2/video/1) there is a sample code that makes tabs in angular:
HTML
<section class="tab" ng-controller="TabController as tab">
<ul class="nav nav-pills">
<li ng-class="{active:tab.isSet(1)}">
<a href ng-click="tab.setTab(1)">Description</a></li>
<li ng-class="{active:tab.isSet(2)}">
<a href ng-click="tab.setTab(2)">Specs</a></li>
<li ng-class="{active:tab.isSet(3)}">
<a href ng-click="tab.setTab(3)">Reviews</a></li>
</ul>
<div ng-show="tab.isSet(1)">
<h4>Description</h4>
<blockquote>{{product.description}}</blockquote>
</div>
<div ng-show="tab.isSet(2)">
<h4>Specs</h4>
<blockquote>Shine: {{product.shine}}</blockquote>
</div>
<div ng-show="tab.isSet(3)">
<h4>Reviews</h4>
<blockquote></blockquote>
</div>
</section>
JavaScript:
app.controller('TabController', function(){
this.tab = 1;
this.setTab = function(newValue){
this.tab = newValue;
};
this.isSet = function(tabName){
return this.tab === tabName;
};
});
I know that twitter bootstrap has its own JavaScript for managing dynamic tabs (http://getbootstrap.com/javascript/#tabs).
My question is: is angularjs using bootstrap javascript here? I guess not. And if not (while this means angular is using only bootstrap's CSS), then why is angular reinventing the wheel = implementing new code that does the same thing as bootstrap's javascript code? I mean, why writing different code that does the same stuff, why not to use existing code?
Maybe it's just a matter of this tutorial - but is there a way to make angular use native bootstrap's javascript?
bootstrap provides one-way binding data. Howerver, angularJS supplies two-way binding. I suggest you should take a look at angular-ui. If you want use bootstrap with angularjs, you shoud search keyword "custom directive angularjs".
Reinventing the wheel? They are only using ng-show, which just changes the display style in your element to none.
Angular has no problem to use anyone scripts, you only have to do it the angular way. In this case it is called directives (most cases when you are going to manipulate DOM this is the way).
So for angular directives you can use template or templateUrl, template you give a string, templateUrl you give a file path. In your case I recommend you to place a new html file and write there your tabs content.
so in you tabs.html file
<div class="tab-content">
<div class="tab-pane active" class="home">...</div>
<div class="tab-pane" class="profile">...</div>
<div class="tab-pane" class="messages">...</div>
<div class="tab-pane" class="settings">...</div>
</div>
your directive should look something like this, according to bootstrap docs
myapp.directive('theNameOfMyDirective', function () {
return {
restrict: 'E',
replace: true,
templateUrl: 'the path to my html file', you can use only template too and writte your html as string, but in your case I think it is more clean if you do it in a diferent file
link: function (scope,element){
// angular.element() this is similar to $() in Jquery or Jquery()
angular.element(element).find('.profile').on('click', function (e){
e.preventDefault()
$(this).tab('show');
});
angular.element(element).find('.home').on('click', function (e){
e.preventDefault()
$(this).tab('show');
});
//some other tabs
}
}
});
since we restrict our directive to be E (Element), we have to add this html to render our tabs wherever we need them
<theNameOfMyDirective></theNameOfMyDirective>
for more info of custom directives http://tutorials.jenkov.com/angularjs/custom-directives.html

Loading HTML in <div> before .ready

At first I'm using JQuery Mobile. I have already investigated about loading HTML inside a div but I having some problems.
The main idea is that I have 3 differents menus (which are lists) and each one stored in a HTML file generated by the server. /Menu1.html, /Menu2.html, /Menu3.html. It has to be this way because menus could change dynamically.
So, the menus looks like this:
<ul>
<il><a href="whatever1> Option1 </a></li>
<ul>
<il><a href="whatever1> Option1.1 </a></li>
</ul>
<il><a href="whatever2> Option2 </a></li>
</ul>
I'm doing it this way:
<div id="menuview">
</div>
<script type="text/javascript">
$("#menuview").load("data/menu1.html");
</script>
And it is loading the list, right, but without css. So What I'm seeing is just the list and not a JQM linked list view like the demo here: http://demos.jquerymobile.com/1.4.0/listview/
If I copy the menu1.html inside the div manually it works perfectly.
I'm not just asking for a solution, maybe is there any better way to do this and I don't know it.
Thanks in advance!
When adding any items dynamically, you need to initialize them manually.
Inside each menu you have, add initialization function.
<ul>
<!-- elements -->
<script>
$(function () {
$("ul").listview();
});
</script>
</ul>
Note that nested listview is removed from jQM 1.4.
To create a nested listview, check this official demo.

Make accordion js better

I've wrote a simple accordion faqs list using jQuery, but looking for some feedback on ways to improve it better.
My mark-up looks something like this:
<ul class="faqs">
<li><h4>Question</h4>
<div class="answer">answer</div>
</li>
<li><h4>Question</h4>
<div class="answer">answer</div>
</li>
<li><h4>Question</h4>
<div class="answer">answer</div>
</li>
</ul>
My JS looks something like this:
var question = $('.faqs h4');
question.click(function() {
$(this).next('div').slideToggle('fast');
});
All .answer divs are set to display:none on page load, but if js is disabled, all .answer div would be shown by default.
Cheers
I'd suggest adding $(".answer").slideUp() so that only one accordion item can be open at a time:
var question = $('.faqs h4');
question.click(function() {
$(".answer").slideUp();
$(this).next('div').slideToggle('fast');
});
(Also, maybe add a little style, eg the :hover pseudo-class. Maybe add some other animations.)
Fiddle
I wonder, why to try yourself with something from scratch when there's so many good accordions out there ...
Did you try the Bootstrap Collapse?
http://twitter.github.com/bootstrap/javascript.html#collapse
Simple markup and you can use as part of the hole Bootstrap Framework, or simply use it independently from anything else (you need jQuery though)

Categories