|
|
Line 10: |
Line 10: |
| <meta charset="UTF-8"> | | <meta charset="UTF-8"> |
| <script src="http://code.jquery.com/jquery-1.8.2.js"></script> | | <script src="http://code.jquery.com/jquery-1.8.2.js"></script> |
− | <script type='text/javascript'> | + | <script src='https://2017.igem.org/Team:William_and_Mary/jquery_csvplugin?action=raw&ctype=text/javascript' type='text/javascript'></script> |
− | /**
| + | |
− | * jQuery-csv (jQuery Plugin)
| + | |
− | *
| + | |
− | * This document is licensed as free software under the terms of the
| + | |
− | * MIT License: http://www.opensource.org/licenses/mit-license.php
| + | |
− | *
| + | |
− | * Acknowledgements:
| + | |
− | * The original design and influence to implement this library as a jquery
| + | |
− | * plugin is influenced by jquery-json (http://code.google.com/p/jquery-json/).
| + | |
− | * If you're looking to use native JSON.Stringify but want additional backwards
| + | |
− | * compatibility for browsers that don't support it, I highly recommend you
| + | |
− | * check it out.
| + | |
− | *
| + | |
− | * A special thanks goes out to rwk@acm.org for providing a lot of valuable
| + | |
− | * feedback to the project including the core for the new FSM
| + | |
− | * (Finite State Machine) parsers. If you're looking for a stable TSV parser
| + | |
− | * be sure to take a look at jquery-tsv (http://code.google.com/p/jquery-tsv/).
| + | |
− | | + | |
− | * For legal purposes I'll include the "NO WARRANTY EXPRESSED OR IMPLIED.
| + | |
− | * USE AT YOUR OWN RISK.". Which, in 'layman's terms' means, by using this
| + | |
− | * library you are accepting responsibility if it breaks your code.
| + | |
− | *
| + | |
− | * Legal jargon aside, I will do my best to provide a useful and stable core
| + | |
− | * that can effectively be built on.
| + | |
− | *
| + | |
− | * Copyrighted 2012 by Evan Plaice.
| + | |
− | */
| + | |
− | | + | |
− | RegExp.escape= function(s) {
| + | |
− | return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
| + | |
− | };
| + | |
− | | + | |
− | (function (undefined) {
| + | |
− | 'use strict';
| + | |
− | | + | |
− | var $;
| + | |
− | | + | |
− | // to keep backwards compatibility
| + | |
− | if (typeof jQuery !== 'undefined' && jQuery) {
| + | |
− | $ = jQuery;
| + | |
− | } else {
| + | |
− | $ = {};
| + | |
− | }
| + | |
− | | + | |
− | | + | |
− | /**
| + | |
− | * jQuery.csv.defaults
| + | |
− | * Encapsulates the method paramater defaults for the CSV plugin module.
| + | |
− | */
| + | |
− | | + | |
− | $.csv = {
| + | |
− | defaults: {
| + | |
− | separator:',',
| + | |
− | delimiter:'"',
| + | |
− | headers:true
| + | |
− | },
| + | |
− | | + | |
− | hooks: {
| + | |
− | castToScalar: function(value, state) {
| + | |
− | var hasDot = /\./;
| + | |
− | if (isNaN(value)) {
| + | |
− | return value;
| + | |
− | } else {
| + | |
− | if (hasDot.test(value)) {
| + | |
− | return parseFloat(value);
| + | |
− | } else {
| + | |
− | var integer = parseInt(value);
| + | |
− | if(isNaN(integer)) {
| + | |
− | return null;
| + | |
− | } else {
| + | |
− | return integer;
| + | |
− | }
| + | |
− | }
| + | |
− | }
| + | |
− | }
| + | |
− | },
| + | |
− | | + | |
− | parsers: {
| + | |
− | parse: function(csv, options) {
| + | |
− | // cache settings
| + | |
− | var separator = options.separator;
| + | |
− | var delimiter = options.delimiter;
| + | |
− | | + | |
− | // set initial state if it's missing
| + | |
− | if(!options.state.rowNum) {
| + | |
− | options.state.rowNum = 1;
| + | |
− | }
| + | |
− | if(!options.state.colNum) {
| + | |
− | options.state.colNum = 1;
| + | |
− | }
| + | |
− | | + | |
− | // clear initial state
| + | |
− | var data = [];
| + | |
− | var entry = [];
| + | |
− | var state = 0;
| + | |
− | var value = '';
| + | |
− | var exit = false;
| + | |
− | | + | |
− | function endOfEntry() {
| + | |
− | // reset the state
| + | |
− | state = 0;
| + | |
− | value = '';
| + | |
− | | + | |
− | // if 'start' hasn't been met, don't output
| + | |
− | if(options.start && options.state.rowNum < options.start) {
| + | |
− | // update global state
| + | |
− | entry = [];
| + | |
− | options.state.rowNum++;
| + | |
− | options.state.colNum = 1;
| + | |
− | return;
| + | |
− | }
| + | |
− |
| + | |
− | if(options.onParseEntry === undefined) {
| + | |
− | // onParseEntry hook not set
| + | |
− | data.push(entry);
| + | |
− | } else {
| + | |
− | var hookVal = options.onParseEntry(entry, options.state); // onParseEntry Hook
| + | |
− | // false skips the row, configurable through a hook
| + | |
− | if(hookVal !== false) {
| + | |
− | data.push(hookVal);
| + | |
− | }
| + | |
− | }
| + | |
− | //console.log('entry:' + entry);
| + | |
− |
| + | |
− | // cleanup
| + | |
− | entry = [];
| + | |
− | | + | |
− | // if 'end' is met, stop parsing
| + | |
− | if(options.end && options.state.rowNum >= options.end) {
| + | |
− | exit = true;
| + | |
− | }
| + | |
− |
| + | |
− | // update global state
| + | |
− | options.state.rowNum++;
| + | |
− | options.state.colNum = 1;
| + | |
− | }
| + | |
− | | + | |
− | function endOfValue() {
| + | |
− | if(options.onParseValue === undefined) {
| + | |
− | // onParseValue hook not set
| + | |
− | entry.push(value);
| + | |
− | } else {
| + | |
− | var hook = options.onParseValue(value, options.state); // onParseValue Hook
| + | |
− | // false skips the row, configurable through a hook
| + | |
− | if(hook !== false) {
| + | |
− | entry.push(hook);
| + | |
− | }
| + | |
− | }
| + | |
− | //console.log('value:' + value);
| + | |
− | // reset the state
| + | |
− | value = '';
| + | |
− | state = 0;
| + | |
− | // update global state
| + | |
− | options.state.colNum++;
| + | |
− | }
| + | |
− | | + | |
− | // escape regex-specific control chars
| + | |
− | var escSeparator = RegExp.escape(separator);
| + | |
− | var escDelimiter = RegExp.escape(delimiter);
| + | |
− | | + | |
− | // compile the regEx str using the custom delimiter/separator
| + | |
− | var match = /(D|S|\r\n|\n|\r|[^DS\r\n]+)/;
| + | |
− | var matchSrc = match.source;
| + | |
− | matchSrc = matchSrc.replace(/S/g, escSeparator);
| + | |
− | matchSrc = matchSrc.replace(/D/g, escDelimiter);
| + | |
− | match = new RegExp(matchSrc, 'gm');
| + | |
− | | + | |
− | // put on your fancy pants...
| + | |
− | // process control chars individually, use look-ahead on non-control chars
| + | |
− | csv.replace(match, function (m0) {
| + | |
− | if(exit) {
| + | |
− | return;
| + | |
− | }
| + | |
− | switch (state) {
| + | |
− | // the start of a value
| + | |
− | case 0:
| + | |
− | // null last value
| + | |
− | if (m0 === separator) {
| + | |
− | value += '';
| + | |
− | endOfValue();
| + | |
− | break;
| + | |
− | }
| + | |
− | // opening delimiter
| + | |
− | if (m0 === delimiter) {
| + | |
− | state = 1;
| + | |
− | break;
| + | |
− | }
| + | |
− | // null last value
| + | |
− | if (/^(\r\n|\n|\r)$/.test(m0)) {
| + | |
− | endOfValue();
| + | |
− | endOfEntry();
| + | |
− | break;
| + | |
− | }
| + | |
− | // un-delimited value
| + | |
− | value += m0;
| + | |
− | state = 3;
| + | |
− | break;
| + | |
− | | + | |
− | // delimited input
| + | |
− | case 1:
| + | |
− | // second delimiter? check further
| + | |
− | if (m0 === delimiter) {
| + | |
− | state = 2;
| + | |
− | break;
| + | |
− | }
| + | |
− | // delimited data
| + | |
− | value += m0;
| + | |
− | state = 1;
| + | |
− | break;
| + | |
− | | + | |
− | // delimiter found in delimited input
| + | |
− | case 2:
| + | |
− | // escaped delimiter?
| + | |
− | if (m0 === delimiter) {
| + | |
− | value += m0;
| + | |
− | state = 1;
| + | |
− | break;
| + | |
− | }
| + | |
− | // null value
| + | |
− | if (m0 === separator) {
| + | |
− | endOfValue();
| + | |
− | break;
| + | |
− | }
| + | |
− | // end of entry
| + | |
− | if (/^(\r\n|\n|\r)$/.test(m0)) {
| + | |
− | endOfValue();
| + | |
− | endOfEntry();
| + | |
− | break;
| + | |
− | }
| + | |
− | // broken paser?
| + | |
− | throw new Error('CSVDataError: Illegal State [Row:' + options.state.rowNum + '][Col:' + options.state.colNum + ']');
| + | |
− | | + | |
− | // un-delimited input
| + | |
− | case 3:
| + | |
− | // null last value
| + | |
− | if (m0 === separator) {
| + | |
− | endOfValue();
| + | |
− | break;
| + | |
− | }
| + | |
− | // end of entry
| + | |
− | if (/^(\r\n|\n|\r)$/.test(m0)) {
| + | |
− | endOfValue();
| + | |
− | endOfEntry();
| + | |
− | break;
| + | |
− | }
| + | |
− | if (m0 === delimiter) {
| + | |
− | // non-compliant data
| + | |
− | throw new Error('CSVDataError: Illegal Quote [Row:' + options.state.rowNum + '][Col:' + options.state.colNum + ']');
| + | |
− | }
| + | |
− | // broken parser?
| + | |
− | throw new Error('CSVDataError: Illegal Data [Row:' + options.state.rowNum + '][Col:' + options.state.colNum + ']');
| + | |
− | default:
| + | |
− | // shenanigans
| + | |
− | throw new Error('CSVDataError: Unknown State [Row:' + options.state.rowNum + '][Col:' + options.state.colNum + ']');
| + | |
− | }
| + | |
− | //console.log('val:' + m0 + ' state:' + state);
| + | |
− | });
| + | |
− | | + | |
− | // submit the last entry
| + | |
− | // ignore null last line
| + | |
− | if(entry.length !== 0) {
| + | |
− | endOfValue();
| + | |
− | endOfEntry();
| + | |
− | }
| + | |
− | | + | |
− | return data;
| + | |
− | },
| + | |
− | | + | |
− | // a csv-specific line splitter
| + | |
− | splitLines: function(csv, options) {
| + | |
− | // cache settings
| + | |
− | var separator = options.separator;
| + | |
− | var delimiter = options.delimiter;
| + | |
− | | + | |
− | // set initial state if it's missing
| + | |
− | if(!options.state.rowNum) {
| + | |
− | options.state.rowNum = 1;
| + | |
− | }
| + | |
− | | + | |
− | // clear initial state
| + | |
− | var entries = [];
| + | |
− | var state = 0;
| + | |
− | var entry = '';
| + | |
− | var exit = false;
| + | |
− | | + | |
− | function endOfLine() {
| + | |
− | // reset the state
| + | |
− | state = 0;
| + | |
− |
| + | |
− | // if 'start' hasn't been met, don't output
| + | |
− | if(options.start && options.state.rowNum < options.start) {
| + | |
− | // update global state
| + | |
− | entry = '';
| + | |
− | options.state.rowNum++;
| + | |
− | return;
| + | |
− | }
| + | |
− |
| + | |
− | if(options.onParseEntry === undefined) {
| + | |
− | // onParseEntry hook not set
| + | |
− | entries.push(entry);
| + | |
− | } else {
| + | |
− | var hookVal = options.onParseEntry(entry, options.state); // onParseEntry Hook
| + | |
− | // false skips the row, configurable through a hook
| + | |
− | if(hookVal !== false) {
| + | |
− | entries.push(hookVal);
| + | |
− | }
| + | |
− | }
| + | |
− | | + | |
− | // cleanup
| + | |
− | entry = '';
| + | |
− | | + | |
− | // if 'end' is met, stop parsing
| + | |
− | if(options.end && options.state.rowNum >= options.end) {
| + | |
− | exit = true;
| + | |
− | }
| + | |
− |
| + | |
− | // update global state
| + | |
− | options.state.rowNum++;
| + | |
− | }
| + | |
− | | + | |
− | // escape regex-specific control chars
| + | |
− | var escSeparator = RegExp.escape(separator);
| + | |
− | var escDelimiter = RegExp.escape(delimiter);
| + | |
− | | + | |
− | // compile the regEx str using the custom delimiter/separator
| + | |
− | var match = /(D|S|\n|\r|[^DS\r\n]+)/;
| + | |
− | var matchSrc = match.source;
| + | |
− | matchSrc = matchSrc.replace(/S/g, escSeparator);
| + | |
− | matchSrc = matchSrc.replace(/D/g, escDelimiter);
| + | |
− | match = new RegExp(matchSrc, 'gm');
| + | |
− | | + | |
− | // put on your fancy pants...
| + | |
− | // process control chars individually, use look-ahead on non-control chars
| + | |
− | csv.replace(match, function (m0) {
| + | |
− | if(exit) {
| + | |
− | return;
| + | |
− | }
| + | |
− | switch (state) {
| + | |
− | // the start of a value/entry
| + | |
− | case 0:
| + | |
− | // null value
| + | |
− | if (m0 === separator) {
| + | |
− | entry += m0;
| + | |
− | state = 0;
| + | |
− | break;
| + | |
− | }
| + | |
− | // opening delimiter
| + | |
− | if (m0 === delimiter) {
| + | |
− | entry += m0;
| + | |
− | state = 1;
| + | |
− | break;
| + | |
− | }
| + | |
− | // end of line
| + | |
− | if (m0 === '\n') {
| + | |
− | endOfLine();
| + | |
− | break;
| + | |
− | }
| + | |
− | // phantom carriage return
| + | |
− | if (/^\r$/.test(m0)) {
| + | |
− | break;
| + | |
− | }
| + | |
− | // un-delimit value
| + | |
− | entry += m0;
| + | |
− | state = 3;
| + | |
− | break;
| + | |
− | | + | |
− | // delimited input
| + | |
− | case 1:
| + | |
− | // second delimiter? check further
| + | |
− | if (m0 === delimiter) {
| + | |
− | entry += m0;
| + | |
− | state = 2;
| + | |
− | break;
| + | |
− | }
| + | |
− | // delimited data
| + | |
− | entry += m0;
| + | |
− | state = 1;
| + | |
− | break;
| + | |
− | | + | |
− | // delimiter found in delimited input
| + | |
− | case 2:
| + | |
− | // escaped delimiter?
| + | |
− | var prevChar = entry.substr(entry.length - 1);
| + | |
− | if (m0 === delimiter && prevChar === delimiter) {
| + | |
− | entry += m0;
| + | |
− | state = 1;
| + | |
− | break;
| + | |
− | }
| + | |
− | // end of value
| + | |
− | if (m0 === separator) {
| + | |
− | entry += m0;
| + | |
− | state = 0;
| + | |
− | break;
| + | |
− | }
| + | |
− | // end of line
| + | |
− | if (m0 === '\n') {
| + | |
− | endOfLine();
| + | |
− | break;
| + | |
− | }
| + | |
− | // phantom carriage return
| + | |
− | if (m0 === '\r') {
| + | |
− | break;
| + | |
− | }
| + | |
− | // broken paser?
| + | |
− | throw new Error('CSVDataError: Illegal state [Row:' + options.state.rowNum + ']');
| + | |
− | | + | |
− | // un-delimited input
| + | |
− | case 3:
| + | |
− | // null value
| + | |
− | if (m0 === separator) {
| + | |
− | entry += m0;
| + | |
− | state = 0;
| + | |
− | break;
| + | |
− | }
| + | |
− | // end of line
| + | |
− | if (m0 === '\n') {
| + | |
− | endOfLine();
| + | |
− | break;
| + | |
− | }
| + | |
− | // phantom carriage return
| + | |
− | if (m0 === '\r') {
| + | |
− | break;
| + | |
− | }
| + | |
− | // non-compliant data
| + | |
− | if (m0 === delimiter) {
| + | |
− | throw new Error('CSVDataError: Illegal quote [Row:' + options.state.rowNum + ']');
| + | |
− | }
| + | |
− | // broken parser?
| + | |
− | throw new Error('CSVDataError: Illegal state [Row:' + options.state.rowNum + ']');
| + | |
− | default:
| + | |
− | // shenanigans
| + | |
− | throw new Error('CSVDataError: Unknown state [Row:' + options.state.rowNum + ']');
| + | |
− | }
| + | |
− | //console.log('val:' + m0 + ' state:' + state);
| + | |
− | });
| + | |
− | | + | |
− | // submit the last entry
| + | |
− | // ignore null last line
| + | |
− | if(entry !== '') {
| + | |
− | endOfLine();
| + | |
− | }
| + | |
− | | + | |
− | return entries;
| + | |
− | },
| + | |
− | | + | |
− | // a csv entry parser
| + | |
− | parseEntry: function(csv, options) {
| + | |
− | // cache settings
| + | |
− | var separator = options.separator;
| + | |
− | var delimiter = options.delimiter;
| + | |
− |
| + | |
− | // set initial state if it's missing
| + | |
− | if(!options.state.rowNum) {
| + | |
− | options.state.rowNum = 1;
| + | |
− | }
| + | |
− | if(!options.state.colNum) {
| + | |
− | options.state.colNum = 1;
| + | |
− | }
| + | |
− | | + | |
− | // clear initial state
| + | |
− | var entry = [];
| + | |
− | var state = 0;
| + | |
− | var value = '';
| + | |
− | | + | |
− | function endOfValue() {
| + | |
− | if(options.onParseValue === undefined) {
| + | |
− | // onParseValue hook not set
| + | |
− | entry.push(value);
| + | |
− | } else {
| + | |
− | var hook = options.onParseValue(value, options.state); // onParseValue Hook
| + | |
− | // false skips the value, configurable through a hook
| + | |
− | if(hook !== false) {
| + | |
− | entry.push(hook);
| + | |
− | }
| + | |
− | }
| + | |
− | // reset the state
| + | |
− | value = '';
| + | |
− | state = 0;
| + | |
− | // update global state
| + | |
− | options.state.colNum++;
| + | |
− | }
| + | |
− | | + | |
− | // checked for a cached regEx first
| + | |
− | if(!options.match) {
| + | |
− | // escape regex-specific control chars
| + | |
− | var escSeparator = RegExp.escape(separator);
| + | |
− | var escDelimiter = RegExp.escape(delimiter);
| + | |
− |
| + | |
− | // compile the regEx str using the custom delimiter/separator
| + | |
− | var match = /(D|S|\n|\r|[^DS\r\n]+)/;
| + | |
− | var matchSrc = match.source;
| + | |
− | matchSrc = matchSrc.replace(/S/g, escSeparator);
| + | |
− | matchSrc = matchSrc.replace(/D/g, escDelimiter);
| + | |
− | options.match = new RegExp(matchSrc, 'gm');
| + | |
− | }
| + | |
− | | + | |
− | // put on your fancy pants...
| + | |
− | // process control chars individually, use look-ahead on non-control chars
| + | |
− | csv.replace(options.match, function (m0) {
| + | |
− | switch (state) {
| + | |
− | // the start of a value
| + | |
− | case 0:
| + | |
− | // null last value
| + | |
− | if (m0 === separator) {
| + | |
− | value += '';
| + | |
− | endOfValue();
| + | |
− | break;
| + | |
− | }
| + | |
− | // opening delimiter
| + | |
− | if (m0 === delimiter) {
| + | |
− | state = 1;
| + | |
− | break;
| + | |
− | }
| + | |
− | // skip un-delimited new-lines
| + | |
− | if (m0 === '\n' || m0 === '\r') {
| + | |
− | break;
| + | |
− | }
| + | |
− | // un-delimited value
| + | |
− | value += m0;
| + | |
− | state = 3;
| + | |
− | break;
| + | |
− | | + | |
− | // delimited input
| + | |
− | case 1:
| + | |
− | // second delimiter? check further
| + | |
− | if (m0 === delimiter) {
| + | |
− | state = 2;
| + | |
− | break;
| + | |
− | }
| + | |
− | // delimited data
| + | |
− | value += m0;
| + | |
− | state = 1;
| + | |
− | break;
| + | |
− | | + | |
− | // delimiter found in delimited input
| + | |
− | case 2:
| + | |
− | // escaped delimiter?
| + | |
− | if (m0 === delimiter) {
| + | |
− | value += m0;
| + | |
− | state = 1;
| + | |
− | break;
| + | |
− | }
| + | |
− | // null value
| + | |
− | if (m0 === separator) {
| + | |
− | endOfValue();
| + | |
− | break;
| + | |
− | }
| + | |
− | // skip un-delimited new-lines
| + | |
− | if (m0 === '\n' || m0 === '\r') {
| + | |
− | break;
| + | |
− | }
| + | |
− | // broken paser?
| + | |
− | throw new Error('CSVDataError: Illegal State [Row:' + options.state.rowNum + '][Col:' + options.state.colNum + ']');
| + | |
− | | + | |
− | // un-delimited input
| + | |
− | case 3:
| + | |
− | // null last value
| + | |
− | if (m0 === separator) {
| + | |
− | endOfValue();
| + | |
− | break;
| + | |
− | }
| + | |
− | // skip un-delimited new-lines
| + | |
− | if (m0 === '\n' || m0 === '\r') {
| + | |
− | break;
| + | |
− | }
| + | |
− | // non-compliant data
| + | |
− | if (m0 === delimiter) {
| + | |
− | throw new Error('CSVDataError: Illegal Quote [Row:' + options.state.rowNum + '][Col:' + options.state.colNum + ']');
| + | |
− | }
| + | |
− | // broken parser?
| + | |
− | throw new Error('CSVDataError: Illegal Data [Row:' + options.state.rowNum + '][Col:' + options.state.colNum + ']');
| + | |
− | default:
| + | |
− | // shenanigans
| + | |
− | throw new Error('CSVDataError: Unknown State [Row:' + options.state.rowNum + '][Col:' + options.state.colNum + ']');
| + | |
− | }
| + | |
− | //console.log('val:' + m0 + ' state:' + state);
| + | |
− | });
| + | |
− | | + | |
− | // submit the last value
| + | |
− | endOfValue();
| + | |
− | | + | |
− | return entry;
| + | |
− | }
| + | |
− | },
| + | |
− | | + | |
− | helpers: {
| + | |
− | | + | |
− | /**
| + | |
− | * $.csv.helpers.collectPropertyNames(objectsArray)
| + | |
− | * Collects all unique property names from all passed objects.
| + | |
− | *
| + | |
− | * @param {Array} objects Objects to collect properties from.
| + | |
− | *
| + | |
− | * Returns an array of property names (array will be empty,
| + | |
− | * if objects have no own properties).
| + | |
− | */
| + | |
− | collectPropertyNames: function (objects) {
| + | |
− | | + | |
− | var o, propName, props = [];
| + | |
− | for (o in objects) {
| + | |
− | for (propName in objects[o]) {
| + | |
− | if ((objects[o].hasOwnProperty(propName)) &&
| + | |
− | (props.indexOf(propName) < 0) &&
| + | |
− | (typeof objects[o][propName] !== 'function')) {
| + | |
− | | + | |
− | props.push(propName);
| + | |
− | }
| + | |
− | }
| + | |
− | }
| + | |
− | return props;
| + | |
− | }
| + | |
− | },
| + | |
− | | + | |
− | /**
| + | |
− | * $.csv.toArray(csv)
| + | |
− | * Converts a CSV entry string to a javascript array.
| + | |
− | *
| + | |
− | * @param {Array} csv The string containing the CSV data.
| + | |
− | * @param {Object} [options] An object containing user-defined options.
| + | |
− | * @param {Character} [separator] An override for the separator character. Defaults to a comma(,).
| + | |
− | * @param {Character} [delimiter] An override for the delimiter character. Defaults to a double-quote(").
| + | |
− | *
| + | |
− | * This method deals with simple CSV strings only. It's useful if you only
| + | |
− | * need to parse a single entry. If you need to parse more than one line,
| + | |
− | * use $.csv2Array instead.
| + | |
− | */
| + | |
− | toArray: function(csv, options, callback) {
| + | |
− | options = (options !== undefined ? options : {});
| + | |
− | var config = {};
| + | |
− | config.callback = ((callback !== undefined && typeof(callback) === 'function') ? callback : false);
| + | |
− | config.separator = 'separator' in options ? options.separator : $.csv.defaults.separator;
| + | |
− | config.delimiter = 'delimiter' in options ? options.delimiter : $.csv.defaults.delimiter;
| + | |
− | var state = (options.state !== undefined ? options.state : {});
| + | |
− | | + | |
− | // setup
| + | |
− | options = {
| + | |
− | delimiter: config.delimiter,
| + | |
− | separator: config.separator,
| + | |
− | onParseEntry: options.onParseEntry,
| + | |
− | onParseValue: options.onParseValue,
| + | |
− | state: state
| + | |
− | };
| + | |
− | | + | |
− | var entry = $.csv.parsers.parseEntry(csv, options);
| + | |
− | | + | |
− | // push the value to a callback if one is defined
| + | |
− | if(!config.callback) {
| + | |
− | return entry;
| + | |
− | } else {
| + | |
− | config.callback('', entry);
| + | |
− | }
| + | |
− | },
| + | |
− | | + | |
− | /**
| + | |
− | * $.csv.toArrays(csv)
| + | |
− | * Converts a CSV string to a javascript array.
| + | |
− | *
| + | |
− | * @param {String} csv The string containing the raw CSV data.
| + | |
− | * @param {Object} [options] An object containing user-defined options.
| + | |
− | * @param {Character} [separator] An override for the separator character. Defaults to a comma(,).
| + | |
− | * @param {Character} [delimiter] An override for the delimiter character. Defaults to a double-quote(").
| + | |
− | *
| + | |
− | * This method deals with multi-line CSV. The breakdown is simple. The first
| + | |
− | * dimension of the array represents the line (or entry/row) while the second
| + | |
− | * dimension contains the values (or values/columns).
| + | |
− | */
| + | |
− | toArrays: function(csv, options, callback) {
| + | |
− | options = (options !== undefined ? options : {});
| + | |
− | var config = {};
| + | |
− | config.callback = ((callback !== undefined && typeof(callback) === 'function') ? callback : false);
| + | |
− | config.separator = 'separator' in options ? options.separator : $.csv.defaults.separator;
| + | |
− | config.delimiter = 'delimiter' in options ? options.delimiter : $.csv.defaults.delimiter;
| + | |
− | | + | |
− | // setup
| + | |
− | var data = [];
| + | |
− | options = {
| + | |
− | delimiter: config.delimiter,
| + | |
− | separator: config.separator,
| + | |
− | onPreParse: options.onPreParse,
| + | |
− | onParseEntry: options.onParseEntry,
| + | |
− | onParseValue: options.onParseValue,
| + | |
− | onPostParse: options.onPostParse,
| + | |
− | start: options.start,
| + | |
− | end: options.end,
| + | |
− | state: {
| + | |
− | rowNum: 1,
| + | |
− | colNum: 1
| + | |
− | }
| + | |
− | };
| + | |
− | | + | |
− | // onPreParse hook
| + | |
− | if(options.onPreParse !== undefined) {
| + | |
− | options.onPreParse(csv, options.state);
| + | |
− | }
| + | |
− | | + | |
− | // parse the data
| + | |
− | data = $.csv.parsers.parse(csv, options);
| + | |
− | | + | |
− | // onPostParse hook
| + | |
− | if(options.onPostParse !== undefined) {
| + | |
− | options.onPostParse(data, options.state);
| + | |
− | }
| + | |
− | | + | |
− | // push the value to a callback if one is defined
| + | |
− | if(!config.callback) {
| + | |
− | return data;
| + | |
− | } else {
| + | |
− | config.callback('', data);
| + | |
− | }
| + | |
− | },
| + | |
− | | + | |
− | /**
| + | |
− | * $.csv.toObjects(csv)
| + | |
− | * Converts a CSV string to a javascript object.
| + | |
− | * @param {String} csv The string containing the raw CSV data.
| + | |
− | * @param {Object} [options] An object containing user-defined options.
| + | |
− | * @param {Character} [separator] An override for the separator character. Defaults to a comma(,).
| + | |
− | * @param {Character} [delimiter] An override for the delimiter character. Defaults to a double-quote(").
| + | |
− | * @param {Boolean} [headers] Indicates whether the data contains a header line. Defaults to true.
| + | |
− | *
| + | |
− | * This method deals with multi-line CSV strings. Where the headers line is
| + | |
− | * used as the key for each value per entry.
| + | |
− | */
| + | |
− | toObjects: function(csv, options, callback) {
| + | |
− | options = (options !== undefined ? options : {});
| + | |
− | var config = {};
| + | |
− | config.callback = ((callback !== undefined && typeof(callback) === 'function') ? callback : false);
| + | |
− | config.separator = 'separator' in options ? options.separator : $.csv.defaults.separator;
| + | |
− | config.delimiter = 'delimiter' in options ? options.delimiter : $.csv.defaults.delimiter;
| + | |
− | config.headers = 'headers' in options ? options.headers : $.csv.defaults.headers;
| + | |
− | options.start = 'start' in options ? options.start : 1;
| + | |
− |
| + | |
− | // account for headers
| + | |
− | if(config.headers) {
| + | |
− | options.start++;
| + | |
− | }
| + | |
− | if(options.end && config.headers) {
| + | |
− | options.end++;
| + | |
− | }
| + | |
− | | + | |
− | // setup
| + | |
− | var lines = [];
| + | |
− | var data = [];
| + | |
− | | + | |
− | options = {
| + | |
− | delimiter: config.delimiter,
| + | |
− | separator: config.separator,
| + | |
− | onPreParse: options.onPreParse,
| + | |
− | onParseEntry: options.onParseEntry,
| + | |
− | onParseValue: options.onParseValue,
| + | |
− | onPostParse: options.onPostParse,
| + | |
− | start: options.start,
| + | |
− | end: options.end,
| + | |
− | state: {
| + | |
− | rowNum: 1,
| + | |
− | colNum: 1
| + | |
− | },
| + | |
− | match: false,
| + | |
− | transform: options.transform
| + | |
− | };
| + | |
− | | + | |
− | // fetch the headers
| + | |
− | var headerOptions = {
| + | |
− | delimiter: config.delimiter,
| + | |
− | separator: config.separator,
| + | |
− | start: 1,
| + | |
− | end: 1,
| + | |
− | state: {
| + | |
− | rowNum:1,
| + | |
− | colNum:1
| + | |
− | }
| + | |
− | };
| + | |
− | | + | |
− | // onPreParse hook
| + | |
− | if(options.onPreParse !== undefined) {
| + | |
− | options.onPreParse(csv, options.state);
| + | |
− | }
| + | |
− | | + | |
− | // parse the csv
| + | |
− | var headerLine = $.csv.parsers.splitLines(csv, headerOptions);
| + | |
− | var headers = $.csv.toArray(headerLine[0], options);
| + | |
− | | + | |
− | // fetch the data
| + | |
− | lines = $.csv.parsers.splitLines(csv, options);
| + | |
− | | + | |
− | // reset the state for re-use
| + | |
− | options.state.colNum = 1;
| + | |
− | if(headers){
| + | |
− | options.state.rowNum = 2;
| + | |
− | } else {
| + | |
− | options.state.rowNum = 1;
| + | |
− | }
| + | |
− |
| + | |
− | // convert data to objects
| + | |
− | for(var i=0, len=lines.length; i<len; i++) {
| + | |
− | var entry = $.csv.toArray(lines[i], options);
| + | |
− | var object = {};
| + | |
− | for(var j=0; j <headers.length; j++) {
| + | |
− | object[headers[j]] = entry[j];
| + | |
− | }
| + | |
− | if (options.transform !== undefined) {
| + | |
− | data.push(options.transform.call(undefined, object));
| + | |
− | } else {
| + | |
− | data.push(object);
| + | |
− | }
| + | |
− |
| + | |
− | // update row state
| + | |
− | options.state.rowNum++;
| + | |
− | }
| + | |
− | | + | |
− | // onPostParse hook
| + | |
− | if(options.onPostParse !== undefined) {
| + | |
− | options.onPostParse(data, options.state);
| + | |
− | }
| + | |
− | | + | |
− | // push the value to a callback if one is defined
| + | |
− | if(!config.callback) {
| + | |
− | return data;
| + | |
− | } else {
| + | |
− | config.callback('', data);
| + | |
− | }
| + | |
− | },
| + | |
− | | + | |
− | /**
| + | |
− | * $.csv.fromArrays(arrays)
| + | |
− | * Converts a javascript array to a CSV String.
| + | |
− | *
| + | |
− | * @param {Array} arrays An array containing an array of CSV entries.
| + | |
− | * @param {Object} [options] An object containing user-defined options.
| + | |
− | * @param {Character} [separator] An override for the separator character. Defaults to a comma(,).
| + | |
− | * @param {Character} [delimiter] An override for the delimiter character. Defaults to a double-quote(").
| + | |
− | *
| + | |
− | * This method generates a CSV file from an array of arrays (representing entries).
| + | |
− | */
| + | |
− | fromArrays: function(arrays, options, callback) {
| + | |
− | options = (options !== undefined ? options : {});
| + | |
− | var config = {};
| + | |
− | config.callback = ((callback !== undefined && typeof(callback) === 'function') ? callback : false);
| + | |
− | config.separator = 'separator' in options ? options.separator : $.csv.defaults.separator;
| + | |
− | config.delimiter = 'delimiter' in options ? options.delimiter : $.csv.defaults.delimiter;
| + | |
− | | + | |
− | var output = '',
| + | |
− | line,
| + | |
− | lineValues,
| + | |
− | i, j;
| + | |
− | | + | |
− | for (i = 0; i < arrays.length; i++) {
| + | |
− | line = arrays[i];
| + | |
− | lineValues = [];
| + | |
− | for (j = 0; j < line.length; j++) {
| + | |
− | var strValue = (line[j] === undefined || line[j] === null) ? '' : line[j].toString();
| + | |
− | if (strValue.indexOf(config.delimiter) > -1) {
| + | |
− | strValue = strValue.replace(new RegExp(config.delimiter, 'g'), config.delimiter + config.delimiter);
| + | |
− | }
| + | |
− | | + | |
− | var escMatcher = '\n|\r|S|D';
| + | |
− | escMatcher = escMatcher.replace('S', config.separator);
| + | |
− | escMatcher = escMatcher.replace('D', config.delimiter);
| + | |
− | | + | |
− | if (strValue.search(escMatcher) > -1) {
| + | |
− | strValue = config.delimiter + strValue + config.delimiter;
| + | |
− | }
| + | |
− | lineValues.push(strValue);
| + | |
− | }
| + | |
− | output += lineValues.join(config.separator) + '\r\n';
| + | |
− | }
| + | |
− | | + | |
− | // push the value to a callback if one is defined
| + | |
− | if(!config.callback) {
| + | |
− | return output;
| + | |
− | } else {
| + | |
− | config.callback('', output);
| + | |
− | }
| + | |
− | },
| + | |
− | | + | |
− | /**
| + | |
− | * $.csv.fromObjects(objects)
| + | |
− | * Converts a javascript dictionary to a CSV string.
| + | |
− | *
| + | |
− | * @param {Object} objects An array of objects containing the data.
| + | |
− | * @param {Object} [options] An object containing user-defined options.
| + | |
− | * @param {Character} [separator] An override for the separator character. Defaults to a comma(,).
| + | |
− | * @param {Character} [delimiter] An override for the delimiter character. Defaults to a double-quote(").
| + | |
− | * @param {Character} [sortOrder] Sort order of columns (named after
| + | |
− | * object properties). Use 'alpha' for alphabetic. Default is 'declare',
| + | |
− | * which means, that properties will _probably_ appear in order they were
| + | |
− | * declared for the object. But without any guarantee.
| + | |
− | * @param {Character or Array} [manualOrder] Manually order columns. May be
| + | |
− | * a strin in a same csv format as an output or an array of header names
| + | |
− | * (array items won't be parsed). All the properties, not present in
| + | |
− | * `manualOrder` will be appended to the end in accordance with `sortOrder`
| + | |
− | * option. So the `manualOrder` always takes preference, if present.
| + | |
− | *
| + | |
− | * This method generates a CSV file from an array of objects (name:value pairs).
| + | |
− | * It starts by detecting the headers and adding them as the first line of
| + | |
− | * the CSV file, followed by a structured dump of the data.
| + | |
− | */
| + | |
− | fromObjects: function(objects, options, callback) {
| + | |
− | options = (options !== undefined ? options : {});
| + | |
− | var config = {};
| + | |
− | config.callback = ((callback !== undefined && typeof(callback) === 'function') ? callback : false);
| + | |
− | config.separator = 'separator' in options ? options.separator : $.csv.defaults.separator;
| + | |
− | config.delimiter = 'delimiter' in options ? options.delimiter : $.csv.defaults.delimiter;
| + | |
− | config.headers = 'headers' in options ? options.headers : $.csv.defaults.headers;
| + | |
− | config.sortOrder = 'sortOrder' in options ? options.sortOrder : 'declare';
| + | |
− | config.manualOrder = 'manualOrder' in options ? options.manualOrder : [];
| + | |
− | config.transform = options.transform;
| + | |
− | | + | |
− | if (typeof config.manualOrder === 'string') {
| + | |
− | config.manualOrder = $.csv.toArray(config.manualOrder, config);
| + | |
− | }
| + | |
− | | + | |
− | if (config.transform !== undefined) {
| + | |
− | var origObjects = objects;
| + | |
− | objects = [];
| + | |
− | | + | |
− | var i;
| + | |
− | for (i = 0; i < origObjects.length; i++) {
| + | |
− | objects.push(config.transform.call(undefined, origObjects[i]));
| + | |
− | }
| + | |
− | }
| + | |
− | | + | |
− | var props = $.csv.helpers.collectPropertyNames(objects);
| + | |
− | | + | |
− | if (config.sortOrder === 'alpha') {
| + | |
− | props.sort();
| + | |
− | } // else {} - nothing to do for 'declare' order
| + | |
− | | + | |
− | if (config.manualOrder.length > 0) {
| + | |
− | | + | |
− | var propsManual = [].concat(config.manualOrder);
| + | |
− | var p;
| + | |
− | for (p = 0; p < props.length; p++) {
| + | |
− | if (propsManual.indexOf( props[p] ) < 0) {
| + | |
− | propsManual.push( props[p] );
| + | |
− | }
| + | |
− | }
| + | |
− | props = propsManual;
| + | |
− | }
| + | |
− | | + | |
− | var o, p, line, output = [], propName;
| + | |
− | if (config.headers) {
| + | |
− | output.push(props);
| + | |
− | }
| + | |
− | | + | |
− | for (o = 0; o < objects.length; o++) {
| + | |
− | line = [];
| + | |
− | for (p = 0; p < props.length; p++) {
| + | |
− | propName = props[p];
| + | |
− | if (propName in objects[o] && typeof objects[o][propName] !== 'function') {
| + | |
− | line.push(objects[o][propName]);
| + | |
− | } else {
| + | |
− | line.push('');
| + | |
− | }
| + | |
− | }
| + | |
− | output.push(line);
| + | |
− | }
| + | |
− | | + | |
− | // push the value to a callback if one is defined
| + | |
− | return $.csv.fromArrays(output, options, config.callback);
| + | |
− | }
| + | |
− | };
| + | |
− | | + | |
− | // Maintenance code to maintain backward-compatibility
| + | |
− | // Will be removed in release 1.0
| + | |
− | $.csvEntry2Array = $.csv.toArray;
| + | |
− | $.csv2Array = $.csv.toArrays;
| + | |
− | $.csv2Dictionary = $.csv.toObjects;
| + | |
− | | + | |
− | // CommonJS module is defined
| + | |
− | if (typeof module !== 'undefined' && module.exports) {
| + | |
− | module.exports = $.csv;
| + | |
− | }
| + | |
− | | + | |
− | }).call( this );
| + | |
− | </script> | + | |
− | <!--END JQUERY CSV-->
| + | |
| <script type='text/javascript'> | | <script type='text/javascript'> |
| function generateTable(data) { | | function generateTable(data) { |
Line 1,038: |
Line 61: |
| | | |
| $(document).ready(function() { | | $(document).ready(function() { |
− | console.log(Object.keys($)) | + | console.log() |
| | | |
| $.ajax({ | | $.ajax({ |