Related
I'm facing issue with Feature layer. When plot map with local data. But when I'm using hosted data in feature layer then Drawing feature is working fine and query on drawing data is also working perfectly.
But when I'm using my local system data using api request then draw objects on map is working fine but query filtering is not working on feature layer data. Below is the example code.
<link rel="stylesheet" href="https://js.arcgis.com/4.8/esri/css/main.css">
<style>
#viewDiv {
height: 100%;
}
.popUpMapView {
height: 400px;
border: 1px solid #A8A8A8;
}
#drawActions {
padding: 0 5px;
background: #eee;
border-left: 1px solid #999;
border-right: 1px solid #999;
}
#drawActions ul {
list-style-type: none;
margin: 0;
padding: 0;
}
#drawActions ul li {
display: inline-block;
}
#drawActions ul li .esri-widget--button {
background: #eee;
}
#drawActions ul li .esri-widget--button:hover {
background: #fff;
}
.esri-ui-top-left .esri-component {
margin-bottom: 0;
border-top: solid 1px rgba(50,50,50,0.25);
}
.esri-popup.esri-widget {
max-height: 100%;
}
.esri-view-width-xlarge .esri-popup__main-container {
width: 580px;
}
.esri-view-height-less-than-medium .esri-popup__main-container {
max-height: 500px;
}
.esri-view-height-small .esri-ui-corner .esri-component .esri-expand__content,
.esri-view-width-greater-than-xsmall .esri-expand--auto .esri-expand__content {
margin-left: 0;
white-space: nowrap;
}
.esri-widget--button {
outline: 0;
}
.esri-legend__layer-body {
display: table;
width: 100%;
margin: 0;
}
.color-selection-item-container {
cursor: pointer;
}
.item-selected .color-selection-item-container {
opacity: 0.5;
}
.item-selected .color-selection-item-container.active {
opacity: 1;
}
.item-selected .color-selection-item-container.active .esri-legend__layer-cell--info {
color: #000;
}
</style>
<script>
var dojoConfig = {
has: {
"esri-featurelayer-webgl": 1
}
}
</script>
<script src="https://js.arcgis.com/4.8/"></script>
<script>
let highlight;
let highlightFields = [];
let povLayer;
let plantTypeFilterObj = [];
require([
"esri/Map",
"esri/views/MapView",
"esri/WebMap",
"esri/widgets/Sketch/SketchViewModel",
"esri/Graphic",
"esri/layers/GraphicsLayer",
"esri/layers/FeatureLayer",
"esri/widgets/Home",
"esri/widgets/Legend",
"esri/widgets/Expand",
"esri/geometry/Point",
"esri/config",
"esri/request",
"dojo/domReady!"
], function(
Map, MapView, WebMap, SketchViewModel, Graphic, GraphicsLayer, FeatureLayer, Home, Legend, Expand, Point, erisConfig, Request
) {
const tempGraphicsLayer = new GraphicsLayer();
var map = new Map({
basemap: "dark-gray",
layers: [tempGraphicsLayer]
});
const view = new MapView({
map: map,
container: "viewDiv",
center: [-91.891111, 42.477778],
zoom: 4,
highlightOptions: {
color: "black",
haloOpacity: 0,
fillOpacity: 0.45
},
});
let highlightHandle = null;
view.when(function() {
getData()
.then(createGraphics)
.then(createLayer)
.catch(errback);
});
function getData() {
let url = "http://localhost/arcgis/points-listing";
return Request(url, {
responseType: "json"
});
}
function createGraphics(response) {
let items = response.data.data;
let geojson = items.map(function(item, i) {
return {
geometry: new Point({
x: item.lng,
y: item.lat
}),
attributes: {
ObjectID: item.plant_id,
name: item.name,
address: item.street_address,
city: item.city,
state_code: item.state_code,
zip: item.zip,
county: item.county,
lng: item.lng,
lat: item.lat,
nameplate_capacity: item.nameplate_capacity,
plant_type: item.plant_type
}
};
});
return geojson;
}
function createLayer(graphics) {
let layer = new FeatureLayer({
source: graphics,
fields: getFields(),
objectIdField: "ObjectID",
renderer: getRender(),
geometryType: "point",
popupTemplate: getTemplate(),
elevationInfo: {
mode: "on-the-ground"
}
});
var legend = new Legend({
view: view,
layerInfos: [{
layer: layer,
title: "Plants detail"
}]
});
view.ui.add(legend, "top-right");
map.add(layer);
view.whenLayerView(layer).then(function(layerView) {
sketchGraphics(layerView);
setTimeout(function() {
hideShowPointsOnPlantTypeBasis();
colorSelectionClick();
}, 1000);
});
return layer;
}
function hideShowPointsOnPlantTypeBasis()
{
let legendContainer = document.getElementsByClassName("esri-legend__layer-table--size-ramp")[0];
legendContainer.className += " color-section";
let legendInfoItem = legendContainer.getElementsByClassName("esri-legend__layer-cell--info");
for (let i = 0; i < legendInfoItem.length; i++) {
let element = legendInfoItem[i];
let text = element.innerHTML;
let value = (text.toUpperCase()).replace(" ", "_");
checkbox = document.createElement("input");
checkbox.setAttribute("type", "checkbox");
checkbox.setAttribute("class", "plant-type-filtering-checkbox");
checkbox.setAttribute("style", "display:none;");
checkbox.setAttribute("value", value);
element.parentNode.classList.add("color-selection-item-container");
element.parentNode.insertBefore(checkbox, element.parentNode.firstChild);
}
}
function colorSelectionClick() {
$('.esri-expand__content').on('click', '.color-selection-item-container', function(e) {
e.preventDefault();
let $this = $(this);
let $input = $this.find('input.plant-type-filtering-checkbox');
let selectedVal = $input.val();
if(!$input.is(':checked')) {
plantTypeFilterObj.push(selectedVal);
$input.prop('checked', true);
$this.addClass('active');
} else {
$this.removeClass('active');
plantTypeFilterObj = plantTypeFilterObj.filter(function(value, index, arr){
return value != selectedVal;
});
$input.prop('checked', false);
}
let layerViews = view.layerViews;
if(plantTypeFilterObj.length > 0) {
viewLayer.layer.definitionExpression = "nameplate_capacity > 0 AND plant_type IN ('" + plantTypeFilterObj.join("','") + "')";
} else {
viewLayer.layer.definitionExpression = '';
}
let selectedCount = $('.esri-expand__content').find('.color-selection-item-container.active').length;
if(selectedCount > 0) {
$('.esri-expand__content').addClass('item-selected');
} else {
$('.esri-expand__content').removeClass('item-selected');
}
});
}
function sketchGraphics(layer) {
viewLayer = layer;
// create a new sketch view model
const sketchViewModel = new SketchViewModel({
view: view,
layer: tempGraphicsLayer,
pointSymbol: {
type: "simple-marker", // autocasts as new SimpleMarkerSymbol()
style: "square",
size: "16px"
}
});
setUpClickHandler(view);
sketchViewModel.on("create", createGraphic);
sketchViewModel.on("create-complete", addGraphic);
// Listen the sketchViewModel's update-complete and update-cancel events
sketchViewModel.on("update-complete", updateGraphic);
sketchViewModel.on("update-cancel", updateGraphic);
var drawCircleButton = document.getElementById("circleButton");
var drawRectangleButton = document.getElementById("rectangleButton");
var drawPolygonButton = document.getElementById("polygonButton");
drawCircleButton.onclick = function() {
resetSketchView();
sketchViewModel.create("circle");
setActiveButton(this);
};
drawRectangleButton.onclick = function() {
resetSketchView();
sketchViewModel.create("rectangle");
setActiveButton(this);
};
drawPolygonButton.onclick = function() {
resetSketchView();
sketchViewModel.create("polygon");
setActiveButton(this);
};
view.on('click', function(event) {
resetSketchView();
});
// reset all the changes from map on btn click.
document.getElementById("resetBtn").onclick = function() {
resetSketchView();
};
function addGraphic(event) {
const graphic = new Graphic({
geometry: event.geometry,
symbol: sketchViewModel.graphic.symbol
});
tempGraphicsLayer.add(graphic);
selectFeatures(event.geometry);
}
function createGraphic(event) {
resetHideShowPoints();
}
function updateGraphic(event) {
event.graphic.geometry = event.geometry;
tempGraphicsLayer.add(event.graphic);
editGraphic = null;
}
function setActiveButton(selectedButton) {
view.focus();
var elements = document.getElementsByClassName("active");
for (var i = 0; i < elements.length; i++) {
elements[i].classList.remove("active");
}
if (selectedButton) {
selectedButton.classList.add("active");
}
}
function resetSketchView() {
sketchViewModel.reset();
tempGraphicsLayer.removeAll();
// remove existing highlighted features
if (highlight) {
highlight.remove();
}
}
}
function selectFeatures(geometry) {
view.graphics.removeAll();
if (viewLayer) {
let query = {};
query.returnGeometry = true;
query.outFields = ["*"];
viewLayer.queryFeatures(query).then(function(results) {
const graphics = results.features;
if (graphics.length > 0) {
// remove existing highlighted features
if (highlight) {
highlight.remove();
}
highlight = viewLayer.highlight(graphics);
}
})
.catch(errback);
}
}
function removeUnSelectedPoints(viewLayer, graphics)
{
graphics.forEach(item => {
highlightFields.push(item.attributes.FID);
});
setTimeout(function() {
viewLayer.layer.definitionExpression = "FID IN (" + highlightFields.join(",") + ")";
}, 1000);
}
function resetHideShowPoints() {
if(highlightFields.length > 0) {
highlightFields = [];
viewLayer.layer.definitionExpression = "";
console.log('reset', highlightFields);
}
}
function errback(error) {
console.error(error);
}
function setUpClickHandler(mapview) {
mapview.on("click", function(event) {
event.stopPropagation();
streetView(view, event)
mapview.hitTest(event).then(function(response) {
var results = response.results;
});
});
}
function streetView(mainMapView, event) {
// Make sure that there is a valid latitude/longitude
if (event && event.mapPoint) {
// Create lat/lon vars to display in popup title
var lat = Math.round(event.mapPoint.latitude * 1000) / 1000;
var lon = Math.round(event.mapPoint.longitude * 1000) / 1000;
mainMapView.popup.open({
// Set the popup's title to the coordinates of the location
title: "Map view coordinates: [" + lon + ", " + lat + "]",
location: event.mapPoint, // Set the location of the popup to the clicked location
content: innerMapPopUp(
mainMapView,
mainMapView.center,
mainMapView.scale
)
});
} else {
mainMapView.popup.open({
// Set the popup's title to the coordinates of the location
title: "Invalid point location",
location: event.mapPoint, // Set the location of the popup to the clicked location
content: "Please click on a valid location."
});
}
}
function innerMapPopUp(mainMapView, center, scale) {
var popupDiv = document.createElement("div");
popupDiv.classList.add("popUpMapView");
var popupView = new MapView({
container: popupDiv,
map: new Map({
basemap: "topo"
}),
center: center,
zoom: 8,
ui: {
components: []
}
});
console.log(popupView);
// Return a dom node
return popupView.container;
}
function getFields() {
var fields = [
{
name: "ObjectID",
alias: "ObjectID",
type: "oid"
}, {
name: "name",
alias: "name",
type: "string"
}, {
name: "address",
alias: "address",
type: "string"
}, {
name: "city",
alias: "city",
type: "string"
}, {
name: "state_code",
alias: "state_code",
type: "string"
}, {
name: "zip",
alias: "zip",
type: "string"
}, {
name: "county",
alias: "county",
type: "string"
}, {
name: "plant_type",
alias: "plant_type",
type: "string"
}, {
name: "nameplate_capacity",
alias: "nameplate_capacity",
type: "double"
}
];
return fields;
}
function getTemplate() {
// Set up popup template for the layer
var pTemplate = {
title: "{name}",
content: [{
type: "fields",
fieldInfos: [
{
fieldName: "street_address",
label: "Address",
visible: true
},
{
fieldName: "city",
label: "City",
visible: true
},
{
fieldName: "state_code",
label: "State Code",
visible: true
},
{
fieldName: "zip",
label: "Zip",
visible: true
},
{
fieldName: "county",
label: "County",
visible: true
},
{
fieldName: "plant_type",
label: "Plant Type",
visible: true
},
{
fieldName: "latitude",
label: "Latitude",
visible: true
},
{
fieldName: "longitude",
label: "Longitude",
visible: true
},
{
fieldName: "nameplate_capacity",
label: "Capacity (MW)",
visible: true
}
]
}]
};
return pTemplate;
}
function getRender() {
var renderer = {
type: "unique-value", // autocasts as new SimpleRenderer()
// Define a default marker symbol with a small outline
symbol: {
type: "simple-marker", // autocasts as new SimpleMarkerSymbol()
color: "#FFD733"
},
defaultLabel: "Other",
field: "plant_type",
label: "Plant Type",
uniqueValueInfos: [
{
value: "HYDRO",
symbol: {
type: "simple-marker",
color: "hsla(345,80%, 65%, 1)"
},
label: "Hydro"
},
{
value: "NATURAL_GAS",
symbol: {
type: "simple-marker",
color: "hsla(213,80%, 65%, 1)"
},
label: "Natural Gas"
},
{
value: "BIOMASS",
symbol: {
type: "simple-marker",
color: "hsla(195,80%, 65%, 1)"
},
label: "Biomass"
},
{
value: "COAL",
symbol: {
type: "simple-marker",
color: "hsla(336,80%, 65%, 1)"
},
label: "Coal"
},
{
value: "NUCLEAR",
symbol: {
type: "simple-marker",
color: "hsla(224,80%, 65%, 1)"
},
label: "Nuclear"
},
{
value: "PETROLIUM",
symbol: {
type: "simple-marker",
color: "hsla(264,80%, 65%, 1)"
},
label: "Petrolium"
},
{
value: "SOLAR",
symbol: {
type: "simple-marker",
color: "hsla(287,80%, 65%, 1)"
},
label: "Solar"
},
{
value: "WIND",
symbol: {
type: "simple-marker",
color: "hsla(344,80%, 65%, 1)"
},
label: "Wind"
}
],
visualVariables: [
{
type: "size",
field: "nameplate_capacity",
valueUnit: "unknown",
legendOptions: {
title: "Nameplate Capacity (MW)"
},
stops: [
{
value: 500,
size: 10,
label: "<500"
},
{
value: 2000,
size: 15,
label: "1000"
},
{
value: 3000,
size: 20,
label: "4000"
},
{
value: 5000,
size: 35,
label: "< 10000"
}]
}
]
};
return renderer;
}
// Set up a home button for resetting the viewpoint to the intial extent
var homeBtn = new Home({
view: view
}, "homeDiv");
// Instructions expand widget
const drawIcons = document.getElementById("drawActions");
instructionsExpand = new Expand({
expandIconClass: "esri-icon-expand",
expandTooltip: "Draw Actions",
expanded: false,
view: view,
iconNumber: 4,
content: drawIcons
});
view.ui.add(homeBtn, "top-left");
view.ui.add(instructionsExpand, "top-left");
// hide the instructions expand widget when the view becomes focused
view.watch("focused", function(newValue, oldValue, property, object) {
if (newValue) {
instructionsExpand.expanded = false;
}
});
});
</script>
And below is the screen-shot what issue I'm getting.
I spend my too much time to research on that. But unfortunately I'm not finding any way how to resolve this issue.
Please give a clue what I'm missing.
It looks like you are not setting up the query correctly. You have:
let query = {};
query.returnGeometry = true;
query.outFields = ["*"];
viewLayer.queryFeatures(query)
You need to use the featureLayer's createQuery method to create a query object:
let query = layer.createQuery();
query.returnGeometry = true;
query.outFields = ["*"];
viewLayer.queryFeatures(query)
Also, WebGL rendering is only supported for layers hosted on ArcGIS Online, or on ArcGIS Server 10.6.1 so highlight and other functionality will not work on layers that do not meet these requirements.
I am trying to parse data from a JS Object array and get the value by passing field names and then saving the data in an array. But for some reason, I am not getting the right results. This is what I tried so far. I tried logging the results that I get in val and this is what I get.
val:Array[6]
0
:
Object
BankName
:
"IM BANK"
MERCHANTNAME
:
"MPesa"
NO_OF_FAILED_BANK_TRANSACTIONS
:
0
NO_OF_FAILED_SERVICE_TRANSACTIONS
:
2
NO_OF_SUCCESSFUL_TRANSACTIONS
:
28
__proto__
:
Object
1
:
Object
2
:
Object
3
:
Object
4
:
Object
5
:
Object
length
:
6
How Do I parse the data from my val array by passing field names and then store inside my merchantname array etc.
Homepage.js
<html>
<head>
<script src="http://code.jquery.com/jquery-1.11.3.min.js" ></script>
<script src="http://code.highcharts.com/highcharts.js" ></script>
<script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
</head>
<body>
<div id="container1" style="width:100%; height:400px;"></div>
<div id ="container2" style="height:20px;"></div>
<div id ="container3" style="width:100%; height:400px;"></div>
<script type="text/javascript">
$(document).ready(function () {
var bankid = [ 57, 9912, 9905, 16, 58 ];
var country = ["KENYA", "KENYA", "KENYA", "UGANDA", "UGANDA"];
var counter = 0;
var merchantname = [];
var successtranscs = [];
var failedtranscs = [];
var servicetranscs = [];
var bankname;
var rows =<%-JSON.stringify(Resultset)%>
function initfunc() {
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "/dashboard",
data: JSON.stringify({country: country[counter], bankid: bankid[counter]}),
dataType: "json",
success: function (Result) {
Result = Result.Resultset
// console.log("result", Result);
// console.log("result",Result);
var data = [];
var merchantname = [];
var successtranscs = [];
var failedtranscs = [];
var servicetranscs = [];
var bankname;
$.each(Result, function(item, value){
console.log("val",value);
for (var i in value) {
$.each(value[i], function(item, val){
console.log(val);
for(var i =0;i<val.length;i++)
{
merchantname.push(val[i].merchant_name);
successtranscs.push(val[i].success_transcs);
failedtranscs.push(val[i].failed_transcs);
servicetranscs.push(val[i].service_transcs);
bankname =val[i].bankname;
console.log("merchantname",merchantname);
}
//
})
}
})
// merchantname.push(Result[i].merchant_name);
// successtranscs.push(Result[i].success_transcs);
// failedtranscs.push(Result[i].failed_transcs);
// servicetranscs.push(Result[i].service_transcs);
// bankname = Result[i].bankname;
// console.log("merchantname",merchantname);
StackedChart(bankname, merchantname, successtranscs, failedtranscs, servicetranscs);
merchantname = [];
successtranscs = [];
failedtranscs = [];
servicetranscs = [];
if (counter == country.length - 1) {
counter = -1;
counter++;
}
else {
counter++;
}
},
error: function (Result) {
console.log(Result);
}
});
}
initfunc();
function StackedChart(bank_name,merch_name, succ_val, fail_val, ser_val) {
var myChart = Highcharts.chart('container1', {
chart: {
type: 'column'
},
title: {
text: bank_name
},
xAxis: {
categories: merch_name
},
yAxis: {
min: 0,
title: {
text: 'TransactionStatus'
},
stackLabels: {
enabled: true,
style: {
fontWeight: 'bold',
color: (Highcharts.theme && Highcharts.theme.textColor) || 'gray'
}
}
},
legend: {
align: 'right',
x: -30,
verticalAlign: 'top',
y: 25,
floating: true,
backgroundColor: (Highcharts.theme && Highcharts.theme.background2) || 'white',
borderColor: '#CCC',
borderWidth: 1,
shadow: false
},
tooltip: {
headerFormat: '<b>{point.x}</b><br/>',
pointFormat: '{series.name}: {point.y}<br/>Total: {point.stackTotal}'
},
plotOptions: {
column: {
stacking: 'normal',
dataLabels: {
enabled: true,
color: (Highcharts.theme && Highcharts.theme.dataLabelsColor) || 'white'
}
}
},
series: [{
name: 'Servicefailure',
data: ser_val
}, {
name: 'Failure',
data: fail_val
}, {
name: 'Success',
data: succ_val
}]
});
}
setInterval(initfunc, 2000);
});
</script>
</body>
</html>
Your access keys (marchant_name, success_transcs, ..) are not same with the keys of the objects in the array (MERCHANTNAME, NO_OF_FAILED_BANK_TRANSACTIONS, ...).
Try using the exact same keys:
...
merchantname.push(val[i].MERCHANTNAME);
successtranscs.push(val[i].NO_OF_SUCCESSFUL_TRANSACTIONS);
...
Nested loops in initfunc() look all wrong.
Callback signature
$.each()'s callback signature is (item, index)
Nesting
Do you realise that $.each(function() {...}) is a looping structure in its own right, without the need of a for loop?
You have loops nested at 4-levels. In summary :
$.each(..., { // outer loop (n1 iterations)
for(...) { // first inner loop (n2 iterations)
$.each(..., function(element2, index2) { // second inner loop (n3 iterations)
for() { // third inner loop (n4 iterations)
// Here, inner statements are called n1 x n2 x n3 x n4 times
}
});
}
});
That's not necessarily wrong, but it's very unusual to need loops nested that deeply.
I rather imagine you want :
$.each(Result, function(item) {
$.each(item, function(val) {
merchantname.push(val.merchant_name); // or .MERCHANTNAME?
successtranscs.push(val.success_transcs); // or .NO_OF_SUCCESSFUL_TRANSACTIONS?
failedtranscs.push(val.failed_transcs); // or .NO_OF_FAILED_BANK_TRANSACTIONS?
servicetranscs.push(val.service_transcs); // or .NO_OF_FAILED_SERVICE_TRANSACTIONS?
bankname = val.bankname; // or .BankName?
});
});
or maybe just :
$.each(Result, function(val) {
merchantname.push(val.merchant_name); // or .MERCHANTNAME?
successtranscs.push(val.success_transcs); // or .NO_OF_SUCCESSFUL_TRANSACTIONS?
failedtranscs.push(val.failed_transcs); // or .NO_OF_FAILED_BANK_TRANSACTIONS?
servicetranscs.push(val.service_transcs); // or .NO_OF_FAILED_SERVICE_TRANSACTIONS?
bankname = val.bankname; // or .BankName?
});
I am using Odoo 10.
I need to use JQuery selectors instead $el.find to navigate the DOM, but I'm having some difficulties. Is there a specific Widget I should extend to do that?
For now I achieved this task only setting a timeout, but I would prefer to not do that.
My code:
openerp.grid = function(instance, local) {
local.GridWidget = instance.web.form.FormWidget.extend({
start: function () {
this._super.apply(this, arguments)
var self = this
var container = document.createElement('div')
container.className = 'grid_container'
this.$el.append(container)
self.draw_grid()
},
draw_grid: function() {
var grid;
var columns = [
{id: 'title', name: 'Title', field: 'title'},
{id: 'attr', name: 'Attribute', field: 'attr'},
]
var options = {
enableCellNavigation: true,
enableColumnReorder: false,
};
var data = [];
for (var i = 0; i < 500; i++) {
data[i] = {
title: "Task " + i,
attr: "Attr " + i,
};
}
setTimeout(function() {
grid = new Slick.Grid('.grid_container', data, columns, options);
}, 50)
}
})
instance.web.form.custom_widgets.add('GridWidget','instance.grid.GridWidget')
}
Is it possible, in Javascript, to run a function in background ?
I am generating a pdf with pdfmake tool in an angularJS app, but the pdf generation is quite long (3-4 seconds) and during this time, the ui freeze completely.
I would like to run a background task and force the pdf download without freezing the user ui, is it possible ?
Here how I am running pdfmake (pdfmake and _ are custom factories):
'use strict';
angular.module('App')
.service('CatalogPdfService', ['pdfmake', '_', '$q', '$filter',
function (pdfmake, _, $q, $filter) {
var $translate = $filter('translate');
var listDate = new Date();
return {
download: download
};
function download(data) {
listDate = _.first(data).publishedOn;
console.log('start download');
var deferred = $q.defer();
var filename = $translate('APP.EXPORT.pdf.catalog.title', {date: $filter('amDateFormat')(listDate, 'DDMMYYYY')}) + '.pdf';
create(data).download(filename, function () {
console.log('end download');
deferred.resolve();
});
return deferred.promise;
}
function create(data) {
// group data by category
var dataByCategory = _.groupBy(data, function (d) {
return d.category;
});
// group categories data by subcategory
_.forEach(dataByCategory, function (d, i) {
dataByCategory[i] = _.groupBy(d, function (d) {
return d.subcategory;
});
});
var content = {
table: {
headerRows: 1,
widths: ['*', 20, 10, 20, 20, 20, 20, 40, 20, 30],
body: [
[
{text: $translate('APP.EXPORT.pdf.catalog.header.article') , style: 'headings', alignment: 'left'},
{text: $translate('APP.EXPORT.pdf.catalog.header.mine') , style: 'headings'},
{text: $translate('APP.EXPORT.pdf.catalog.header.rank') , style: 'headings'},
{text: $translate('APP.EXPORT.pdf.catalog.header.origin') , style: 'headings'},
{text: $translate('APP.EXPORT.pdf.catalog.header.transporter') , style: 'headings'},
{text: $translate('APP.EXPORT.pdf.catalog.header.culture') , style: 'headings'},
{text: $translate('APP.EXPORT.pdf.catalog.header.label') , style: 'headings'},
{text: $translate('APP.EXPORT.pdf.catalog.header.unit') , style: 'headings'},
{text: $translate('APP.EXPORT.pdf.catalog.header.packing') , style: 'headings'},
{text: $translate('APP.EXPORT.pdf.catalog.header.price') , style: 'headings'}
]
]
},
layout: {
hLineWidth: function (i) {
return (i == 0) ? 0 : 1;
},
vLineWidth: function (i) {
return 0;
},
hLineColor: function (i, node) {
return '#ccc';
}
}
};
_.forEach(dataByCategory, function (data, category) {
content.table.body = content.table.body.concat(renderCategory(category, data));
});
var dd = {};
dd.content = renderHeader().concat(content);
dd.header = function (currentPage, pageCount) {
return {
text: $translate('APP.EXPORT.pdf.catalog.pagecount', {start: currentPage.toString(), end: pageCount.toString()}),
alignment: 'right',
color: '#666',
margin: [0, 20, 40, 0]
};
};
dd.styles = {
title: {
fontSize: 15,
bold: true
},
headings: {
italics: true,
alignment: 'center'
},
flag: {
alignment: 'center',
italics: true,
color: '#666'
},
category: {
bold: true,
fontSize: 12,
margin: [0, 10, 0, 0] // Left, Top, Right, Bottom
},
subcategory: {
bold: true,
fontSize: 10,
margin: [0, 7, 0, 5] // Left, Top, Right, Bottom
}
};
dd.defaultStyle = {
fontSize: 8
};
return pdfmake.createPdf(dd);
}
function renderHeader() {
return [
{image: logo(), height:40, width: 86},
{
margin: [0, 10, 0, 20],
table: {
widths: [100, 100, 100, '*'],
body: [
[
{text: $translate('APP.COMMON.address', {char: '\n'})},
{text: '\n' + $translate('APP.COMMON.phone')},
{text: '\n' + $translate('APP.COMMON.fax')},
{text: '\n' + $translate('APP.EXPORT.pdf.catalog.listno', {date: $filter('amDateFormat')(listDate, 'DD/MM/YYYY')}) , alignment: 'right'}
]
]
},
layout: {
hLineWidth: function (i) {
return (i == 0) ? 0 : 1;
},
vLineWidth: function (i) {
return 0;
}
}
}];
}
function renderCategory(name, data) {
var category = [
[
{text: name, style: 'category', colspan: 10},
'', '', '', '', '', '', '', '', ''
]
];
_.forEach(data, function (data, name) {
category = category.concat(renderSubcategory(name, data));
});
return category;
}
function renderSubcategory(name, data) {
var subcategory = [
[
{text: name, style: 'subcategory', colspan: 10},
'', '', '', '', '', '', '', '', ''
]
];
_.forEach(data, function (product) {
subcategory.push(renderProduct(product));
});
return subcategory;
}
function renderProduct(product) {
return [
product.name,
{
text: (product.isInPrivateList ? 'Oui' : ''),
style: 'flag'
},
{
text: (null === product.rank ? '' : String(product.rank)),
style: 'flag'
},
{
text: (product.origin || ''),
style: 'flag'
},
{
text: (product.transporter || ''),
style: 'flag'
},
{
text: (product.label || ''),
style: 'flag'
},
{
text: (product.culture || ''),
style: 'flag'
},
{
text: product.unit,
margin: [0, 0, 5, 0],
italics: true,
alignment: 'right'
},
{
text: (product.quantity || '1'),
italics: true,
fillColor: '#eee',
alignment: 'center'
},
{
text: product.unitPrice,
margin: [0, 0, 5, 0],
italics: true,
fillColor: '#eee',
alignment: 'right'
}
];
}
function logo() {
return 'data:image/jpeg;base64,blabla bigbase64 string'
}
}]);
You could use a Web Worker to generate the PDF. But you should be aware of some restrictions when using them. Here is a good reference.
I created a factory in Angular for doing work on a worker thread. Something like this:
/*
Here's an example on how to get this sack of moldering spuds to do something:
var myWorker = new MyWorker({ fn: function() {
this.onmessage = function(args) {
setTimeout(function() {
this.postMessage('Got args: ' + args.data);
}, 20000);
};
} });
myWorker.do('Test').then(function(message) {
alert(message);
});
*/
'use strict';
angular.module('myApp')
.factory('MyWorker', function($q) {
var _worker;
var MyWorker = function(settings) {
_init(settings);
};
MyWorker.prototype.do = function(args) {
var deferred = $q.defer();
_worker.onmessage = function(message) {
deferred.resolve(message.data);
};
//Fire up the blades.
if (args)
_worker.postMessage(args);
else
_worker.postMessage();
return deferred.promise;
};
MyWorker.prototype.destroy = function() {
_worker.terminate();
};
function _init(settings) {
if (settings.script)
_worker = new Worker(settings.script);
//Need to make this IE (10+) friendly.
else if (settings.fn) {
var blobUrl = window.URL.createObjectURL(new Blob(
['(', settings.fn.toString(), ')()'],
{ type: 'application/javascript' }
));
_worker = new Worker(blobUrl);
}
};
return MyWorker;
});
This will give you a rough idea about how it can be implemented in AngularJS, but seriously take it with a grain of salt.
I am trying to use Fuelux repeater for one of my projects but I cant figure out how to populate data using javascript. The examples they have provided use couple of other plugins(Require.js and underscore.js) and I am not familiar with those. Can someone please help me to do this without any other plugins. I removed all require methods in the code but that didnt work either. Please look at this fiddle for what I have so far.
/*!
* JavaScript for Fuel UX's docs - Repeater Examples
* Copyright 2011-2014 ExactTarget, Inc.
* Licensed under the Creative Commons Attribution 3.0 Unported License. For
* details, see http://creativecommons.org/licenses/by/3.0/.
*/
define function(require){
// var $ = require('jquery');
// var _ = require('underscore');
var colors = {
bug: '#A8B820',
dark: '#705848',
dragon: '#7038F8',
electric: '#F8D030',
fairy: '#EE99AC',
fighting: '#C03028',
fire: '#F08030',
flying: '#A890F0',
ghost: '#705898',
grass: '#78C850',
ground: '#E0C068',
ice: '#98D8D8',
normal: '#A8A878',
poison: '#A040A0',
psychic: '#F85888',
rock: '#B8A038',
steel: '#B8B8D0',
water: '#6890F0'
};
var columns = [
{
label: 'Name',
property: 'name',
sortable: true
},
{
label: 'Id',
property: 'id',
sortable: true
},
{
label: 'Type',
property: 'type',
sortable: true
},
{
label: 'Height (in)',
property: 'height',
sortable: true
},
{
label: 'Weight (lbs)',
property: 'weight',
sortable: true
},
{
label: 'Abilities',
property: 'abilities',
sortable: true
},
{
label: 'Weakness',
property: 'weakness',
sortable: true
}
];
var delays = ['300', '600', '900', '1200'];
var pokemon = [{
"abilities": "Overgrow",
"weight": "15.2",
"weakness": "fire, flying, ice, psychic",
"height": "28.0",
"id": "001",
"name": "Bulbasaur",
"ThumbnailAltText": "Bulbasaur",
"ThumbnailImage": "http://assets2.pokemon.com/assets/cms2/img/pokedex/detail/001.png",
"type": "grass, poison"
},
{
"abilities": "Overgrow",
"weight": "28.7",
"weakness": "fire, flying, ice, psychic",
"height": "39.0",
"id": "002",
"name": "Ivysaur",
"ThumbnailAltText": "Ivysaur",
"ThumbnailImage": "http://assets3.pokemon.com/assets/cms2/img/pokedex/detail/002.png",
"type": "grass, poison"
},
{
"abilities": "Overgrow, Thick Fat",
"weight": "342.8",
"weakness": "fire, psychic, flying, ice",
"height": "94.0",
"id": "003",
"name": "Venusaur",
"ThumbnailAltText": "Venusaur",
"ThumbnailImage": "http://assets4.pokemon.com/assets/cms2/img/pokedex/detail/003.png",
"type": "grass, poison"
}];
var dataSource, filtering;
// require('bootstrap');
// require('fuelux');
dataSource = function(options, callback){
var items = filtering(options);
var resp = {
count: items.length,
items: [],
page: options.pageIndex,
pages: Math.ceil(items.length/(options.pageSize || 50))
};
var i, items, l;
i = options.pageIndex * (options.pageSize || 50);
l = i + (options.pageSize || 50);
l = (l <= resp.count) ? l : resp.count;
resp.start = i + 1;
resp.end = l;
if(options.view==='list' || options.view==='thumbnail'){
if(options.view==='list'){
resp.columns = columns;
for(i; i<l; i++){
resp.items.push(items[i]);
}
}else{
for(i; i<l; i++){
resp.items.push({
color: colors[items[i].type.split(', ')[0]],
name: items[i].name,
src: items[i].ThumbnailImage
});
}
}
setTimeout(function(){
callback(resp);
}, delays[Math.floor(Math.random() * 4)]);
}
};
filtering = function(options){
var items = $.extend([], pokemon);
var search;
if(options.filter.value!=='all'){
items = _.filter(items, function(item){
return (item.type.search(options.filter.value)>=0);
});
}
if(options.search){
search = options.search.toLowerCase();
items = _.filter(items, function(item){
return (
(item.name.toLowerCase().search(options.search)>=0) ||
(item.id.toLowerCase().search(options.search)>=0) ||
(item.type.toLowerCase().search(options.search)>=0) ||
(item.height.toLowerCase().search(options.search)>=0) ||
(item.weight.toLowerCase().search(options.search)>=0) ||
(item.abilities.toLowerCase().search(options.search)>=0) ||
(item.weakness.toLowerCase().search(options.search)>=0)
);
});
}
if(options.sortProperty){
items = _.sortBy(items, function(item){
if(options.sortProperty==='id' || options.sortProperty==='height' || options.sortProperty==='weight'){
return parseFloat(item[options.sortProperty]);
}else{
return item[options.sortProperty];
}
});
if(options.sortDirection==='desc'){
items.reverse();
}
}
return items;
};
// REPEATER
$('#repeaterIllustration').repeater({
dataSource: dataSource
});
$('#myRepeater').repeater({
dataSource: dataSource
});
$('#myRepeaterList').repeater({
dataSource: dataSource
});
$('#myRepeaterThumbnail').repeater({
dataSource: dataSource,
thumbnail_template: '<div class="thumbnail repeater-thumbnail" style="background: {{color}};"><img height="75" src="{{src}}" width="65"><span>{{name}}</span></div>'
});
}
You seem to be doing everything right.. Only thing you had to do was load jQuery on onLoad and comment out define function(require) statement..
JSFiddle