How Exporting a table to Excel? - angularjs

what is the best way of this? I have table and it's data coming from api. I used angularJs for data. Here my source codes:
Here's my table in Index:
<div style="width:1100px; max-height:480px; overflow:scroll; border-top:1px solid #808080">
<table class="table">
<tr>
<th>AdaNo</th>
<th>ParselNo</th>
<th>CiltNo</th>
<th>SayfaNo</th>
<th>ZeminTip</th>
<th>İl</th>
<th>İlçe</th>
<th>Mahalle</th>
<th>Kurum</th>
<th>Alan</th>
<th>Pay</th>
<th>Nitelik</th>
<th>EdinmeSebep</th>
<th>Ad</th>
<th>SoyAd</th>
<th>TcKimlikNo</th>
<th>HissePay</th>
<th>HissePayda</th>
</tr>
<tr data-ng-repeat="zemin in Zeminler">
<td>{{zemin.AdaNo}}</td>
<td>{{zemin.ParselNo}}</td>
<td>{{zemin.CiltNo}}</td>
<td>{{zemin.SayfaNo}}</td>
<td>{{zemin.ZeminTip.Ad}}</td>
<td>{{zemin.Il.Ad}}</td>
<td>{{zemin.Ilce.Ad}}</td>
<td>{{zemin.Mahalle.Ad}}</td>
<td>{{zemin.Kurum.Ad}}</td>
<td>{{zemin.AnaTasinmaz.Alan}}</td>
<td>{{zemin.KatMulkiyeti.ArsaPay}}/{{zemin.KatMulkiyeti.ArsaPayda}}</td>
<td>{{zemin.AnaTasinmaz.Nitelik}}</td>
<td>{{zemin.Hisseler[0].EdinmeSebep}}</td>
<td>{{zemin.Hisseler[0].Kisi.GercekKisi.Ad}}{{zemin.Hisseler[0].Kisi.TuzelKisi.Ad}}</td>
<td>{{zemin.Hisseler[0].Kisi.GercekKisi.SoyAd}}</td>
<td>{{zemin.Hisseler[0].Kisi.GercekKisi.TcKimlikNo}}</td>
<td>{{zemin.Hisseler[0].HissePay}}</td>
<td>{{zemin.Hisseler[0].HissePayda}}</td>
</tr>
</table>
</div>
Here's my Apis for this Data:
[Route("api/TapuZeminApi/GetZemins")]
[HttpPost]
public string GetZeminsFromZeminArg(object arg)
{
ZeminArg zemArg = SConvert.DeserializeJSON<ZeminArg>(arg.ToString());
List<TapuZeminModel> zeminList = TapuModule.GetZeminListFromArgs(zemArg);
string jsonResult = SConvert.SerializeJSON(zeminList);
return jsonResult;
}
// GET api/<controller>/5
public string GetZeminsFromTcNo(long id)
{
List<TapuZeminModel> zeminList = TapuModule.GetZeminListFromTcNo(id.ToString());
string jsonResult = SConvert.SerializeJSON(zeminList);
return jsonResult;
}
public string GetZeminsFromKurumId(long id)
{
List<TapuZeminModel> zeminList = TapuModule.GetZeminListKurumId(id);
string jsonResult = SConvert.SerializeJSON(zeminList);
return jsonResult;
}
Article
I used it in my solution like:
First made ExportToExcelService.Js:
angular.module('TapuAppModule')
.factory('Excel', function tapuExcelFactory($window) {
var uri = 'data:application/vnd.ms-excel;base64,',
template = '<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40"><head><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>{worksheet}</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--></head><body><table>{table}</table></body></html>',
base64 = function (s) { return $window.btoa(unescape(encodeURIComponent(s))); },
format = function (s, c) { return s.replace(/{(\w+)}/g, function (m, p) { return c[p]; }) };
return {
tableToExcel: function (tableId, worksheetName) {
alert('Olcak olcak')
var table = $(tableId),
ctx = { worksheet: worksheetName, table: table.html() },
href = uri + base64(format(template, ctx));
return href;
}
};
})
and here my controller tapuController.js:
$scope.exportToExcel = function (tableId) {
$scope.exportHref = Excel.tableToExcel(tableId, 'sheet name');
$timeout(function () { location.href = $scope.fileData.exportHref; }, 100); // trigger download
};
and my button like this in Index:
<button class="btn btn-link" ng-click="exportToExcel('#dataTable')">
<span class="w-icon-page-excel"></span> Export to Excel
</button>
When I click button I'm getting alert that in ExportToExcelService.Js 'Olcak Olcak'. So I think it can be triggered method in ExportToExcelService.Js. Then I got this error like at console in Chrome:
TypeError: Cannot read property 'exportHref' of undefined
at tapuController.js:81
at angular.js:17682
at completeOutstandingRequest (angular.js:5387)
at angular.js:5659
Why I'm getting this error? What should I do?

Try to change the location.href value by $scope.exportHref; without fileData.
$timeout(function () { location.href = $scope.exportHref; }, 100); // trigger download
that works for me.

Related

Generated password using angular js not working

I want to make the password is auto generated and to pass it to the controller :
this is my view.jsp:
<tr>
<td class="leftDetails">Password</td>
<td class="rightDetails"><input type="text" name="password" ng-model="newUser.password" ng-disabled="isEditMode" id="p"/></td>
<td class="rightDetails"><input type='button' value ='generate' onclick='document.getElementById("p").value = Password.generate(16)' ng-show="add"></td>
<td class="leftDetails"></td>
<td class="rightDetails"></td>
</tr>
<script>
var Password = {
_pattern : /[a-zA-Z0-9_\-\+\.]/,
_getRandomByte : function()
{
if(window.crypto && window.crypto.getRandomValues)
{
var result = new Uint8Array(1);
window.crypto.getRandomValues(result);
return result[0];
}
else if(window.msCrypto && window.msCrypto.getRandomValues)
{
var result = new Uint8Array(1);
window.msCrypto.getRandomValues(result);
return result[0];
}
else
{
return Math.floor(Math.random() * 256);
}
},
generate : function(length)
{
return Array.apply(null, {'length': length})
.map(function()
{
var result;
while(true)
{
result = String.fromCharCode(this._getRandomByte());
if(this._pattern.test(result))
{
return result;
}
}
}, this)
.join('');
}
};
My problem is want to pass the generated password to my controller ,it was empty
How to correct that. thanks in advance?
The angular way to solve this issue is to update your input ng-model instead of selecting the element (Jquery way).
Instead of onClick use ng-click="newUser.password = Password.generate(16)"

AngularJS Datatables insert Table-Footer with column totals

Do you know how I can easily insert a simple footer (tfoot) into my datatable?
I have build my Datatable in my Angular-Controller like this:
function Controller(DTOptionsBuilder, DTColumnBuilder, $compile) {
var ctrl = this;
ctrl.totals = {};
var initDatatable = function() {
ctrl.dtInstance = {};
ctrl.dtColumns = [
DTColumnBuilder.newColumn('id', 'Id'),
DTColumnBuilder.newColumn('title', 'Name').renderWith(actionsHtml),
// ... some columns here
];
var renderDatatable = function() {
ctrl.dtOptions = DTOptionsBuilder
.newOptions()
.withFnServerData(serverData)
.withDataProp('data')
.withOption('processing', true)
.withOption('serverSide', true)
.withOption('createdRow', createdRow)
.withOption('fnFooterCallback', footerCallback);
function createdRow(row, data, dataIndex) {
$compile(angular.element(row).contents())($scope);
}
function serverData(sSource, aoData, fnCallback, oSettings) {
// get data from Server by ajax
// and then sum the total values
ctrl.total.col1 += data1;
ctrl.total.col2 += data2;
ctrl.total.col3 += data3;
var records = {
'draw': draw,
'recordsTotal': entries.length,
'recordsFiltered': entries.length,
'data': entries // filtered data entries
};
fnCallback(records);
}
function activateDatatable() {
initDatatable();
renderDatatable();
}
activateDatatable();
}
The Code is compressed by me to see the general structure.
Now I created the function "footerCallback()" to define the table footer, but datatables doesnt generate the <tfoot> automatically and because of that I have to create it manually into the template:
<table datatable="" dt-instance="ctrl.dtInstance" dt-options="ctrl.dtOptions" dt-columns="ctrl.dtColumns" class="table table-striped table-bordered">
<tfoot>
<tr>
<th></th>
</tr>
</tfoot>
</table>
After a long time of research I find out that I should be generate every th-tag into the footer but I couldn't get my total values from serverData() to insert in the cells.
Could everyone help me?
i know its an old one, but for completion:
to use the footerCallback you have to change this datatables plugin sum to angularjs way. (there is a similar way with drawCallback)
.withOption('footerCallback', function () {
var api = this.api();
total = api.column(5).data()
.flatten()
.reduce( function (a,b) {
if ( typeof a === 'string' ) {a = a.replace(/[^\d.-]/g, '') * 1;}
if ( typeof b === 'string' ) {b = b.replace(/[^\d.-]/g, '') * 1;}
return a + b;
}, 0);
$( api.columns(5).footer() ).html( total );
})
you even can use render for the footer, to keep number localization (and currency). for example with the help of the datatables plugin intl
var renderit = $.fn.dataTable.render.intlNumber('fr', {style: 'currency',currency: 'EUR'} );
$( api.columns(5).footer() ).html( renderit(total,'display') );

mvc using angular js when value change in dropdownlist table data changes

public JsonResult GetdataByID(int Id)
{
var x = (from n in db.Employees
where n.Id == Id
select n).FirstOrDefault();
return new JsonResult { Data = x, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
public JsonResult GetCountries()
{
List<Employee> allCountry = new List<Employee>();
using (WorkdbEntities dc = new WorkdbEntities())
{
allCountry = dc.Employees.OrderBy(a => a.Id).ToList();
}
return new JsonResult { Data = allCountry, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
}
HTML Code
<div ng-controller="BindData">
<select ng-model="Id" ng-options="I.Id as I.Id for I in BindId" ng-change="GetState()">
<option value="">Select Id</option>
</select>
<table>
<tr>
<td>Employeename</td>
</tr>
<tr ng-repeat="ff in BindTable">
<td>
{{ff.Name}}
</td>
</tr>
</table>
</div>
Controller Code
angular.module("MyApp")
.controller("BindData", function ($scope, LocationId) {
$scope.BindId = null;
$scope.Id = null;
LocationId.GetCountries()
.then(function (d) {
$scope.BindId = d.data;})$scope.GetState = function (Employee) {LocationId.GetdataByID($scope.Id).then(function (d) $scope.BindTable = d.data;})}})
Factory Code
.factory("LocationId", function ($http) {
var fac = {};
fac.GetCountries = function () {
return $http.get("/Home/GetCountries")
}
fac.GetState = function (Id) {
return $http.get("Home/GetdataByID ? Id=" + Id)
}
return fac;})
I am not even sure what exactly you are trying to do but one thing I noticed that is wrong for sure is:
LocationId.GetdataByID()
You have never defined a GetdataById property/method on your LocationId object.
Please provide more information and try to be more clear with what you are trying to do.
Also, you really need to try to format your questions better if you are expecting someone to help you. Reading code is not always easy as it is, and especially not when you don't invest the effort to make it as easy as possible.

Pushing multiple entries and saving them in database through AngularJS

I am stuck saving multiple rows I pushed in "$scope.arr" to my SQL Server database. I have my code below and it works fine but when I click on "Save To DB" button after adding/pushing some entries by pressing "Add Person" button, it passes a row with null values to SQL Server database. Please guide me where I am doing the mistake:
I also heard about using angular.forEach loop but I am confused using that too.
I have my model class "TestModel.cs" here:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace TestProj.Models
{
public class TestModel
{
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
}
My MVC Controller named TestController's Add method here:
[HttpPost]
public string AddPerson(TestModel test)
using (TestContext db = new TestContext())
{
if (test != null)
{
db.TestModels.Add(test);
db.SaveChanges();
return "Successful";
}
else
{
return "Failed";
}
}
}
My AngularJS script here:
var app = angular.module("TestApp", []);
app.controller("TestCtrl", function ($scope, TestService) {
$scope.arr = [];
$scope.addPerson = function () {
var myobj = {
FirstName: $scope.firstname,
LastName: $scope.lastname
}
$scope.arr.push(myobj);
};
$scope.savePerson = function () {
var TestData = TestService.AddPer($scope.arr);
TestData.then(function (msg) {
alert(msg.data);
}, function () {
alert('Error In Adding Person');
});
};
});
app.service("TestService", function ($http) {
this.AddPer = function (person) {
var response = $http({
method: "post",
url: "/Test/AddPerson",
data: JSON.stringify(person),
dataType: "json",
});
console.log(response);
return response;
}
});
And my Index.cshtml file here:
<div ng-controller="TestCtrl">
<form>
FirstName: <input class="form-control" ng-model="firstname" /><br />
LastName: <input class="form-control" ng-model="lastname" /><br />
<button class="btn btn-success" ng-click="addPerson()">Add Person</button>
<button class="btn btn-success" ng-click="savePerson()">Save To DB</button>
<table class="table table-bordered">
<tr>
<th>S. No</th>
<th>First Name</th>
<th>Last Name</th>
</tr>
<tr ng-repeat="a in arr">
<td>{{$index+1}}</td>
<td>{{a.FirstName}}</td>
<td>{{a.LastName}}</td>
</tr>
</table>
</form>
</div>
<script src="~/Scripts/MyAngular/Module.js"></script>
Your help will be appreciated. Thanks!
Then server side action should expect collection of TestModel, you could us List there. If you [FromBody] before parameter, you don't need to stringify data before posting it to server.
Code
[HttpPost]
public string AddPerson([FromBody] List<TestModel> test)
using(TestContext db = new TestContext()) {
test.forEach(t=> {
if (t != null) {
db.TestModels.Add(t);
return "Successful";
} else {
return "Failed";
}
});
db.SaveChanges(); //save context at the end, when no error occurs
}
}
The problem was in my Server Side Code i.e, my C# controller, this method worked:
[HttpPost]
public void AddPerson(List<TestModel> test)
{
using (TestContext db = new TestContext())
{
foreach(var t in test)
{
if (t != null)
{
db.TestModels.Add(t);
Console.WriteLine("Success");
}
}
db.SaveChanges(); //save context at the end, when no error occurs
}
}

Angularjs Highlight is displaying last row (i.e; $index) after sorting the name

I am sorry for posting questions regularly about Angularjs, I am new to this and lot of confustion is there this is the reason I am posting the questions.
My doubt is I have a list of names whenever I created a new list the highlight is displaying the created name which is working but when I tried to set that names in alphabetical order the highlight issue is displaying the new $index value which is adding. I tried to pass the id in place of $index which is not and highlight is also not displaying. Here is the code which i tried
<table data-ng-repeat="SupplierModels in Supplierlist | filter:suppliersearch">
<tr>
<td class="roundedCorners6_account" ng-class='{roundedCorners6_account_active: $index==selectedRowslist}' style="width: 200px; cursor: pointer; text-align: center;">
<div ng-click="showSupplier(SupplierModels.supplier_ID, $index)">{{SupplierModels.supplier_Name | truncate}}</div>
</td>
</tr>
</table>
$scope function is
function initialLoading() {
ServiceFactory.Invoke(baseurl + 'Api/SupplierApi/SupplierList').success(function (success) {
$scope.Supplierlist = success;
}).error(function (error) {
alert(error);
})
}
$scope.SaveSupplier = function () {
$scope.IsValidatesupplierData($scope);
if ($rootScope.alerts.length == 0) {
ServiceFactory.InvokeWithParameters(baseurl + 'Api/SupplierApi/SaveSupplier', $scope.supplier).success(function (success) {
initialLoading();
var rows = $scope.selectedRowslist == undefined ? $scope.Supplierlist.length : $scope.selectedRowslist;
var supId = success;
$scope.showSupplier(supId, rows);
$scope.visible = true;
}).error(function (error) {
alert(error);
})
}
else {
$rootScope.isErrorPopUpShow = true;
}
}
$scope.showSupplier = function (id, rows) {
$scope.visible = true;
ServiceFactory.InvokeWithParameters(baseurl + 'Api/SupplierApi/SupplierDetail?supplierId=' + id).success(function (success) {
$scope.supplier = success;
$scope.selectedRowslist = rows;
}).error(function (error) {
alert(error);
})
}
I hope I gave a proper explanation. Thanks
I think it would be better to use a natural id in the data model.
id would work, but does supplier have an id field? If so you could use that.
<td class="roundedCorners6_account"
ng-class='{roundedCorners6_account_active: activeSupplierID== SupplierModels.supplier_ID}'
$scope.showSupplier = function (id, rows) {
$scope.visible = true;
ServiceFactory.InvokeWithParameters(baseurl + 'Api/SupplierApi/SupplierDetail?supplierId=' + id).success(function (success) {
$scope.supplier = success;
$scope.activeSupplierID = id; //supplier.id ? if it exists.
...
};

Resources