AngularJS ng-repeat show spinners - angularjs

I have the following code. The goal is, to show spinner for each clicked <span> - but it doesn't show. Why ?
<tr ng-repeat="cat in myItems">
<td>
<div class='spinner' ng-show="{{cat.loading}}">
<img src='/Content/loading.GIF' alt=''/>
</div>
<div ng-click="changeItem(cat)" class="contentCell">
<span>click me</span>
</div>
</td>
</tr>
controller:
$scope.changeItem = function (cat) {
cat.loading = true;
catService.doSth(cat.id).then(function (data) {
cat.loading = false;
});
}
I see that div has ng-hide class, no matter if ng-show="false" or ng-show="true" it remains there, I think that can be the reason
<div class="spinner ng-hide" ng-show="false">
<img alt="" src="/Content/loading.GIF">
</div>

Try to remove the {{}} in the ng-show, it evaluates an expression, not a value .
<tr ng-repeat="cat in myItems">
<td>
<div class='spinner' ng-show="cat.loading">
<img src='/Content/loading.GIF' alt=''/>
</div>
<div ng-click="changeItem(cat)" class="contentCell">
<span>click me</span>
</div>
</td>
</tr>

Try This:
$scope.cat = false;
$scope.changeItem = function (cat) {
$scope.cat.loading = true;
catService.doSth(cat.id).then(function (data) {
$scope.cat.loading = false;
});
}
You are trying to react the $scope.cat but it does not exist

Related

Edit input after getting all data angular

I have function in my controller where I retrieve all my data from database (id,name,surname,emai,review):
function loadAll() {
UniversalService.GetAll()
.then(function (a) {
$scope.all=a;
});
}
then I print it like this in html:
<div class="row comment-table" ng-repeat="item in all ">
<div class="col-md-1">
<img ng-src="http://www.gravatar.com/avatar/{{hash[$index]}}" alt="Description" />
</div>
<div class="col-md-9">
<p>Review posted by: {{item.name}}</p>
<p>{{item.review}}</p>
<span uib-rating ng-model="rate" max=5 on-hover="hoveringOver(value)" on-leave="overStar = null" titles="['one','two','three']" aria-labelledby="default-rating"></span>
<span class="label" ng-class="{'label-warning': percent<30, 'label-info': percent>=30 && percent<70, 'label-success': percent>=70}" ng-show="overStar && !isReadonly">{{percent}}%</span>
</div>
</div>
Now, I added edit and delete buttons for each review. But I am not sure how to actually edit specific review beause I need to have these values inside inputs and how to delete them. Is it possible when I printed my values with loadAll() ?
By using the $index.
In you html:
<div class="row comment-table" ng-repeat="item in all ">
<div class="col-md-1">
<img ng-src="http://www.gravatar.com/avatar/{{hash[$index]}}" alt="Description" />
</div>
<div class="col-md-9">
<p>Review posted by: {{item.name}}</p>
<p>{{item.review}}</p>
<button ng-click="edit($index)">Edit</button>
<button ng-click="delete($index)">Delete</button>
</div>
</div>
Then in your controller:
$scope.edit = function(index) {
$scope.all[index] = // Your logic here.
};
$scope.delete = function(index) {
$scope.all[index] = // Your logic here.
};

How to switch from one tab to another in angularjs?

How do i switch from one tab to another tab in angular js? I am using multiple divs for creating tabs. I want to switch from one tab to another by click on button.
This is part of my code -
<div ng-controller="MyController">
<div class="tabgroup" ng-init="tab=1">
<div class="tab" ng-class="{selected: tab==1}" ng-click="tab = 1">Home</div>
<div class="tab" ng-class="{selected: tab==2}" ng-click="tab = 2">Display Records</div>
<div class="tab" ng-class="{selected: tab==3}" ng-click="tab = 3">Add Records</div>
<div class="tab" ng-class="{selected: tab==4}" ng-click="tab = 4">Remove Records</div>
</div>
<div class="otherContainer">
<div class="tabcontents">
<div ng-show="tab == 1">
This application shows employee details registered for this site. You can add your records by clicking on add button. Also you can update and delete records.
</div>
<div ng-show="tab == 2">
<table border=1>
<thead>
<th>Id</th>
<th>Name</th>
<th>Birthdate</th>
<th>Address</th>
<th>Contact</th>
<th>Email</th>
</thead>
<tr data-ng-repeat="Emp in EmpList">
<td ng-bind="Emp.Id"></td>
<td ng-bind="Emp.Name"></td>
<td ng-bind="Emp.Birthdate"></td>
<td ng-bind="Emp.Address"></td>
<td ng-bind="Emp.Contact"></td>
<td ng-bind="Emp.Email"></td>
<th><input type="button" ng-click="removeItem()" value="Remove" /></th>
<th><input type="button" ng-click="editItem(i)" value="Edit" /></th>
</tr>
</table>
</div>
You can refer the following sample
//in your controller
// code to switch you views based on tabs
$scope.onep = true; // sets bydefault true on div
$scope.one = function() {
$scope.onep = true;
$scope.twop = false;
$scope.threep = false;
}
//follow as above for funcions two() and three()
//your tabs
<div ng-click=one()>
//div content
</div>
<div ng-click=two()>
//div content
</div>
<div ng-click=three()>
//div content
</div>
<p ng-show=onep></p>
<p ng-show=twop></p>
<p ng-show=threep></p>
Using JavaScript for this problem will easily solve the problem.
<div class="tab" data-target="#tab1" ng-class="{selected: tab==1}" ng-click="goToTab(1)">Home</div>
In your controller
$scope.goToTab = function(tabIndex) {
$scope.tab = tabIndex;
angular.element('[data-target="#tab'+tabIndex+'"]').tab('show');
}

Edit many same name isolated variables at a time in Angularjs

I have a table. Each cell can hold its value as a string or the edit in place template for that datatype.
I render one thing or the other based on the value of the variable "ttt" of that table cell. If ttt=true it renders the editing template if false it renders the value as string.
The way things are set up you can toggle between true and false of a specific cell each time you double-click on it.
I wish to have as well a button at top of the page that toggles all the "ttt" variables between true or false at the same time for all the table cells.
What is the best way to do this the way I have things set up.
Here is the template of the table:
<script type="text/ng-template" id="editabletable">
<div ng-controller="listeditorController" cg-busy="{promise:myPromise, message:' '}">
<div tasty-table bind-resource-callback="getResource" bind-init="init" bind-filters="filterBy">
<div class="table-responsive" style="width:100%;">
<table class="superResponsive" adapt-table style="width:{{theWidth}};margin:0 auto;">
<thead>
<!-- <thead tasty-thead bind-not-sort-by="notSortBy"></thead> -->
<tr>
<th style="max-width:{{columnWidth}}px;" ng-repeat="attobj in rows[0].class_attributes()">
{{ attobj.label }}
</th>
</tr>
<tr>
<td style="max-width:{{columnWidth}}px;" ng-repeat="attobj in header.columns track by $index">
<input ng-if="attobj.filterable" type="text" class="form-control input-sm" ng-model="filterBy[attobj.filterkey || attobj.key]" ng-model-options="{ debounce: 2000 }" />
</td>
</tr>
</thead>
<tbody>
<tr ng-repeat="dbo in rows">
<td style="max-width:{{columnWidth}}px;" ng-repeat="attobj in header.columns" ng-dblclick="ttt=!ttt">
<div>
<form name="theForm" novalidate>
<div ng-if="ttt" ng-init="attobj = attobj.attobj" ng-include src="getAttValuesEditorTemplate(dbo, attobj)">
</div>
</form>
<div ng-if="!ttt" ng-repeat="v in dbo.get4(attobj.key) track by $index">
<p ng-if="v.cid">{{ v.displayName() }}</p>
<p ng-if="!v.cid">{{ v }}</p>
</div>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<div tasty-pagination bind-list-items-per-page="listItemsPerPage" bind-items-per-page="itemsPerPage" bind-template-url="'/templates/table/pagination.html'"></div>
</div>
</div>
</script>
Ok, the solution I came up with is fairly simple but SLOW.
I added a controller at the table level which defines a scope variable "editGird" defined on load as "false".
On click of the button "Edit gird" the scope variable "editGird" toggles between true and false.
If set to true the cell is rendered like:
<td ng-if="editGird==true" style="max-width:{{columnWidth}}px;" ng-repeat="attobj in header.columns">
<div>
<form name="theForm" novalidate>
<div ng-init="attobj = attobj.attobj" ng-include src="getAttValuesEditorTemplate(dbo, attobj)">
</div>
</form>
</div>
</td>
If editGird == false:
<td ng-if="editGird==false" style="max-width:{{columnWidth}}px;" ng-repeat="attobj in header.columns" ng-dblclick="ttt=!ttt">
<div>
<form name="theForm" novalidate>
<div ng-if="ttt" ng-init="attobj = attobj.attobj" ng-include src="getAttValuesEditorTemplate(dbo, attobj)">
</div>
</form>
<div ng-if="!ttt" ng-repeat="v in dbo.get4(attobj.key) track by $index">
<p ng-if="v.cid">{{ v.displayName() }}</p>
<p ng-if="!v.cid">{{ v }}</p>
</div>
</div>
</td>
Controller:
app.controller('editGirdController', ['$scope',
function ($scope) {
$scope.editGird= false;
$scope.onOff = function() {
if ($scope.editGird == true){
$scope.editGird = false;
$scope.editGirdColor ='#0887A7';
} else{
$scope.editGird = true;
$scope.editGirdColor ='lightGreen';
}
console.log($scope.editGird);
console.log($scope);
}
}
]);
But this is very very slow!!!
On tables which have 25-35 columns it takes 1 second for each 5 rows to render!!!
How can I make this more efficient???

Loading partial view into the main view AngularJS

I have a partial view, which I plan to include in different pages.
I tried out the following to load the partial view but the view doesn't display the values stored in the model.
Angular controller:
//This gets the required data as JSON
AdminService.getSettings(function (callback) {
$scope.attributes = callback;
$scope.groups = _.groupBy($scope.attributes, "Group");
$scope.previous = angular.copy($scope.attributes);
//This gets the partial view and adds to the main view
CommonService.SettingsListView_get(function (callback) {
angular.element('#settingsList').html(callback);
});
});
MVC Controller:
public ActionResult SettingsList()
{
return PartialView();
}
View: Main
<body ng-app="AngularAdmin" ng-cloak>
<div ng-controller="SettingsCtrl" id="top" ng-init="init()">
<br />
<div id="settingsList" >
</div>
View:partial
<div class="panel-group" id="accordion">
<div style="padding:5px 0"><button ng-click="updateAttributes(attributes)" class="btn btn-primary"><span class="glyphicon glyphicon-floppy-disk"></span> Update Settings</button></div>
<div class="panel panel-primary" data-ng-repeat="(items, item) in groups" ng-style="$index < 11 ? panelStyle[$index] : commonPanelStyle">
<div class="panel-heading" ng-style="$index < 11 ? panelHeaderStyle[$index] : commonPanelHeaderStyle">
<a data-toggle="collapse" href="#accordion{{$index}}" ng-style="anchorStyle">
<h4 class="panel-title">
{{ items }}
</h4>
</a>
</div>
<div id="accordion{{$index}}" class="panel-collapse collapse">
<div class="panel-body" ng-style="$index < 11 ? panelBodyStyle[$index] : commonPanelBodyStyle">
<table class="table">
<tr>
<th>Attribute</th>
<th>Description</th>
<th>Value</th>
<th>Taken from</th>
<th>Editable</th>
<th>Delete</th>
</tr>
<tr data-ng-repeat="i in item">
<td> {{ i.AttributeName }} </td>
<td> {{ i.Description }} </td>
<td> <input type="text" ng-model="i.Value" class="form-control" ng-disabled="{{!i.Editable}}" />
</td>
<td><span ng-bind="i.TakenFrom | settingsfilter">{{ Heritage }}</span> </td>
<td><span ng-class="i.Editable | activefilter : { icon1 : 'glyphicon-edit', icon2 : 'glyphicon-remove'}" class="glyphicon" style="font-weight: bolder"></span></td>
<td><span ng-click="deleteAttribute(i.AttributeGuid)" ng-class="i.TakenFrom | deletefilter : 1" class="glyphicon" style="font-weight: bolder"></span></td>
</tr>
</table>
<button style="float:right" class="btn btn-default" ng-click="updateAttributes(item)"><span class="glyphicon glyphicon-floppy-disk"></span> Update <em>{{ items }}</em> Settings </button>
</div>
</div>
Issue:
I can't display the settings data I can see {{ items }} and nothing else in the view.
The preferred way to achieve this is to create a "settingsList" directive and set the templateUrl to the url of the partial view. You could get rid of this:
CommonService.SettingsListView_get(function (callback) {
angular.element('#settingsList').html(callback);
});
and replace this:
<div id="settingsList" >
</div>
with this:
<div settingsList></div>
If for some reason this isn't possible in your situation, try changing your controller code the following (you'll need to inject the $compile service):
CommonService.SettingsListView_get(function (callback) {
var element = angular.element(callback);
$compile(element)($scope);
angular.element('#settingsList').append(element);
$scope.digest();
});
this code working good :
CommonService.SettingsListView_get(function (callback) {
var element `enter code here`= angular.element(callback);
$compile(angular.element('#settingsList').append(element))($scope);
});

ng-click not executing controller function

I have a very simple function in one of my angular controllers
$scope.search = function () {
alert("Search");
};
and from my view I have
<button type="button" data-ng-click="search()"><i class="fa fa-search"></i></button>
The function is never executed when the button is clicked, but the rest of the code in my controller is executed as expected. Is there any reason why the ng-click directive will not fire my function?
I have similar controllers all working as expected.
Update
The button is within a bootstrap 3 modal, when the button is moved out of the modal, the click event works. Any reason for this happening?
Update
The button is within scope of the controller, here is my controller and view for clarity
(function () {
var module = angular.module("crest");
var brokerGridController = function ($scope, readEndpoint, readBroker) {
$scope.endpoint = "";
$scope.isBusy = false;
$scope.havebroker = false;
$scope.brokers = [];
$scope.searchCriteria = "";
$scope.exception = "";
var setEndpoint = function (response) {
$scope.endpoint = response.Endpoint;
};
readEndpoint.read("BusinessLogicAPI").then(setEndpoint);
var onSuccess = function (response) {
if (response.Message.MessageType == 1) {
onError();
}
$scope.havebrokers = response.brokers.length > 0;
angular.copy(response.brokers, $scope.brokers);
angular.copy(response.Message.body, $scope.exception);
};
var onError = function () {
$("#errorMessageModal").modal("show");
};
$scope.search = function () {
alert("Search");
};
};
module.controller("brokerGridController", ["$scope", "readEndpoint", "readBroker", brokerGridController]);
}());
and the view
<div data-ng-controller="brokerGridController">
<div>
<div class="col-md-4">
<div class="contacts">
<div class="form-group multiple-form-group input-group">
<div id="searchBrokerDropdown" class="input-group-btn input-group-select">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown">
<span class="concept">Broker Name</span> <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li>Broker Name</li>
</ul>
<input type="hidden" class="input-group-select-val" name="contacts['type'][]" value="phone">
</div>
<input type="text" name="contacts['value'][]" class="form-control" data-ng-model="searchPhrase">
<span class="input-group-btn searchButton">
<button type="button" class="btn btn-success btn-add" data-ng-click="$parent.search()"><i class="fa fa-search"></i></button>
</span>
</div>
</div>
</div>
</div>
<div>
<div class="col-md-12">
#Html.Partial("_Loading", new LoadingViewModel() { DisplayText = "Loading brokers..." })
<div data-ng-show="!isBusy && !haveBrokers">
<h3>No brokers found.</h3>
</div>
<div class="panel" data-ng-show="!isBusy && haveBrokers">
<div class="panel-heading">
<h4 class="panel-title">Brokers</h4>
<div class="pull-right">
<span class="clickable filter" data-toggle="tooltip" title="Filter Brokers" data-container="body">
<i class="fa fa-filter"></i>
</span>
</div>
</div>
<div class="panel-body">
<input type="text" class="form-control" id="task-table-filter" data-action="filter" data-filters="#task-table" placeholder="Filter Tasks" />
</div>
<table class="table table-hover" id="task-table">
<thead>
<tr>
<th>Broker Name</th>
</tr>
</thead>
<tbody>
<tr data-ng-repeat="broker in brokers">
<td>{{ broker.Name }}</td>
<td data-ng-show="searchCriteria != 'PolicyNumberLike'"><i class="fa fa-search"></i> View Policies</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
You have to check 2 things in that situation:
Check if your button is in the front (rise his z-index or check is :hover is working), maybe it is not on top so it can't be clickable.
Check if that buttont dont have own $scope (it is crated in subdirective, or in ng-repeat for example), in taht situation check:
<button type="button" data-ng-click="$parent.search()"><i class="fa fa-search"></i></button>
If that 2 things dosen't work check if any command ex. console.log('test_mode') will fire after click.
It's most likely that the button is outside of controller scope, if you provide model with a specific controller you should put search function inside said controller, if you want to keep it in parent controller specify it like this:
$scope.modalFunctions = {
search: function () {
//do something
}
}
then use ng-click="modalFunctions.search"
Ok, I finally found the problem. My angular view is within a bootstrap wizard component (within a bootstrap modal) that I copied from Bootsnipp. The problem was with the javascript that was supplied,
wizardContent.html(currStep.html());
this piece of code replaced the wizard content with the HTML of the correct step. I modified the javascript to hide and show the correct steps instead of copying the HTML of the correct step to the div displayed to the user, which resolved the issue.

Resources