I am developing an application. I have multiple ajax calls and I need to bind all json into single json. I used below code. But when doing it's also appending json response headers, status and others. I need to push only the key values. Can anyone help me out of this ?
My code is below :
$scope.downloadPdf = function () {
var frequency = $http.get("myapplicationurl" + $stateParams.searchId + "?" + "startDate=" + $stateParams.startDate + "&" + "endDate=" + $stateParams.endDate)//,
// name = $http.get("../myapplicationurl/" + $stateParams.searchId)
$q.all([frequency]).then(function (arrayOfResults) {
angular.forEach(arrayOfResults[0], function (value, key) {
angular.forEach(value[0], function (data, header) {
$scope.header.push([header]);
})
angular.forEach(value, function (it, header) {
$scope.columns.push(it);
console.log("Body : " + $scope.columns);
})
})
console.log("Header : " + $scope.header);
pdfMake.createPdf({
header: 'simple text',
content: [
{
text: 'Fruits and Calories'
},
{
style: 'demoTable',
table: {
widths: ['*', '*', '*'],
body: [
$scope.header,
// $scope.columns
]
}
}
],
footer: {
columns: [
'Left part',
{text: 'Right part', alignment: 'right'}
]
},
styles: {
header: {
bold: true,
color: '#000',
fontSize: 11
},
demoTable: {
color: '#666',
fontSize: 10
}
}
}).download('Sample.pdf');
});
};
First, not sure why you need to use $q.all(), as you have only 1 promise to wait for.
Second, write a simple .then(function(result) {... }) for your $http call, and inspect the returned object. There you can find out which element you should extract for getting only "key values", as the result object will contain also the request, headers, statuses etc.
I think what you are looking for is on "result.data".
Related
Hi I have the below code to achieve print functionality . The code works fine in Chrome, but doesnt work in Edge. Getting the follwing error in edge.I am building the layout in javascript in generatePDF function.
Below is my JS code:
$scope.printRepayment = function() {
var documentDefinition = generatePDF(); pdfMake.createPdf(documentDefinition).print();
}
var generatePDF = function() {
var repayments = $scope.repayments;
var rows = [
[
{ text: "Payment No", style: "tableHeader" },
{ text: "Installment", style: "tableHeader" },
]
];
for (var i = 0; i < repayments.length; i++) {
rows.push([
{ text: i + 1, style: "tablefirst" },
{
text:
"AED " +
numberWithCommas(
parseFloat(repayments[i].installment).toFixed(2)
),
style: "tableOther"
},
]);
}
return {
content: [
{ text: "Repayment schedule", style: "subheader" },
{
style: "tableExample",
table: {
widths: ["*", "*", "*", "*", "*"],
body: rows
},
layout: {
vLineColor: function(i, node) {
return "#ECF3FE";
}
}
}
],
styles: {
tabletop: {
margin: [10, 0, 0, 10]
},
tabletopHeader: {
fontSize: 16,
bold: true
}
}
};
};
With refer to this article, we can see that the pdfMake print() method doesn't support Edge browser. So, as a workaround, I think you could create a web page which contains the display the pdf content, then, calling the window.print(); method to print this page. Otherwise, as Master Po said, you could download the pdf file first, then, print the pdf content.
Thanks a ton #Zhi Lv - MSFT, for giving the solution in plain english and then after having discovered how to do, this is what worked for me
var pdf = pdfMake.createPdf(doc);
pdf.getBuffer(function (buffer) {
var file = new Blob([buffer], {type: 'application/pdf'});
var fileURL = URL.createObjectURL(file);
window.location.href = fileURL;
}); // {autoPrint: true});
the pdf file generated is converted into a blob and the url of that file is then opened up as a new window, shows the pdf doc and can be printed
Yet not sure how autoPrint works, will need to work a bit more
I have a paging grid with local store, and I want to apply a filter using my own function. But it is failed.
From internet recommendations I used remoteFilter: true and enablePaging: true options in store config.
And it works perfectly if I filter store with specific configuration object:
store.filter([{ property: 'age', value: 12 }]);
unfortunately it is not enough to build complex filter criteria.
In accordance with documentation there is a special filterBy method in store object to use function as filter. But, when I am providing it like this:
store.filterBy( function( record ) {
return record.get( 'age' ) <= 12;
});
I got an error Uncaught Error: Unable to use a filtering function in conjunction with remote filtering.
Here is my working example in fiddle https://fiddle.sencha.com/#fiddle/2u8l
This is my store configuration and all business logic from controller. I'll skip view configuration here to focus on main part( IMO )of code
Ext.define('TestGridViewModelr', {
extend: 'Ext.app.ViewModel',
alias: 'viewmodel.myexmpl.main.testgrid',
data: {
},
formulas: {},
stores: {
simpsons: {
model: 'Ext.data.Model',// 'SimpsonModel',
pageSize: 2,
// remoteSort: true,
remoteFilter: true,
proxy: {
type: 'memory',
enablePaging: true,
reader: {
type: 'json',
rootProperty: 'items'
}
}
}
}
});
Ext.define('TestGridController', {
extend: 'Ext.app.ViewController',
alias: 'controller.myexmpl.main.testgrid',
init: function () {
console.log('controller inititalized\n init async store loading...');
setTimeout( this.onStoreLoad.bind( this ), 1000 );
},
initViewModel: function(vm){
console.log( 'viewModel init', vm.get('test') );
},
emptyMethod: function () {},
onStoreLoad: function () {
console.log('loading store');
var vm = this.getViewModel();
var store = vm.getStore('simpsons');
store.getProxy().data = this.getSimpsonsData().items;
store.reload();
// store.loadData( this.getSimpsonsData() );
},
//++++++++++++ FILTERING ++++++++
/* NO PROBLEM */
onToggleFilter: function () {
console.log('simple filter');
var filter = this.getSimpleFilter()
this.toggleFilter( filter );
},
/* PROBLEM */
onToggleFnFilter: function(){
console.log('function filter');
// var filterFn = this.filterChildren;
var filterFn = this.getFilterUtil()
this.toggleFilter( filterFn );
},
/* NO PROBLEM */
getSimpleFilter: function(){
return {
property: 'age',
value: '12'
};
},
/* PROBLEM */
getFilterUtil: function() {
return Ext.create( 'Ext.util.Filter', {
filterFn: this.filterChildren
})
},
filterChildren: function( record ) {
var age = record.get( 'age' );
console.log( 'filter record up to age:', age )// debugger;
return parseInt( age ) <= 12;
},
toggleFilter: function( fltr ) {
var store = this.getViewModel().getStore( 'simpsons' );
var filters = store.getFilters();
if ( filters.length > 0 ) {
store.clearFilter();
} else {
this. applyFilterToStore( fltr, store );
}
},
applyFilterToStore: function( filter, store ){
var method = Ext.isFunction( filter ) || filter instanceof Ext.util.Filter
? 'filterBy'
: 'setFilters';
store[method]( filter );
},
getSimpsonsData: function(){
return {
'items': [{
'name': 'Lisa',
'age': 12,
"email": "lisa#simpsons.com",
"phone": "555-111-1224"
}, {
'name': 'Bart',
'age': 8,
"email": "bart#simpsons.com",
"phone": "555-222-1234"
}, {
'name': 'Homer',
'age': 40,
"email": "homer#simpsons.com",
"phone": "555-222-1244"
}, {
'name': 'Marge',
'age': 34,
"email": "marge#simpsons.com",
"phone": "555-222-1254"
}]
}
}
});
In general I want to have ability to set up filter criteria on paging grid with local store programmatically. Function allows me to extend filter capabilities and build flexible logical expression using conjunction and disquisition. For example:
name.lenght <= 4 && ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0)
Thank you in advance,
A.
You can't use both remoteFilter and filterBy in one store. Decide where should be the logic of the filter - on Client Side or Server Side?
If on server side, set the remoteFilter as true and use filter action with extra paramaters which you can catch on server and perform the filter.
If on client side, set the remoteFilter as false and use filterBy function like you attached.
Check the example on fiddle (I just changed a few things): https://fiddle.sencha.com/#fiddle/2ua4&view/editor
I have finally resolved this issue!
Mentioned error raised in onFilterEndUpdate method of store in next lines:
...
me.getFilters().each(function(filter) {
if (filter.getInitialConfig().filterFn) {
Ext.raise('Unable to use a filtering function in conjunction with remote filtering.');
}
});
...
I have override this method in my store entity and commented out these lines.
I know it is not best solution, but I could not find better one.
Here is the complete solution concerning this topic:
Configure store with remoteFilter: true and enablePaging: true options:
{
model: 'Ext.data.Model',
pageSize: 2,
remoteFilter: true,
proxy: {
type: 'memory',
enablePaging: true,
reader: {
type: 'json'
}
}
}
Load data into the store using its Proxy instead of loadData method:
store.getProxy().data = this.getSimpsonsData().items;
store.reload();
Override method onFilterEndUpdate after store initialization and comment out mentioned lines i.e:
onStoreLoad: function() {
...
store.onFilterEndUpdate = this.onFilterEndUpdate.bind( store );
...
},
onFilterEndUpdate: function() {
var me = this
, suppressNext = me.suppressNextFilter
, filters = me.getFilters(false);
// If the collection is not instantiated yet, it's because we are constructing.
if (!filters) {
return;
}
if (me.getRemoteFilter()) {
// me.getFilters().each(function(filter) {
// if (filter.getInitialConfig().filterFn) {
// Ext.raise('Unable to use a filtering function in conjunction with remote filtering.');
// }
// });
me.currentPage = 1;
if (!suppressNext) {
me.load();
}
} else if (!suppressNext) {
me.fireEvent('datachanged', me);
me.fireEvent('refresh', me);
}
if (me.trackStateChanges) {
// We just mutated the filter collection so let's save stateful filters from this point forward.
me.saveStatefulFilters = true;
}
// This is not affected by suppressEvent.
me.fireEvent('filterchange', me, me.getFilters().getRange());
}
Here is live example in fiddle https://fiddle.sencha.com/#fiddle/2ub7
I have several unique cases inside ui-grid where the cells of certain table contents need additional class, or even style rules assigned, so the appearance for these cells stands out compared to others. Looking through the official ui-grid documentation I found that it could be done with cellTemplate, but I couldn't get any consistent results. What is the best approach here?
Below are the code changes I have attempted before, with the intent being to change the class name based on the returned value from a filter call made
//Define Grid Headings
$scope.scheduledPatientAppointments = [
{
field: 'appointment_date',
displayName: 'Appointment Date'
},
{
field: 'doctor_name',
displayName: 'Doctor Name'
},
{
field: 'procedure_type_eng',
displayName: 'Medical Procedure Type'
},
{
field: 'appointment_status_eng',
displayName: 'Appointment Status'
},
{
field: 'docs_received',
displayName: 'Related Documents',
cellTemplate: '<div class="ui-grid-cell-contents" ng-click="grid.appScope.loadDocumentsModal(\'{{row.entity.id}}\')">{{grid.getCellValue(row, col) | hasDocuments}}</div>',
cellFilter: 'hasDocuments',
cellClass: function(grid, row, col, rowRenderIndex, colRenderIndex) {
if (grid.getCellValue(row, col).toLowerCase() === 'missing') {
return 'missing';
} else if (grid.getCellValue(row, col).toLowerCase() === 'received') {
return 'received';
} else {
return 'undefined';
}
}
}
];
// Define Grid Options
$scope.PatientAppointmentsGrid = {
selectionRowHeaderWidth: 25,
enableHorizontalScrollbar: false,
rowHeight: 35,
enableSorting: true,
columnDefs: $scope.columnsPatient,
data: [],
onRegisterApi: function (gridApi) {
$scope.gridApi = gridApi;
}
};
//Behavior for patient page load
$scope.appointmentsProvider = patientsService.patientFactory.getAppointmentsForPatient($stateParams.id).then(
function successCallback(response) {
var preFetchData = response.data.data;
angular.forEach(preFetchData, function (value, key) {documentsService.documentsFactory.getDocumentsByAppointmentId(value.id).then(
function successCallback(response2) {
if (response2.data.length >= 1) {
//Append value state to the preFetchData object (count size)
var totalFiles = response2.data.length;
preFetchData[key].docs_received = totalFiles;
} else {
preFetchData[key].docs_received = 0;
}
}, function errorCallback(response2) {
console.debug("Error", response2);
});
});
$scope.PatientAppointmentsGrid.data = preFetchData;
},
function errorCallback(response) {
console.debug("Error", response);
});
The contents from the "Related Documents" are initally set to Missing (the original rest call returns nothing, and the filter call sets it to that. However, a later call actually loads associated documents per row, and I believe the inactivity of the grid on this particular call is what is causing no class to get set here.
Thoughts on the best approach here?
adding custom class with cellTemplate:
columnDefs: [
{
name:'firstName',
field: 'first-name',
// adding custom class
cellTemplate: "<div class=\"ui-grid-cell-contents custom-class\" title=\"TOOLTIP\">{{COL_FIELD CUSTOM_FILTERS}}</div>"
},
{ name:'1stFriend', field: 'friends[0]' },
{ name:'city', field: 'address.city'},
{ name:'getZip', field: 'getZip()', enableCellEdit:false}
],
.......
there are plenty of predefined customizable templates defined with $templateCache at the bottom of https://cdnjs.cloudflare.com/ajax/libs/angular-ui-grid/3.2.9/ui-grid.js
adding custom style:
.......
onRegisterApi: function(gridApi){
//set gridApi on scope
$scope.gridApi = gridApi;
// adding custom style
gridApi.grid.registerStyleComputation({
func: function () {
return [
'.custom-class { ',
' color: red; ',
' font-weight: bold; ',
'} ',
'.ui-grid-row:nth-child(1) .custom-class { ',
' color: blue; ',
'} '
].join('\n');
}
});
}
plunker: http://plnkr.co/edit/YbnYoWLlEYzwmjuKOFa0?p=preview
My problem is that I have a datatable containing thousands of datas and I faced performance problems on Internet Explorer 11 (I don't want <11 and I'm not facing any issues on Firefox and Chrome). To solve the performance problem I added deferRender: true to my dataTable which was really successful but then I faced another problem I don't have solved yet.
The new problem is that each row of my table has a checkbox and the datatable header has a checkbox which check/uncheck all row checkboxes when there is a click on it.
When the click happen I retrieve all nodes in my table by doing var allNodes = myTable.rows().nodes() and change the checked property of each row checkbox.
Without the deferRender option I was retrieving all nodes but since I had this option which is doing a lazy loading I am only retrieving nodes already loaded (first page and pages loaded).
So my question is :
Is there a way to keep the IE performance patch with the lazy loading deferRender option and still have access to all nodes (maybe through a function I haven't find yet) or is there another way to improve performance on IE ?
Thank you for your help.
P.S. : If needed I add my datatable initialization code here :
$('#myTable').DataTable({
ajax: {
url: myUrl,
contentType: 'application/json',
type: 'POST',
data: function (d) {
return JSON.stringify(dataToSend);
}
},
columns: [
{
data: 'Identifier',
type: 'html',
sortable: false,
render: function (data, type, row) {
return '<input type="checkbox" name="checkboxRow" value="' + $('<div/>').text(data).html() + '">';
}
},
{
data: 'Mnemo',
render: function (data, type, row) {
return '<a class="hand-cursor">' + $('<div/>').text(data).html() + '</a>';
}
},
{ data: 'FamGam.Family' },
{ data: 'FamGam.Gamme' },
{
fnCreatedCell: function (nTd, oData, iRow, iCol) {
if (oData === 'En service') {
$(nTd).addClass('cell-text-green');
} else if (oData === 'En cours de démontage') {
$(nTd).addClass('cell-text-orange');
}
},
data: 'dataState.Libelle'
},
{ data: 'IdentifierUI' },
{ data: 'TechnicalRoom.InterventionUnitySenderSite' },
{ data: 'IdentifierTechnicalRoom' },
{
type: 'html',
sortable: false,
defaultContent: '<img class="imgBtn secondBtn" ' +
'src="' + urlImages + '/edit.png" ' +
'alt="Editer" title="Editer" />'
}
],
deferRender: true,
destroy: true,
searching: true,
retrieve: true,
order: [1, 'asc']
});
I wrote this code to create chart, table and toolbar.
google.load("visualization", "1", { packages: ["corechart"] });
google.load('visualization', '1', { packages: ['table'] });
//google.setOnLoadCallback(drawChart);
function drawChart() {
$.ajax({
type: "GET",
url: '#Url.Action("GunlukOkumalar", "Enerji")',
data: "startDate=" + $('#start_date').val() + "&endDate=" + $('#end_date').val() + "&sayac_id=" + $("#sayaclar").val(), //belirli aralıklardaki veriyi cekmek için
success: function (result) {
if (result.success) {
var evalledData = eval("(" + result.chartData + ")");
var opts = { curveType: "function", width: '100%', height: 500, pointSize: 5 };
new google.visualization.LineChart($("#chart_div").get(0)).draw(new google.visualization.DataTable(evalledData, 0.5), opts);
$('#chart_div').show();
var visualization;
var data;
var options = { 'showRowNumber': true };
data = new google.visualization.DataTable(evalledData, 0.5);
// Set paging configuration options
// Note: these options are changed by the UI controls in the example.
options['page'] = 'enable';
options['pageSize'] = 10;
options['pagingSymbols'] = { prev: 'prev', next: 'next' };
options['pagingButtonsConfiguration'] = 'auto';
// Create and draw the visualization.
visualization = new google.visualization.Table(document.getElementById('table'));
visualization.draw(data, options);
var components = [
{ type: 'html', datasource: data },
{ type: 'csv', datasource: data }
];
var container = document.getElementById('toolbar_div');
google.visualization.drawToolbar(container, components);
return false;
}
else {
$('#chart_div').html('<span style="color:red;"><b>' + result.Error + '</b></span>');
$('#chart_div').show();
$('#table').html('<span style="color:red;"><b>' + result.Error + '</b></span>');
$('#table').show();
return false;
}
}
});
}
Google example
function drawToolbar() {
var components = [
{type: 'igoogle', datasource: 'https://spreadsheets.google.com/tq?key=pCQbetd-CptHnwJEfo8tALA',
gadget: 'https://www.google.com/ig/modules/pie-chart.xml',
userprefs: {'3d': 1}},
{type: 'html', datasource: 'https://spreadsheets.google.com/tq?key=pCQbetd-CptHnwJEfo8tALA'},
{type: 'csv', datasource: 'https://spreadsheets.google.com/tq?key=pCQbetd-CptHnwJEfo8tALA'},
{type: 'htmlcode', datasource: 'https://spreadsheets.google.com/tq?key=pCQbetd-CptHnwJEfo8tALA',
gadget: 'https://www.google.com/ig/modules/pie-chart.xml',
userprefs: {'3d': 1},
style: 'width: 800px; height: 700px; border: 3px solid purple;'}
];
var container = document.getElementById('toolbar_div');
google.visualization.drawToolbar(container, components);
};
Google get dataSource from url, but I get dataSource dynamicly from controller. When I try to export It forwards page to another page like this:
http://localhost:49972/Enerji/%5Bobject%20Object%5D?tqx=out%3Acsv%3B
How can I use exporting toolbar for dynamic Json data? Is there any example about this topic?
I also had this problem and after a lot of trawling I found this!
https://developers.google.com/chart/interactive/docs/dev/implementing_data_source
I haven't implemented it yet but I reckon it's the way to go.