A Pen by Suzanne Atkinson on CodePen.
Created
November 2, 2016 14:30
-
-
Save AdventureBear/a13af628e273a73c2db3959c07eb7cf9 to your computer and use it in GitHub Desktop.
Rhino Crunch - with bind.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<img class="logo" src="http://www.teamrhinotraining.com/wp-content/uploads/2013/05/icon1.png" width="200px"> | |
<h1><a href="http://www.teamrhinotraining.com/app/">Rhino Crunch</a></h1></div> | |
<div class="grid-25"> | |
Some Options here if needed | |
<div class="config-options"> | |
<label><input type="checkbox" id="download"> Download</label> | |
<label><input type="checkbox" id="stream"> Stream</label> | |
<label><input type="checkbox" id="chunk"> Chunk</label> | |
<label><input type="checkbox" id="worker"> Worker thread</label> | |
<label><input type="checkbox" id="header" checked> Header row</label> | |
<label><input type="checkbox" id="dynamicTyping"> Dynamic typing</label> | |
<label><input type="checkbox" id="fastmode"> Fast mode</label> | |
<label><input type="checkbox" id="skipEmptyLines"> Skip empty lines</label> | |
<label><input type="checkbox" id="step-pause"> Pause on step</label> | |
<label><input type="checkbox" id="print-steps"> Log each step/chunk</label> | |
<label>Delimiter: <input type="text" size="5" placeholder="auto" id="delimiter"> <a href="javascript:" id="insert-tab">tab</a></label> Line Endings: | |
<label style="display: inline;"><input type="radio" name="newline" id="newline-auto" checked>Auto</label> | |
<label style="display: inline;"><input type="radio" name="newline" id="newline-n">\n</label> | |
<label style="display: inline;"><input type="radio" name="newline" id="newline-r">\r</label> | |
<label style="display: inline;"><input type="radio" name="newline" id="newline-rn">\r\n</label> | |
<label>Preview: <input type="number" min="0" max="1000" placeholder="default" id="preview"></label> | |
<label>Encoding: <input type="text" id="encoding" placeholder="default" size="10"></label> | |
<label>Comment char: <input type="text" size="5" maxlength="1" placeholder="default" id="comments"></label> | |
<label>Papa.LocalChunkSize: <input type="number" min="0" placeholder="default" id="localChunkSize"></label> | |
<label>Papa.RemoteChunkSize: <input type="number" min="0" placeholder="default" id="remoteChunkSize"></label> | |
</div> | |
</div> | |
<div class="grid-100 text-center"> | |
<input type="file" name="file" id="files" class="inputfile" /> | |
<label for="files"><span class="glyphicon glyphicon-open" aria-hidden="true"></span> Choose a file...</label> | |
<br><br> | |
<button id="submit-parse">Upload</button> | |
<!--<button id="submit-unparse">Unparse</button>--> | |
<button id="download-csv">Download</button> | |
<br><br> | |
<i>Open the Console in your browser's inspector tools to debug.</i> | |
<br><br> | |
<div id="uniqueUsers"> | |
</div> | |
<div id="object"></div> | |
</div> | |
<div id="month picker"> | |
<input type="text" id="date" data-format="DD-MM-YYYY" data-template="D MMM YYYY" name="date" value="09-01-2013"> | |
</div> | |
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var stepped = 0, | |
chunks = 0, | |
rows = 0; | |
var start, end; | |
var parser; | |
var pauseChecked = false; | |
var printStepChecked = false; | |
var userSummary = []; | |
var newSummary = {}; | |
//var CSVready = []; | |
$(function() { | |
$('#submit-parse').click(function() { | |
stepped = 0; | |
chunks = 0; | |
rows = 0; | |
var txt = $('#input').val(); | |
var localChunkSize = $('#localChunkSize').val(); | |
var remoteChunkSize = $('#remoteChunkSize').val(); | |
var files = $('#files')[0].files; | |
var config = buildConfig(); | |
$('#date').combodate(); | |
// NOTE: Chunk size does not get reset if changed and then set back to empty/default value | |
if (localChunkSize) | |
Papa.LocalChunkSize = localChunkSize; | |
if (remoteChunkSize) | |
Papa.RemoteChunkSize = remoteChunkSize; | |
pauseChecked = $('#step-pause').prop('checked'); | |
printStepChecked = $('#print-steps').prop('checked'); | |
if (files.length > 0) { | |
if (!$('#stream').prop('checked') && !$('#chunk').prop('checked')) { | |
for (var i = 0; i < files.length; i++) { | |
if (files[i].size > 1024 * 1024 * 10) { | |
alert("A file you've selected is larger than 10 MB; please choose to stream or chunk the input to prevent the browser from crashing."); | |
return; | |
} | |
} | |
} | |
start = performance.now(); | |
$('#files').parse({ | |
config: config, | |
before: function(file, inputElem) { | |
console.log("Parsing file:", file); | |
}, | |
complete: function() { | |
console.log("Done with all files."); | |
} | |
}); | |
} else { | |
start = performance.now(); | |
var results = Papa.parse(txt, config); | |
console.log("Synchronous parse results:", results); | |
} | |
}); | |
$('#submit-unparse').click(function() { | |
//var input = $('#input').val(); | |
var input = userSummary; | |
var delim = $('#delimiter').val(); | |
var results = Papa.unparse(input, { | |
delimiter: delim | |
}); | |
console.log("Unparse complete!"); | |
console.log("--------------------------------------"); | |
console.log(results); | |
console.log("--------------------------------------"); | |
}); | |
$("#download-csv").click(function() { | |
console.log("CSV Downlaod Clicked"); | |
downloadCSV({ | |
filename: "CSVData.csv" | |
}); | |
}) | |
$("#score").click(function(){ | |
//total up score | |
//So, the first five columns divide by 10, the next two (team call & SC) are just added, and the last column (volume) is divide by 50. | |
}) | |
$('#insert-tab').click(function() { | |
$('#delimiter').val('\t'); | |
}); | |
}); | |
function downloadCSV(args) { | |
var reformatted = reformatBindObjforCSV(newSummary); | |
console.log("Download CSV Function"); | |
var data, filename, link; | |
var csv = convertArrayOfObjectsToCSV({ | |
data: reformatted | |
}); | |
if (csv == null) return; | |
filename = args.filename || 'export.csv'; | |
if (!csv.match(/^data:text\/csv/i)) { | |
csv = 'data:text/csv;charset=utf-8,' + csv; | |
} | |
data = encodeURI(csv); | |
link = document.createElement('a'); | |
link.setAttribute('href', data); | |
link.setAttribute('download', filename); | |
link.click(); | |
} | |
function convertArrayOfObjectsToCSV(args) { | |
var result, ctr, keys, columnDelimiter, lineDelimiter, data; | |
console.log("Converting objects to CSV", args); | |
data = args.data || null; | |
if (data == null || !data.length) { | |
console.log("Data is null"); | |
return null; | |
} | |
columnDelimiter = args.columnDelimiter || ','; | |
lineDelimiter = args.lineDelimiter || '\n'; | |
keys = Object.keys(data[0]); | |
console.log("Keys: ", keys); | |
result = ''; | |
result += keys.join(columnDelimiter); | |
result += lineDelimiter; | |
data.forEach(function(item) { | |
ctr = 0; | |
keys.forEach(function(key) { | |
if (ctr > 0) result += columnDelimiter; | |
result += item[key]; | |
ctr++; | |
}); | |
result += lineDelimiter; | |
}); | |
return result; | |
} | |
//http://halistechnology.com/2015/05/28/use-javascript-to-export-your-data-as-csv/ | |
function buildConfig() { | |
return { | |
delimiter: $('#delimiter').val(), | |
newline: getLineEnding(), | |
header: $('#header').prop('checked'), | |
dynamicTyping: $('#dynamicTyping').prop('checked'), | |
preview: parseInt($('#preview').val() || 0), | |
step: $('#stream').prop('checked') ? stepFn : undefined, | |
encoding: $('#encoding').val(), | |
worker: $('#worker').prop('checked'), | |
comments: $('#comments').val(), | |
complete: completeFn, | |
error: errorFn, | |
download: $('#download').prop('checked'), | |
fastMode: $('#fastmode').prop('checked'), | |
skipEmptyLines: $('#skipEmptyLines').prop('checked'), | |
chunk: $('#chunk').prop('checked') ? chunkFn : undefined, | |
beforeFirstChunk: undefined, | |
}; | |
function getLineEnding() { | |
if ($('#newline-n').is(':checked')) | |
return "\n"; | |
else if ($('#newline-r').is(':checked')) | |
return "\r"; | |
else if ($('#newline-rn').is(':checked')) | |
return "\r\n"; | |
else | |
return ""; | |
} | |
} | |
function stepFn(results, parserHandle) { | |
stepped++; | |
rows += results.data.length; | |
parser = parserHandle; | |
if (pauseChecked) { | |
console.log(results, results.data[0]); | |
parserHandle.pause(); | |
return; | |
} | |
if (printStepChecked) | |
console.log(results, results.data[0]); | |
} | |
function chunkFn(results, streamer, file) { | |
if (!results) | |
return; | |
chunks++; | |
rows += results.data.length; | |
parser = streamer; | |
if (printStepChecked) | |
console.log("Chunk data:", results.data.length, results); | |
if (pauseChecked) { | |
console.log("Pausing; " + results.data.length + " rows in chunk; file:", file); | |
streamer.pause(); | |
return; | |
} | |
} | |
function errorFn(error, file) { | |
console.log("ERROR:", error, file); | |
} | |
function completeFn() { | |
end = performance.now(); | |
if (!$('#stream').prop('checked') && | |
!$('#chunk').prop('checked') && | |
arguments[0] && | |
arguments[0].data) | |
rows = arguments[0].data.length; | |
console.log("Finished input (async). Time:", end - start, arguments); | |
console.log("Rows:", rows, "Stepped:", stepped, "Chunks:", chunks); | |
evaluateData(arguments[0]); | |
} | |
function evaluateData(allData) { | |
var records = allData.data; | |
//console.log(records); | |
//Build array of unique users | |
var uniqueUsers = []; | |
var uniqueUsers = records | |
.map(function(obj) { | |
return obj["Created By"]; | |
}) | |
.filter(function(name, i, arr) { | |
//clever trick to get only first occurances ie unique | |
if (arr.indexOf(name) == i && name != "") { | |
return name; | |
} | |
}) | |
//create "blank" userSummary array | |
uniqueUsers.forEach(function(user) { | |
var obj = { | |
'CreatedBy': user, | |
'New Contacts': 0, | |
'New Invites (Challenge Groups)': 0, | |
'New Invites (Coaching Opportunity)': 0, | |
'New Follow Ups': 0, | |
'New Challenger Check-Ins': 0, | |
'Team Call Participation (National upline team or our team)': 0, | |
'Team Call Participation (National, upline team, or our team)': 0, | |
'SCPoints': 0, | |
'Volume': 0 | |
} | |
userSummary.push(obj); | |
}) | |
//console.log(userSummary[0]); | |
//fill user summary array with actual data | |
//console.log("user summary keys", Object.keys(userSummary[0])); | |
var attributes = Object.keys(userSummary[0]); | |
//console.log(attributes); | |
//Strip "created by" from remainign attributes | |
//User summary already has 'created by' as start of each element. | |
attributes.shift(); | |
userSummary.forEach(function(user, i) { | |
records.forEach(function(record, j) { | |
if (record['Created By'] === user['CreatedBy']) { | |
//strip all but numbers & alpha characters | |
var myName = user['CreatedBy'].replace(/[^a-zA-Z0-9]/g, ''); // <--regex removes non alphanum chars | |
user['CreatedBy'] = myName; | |
console.log(myName); | |
attributes.forEach(function(key) { | |
//turn null sc points & volume from spreadsheet into 0 | |
if (record[key] == null) { | |
var val = 0; | |
} else { | |
val = record[key]; | |
} | |
user[key] += parseInt(val); | |
//console.log(key); | |
}); | |
} | |
}); | |
//User summed up, next | |
//Clean up New Challenger Check ins | |
if (user['Team Call Participation (National, upline team, or our team)'] >= 3) { | |
user['Team Call Participation (National, upline team, or our team)'] = 3; | |
} | |
//clean up key name to remove commas | |
user['Team Call Participation (National upline team or our team)'] = user['Team Call Participation (National, upline team, or our team)']; | |
delete user['Team Call Participation (National, upline team, or our team)']; | |
}); | |
var bindObj = {}; | |
userSummary.forEach(function(user) { | |
var name = user['CreatedBy']; | |
newSummary[name] = user; | |
//create binding object | |
bindObj[name + '.CreatedBy'] = '.created-by-' + name; | |
bindObj[name + '.SCPoints'] = '.sc-points-' + name; | |
bindObj[name + '.Volume'] = '.volume-' + name; | |
}); | |
console.log(JSON.stringify(newSummary.ryanc)); | |
//console.log(JSON.stringify(bindObj)); | |
var timerID = setTimeout(function() { | |
var boundUser = Bind( | |
newSummary, | |
bindObj | |
); | |
}, 1000); | |
createHTMLforBind(userSummary); | |
//console.log(JSON.stringify(bindObj)); | |
//sendObjToHTML(userSummary); | |
} | |
function reformatBindObjforCSV(newSummary){ | |
var CSVready=[]; | |
var users = Object.keys(newSummary); | |
users.forEach(function(user){ | |
CSVready.push(newSummary[user]); | |
}) | |
console.log(CSVready); | |
return CSVready; | |
}; | |
function getMonth(obj){ | |
} | |
function createHTMLforBind(userSummary) { | |
var userStr = ''; | |
var headerStr = "<table class='bordered highlight'> <thead><tr><th>User</th><th>New Contacts</th><th>Invites-Groups</th><th>Invites-Coaching</th><th>New Follow Ups</th><th>New Check-Ins</th><th>Team Call (max 3)</th><th>SC Points</th><th>Volume</th></tr> </thead>"; | |
userSummary.forEach(function(user) { | |
var userStr = "<tr><td><div class='created-by-" + user['CreatedBy'] + "'></div></td>"; | |
userStr += "<td>" + user['New Contacts'] + "</td>"; | |
userStr += "<td>" + user['New Invites (Challenge Groups)'] + "</td>"; | |
userStr += "<td>" + user['New Invites (Coaching Opportunity)'] + "</td>"; | |
userStr += "<td>" + user['New Follow Ups'] + "</td>"; | |
userStr += "<td>" + user['New Challenger Check-Ins'] + "</td>"; | |
userStr += "<td>" + user['Team Call Participation (National upline team or our team)'] + "</td>"; | |
userStr += "<td>" + "<input type='text' class='inline sc-points-" + user['CreatedBy'] + "'></input></td>"; | |
userStr += "<td>" + "<input type='text' class='inline volume-" + user['CreatedBy'] + "'></input></td></tr>"; | |
headerStr += userStr; | |
}) | |
var closingStr = "</table>"; | |
var fullStr = headerStr + closingStr; | |
//console.log(fullStr); | |
$('#uniqueUsers').append(fullStr); | |
}; | |
function sendObjToHTML(userSummary) { | |
var userStr = ''; | |
var headerStr = "<table class='bordered highlight'> <thead><tr><th>User</th><th>New Contacts</th><th>Invites-Groups</th><th>Invites-Coaching</th><th>New Follow Ups</th><th>New Check-Ins</th><th>Team Call (max 3)</th><th>SC Points</th><th>Volume</th></tr> </thead>"; | |
userSummary.forEach(function(user) { | |
var userStr = "<tr><td>" + user['CreatedBy'] + "</td>"; | |
console.log(userStr); | |
userStr += "<td>" + user['New Contacts'] + "</td>"; | |
userStr += "<td>" + user['New Invites (Challenge Groups)'] + "</td>"; | |
userStr += "<td>" + user['New Invites (Coaching Opportunity)'] + "</td>"; | |
userStr += "<td>" + user['New Follow Ups'] + "</td>"; | |
userStr += "<td>" + user['New Challenger Check-Ins'] + "</td>"; | |
userStr += "<td>" + user['Team Call Participation (National upline team or our team)'] + "</td>"; | |
userStr += "<td>" + "<input class='input-sc-'></input>" + "</td>"; | |
userStr += "<td>" + "<input class='input-vol-'></input>" + "</td></tr>"; | |
headerStr += userStr; | |
}) | |
var closingStr = "</table>"; | |
var fullStr = headerStr + closingStr; | |
$('#uniqueUsers').append(fullStr); | |
} | |
/*JS for input file | |
//update file upload label with name of file | |
//http://tympanus.net/codrops/2015/09/15/styling-customizing-file-inputs-smart-way/*/ | |
var inputs = $('.inputfile'); | |
Array.prototype.forEach.call(inputs, function(input) { | |
var label = input.nextElementSibling, | |
labelVal = label.innerHTML; | |
input.addEventListener('change', function(e) { | |
var fileName = ''; | |
fileName = e.target.value.split('\\').pop(); | |
if (fileName) | |
label.querySelector('span').innerHTML = fileName; | |
else | |
label.innerHTML = labelVal; | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.0.0/jquery.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/PapaParse/4.1.2/papaparse.js"></script> | |
<script src="https://rawgit.com/remy/bind.js/master/dist/bind.min.js"></script> | |
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.15.1/moment.min.js"></script> | |
<script src="http://codepen.io/AdventureBear/pen/mAqREJ"></script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.config-options { | |
display: none; | |
} | |
.logo { | |
float: left; | |
} | |
.grid-25 { | |
display: none; | |
} | |
/*CSS for input file | |
//http://tympanus.net/codrops/2015/09/15/styling-customizing-file-inputs-smart-way/*/ | |
.inputfile { | |
width: 0.1px; | |
height: 0.1px; | |
opacity: 0; | |
overflow: hidden; | |
position: absolute; | |
z-index: -1; | |
} | |
.inputfile + label { | |
color: #f1e5e6; | |
background-color: #d3394c; | |
font-size: 1.25em; | |
font-weight: 700; | |
display: inline-block; | |
padding: 5px 10px; | |
border-radius: 5px; | |
} | |
.inputfile:focus + label, | |
.inputfile + label:hover { | |
background-color: #722040; | |
} | |
.input-sc, input-vol { | |
} | |
.inputfile + label { | |
cursor: pointer; /* "hand" cursor */ | |
} | |
.inputfile:focus + label { | |
outline: 1px dotted #000; | |
outline: -webkit-focus-ring-color auto 5px; | |
} | |
#uniqueUsers { | |
margin: 20px 0 40px 0; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<link href="http://codepen.io/AdventureBear/pen/KgPvXZ" rel="stylesheet" /> | |
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" /> | |
<link href="https://cdnjs.cloudflare.com/ajax/libs/materialize/0.97.7/css/materialize.min.css" rel="stylesheet" /> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment