Angularjs not working after html is added with ajax - javascript

My issue is when I load the page first time the angular is working pretty well. but when I try to use same thing when my html is loaded with ajax it is not working at all. nor I can see any relevant error in console.
javascript:
var myApp = angular.module('myApp', ['ngSanitize','ui.utils']);
myApp.controller('CtrlPerformanceByTrack', function($scope, $http) {
$http.get(site_url + 'performance/?method=get_performance_by_track_data').success(function(data, status) {
/*console.log(data.data);
data=[{"title":"title 1","length":"3:02","plays":4,"sales":2,"likes":8},
{"title":"title 1","length":"3:02","plays":4,"sales":2,"likes":8}]
console.log(data);*/
$scope.tracks = data.data;
}).error(function(data, status) {
$scope.data = data || "Request failed";
$scope.status = status;
});
});
html:
<div data-ele="PerformanceByTrackApp" class="track-block" ng-controller="CtrlPerformanceByTrack">
<div class="title">
Performance by track
</div>
<div class="search-block">
<form>
<div class="content fr">
<div class="left-input">
<input type="text" class="form-control" placeholder="Search Track" ng-model="searchTrack">
</div>
<div class="right-icon-block">
<span class="icon-magnifying42 search-icon"></span>
</div>
</div>
</form>
<div class="clearfix"></div>
</div>
<div class="clearfix"></div>
<div class="table-block">
<table class="table table-striped table-responsive track-table">
<thead class="title">
<th style="width:50%;">Title</th>
<th style="width:13%;">Length</th>
<th style="width:13%;">Plays</th>
<th style="width:13%;">Sales</th>
<th style="width:14%;">Likes</th>
</thead>
<tr ng-repeat="item in tracks | filter:searchTrack">
<td>{{item.title}}</td>
<td>{{item.length}}</td>
<td>{{item.plays}}</td>
<td>{{item.sales}}</td>
<td>{{item.likes}}</td>
</tr>
</table>
</div>
</div>
the sample is at below url:
http://engagev2.ncryptedprojects.com/performance
to call the same page via ajax click performance tab at left.

If you're getting this partial HTML via AJAX, then it should be properly inserted. You have to use angular $compile service. Simplified example below.
...
var template = getTemplate();
var compiledElement = $compile(template)($scope);
element.append(compiledElement);
...
Here is the link https://docs.angularjs.org/api/ng/service/$compile

Related

AngularJS: using jsonplaceholder.typicode.com as a data source does not work

I am new to AngularJS so I got stuck with this small Users application.
Instead of writing the users array of data inside the controller - like I have already done HERE (jsFiddle), sucessfully - I want to use jsonplaceholder.typicode.com as a data source:
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", function($scope) {
$scope.users = root + "/users";
}]);
.search-box {
margin: 5px;
}
.table-container .panel-body {
padding: 0;
}
<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 table-bordered" id="dataTable">
<thead>
<tr>
<th>Full name</th>
<th>Email</th>
<th>City</th>
<th>Street</th>
<th>Suite</th>
<th>Zipcode</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>
<td>{{user.address.zipcode}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
But it does not work, for some reason I can't understand. What am I doing wrong? Thank you!
Update: working fiddle HERE.
var root = 'https://jsonplaceholder.typicode.com'
$scope.users = root + "/users";
Here you have not made any http request to retrieve the data . Here the users variable in scope is only a
string i.e
$scope.users = 'https://jsonplaceholder.typicode.com/users'
The code should be something like this
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 is a service in angular which is used to make REST calls
// we call the url and get the data , which is resolved as a promise
$http.get(url)
.then(function(data){
// after the data is resolved we set it in the scope
$scope.users = data.data;
})
}]);

Angular js post/get in nested ng-repeat

I have a table of info generated by ng-repeat.
I want to add a feature to each row of table which gives user ability to see more detail of that specific record. I added another ng-model which gets the key of that row and asks server for more detail.
But controller cannot read this ng-model. my code is as below:
HTML:
<html ng-app = "myApp">
<head>
...
</head>
<body>
...
<div ng-controller = "AppCtrl">
...
<content>
<div class="general_detail">
<div ng-model = "docParam.docNo"></div>
<div class = "dialog" ng-repeat = 'doc in doclist'>
<table class = "detail">
<tbody>
...
<tr>
...
<td style="text-align: right">
<div ng-model = "docDetail.docNo"></div>
<a href="" ng-click="docDetail.docNo = doc.NO; docDetailP()" >More...</a>
</td>
<td>
<div ng-repeat = 'd in detailView'>
<p>
Rev : {{d.REV_NO}}
</p>
</div>
</td>
</tr>
...
</tbody>
</table>
</div>
</div>
</content>
...
</body>
</html>
Controller:
$scope.docDetailP = function() {
$http.post('/docQuery', $scope.docDetail);
docDetailG();
};
var docDetailG = function() {
$http.get('/docDetails').then(function(response) {
$scope.detailView = response.data;
});
};
Thanks in advance for your solutions.
These are the errors which you made,
<div ng-model = "docParam.docNo"></div>
ng-model will work for form elements
why do you assign docDetail.docNo = doc.NO; and then call the method. Instead you can pass as a parameter
Change the way of posting the value $http.post('/docQuery', $scope.docDetail);.
Have a look at the modified code.
HTML
<content>
<div class="general_detail">
<div ng-model = "docParam.docNo"></div>
<div class = "dialog" ng-repeat = 'doc in doclist'>
<table class = "detail">
<tbody>
...
<tr>
...
<td style="text-align: right">
<div ng-model = ""></div>
<a href="" ng-click="docDetailP(doc.NO)" >More...</a>
</td>
<td>
<div ng-repeat = 'd in detailView'>
<p>
Rev : {{d.REV_NO}}
</p>
</div>
</td>
</tr>
...
</tbody>
</table>
</div>
</div>
</content>
Your controller should be like
$scope.docDetailP=function (number) {
$http({
method: 'POST',
url: '/docQuery',
headers: {
'Content-Type': 'application/json'
},
data: number
})
.success(function (data, status, headers, config) {
successcallback(data);
})
.error(function (data, status, headers, config) {
$log.warn(data, status, headers, config);
})
$scope.docDetailG();
}
Be careful that my solution assumes that the web service endpoint recieves a number.

How can I change the innerHTML of div with a variable, inside the scope function in angular js?

I have 2 HTML pages. In my index.html page you can see products information that comes from JSON file. I need to have detail of product in detail.html page when people click on particular product. Alert can show the details but unfortunately the innerHTML of my <p> does not change, please guide me.
<div ng-app="myApp" ng-controller="AppController">
<div id="serachWrapper">
<h1 id="headerTopic">Our Products</h1>
<input id="searchInput" name="search" type="text" placeholder="Search products" ng-model="searchquery"/>
<table id="searchTable">
<thead id="tbHead">
<tr class="tbRow">
<th class="tbTopics">ID</th>
<th class="tbTopics">Name</th>
<th class="tbTopics">Color</th>
<th class="tbTopics">Type</th>
<th class="tbTopics">Capacity</th>
<th class="tbTopics">Price</th>
</tr>
</thead>
<tbody id="tbBody">
<tr class="tbRow" ng-repeat="x in myData | filter:searchquery ">
<td class="tbcontents" >{{x.id}}</td>
<td class="tbcontents">{{x.name}}</td>
<td class="tbcontents">{{x.color}}</td>
<td class="tbcontents">{{x.type}}</td>
<td class="tbcontents">{{x.capacity}}</td>
<td class="tbcontents">{{x.price}}</td>
</tr>
</tbody>
</table>
</div>
And this is my Angular js code:
var app = angular.module('myApp', ['ngSanitize']);
app.controller('AppController', AppController);
function AppController($scope , $http) {
$http.get("products.json").success(function(myData){
$scope.myData = myData;
$scope.go = function(item){
var detail = item.detail;
var productDetail = angular.element(document.getElementById('product-detail')).html();
productDetail = detail;
alert(detail)
};
});
}
You can keep both codes in the page and to solve this with an ng-if directive
Angular ng-if directive
<body ng-app="ngAnimate">
<label>Click me: <input type="checkbox" ng-model="checked" ng-init="checked=true" /></label><br/>
Show when checked:
<span ng-if="checked" class="animate-if">
This is removed when the checkbox is unchecked.
</span>
</body>
Why is your $scope.go function defined inside the http.get request?
Try:
function AppController($scope , $http) {
$http.get("products.json").success(function(myData){
$scope.myData = myData;
});
$scope.go = function(item) {
var detail = item.detail;
var productDetail = angular.element(document.getElementById('product-detail')).html();
productDetail = detail;
alert(detail)
};
}

angularJS print directive losing 2 way binding

I have a print directive in a SPA that seems to lose its 2 way data binding after the first print function is ran. I am sure it has something to do with the cloning and appending of the element.
The Directive is as follows:
agency.directive("pasPrint", ['AgentModel','Dev',
function(agentModel, dev) {
var printSection = document.getElementById("printSection");
function printElement(elem) {
// clones the element you want to print
var domClone = elem.cloneNode(true);
if (!printSection) {
printSection = document.createElement("div");
printSection.id = "printSection";
document.body.appendChild(printSection);
} else {
printSection.innerHTML = "";
}
printSection.appendChild(domClone);
}
return {
restrict: 'A',
link: function($scope, $element, attrs) {
$scope.printModel = {};
$scope.today = new Date().toJSON().slice(0,10);
$element.on("click", function () {
var elemToPrint = document.getElementById(attrs.printElementId);
if (elemToPrint) {
printElement(elemToPrint);
window.print();
}
});
},
controller: ["$scope","$element", "AgentModel", function($scope, $element, agentModel) {
$scope.agentModel = agentModel;
}]
};
}]);
the model that is used in the entire module here is the agentModel.singleAgent which of course represents a single agent. this directive simply prints a cover sheet for an agents hard copy record. the first time we pull up an agents record the cover sheet prints correctly. when we load another agent the print preview show's the correctly updated agent information. in the agentModel.singleAgent 2 way binding (the same values being used in the printSection that gets printed. However the second print attempt also prints the first agent information and so does any other attempt to print any other agents, they all print the first agents data, even thought the singleAgent model has been updated properly.
the html from the print preview is below:
<div class="modal-header ng-scope">
<button type="button" class="close" aria-label="Close" data-ng- click="cancel()"><span aria-hidden="true"> × </span></button>
<h3 class="modal-title ng-binding"> Edit & Print Cover Sheet </h3>
</div>
<div class="modal-body">
<form class="inline-form">
<div class="form-group">
<label class="form-label" for="PRINT_DESC">File Description: </label>
<input class="input-medium" type="text" id="PRINT_DESC" name="PRINT_DESC" data-ng-model="printModel.PRINT_DESC" />
</div>
</form>
<div id="printPreview">
<table class="table table-cell-nowrap table-responsive">
<thead>
<tr>
<th colspan="2"><strong>Type: <em>{{printModel.PRINT_DESC}}</em></strong></th>
<th colspan="2" style="border: 1px #dadada dotted"><div class="clearfix pull-right"><strong>{{agentModel.singleAgent.AGENT_NUMBER}}</strong></div></th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Agent Name: {{ agentModel.singleAgent.AGENT_LNAME }}, {{ agentModel.singleAgent.AGENT_FNAME }} </strong></td>
<td><strong>Agent #: {{ agentModel.singleAgent.AGENT_NUMBER }}</strong></td>
<td><strong>UID: {{ agentModel.singleAgent.AGENT_UID }}</strong></td>
<td></td>
</tr>
<tr><td colspan="4">Printed On: {{ today }} </td></tr>
</tbody>
</table>
</div>
<div id="printSection" class="col-md-12"><!-- place nothing in here except what should be printed. by default the content in the print section IS hidden -->
<table class="table table-cell-nowrap table-responsive printCoverFontSize">
<thead>
<tr>
<th colspan="2"><strong>Type: <em>{{printModel.PRINT_DESC}}</em></strong></th>
<th colspan="2" style="border: 1px #dadada dotted"><div class="clearfix pull-right"><strong>{{agentModel.singleAgent.AGENT_NUMBER}}</strong></div></th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Agent Name: {{ agentModel.singleAgent.AGENT_LNAME }}, {{ agentModel.singleAgent.AGENT_FNAME }} </strong></td>
<td><strong>Agent #: {{ agentModel.singleAgent.AGENT_NUMBER }}</strong></td>
<td><strong>UID: {{ agentModel.singleAgent.AGENT_UID }}</strong></td>
<td></td>
</tr>
<tr><td colspan="4">Printed On: {{ today }} </td></tr>
</tbody>
</table>
</div>
</div>
<div class="modal-footer">
<div class="pull-left">
<button class="btn btn-warning" data-pas-print data-print-element-id="printSection"><i class="fa fa-print fa-lg"></i> Print </button>
</div>
<div class="pull-right">
<button class="btn btn-default" data-ng- click="cancel()">Cancel</button>
</div>
the printModel model simply takes the value from the text box and includes it to be printed, just a descriptive term.
I am at a loss as to why this is not working. I did just piece this together from other scripts I found online to work with our application. I am a bit of an angular Newb and I really appreciate any help I can get so thank you in advance. please if you need more information feel free to ask. If I had to guess I would say it has something to do with cloning and the emptying of the element if I had to guess, but I am at a loss as to how to fix it. HELP please.

My Angular view is not updated with data form server

I am using Angularjs and i make a call form server to retrieve data. Data are successfully retrieved but my view is not updated. I don't understand why. Here are the code i use.
Angularjs and html code :
<div class="row custom-margin" ng-controller="ListCtlr" ng-init="initData()">
<form class="form-inline" role="form" id="formId" name="formId">
<div class="form-group">
<label for="searchInput">Data to search</label>
<input ng-model="searchInput" placeholder="Enter term to search">
</div>
<button type="submitSearch" class="btn btn-primary" ng-click="search()">Go</button>
</form>
</div>
<div class="table-responsive">
<table class="table">
<thead>
<tr class="info">
<th colspan="4" class="centertext">Name</th>
<th colspan="3" class="centertext">Age</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="person in persons">
<td>{{person.name}}</td>
<td>{{person.age}}</td>
</tr>
</tbody>
</table>
</div>
</div>
Controller code :
function ListCtlr($scope, $http, $location,$filter) {
$scope.formId = {searchInput: ''};
$scope.search = function () {
var url='server/search/'+this.searchInput;
$http.get(url)
.success(function (data) {
$scope.persons = data;
})
.error(function(data){
$scope.error = data;
});
};
}
When i inspect the data retrieved form server i get the following JSON data :
[{"name":"John","age":12},{"name":"Mary","age":25},{"name":"Garry","age":28}]
What's missing please ?
Change
<tr ng:repeat="person in persons">
<td>{{person.name}}</td>
<td>{{person.age}}</td>
</tr>
to
<tr ng-repeat="person in persons">
<td>{{person.name}}</td>
<td>{{person.age}}</td>
</tr>
The problem is that your ListCtlr controller is placed on a div that does not contain your ng-repeat.
To solve this, create an outer div, put the ng-controller on that div:
<div ng-controller="ListCtlr">
... (place contents of your html here) ...
</div>
This ensures that ListCtlr's scope includes the ng-repeat.
Note: Be sure to remove the ng-controller="ListCtlr" defined in your inner div.

Categories