框架重构

清除多余的业务
This commit is contained in:
橙子
2022-04-03 23:21:53 +08:00
parent f5fb2ea17b
commit f0d32af3c3
936 changed files with 213647 additions and 86 deletions

View File

@@ -0,0 +1,110 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<title>jQuery editTable</title>
<meta name="description" content="jQuery editTable is a very small jQuery Plugin (~1Kb gzipped) that fill the gap left by the missing of a default input field for data tables.">
<link rel="stylesheet" href="main.css?v=0.2.0">
<script src="../jquery/dist/jquery.js"></script>
<script type="text/javascript" src="jquery.edittable.js?v=0.2.0"></script>
<script src="jquery-ui.js"></script>
<link rel="stylesheet" href="jquery.edittable.css?v=0.2.0">
<link href="jquery-ui.css" rel="stylesheet" />
<script>$(window).ready(function () {
// Example 4
// Custom fields & validation
var mynewtable = $('#examplex').editTable({
field_templates: {
'checkbox': {
html: '<input type="checkbox"/>',
getValue: function (input) {
return $(input).is(':checked');
},
setValue: function (input, value) {
if (value) {
return $(input).attr('checked', true);
}
return $(input).removeAttr('checked');
}
},
'textarea': {
html: '<textarea/>',
getValue: function (input) {
return $(input).val();
},
setValue: function (input, value) {
return $(input).text(value);
}
},
'select': {
html: '<select><option value="">None</option><option>All</option></select>',
getValue: function (input) {
return $(input).val();
},
setValue: function (input, value) {
var select = $(input);
select.find('option').filter(function () {
return $(this).val() == value;
}).attr('selected', true);
return select;
}
}
},
row_template: ['checkbox', 'text', 'text', 'textarea', 'select'],
headerCols: ['Yes/No', 'Date', 'Value', 'Description', 'Which?'],
first_row: false,
data: [
[false, "01/30/2013", "50,00 €", "Lorem ipsum...\n\nDonec in dui nisl. Nam ac libero eget magna iaculis faucibus eu non arcu. Proin sed diam ut nisl scelerisque fermentum."],
[true, "02/28/2013", "50,00 €", 'This is a <textarea>', 'All']
],
validate_field: function (col_id, value, col_type, $element) {
if (col_type === 'checkbox') {
$element.parent('td').animate({ 'background-color': '#fff' });
if (value === false) {
$element.parent('td').animate({ 'background-color': '#DB4A39' });
return false;
}
}
return true;
},
tableClass: 'inputtable custom'
});
$('#examplexconsole').click(function (e) {
console.log(mynewtable.getData());
if (!mynewtable.isValidated()) {
alert('Not validated');
}
e.preventDefault();
});
$('.showcode').click(function () {
$($(this).attr('href')).slideToggle(300);
return false;
});
});</script>
</head>
<body>
<div class="container">
<form method="post" action="#output">
<textarea id="examplex" style="display: none;" name="myField"></textarea>
</form>
</div>
</body>
</html>

View File

@@ -0,0 +1,503 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
<title>jQuery editTable</title>
<meta name="description" content="jQuery editTable is a very small jQuery Plugin (~1Kb gzipped) that fill the gap left by the missing of a default input field for data tables.">
<link rel="stylesheet" href="main.css?v=0.2.0">
<script src="https://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript" src="../jquery.edittable.js?v=0.2.0"></script>
<script src="https://code.jquery.com/ui/1.10.3/jquery-ui.js"></script>
<link rel="stylesheet" href="../jquery.edittable.css?v=0.2.0">
<link rel="stylesheet" href="https://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css">
<script>
$(window).ready(function () {
// Initialize table example 0
$('#source').editTable();
// Initialize table example 1
var eTable = $('#edittable').editTable({
data : [
["Click on the plus symbols on the top and right to add cols or rows"]
]
});
// Load json data trough an ajax call
$('.loadjson').click(function () {
var _this = $(this),text = $(this).text();
$(this).text('Loading...');
$.ajax({
url: 'data.json',
type: 'GET',
data: {
ajax: true
},
complete: function (result) {
_this.text(text);
eTable.loadJsonData(result.responseText);
}
});
return false;
});
// Reset table data
$('.reset').click(function () {
eTable.reset();
return false;
});
// Initialize table example 2
$("#edittable2").editTable({
data : [
["01/01/2013","01/30/2013","50,00 €"],
["02/01/2013","02/28/2013","50,00 €"]
],
headerCols: [
'From',
'To',
'Price'
],
first_row: false,
maxRows: 3
});
// Example of jQuery UI
$("#edittable2").on("focusin", "td:nth-child(1) input, td:nth-child(2) input", function(){
$(this).datepicker();
});
// Example 4
// Custom fields & validation
var mynewtable = $('#examplex').editTable({
field_templates: {
'checkbox' : {
html: '<input type="checkbox"/>',
getValue: function (input) {
return $(input).is(':checked');
},
setValue: function (input, value) {
if ( value ){
return $(input).attr('checked', true);
}
return $(input).removeAttr('checked');
}
},
'textarea' : {
html: '<textarea/>',
getValue: function (input) {
return $(input).val();
},
setValue: function (input, value) {
return $(input).text(value);
}
},
'select' : {
html: '<select><option value="">None</option><option>All</option></select>',
getValue: function (input) {
return $(input).val();
},
setValue: function (input, value) {
var select = $(input);
select.find('option').filter(function() {
return $(this).val() == value;
}).attr('selected', true);
return select;
}
}
},
row_template: ['checkbox', 'text', 'text', 'textarea', 'select'],
headerCols: ['Yes/No','Date','Value','Description', 'Which?'],
first_row: false,
data: [
[false,"01/30/2013","50,00 €","Lorem ipsum...\n\nDonec in dui nisl. Nam ac libero eget magna iaculis faucibus eu non arcu. Proin sed diam ut nisl scelerisque fermentum."],
[true,"02/28/2013","50,00 €",'This is a <textarea>','All']
],
validate_field: function (col_id, value, col_type, $element) {
if ( col_type === 'checkbox' ) {
$element.parent('td').animate({'background-color':'#fff'});
if ( value === false ){
$element.parent('td').animate({'background-color':'#DB4A39'});
return false;
}
}
return true;
},
tableClass: 'inputtable custom'
});
$('#examplexconsole').click(function(e) {
console.log(mynewtable.getData());
if ( !mynewtable.isValidated() ){
alert('Not validated');
}
e.preventDefault();
});
$('.showcode').click(function () {
$($(this).attr('href')).slideToggle(300);
return false;
});
});
</script>
</head>
<body>
<div class="container">
<h1>jQuery editTable <span>v0.2.0</span></h1>
<a href="https://twitter.com/micc1983" class="twitter-follow-button" data-show-count="true" data-lang="en">Follow @micc1983</a>
<a href="https://twitter.com/share" class="twitter-share-button" data-via="Micc1983">Tweet</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
<p>jQuery editTable is a very small jQuery Plugin (~1Kb gzipped) that fill the gap left by the missing of a default <strong>input field for data tables</strong>. jQuery editTable can be used both in ajax and/or HTTP POST contest and let you preset the title and number of columns or just let complete freedom to the user. You can even append custom behaviors to single column cells (ex. <strong>jQuery UI Datepicker</strong>). The only limit is your imagination! :)</p>
<a href="https://github.com/micc83/editTable" class="download_button">Download it on GitHub</a>
<p>To use it you just have to include jQuery and a copy of the plugin in your head or footer:</p>
<pre>
&#x3C;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#x20;&#x74;&#x79;&#x70;&#x65;&#x3D;&#x22;&#x74;&#x65;&#x78;&#x74;&#x2F;&#x6A;&#x61;&#x76;&#x61;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#x22;&#x20;&#x73;&#x72;&#x63;&#x3D;&#x22;&#x68;&#x74;&#x74;&#x70;&#x3A;&#x2F;&#x2F;&#x63;&#x6F;&#x64;&#x65;&#x2E;&#x6A;&#x71;&#x75;&#x65;&#x72;&#x79;&#x2E;&#x63;&#x6F;&#x6D;&#x2F;&#x6A;&#x71;&#x75;&#x65;&#x72;&#x79;&#x2D;&#x6C;&#x61;&#x74;&#x65;&#x73;&#x74;&#x2E;&#x6A;&#x73;&#x22;&#x3E;&#x3C;&#x2F;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#x3E;
&#x3C;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#x20;&#x74;&#x79;&#x70;&#x65;&#x3D;&#x22;&#x74;&#x65;&#x78;&#x74;&#x2F;&#x6A;&#x61;&#x76;&#x61;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#x22;&#x20;&#x73;&#x72;&#x63;&#x3D;&#x22;&#x6A;&#x71;&#x75;&#x65;&#x72;&#x79;&#x2E;&#x65;&#x64;&#x69;&#x74;&#x74;&#x61;&#x62;&#x6C;&#x65;&#x2E;&#x6D;&#x69;&#x6E;&#x2E;&#x6A;&#x73;&#x22;&#x3E;&#x3C;&#x2F;&#x73;&#x63;&#x72;&#x69;&#x70;&#x74;&#x3E;
&#x3C;&#x6C;&#x69;&#x6E;&#x6B;&#x20;&#x72;&#x65;&#x6C;&#x3D;&#x22;&#x73;&#x74;&#x79;&#x6C;&#x65;&#x73;&#x68;&#x65;&#x65;&#x74;&#x22;&#x20;&#x68;&#x72;&#x65;&#x66;&#x3D;&#x22;&#x6A;&#x71;&#x75;&#x65;&#x72;&#x79;&#x2E;&#x65;&#x64;&#x69;&#x74;&#x74;&#x61;&#x62;&#x6C;&#x65;&#x2E;&#x6D;&#x69;&#x6E;&#x2E;&#x63;&#x73;&#x73;&#x22;&#x3E;
</pre>
<p>Now you can trigger editTable on any textarea or block element (ex. div, article, section ...). In case you trigger it on a textarea, its content will be used as JSON source for the table. If the textarea is inside a form, on submit, its content will be updated with the new JSON data. Otherwise, if you trigger it on a block element the table will be appended to the element itself (ajax).</p>
<pre>
var mytable = $('#edittable').editTable({
data: [['']], // Fill the table with a js array (this is overridden by the textarea content if not empty)
tableClass: 'inputtable', // Table class, for styling
jsonData: false, // Fill the table with json data (this will override data property)
headerCols: false, // Fix columns number and names (array of column names)
maxRows: 999, // Max number of rows which can be added
first_row: true, // First row should be highlighted?
row_template: false, // An array of column types set in field_templates
field_templates: false, // An array of custom field type objects
// Validate fields
validate_field: function (col_id, value, col_type, $element) {
return true;
}
});
</pre>
<p>There are of course many methods which can be used on the created table. Let's see...</p>
<pre>
mytable.loadData(dataArray); // Fill the table with js data
mytable.loadJsonData(jsonData); // Fill the table with JSON data
mytable.getData(); // Get a js array of the table data
mytable.getJsonData(); // Get JSON from the table data
mytable.reset(); // Reset the table to the initial set of data
mytable.isValidated() // Check if the table pass validation set with validate_field
</pre>
<p>To define a <strong>custom field type</strong> object (<a href="#e4">click here for a full example</a>):</p>
<pre>
[
'checkbox' : {
html: '&lt;input type="checkbox"/&gt;', // Input type html
// How to get the value from the custom input
getValue: function (input) {
return $(input).is(':checked');
},
// How to set the value of the custom input
setValue: function (input, value) {
if ( value ){
return $(input).attr('checked', true);
}
return $(input).removeAttr('checked');
}
}
]
</pre>
<p>That's it, now give a look to the following examples to understand how it works.</p>
<hr>
<h3>Example 1 - Basics</h3>
<p>In the first example we'll implement the simplest HTML POST use of editTable. If you are looking to use editTable on ajax contest instead just give a look to the next example.</p>
<form method="post" action="#output">
<textarea id="source" style="display: none;" name="myField">[
["Carbon","Hydrogen","Nitrogen","Oxygen"],
[10,15,1,0],
[8,11,1,2],
[10,15,1,1],
[12,17,1,1],
[14,19,1,2]
]</textarea>
<button type="submit">Post data (and check your network tab)</button>
<a href="#example0code" class="showcode button">Show Code</a>
</form>
<div id="example0code" style="display: none;" class="examplecode">
<span class="title">INDEX.PHP</span>
<pre>
&lt;form method=&quot;post&quot; action=&quot;output.php&quot;&gt;
&lt;textarea id=&quot;source&quot; style="display:none" name="myField" &gt;&lt;?php
echo json_encode(array(
array('Period','Full Board', 'Half Board', 'Bed &amp; Breakfast'),
array('01/01 - 30/01','50.00 €', '40.00 €', '30.00 €'),
array('01/02 - 28/02','55.00 €', '45.00 €', '35.00 €'),
array('01/03 - 31/03','60.00 €', '50.00 €', '40.00 €'),
array('01/04 - 30/04','55.00 €', '45.00 €', '35.00 €'),
array('01/05 - 31/05','50.00 €', '40.00 €', '30.00 €')
));
?&gt;&lt;/textarea&gt;
&lt;button type=&quot;submit&quot;&gt;Send data&lt;/button&gt;
&lt;/form&gt;
</pre>
<span class="title">SCRIPT.JS</span>
<pre>
$(window).ready(function () {
$('#source').editTable();
});
</pre>
<span class="title">OUTPUT.PHP</span>
<pre>
&#x3C;&#x3F;&#x70;&#x68;&#x70; var_dump( json_decode( stripslashes( $_POST['myField'] ) ) ); &#x3F;&#x3E;
</pre>
</div>
<hr>
<h3>Example 2 - AJAX with editable columns:</h3>
<div id="edittable"></div>
<a href="#" class="loadjson button">Ajax load JSON</a>
<a href="#" class="reset button">Reset Table</a>
<a href="#example1code" class="showcode button">Show Code</a>
<div id="example1code" style="display: none;" class="examplecode">
<span class="title">index.htm</span>
<pre>
&lt;div id=&quot;edittable&quot;&gt;&lt;/div&gt;
&lt;a href=&quot;#&quot; class=&quot;sendjson button&quot;&gt;Send JSON (check your console)&lt;/a&gt;
&lt;a href=&quot;#&quot; class=&quot;loadjson button&quot;&gt;Load JSON from textarea&lt;/a&gt;
&lt;a href=&quot;#&quot; class=&quot;reset button&quot;&gt;Reset Table&lt;/a&gt;
</pre>
<span class="title">script.js</span>
<pre>
// Initialize table example 1
var eTable = $('#edittable').editTable({
data: [
["Click on the plus symbols on the top and right to add cols or rows"]
]
});
// Load json data trough an ajax call
$('.loadjson').click(function () {
var _this = $(this),text = $(this).text();
$(this).text('Loading...');
$.ajax({
url: 'output.php',
type: 'POST',
data: {
ajax: true
},
complete: function (result) {
_this.text(text);
eTable.loadJsonData(result.responseText);
}
});
return false;
});
// Reset table data
$('.reset').click(function () {
eTable.reset();
return false;
});
// Send JSON data trough an ajax call
$('.sendjson').click(function () {
$.ajax({
url: 'output.php',
type: 'POST',
data: {
ajax: true,
data: eTable.getJsonData()
},
complete: function (result) {
console.log(JSON.parse(result.responseText));
}
});
return false;
});
</pre>
<span class="title">output.php</span>
<pre>
&lt;?php
if ( isset( $_POST['ajax'] ) ){
header( 'Content-Type: application/json' );
if ( isset( $_REQUEST['data'] ) ){
$data = json_decode( stripslashes( $_REQUEST['data'] ) );
} else {
$data = array(
array('Carbon','Hydrogen','Nitrogen','Oxygen'),
array(10,15,1,0),
array(8,11,1,2),
array(10,15,1,1),
array(12,17,1,1),
array(14,19,1,2)
);
}
echo json_encode( $data );
die();
}
</pre>
</div>
<hr>
<h3>Example 3 - Fixed columns, Datepicker, Rows limit:</h3>
<div id="edittable2"></div>
<a href="#example2code" class="showcode button">Show Code</a>
<div id="example2code" style="display: none;" class="examplecode">
<span class="title">index.htm</span>
<pre>&lt;div id=&quot;edittable2&quot;&gt;&lt;/div&gt;</pre>
<span class="title">script.js</span>
<pre>
// Initialize table example 3
$("#edittable2").editTable({
data: [
["01/01/2013","01/30/2013","50,00 €"],
["02/01/2013","02/28/2013","50,00 €"]
],
headerCols: [
'From',
'To',
'Price'
],
maxRows: 3
});
// Example of jQuery UI datePicker
$("#edittable2").on("focusin", "td:nth-child(1) input, td:nth-child(2) input", function(){
$(this).datepicker();
});</pre>
</div>
<hr>
<h3 id="e4">Example 4 - Custom field types &amp; validation</h3>
<form method="post" action="#output">
<textarea id="examplex" style="display: none;" name="myField"></textarea>
<a href="#examplexcode" class="showcode button">Show Code</a>
<a href="#" id="examplexconsole" class="button">Validate table</a>
</form>
<div id="examplexcode" style="display: none;" class="examplecode">
<span class="title">script.js</span>
<pre>
/**
* Example 4 - Custom field types & validation
*/
var mynewtable = $('#examplex').editTable({
field_templates: {
'checkbox' : {
html: '&lt;input type="checkbox"/&gt;',
getValue: function (input) {
return $(input).is(':checked');
},
setValue: function (input, value) {
if ( value ){
return $(input).attr('checked', true);
}
return $(input).removeAttr('checked');
}
},
'textarea' : {
html: '&lt;textarea/&gt;',
getValue: function (input) {
return $(input).val();
},
setValue: function (input, value) {
return $(input).text(value);
}
},
'select' : {
html: '&lt;select&gt;&lt;option value=""&gt;None&lt;/option&gt;&lt;option&gt;All&lt;/option&gt;&lt;/select&gt;',
getValue: function (input) {
return $(input).val();
},
setValue: function (input, value) {
var select = $(input);
select.find('option').filter(function() {
return $(this).val() == value;
}).attr('selected', true);
return select;
}
}
},
row_template: ['checkbox', 'text', 'text', 'textarea', 'select'],
headerCols: ['Yes/No','Date','Value','Description', 'Which?'],
first_row: false,
data: [
[false,"01/30/2013","50,00 €","Lorem ipsum...\n\nDonec in dui nisl. Nam ac libero eget magna iaculis faucibus eu non arcu. Proin sed diam ut nisl scelerisque fermentum."],
[true,"02/28/2013","50,00 €",'This is a &lt;textarea&gt;','All']
],
// Checkbox validation
validate_field: function (col_id, value, col_type, $element) {
if ( col_type === 'checkbox' ) {
$element.parent('td').animate({'background-color':'#fff'});
if ( value === false ){
$element.parent('td').animate({'background-color':'#DB4A39'});
return false;
}
}
return true;
},
tableClass: 'inputtable custom'
});
// Trigger event
$('#examplexconsole').click(function(e) {
// Get data
console.log(mynewtable.getData());
// Check if data are valid
if ( !mynewtable.isValidated() ){
alert('Not validated');
}
e.preventDefault();
});
</pre>
</div>
<hr>
<h2>Credits and contacts</h2>
<p><strong>editTable</strong> has been made by <a href="https://github.com/micc83" target="_blank">me</a>. You can contact me at <a href="mailto:micc83@gmail.com">micc83@gmail.com</a> or <a href="https://twitter.com/Micc1983" target="_blank">twitter</a> for any issue or feauture request.</p>
</div>
</body>
</html>

View File

@@ -0,0 +1,51 @@
body { font-family: "Helvetica Neue"; }
.container {margin: 0 auto;width: 90%;padding: 0 5% 20px 5%;max-width: 960px;}
a { text-decoration: none;color: #4988C6; }
p {color: #444;}
h1 span {color: #ddd;font-size: 26px;}
.title {font-weight: 800;font-size: 12px;text-transform: uppercase;padding: 15px 0 0 0;display: block;}
pre {background-color: #fafafa;padding: 20px;overflow: auto;border: 1px solid #f1f1f1;color: #000;}
.note {color: #999;font-size: 14px;}
.download_button {padding: 15px 0;background: #F2F2F2;display: block;margin: 30px auto;width: 100%;max-width: 200px;text-align: center;color: #4988C6;text-decoration: none;font-weight: 800;font-size: 12px;border-bottom: 3px solid #ddd;}
.download_button:active {position: relative;top: 3px;border-bottom: 0;}
.download_button:hover {background-color: #eaeaea;}
button, a.button {
border: none;padding: 0 20px;height: 40px;background-color: #eee;color: #333;text-decoration: none;display: inline-block;line-height: 40px;
margin: 0;vertical-align: top;font-weight: 200;border-bottom: 1px solid #ddd;font-family: "Helvetica Neue";
-moz-box-sizing: content-box;-webkit-box-sizing: content-box;box-sizing: content-box;font-size: 14px;cursor: pointer;margin: 5px 0;
}
button::-moz-focus-inner { border: 0px; }
button:hover, a.button:hover {
background-color: #f1f1f1;
}
button:active, a.button:active{
background-color: #e9e9e9;
}
textarea {
width: 98%;height: 100px;padding: 1%;border: 1px solid #eee;
}
#ui-datepicker-div {
font-size: 12px;
}
.examplecode {
padding: 15px 2%;background-color: #fffef1;border-top: 2px dotted #eee;border-bottom: 2px dotted #eee;margin-top: 10px;
}
.examplecode pre {
background-color: #ffffff;
}
hr {
border: 0;margin-top: 20px;
color: #eee;background-color: #eee;height: 3px;
}
.inputtable.custom textarea {
width: 96%;margin:0;padding:5px 2%;border: 0;resize: none;height: 100px;
}
.inputtable.custom textarea:focus {
background-color: #fafafa;
}
.inputtable.custom input[type=text]{
height: 110px;
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,79 @@
/* Table */
table.inputtable {
width: 100%;margin: 15px 0;border: 1px solid #ddd;border-collapse: collapse;border-spacing: 0;
-moz-box-shadow:0 1px 3px rgba(0,0,0,.075);
-webkit-box-shadow:0 1px 3px rgba(0,0,0,.075);
box-shadow:0 1px 3px rgba(0,0,0,.075)
}
/* Buttons */
table.inputtable a.icon-button {
background-color: #ccc;display: inline-block;width: 18px;height: 18px;text-decoration: none;color: #fff;font-weight: 800;line-height: 16px;text-align: center;font-size: 14px;
-moz-border-radius: 1px;
-webkit-border-radius: 1px;
border-radius: 1px;
-moz-box-shadow: 0 0 1px rgba(0,0,0,0.2);
-webkit-box-shadow: 0 0 1px rgba(0,0,0,0.2);
box-shadow: 0 0 1px rgba(0,0,0,0.2);
}
/* Add Buttons */
table.inputtable a.icon-button.addcol, table.inputtable a.icon-button.addrow {
background-color: #81b71a;
}
/* Remove Buttons */
table.inputtable a.icon-button.delcol, table.inputtable a.icon-button.delrow {
background-color: #db4a39;
}
/* Disabled Buttons */
table.inputtable a.icon-button.disabled {
background-color: #eee;
}
/* Row last cel */
table.inputtable td:last-child, table.inputtable th:last-child{
background-color: #f8f8f8;width: 54px;border: none;
}
/* Table single cells */
table.inputtable td, table.inputtable th {
border: 1px solid #eee;text-align: center;height: 40px;vertical-align: middle;font-size: 14px;
}
/* Table headers single cells */
table.inputtable th {
background-color: #f1f1f1;
border-color: #ddd;
border-top:none;
border-bottom: 2px solid #ddd;
}
/* Table body inputs */
table.inputtable td input[type=text] {
border: 0;width: 90%;height: 100%;padding: 0 5%;text-align: center;
}
/* Table body inputs on focus */
table.inputtable tr td input:focus {
background-color: #fafafa;
}
/* First body row cells & input on table without columns header */
table.inputtable.wh tbody tr:nth-child(1), table.inputtable.wh tbody tr:nth-child(1) input {
background-color: #fdfdfd;font-weight: 800;
}
/* Hide borders when not needed hack */
table.inputtable th:first-child, table.inputtable td:first-child {
border-left:none;
}
table.inputtable tr:last-child td {
border-bottom:none;
}
/* Mobile Landscape */
@media only screen and (max-width : 480px) {
/* Table single cells */
table.inputtable td, table.inputtable th {
min-width: 40px;height: 80px;
}
/* Buttons */
table.inputtable a.icon-button {
width: 40px;height: 40px;font-size: 18px;min-width: 40px;line-height: 40px;
margin: 3px 0;
}
/* Table body inputs */
table.inputtable td input {
height: 80px;
}
}

View File

@@ -0,0 +1,309 @@
/*! editTable v0.2.0 by Alessandro Benoit */
(function ($, window, i) {
'use strict';
$.fn.editTable = function (options) {
// Settings
var s = $.extend({
data: [['']],
tableClass: 'inputtable',
jsonData: false,
headerCols: false,
maxRows: 999,
first_row: true,
row_template: false,
field_templates: false,
validate_field: function (col_id, value, col_type, $element) {
return true;
}
}, options),
$el = $(this),
defaultTableContent = '<thead><tr></tr></thead><tbody></tbody>',
$table = $('<table/>', {
class: s.tableClass + ((s.first_row) ? ' wh' : ''),
html: defaultTableContent
}),
defaultth = '<th><a class="addcol icon-button" href="#">+</a> <a class="delcol icon-button" href="#">-</a></th>',
colnumber,
rownumber,
reset,
is_validated = true;
// Increment for IDs
i = i + 1;
// Build cell
function buildCell(content, type) {
content = (content === 0) ? "0" : (content || '');
// Custom type
if (type && 'text' !== type){
var field = s.field_templates[type];
return '<td>' + field.setValue(field.html, content)[0].outerHTML + '</td>';
}
// Default
return '<td><input type="text" value="' + content.toString().replace(/"/g, "&quot;") + '" /></td>';
}
// Build row
function buildRow(data, len) {
var rowcontent = '', b;
data = data || '';
if (!s.row_template) {
// Without row template
for (b = 0; b < (len || data.length); b += 1) {
rowcontent += buildCell(data[b]);
}
} else {
// With row template
for (b = 0; b < s.row_template.length; b += 1) {
// For each field in the row
rowcontent += buildCell(data[b], s.row_template[b]);
}
}
return $('<tr/>', {
html: rowcontent + '<td><a class="addrow icon-button" href="#">+</a> <a class="delrow icon-button" href="#">-</a></td>'
});
}
// Check button status (enable/disabled)
function checkButtons() {
if (colnumber < 2) {
$table.find('.delcol').addClass('disabled');
}
if (rownumber < 2) {
$table.find('.delrow').addClass('disabled');
}
if (s.maxRows && rownumber === s.maxRows) {
$table.find('.addrow').addClass('disabled');
}
}
// Fill table with data
function fillTableData(data) {
var a, crow = Math.min(s.maxRows, data.length);
// Clear table
$table.html(defaultTableContent);
// If headers or row_template are set
if (s.headerCols || s.row_template) {
// Fixed columns
var col = s.headerCols || s.row_template;
// Table headers
for (a = 0; a < col.length; a += 1) {
var col_title = s.headerCols[a] || '';
$table.find('thead tr').append('<th>' + col_title + '</th>');
}
// Table content
for (a = 0; a < crow; a += 1) {
// For each row in data
buildRow(data[a], col.length).appendTo($table.find('tbody'));
}
} else if ( data[0] ) {
// Variable columns
for (a = 0; a < data[0].length; a += 1) {
$table.find('thead tr').append(defaultth);
}
for (a = 0; a < crow; a += 1) {
buildRow(data[a]).appendTo($table.find('tbody'));
}
}
// Append missing th
$table.find('thead tr').append('<th></th>');
// Count rows and columns
colnumber = $table.find('thead th').length - 1;
rownumber = $table.find('tbody tr').length;
checkButtons();
}
// Export data
function exportData() {
var row = 0, data = [], value;
is_validated = true;
$table.find('tbody tr').each(function () {
row += 1;
data[row] = [];
$(this).find('td:not(:last-child)').each(function (i, v) {
if ( s.row_template && 'text' !== s.row_template[i] ){
var field = s.field_templates[s.row_template[i]],
el = $(this).find($(field.html).prop('tagName'));
value = field.getValue(el);
if ( !s.validate_field(i, value, s.row_template[i], el) ){
is_validated = false;
}
data[row].push(value);
} else {
value = $(this).find('input[type="text"]').val();
if ( !s.validate_field(i, value, 'text', v) ){
is_validated = false;
}
data[row].push(value);
}
});
});
// Remove undefined
data.splice(0, 1);
return data;
}
// Fill the table with data from textarea or given properties
if ($el.is('textarea')) {
try {
reset = JSON.parse($el.val());
} catch (e) {
reset = s.data;
}
$el.after($table);
// If inside a form set the textarea content on submit
if ($table.parents('form').length > 0) {
$table.parents('form').submit(function () {
$el.val(JSON.stringify(exportData()));
});
}
} else {
reset = (JSON.parse(s.jsonData) || s.data);
$el.append($table);
}
fillTableData(reset);
// Add column
$table.on('click', '.addcol', function () {
var colid = parseInt($(this).closest('tr').children().index($(this).parent('th')), 10);
colnumber += 1;
$table.find('thead tr').find('th:eq(' + colid + ')').after(defaultth);
$table.find('tbody tr').each(function () {
$(this).find('td:eq(' + colid + ')').after(buildCell());
});
$table.find('.delcol').removeClass('disabled');
return false;
});
// Remove column
$table.on('click', '.delcol', function () {
if ($(this).hasClass('disabled')) {
return false;
}
var colid = parseInt($(this).closest('tr').children().index($(this).parent('th')), 10);
colnumber -= 1;
checkButtons();
$(this).parent('th').remove();
$table.find('tbody tr').each(function () {
$(this).find('td:eq(' + colid + ')').remove();
});
return false;
});
// Add row
$table.on('click', '.addrow', function () {
if ($(this).hasClass('disabled')) {
return false;
}
rownumber += 1;
$(this).closest('tr').after(buildRow(0, colnumber));
$table.find('.delrow').removeClass('disabled');
checkButtons();
return false;
});
// Delete row
$table.on('click', '.delrow', function () {
if ($(this).hasClass('disabled')) {
return false;
}
rownumber -= 1;
checkButtons();
$(this).closest('tr').remove();
$table.find('.addrow').removeClass('disabled');
return false;
});
// Select all content on click
$table.on('click', 'input', function () {
$(this).select();
});
// Return functions
return {
// Get an array of data
getData: function () {
return exportData();
},
// Get the JSON rappresentation of data
getJsonData: function () {
return JSON.stringify(exportData());
},
// Load an array of data
loadData: function (data) {
fillTableData(data);
},
// Load a JSON rappresentation of data
loadJsonData: function (data) {
fillTableData(JSON.parse(data));
},
// Reset data to the first instance
reset: function () {
fillTableData(reset);
},
isValidated: function () {
return is_validated;
}
};
};
})(jQuery, this, 0);

View File

@@ -0,0 +1,18 @@
table.inputtable{width:100%;border:1px solid #ddd;border-collapse:collapse;border-spacing:0;-moz-box-shadow:0 1px 3px rgba(0,0,0,.075);-webkit-box-shadow:0 1px 3px rgba(0,0,0,.075);box-shadow:0 1px 3px rgba(0,0,0,.075);margin:15px 0}
table.inputtable a.icon-button{background-color:#ccc;display:inline-block;width:18px;height:18px;text-decoration:none;color:#fff;font-weight:800;line-height:16px;text-align:center;font-size:14px;-moz-border-radius:1px;-webkit-border-radius:1px;border-radius:1px;-moz-box-shadow:0 0 1px rgba(0,0,0,0.2);-webkit-box-shadow:0 0 1px rgba(0,0,0,0.2);box-shadow:0 0 1px rgba(0,0,0,0.2)}
table.inputtable a.icon-button.addcol,table.inputtable a.icon-button.addrow{background-color:#81b71a}
table.inputtable a.icon-button.delcol,table.inputtable a.icon-button.delrow{background-color:#db4a39}
table.inputtable a.icon-button.disabled{background-color:#eee}
table.inputtable td:last-child,table.inputtable th:last-child{background-color:#f8f8f8;width:54px;border:none}
table.inputtable td,table.inputtable th{border:1px solid #eee;text-align:center;height:40px;vertical-align:middle;font-size:14px}
table.inputtable th{background-color:#f1f1f1;border-top:none;border-bottom:2px solid #ddd;border-color:#ddd}
table.inputtable td input[type=text]{border:0;width:90%;height:100%;text-align:center;padding:0 5%}
table.inputtable tr td input:focus{background-color:#fafafa}
table.inputtable.wh tbody tr:nth-child(1),table.inputtable.wh tbody tr:nth-child(1) input{background-color:#fdfdfd;font-weight:800}
table.inputtable th:first-child,table.inputtable td:first-child{border-left:none}
table.inputtable tr:last-child td{border-bottom:none}
@media only screen and max-width 480px {
table.inputtable td,table.inputtable th{min-width:40px;height:80px}
table.inputtable a.icon-button{width:40px;height:40px;font-size:18px;min-width:40px;line-height:40px;margin:3px 0}
table.inputtable td input{height:80px}
}

View File

@@ -0,0 +1,2 @@
/*! editTable v0.2.0 by Alessandro Benoit */
(function(e,t,n){"use strict";e.fn.editTable=function(t){function p(e,t){e=e===0?"0":e||"";if(t&&"text"!==t){var n=r.field_templates[t];return"<td>"+n.setValue(n.html,e)[0].outerHTML+"</td>"}return'<td><input type="text" value="'+e.toString().replace(/"/g,"&quot;")+'" /></td>'}function d(t,n){var i="",s;t=t||"";if(!r.row_template){for(s=0;s<(n||t.length);s+=1){i+=p(t[s])}}else{for(s=0;s<r.row_template.length;s+=1){i+=p(t[s],r.row_template[s])}}return e("<tr/>",{html:i+'<td><a class="addrow icon-button" href="#">+</a> <a class="delrow icon-button" href="#">-</a></td>'})}function v(){if(f<2){u.find(".delcol").addClass("disabled")}if(l<2){u.find(".delrow").addClass("disabled")}if(r.maxRows&&l===r.maxRows){u.find(".addrow").addClass("disabled")}}function m(e){var t,n=Math.min(r.maxRows,e.length);u.html(o);if(r.headerCols||r.row_template){var i=r.headerCols||r.row_template;for(t=0;t<i.length;t+=1){var s=r.headerCols[t]||"";u.find("thead tr").append("<th>"+s+"</th>")}for(t=0;t<n;t+=1){d(e[t],i.length).appendTo(u.find("tbody"))}}else if(e[0]){for(t=0;t<e[0].length;t+=1){u.find("thead tr").append(a)}for(t=0;t<n;t+=1){d(e[t]).appendTo(u.find("tbody"))}}u.find("thead tr").append("<th></th>");f=u.find("thead th").length-1;l=u.find("tbody tr").length;v()}function g(){var t=0,n=[],i;h=true;u.find("tbody tr").each(function(){t+=1;n[t]=[];e(this).find("td:not(:last-child)").each(function(s,o){if(r.row_template&&"text"!==r.row_template[s]){var u=r.field_templates[r.row_template[s]],a=e(this).find(e(u.html).prop("tagName"));i=u.getValue(a);if(!r.validate_field(s,i,r.row_template[s],a)){h=false}n[t].push(i)}else{i=e(this).find('input[type="text"]').val();if(!r.validate_field(s,i,"text",o)){h=false}n[t].push(i)}})});n.splice(0,1);return n}var r=e.extend({data:[[""]],tableClass:"inputtable",jsonData:false,headerCols:false,maxRows:999,first_row:true,row_template:false,field_templates:false,validate_field:function(e,t,n,r){return true}},t),s=e(this),o="<thead><tr></tr></thead><tbody></tbody>",u=e("<table/>",{"class":r.tableClass+(r.first_row?" wh":""),html:o}),a='<th><a class="addcol icon-button" href="#">+</a> <a class="delcol icon-button" href="#">-</a></th>',f,l,c,h=true;n=n+1;if(s.is("textarea")){try{c=JSON.parse(s.val())}catch(y){c=r.data}s.after(u);if(u.parents("form").length>0){u.parents("form").submit(function(){s.val(JSON.stringify(g()))})}}else{c=JSON.parse(r.jsonData)||r.data;s.append(u)}m(c);u.on("click",".addcol",function(){var t=parseInt(e(this).closest("tr").children().index(e(this).parent("th")),10);f+=1;u.find("thead tr").find("th:eq("+t+")").after(a);u.find("tbody tr").each(function(){e(this).find("td:eq("+t+")").after(p())});u.find(".delcol").removeClass("disabled");return false});u.on("click",".delcol",function(){if(e(this).hasClass("disabled")){return false}var t=parseInt(e(this).closest("tr").children().index(e(this).parent("th")),10);f-=1;v();e(this).parent("th").remove();u.find("tbody tr").each(function(){e(this).find("td:eq("+t+")").remove()});return false});u.on("click",".addrow",function(){if(e(this).hasClass("disabled")){return false}l+=1;e(this).closest("tr").after(d(0,f));u.find(".delrow").removeClass("disabled");v();return false});u.on("click",".delrow",function(){if(e(this).hasClass("disabled")){return false}l-=1;v();e(this).closest("tr").remove();u.find(".addrow").removeClass("disabled");return false});u.on("click","input",function(){e(this).select()});return{getData:function(){return g()},getJsonData:function(){return JSON.stringify(g())},loadData:function(e){m(e)},loadJsonData:function(e){m(JSON.parse(e))},reset:function(){m(c)},isValidated:function(){return h}}}})(jQuery,this,0)