Ember CSV Upload
by amindunited
HTML
<link rel="stylesheet" href="http://code.jquery.com/qunit/qunit-1.12.0.css">
<script type="text/x-handlebars" data-template-name="application">
<!-- Buttons are easier to style so we'll use a button as a proxy for the file input -->
<input id="_uploadFile" type='file'/>
<button id="uploadFile">Upload CSV</button>
{{#if employees.length}}
{{x-employee-list employees=employees selectedEmployee=selectedEmployee}}
{{/if}}
{{#if selectedEmployee}}
{{x-payslip employee=selectedEmployee}}
{{/if}}
</script>
<script type="text/x-handlebars" data-template-name="components/x-employee-list">
<i>Select an employee to view</i>
{{#each employee in employees}}
<div class="employeeLink">
<a {{action 'selectEmployee' employee}}>
{{employee.lastName}}, {{employee.firstName}}
</a>
</div>
{{/each}}
</script>
<script type="text/x-handlebars" data-template-name="components/x-payslip">
<div class="payslipWrap">
<h4>{{employee.fullName}}</h4>
<table>
<tr>
<th>
name
</th>
<td>
{{employee.fullName}}
</td>
</tr>
<tr>
<th>
pay period
</th>
<td>
{{employee.paymentStartDate}}
</td>
</tr>
<tr>
<th>
gross income
</th>
<td class="number">
${{employee.gross_income}}
</td>
</tr>
<tr>
<th>
income tax
</th>
<td class="number">
${{employee.income_tax}}
</td>
</tr>
<tr>
<th>
net income
</th>
...
CSS
#_uploadFile {
display: none;
}
button {
background-color: #5c247b;
color: #ffffff;
border: none;
border-radius: 8px 0px;
margin: 5px;
padding: 5px;
line-height: 16px;
font-size: 14px;
outline: none;
cursor: pointer;
}
button.test {
display: none;/*Hide the test button untill the app has loaded*/
}
.employeesList > i {
margin-top: 10px;
margin-bottom: 10px;
display: block;
}
.employeesList .employeeLink a {
display: block;
width: 100%;
height: 20px;
line-height: 16px;
font-size: 16px;
padding: 5px;
border-bottom: solid 1px #cdcdcd;
cursor: pointer;
}
.payslipWrap {
background-color: #ededed;
border-radius: 8px 0px;
padding: 10px;
}
.payslipWrap table tr {
text-align: left;
text-transform: capitalize;
background-color: #ffffff;
}
.payslipWrap table {
width: 100%;
}
.payslipWrap table tr th {
padding: 5px;
}
.payslipWrap table tr td.number {
padding: 5px;
text-align: right;
}
footer {
position: fixed;
bottom: 0px;
left: 0px;
right: 0px;
min-height: 20px;
}
JavaScript
App = Em.Application.create();
function download(filename, text) {
var pom = document.createElement('a');
pom.setAttribute('href', 'data:text/plain;charset=utf-8,' + encodeURIComponent(text));
pom.setAttribute('download', filename);
pom.click();
}
/* Employee
*
*/
App.Employee = Em.Object.extend({
fullName: function(){
return this.get('firstName') +' '+this.get('lastName')
}.property('firstName', 'lastName'),
gross_income: function(){
//60,050 / 12 = 5,004.16666667 (round down) = 5,004
var annualSalary = this.get('annualSalary');
return Math.round(annualSalary / 12);
}.property('annualSalary'),
income_tax: function() {
//(3,572 + (60,050 - 37,000) x 0.325) / 12 = 921.9375 (round up) = 922
var annualSalary = this.get('annualSalary');
var taxes;
App.TaxTable.forEach(function(obj, i){
if (annualSalary < obj.max && annualSalary > obj.min) {
taxes = obj;
console.log("taxes object ", i, obj);
return obj;
}
});
var baseAmount = taxes.base;
var taxable = (annualSalary - taxes.min)
var taxPercent = taxes.overCents/100;
var val = (baseAmount + (taxable) * taxPercent) / 12
return Math.round(val);
}.property('annualSalary'),
net_income: function(){
//5,004 - 922 = 4,082
return this.get('gross_income') - this.get('income_tax');
}.property('gross_income', 'income_tax'),
super_annuation: function(){
return Math.round(this.get('gross_income') * (this.get('superRate')/100));
}.property('superRate'),
payslipCSV: function(){
var fullName = this.get('fullName');
var dates = this.get('paymentStartDate');
var gross_income = this.get('gross_income');
var income_tax = this.get('income_tax');
var net_income...