Populate table data with $http.get on dropdown option selected in Angular - javascript

I am new to Angular and would like to learn how to accomplish this task below:
I have a dropdown that contains a list of table names from a database. When a table name is selected from the drop down I want to make an HTTP GET call to a web API method which returns the list of column names in the selected table.
HTML:
<div class="row">
<div ng-app="myApp">
<div class="col-lg-12">
<h1>Table Information</h1>
<hr />
<div ng-controller="TableController" class="col-lg-6">
<label>Select a Table:</label>
<select id="tablename" ng-options="table.Name for table in tables track by table.Name" ng-model="data.selectedOption" class="form-control"></select>
</div>
</div>
<div class="col-lg-12">
<h1>{{data.selectedOption}}</h1>
<hr />
<div ng-controller="TableColumnController" class="col-lg-6">
<table class="table">
<thead>
<tr>
<th>Column Name</th>
<th>Type</th>
<th>Max Characters</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="tablecolumn in tablecolumns">
<td>
{{tablecolumn.Name}}
</td>
<td>
{{tablecolumn.Type}}
</td>
<td>
{{tablecolumn.MaxCharacters}}
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
Here is my JavaScript:
var app = angular.module('myApp', []);
app.controller('TableColumnController', function ($scope, $http) {
$http.get('http://localhost:61475/api/SxTableInfo/',
{
params: {
tablename: "smsn"
}
}).
success(function (data, status, headers, config) {
$scope.tablecolumns = data;
}).
error(function (data, status, headers, config) {
alert("error!");
});
});
app.controller('TableController', function ($scope, $http) {
$http.get('http://localhost:61475/api/SxTableInfo/').
success(function (data, status, headers, config) {
$scope.tables = data;
}).
error(function (data, status, headers, config) {
alert("error!");
});
});
What is the best way to do this?
Here is just an example of what it looks like:
UPDATED CODE:
<div class="row" ng-app="myApp">
<div ng-controller="ctrl">
<div class="col-lg-12">
<h1>Table Information</h1>
<hr />
<div class="col-lg-6">
<label>Select a Table:</label>
<select id="tablename"
ng-options="table.Name for table in tables track by table.Name"
ng-model="data.selectedOption"
ng-change="getColumns(data.selectedOption)"
class="form-control"></select>
</div>
</div>
<div class="col-lg-12">
<h1>{{data.selectedOption.Name}}</h1>
<hr />
<div class="col-lg-6">
<table class="table table-striped table-hover">
<thead>
<tr>
<th>Column Name</th>
<th>Type</th>
<th>Max Characters</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="tablecolumn in tablecolumns">
<td>
{{tablecolumn.Name}}
</td>
<td>
{{tablecolumn.Type}}
</td>
<td>
{{tablecolumn.MaxCharacters}}
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
#section Scripts{
<script>
var app = angular.module('myApp', []);
app.factory('tableService', ['$http', function ($http) {
function getColumns(selection) {
$http.get('http://localhost:61475/api/SxTableInfo/', { params: { tablename: selection } }).success(function (data) {
return data;
});
}
function getTables() {
$http.get('http://localhost:61475/api/SxTableInfo/').success(function (data) {
return data;
});
}
return { getColumns: getColumns, getTables: getTables }
}]);
app.controller('ctrl', ['$http', '$scope', 'tableService', function ($http, $scope, tableService) {
$scope.tables = tableService.getTables();
$scope.getColumns = function (selection) {
$scope.tablecolumns = tableService.getColumns(selection.Name);
}
}]);
</script>
}

No need for multiple controllers, and you'll need to bind to ngChange. Observe the following example, specifically, the binding to getStuff...
<select
id="tablename"
ng-options="table.Name for table in tables track by table.Name"
ng-model="data.selectedOption"
ng-change="getStuff(data.selectedOption)"
class="form-control">
</select>
app.controller('ctrl', function ($scope, $http) {
$scope.getStuff = function(selection) {
$http.get('http://localhost:61475/api/SxTableInfo/', {
params: { tablename: selection }
})
.success(function (data, status, headers, config) {
$scope.tablecolumns = data;
});
}
}
I would recommend moving this logic into an injectable service, most likely your next step. Something like...
app.factory('TableService', ['$http', function($http) {
function getMetaData(selection) {
$http.get('http://localhost:61475/api/SxTableInfo/', { params: { tablename: selection } }
}
return { getMetaData: getMetaData }
}]);
app.controller('ctrl', ['$scope', 'TableService', function ($scope, TableService) {
$scope.getStuff = function(selection) {
TableService.getMetaData(selection).then(function(response) {
$scope.tablecolumns = response.data;
});
}
}]);
Plunker Link - simplified demo
Edit per your example and updated code, give this a shot...
app.controller('ctrl',...
tableService.getTables().then(function(response) {
$scope.tables = response.data;
});
$scope.getColumns = function (selection) {
tableService.getColumns(selection.Name).then(function(response) {
$scope.tablecolumns = response.data
});
}

You should not use two controllers for this purpose, instead you can use a service or factory for $https request to get you data from the server.
You should also use ng-change to invoke table column name info call
Try this
in app.js
var app = angular.module('plunker', []);
app.factory('userFactory', ['$http', function($http) {
var dataFactory = {};
dataFactory.getTableNames = function() {
/*$http.get('http://localhost:61475/api/SxTableInfo/').
success(function (data, status, headers, config) {
$scope.tables = data;
}).
error(function (data, status, headers, config) {
alert("error!");
});*/
data = [{
id: 1,
tableName: 'table1'
}, {
id: 2,
tableName: 'table2'
}, {
id: 3,
tableName: 'table3'
}];
return data;
}
dataFactory.getColumnNames = function() {
alert('implement your logic here . ');
/* $http.get('http://localhost:61475/api/SxTableInfo/',
{
params: {
tablename: "smsn"
}
}).
success(function (data, status, headers, config) {
$scope.tablecolumns = data;
}).
error(function (data, status, headers, config) {
alert("error!");
});*/
}
return dataFactory;
}]);
app.controller('MainCtrl', ['$scope', 'userFactory', function($scope, userFactory) {
$scope.name = 'World';
$scope.items = userFactory.getTableNames();
$scope.getColumnNames= function(){
userFactory.getColumnNames();
}
}]);
in HTML,
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js#1.4.x" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.min.js" data-semver="1.4.6"></script>
<script src="app.js"></script>
</head>
<body ng-controller="MainCtrl">
<p>Hello {{name}}!</p>
<select ng-change="getColumnNames()" ng-model="selectedItem" ng-options="item.tableName as item.tableName for item in items"></select>
</body>
</html>
Plunker link for the same.

Related

Use jsPDF to Populate PDF with JSON Data

I want to create letters to clients, using json data such as {{client.name}}, {{client.id}}, etc..
Currently, when I try to create the PDF I get undefined values for my json data input. This is my HTML:
`<!DOCTYPE html>
<html lang="en">
<html ng-app="app">
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0">
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/font-awesome/3.1.0/css/font-awesome.min.css" />
<% include headerpdf %>
<% include navbar %>
<body>
<div id="render_me">
<div class="container">
<div ng-controller="ClientCtrl">
<div class="datagrid"><table>
<thead>
<tr>
<th> ID </th>
<th> Phone </th>
<th> Address </th>
<th> Zip </th>
</tr>
</thead>
<tbody>
<tr ng-repeat="client in clients | orderBy:'id' | filter:{id:clientId} | limitTo: 1">
<td>
{{client.id}}
</td>
<td>{{client.phone}} </td>
<td>{{client.address}}</td>
<td>{{client.zip}}</td>
</tr>
</tbody>
</table>
Download Test PDF
<script type="text/javascript">
var doc = new jsPDF();
// We'll make our own renderer to skip this editor
var specialElementHandlers = {
'#editor': function(element, renderer){
return true;
}
};
doc.fromHTML($('#render_me').get(0), 15, 15, {
'width': 170,
'elementHandlers': specialElementHandlers
});
//doc.save('Test.pdf');
$('a').click(function(){
doc.save('TestHTMLDoc.pdf');
});
</script>`
Here is the clientCtrl :
var myApp = angular.module('app', ['ngRoute']);
myApp.config(['$routeProvider', '$locationProvider', function($routeProvider, $locationProvider) {
// configure the routing rules here
$locationProvider.html5Mode({enabled : true, requireBase : false});
$routeProvider.when('/client/:id', {
controller: 'viewController'
})}]);
myApp.controller('ClientCtrl', ['$scope', '$http', '$routeParams', function($scope, $http, $routeParams) {
$scope.clients = [];
$http.get('/client').success(function(data, status, headers, config) {
$scope.clients = data;
if (data == "") {
$scope.clients = [];
}
}).error(function(data, status, headers, config) {
console.log("Ops: could not get any data");
});
$scope.addClient = function() {
$http.post('/client', {
name : $scope.clientName,
age : $scope.clientAge,
birthday : $scope.clientBirthday,
canreceivetxt : $scope.clientcanreceivetxt,
phone : $scope.clientPhone,
address : $scope.clientAddress,
ssn : $scope.clientSsn,
}).success(function(data, status, headers, config) {
$scope.clients.push({
name : $scope.clientName,
age : $scope.clientAge,
birthday : $scope.clientBirthday,
canreceivetxt : $scope.clientcanreceivetxt,
phone : $scope.clientPhone,
address : $scope.clientAddress,
ssn : $scope.clientSsn,
});
$scope.clientName = '';
$scope.clientAge = '';
$scope.clientBirthday = '';
$scope.clientcanreceivetxt = '';
$scope.clientPhone = '';
$scope.clientAddress = '';
$scope.clientSsn = '';
}).error(function(data, status, headers, config) {
console.log("Ops: " + data);
});
};
$scope.clientId = document.location.href.split('client/')[1];
}]);
myApp.controller('viewController',['$scope','$http', '$location' , '$routeParams',function($scope, $http, $location, $routeParams){
$http.get('/client/' + $routeParams.id).success(function(data) {
$scope.clients = data;
$scope.client=$scope.clients[$routeParams.id]
})}]);
clients has to be defined on your ClientCtrl. Could you post your controller? maybe clients is not on your $scope or is not initialized correctly
EDIT !
--> Final solution was to move the doc.fromHTML($(..... inside the $('a').click(function() { ...

data-ng-repeat in partial view does not display data

This is my module.js
var app = angular.module("ApplicationModule", ["ngRoute"]);
app.factory("ShareData", function () {
return { value: 0 }
});
//Showing Routing
app.config(['$routeProvider', '$locationProvider', function
($routeProvider, $locationProvider) {
debugger;
$routeProvider.when('/ShowAll',
{
templateUrl: 'Home/ShowAll',
controller: 'ShowAllController'
});
$routeProvider.otherwise(
{
redirectTo: '/'
});
}]);
This is my Services.js
app.service("SampleService", function ($http) {
this.getSamples = function () {
return $http.get("/api/Sample");
};
this.getSample = function (id) {
return $http.get("/api/Sample" + id);
};
});
This is my ShowAllController.js
app.Controller('ShowAllController', function ($scope,
SampleService) {
loadAll();
function loadAll() {
var promiseGet = SampleService.getSamples();
promiseGet.success(function (data) { $scope.Samples = data
},
function (errordata) {
$scope.error = errordata;
}
);
}
});
This is my index.cshtml
#{
ViewBag.Title = "API's";
}
#section scripts{
<script src="~/Scripts/angular.js"></script>
<script src="~/Scripts/angular-route.min.js"></script>
<script src="~/Scripts/Module.js"></script>
<script src="~/Scripts/Services.js"></script>
<script src="~/Scripts/ShowAllController.js"></script>
}
<div class="container" data-ng-app="ApplicationModule">
<div class="panel panel-default">
<div class="panel-header">
<div class="row">
<div><h4 class="col-xs-6">GET api/Patient</h4>Patients List</div>
</div></div>
<div class="panel-body" data-ng-view>
</div>
</div>
This is my partial view (ShowAll.cshtml)
<div data-ng-controller="ShowAllController">
<table>
<tr>
<th>ID</th>
<th>Name</th>
<th>Age</th>
<th>Address</th>
</tr>
<tr data-ng-repeat="person in Samples">
<td>{{person.Id}}</td>
<td>{{person.Name}}</td>
<td>{{person.Age}}</td>
<td>{{person.Address}}</td>
</tr>
</table>
</div>
My return PartialView code is in my HomeController inside the ShowAll ActionResult. The problem is that when I click the button it just displays the header of the table without the data.
Note: This is a web api.
Thank you.
Add the following statement to your ShowAllController before the ajax call so Angular is aware of this scope var in Config time
app.Controller('ShowAllController', function ($scope, SampleService) {
$scope.Samples = []; // <- NEW LINE HERE!
loadAll();
function loadAll() {
var promiseGet = SampleService.getSamples();
promiseGet.success(function (data) { $scope.Samples = data
},
function (errordata) {
$scope.error = errordata;
}
);
}
});
Angular Dependency Injection might not be setting up the scope var Samples in Config time. Then in Run time, it won't recognize this var as something that should be updated.
If that doesn't work, also try to wrap the success result of of your promise into $scope.$apply() as angular might not be aware of it when running its digest function.
$scope.$apply(function () {
$scope.Samples = data;
})

xmlhttprequest function while typing instead of form submit

Search form xmlhttprequest works fine.
is there any option to use this function while typing instead of submit form ?
function customersController($scope, $http) {
$scope.search = function() {
$scope.url = 'http://www.vanmaram.com/json_result.php?en=' + $scope.keywords;
$http.get($scope.url).
success(function(data, status) {
$scope.status = status;
$scope.data = data;
$scope.result = data; // Show result from server in <li> element
}).
error(function(data, status) {
$scope.data = data || "Request failed";
$scope.status = status;
});
};
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="" ng-csp ng-controller="customersController">
<form style="position:relative;" ng-submit="search()">
<input type="search" placeholder="Type english word" ng-model="keywords">
<input type="submit" value="Search">
</form>
<ul>
<li ng-repeat="word in result | limitTo:9">{{ word }}</li>
</ul>
</div>
Hi Please check this example in plunkr [link:http://plnkr.co/edit/6kuVR4?p=preview]
Hope it helps.
Js
var app = angular.module('plunker', []);
app.controller('MainCtrl', function($scope) {
$scope.name = 'World';
$scope.selected = "";
$scope.countries = ["India", "Australia", "Japan"];
});
app.directive('autoComplete', function($timeout) {
return function(scope, iElement, iAttrs) {
iElement.autocomplete({
source: scope[iAttrs.uiItems],
select: function() {
$timeout(function() {
iElement.trigger('input');
}, 0);
}
});
};
});
In HTML
<body ng-controller="MainCtrl">
<p>Countries {{countries|json}}!</p>
<div ng-app="MyModule">
<div>
<input auto-complete="" ui-items="countries" ng-model="selected" />selected = {{selected}}
</div>
</div>
</body>
used library jqueryui/1.8.16/jquery-ui.js
The solution found with ng-change which call the same function of form submit
function customersController($scope, $http) {
$scope.suggestword = function(argument) {
$scope.url = 'http://www.vanmaram.com/ajax_json_suggestion.php?en=' + $scope.keywords; // The url of our search
$http.get($scope.url).
success(function(data, status) {
$scope.status = status;
$scope.data = data;
$scope.suggetionresult = data; // Show result from server in <li> element
$scope.result = null;
}).
error(function(data, status) {
$scope.data = data || "Request failed";
$scope.status = status;
});
};
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="" ng-csp ng-controller="customersController">
<form style="position:relative;" ng-submit="search()">
<input type="search" placeholder="Type english word" ng-model="keywords" ng-change="suggestword()">
<input type="submit" value="Search">
</form>
<ul ng-if='result.length'>
<li ng-repeat="word in result | limitTo:9">{{ word }}</li>
</ul>
<div id="suggestion" ng-if='suggetionresult.length > 1'>
Suggestions: <a ng-repeat="word in suggetionresult | limitTo:9">{{ word }}</a>
</div>
</div>

Push values to array AngularJS

Im trying to push a data value to an array in AngularJS, with .push();, but I always get this error message:
Error: $scope.test.push is not a function
Here is my HTML:
<div ng-controller="Test">
<div class="container">
<div class="col-sm-9 col-sm-offset-2">
<div class="page-header"><h1>Testar</h1></div>
<table class="table table-striped table-condensed">
<thead>
<tr>
<th>Sträcka</th>
<th>Tid</th>
</tr>
</thead>
<tr ng-repeat="info in test"><td>{{info.stracka}}</td><td>{{info.tid}}</td></tr>
</table>
<form name="userForm" ng-submit="submitForm(userForm.$valid)" novalidate> <!-- novalidate prevents HTML5 validation since we will be validating ourselves -->
<div class="form-group" ng-class="{'has-error' : userForm.stracka.$invalid && !userForm.stracka.$pristine, 'has-success' : userForm.stracka.$valid }">
<label>Sträcka(m):</label>
<input type="text" name="stracka" class="form-control" ng-model="form.stracka" required>
<p ng-show="userForm.stracka.$invalid && !userForm.stracka.$pristine" class="help-block">Fel sträcka</p>
</div>
<div class="form-group" ng-class="{'has-error' : userForm.tid.$invalid && !userForm.tid.$pristine, 'has-success' : userForm.tid.$valid && !userForm.tid.$pristine}">
<label>Tid:</label>
<input type="text" name="tid" class="form-control" ng-model="form.tid" ng-minlength="3" ng-maxlength="8">
<p ng-show="userForm.tid.$error.minlength" class="help-block">För kort</p>
<p ng-show="userForm.tid.$error.maxlength" class="help-block">För långt</p>
</div>
<button type="submit" class="btn btn-primary">Lägg till</button>
</form>
</div>
</div>
</div>
And here is my controller:
as.controller('Test', function($scope, $http, $rootScope, testFactory)
{
$http.get($rootScope.appUrl + '/nao/test/test')
.success(function(data, status, headers, config) {
$scope.test = data.data;
});
$scope.form = {};
$scope.submitForm = function(isValid) {
if(isValid)
{
/*testFactory.testFactoryMethod(function($http) {
$scope.test = data;
});*/
$http.post($rootScope.appUrl + '/nao/test', $scope.form)
.success(function(data, status, headers, config) {
console.log(data);
$scope.test.push($scope.form);
}).error(function(data, status) {
});
}
};
});
Can anyone help me and explain why I get this message?
Try doing this:
$scope.test = [];
$scope.test.push($scope.form);
Try this:
as.controller('Test', function($scope, $http, $rootScope, testFactory)
{
$http.get($rootScope.appUrl + '/nao/test/test')
.success(function(data, status, headers, config) {
$scope.test = data.data;
});
$scope.form = {};
$scope.submitForm = function(isValid) {
if(isValid)
{
/*testFactory.testFactoryMethod(function($http) {
$scope.test = data;
});*/
$http.post($rootScope.appUrl + '/nao/test', $scope.form)
.success(function(data, status, headers, config) {
console.log(data);
$scope.test = $scope.test || [];
$scope.test.push($scope.form);
}).error(function(data, status) {
});
}
};
});
create an array first -
$scope.usermsg = [];
then push value in it -
$scope.usermsg.push($variable);

Binding data to AngularUI dialog

I'm trying to write a simple angularapp to allow the teachers to edit their class information. I'm using angular-ui dialog directive to get the lightbox. On userclick I've written a function to pass the data to the modal and open the dialog. But for some reason the data is not properly binded.
This is my controller.js
'use strict';
define(['app' ], function(app) {
app.controller('TeacherClasses',
[ '$scope', '$http', '$dialog','$location', 'teacherClassService',
function($scope, $http, $dialog, $location, teacherClassService) {
$scope.newClass={};
$scope.show = {"createClassModal": false};
$http.get('/grades').success(function(data) {
$scope.grades = data;
});
$scope.newClass.grade = "Grade";
$scope.setGrade = function(grade){
$scope.newClass.grade = grade;
};
$scope.fetchStudentGroups = function(){
$http.get('/teacher/studentGroups').success(function(data) {
$scope.studentGroups = data;
});
};
$scope.fetchStudentGroups();
$scope.createClass = function(){
$http.post('/studentGroup', $scope.newClass).
success(function(data, status, headers, config) {
$scope.show.createClassModal = false;
//Clearing it out for next time
$scope.newClass = {};
$scope.fetchStudentGroups();
}).
error(function(data, status, headers, config) {
});
console.log($scope.newClass);
};
$scope.openDialog = function(studentGroup, dialog){
$scope.newClass = angular.copy(studentGroup);
$scope.opts = {
backdrop: true,
keyboard: true,
backdropClick: true,
templateUrl: '/assets/partials/teacher/manage/editClassInfo.html',
resolve: {
data: function(){
return $scope.newClass;
}
}
};
var modal = $dialog.dialog($scope.opts);
modal.open();
}
}]);
return app;
});
And this is my partial
<div class="modal-header">
Edit Class
</div>
<div class="modal-body">
<form class="form-horizontal">
<div class="control-group">
<input type="text" ng-model="newClass.name" class="span4">
</div>
<div class="control-group">
<select ui-select2 data-placeholder="Choose a grade" id="grades" class="span4">
<option></option>
<option ng-repeat="grade in grades" ng-model="grades" >{{grade}}</option>
</select>
</div>
<label>Students {{newClass.noOfStudents}}</label>
<label>{{newClass.name}}</label>
</form>
</div>
<div class="modal-footer"></div>
My module definitions are in app.js
'use strict';
define([ 'angular' ], function(angular) {
var myModule = angular.module('myApp',
[ 'ngResource', 'ui', 'infinite-scroll', 'ngDragDrop', 'blueimp.fileupload','ui.bootstrap.dialog', 'ui.bootstrap.modal',
'ui.bootstrap.dropdownToggle', 'LoadingIndicator', 'http-auth-interceptor']);
myModule.value('ui.config', {
select2 : {
allowClear : true
},
redactor: {
plugins: ['fullscreen']
}
});
return myModule;
});
But none of these values are tied back to the view. What am I doing wrong here?

Categories

Resources