change() for select element is not working - javascript

I am learning Nodejs with node cookbook 2nd edition.
I like this book because it is teaching us with explaining sample code which looks very practical.
The example code is part of Browser-server transmission via AJAX part
Anyway the main question is that below is in the EX code, below is index.html file
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<script>
$.get("http://localhost:8080/profiles",function (profile_names) {
$.each(profile_names, function (i, pname) {
$("#profiles").append("<option>" + pname + "</option>");
});
}, "json");
$("#formats, #profiles").change(function () {
alert("2");
var format = $("#formats").val();
$.get("http://localhost:8080/profile/" + $("#profiles").val() + "." + format,
function (profile, stat, jqXHR) {
var cT = jqXHR.getResponseHeader("Content-Type");
$("#raw").val(profile);
$("#output").html('');
if (cT === "application/json") {
$.each($.parseJSON(profile), function (k, v) {
$("#output").append("<b>" + k + "</b> : " + v + "<br>");
});
return;
}
if (cT === "application/xml") {
profile = jqXHR.responseXML.firstChild.childNodes;
$.each(profile, function (k, v) {
if (v && v.nodeType === 1) {
$("#output").append("<b>" + v.tagName + "</b> : " + v.textContent + "<br>");
}
});
}
},
"text");
});
</script>
<style>
#frm, #raw {display:block; float:left; width:210px},
#raw {height:150px; width:310px; margin-left:0.5em}
</style>
<title> INDEX </title>
</head>
<body>
<form id="frm">
Profile: <select id="profiles">
<option> </option>
</select>
<br></br>
Format:<select id="formats">
<option value="json"> JSON </option>
<option value="xml"> XML </option>
</select>
<br></br>
<div id="output"></div>
</form>
<textarea id="raw"></textarea>
</body>
</html>
Second, server.js file
var http = require('http');
var fs = require('fs');
var path = require('path');
var profiles = require('./profiles');
var xml2js = require('xml2js');
var index = fs.readFileSync('index.html');
var routes, mimes = {xml: "application/xml", json: "application/json"}
function output(content, format, rootNode) {
if (!format || format === 'json') {
return JSON.stringify(content);
}
if (format === 'xml') {
return (new xml2js.Builder({rootName: rootNode})).buildObject(content);
}
}
routes = {
'profiles': function (format) {
return output(Object.keys(profiles), format);
},
'/profile': function (format, basename) {
return output(profiles[basename], format, basename);
}
};
http.createServer(function (request, response) {
var dirname = path.dirname(request.url),
extname = path.extname(request.url),
// $.get('http://localhost:8080/profile/' + $('#profiles').val() + '.' + format
basename = path.basename(request.url, extname);
extname = extname.replace('.', ''); //remove period
response.setHeader("Content-Type", mimes[extname] ||'text/html');
if (routes.hasOwnProperty(dirname)) {
response.end(routes[dirname](extname, basename));
return;
}
if (routes.hasOwnProperty(basename)) {
response.end(routes[basename](extname));
return;
}
response.end(index);
}).listen(8080);
below is profiles.js file
module.exports = {
ryan: {
name: "Ryan Dahl",
irc: "ryah",
twitter: "ryah",
github: "ry",
location: "San Francisco, USA",
description: "Creator of node.js"
},
isaac: {
name: "Isaac Schlueter",
irc: "isaacs",
twitter: "izs",
github: "isaacs",
location: "San Francisco, USA",
description: "Former project gatekeeper, CTO npm, Inc."
}
};
I think at index file $("#formats, #profiles").change(function () { is not working.
I just input alert("2"); to test the code but I have never seen the alert.
I also tried to change code like
$("#formats").change(function () {,
$("#profiles").change(function () {
Both of them were not working neither.
Can you let me know what is the reason?

Either wrap your client-code in a DOM ready statement or move it to the end of the <body>. Your script is being executed before the page has rendered.

Related

Accessing the Forge Viewer From Two HTML Files

I have been working on a website incorporating the autodesk-forge viewer (more details can be seen on my past questions). I have successfully made many autodesk-forge viewer functions in a standard javascript (.js) file. These functions include displaying the viewer, and isolating to a particular part, when an external button is pressed.
Currently I have a main html/php home page where I have included my javascript file with all my forge functions using <script src="MyForgeFunctions.js"></script>
These functions are accessed through a button, which successfully displays the viewer in the html page. Attached to my main php/html page, another html/php page was added through an iframe html reference (<iframe src="URL.php"></iframe>). My home page displays the main machines we make, while the embedded php/html page displays all the stations within the machine. I have also included the MyForgeFunctions.js inside this second php/html page. Because of the way the website is set up, I need to be able to access the viewer in both web pages. However, when I attempt to access the viewer from the second html page, I get a message that the viewer is undefined. Below is my code from MyForgeFunctions.js.
var ext = '';
var dim = '';
var assemblyname = '';
function getAssemblyName(){
assemblyname = sessionStorage.getItem("assemblyName");
//var ext = partname.substr(partname.lastIndexOf('.'));
ext = assemblyname.split('.');
dim = ext[0] + ':1';
console.log(assemblyname);
console.log(dim);
if (dim !== ''){
isolateSelected();
}
}
//function to get part name from __MachineParts.php
var partname = '';
var extension = '';
var namewithoutextension = '';
function getPartName(){
partname = sessionStorage.getItem("partName");
//var ext = partname.substr(partname.lastIndexOf('.'));
extension = partname.split('.');
namewithoutextension = extension[0] + ':1'
console.log(partname);
console.log(namewithoutextension);
if (namewithoutextension !== ''){
isolateSelectedPart();
}
}
/*******************************************************************************
*
* AUTODESK FORGE VIEWER CODE (HTTP REQUESTS)
*
*******************************************************************************/
//VARIABLE DECLARATION
var code = '';
var access_token = '';
const hub = 'xxxxxxxxxxxxxxxxxxxxxxxxxxx';
const project ='xxxxxxxxxxxxxxxxxxxxxxxxxxx';
const folder='xxxxxxxxxxxxxxxxxxxxxxxxx';
const item = 'xxxxxxxxxxxxxxxxxxxxxxxxx';
var itemid = '';
var urn = '';
var urn2 = '';
//allow the program to view data from autodesk
function authorize(){
window.location.href = "https://developer.api.autodesk.com/authentication/v1/authorize?response_type=code&client_id=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&redirect_uri=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx&scope=data:read data:write bucket:read viewables:read bucket:create data:create";
}
//grab the code from the url
function getCode(){
const querystring = window.location.search;
// console.log(querystring);
const urlParams = new URLSearchParams(querystring);
code = urlParams.get('code');
// console.log(code);
}
//call the function to get the code right away, and obtain a token
getCode();
getToken();
//function to obtain access token
function getToken(){
$.ajax({
method: 'POST',
url: 'https://developer.api.autodesk.com/authentication/v1/gettoken',
headers: {
'Content-Type':'application/x-www-form-urlencoded'
},
data:'client_id=dm2VLfnwJ6rYHKPAg7dG6l9yVbBQPGlH&client_secret=HRMpOPusLhsVoIMk&grant_type=authorization_code&code=' + code + '&redirect_uri=http://team/__MachineViewerMV.php',
success:function(response){
// console.log(response);
access_token = response.access_token;
console.log(access_token);
}
})
}
//Grab desired file id from project folder
function getItem(){
$.ajax({
method:'GET',
url: 'https://developer.api.autodesk.com/data/v1/projects/' + project + '/folders/' + item + '/contents',
headers:{
Authorization:'Bearer ' + access_token
},
/* beforeSend:function(before){
if(access_token !== '' && viewer !==''){
destroyViewer();}
},*/
success:function(response){
//console.log(response);
// folder = response.data[0].id;
// console.log(folder);
// itemid = response.data[0].id;
//console.log(itemid);
console.log(response);
for (var i = 0; i<response.data.length; i++){
//console.log(response.data[i].attributes.displayName);
if(response.data[i].attributes.displayName == fileName){
//console.log('hooray');
itemid = response.data[i].id;
console.log(itemid);
getVersion();
break;
}
else if (response.data[i].attributes.displayName !== fileName){
itemid = '';
}
}
},
error:function(error){
authorize();
}
})
}
function get2dItem(){
$.ajax({
method:'GET',
url: 'https://developer.api.autodesk.com/data/v1/projects/' + project + '/folders/' + item + '/contents',
headers:{
Authorization:'Bearer ' + access_token
},
/*beforeSend:function(before){
if(access_token !== '' && viewer !== ''){
destroyViewer();}
},*/
success:function(response){
//console.log(response);
// folder = response.data[0].id;
// console.log(folder);
// itemid = response.data[0].id;
//console.log(itemid);
console.log(response);
for (var i = 0; i<response.data.length; i++){
//console.log(response.data[i].attributes.displayName);
if(response.data[i].attributes.displayName == fileName2d){
//console.log('hooray');
itemid = response.data[i].id;
console.log(itemid);
getVersion();
break;
}
else if (response.data[i].attributes.displayName !== fileName2d){
itemid = '';
}
}
},
error:function(error){
authorize();
}
})
}
//get version of the file using its id
function getVersion(){
$.ajax({
method:'GET',
url: 'https://developer.api.autodesk.com/data/v1/projects/' + project + '/items/' + itemid + '/versions',
headers:{
Authorization:'Bearer ' + access_token
},
success:function(response){
//console.log(response);
urn = btoa(response.data[0].relationships.storage.data.id);
console.log(urn);
translateToSVF();
}
})
}
function translateToSVF(){
$.ajax({
method: 'POST',
url:"https://developer.api.autodesk.com/modelderivative/v2/designdata/job",
headers:{
"content-type": "application/json",
Authorization: "Bearer " + access_token
},
data:JSON.stringify({
"input":{ "urn":urn
},
"output": {
"formats": [
{
"type": "svf",
"views": [
"2d",
"3d"
]
}
]
}
}),
success:function(response){
// console.log(response);
urn2 = response.urn;
console.log(urn2);
checkStatus();
}
})
}
function checkStatus(){
$.ajax({
method: 'GET',
url: "https://developer.api.autodesk.com/modelderivative/v2/designdata/" + urn2 + "/manifest",
headers:{
Authorization: "Bearer " + access_token
},
success: function(response){
console.log(response);
if (response.progress == 'complete'){
displayViewer();
}
else if (response.progress !== 'complete'){
alert('File Still Uploading, Press the Display Button Again!');
}
}
})
}
//function to get list of viewables\
var guid = '';
function getViewable(){
$.ajax({
method:'GET',
headers:{
Authorization: "Bearer " + access_token
},
url: 'https://developer.api.autodesk.com/modelderivative/v2/designdata/' + urn2 + '/metadata',
success:function(response){
console.log(response);
guid = response.data.metadata[0].guid;
console.log(guid);
}
})
}
//funciton to get the list of items within a model
function getTree(){
$.ajax({
method: 'GET',
headers:{
Authorization: "Bearer " + access_token
},
url:'https://developer.api.autodesk.com/modelderivative/v2/designdata/' + urn2 + '/metadata/' + guid + '/properties',
success:function(response){
console.log(response);
}
})
}
/**********************************************************************************
*
* FUNCTION TO DISPLAY THE VIEWER IN THE HTML PAGE
*
**********************************************************************************/
var viewer;
function displayViewer(){
//var viewer;
var options = {
env: 'AutodeskProduction',
api: 'derivativeV2', // for models uploaded to EMEA change this option to 'derivativeV2_EU'
getAccessToken: function(onTokenReady) {
var token = access_token;
console.log(token);
var timeInSeconds = 3600; // Use value provided by Forge Authentication (OAuth) API
onTokenReady(token, timeInSeconds);
}
};
Autodesk.Viewing.Initializer(options, function() {
var htmlDiv = document.getElementById('forgeViewer');
viewer = new Autodesk.Viewing.Private.GuiViewer3D(htmlDiv);
var startedCode = viewer.start();
// sessionStorage.setItem("viewer", viewer);
if (startedCode > 0) {
console.error('Failed to create a Viewer: WebGL not supported.');
return;
}
console.log('Initialization complete, loading a model next...');
});
var documentId = 'urn:'+urn2;
Autodesk.Viewing.Document.load(documentId, onDocumentLoadSuccess, onDocumentLoadFailure);
function onDocumentLoadSuccess(viewerDocument) {
var defaultModel = viewerDocument.getRoot().getDefaultGeometry();
viewer.loadDocumentNode(viewerDocument, defaultModel);
console.log(viewer);
}
function onDocumentLoadFailure() {
console.error('Failed fetching Forge manifest');
}
}
//function to hide the viewer
function destroyViewer(){
console.log(viewer);
viewer.finish();
viewer = null;
Autodesk.Viewing.shutdown();
}
/*****************************************************************************
* FUNCTIONS TO MODIFY THE VIEWER TO ZOOM INTO THE CORRECT PART/ASSEMBLY
*/
function isolateSelected(){
console.log(dim);
console.log(viewer);
viewer.search(dim, function(dbIds) {
// viewer.search('"' + 'M-109408 FOLDING PLOUGH:2' + '"', function(dbIds) {
console.log(dbIds.length);
getSubset(dbIds, 'label', dim, function(dbIds) {
// getSubset(dbIds, 'label', 'M-109408 FOLDING PLOUGH:2', function(dbIds) {
// getSubset(dbIds, property.name, 'M-54439 POST TUBING:1', function(dbIds) {
//getSubset(dbIds, property.name, property.value, function(dbIds){
var it = viewer.model.getData().instanceTree;
//console.log(it);
for (i = 0; i<dbIds.length; i++){
var namepart = it.getNodeName(dbIds[i]);
if (namepart !== undefined){
console.log(dbIds);
console.log(namepart);}}
/* for (i = 121; i<381;i++){
var dbId = i;
var it = NOP_VIEWER.model.getData().instanceTree;
var name = it.getNodeName(dbId);
console.log(name);}*/
viewer.isolate(dbIds)
viewer.select(dbIds);
viewer.utilities.fitToView();
})
}, function(error) {})
}
function isolateSelectedPart(){
console.log(namewithoutextension);
viewer.search(namewithoutextension, function(dbIds) {
// viewer.search('"' + 'M-109408 FOLDING PLOUGH:2' + '"', function(dbIds) {
console.log(dbIds.length);
getSubset(dbIds, 'label', namewithoutextension, function(dbIds) {
// getSubset(dbIds, 'label', 'M-109408 FOLDING PLOUGH:2', function(dbIds) {
// getSubset(dbIds, property.name, 'M-54439 POST TUBING:1', function(dbIds) {
//getSubset(dbIds, property.name, property.value, function(dbIds){
var it = viewer.model.getData().instanceTree;
//console.log(it);
for (i = 0; i<dbIds.length; i++){
var namepart = it.getNodeName(dbIds[i]);
if (namepart !== undefined){
console.log(dbIds);
console.log(namepart);}}
/* for (i = 121; i<381;i++){
var dbId = i;
var it = NOP_VIEWER.model.getData().instanceTree;
var name = it.getNodeName(dbId);
console.log(name);}*/
viewer.isolate(dbIds)
viewer.select(dbIds);
viewer.utilities.fitToView();
})
}, function(error) {})
}
//function to find the dbid of the part/assembly
function getSubset(dbIds, name, value, callback) {
console.log("getSubset, dbIds.length before = " + dbIds.length)
viewer.model.getBulkProperties(dbIds, {
propFilter: [name],
ignoreHidden: true
}, function(data) {
var newDbIds = []
for (var key in data) {
var item = data[key]
// console.log(item.properties);
if (item.properties[0].displayValue === value) {
newDbIds.push(item.dbId)
}
}
console.log("getSubset, dbIds.length after = " + newDbIds.length)
callback(newDbIds)
}, function(error) {})
}
Because of how the webpage is set up, when I needed to use a variable from the second web page in the first, I used sessionStorage.getItem and sessionStorage.setItem. I have also made a simple function as so inside MyForgeFunctions.js:
function checkViewer(){
console.log(viewer);
}
I then included a button in both html pages to execute the function with an onclick event. When the function is run from the first/home html page the following is displayed:
T {globalManager: e, clientContainer: div#forgeViewer, container: div.adsk-viewing-viewer.notouch.dark-theme.quality-text, config: {…}, contextMenu: o, …}. Which is normal for the viewer, but when the function is executed from the second html page, the viewer is undefined. Any help as to why this is happening or any solutions will be greatly appreciated. Cheers!
From the iframe, in order to access the viewer inside the main web page, I had to use (parent.viewer).

How to filter by file path in Google apps script

I am trying to have the following script filter by file path. Ideally this should only show results from the folder marked 'GUEST' in my drive. Right now it shows those and anything else with the shared folder ID of this root (I do not want to use the GUEST folder ID because I will later use this to filter other users accessing my drive).
My google drive file path is as follows Root/GUEST
CODE UPDATED WITH ANSWER FROM COMMENTS:
var folderId = "MyID"; // <--- Your shared folder ID
function doGet() {
var t = HtmlService.createTemplateFromFile('index');
t.data = getFileList();
return t.evaluate() .setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);;
}
function getparams(e) {
return zipping(typeof(e.fileId) == "string" ? [e.fileId] : e.fileId);
}
function getFileList() {
var folderlist = (function(folder, folderSt, results) {
var ar = [];
var folders = folder.getFoldersByName("GUEST");
while (folders.hasNext()) ar.push(folders.next());
folderSt += folder.getId() + "#_aabbccddee_#";
var array_folderSt = folderSt.split("#_aabbccddee_#");
array_folderSt.pop()
results.push(array_folderSt);
ar.length == 0 && (folderSt = "");
for (var i in ar) arguments.callee(ar[i], folderSt, results);
return results;
})(DriveApp.getFoldersByName("GUEST").next(), "", []);
var localTimeZone = Session.getScriptTimeZone();
var filelist = [];
var temp = {};
for (var i in folderlist) {
var folderid = folderlist[i][folderlist[i].length - 1];
var folder = DriveApp.getFoldersByName("GUEST");
var files = folder.next().getFiles();
while (files.hasNext()) {
var file = files.next();
temp = {
folder_tree: function(folderlist, i) {
if (i > 0) {
return "/" + [DriveApp.getFolderById(folderlist[i][j]).getName() for (j in folderlist[i])
if (j > 0)].join("/") + "/";
} else {
return "/";
}
}(folderlist, i),
file_id: file.getId(),
file_name: file.getName(),
file_size: file.getBlob().getBytes().length,
file_created: Utilities.formatDate(file.getDateCreated(), localTimeZone, "yyyy/MM/dd HH:mm:ss"),
file_updated: Utilities.formatDate(file.getLastUpdated(), localTimeZone, "yyyy/MM/dd HH:mm:ss"),
};
filelist.push(temp);
temp = {}
}
}
var sortedlist = filelist.sort(function(e1, e2) {
return (e1.folder_tree > e2.folder_tree ? 1 : -1) });
return sortedlist;
}
function zipping(fileId) {
var blobs = [];
var mimeInf = [];
fileId.forEach(function(e) {
try {
var file = DriveApp.getFileById(e);
var mime = file.getMimeType();
var name = file.getName();
} catch (e) {
return e
}
Logger.log(mime)
var blob;
if (mime.indexOf('google-apps') > 0) {
mimeInf =
mime == "application/vnd.google-apps.spreadsheet" ? ["application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", name + ".xlsx"] : mime == "application/vnd.google-apps.document" ? ["application/vnd.openxmlformats-officedocument.wordprocessingml.document", name + ".docx"] : mime == "application/vnd.google-apps.presentation" ? ["application/vnd.openxmlformats-officedocument.presentationml.presentation", name + ".pptx"] : ["application/pdf", name + ".pdf"];
blob = UrlFetchApp.fetch("https://www.googleapis.com/drive/v3/files/" + e + "/export?mimeType=" + mimeInf[0], {
method: "GET",
headers: { "Authorization": "Bearer " + ScriptApp.getOAuthToken() },
muteHttpExceptions: true
}).getBlob().setName(mimeInf[1]);
} else {
blob = UrlFetchApp.fetch("https://www.googleapis.com/drive/v3/files/" + e + "?alt=media", {
method: "GET",
headers: { "Authorization": "Bearer " + ScriptApp.getOAuthToken() },
muteHttpExceptions: true
}).getBlob().setName(name);
}
blobs.push(blob);
});
var zip = Utilities.zip(blobs, Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "yyyyMMdd_HHmmss") + '.zip');
var bytedat = DriveApp.createFile(zip).getBlob().getBytes();
return Utilities.base64Encode(bytedat);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.0/jquery.min.js"></script>
<script>
function postLogin(event) {
var form = document.getElementById("myForm");
form.submit();
event.preventDefault();
}
</script>
<a href="" onClick="postLogin(event);" >Click!</a>
<form id="myForm" action="MYEXECLINK" target="my_iframe"></form>
<iframe id="my_iframe"name="my_iframe" style= "width: 500px; height: 50%;" frameBorder="0" style="overflow:hidden"></iframe>
I tried to use an if statement at line 61, but it could not pull the variables for some reason (I think I'm not setting up my variables correctly):
if (filelist(folder_tree == "/GUEST/"){
return sortedlist;}
else
{return null}
Does anyone know how to make this script filter by folder_tree? Hopefully by comparing it to a var (like user=guest)?
To clarify, here is the current result:
And this is the expected output:
Thanks for any help, I'll post updates as I work on it to clarify.
You want to retrieve a file list under the specific folder.
Subfolders in the specific folder are not required to be retrieved.
You want to achieve this using Google Apps Script.
I could understand like above. If my understanding is correct, how about this modification? I think that your updated script works. But I thought that your script might be able to be modified more simple. So how about the following modification?
Modification point:
In this modification, getFileList() was modified.
In your script, at first, the folder tree is retrieved. Then, the files in all folders are retrieved. But in your situation, the folder tree is not required to be retrieved. By this, your script can be modified more simple.
At first, "FileIterator" are retrieved with DriveApp.getFoldersByName("GUEST").next().getFiles(). Then, the values are retrieved from "FileIterator".
Modified script:
function getFileList() {
var folderName = "GUEST";
var files = DriveApp.getFoldersByName(folderName).next().getFiles();
var localTimeZone = Session.getScriptTimeZone();
var filelist = [];
while (files.hasNext()) {
var file = files.next();
var temp = {
file_id: file.getId(),
file_name: file.getName(),
file_size: file.getBlob().getBytes().length,
file_created: Utilities.formatDate(file.getDateCreated(), localTimeZone, "yyyy/MM/dd HH:mm:ss"),
file_updated: Utilities.formatDate(file.getLastUpdated(), localTimeZone, "yyyy/MM/dd HH:mm:ss"),
};
filelist.push(temp);
}
return filelist;
}
References:
getFoldersByName(name)
getFiles()
Class FileIterator

nodejs request url and return json, body is empty

I found an interesting solution here to get the instagram public profile photos.
var name = "smena8m",
items;
$.getJSON("https://query.yahooapis.com/v1/public/yql?callback=?", {
q: "select * from json where url='https://www.instagram.com/" + name + "/?__a=1'",
format: "json"
}, function(data) {
console.log(data);
if (data.query.results) {
items = data.query.results.json.user.media.nodes;
$.each(items, function(n, item) {
$('body').append(
$('<a/>', {
href: 'https://www.instagram.com/p/'+item.code,
target: '_blank'
}).css({
backgroundImage: 'url(' + item.thumbnail_src + ')'
}));
});
}
});
i am trying to do the same in my nodejs app:
var request = require('request');
var name = "smena8m";
var propertiesObject = { q: "select * from json where url='https://www.instagram.com/" + name + "/?__a=1'" };
var myurl = "https://query.yahooapis.com/v1/public/yql?callback=?";
var items;
request.get(myurl, { qs:propertiesObject}, function(err, response, body) {
if(err) { console.log(err); return; }
console.log("Get response: " + response.statusCode);
if (body.data.query.results) {
items = body.data.query.results.json.user.media.nodes;
items.forEach(function(n, item) {
var itemCodes = 'https://www.instagram.com/p/'+item.code;
var thumbnails = item.thumbnail_src;
console.log('here: ', itemCodes, thumbnails);
});
}
});
but my body returns empty. could somebody help me achieve the same in nodejs?
update:
response code is 200 and body is empty.
change myurl to:
myurl='https://www.instagram.com/' +name '/?__a=1';
console.log(body) then and you should be happy!

Download data as Excel file using web api and angular JS

I have a scenario to download file from the web app that uses a) Angular JS as front end b) Web api as server and the browser is IE9.
I have tried lot of plugins for converting HTML table to excel,csv but none of them worked for IE9.So i have decided generate the file in web api and download in the client.But that too does not work.
Can any one share an working example for this scenario ?
Angular JS Code:
var app = angular.module('myApp', []);
app.controller('myCtrl', function ($scope, exportToExcelService) {
$scope.export = function () {
exportToExcelService.download().success(
function (response) {
})
.error(function (response, status) {
});
}
}).
factory('exportToExcelService', function ($http) {
var sampleAPI = {};
sampleAPI.download = function () {
return $http({
method: 'POST',
url: 'api/Sample/download'
});
}
return sampleAPI;
});
Web APi Controller code:
[HttpPost]
public HttpResponseMessage download()
{
List<Record> obj = new List<Record>();
obj = RecordInfo();
StringBuilder str = new StringBuilder();
str.Append("<table border=`" + "1px" + "`b>");
str.Append("<tr>");
str.Append("<td><b><font face=Arial Narrow size=3>FName</font></b></td>");
str.Append("<td><b><font face=Arial Narrow size=3>LName</font></b></td>");
str.Append("<td><b><font face=Arial Narrow size=3>Address</font></b></td>");
str.Append("</tr>");
foreach (Record val in obj)
{
str.Append("<tr>");
str.Append("<td><font face=Arial Narrow size=" + "14px" + ">" + val.FName.ToString() + "</font></td>");
str.Append("<td><font face=Arial Narrow size=" + "14px" + ">" + val.LName.ToString() + "</font></td>");
str.Append("<td><font face=Arial Narrow size=" + "14px" + ">" + val.Address.ToString() + "</font></td>");
str.Append("</tr>");
}
str.Append("</table>");
HttpResponseMessage result = null;
// serve the file to the client
result = Request.CreateResponse(HttpStatusCode.OK);
byte[] array = Encoding.ASCII.GetBytes(str.ToString());
MemoryStream mem = new MemoryStream(array);
result.Content = new StreamContent(mem);
result.Content.Headers.ContentType = new MediaTypeHeaderValue("application/vnd.ms-excel");
result.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
{
FileName = "Data.xls"
};
return result;
}
public List<Record> RecordInfo()
{
List<Record> recordobj = new List<Record>();
recordobj.Add(new Record { FName = "Smith", LName = "Singh", Address = "Knpur" });
recordobj.Add(new Record { FName = "John", LName = "Kumar", Address = "Lucknow" });
recordobj.Add(new Record { FName = "Vikram", LName = "Kapoor", Address = "Delhi" });
recordobj.Add(new Record { FName = "Tanya", LName = "Shrma", Address = "Banaras" });
recordobj.Add(new Record { FName = "Malini", LName = "Ahuja", Address = "Gujrat" });
recordobj.Add(new Record { FName = "Varun", LName = "Katiyar", Address = "Rajasthan" });
recordobj.Add(new Record { FName = "Arun ", LName = "Singh", Address = "Jaipur" });
recordobj.Add(new Record { FName = "Ram", LName = "Kapoor", Address = "Panjab" });
return recordobj;
}
I found the solution by using the following code and it works like a charm.We just need to add window.location.href.
app.controller('myCtrl', function ($scope, exportToExcelService,$location) {
$scope.export = function () {
exportToExcelService.download().success(
function (response) {
window.location.href = 'api/sample/download'
})
.error(function (response, status) {
var str = 'Hello'
});
}
}).

Using jquery, How can I iterate every node in xml?

I have another question about below example code.
below is index.html file
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<style>
#frm, #raw {display:block; float:left; width:210px},
#raw {height:150px; width:310px; margin-left:0.5em}
</style>
<title> INDEX </title>
</head>
<body>
<form id="frm">
Profile: <select id="profiles">
<option> </option>
</select>
<br></br>
Format:<select id="formats">
<option value="json"> JSON </option>
<option value="xml"> XML </option>
</select>
<br></br>
<div id="output"></div>
</form>
<textarea id="raw"></textarea>
</body>
<script>
$.get("http://localhost:8080/profiles",function (profile_names) {
$.each(profile_names, function (i, pname) {
$("#profiles").append("<option>" + pname + "</option>");
});
}, "json");
$("#formats, #profiles").change(function () {
var format = $("#formats").val();
$.get("http://localhost:8080/profile/" + $("#profiles").val() + "." + format,
function (profile, stat, jqXHR) {
var cT = jqXHR.getResponseHeader("Content-Type");
$("#raw").val(profile);
$("#output").html('');
if (cT === "application/json") {
$.each($.parseJSON(profile), function (k, v) {
$("#output").append("<b>" + k + "</b> : " + v + "<br>");
});
return;
}
if (cT === "application/xml") {
xmlDoc = $.parseXML( profile ),
$xml = $( xmlDoc );
$($xml).each(function(){
$("#output").append($(this).text() + "<br/>");
});
}
},
"text");
});
</script>
</html>
Second, server.js file
var http = require('http');
var fs = require('fs');
var path = require('path');
var profiles = require('./profiles');
var xml2js = require('xml2js');
var index = fs.readFileSync('index.html');
var routes, mimes = {xml: "application/xml", json: "application/json"}
function output(content, format, rootNode) {
if (!format || format === 'json') {
return JSON.stringify(content);
}
if (format === 'xml') {
return (new xml2js.Builder({rootName: rootNode})).buildObject(content);
}
}
routes = {
'profiles': function (format) {
return output(Object.keys(profiles), format);
},
'/profile': function (format, basename) {
return output(profiles[basename], format, basename);
}
};
http.createServer(function (request, response) {
var dirname = path.dirname(request.url),
extname = path.extname(request.url),
// $.get('http://localhost:8080/profile/' + $('#profiles').val() + '.' + format
basename = path.basename(request.url, extname);
extname = extname.replace('.', ''); //remove period
response.setHeader("Content-Type", mimes[extname] ||'text/html');
if (routes.hasOwnProperty(dirname)) {
response.end(routes[dirname](extname, basename));
return;
}
if (routes.hasOwnProperty(basename)) {
response.end(routes[basename](extname));
return;
}
response.end(index);
}).listen(8080);
below is profiles.js file
module.exports = {
ryan: {
name: "Ryan Dahl",
irc: "ryah",
twitter: "ryah",
github: "ry",
location: "San Francisco, USA",
description: "Creator of node.js"
},
isaac: {
name: "Isaac Schlueter",
irc: "isaacs",
twitter: "izs",
github: "isaacs",
location: "San Francisco, USA",
description: "Former project gatekeeper, CTO npm, Inc."
}
};
at index.html file,
After if (cT === "application/xml") { is not working properly compare to JSON one.
Actually, the original example code was like this
if (cT === "application/xml") {
profile = jqXHR.responseXML.firstChild.childNodes;
$.each(profile, function (k, v) {
if (v && v.nodeType === 1) {
$("#output").append("<b>" + v.tagName + "</b> : " + v.textContent + "<br>");
}
});
but above one was not working so I searched a way to show all the child node and text at the
selected one.
Is there any way for XML to show the same format as JSON selected at index.html file?
Thank you for understanding dissy question!!!
I found the way exactly what I want to show for element name and text.
if (cT === "application/xml") {
var xmlDoc =$.parseXML( profile );
var $xml = $(xmlDoc);
var kids = $xml.children().children();
kids.each(function(){
var tagName=this.tagName;
var val=$(this).text();
$("#output").append("<b>" + tagName + "</b> : " + val + "<br>");
});
}
I do not know why but when profile is parsed for 'tj', below is the result.
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<tj>
<name>TJ Holowaychuk</name>
<irc>tjholowaychuk</irc>
<twitter>tjholowaychuk</twitter>
<github>visionmedia</github>
<location>Victoria, BC, Canada</location>
<description>Author of express, jade and many other modules</description>
</tj>
So first child of the $xml is <tj> </tj>. so I used children() method twice and then
I can iterate all of <tj> </tj>es child and then print child's name and text.
Is there someone who can explain my code clearly
Please let me know.
Thank you.

Categories