Skip to content

Instantly share code, notes, and snippets.

@stla
Created September 8, 2016 11:21
Show Gist options
  • Select an option

  • Save stla/fded798a6188a6dfa34463cfd36cdc0d to your computer and use it in GitHub Desktop.

Select an option

Save stla/fded798a6188a6dfa34463cfd36cdc0d to your computer and use it in GitHub Desktop.
Angular - Upload CSV file and select two numeric columns
<!DOCTYPE html>
<html>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="modules/ng-flow-standalone.min.js"></script>
<script src="libraries/PapaParse-4.1.2/papaparse.min.js"></script>
<style>
select option:empty {display:none}
</style>
<body>
<div ng-app="myApp" ng-controller="myCtrl">
<div class="container">
<div class="row">
<div class="col-sm-3 well">
<div flow-init="{target: '/upload'}" flow-files-submitted="$flow.upload()">
<label for="upload" class="btn btn-primary" ng-hide="hideUploader">Select CSV file</label>
<input id="upload" type="file" flow-btn style="visibility:hidden" accept=".csv"
onchange="angular.element(this).scope().uploaded(this)" />
<div ng-repeat="file in $flow.files" class="transfer-box">
{{file.relativePath}} ({{file.size}}bytes)
<div class="progress progress-striped" ng-class="{active: file.isUploading()}">
<div class="progress-bar" role="progressbar" aria-valuenow="{{file.progress() * 100}}" aria-valuemin="0" aria-valuemax="100" ng-style="{width: (file.progress() * 100) + '%'}">
<span class="sr-only">{{file.progress()}}% Complete</span>
</div>
</div>
</div>
</div>
<select id="selectColumn1" ng-attr-size="{{selSize}}"
ng-hide="hideSelectColumn"
ng-model="selectColumn1"
ng-options="o.label disable when isNumeric[o.value]==false for o in options track by o.value"
ng-change="changeSel1()">
</select>
<select id="selectColumn2" ng-attr-size="{{selSize}}"
ng-hide="hideSelectColumn"
ng-model="selectColumn2"
ng-options="o.label disable when isNumeric[o.value]==false for o in options track by o.value"
ng-change="changeSel2()">
</select>
</div>
<div class="col-sm-9">
<table id="dataTable" width="100%" class="table table-bordered table-striped">
<thead>
<tr>
<th ng-repeat="header in columns">
<a href="#" ng-click="sortTable(header)">
{{header}}
<span ng-show="sortType == header && !sortReverse" class="fa fa-caret-down"></span>
<span ng-show="sortType == header && sortReverse" class="fa fa-caret-up"></span>
</a>
</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="row in jsonTable | orderBy:rawProperty(sortType):sortReverse">
<td ng-repeat="cell in row">{{cell}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
<script>
var app = angular.module('myApp', ['flow']);
app.controller('myCtrl', function($scope) {
// function to handle dots in strings in orderBy
$scope.rawProperty = function(key) {
return function(item) {
return item[key];
};
};
// hide the column selector
$scope.hideSelectColumn = true;
// on change select column
$scope.changeSel1 = function(){
var sel1 = $scope.selectColumn1;
var sel2 = $scope.selectColumn2;
if(!(sel2 === undefined) && sel1.label == sel2.label){
$scope.selectColumn2 = false
}
var rows = document.getElementById("dataTable").rows;
angular.forEach(rows, function(row){
var cells = row.cells;
for(j=0; j<cells.length; j++){
if(j==sel1.value){
angular.element(cells[j]).css("color", "blue");
}else{
if(sel2 === undefined || j!=sel2.value){
angular.element(cells[j]).css("color", "gray");
}
}
}
});
};
$scope.changeSel2 = function(){
var sel1 = $scope.selectColumn1;
var sel2 = $scope.selectColumn2;
if(!(sel1 === undefined) && sel2.label == sel1.label){
$scope.selectColumn1 = false
}
var rows = document.getElementById("dataTable").rows;
angular.forEach(rows, function(row){
var cells = row.cells;
for(j=0; j<cells.length; j++){
if(j==sel2.value){
angular.element(cells[j]).css("color", "green");
}else{
if(sel1 === undefined || j!=sel1.value){
angular.element(cells[j]).css("color", "gray");
}
}
}
});
};
// uploaded on change action
$scope.uploaded = function() {
var uploader = angular.element(document.querySelector("#upload"));
$scope.hideUploader = true;
var myfile = uploader[0].files[0];
angular.element(document.querySelector("label[for='upload']")).text(myfile.name);
// read file
var reader = new FileReader();
reader.onload = function(e) {
// get file as JSON
var json = Papa.parse(reader.result,
{
header: true,
skipEmptyLines: true,
dynamicTyping: true
}
);
// the table without the hashkey
var jsonTable = angular.copy(json.data);
var columns = Object.keys(jsonTable[0]);
// send the table as JSON to the scope
$scope.$apply(function(){
// sort options
$scope.sortReverse = false;
//$scope.sortType = columns[0];
$scope.sortTable = function(header){
$scope.sortReverse=!$scope.sortReverse;
$scope.sortType = header;
}
// table
$scope.columns = columns;
$scope.jsonTable=json.data;
});
// make the df in columns format
var dfcolumns = {};
for (i = 0; i < columns.length; i++) {
var column = [];
var colname = columns[i];
for (j = 0; j < jsonTable.length; j++) {
column.push(jsonTable[j][colname]);
}
dfcolumns[colname] = column;
}
// find numeric columns
var isNumeric = [];
for (var key in dfcolumns) {
var col = dfcolumns[key];
var i = 0;
while (col[i] == "") {i++}
isNumeric.push(typeof(col[i]) == "number")
}
$scope.$apply(function(){
$scope.isNumeric = isNumeric;
})
// options for the dropdown list
var options = [];
for(i=0; i<columns.length; i++){
var option={};
option["label"] = columns[i];
option["value"] = i;
options.push(option);
}
$scope.$apply(function(){
$scope.hideSelectColumn = false;
$scope.options=options;
});
// set the size
if (columns.length < 5) {
var size = columns.length;
} else {
var size = 5;
}
$scope.$apply(function(){
$scope.selSize = size;
})
}
reader.readAsText(myfile);
};
});
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment