-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 2cff32f
Showing
12 changed files
with
347 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,136 @@ | ||
@font-face { | ||
font-family: 'fira_sansbold'; | ||
src: url('./fonts/FiraSans-Bold.eot'); | ||
src: url('./fonts/FiraSans-Bold.eot?#iefix') format('embedded-opentype'), | ||
url('./fonts/FiraSans-Bold.woff') format('woff'), | ||
url('./fonts/FiraSans-Bold.ttf') format('truetype'); | ||
font-weight: normal; | ||
font-style: normal; | ||
|
||
} | ||
|
||
|
||
@font-face { | ||
font-family: 'fira_sansregular'; | ||
src: url('./fonts/FiraSans-Regular.eot'); | ||
src: url('./fonts/FiraSans-Regular.eot?#iefix') format('embedded-opentype'), | ||
url('./fonts/FiraSans-Regular.woff') format('woff'), | ||
url('./fonts/FiraSans-Regular.ttf') format('truetype'); | ||
font-weight: normal; | ||
font-style: normal; | ||
} | ||
|
||
@font-face { | ||
font-family: 'fira_sanslight'; | ||
src: url('./fonts/FiraSans-Light.eot'); | ||
src: url('./fonts/FiraSans-Light.eot?#iefix') format('embedded-opentype'), | ||
url('./fonts/FiraSans-Light.woff') format('woff'), | ||
url('./fonts/FiraSans-Light.ttf') format('truetype'); | ||
font-weight: normal; | ||
font-style: normal; | ||
} | ||
.csvtogeocoder { | ||
font-family: 'fira_sanslight', sans-serif; | ||
padding: 20px; | ||
} | ||
.csvtogeocoder h1, .csvtogeocoder h2 { | ||
font-family: 'fira_sansbold', sans-serif; | ||
font-weight: normal; | ||
} | ||
.csvtogeocoder #holder, | ||
.csvtogeocoder #chosenColumns, | ||
.csvtogeocoder #availableColumns { | ||
width: 90%; | ||
margin: 20px auto; | ||
} | ||
.csvtogeocoder #holder { | ||
border: 1px dashed #ccc; | ||
height: 200px; | ||
text-align: center; | ||
line-height: 200px; | ||
} | ||
.csvtogeocoder #availableColumns { | ||
padding: 0; | ||
} | ||
.csvtogeocoder #holder.hover { border: 1px dashed #333; } | ||
.csvtogeocoder #chosenColumns { | ||
padding: 0; | ||
height: 37px; | ||
line-height: 37px; | ||
border: 1px dashed #ccc; | ||
color: #ccc; | ||
} | ||
.csvtogeocoder #chosenColumns:empty:before { | ||
content: 'Drag columns here'; | ||
padding-left: 5px; | ||
} | ||
.csvtogeocoder #chosenColumns li, | ||
.csvtogeocoder #availableColumns li { | ||
background-color: #eee; | ||
border: 1px solid #aaa; | ||
display: inline; | ||
padding: 5px 5px 5px 0;; | ||
cursor: grab; | ||
color: #444; | ||
margin-right: 2px; | ||
} | ||
.csvtogeocoder #chosenColumns li:before, | ||
.csvtogeocoder #availableColumns li:before { | ||
background-color: #999; | ||
color: #efefef; | ||
content: "+"; | ||
display: inline-block; | ||
font-family: fira_sansbold; | ||
height: 35px; | ||
line-height: 35px; | ||
margin-right: 5px; | ||
padding: 0 5px; | ||
vertical-align: middle; | ||
cursor: pointer; | ||
} | ||
.csvtogeocoder #chosenColumns li:before { | ||
content: '-'; | ||
} | ||
.csvtogeocoder #chosenColumns.hover { border: 1px dashed #333; } | ||
.csvtogeocoder #fileInput {display: none;} | ||
.csvtogeocoder input[type="button"] { | ||
display: block; | ||
min-width: 200px; | ||
background-color: #2c3e50; | ||
color: #fff; | ||
border: none; | ||
margin-bottom: 14px; | ||
text-align: center; | ||
min-height: 56px; | ||
line-height: 56px; | ||
border-radius: 2px; | ||
font-weight: normal; | ||
cursor: pointer; | ||
margin-left: auto; | ||
margin-right: auto; | ||
} | ||
.csvtogeocoder input[type="button"]:hover { | ||
background-color: #34495e; | ||
} | ||
.csvtogeocoder .progressBar { | ||
-moz-box-sizing: border-box; | ||
-webkit-box-sizing: border-box; | ||
box-sizing: border-box; | ||
height: 10px; | ||
width: 90%; | ||
margin: 20px auto; | ||
border: 1px solid #444; | ||
} | ||
.csvtogeocoder .progressBar hr { | ||
background-color: #444; | ||
border: medium none; | ||
color: #444; | ||
height: 8px; | ||
line-height: 10px; | ||
margin: 0; | ||
text-align: left; | ||
vertical-align: middle; | ||
width: 0; | ||
-webkit-transition: all 500ms ease-in; | ||
transition: all 500ms ease-in; | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,196 @@ | ||
var CSVToGeocoder = function (options) { | ||
options = options || {}; | ||
|
||
var createNode = function (what, attrs, parent, content) { | ||
var el = document.createElement(what); | ||
for (var attr in attrs || {}) el[attr] = attrs[attr]; | ||
if (typeof parent !== 'undefined') parent.appendChild(el); | ||
if (content) { | ||
if (content.nodeType && content.nodeType === 1) el.appendChild(content); | ||
else el.innerHTML = content; | ||
} | ||
return el; | ||
}; | ||
|
||
var reader = new FileReader(), file, | ||
formData = new FormData(), container; | ||
if (options.container) { | ||
if (typeof options.container === "string") container = document.querySelector(options.container); | ||
else container = options.container; | ||
} else { | ||
container = document.body; | ||
} | ||
container.setAttribute('class', (container.getAttribute('class') ? container.getAttribute('class') + ' ' : '') + 'csvtogeocoder'); | ||
createNode('h2', {}, container, '1. Choose a file'); | ||
var fileInput = createNode('input', {type: 'file', id: 'fileInput'}, container); | ||
var holder = createNode('div', {id: 'holder'}, container, 'Drag your file here, or <a id="browseLink" href="#">browse</a>'); | ||
createNode('h2', {}, container, '2. Choose the columns to consider'); | ||
var availableColumns = createNode('ul', {id: 'availableColumns'}, container); | ||
var chosenColumns = createNode('ul', {id: 'chosenColumns'}, container); | ||
createNode('h2', {}, container, '3. Run the process'); | ||
var optionsContainer = createNode('div', {id: 'options'}, container), | ||
matchAllContainer = createNode('label', {'for': 'matchAll'}, optionsContainer, 'Strict (all words must be found)'), | ||
matchAll = createNode('input', {type: 'checkbox', id: 'matchAll'}, matchAllContainer); | ||
var submitButton = createNode('input', {type: 'button', value: 'Geocode', disabled: 'disabled'}, container); | ||
|
||
var stop = function (e) { | ||
e.stopPropagation(); | ||
e.preventDefault(); | ||
}; | ||
var submit = function () { | ||
var progressBarContainer = createNode('div', {className: 'progressBar'}, container), | ||
progressBar = createNode('hr', {}, progressBarContainer); | ||
var xhr = new XMLHttpRequest(); | ||
xhr.open('POST', options.postURL || '.'); | ||
xhr.overrideMimeType('text/csv; charset=utf-8'); | ||
var columns = document.querySelectorAll('#chosenColumns li'); | ||
for (var i = 0; i < columns.length; i++) { | ||
formData.append('columns', columns[i].id); | ||
} | ||
formData.append('match_all', !!matchAll.checked); | ||
xhr.onreadystatechange = function() { | ||
if (xhr.readyState === 4 && xhr.status === 200) { | ||
window.URL = window.URL || window.webkitURL; | ||
var blob = new Blob([xhr.responseText], {type: 'text/csv'}); | ||
window.open(window.URL.createObjectURL(blob)); | ||
} | ||
}; | ||
xhr.upload.addEventListener("progress", function (e) { | ||
if (e.lengthComputable) { | ||
var percentage = Math.round((e.loaded * 100) / e.total); | ||
progressBar.style.width = percentage + '%'; | ||
} | ||
}, false); | ||
xhr.upload.addEventListener("load", function(e){ | ||
progressBarContainer.parentNode.removeChild(progressBarContainer); | ||
}, false); | ||
xhr.send(formData); | ||
return false; | ||
}; | ||
var processFile = function (f) { | ||
file = f; | ||
reader.readAsText(file); | ||
holder.innerHTML = '<strong>' + file.name + '</strong> (or drag another file here, or <a id="browseLink" href="#">browse</a>)'; | ||
listenBrowseLink(); | ||
}; | ||
var onFileDrop = function (e) { | ||
this.className = ''; | ||
stop(e); | ||
processFile(e.dataTransfer.files[0]); | ||
}; | ||
var onDragOver = function (e) { | ||
stop(e); | ||
this.className = 'hover'; | ||
}; | ||
var onDragLeave = function (e) { | ||
stop(e); | ||
this.className = ''; | ||
return false; | ||
}; | ||
var onDragEnter = function (e) { | ||
stop(e); | ||
}; | ||
var onFileLoad = function () { | ||
var rawHeaders = reader.result.slice(0, reader.result.indexOf('\n')), | ||
separators = [',', ';', '|', ':'], currentCount = 0, separator, count; | ||
for (var i = 0; i < separators.length; i++) { | ||
count = (rawHeaders.match(new RegExp('\\' + separators[i],'g')) || []).length; | ||
if (count > currentCount) { | ||
currentCount = count; | ||
separator = separators[i]; | ||
} | ||
} | ||
if (currentCount === 0) return; | ||
var headers = rawHeaders.split(separator), column; | ||
availableColumns.innerHTML = ''; | ||
chosenColumns.innerHTML = ''; | ||
for (var j = 0; j < headers.length; j++) { | ||
column = document.createElement('li'); | ||
column.setAttribute('draggable', 'true'); | ||
column.innerHTML = column.value = column.id = headers[j]; | ||
column.ondragstart = onColumnDragStart; | ||
column.onclick = onColumnClick; | ||
column.ondrop = onColumnDrop; | ||
column.ondragover = onColumnDragOver; | ||
column.ondragleave = onColumnDragLeave; | ||
availableColumns.appendChild(column); | ||
} | ||
submitButton.disabled = false; | ||
var blob = new Blob([reader.result], {type: 'text/csv'}); | ||
formData.append('data', blob); | ||
}; | ||
var onSubmit = function (e) { | ||
stop(e); | ||
submit(file); | ||
return false; | ||
}; | ||
var onColumnDragStart = function (e) { | ||
e.dataTransfer.effectAllowed = 'copyMove'; | ||
e.dataTransfer.setData('text/plain', this.id); | ||
}; | ||
var onColumnDropboxDragover = function (e) { | ||
stop(e); | ||
this.className = 'hover'; | ||
e.dataTransfer.dropEffect = 'copyMove'; | ||
}; | ||
var onColumnDropboxDragleave = function (e) { | ||
stop(e); | ||
this.className = ''; | ||
}; | ||
var onColumnDropboxDrop = function (e) { | ||
this.className = ''; | ||
stop(e); | ||
var el = document.getElementById(e.dataTransfer.getData('text/plain')); | ||
el.parentNode.removeChild(el); | ||
chosenColumns.appendChild(el); | ||
return false; | ||
}; | ||
var onColumnDrop = function (e) { | ||
stop(e); | ||
var el = document.getElementById(e.dataTransfer.getData('text/plain')); | ||
this.parentNode.insertBefore(el, this); | ||
}; | ||
var onColumnClick = function (e) { | ||
this.className = ''; | ||
var from, to; | ||
if (this.parentNode === chosenColumns) { | ||
from = chosenColumns; | ||
to = availableColumns; | ||
} else { | ||
from = availableColumns; | ||
to = chosenColumns; | ||
} | ||
from.removeChild(this); | ||
to.appendChild(this); | ||
}; | ||
var onColumnDragOver = function (e) { | ||
this.className = 'hover'; | ||
}; | ||
var onColumnDragLeave = function (e) { | ||
this.className = ''; | ||
}; | ||
var onFileInputChange = function (e) { | ||
stop(e); | ||
processFile(this.files[0]); | ||
}; | ||
var listenBrowseLink = function () { | ||
var browseLink = document.querySelector('#browseLink'); | ||
var onBrowseLinkClick = function (e) { | ||
stop(e); | ||
fileInput.click(); | ||
}; | ||
browseLink.addEventListener('click', onBrowseLinkClick, false); | ||
}; | ||
listenBrowseLink(); | ||
reader.addEventListener('load', onFileLoad, false); | ||
holder.addEventListener('dragenter', onDragEnter, false); | ||
holder.addEventListener('dragover', onDragOver, false); | ||
holder.addEventListener('dragleave', onDragLeave, false); | ||
holder.addEventListener('drop', onFileDrop, false); | ||
submitButton.addEventListener('click', onSubmit, false); | ||
chosenColumns.addEventListener('dragover', onColumnDropboxDragover, false); | ||
chosenColumns.addEventListener('dragleave', onColumnDropboxDragleave, false); | ||
chosenColumns.addEventListener('drop', onColumnDropboxDrop, false); | ||
fileInput.addEventListener('change', onFileInputChange, false); | ||
|
||
}; |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
{ | ||
"name": "csvtogeocoder-ui", | ||
"version": "0.0.1", | ||
"description": "Javascript UI to help users upload a CSV to be geocoded", | ||
"main": "csvtogeocode.js", | ||
"scripts": { | ||
"test": "echo \"Error: no test specified\" && exit 1" | ||
}, | ||
"keywords": [ | ||
"csv", | ||
"geocoding" | ||
], | ||
"author": "Yohan Boniface", | ||
"license": "WTFPL" | ||
} |