I have the following angular code for showing student info in the tabbed format.
Following is the student.html class
<div class="panel panel-default">
<ul class="nav nav-tabs">
<li ng-repeat="studentTab in studentList"
ng-class="{active: selectedStudentTab.name === studentTab.name}">
<a ng-click="selectStudentTab(studentTab)">{{studentTab.name}}</a>
</li>
</ul>
<div class="panel-body">
<div class="tab-content">
<div class="tab-pane active" ng-repeat="studentTab in studentList"
ng-show="selectedStudentTab.name === studentTab.name">
<div style="padding: 35px; text-align: left;">
<div ng-repeat="project in studentTab.projects">
<p><pre>{{project.log}}</pre></p>
</div>
</div>
</div>
</div>
</div>
</div>
in my studentController.js I have assigned the oth element of studentList to the tab, following is the code:
$scope.init = function () {
$rootScope.initOrRedirectToLandingPage($scope.loadStudents);
};
$scope.studentList = [];
$rootScope.loadStudents = function(){...
};
$scope.selectedStudentTab = $scope.studentList[0];
$scope.selectStudentTab = function (studentTab) {
$scope.selectedStudentTab = studentTab;
};
Here the tabs are created properly, but the first tab is not selected/active by default on loading of the page and becomes active only on the click event.
Can someone help me to figure out what am I missing? any help is appreciated.
In your controller after you load the studentList assign the selectedStudentTab to the first item in the list.
$scope.studentList = [...];
$scope.selectedStudentTab = $scope.studentList[0];
Related
I'm developing a website for our company, and one of the pages contains several tabs :
I want the loading operation to be done for each tab only once and not every time I click it, because these tabs have some API calls, and reloading takes time.
What is the best way to do it? I'm using Ui-router and ui-sref to move between each tab :
<div class="col-xs-2">
<div class="panel panel-default">
<div class="list-group panel panel-default">
<a ui-sref="dashboards.firstTab" ui-sref-active="active" class="list-group-item" id="firstTab_button">
<i style="color:darkblue" class="fa fa-area-chart"></i> TAB1 </a>
<a ui-sref="dashboards.secondTab" ui-sref-active="active" class="list-group-item" id="secondTab_button">
<i style="color:darkblue" class="fa fa-line-chart"></i> TAB2 </a>
<a ui-sref="dashboards.thirdTab" ui-sref-active="active" class="list-group-item" id="thirdTab_button">
<i style="color:darkblue" class="fa fa-server"></i> TAB3 </a>
</div>
</div>
</div>
<div ui-view class="col-xs-12">
<div class="row">
<div class="col-xs-12" ng-if="vm.isTabOneSelected">
<div ng-include src="'components/Cards/Tabs/TabOne/TabOne.html'"></div>
</div>
</div>
<div class="row">
<div class="col-xs-12" ng-if="vm.isTabTwoSelected">
<div ng-include src="'components/Cards/Tabs/TabTwo/TabTwo.html'"></div>
</div>
</div>
<div class="row">
<div class="col-xs-12" ng-if="vm.isTabThreeSelected">
<graph-panel panel-title="TabThree {{vm.isTabThreeSelected}}" chart-config="vm.charts.TabOneChartSite"></graph-panel>
</div>
</div>
</div>
On Each Controller, You can cache your loaded data in a service, and when you load your controller you will start by checking this service if it does not have the data, then you will request it from your APIs , in this case you only request your data once you access the tab for the first time :
eg. your service
app.service('dataService', function() {
this.firstTabData = null;
this.getFirstTabData = function () {
return this.firstTabData;
};
this.setFirstTabData = function (data) {
this.firstTabData = data;
};
});
your controller
app.controller('tabOne', function($scope, dataService) {
$scope.data = {};
$scope.load = function () {
if(dataService.getFirstTabData()) {
$scope.data = dataService.getFirstTabData();
}
else {
$scope.data = getDataFromAPI();
}
};
var getDataFromAPI = function () {
//get your data
dataService.setFirstTabData(dataFromAPI);
};
});
I am using AngularJS. I am generating pipeline-like structure. At first onload I am having one default ng-repeat value. After clicking "add more" I am displaying another list. It goes on adding as long as I am clicking the "add" button.
Here is my HTML:
Add button
<button data-ng-click="addNew()">Add New Workboard</button>
New pipeline will be created with Pipeline Names and one text box to add stageNames
<div data-ng-show="listOfLists.length > 0">
<div data-ng-repeat="list in listOfLists">
<div data-ng-repeat="pipeline in workboardstages track by $index">
<div class="added-eachboard">
<div class="form-group">
<input name="pipelineName" id="pipelineName" data-ng-
model="pipeline.pipelineName" type="text">
</div>
<ul class="simpleDemo workboard-drags" data-ng-repeat="(key,
workboardlist) in pipeline.workBoardStageMap">
<li data-ng-if="pipeline.pipelineName == key" ng-repeat="workboard in
workboardlist">{{workboard.stageName}}
<a href ="javascript:void(0)" data-ng-
click="editWorkboardStage(workboard.stageId)"><img src =
"resources/zingy/images/Edit-Small.png" class="TableIcon"></a>
</li>
</ul>
<div>
<p class="weak">Stage Name:</p>
<div class="form-group">
<input name="stageName" id="stageName" data-ng-
model="newworkboard.stageName" type="text">
</div>
</div>
</div>
</div>
</div>
</div>
Controller.js
$scope.listOfLists = [];
$scope.workboardStagesWithDefault = [
{
Name:"Test"
},
{
Name:"Test2"
},
{
Name:"Test3"
}
];
$scope.addNew = function(){
var clonedList = angular.copy($scope.workboardStagesWithDefault);
$scope.listOfLists.push(clonedList);
};
$scope.editWorkboardStage = function(stageId){
AccountService.editWorkboardStage(stageId).then(function(response){
$scope.newworkboard = response.data;
});
}
$scope.getAllWorkboardStages = function(){
AccountService.getAllWorkboardStages().then(function(response){
$scope.workboardstages = response.data;
$scope.listOfLists.push($scope.workboardstages);
});
}
After clicking edit i am displaying stage name in that particular text box.But the problem is it is displaying same for neighbouring pipeline also.I want to display only for that current pipeline.As i am displaying using ng-model it is taking for all pipelines.How to display the value only for that particular pipeline?
So, the problem is related to indexing. I made $scope.newworkboard index wise.
This is the solution: (newworkboard is based on pipeline index and pass index from editWorkboardStage function.)
<input name="stageName" id="stageName" data-ng-model="newworkboard[$index].stageName" type="text">
AND
<a href ="javascript:void(0)" data-ng-click="editWorkboardStage(workboard.stageId, $parent.$parent.$index)"><img src =
"resources/zingy/images/Edit-Small.png" class="TableIcon"></a>
HTML
<div data-ng-show="listOfLists.length > 0">
<div data-ng-repeat="list in listOfLists">
<div data-ng-repeat="pipeline in workboardstages track by $index">
<div class="added-eachboard">
<div class="form-group">
<input name="pipelineName" id="pipelineName" data-ng-
model="pipeline.pipelineName" type="text">
</div>
<ul class="simpleDemo workboard-drags" data-ng-repeat="(key,
workboardlist) in pipeline.workBoardStageMap">
<li data-ng-if="pipeline.pipelineName == key" ng-repeat="workboard in
workboardlist">{{workboard.stageName}}
<a href ="javascript:void(0)" data-ng-
click="editWorkboardStage(workboard.stageId, $parent.$parent.$index)"><img src =
"resources/zingy/images/Edit-Small.png" class="TableIcon"></a>
</li>
</ul>
<div>
<p class="weak">Stage Name:</p>
<div class="form-group">
<input name="stageName" id="stageName" data-ng-
model="newworkboard[$index].stageName" type="text">
</div>
</div>
</div>
</div>
</div>
</div>
Controller
In the controller make an array of newworkboard and assign response.data index wise.
$scope.newworkboard = [];
$scope.editWorkboardStage = function(stageId, index){
AccountService.editWorkboardStage(stageId).then(function(response){
$scope.newworkboard[index] = response.data;
});
I am using angularjs.I am doing ng-repeat to display list of notify types and i am display in li tag.In this list three values are default.I have one Add button next to the list.If i click add button then i need to display another list with the three default values.Again add button shifts place to next.And if i click add button again then it displays another list with default values and add button shifts place and this process goes on.
Here is the first list i am displaying with default and other values
<div class="col-xs-12 col-sm-4 col-md-4" data-ng-
if="workboardstages.length">
<ul class="simpleDemo row">
<li data-ng-repeat="workboard in workboardstages">
{{workboard.stageName}}
</li>
</ul>
</div>
Here is the add button i am placing next to the list
<div class="col-xs-12 col-sm-4 col-md-4">
<button data-ng-click="addNew()">Add New Workboard</button>
</div>
Here is how i am trying to display another list after clicking add button but i am not sure how to do it.
<div class="col-xs-12 col-sm-4 col-md-4" data-ng-show="flag">
<ul class="simpleDemo row">
<li data-ng-repeat="workboard in workboardStagesWithDefault">
{{workboard.Name}}
</li>
</ul>
</div>
Here is the Controller.js
$scope.workboardStagesWithDefault = [
{
Name:"New"
},
{
Name:"Won"
},
{
Name:"Lost"
}
];
$scope.flag=false;
$scope.addNew = function(){
$scope.flag=true;
};
$scope.getAllWorkboardStages = function(){
AccountSettingService.getAllWorkboardStages().then(function(response){
$scope.workboardstages = response.data;
});
}
Here after clicking add button i am displaying another list with default values "New","Won" and "Lost" but if i click another time add value it is not adding list again.I want to add lists whenever i click add button.But now it is adding only once.Can anyone tell how to keep adding the div list when add is clicked?
Each time you want to add a list add it to a list containing lists, $scope.listOfLists = [];. You could then use NgRepeat with the listOfLists and dynamically add more list to the view.
Here's an example:
angular.module("app",[]).controller("myCtrl",function($scope){
$scope.listOfLists = [];
$scope.workboardstages = [
{
stageName:"stageName1"
},
{
stageName:"stageName2"
},
{
stageName:"stageName3"
}
];
$scope.workboardStagesWithDefault = [
{
Name:"New"
},
{
Name:"Won"
},
{
Name:"Lost"
}
];
$scope.addNew = function(){
var clonedList = angular.copy($scope.workboardStagesWithDefault);
$scope.listOfLists.push(clonedList);
};
$scope.removeMe = function(index){
$scope.listOfLists.splice(index,1);
};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app" ng-controller="myCtrl">
<div class="col-xs-12 col-sm-4 col-md-4" data-ng-
if="workboardstages.length">
<ul class="simpleDemo row">
<li data-ng-repeat="workboard in workboardstages">
{{workboard.stageName}}
</li>
</ul>
</div>
<div class="col-xs-12 col-sm-4 col-md-4" data-ng-show="listOfLists.length > 0">
<div data-ng-repeat="list in listOfLists">
<ul class="simpleDemo row">
<li data-ng-repeat="workboard in list">
{{workboard.Name}}
</li>
</ul>
<button ng-click="removeMe($index)">remove {{$index}}</button>
</div>
</div>
<div class="col-xs-12 col-sm-4 col-md-4">
<button data-ng-click="addNew()">Add New Workboard</button>
</div>
</div>
If you want to add new elements after click you should extend the list which you are iterating. In your code for example if you change your code in the following way:
$scope.addNew = function(){
$scope.flag=true;
$scope.workboardStagesWithDefault.push({Name:"ButtonNew"});
};
You will be adding new position ButtonNew whenever you will click Add New Workboard button.
I have a little problem with LightGallery plugin (lightGallery - Git). I use jQueryMobile.
My gallery is on a specific page. When I arrive on this page, it will request a remote server to get some pics.
Then I initialize LightGallery. No problem the first time.
But when I leave the Gallery Page and come back after (there is a new request to server), lightGallery is not running.
No error in the browser, I have my photos displayed but I can't click on it to run LightGallery like I've done the first time.
My Code:
HTML:
<div data-role="page" id="pageGallery" data-theme="a">
<div data-role="content" class="center-body">
<h3 class="nomGroupe"></h3><br/>
<div class="demo-gallery">
<ul id="lightgallery" class="list-unstyled row">
</ul>
</div>
</div>
</div>
Javscript :
$( document ).on( "pagecontainerbeforeshow", function ( event, ui ) {
var activePage = $.mobile.pageContainer.pagecontainer( "getActivePage" );
if (activePage[0].id == "pageGallery" ) {
$('#lightgallery').empty();
$(".groupName").empty().append("group "+localStorage['groupName']);
envoieRequete('http://myServer/', {'idGroup' : localStorage['idGroup'], 'token' : localStorage['token']}, 'post', function(output){
if(output.group.photos.length === 0) {
$("#lightgallery").append('<br/><p>Empty for Group : ' + localStorage['groupName']+'</p>');
}
else {
for(i=0; i<output.group.photos.length; i++) {
$('#lightgallery').append('<li class="col-xs-6 col-sm-4 col-md-3" data-responsive="http://myServer/'+localStorage['token']+'/'+localStorage['idGroup']+'/' + output.group.photos[i].id
+ '" data-src="http://myServer/'+localStorage['token']+'/'+localStorage['idGroup']+'/' + output.group.photos[i].id + '" data-sub-html="<h4>PhotoAlt</H4>"><a href=""><img class="img-responsive"\n\
src="http://myServer/'+localStorage['token']+'/'+localStorage['idGroup']+'/' + output.group.photos[i].id + '"/></a></li>');
}
}
});
}
});
$(document).on("pagecontainershow", function () {
var activePage = $.mobile.pageContainer.pagecontainer("getActivePage");
var activePageId = activePage[0].id;
switch (activePageId) {
case 'pageGallery':
$(document).on("tap", "#lightgallery li", function (){
$('#lightgallery').lightGallery({});
});
}
});
You might be using wrong html markup. you can check the following code for reference. This is sample code.
HTML
<div class="row">
<div class="large-12 columns">
<ul class="small-block-grid-2 medium-block-grid-3" id="lightgallery">
<li> <a class="item" href="img/alchemy_icon1.jpg"><img src="img/alchemy_icon1_th.jpg"></a>
</li>
<li> <a class="item" href="img/chandra1.jpg"><img src="img/chandra1-th.jpg"></a>
</li>
<li> <a class="item" href="img/Fish.jpg"><img src="img/Fish-th.jpg"></a>
</li>
</ul>
</div>
</div>
Javascript
$("#lightgallery").lightGallery({
selector: '.item'
});
It's 3:40AM and I'm going to give up trying for tonight.
The tabs will not update the page outside of the navigation area.
The PanelController looks like this:-
app.controller('PanelController', function($scope) {
$scope.tab = 1;
$scope.selectTab = function(setTab) {
$scope.tab = setTab;
};
$scope.isSelected = function(checkTab) {
return $scope.tab === checkTab;
};
});
and the nav pane looks like this:-
<div class="navbar-collapse collapse" ng-controller="PanelController">
<ul class="nav navbar-nav navbar-right">
<li ng-class="{ active:isSelected(1) }">
<a href ng-click="selectTab(1)">Blog</a>
</li>
<li ng-class="{ active:isSelected(2) }">
<a href ng-click="selectTab(2)">About{{tab}}</a>
</li>
<li ng-class="{ active:isSelected(3) }">
<a href ng-click="selectTab(3)">Contact</a>
</li>
</ul>
</div>
and the placeholder HTML for my two tabs is as follows:-
<div ng-controller="PanelController">
<div ng-show="isSelected(1)">
<p>Hello</p>
</div>
<div ng-show="isSelected(2)">
<p>Please work</p>
</div>
</div>
As you can see, the {{tab}} next to 'About' in my navbar is updating in my view as I click the tabs, as is the active class. When I place a {{tab}} expression outside of the navbar it isn't updating whenever it's clicked. Obviously this is something related to the scope of the variable, but I am using the PanelController on the parent of both the nav and my main area.
I can't see what I'm doing wrong.
I'd appreciate a fresh pair of eyes -- I've already some help with this already and any more will be graciously accepted.
The problem diagnosis is fairly simple, 2 controllers means 2 instances that each have their own scope
You would need to use a service or events to have them communicate together