Angular Bootstrap UI - Only collapsing one element - javascript

I am using the angular bootstrap UI library:
https://angular-ui.github.io/bootstrap/
to create a collapsable feature on my site. The functionality itself is working, but it will expand/collapse every element I have the collapse feature on, instead of just the unique element that is clicked.
Here is my code:
var app = angular.module('someApp', ['ui.bootstrap']);
app.controller('collapseController', ['$scope', function ($scope) {
$scope.isCollapsed = true;
};
.passInfoDropdown {
margin-top: 10px;
margin-bottom: 10px;
margin-left: 5px;
font-weight: bold;
}
.dividerLine {
background-color: #DED7CF;
height: 2px;
}
.passInfoTableCellLeft {
width: 220px;
}
<div class="dividerLine"></div>
<div class="click" ng-click="isCollapsed = !isCollapsed">
<table>
<tr>
<td class="passInfoTableCellLeft"><div class="passInfoDropdown inline">TSA Information (optional)</div></td>
<td><i class="fa fa-chevron-down inline"></i></td>
</tr>
</table>
<div collapse="isCollapsed">
<div class="well well-lg">Some content</div>
</div>
</div>
<div class="dividerLine"></div>
<div class="click" ng-click="isCollapsed = !isCollapsed">
<table>
<tr>
<td class="passInfoTableCellLeft"><div class="passInfoDropdown inline">Loyalty Programs (optional)</div></td>
<td><i class="fa fa-chevron-down inline"></i></td>
</tr>
</table>
<div collapse="isCollapsed">
<div class="well well-lg">Some content</div>
</div>
</div>
How can I make it so just the unique element i click collapses?

At the moment both isCollapsed refer to the same propertie on your $scope object. If you want those to be separed, I see two options.
Two properties in the scope
$scope.isCollapsedContent1 = true;
$scope.isCollapsedContent2 = true;
or
$scope.isCollapsed = {};
$scope.isCollapsed['content1'] = true;
$scope.isCollapsed['content2'] = true;
Two ng-model
If you do not need to know whether the content is collapsed or not in your controller, you might as well put the isCollapsed value into your html and remove the propertie of your $scope.
<div class="click" ng-click="isCollapsedContent1 = !isCollapsedContent1" ng-model="isCollapsedContent1" ng-init="isCollapsedContent1=true">

Brandon, HI there. It also looks (in the full snippet code) like you have left out these....
<html ng-app="ui.bootstrap.demo">
and
<div ng-controller="CollapseDemoCtrl">
Have a look at the working Fiddle.

Related

Paginate an AngularJS data table

I have gathered some JSON (dummy) data in a users table.
var root = 'https://jsonplaceholder.typicode.com';
// Create an Angular module named "usersApp"
var app = angular.module("usersApp", []);
// Create controller for the "usersApp" module
app.controller("usersCtrl", ["$scope", "$http", function($scope, $http) {
var url = root + "/users"
$http.get(url)
.then(function(data) {
$scope.users = data.data;
});
}]);
.search-box {
margin: 5px;
}
.panel-heading {
font-weight: bold;
}
.table-container .panel-body {
padding: 0;
}
.table-container table tr th {
font-weight: bold;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<div class="container" data-ng-app="usersApp">
<div class="panel panel-default table-container">
<div class="panel-heading">Users</div>
<div class="panel-body" data-ng-controller="usersCtrl">
<div class="row">
<div class="col-sm-12">
<div class="form-group search-box">
<input type="text" class="form-control" id="search" placeholder="Search User" data-ng-model="search">
</div>
</div>
<div class="col-sm-12">
<table class="table table-striped" id="dataTable">
<thead>
<tr>
<th>Full name</th>
<th>Email</th>
<th>City</th>
<th>Street</th>
<th>Suite</th>
</tr>
</thead>
<tbody>
<tr data-ng-repeat="user in users|filter:search">
<td>{{user.name}}</td>
<td>{{user.email}}</td>
<td>{{user.address.city}}</td>
<td>{{user.address.street}}</td>
<td>{{user.address.suite}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
The table has only 10 rows but, in a real-world app, there is a lot more data to manage so it needs to be paginated. The above one could have 3 rows per page (except the 4th one, which should have one).
Question(s):
Does AngularJS have a built-in, easy way to paginate such a table?
If not, what are the best alternatives?
Angularjs don't have built-in pagination feature. You have to use some third-party modules like angular-ui-grid. OR you can try this <https://codepen.io/khilnani/pen/qEWojX>
You can use ngInfiniteScroll for pagination. https://sroze.github.io/ngInfiniteScroll/

the passed value didn't show on my popup window using angularjs and bootstrap

using angularjs and bootstrap,
I am tring to edit the table row as popup window but I couldn't pass the edite fields to the window
this is my code
controller.js
this.openUser = function(row) {
$scope.user = row;
var userInstance = $uibModal
.open({
animation : $scope.animationsEnabled,
templateUrl : './user_model',
controller : 'userModelController',
backdrop : true,
windowClass: 'monitoring-modal',
resolve : {
row: function () {
return row;
}
}
});
};
and this is my modal controller
angular.module('users').controller('userModelController', ['$scope', 'row',
function($scope ,row) {
this.row = row
} ]);
and this is my popup window html
<div class="modal-header">
<h3 class="modal-title">Users</h3>
</div>
<div class="modal-body">
<table class="table table-bordered" style="height: 350px; border-collapse:collapse;">
<thead>
<tr class="modal-body">
<th class="col-md-1" style="text-align: center; vertical-align: middle;"> {{ row }} </th>
<th class="col-md-1" style="text-align: center; vertical-align: middle;"> last name </th>
</thead>
</table>
</div>
<div class="modal-footer">
<button class="btn btn-primary" type="button" ng-click="ok()">OK</button>
<button class="btn btn-warning" type="button" ng-click="cancel()">Cancel</button>
</div>
but what I get in my window is blank value
You have set the row on this.
Try setting the row on $scope.
$scope.row = row;
I haven't used ui-bootstrap modal lately, but I don't think it supports controllerAs syntax. At least not with your current configurations.
EDIT: Turns out, it does support controllerAs syntax: https://stackoverflow.com/a/23806963/841804
And even if it does support it, you should then be binding to <controler-as-name>.row, shouldn't you?

Adding objects to the DOM after adding new data to the list

I have an array of objects which i populate on a button click.
When populating this array i make sure that i only add 10 objects to it.
When this is all loaded in the dom i give the user the oppertunity to add a few more objects.
I do this like this:
$scope.Information = [];
$.each(data, function (i, v) {
if (i<= 9)
$scope.Information.push(data[i]);
if(i >= 10) {
cookieList.push(data[i]);
}
}
if (cookieList.length) {
localStorage.setItem("toDoList", JSON.stringify(cookieList));
$(".showMore").removeClass("hidden");
}
$(".showMore").on("click", function() {
var obj = JSON.parse(localStorage.getItem("toDoList"));
console.log(obj);
console.log(obj.length);
SetSpinner('show');
$scope.Information.push(obj);
SetSpinner('hide');
//$.removeCookie("toDoList2");
});
part of the HTML:
<div ng-repeat="info in Information" class="apartment container" style="padding-right:35px !important">
<div class="row" style="height:100%">
<div class="col-md-1 col-xs-12">
<div>
<h4 class="toDoListHeadings">Nummer</h4>
<div style="margin-top: -15px; width:100%">
<span class="toDoListItems number">
{{info.orderraderid}}
</span>
</div>
</div>
</div>
</div>
</div>
My issue: When i add objects to my array of objects "$scope.Information.push(obj);" I assumed that they would get added in the DOM but they do not, how do i do this the angular way?
EDIT MY SOLOUTION:
edited the HTML to use ng-click and the method is as follows:
$scope.addMore = function() {
var obj = JSON.parse(localStorage.getItem("toDoList"));
SetSpinner('show');
$.each(obj, function(i,v) {
$scope.Information.push(v);
});
SetSpinner('hide');
}
Here is the angular way:
 The view
<!-- Reference your `myapp` module -->
<body data-ng-app="myapp">
<!-- Reference `InfoController` to control this DOM element and its children -->
<section data-ng-controller="InfoController">
<!-- Use `ng-click` directive to call the `$scope.showMore` method binded from the controller -->
<!-- Use `ng-show` directive to show the button if `$scope.showMoreButton` is true, else hide it -->
<button data-ng-click="showMore()" data-ng-show="showMoreButton">
Show more
</button>
<div ng-repeat="info in Information" class="apartment container" style="padding-right:35px !important">
<div class="row" style="height:100%">
<div class="col-md-1 col-xs-12">
<div>
<h4 class="toDoListHeadings">Nummer</h4>
<div style="margin-top: -15px; width:100%">
<span class="toDoListItems number">
{{info.orderraderid}}
</span>
</div>
</div>
</div>
</div>
</div>
</section>
</body>
The module and controller
// defining angular application main module
var app = angular.module('myapp',[])
// defining a controller in this module
// injecting $scope service to the controller for data binding with the html view
// (in the DOM element surrounded by ng-controller directive)
app.controller('InfoController',function($scope){
$scope.Information = [];
$scope.showMoreButton = false;
// Bind controller method to the $scope instead of $(".showMore").on("click", function() {});
$scope.showMore = function(){
var obj = JSON.parse(localStorage.getItem("toDoList"));
console.log(obj);
console.log(obj.length);
SetSpinner('show');
$scope.Information.push(obj);
SetSpinner('hide');
//$.removeCookie("toDoList2");
};
$.each(data, function (i, v) {
if (i<= 9) $scope.Information.push(data[i]);
if(i >= 10) cookieList.push(data[i]);
});
if (cookieList.length) {
localStorage.setItem("toDoList", JSON.stringify(cookieList));
//$(".showMore").removeClass("hidden");
$scope.showMoreButton = true; // use $scope vars and ng-class directive instead of $(".xyz").blahBlah()
}
});
You should not use JQuery, use ng-click to detect the click, because angular has no idea when JQuery is done and when it needs to refresh the interface

Reset data on click for a different controller

I have two divs - the first contains the second. The contained div has its own controller. When I click an icon button in the container, I change a variable which then affects the visibility of the contained div.
It looks like this:
<div ng-controller="BarController">
<div class="navbar navbar-default navbar-fixed-top">
<div class="container-fluid">
<div class="col-lg-2 page-title">My Page</div>
<div class="col-lg-10">
<span class="actions">
<i class="fa fa-lg fa-download fa-inverse" tooltip="Download"
ng-click="showSecondaryBar=!showSecondaryBar"></i>
</span>
</div>
</div>
</div>
<div class="download navbar download-in download-out"
ng-class="{'myhidden': !showSecondaryBar}"
ng-cloak>
<div class="col-lg-offset-4 col-lg-4 form-inline form-group" ng-controller="TagsController">
<div class="download-label col-lg-6">
<label>Download by tags:</label>
</div>
<div class="download-tags col-lg-6">
<tags-input class="bootstrap" spellcheck="false" min-length="1" ng-model="tags" add-from-autocomplete-only="true">
<auto-complete source="loadTags($query)" min-length="1" load-on-down-arrow="true"
load-on-focus="true" max-results-to-show="5"
highlight-matched-text="false"></auto-complete>
</tags-input>
</div>
</div>
</div>
</div>
The <tags-input> is taken from ng-tags-input and I would like to reset the tags that were already typed to it whenever the icon button is clicked (which changes the visilibyt of the div that contains the ng-tags-input).
Problem is, because I have the TagsController which contains the data (tags) and this data is not visible in the BarController, I'm not sure how I can reset the tags array to become empty.
I thought of using a service but it fills like too much of a coupling. I would prefer to have a function in TagsController which is called upon click. But I can't figure out how to do it from another controller
You are right you have to use a service.
Why don't you use a broadcast as your TagsController is included in BarController?
You can include a scope.broadcast("Event") in BarController
Then a "on" listener on TagsController who will reset the tags array when "Event" Occur.
I would personnaly to this.
https://docs.angularjs.org/api/ng/type/$rootScope.Scope
You can use $broadcast on $rootScope to send an event to TagsController. So TagsController can receive this event by registering an event listener for it. See following example.
Refer to $rootScope API docs
angular.module('app',[])
.controller('ParentController', function($rootScope) {
var parentCtrl = this;
parentCtrl.someFlag = true;
parentCtrl.changeFlag = function() {
parentCtrl.someFlag = !parentCtrl.somFlag;
$rootScope.$broadcast('resettags', {'defaultTags': 'whatever_tag'});
}
})
.controller('ChildController', function($rootScope){
var childCtrl = this;
childCtrl.tags = "Some tags entered by user";
$rootScope.$on('resettags', function(event, args) {
childCtrl.tags = args.defaultTags;
});
});
.myHidden {
display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="app">
<div id="main" ng-controller="ParentController as parentCtrl">
<button type="button" ng-click="parentCtrl.changeFlag()">Toggle</button>
<div ng-class="{'myHidden' : !parentCtrl.someFlag}">
<div ng-controller="ChildController as childCtrl">
<h1>{{childCtrl.tags}}</h1>
</div>
</div>
</div>
</div>

Accessing element from click event in jquery widget

I am trying to make a custom widget that creates tabs .But the problem Im facing is ,I have a click event defined on clicking on one of the tabs but I am unable to access the attributes associated with that tab element (like myid="summarytab")
Here is a code snippet for the same
jquery.tabs.js
$.widget('ui.tabs', {
options: {
},
_create: function() {
alert('attaching')
var me = this
me._on('td', {
click: "_selectedTab"
})
},
_selectedTab: function(el) {
alert("coming" + el.attr('goto'))
},
_destroy: function() {
}
});
jstChking.html
<table id="tabs-container" goto="summary">
<tbody>
<tr class="a-detail-menu">
<td myid="summary" goto="summary" class="selected">
<i class="fa fa-bank deco"></i>
Summary
</td>
<td goto="applicability" myid="applicabilityTab" >
<i class="fa fa-tags deco"></i>
Applicability
</td>
<td goto="assessments" myid="assessmentTab">
<i class="fa fa-check-circle-o deco"></i>
Assessments
</td>
<td class="ignore"></td><td class="ignore"></td>
</tr>
</tbody>
</table>
<div class="a-section summary" >
<h2>HTML Markup for these tabs</h2>
content1
</div>
<div class="a-section applicability" style="display:none">
<h2>JS for these tabs</h2>
content2
</div>
<div class="a-section assessments" style="display:none">
<h2>CSS Styles for these tabs</h2>
content3
</div>
The idea is to hide all tabs and show the one that is clicked.I am trying to do that in jquery using the goto="xyz" and and show only that div. Now when i m trying to make in widget then i m not getting the attribute.Also if u have any suggestions ,that would be welcome.
Thanks in advance

Categories

Resources