Skip to content

Commit

Permalink
Editable table with the use of editable-table. Patched so we can choo…
Browse files Browse the repository at this point in the history
…se an editable column instead of whole table
  • Loading branch information
dovadi committed May 30, 2014
1 parent e60c0a0 commit a74b009
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 3 deletions.
8 changes: 8 additions & 0 deletions app/assets/javascripts/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,12 @@ $(function(){
});
});

$('table.participants').editableTableWidget({column: 'td.editable'});

$('table.participants').on('change', function(evt, newValue) {
// do something with the new cell value
console.log($(evt.target).parent());
console.log(newValue)
});

});
139 changes: 139 additions & 0 deletions app/assets/javascripts/mindmup-editabletable.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
// A tiny jQuery/Bootstrap widget that makes a HTML table editable
// See https://github.com/mindmup/editable-table
// Patched by FO: added a editable column option

/*global $, window*/
$.fn.editableTableWidget = function (options) {
'use strict';
return $(this).each(function () {
var buildDefaultOptions = function () {
var opts = $.extend({}, $.fn.editableTableWidget.defaultOptions);
opts.editor = opts.editor.clone();
return opts;
},
activeOptions = $.extend(buildDefaultOptions(), options),
ARROW_LEFT = 37, ARROW_UP = 38, ARROW_RIGHT = 39, ARROW_DOWN = 40, ENTER = 13, ESC = 27, TAB = 9,
element = $(this),
editor = activeOptions.editor.css('position', 'absolute').hide().appendTo(element.parent()),
column = activeOptions.column,
active,
showEditor = function (select) {
active = element.find(':focus');
if (active.length) {
editor.val(active.text())
.removeClass('error')
.show()
.offset(active.offset())
.css(active.css(activeOptions.cloneProperties))
.width(active.width())
.height(active.height())
.focus();
if (select) {
editor.select();
}
}
},
setActiveText = function () {
var text = editor.val(),
evt = $.Event('change'),
originalContent;
if (active.text() === text || editor.hasClass('error')) {
return true;
}
originalContent = active.html();
active.text(text).trigger(evt, text);
if (evt.result === false) {
active.html(originalContent);
}
},
movement = function (element, keycode) {
if (keycode === ARROW_RIGHT) {
return element.next('td');
} else if (keycode === ARROW_LEFT) {
return element.prev('td');
} else if (keycode === ARROW_UP) {
return element.parent().prev().children().eq(element.index());
} else if (keycode === ARROW_DOWN) {
return element.parent().next().children().eq(element.index());
}
return [];
};
editor.blur(function () {
setActiveText();
editor.hide();
}).keydown(function (e) {
if (e.which === ENTER) {
setActiveText();
editor.hide();
active.focus();
e.preventDefault();
e.stopPropagation();
} else if (e.which === ESC) {
editor.val(active.text());
e.preventDefault();
e.stopPropagation();
editor.hide();
active.focus();
} else if (e.which === TAB) {
active.focus();
} else if (this.selectionEnd - this.selectionStart === this.value.length) {
var possibleMove = movement(active, e.which);
if (possibleMove.length > 0) {
possibleMove.focus();
e.preventDefault();
e.stopPropagation();
}
}
})
.on('input paste', function () {
var evt = $.Event('validate');
active.trigger(evt, editor.val());
if (evt.result === false) {
editor.addClass('error');
} else {
editor.removeClass('error');
}
});
element.find(column).on('click keypress dblclick', showEditor)
.css('cursor', 'pointer')
.keydown(function (e) {
var prevent = true,
possibleMove = movement($(e.target), e.which);
if (possibleMove.length > 0) {
possibleMove.focus();
} else if (e.which === ENTER) {
showEditor(false);
} else if (e.which === 17 || e.which === 91 || e.which === 93) {
showEditor(true);
prevent = false;
} else {
prevent = false;
}
if (prevent) {
e.stopPropagation();
e.preventDefault();
}
});

element.find(column).prop('tabindex', 1);

$(window).on('resize', function () {
if (editor.is(':visible')) {
editor.offset(active.offset())
.width(active.width())
.height(active.height());
}
});
});

};
$.fn.editableTableWidget.defaultOptions = {
cloneProperties: ['padding', 'padding-top', 'padding-bottom', 'padding-left', 'padding-right',
'text-align', 'font', 'font-size', 'font-family', 'font-weight',
'border', 'border-top', 'border-bottom', 'border-left', 'border-right'],
editor: $('<input>'),

//FO: Added so we can target editable elements with the use of a class
//For example 'td.editable'
column: 'td'
};
6 changes: 3 additions & 3 deletions app/views/participants/index.html.erb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<h1><%= t('helpers.select.list') + ' ' + t('activerecord.models.plural.participant') %></h1>

<table>
<table class='participants'>
<thead>
<tr>
<th><%= t('activerecord.attributes.participant.firstname') %></th>
Expand All @@ -22,7 +22,7 @@

<tbody>
<% @participants.each do |participant| %>
<tr>
<tr id=<%= dom_id(participant) %>>
<td><%= participant.firstname %></td>
<td><%= participant.lastname %></td>
<td><%= participant.street %></td>
Expand All @@ -33,7 +33,7 @@
<td><%= participant.phone %></td>
<td><%= participant.date_of_birth %></td>
<td><%= show_gender(participant) %></td>
<td><%= participant.distance %></td>
<td class='editable'><%= participant.distance %></td>
<td><%= link_to t('helpers.navigate.show'), participant %></td>
<td><%= link_to t('helpers.navigate.edit'), edit_participant_path(participant) %></td>
<td><%= link_to t('helpers.navigate.destroy'), participant, method: :delete, data: { confirm: t('helpers.navigate.are_you_sure') } %></td>
Expand Down

0 comments on commit a74b009

Please sign in to comment.