Skip to content

Instantly share code, notes, and snippets.

@chrisdone
Forked from mightybyte/local.js
Created January 17, 2012 19:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save chrisdone/1628400 to your computer and use it in GitHub Desktop.
Save chrisdone/1628400 to your computer and use it in GitHub Desktop.
Javascript for digestive-functors massInput
/*******************************************************************************
* Main entry point.
*/
$(document).ready(function(){
setupErrors();
setupDates();
setupAutoHide();
setupManageItems();
setupConfirms();
});
/*******************************************************************************
* Setup focusing the erroneous inputs.
*/
function setupErrors(){
$('form.submitted .digestive-error-list').each(function(){
var x = $(this).prev().find('input,select,textarea');
if(!x.length) x= $(this).parent().find('input,select,textarea');
if(x.length) {
x.focus();
return false;
}
});
}
/*******************************************************************************
* Setup calendar pop-ups for dates.
*/
function setupDates(){
$('.input-date input').each(function(){
var e = $(this).get(0);
Calendar.setup({
trigger: e,
inputField: e,
onSelect: function(){ this.hide(); },
dateFormat: '%Y/%m/%d'
});
});
}
/*******************************************************************************
* Setup to auto-hide items not filled in.
*/
function setupAutoHide(){
$('.inputList').each(function(){
if($(this).parent('form').hasClass('submitted') &&
$(this).find('.digestive-error-list')) return true;
var existingCount = $(this).find('input[width]').attr('width') * 1;
if(existingCount == 0) {
removeItem($(this).find('input[type=button]'));
}
});
}
/*******************************************************************************
* Setup managing the items in the list.
*/
function setupManageItems(spec) {
$(spec || '.inputListItem').each(function(){
var item = $(this);
// Only divs.
if(!$(this).get(0).tagName.match(/^div$/i)) return true;
// Add it
var manager = $('<div class="manage-bar"></div>');
$(this).append(manager);
manager.css({
position: 'absolute',
right: 0,
top: 0,
bottom: 0,
width: 0,
'text-align': 'center'
});
manager.append($('<button>Up</button>').click(function(){
setTimeout(function(){ moveItemUp(item); });
return false;
}));
manager.append($('<button>Down</button>').click(function(){
setTimeout(function(){ moveItemDown(item); });
return false;
}));
manager.append($('<button>Delete</button>').click(function(){
setTimeout(function(){ removeItemByEl(item); });
return false;
}));
$(this).css({ position:'relative', 'padding-right': $(manager).width() + 'px' });
});
}
/*******************************************************************************
* Remove a list item.
*/
function removeItemByEl(el){
if(el.prev().length && el.prev().hasClass('inputListItem') ||
el.next().length && el.next().hasClass('inputListItem')) {
// Decrement counter
var count = el.parents('.inputList').find(':hidden').first();
count.val(parseInt(count.val())-1);
var next = el;
while ((next = next.next()).length) {
adjustItemId(next,function(c){ return c-1; });
setupManageItems(next);
}
el.remove();
} else {
alert("Cannot remove any more rows.");
}
}
/*******************************************************************************
* Find a mass input.
*/
function findMassInput(button) {
var mainDiv = $(button).parent();
while ( !mainDiv.hasClass('inputList') ) {
mainDiv = $(mainDiv).parent();
}
return mainDiv;
}
/*******************************************************************************
* Find arbitrary input list items.
*/
function findItems(button) {
return $('.inputListItem', findMassInput(button));
}
/*******************************************************************************
* Move an item up in the list.
*/
function moveItemUp(item) {
var other = item.prev();
if(other.hasClass('inputListItem')){
item.fadeOut(function(){
other.before(item);
swapItemIds(item,other);
item.fadeIn();
});
}
}
/*******************************************************************************
* Move an item down in the list.
*/
function moveItemDown(item) {
var other = item.next();
if(other.hasClass('inputListItem')){
item.fadeOut(function(){
other.after(item);
swapItemIds(other,item);
item.fadeIn();
});
}
}
/*******************************************************************************
* Swap the input ids of two items.
*/
function swapItemIds(first,second){
adjustItemId(first,function(c){ return c - 1; });
adjustItemId(second,function(c){ return c + 1; });
setupManageItems(first);
setupManageItems(second);
}
/*******************************************************************************
* Add an input list item. Called from the buttons.
*/
function addItem(button) {
var count = $($(':hidden', findMassInput(button))[0]);
var items = findItems(button);
var item = $(items[items.length-1]);
// Check we don't have the hidden "zero items" list item
if(items.length == 1){
if(!item.is(':visible')) {
// Increment counter
count.val(parseInt(count.val())+1);
item.show();
return;
}
}
var newItem = item.clone(true).show();
var i;
// Increment counter
count.val(parseInt(count.val())+1);
adjustItemId(newItem,function(c){ return c + 1; });
newItem.appendTo(item.parent());
// Copy the values of all children that had the name attribute set.
// The direct html insertion does not preserve the most current
// values. It only preserves default values, so if we want values
// copied, we have to use an approach like this.
var items2 = findItems(button);
var newLast = $(items2[items2.length-1]);
var c1 = $('[name]', item);
var c2 = $('[name]', newLast);
if ( c1.length == c2.length ) {
for ( i = 0; i < c1.length; i++ ) {
//This way copies the values
//$(c2[i]).val($(c1[i]).val());
//and this way blanks them
$(c2[i]).val('');
}
}
setupManageItems(newItem);
}
/*******************************************************************************
* Adjust the id of a list item.
*/
function adjustItemId(item,f){
var values = {};
$('[name]',item).each(function(){
var v = $(this).val();
values[$(this).attr('name')] = v? v : '';
});
var html = item.html();
item.html(replaceInString(html));
for(var name in values){
item.find('[name="' + replaceInString(name) + '"]').val(values[name]);
}
// We have to change the raw html because IE doesn't allow the
// name field to be changed.
function replaceInString(html){
return html.replace(/fval\[(\d+\.)*(\d+)\.(\d+)\]/g,function(a,b,c,d){
var c = parseInt(c);
return a.replace(/\d+\.\d+\]/,
f(c)+'.'+d+']');
});
}
}
/*******************************************************************************
* Remove the last item from the input list.
*/
function removeItem(button) {
var items = findItems(button);
if ( items.length > 1 ) {
var count = $($(':hidden', findMassInput(button))[0]);
var item = $(items[items.length-1]);
item.remove();
// Decrement counter
count.val(parseInt(count.val())-1);
} else if(items.length == 1) {
var count = $($(':hidden', findMassInput(button))[0]);
var item = $(items[items.length-1]);
item.hide();
// Decrement counter
count.val(Math.max(0,parseInt(count.val())-1));
} else {
}
}
/*******************************************************************************
* Setup draggable list items from an input list.
* Not used for now.
*/
function _setupDraggables(){
$('.inputListItem').each(function(){
// Set it up once for an item.
if($(this).find('.dragbar').length) return true;
// Only divs.
if(!$(this).get(0).tagName.match(/^div$/i)) return true;
// Add it
$(this).css('position','relative');
var mover = $('<div></div>');
$(this).append(mover);
mover.css({
position: 'absolute',
width: 4,
left:0,
top: 0,
bottom: 0,
background: 'url(/images/dots.png) #ddd no-repeat center center',
padding: '0 0 0 2px',
cursor: 'move'
});
});
}
/*******************************************************************************
* Setup confirmation for links with the 'confirm' class.
*/
function setupConfirms(){
$('.confirm').each(function(){
var title = $(this).attr('title');
$(this).click(function(){
return confirm($(this).text() + "?" + (title? '\n\n' + title : ''));
});
});
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment