AngularJS NG-CSV files not downloading - angularjs

I am fairly new to AngularJS, i am trying to generate .csv files from an Array using ng-csv.
Now i have tried everything but the files are not generated, i even tried the most simple example i could see on the internet.
I do not see any errors in the error console but still no files are generated.
I am working under windows with XAMPP.
<!DOCTYPE html>
<html ng-app="APP">
<head>
<meta charset="UTF-8">
<title>angular-count-to example</title>
<style type="text/css">
.element{cursor:pointer;float:left;background-color:#ccc;padding:4px;}
</style>
</head>
<body ng-controller="ExampleController">
<p>{{data}}</p>
<button type="button" ng-csv="data" filename="test.csv">Export</button>
<script type="text/javascript" src="bower_components/angular/angular.min.js"></script>
<script type="text/javascript" src="bower_components/angular-sanitize/angular-sanitize.min.js"></script>
<script type="text/javascript" src="bower_components/ng-csv/src/ng-csv/ng-csv.js"></script>
<script>
angular.module('APP',["ngSanitize","ngCsv"]).
controller('ExampleController', function ($scope) {
$scope.filename = "test";
$scope.data = [{a: 1, b:2}, {a:3, b:4}];
});
</script>
</body>
</html>
Above is the simplest example i tried, however even this is not working.

Try out a pure HTML5 Solution. This was a code block i did a while ago. Try customizing for yourself by excluding useless paramaters
function (JSONData, ReportTitle, ShowLabel, reportType, reportName) {
//If JSONData is not an object then JSON.parse will parse the JSON string in an Object
var arrData = typeof JSONData != 'object' ? JSON.parse(JSONData) : JSONData;
angular.forEach(arrData, function (data, index) {
if (data.date != undefined)
data.date = dateFormat(data.date)
});
var CSV = '';
//Set Report title in first row or line
CSV += ReportTitle + '\r\n\n';
//This condition will generate the Label/Header
if (ShowLabel) {
var row = "";
//This loop will extract the label from 1st index of on array
for (var index in arrData[0]) {
row += index + ';';
}
row = row.slice(0, -1);
//append Label row with line break
CSV += row + '\r\n';
}
//1st loop is to extract each row
for (var i = 0; i < arrData.length; i++) {
var row = "";
//2nd loop will extract each column and convert it in string comma-seprated
for (var index in arrData[i]) {
//var temp = arrData[i][index].toString().replace('.', ',');
//arrData[i][index] = temp;
row += '"' + arrData[i][index] + '";';
}
row = row.split('.').join(",");
row.slice(0, row.length - 1);
//add a line break after each row
CSV += row + '\r\n';
}
if (CSV == '') {
alert("Invalid data");
return;
}
//Generate a file name
var fileName = "MyReport_";
//this will remove the blank-spaces from the title and replace it with an underscore
fileName += ReportTitle.replace(/ /g, "_");
//Initialize file format you want csv or xls
var uri = 'data:text/csv;charset=utf-8,' + escape(CSV);
// Now the little tricky part.
// you can use either>> window.open(uri);
// but this will not work in some browsers
// or you will not get the correct file extension
//this trick will generate a temp <a /> tag
var link = document.createElement("a");
link.href = uri;
//set the visibility hidden so it will not effect on your web-layout
link.style = "visibility:hidden";
link.download = fileName + ".csv";
//this part will append the anchor tag and remove it after automatic click
document.body.appendChild(link);
link.click();
document.body.removeChild(link);
};

It looks like you are linking to the wrong ng-csv.js. The ng-csv.js file in the bower_components/ng-csv/src/ng-csv/ folder doesn't contain all of the code, you need to use the build version. Try this:
<script type="text/javascript" src="bower_components/ng-csv/build/ng-csv.js"></script>

Related

Why variable tbl defined by document.getElementById('table') returns null?

I am trying to appendColumn to existing table with data downloaded from textfile (numbers without user names). Below is my code and output.
<!DOCTYPE html>
<html>
<head>
<meta content="text/html;charset=utf-8" http-equiv="Content-Type">
<meta content="utf-8" http-equiv="encoding">
<title>Read Text File</title>
</head>
<body>
<input type="file" name="inputfile"
id="inputfile">
<br>
<pre id="output"></pre>
<script>
var flag1=false;
var file = document.getElementById('inputfile');
var txtArr = [];
file.addEventListener('change', () =>
{
var fr = new FileReader();
fr.onload = function()
{
// By lines
var lines = this.result.split('\n');
for (var line = 0; line < lines.length; line++)
{
txtArr.push(lines[line].split(" "));
}
}
fr.readAsText(file.files[0]);
});
console.log(flag1);
// document.getElementById('output').textContent=txtArr.join("");
//document.getElementById("output").innerHTML = txtArr[0];
// console.log(txtArr[2]);
function generate_table()
{
if ( typeof(document.getElementsByTagName("table")[0]) !="undefined" )
{
document.getElementsByTagName("table")[0].remove();
}
// get the reference for the body
var body = document.getElementsByTagName("body")[0];
// creates a <table> element and a <tbody> element
var tbl = document.createElement("table"),thead = document.createElement('thead');
var tblBody = document.createElement("tbody");
// creating all cells
if (flag1 == false)
{
th = document.createElement('th'),
th.innerHTML="Name";
tbl.appendChild(th);
th = document.createElement('th');
th.innerHTML= "Sample1";
tbl.appendChild(th);
tbl.appendChild(thead);
tbl.appendChild(tblBody);
}//endif flag1=false
else
{
th = document.createElement('th');
th.innerHTML= "Sample2";
tbl.appendChild(th);
tbl.appendChild(thead);
tbl.appendChild(tblBody);
}
for (var i = 0; i < txtArr.length-1; i++)
{
// creates a table row
var row = document.createElement("tr");
for (var j = 0; j < 2; j++)
{
var cell = document.createElement("td");
var cellText = document.createTextNode(txtArr[i][j]);
cell.appendChild(cellText);
row.appendChild(cell);
tblBody.appendChild(row);
}
flag1=true;
// put the <tbody> in the <table>
tbl.appendChild(tblBody);
// appends <table> into <body>
body.appendChild(tbl);
// sets the border attribute of tbl to 2;
tbl.setAttribute("border", "2");
}
txtArr=[];
}
/////////// testing problems here /////////////////////
function testing()
{
var tbl = document.getElementById('table'),thead = document.createElement('thead'),i;
var tblBody = document.createElement("tbody");
for (i = 0; i < tbl.rows.length; i++) {}
}
/////////// end of testing ////////////////////////////
function appendColumn()
{ var tbl = document.getElementById("table"),thead = document.createElement('thead'), // table reference
i;
// open loop for each row and append cell
for (i = 0; i < tbl.rows.length; i++) {
createCell(tbl.rows[i].insertCell(tbl.rows[i].cells.length), i, 'col');}
}
// create DIV element and append to the table cell
function createCell(cell, text, style) {
var div = document.createElement('div'), // create DIV element
txt = document.createTextNode(text); // create text node
div.appendChild(txt); // append text node to the DIV
div.setAttribute('class', style); // set DIV class attribute
div.setAttribute('className', style); // set DIV class attribute for IE (?!)
cell.appendChild(div); // append DIV to the table cell
}
// delete table columns with index greater then 0
function deleteColumns() {
// if ( typeof(document.getElementsByTagName("table")[0]) !="undefined" )
// {
// document.getElementsByTagName("table")[0].remove();
// }
// get the reference for the body
// var body = document.getElementsByTagName("body")[0];
// creates a <table> element and a <tbody> element
var tbl = document.getElementById("table"), // table reference
lastCol = tbl.rows[0].cells.length - 1, // set the last column index
i, j;
// delete cells with index greater then 0 (for each row)
for (i = 0; i < tbl.rows.length; i++) {
for (j = lastCol; j > 0; j--) {
tbl.rows[i].deleteCell(j);
}
}
}
</script>
<input type="button" value="Generate a table." onclick="generate_table()">
<input type="button" value="Add column" onclick="appendColumn()">
<input type="button" value="Delete columns" onclick="deleteColumns()">
<input type="button" value="testing" onclick="testing()">
<table id="table">
</body>
</html>
I use browse button to download txt file with user names and their grades. After clicking generate table the output is,
if I want add new grades from new text file called sample2.txt it has the same list of names but with different grades. I browse again and use appendColumn function to create a new column in existing table. However, it does not work. I broke down this problem using testing button. I found out that tbl variable is empty inside For loop. Obviously I am doing something wrong with recall of existing table tbl. How do you recall the existing variable tbl already defined previously by generate_table function?
To make it work I declared tbl globally by placing this code line just below line,
var tbl = document.getElementById('table');
and removed tbl declaration from each function.

How to create autogenerate ID in angular?

Want to create autogenerate code in angular inputbox on refresh page
like rand(function) in php. Im using this script for this. But problem
is its vanished on page refresh not working properly.
<script type="text/javascript">
function randString(x){
var s = "OL-";
while(s.length<x&&x>0){
var r = Math.random();
s+= (r<0.1?Math.floor(r*100):String.fromCharCode(Math.floor(r*26) + (r>0.5?97:65)));
}
return s;
}
document.getElementById("referal_code").value = randString(10);
</script>
<input required type='text' class='span2' id='referal_code' ng-model='empInfo.referal_code'>
Try this
<!DOCTYPE html>
<html>
<head>
<script type="text/javascript">
function getNewID() {
try {
var myDate = new Date();
var varID = myDate.getHours() + "" + myDate.getMinutes() + "" + myDate.getSeconds() + "" + myDate.getMilliseconds();
if (varID.Length > 15) {
varID = varID.substr(0, 15);
}
return varID;
} catch (e) {
console.log(e.message);
}
}
function randString(x){
var s = getNewID();
return s;
}
window.onload = function(){
document.getElementById("referal_code").value = randString(10);
}
</script>
</head>
<body>
<input required type='text' class='span2' id='referal_code' ng-model='empInfo.referal_code'>
</body>
</html>
For any attribute in angular world you can use interpolation like this:
<input id="{{randString(10)}}"/>
If you want to have a certain value as id and not get lost after refresh you have to save it on some web storage (localstorage, sessionstorage).
e.g. :
function randString(x){
// ... your function's logic
//Save it in localStorage before returning it
localStorage.inputId = s;
return s;
}
document.getElementById("referal_code").value = localStorage.inputId || randString(10)

ngRepeat dont refresh when I change the values - AngularJS

I'm doing a application to a calendar and I create a function that everytime change the values of my variable called "$scope.days", when I was using the version 1.0 didnt give error, but now the ngRepeat doesnt refresh, the new values go to the variable, but the ngRepeat dont show the new result...
$scope.loadMonth = function()
{
$scope.titleCalendar = $scope.months[$scope.month-1].name + ' ' + $scope.year;
getTotalFebruary($scope.year);
var dtString = $scope.year + '/' + $scope.month + '/' + 1,
date = new Date(dtString),
day = 1,
weekday = date.getDay(),
totalDays = $scope.months[date.getMonth()].qty + date.getDay();
$scope.days = [];
for(var i = 0; i < totalDays; i++)
{
if(i < weekday)
$scope.days.push('');
else
$scope.days.push(day++);
}
};
my html:
<div class="day" ng-repeat="day in days"><p>{{ day }}</p></div>
If I put an alert after push new values, I can see the new values, but my ngRepeat doesnt refresh the results, I already try many things but didnt work. Somebody know the solution?
Not sure I understand what you are trying to achieve given the small sample of code you provided but if you look at this sample you'll see that it should update the display every time you click the click me text, just enter either 1,2, or 3 in the input area. you might want to check that looping logic of yours.
<html lang="en-US" ng-app="mainModule">
<head>
<meta charset="UTF-8">
<title></title>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.4/angular.min.js"></script>
</head>
<body>
<div ng-controller="mainController">
<input type="text" ng-model="monthModel" placeholder="enter 1 2 or 3"/>
<h1 ng-click="loadMonth(monthModel)">Click Me to Repeat</h1>
<span class="day" ng-repeat="day in days">{{ day }} , </span>
</div>
<script type="text/javascript">
var app = angular.module("mainModule", []);
app.controller("mainController", function ($scope) {
//$scope.monthModel = 1; // default some date
$scope.year = "2014";
$scope.months = [
{"name":"January", "qty":10},
{"name":"February", "qty":5},
{"name":"March", "qty":10},
];
$scope.loadMonth = function(monthModel)
{
$scope.month = monthModel;
$scope.titleCalendar = $scope.months[$scope.month-1].name + ' ' + $scope.year;
//getTotalFebruary($scope.year);
var dtString = $scope.year + '/' + $scope.month + '/' + 1,
date = new Date(dtString),
day = 1,
weekday = date.getDay(),
totalDays = $scope.months[date.getMonth()].qty + date.getDay();
$scope.days = [];
for(var i = 0; i < totalDays; i++)
{
//if(i < weekday)
// $scope.days.push('');
//else
$scope.days.push(day++);
console.log($scope.days) ;
}
};
});
</script>
</body>
</html>

gmap4rails box showing up under map won't go away

There's this box that I can get to go away under my maps. I have a main map for my index and another map for show. I have the map options different for both of them. When I look at my page source I see my scripts for both maps. I can't figure out why this is happening.
<script type="text/javascript" charset="utf-8">
Gmaps.map = new Gmaps4RailsGoogle();
Gmaps.load_map = function() {
Gmaps.map.map_options.auto_adjust = true;
Gmaps.map.initialize();
Gmaps.map.markers = [{"description":"test, 217 cleveland ave , liverpool, This is some additional information.","lat":43.1155,"lng":-76.2292},{"description":"bah, 215 university place, syracuse, ","lat":43.0396,"lng":-76.1355}];
Gmaps.map.markers_conf.do_clustering = true;
Gmaps.map.create_markers();
Gmaps.map.adjustMapToBounds();
Gmaps.map.callback();
};
window.onload = function() { Gmaps.loadMaps(); };
</script>
<script type="text/javascript" src="//maps.google.com/maps/api/js?v=3.8&sensor=false&libraries=geometry&language=&hl=&region="></script>
`<script type="text/javascript" charset="utf-8">
Gmaps.map = new Gmaps4RailsGoogle();
Gmaps.load_map = function() {
Gmaps.map.map_options.auto_adjust = true;
Gmaps.map.map_options.auto_zoom = false;
Gmaps.map.map_options.zoom = 10;
Gmaps.map.map_options.detect_location = true;
Gmaps.map.map_options.center_on_user = false;
Gmaps.map.initialize();
Gmaps.map.markers = [{"description":"test, 217 cleveland ave , liverpool, This is some additional information.","lat":43.1155,"lng":-76.2292},{"description":"bah, 215 university place, syracuse, ","lat":43.0396,"lng":-76.1355}];
Gmaps.map.create_markers();
Gmaps.map.adjustMapToBounds();
Gmaps.map.callback();
};
window.onload = function() { Gmaps.loadMaps(); };
</script>`
I fixed it by making .map_container twice as small as the map height. My map height is 400px and my map container height is 200px. I still don't know why that would happen.

Loop thru 100 background-images onClick

a) I have 100 body-background images
b) and a single link
The background image should change to the next one in the lot every time the link is clicked, going thru the lot one by one (would be nice if the name/number of current image also is displayed).
The images are all in a dedicated directory. jQuery is already loaded.
Anyone know where I can find the code to do this simply?
All the best...
var allImages = ["path/to/image2", "path/to/image1"];
$(document).ready(function() {
$("#theLink").click(function() {
var newImageLink = allImages.pop();
$("body").css("background-image", "url(" + newImageLink + ")");
});
});
You don't necessarily need to hard code the path to your images that way. You can name your images something like image_xxx.png, 1 - 100 and refer to that name in one place. That way if you ever need to change the name, you can easily do it in one place. Furthermore, make sure that the href attribute of the anchor tag is set to # to prevent page reloads on each click.
Here's a more complete solution that also does range checking and it wraps around when we reach our limit:
<script language="javascript" type="text/javascript">
<!--
var ctr = 0;
$(document).ready( function () {
nextBg();
});
function nextBg()
{
++ctr;
if( ctr <= 100 )
{
$("body").css( "background-image", "url(images/image_" + ctr + ".png)" );
$("#message").text("Current image: " + "image_" + ctr + ".png");
if( ctr == 100 )
ctr = 0;
}
}
//-->
</script>
</head>
<body>
<div>
<span id="message"></span><br />
<a href="#" onclick="nextBg();" />Next</a>
</div>
</body>
(added counter to gs' answer)
var allImages = ["path/to/image2", "path/to/image1"];
var counter = 0;
$(document).ready(function() {
$("#theLink").click(function() {
var newImageLink = allImages.pop();
$("body").css("background-image", "url(" + newImageLink + ")");
$("#displayhere").html("<b>"+ counter +"</b>");
counter = counter + 1;
});
});

Resources