<!DOCTYPE html>
<html ng-app="myApp">
<head lang="en">
<meta charset="utf-8">
<title>Custom Plunker</title>
<link rel="stylesheet" type="text/css" href="http://angular-ui.github.com/ng-grid/css/ng-grid.css" />
<link rel="stylesheet" type="text/css" href="style.css" />
<link rel="stylesheet" type="text/css" href="//maxcdn.bootstrapcdn.com/bootswatch/3.2.0/lumen/bootstrap.min.css" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular.min.js"></script>
<script src="https://cdn.firebase.com/js/client/1.0.17/firebase.js"></script>
<script src="https://cdn.firebase.com/libs/angularfire/0.8.0/angularfire.js"></script>
<script type="text/javascript" src="http://angular-ui.github.com/ng-grid/lib/ng-grid.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.1.5/angular-sanitize.js"></script>
<script src="//angular-ui.github.io/bootstrap/ui-bootstrap-tpls-0.11.0.js"></script>
<script src="ng-csv.js"></script>
<script type="text/javascript" src="main.js"></script>
</head>
<body ng-controller="MyCtrl">
<div class="row">
<div class="col-md-8">
<h1>List</h1>
<div class="panel panel-default">
<div class="panel-body" style="padding:0">
<div class="gridStyle" ng-grid="gridReceived"></div>
</div>
<div class="panel-footer text-right"><a href="https://docs.google.com/spreadsheets/d/1hhQ1nZh2dTzbZPsYn0zdLfqclJj85IzPm2CqpnBeVzo/edit?usp=sharing">Open Google Sheet</a></div>
</div>
</div>
<form role="form">
</form>
<div class="col-md-4">
<h1>Input</h1>
<form role="form">
<div class="form-group">
<div class="input-group">
<input ng-model="filterOptions.filterText" type="text" class="form-control"><div class="input-group-addon"><span class="glyphicon glyphicon-search"></span></div>
</div>
</div>
<div class="well" ng-repeat="selection in sheetSelections">
<div class="form-group">
<label>Title:</label>
<input ng-change="saveItems()" ng-model="selection.title" type="text" class="form-control">
</div>
<div class="form-group">
<label>MPN:</label>
<input ng-change="saveItems()" ng-model="selection.mpn" type="text" class="form-control">
</div>
<div class="form-group">
<label class="">Condition:</label>
<textarea ng-change="saveItems()" ng-model="selection.condition" rows="4" type="text" class="form-control"></textarea>
</div>
<div class="btn-group">
<button ng-click="getWalmartData(selection.title)" class="btn btn-primary " type="button">
<span class="glyphicon glyphicon-usd"></span> Fetch Data
</button><!-- /input-group -->
</div>
<br><br>
<div class="row">
<div class="col-sm-5 text-center">
<h3>{{walmartData.msrp}}</h3>
<img class="text-center" ng-src="{{walmartData.rating}}"></img>
</div>
<div class="col-sm-7 text-center">
<img class="text-center" ng-src="{{walmartData.image}}"></img>
</div>
</div>
</div>
<br>
<div class="btn-group">
<button ng-click="pullsheet()" class="btn btn-success btn-lg" type="button">
<span class="glyphicon glyphicon-import"></span> Import
</button><!-- /input-group -->
<button ng-csv="getExportSheet()" filename="test.csv" class="btn btn-warning btn-lg" csv-header="['Title', 'MPN', 'Condition', 'SKU']" type="button">
<span class="glyphicon glyphicon-export"></span> Export
</button><!-- /input-group -->
</div>
<div class="btn-group pull-right">
<button ng-click="clearsheet()" class="btn btn-danger btn-lg" type="button">
<span class="glyphicon glyphicon-trash"></span> Clear
</button><!-- /input-group -->
</div>
</form>
<br>
<br>
<alert ng-repeat="alert in alerts" type="{{alert.type}}" close="closeAlert($index)"><b>{{alert.title}}</b><p>{{alert.msg}}</p></alert>
</div>
</div>
</body>
</html>
// main.js
var app = angular.module('myApp', ['ngGrid', 'firebase', 'ngCsv', 'ui.bootstrap']);
app.directive('ngEnter', function () {
return function (scope, element, attrs) {
element.bind("keydown keypress", function (event) {
if(event.which === 13) {
scope.$apply(function (){
scope.$eval(attrs.ngEnter);
});
event.preventDefault();
}
});
};
});
app.controller('MyCtrl', function($scope, $http, $firebase, $log, $timeout) {
//GET EXPORT SHEEt
$scope.getExportSheet = function() {
var exportSheet = [];
var exportRow = [];
angular.forEach($scope.syncSheet, function(value) {
exportRow.push(value.title);
exportRow.push(value.mpn);
exportRow.push(value.condition);
exportRow.push(value.sku);
exportSheet.push(exportRow);
exportRow = [];
});
//console.log(exportSheet);
return exportSheet;
};
//SAVE ITEMs
$scope.saveItems = function () {
//console.log($scope.sheetSelections);
angular.forEach($scope.sheetSelections, function(value, key) {
$scope.syncSheet.$save(value);
});
};
//SELECT ITEM
$scope.selectItem = function (key) {
$scope.selection = key;
//console.log(key);
//console.log($scope.syncSheet[key]);
};
//REMOVE ALL ITEMS FROM SHEET
$scope.clearsheet = function () {
console.log($scope.syncSheet);
angular.forEach($scope.syncSheet, function(value, key) {
$scope.syncSheet.$remove(key);
//console.log(key);
});
};
//GET DATA FROM WALMART API
$scope.getWalmartData = function (query) {
$http.jsonp('http://walmartlabs.api.mashery.com/v1/search?query=' + query + '&format=json&apiKey=zp83ttcps659pqd6jmnvybgw' + '&callback=JSON_CALLBACK').success(function(data) {
$scope.walmartData.image = data.items[0].thumbnailImage;
$scope.walmartData.msrp = data.items[0].msrp;
$scope.walmartData.rating = data.items[0].customerRatingImage;
}).error(function(error) {
});
};
//PULL DATA FROM GOOGLE INTO FIREBASE
$scope.pullsheet = function () {
$http.jsonp('http://spreadsheets.google.com/feeds/list/1hhQ1nZh2dTzbZPsYn0zdLfqclJj85IzPm2CqpnBeVzo/od6/public/values?alt=json-in-script' + '&callback=JSON_CALLBACK').success(function(data) {
angular.forEach(data, function(value){
angular.forEach(value.entry, function(classes){
var newUnlisted = {};
newUnlisted.condition = classes.gsx$attribute2value.$t.replace(/,/g, "- ");
newUnlisted.mpn = classes.gsx$mpn.$t.replace(/,/g, "- ");
newUnlisted.title = classes.gsx$auctiontitle.$t.replace(/,/g, "- ");
newUnlisted.sku = classes.gsx$inventorynumber.$t;
console.log($scope.syncSheet);
$scope.syncSheet.$add(newUnlisted);
});
});
}).error(function(error) {
});
};
//SYNC SHEET WITH FIREBASE
$scope.bindSheet = function () {
var ref = new Firebase("https://milver.firebaseio.com");
var sync = $firebase(ref);
// create a synchronized object, all server changes are downloaded in realtime
var sheet = sync.$asArray();
$scope.syncSheet = sheet;
//sheetObj.$bindTo($scope, "syncSheet");
};
$scope.walmartData=[];
$scope.sheetSelections=[];
$scope.syncSheet = [];
$scope.bindSheet();
//console.log($scope.syncSheet);
//console.log('$scope.syncSheet');
$scope.receivedData = [];
$scope.unlistedData = [];
$scope.receivedFound = false;
$scope.unlistedFound = false;
$scope.filterOptions = {
filterText: ''
};
//SHEET SHIT
$scope.gridUnlisted = {
data: 'unlistedData',
filterOptions: $scope.filterOptions
};
$scope.gridReceived = {
data: 'syncSheet',
filterOptions: $scope.filterOptions,
selectedItems: $scope.sheetSelections,
multiSelect: false,
enableRowSelection: true,
showGroupPanel: true,
columnDefs: [ { field: 'sku', displayName: 'SKU', width: '10%' },
{ field: 'title', displayName: 'Title', width: '45%' },
{ field: 'mpn', displayName: 'MPN', width: '15%'},
{ field: 'condition', displayName: 'Condition'}]
};
//ALERTS
$scope.alerts = [];
$scope.addAlert = function(title, msg, type, timeout) {
var alert =[];
alert.title = title;
alert.msg = msg;
alert.type = type;
$scope.alerts.push(alert);
if (timeout) {
$timeout(function(){
$scope.closeAlert($scope.alerts.indexOf(alert));
}, timeout);
}
};
$scope.closeAlert = function(index) {
$scope.alerts.splice(index, 1);
};
$scope.$on('ngGridEventData', function(){
//console.log($scope.syncSheet);
$scope.addAlert('Like whoa!!', 'There has been a significant change to the dataset.','info', 1500);
});
//NgGRID REMOVE
$scope.removeRow = function(index) {
$scope.gridReceived.selectItem(index, false);
$scope.receivedData.splice(index, 1);
};
//NgGRID CHECK IF ITEM EXISTS AND REDUCE QUANTITY or REMOVE
$scope.check = function(){
$scope.receivedFound=false;
angular.forEach($scope.receivedData, function(data, index){
$scope.syncSheet
if(data.SKU == $scope.SKU){
$scope.receivedFound = true;
$scope.gridReceived.selectItem(index, true);
data.qty = data.qty - 1;
if(data.qty < 1){
$scope.removeRow(index);
}
}
});
if($scope.receivedFound === false){
snd.play();
$scope.unlistedFound = false;
angular.forEach($scope.unlistedData, function(data, index){
if(data.SKU == $scope.SKU){
$scope.unlistedFound = true;
data.qty = data.qty + 1;
$scope.gridReceived.selectItem(index, true);
}
});
if($scope.unlistedFound === false) {
var newUnlisted = {};
newUnlisted.SKU = $scope.SKU;
newUnlisted.qty = 1;
$scope.unlistedData.push(newUnlisted);
}
}
$scope.SKU ="";
$scope.counter = 0;
$scope.$watch('syncSheet', function() {
alert('hey, myVar has changed!');
});
};
});
/*style.css*/
.gridStyle {
width: 100%;
height: 750px;
}
body {width:97%; padding-left: 3%; padding-top:1%; }
@keyframes fadeOut
{
from { opacity: 1.0; }
to { opacity: 0.0; }
}
@-webkit-keyframes fadeOut
{
from { opacity: 1.0 }
to { opacity: 0.0 }
}
.fade-out
{
animation: fadeOut 2s infinite;
-webkit-animation: fadeOut 2s infinite;
}
(function(window, document) {
// Create all modules and define dependencies to make sure they exist
// and are loaded in the correct order to satisfy dependency injection
// before all nested files are concatenated by Grunt
// Config
angular.module('ngCsv.config', []).
value('ngCsv.config', {
debug: true
}).
config(['$compileProvider', function($compileProvider){
if (angular.isDefined($compileProvider.urlSanitizationWhitelist)) {
$compileProvider.urlSanitizationWhitelist(/^\s*(https?|ftp|mailto|file|data):/);
} else {
$compileProvider.aHrefSanitizationWhitelist(/^\s*(https?|ftp|mailto|file|data):/);
}
}]);
// Modules
angular.module('ngCsv.directives', ['ngCsv.services']);
angular.module('ngCsv.services', []);
angular.module('ngCsv',
[
'ngCsv.config',
'ngCsv.services',
'ngCsv.directives',
'ngSanitize'
]);
/**
* Created by asafdav on 15/05/14.
*/
angular.module('ngCsv.services').
service('CSV', ['$q', function($q) {
var EOL = encodeURIComponent('\r\n');
var DATA_URI_PREFIX = "data:text/csv;charset=utf-8,";
/**
* Stringify one field
* @param data
* @param delimier
* @returns {*}
*/
this.stringifyField = function(data, delimier, quoteText) {
if (typeof data === 'string') {
data = data.replace(/"/g, '""'); // Escape double qoutes
if (quoteText || data.indexOf(',') > -1 || data.indexOf('\n') > -1 || data.indexOf('\r') > -1) data = delimier + data + delimier;
return encodeURIComponent(data);
}
if (typeof data === 'boolean') {
return data ? 'TRUE' : 'FALSE';
}
return data;
};
/**
* Creates a csv from a data array
* @param data
* @param options
* * header - Provide the first row (optional)
* * fieldSep - Field separator, default: ','
* @param callback
*/
this.stringify = function (data, options)
{
var def = $q.defer();
var that = this;
var csv;
var csvContent = "";
var dataPromise = $q.when(data).then(function (responseData)
{
responseData = angular.copy(responseData);
// Check if there's a provided header array
if (angular.isDefined(options.header) && options.header)
{
var encodingArray, headerString;
encodingArray = [];
angular.forEach(options.header, function(title, key)
{
this.push(that.stringifyField(title, options.txtDelim, options.quoteStrings));
}, encodingArray);
headerString = encodingArray.join(options.fieldSep ? options.fieldSep : ",");
csvContent += headerString + EOL;
}
var arrData;
if (angular.isArray(responseData)) {
arrData = responseData;
}
else {
arrData = responseData();
}
angular.forEach(arrData, function(row, index)
{
var dataString, infoArray;
infoArray = [];
angular.forEach(row, function(field, key)
{
this.push(that.stringifyField(field, options.txtDelim, options.quoteStrings));
}, infoArray);
dataString = infoArray.join(options.fieldSep ? options.fieldSep : ",");
csvContent += index < arrData.length ? dataString + EOL : dataString;
});
if(window.navigator.msSaveOrOpenBlob) {
csv = csvContent;
}else{
csv = DATA_URI_PREFIX + csvContent;
}
def.resolve(csv);
});
if (typeof dataPromise.catch === 'function') {
dataPromise.catch(function(err) {
def.reject(err);
});
}
return def.promise;
};
}]);/**
* ng-csv module
* Export Javascript's arrays to csv files from the browser
*
* Author: asafdav - https://github.com/asafdav
*/
angular.module('ngCsv.directives').
directive('ngCsv', ['$parse', '$q', 'CSV', '$document', '$timeout', function ($parse, $q, CSV, $document, $timeout) {
return {
restrict: 'AC',
scope: {
data:'&ngCsv',
filename:'@filename',
header: '&csvHeader',
txtDelim: '@textDelimiter',
quoteStrings: '@quoteStrings',
fieldSep: '@fieldSeparator',
lazyLoad: '@lazyLoad',
ngClick: '&'
},
controller: [
'$scope',
'$element',
'$attrs',
'$transclude',
function ($scope, $element, $attrs, $transclude) {
$scope.csv = '';
if (!angular.isDefined($scope.lazyLoad) || $scope.lazyLoad != "true")
{
if (angular.isArray($scope.data))
{
$scope.$watch("data", function (newValue) {
$scope.buildCSV();
}, true);
}
}
$scope.getFilename = function ()
{
return $scope.filename || 'download.csv';
};
function getBuildCsvOptions() {
var options = {
txtDelim: $scope.txtDelim ? $scope.txtDelim : '"',
quoteStrings: $scope.quoteStrings
};
if (angular.isDefined($attrs.csvHeader)) options.header = $scope.$eval($scope.header);
options.fieldSep = $scope.fieldSep ? $scope.fieldSep : ",";
return options;
}
/**
* Creates the CSV and updates the scope
* @returns {*}
*/
$scope.buildCSV = function() {
var deferred = $q.defer();
CSV.stringify($scope.data(), getBuildCsvOptions()).then(function(csv) {
$scope.csv = csv;
deferred.resolve(csv);
});
$scope.$apply(); // Old angular support
return deferred.promise;
};
}
],
link: function (scope, element, attrs) {
function doClick() {
if(window.navigator.msSaveOrOpenBlob) {
var blob = new Blob([scope.csv],{
type: "text/csv;charset=utf-8;"
});
navigator.msSaveBlob(blob, scope.getFilename());
} else {
var downloadLink = angular.element('<a></a>');
downloadLink.attr('href',scope.csv);
downloadLink.attr('download',scope.getFilename());
$document.find('body').append(downloadLink);
$timeout(function() {
downloadLink[0].click();
downloadLink.remove();
}, null);
}
}
element.bind('click', function (e)
{
scope.buildCSV().then(function(csv) {
doClick();
});
scope.$apply();
});
}
};
}]);
})(window, document);