Getting null result on page using angularjs function call - javascript

call other page on finish click event :-
<a class="btn btn-default finish" style="display:none" ng-click="result()" onclick="alert('Thank you ..');">Finish</a>
My html code look like below for other page :-
<div class="tab-pane fade" id="messages" ng-init="result()">
<div class="all_ques_back col-md-12" ng-repeat="ans in correctAnswer">
<div class="col-xs-1 col-md-1"><i class="fa fa-times-circle fa-2x col_padd wrong_ans_font"></i></div>
<div class="col-xs-9 col-md-10 col_padd"><div class="all_ques" ng-repeat=" (key, val) in ans">hello your ans {{val}}</div></div>
<div class="col-xs-1 col-md-1 col_padd"><i class="fa fa-angle-right right_arrow"></i></div>
</div>
</div>
and my controller code look like below :-
$scope.correctAnswer = [];
$scope.result = function () {
$(".optionlist").find("li").each(function () {
if ($(this).attr('id') == 'true') {
var label = $(this).parent('ul').attr('que-label');
var value = $(this).find('input[type=checkbox]').attr('value');
$scope.correctAnswer.push({ "label": label }, { "Option": value });
}
});
console.log($scope.correctAnswer);
$location.path("/reviewans");
}

The function on the controller are looking for a "li" tag, but on html you define the ngRepeat on a "div" tag. The ngRepeat will repeat all the HTML code at tag it's defined on. So, you can try:
<div class="col-xs-9 col-md-10 col_padd"><ul><li class="all_ques" ng-repeat=" (key, val) in ans">hello your ans {{val}}</li></ul></div>
Like Okazari commented, don't use Jquery inside your angularJs code. I recommend to take a time to read angularJS docs. It's pretty easy to learn. And about ngRepeat, you can see here.

Related

My single page application which is implemented using AngularJS is taking long time to load the page

I am working on the Single page application and using AngularJS. In my application, all DOM elements get loads using ajax and due to this I have used number of ng-repeat and binding expression and this is the reason my page is taking long time to load the page. Please help to solve my issue.
app
angular.module('tabApp', []);
Service
angular.module('tabApp')
.service('mrcService', ['$http', function($http) {
this.categories = [];
this.getCategories = function() {
return $http({
method: "GET",
url: 'mrcdata.aspx'
}).success(function(data) {
categories = data;
return categories;
});
};
}]);
Controller
angular.module('tabApp')
.controller('dynamicContentCtrl', ['$scope', 'mrcService', function($scope, mrcService) {
$scope.categories = [];
mrcService.getCategories().then(function(response) {
$scope.categories = response.data.Categories;
});
}]);
HTML code
<div class="main-content container" ng-controller="dynamicContentCtrl">
<div ng-controller="desktopTabCtrl" class="row desktop-content">
<div class="col-md-3 col-sm-4 category-items">
<nav class="nav categories-nav">
<ul class="categories">
<li ng-repeat="category in categories" class="category" ng-class="{ active: isSet(category.CategoryRank) }">
<a href="javascript:void(0)" ng-click="setTab(category.CategoryRank)" class="text">
<span>{{category.CategoryTitle}}</span>
</a>
<span class="arrow-right"></span>
</li>
<li class="category static">
<C5:LocalLiteral runat="server" Text="mrc.home.learnmoretab"/>
</li>
</ul>
</nav>
</div>
<div class="col-md-9 col-sm-8 document-tiles">
<div ng-repeat="category in categories" ng-show="isSet(category.CategoryRank)" class="tile-container">
<div class="row">
<div ng-repeat="document in category.Documents" class="col-md-6 col-sm-6 tile">
<div class="tile-content row">
<div class="col-md-12 col-sm-12">
<div class="thumbNail-content col-md-6 col-sm-6">
<p class="title">{{document.DocumentTitle}}</p>
<p class="audience">{{document.Audience}}</p>
</div>
<div class="thumbNail-image col-md-6 col-sm-6">
<img alt="Thumb Nail" src="{{document.ThumbnailUrl}}">
</div>
</div>
<div class="col-md-12 col-sm-12">
<div class="download-section">
<select class="lang-dropdwn"
ng-model="document.DefaultDialectId"
ng-change="selectLang(document , document.LocalizedDocuments , document.DefaultDialectId )">
<option ng-repeat="localizedDocument in document.LocalizedDocuments"
value="{{localizedDocument.DialectId}}">
{{localizedDocument.LanguageName}}
</option>
</select>
</div>
<div class="button-conatiner" ng-init="document.DownloadLink = document.DocumentId +':'+document.DefaultLocalizedDocumentId">
<a class="button" href="documentdownloader.aspx?documentid={{document.DownloadLink}}"><C5:LocalLiteral runat="server" Text="basket.esddelivery"/></a>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Here's a few options you can try to improve performance.
1. You should set the track by in the ng-repeats
To minimize creation of DOM elements, ngRepeat uses a function to "keep track" of all items in the collection and their corresponding DOM elements. For example, if an item is added to the collection, ngRepeat will know that all other items already have DOM elements, and will not re-render them.
The default tracking function (which tracks items by their identity) does not allow duplicate items in arrays. This is because when there are duplicates, it is not possible to maintain a one-to-one mapping between collection items and DOM elements.
If you do need to repeat duplicate items, you can substitute the default tracking behavior with your own using the track by expression.
For example, you may track items by the index of each item in the collection, using the special scope property $index.
Example:
<div ng-repeat="item in items track by $index">{{item.name}}</div>
2. You could use one way data binding to items you know wont be changed. This will disable the watchers for those items and improve performance. Example:
Instead of this
{{item.name}}
Use this
{{::item.name}}
Please remember that this is a one way binding and these values will not be updated if something changes in your scope but you will need to manually update it.
3. Try to limit the ng-show and ng-hide attributes since this will add more watchers and leads to poor performance.

How do I access ng-show directive with ng-click? AngularJS

I just started learning so I'm creating a todo app.
I'm trying to show a div when I click on the edit button to edit my task.
this is my html
<div ng-controller='TasksCtrl'>
<div ng-repeat='(key, task) in tasksList' class='task-list'>
<div class='easy'>
<div class='div-list-style'></div>
<div id='task-{{key}}' style='cursor:pointer;z-index:5'
ng-click='editTask()' data-key='{{key}}' class='options
pull-right glyphicon glyphicon-pencil'>
</div>
<div class='task-desc' ng-bind='task.description'></div>
<div ng-hide='taskEdit = true'>FORM</div>
</div>
</div>
</div
This is my controller
todoApp.controller('TasksCtrl',['$scope', 'saveTaskService', function($scope, saveTaskService){
$scope.editTask= function(){
todoApp.directive('taskEdit', function(){
return function(scope, element){
//so I guess over here I need do ngHide = 'false' ? //
alert(element.attr('data-key'));
};
});
};
}]);
Here is a quick solution, you have a scope variable called taskShow that will tell ng-hide when to show it, then on ng-click you will trigger a function that will toggle that value:
<div ng-controller='TasksCtrl'>
<div ng-repeat='(key, task) in tasksList' class='task-list'>
<div class='easy'>
<div class='div-list-style'></div>
<div id='task-{{key}}' style='cursor:pointer;z-index:5'
ng-click='toggleHide(key)' data-key='{{key}}' class='options
pull-right glyphicon glyphicon-pencil'>
</div>
<div class='task-desc' ng-bind='task.description'></div>
<div ng-show='taskShow[key]'>FORM</div>
</div>
</div>
</div>
Controller:
todoApp.controller('TasksCtrl',['$scope', 'saveTaskService', function($scope, saveTaskService){
$scope.taskShow = {};
$scope.toggleHide = function (key) {
$scope.taskShow[key] = !$scope.taskShow[key];
};
}]);
Edit: switched ng-hide to ng-show so the divs are hidden by default and only shown when the other is clicked.

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>

ng-repeat nested inside Popover not working

I have the following ng-repeat list:
<div class="row msf-row"
ng-repeat="record in recordlist
people-popover>
<div class="col-md-1 msf-centered" ng-show="editItem == false" ng-hide="editItem">
<button class="btn btn-primary form-control msf-paxlist"
rel="popover"
data-content="<li ng-repeat='passanger in record.pax'>
{{passanger.name}}
</li>"
data-original-title="Passanger List">
{{record.pax.length}} <i class="fa fa-user"></i>
</button>
</div>
</div>
I initialize the popover with a directive:
.directive('peoplePopover', function() {
return function(scope, element, attrs) {
element.find("button[rel=popover]").popover({ placement: 'bottom', html: 'true'});
};
})
The problem is the <li ng-repeat="pasanger in record.pax">{{pasanger.name}}</li>, which will not show.
If I use <li ng-repeat="record.pax">{{pax}}</li>, it will display the array, but if I try to list the objects of the array with ng-repeat, it won't work.
This is how the array (record) looks like:
record in recordlist {
date : "02/12/2014"
time : "00.02.01"
car : "369"
pax: [
{
name : "Ben"
chosen : true
},
{
name : "Eric"
chosen : true
}
]
}
Any tips?
I ran into similar problem and I solved it this way.
I wrapped the ng-repeat block in another directive and pass the collection to that external directive.
div class="row msf-row"
ng-repeat="record in recordlist
people-popover>
<div class="col-md-1 msf-centered" ng-show="editItem == false" ng-hide="editItem">
<button class="btn btn-primary form-control msf-paxlist"
rel="popover"
data-content="<new-directive records=record.pax></new-directive>"
data-original-title="Passanger List">
{{record.pax.length}} <i class="fa fa-user"></i>
</button>
</div>
</div>
Inside the new directive, you will have this code.
<li ng-repeat='passanger in record.pax'>
{{passanger.name}}
</li>
Hopefully this helps someone who runs into similar problem.

Categories

Resources