// TODO: confirm
// TODO: popup
// TODO: disable_with
jQuery(function ($) {
var rails = {
update: function (selector, content, position) {
var element = $('#' + selector);
if (position) {
switch (position) {
case "before":
element.before(content);
break;
case "after":
element.after(content);
break;
case "top":
element.prepend(content);
break;
case "bottom":
element.append(content);
break;
default:
element.append(content);
break;
}
} else {
element.html(content);
}
},
remote: function (e) {
var el = $(this),
data = [],
condition = el.attr('data-condition') ? eval(el.attr('data-condition')) : true,
method = el.attr('method') || el.attr('data-method') || 'GET',
url = el.attr('action') || el.attr('data-url') || '#',
async = el.attr('data-remote-type') === 'synchronous' ? false : true;
if (el.attr('data-submit')) {
data = $('#' + el.attr('data-submit')).serializeArray();
} else if (el.attr('data-with')) {
if (e && e.target.tagName.toUpperCase() == 'SCRIPT' && el.attr('data-observed') !== null) {
var observed = $('#' + el.attr('data-observed'));
if(observed[0].tagName.toUpperCase() === 'FORM'){
data = el.attr('data-with') + '=' + observed.serialize();
} else if(observed[0].tagName.toUpperCase() === 'INPUT' && observed.attr('type').toUpperCase() !== "BUTTON" && observed.attr('type').toUpperCase() !== "SUBMIT") {
data = el.attr('data-with') + '=' + observed.val();
}
} else {
// TODO: remove eval when deprecated
data = eval(el.attr('data-with'));
}
} else if (e && e.target.tagName.toUpperCase() == 'FORM') {
data = el.serializeArray();
} else if (e && e.target.tagName.toUpperCase() == 'INPUT') {
data = el.closest('form').serializeArray();
}
if (condition) {
el.trigger('rails:before');
$.ajax({
async: async,
url: url,
data: data,
type: method.toUpperCase(),
beforeSend: function (xhr) {
xhr.setRequestHeader("Accept", "text/javascript")
el.trigger('rails:after', xhr);
el.trigger('rails:loading', xhr);
},
success: function (data, status, xhr) {
el.trigger('rails:success', [data, status, xhr]);
if (el.attr('data-update-success')) {
rails.update(el.attr('data-update-success'), data, el.attr('data-update-position'));
}
},
complete: function (xhr) {
el.trigger('rails:complete', xhr);
el.trigger('rails:loaded', xhr);
},
error: function (xhr, status, error) {
el.trigger('rails:failure', [xhr, status, error]);
if (el.attr('data-update-failure')) {
rails.update(el.attr('data-update-failure'), xhr.responseText, el.attr('data-update-position'));
}
}
});
}
e.preventDefault();
}
}
/**
* observe_form, and observe_field
*/
$('script[data-observe="true"]').each(function (index, e) {
var el = $(e),
observed = $('#' + $(e).attr('data-observed'));
frequency = el.attr('data-frequency') ? el.attr('data-frequency') : 10,
value = observed[0].tagName.toUpperCase() === 'FORM' ? observed.serialize() : observed.val();
var observe = function (observed, frequency, value, e) {
return function () {
var event = new jQuery.Event('periodical'),
newValue = observed[0].tagName.toUpperCase() === 'FORM' ? observed.serialize() : observed.val();
event.target = e;
if(value !== newValue) {
value = newValue;
$(e).trigger('rails:observe');
rails.remote.call(el, event);
}
}
}(observed, frequency, value, e);
setInterval(observe, frequency * 1000);
});
/**
* periodically_call_remote
*/
$('script[data-periodical="true"]').each(function (index, e) {
var el = $(e),
frequency = el.attr('data-frequency') ? el.attr('data-frequency') : 10;
setInterval(function () {
return function () {
var event = new jQuery.Event('periodical');
event.target = e;
rails.remote.call(el, event);
}
}(e, el), frequency * 1000);
});
/**
* remote_form_tag, and remote_form_for
*/
$('form[data-remote="true"]').live('submit', rails.remote);
/**
* link_to_remote, button_to_remote, and submit_to_remote
*/
$('a[data-remote="true"],input[data-remote="true"],input[data-remote-submit="true"]').live('click', rails.remote);
/**
*
* Rails 2.x Helper / Event Handlers
* By default we listen to all callbacks, and status code callbacks and
* check the element for data-<callback> attribute and eval it.
*
*/
rails.compat = {
evalAttribute: function (element, attribute) {
var el = $(element),
attr = el.attr('data-' + attribute);
return (attr) ? eval(attr) : true;
}
};
$('form[data-remote="true"],a[data-remote="true"],input[data-remote="true"],script[data-observe="true"]')
.live('rails:before', function (e) {
rails.compat.evalAttribute(this, 'onbefore');
})
.live('rails:after', function (e, xhr) {
rails.compat.evalAttribute(this, 'onafter');
})
.live('rails:loading', function (e, xhr) {
rails.compat.evalAttribute(this, 'onloading');
})
.live('rails:loaded', function (e, xhr) {
rails.compat.evalAttribute(this, 'onloaded');
})
.live('rails:complete', function (e, xhr) {
rails.compat.evalAttribute(this, 'oncomplete');
rails.compat.evalAttribute(this, 'on' + xhr.status);
})
.live('rails:success', function (e, data, status, xhr) {
rails.compat.evalAttribute(this, 'onsuccess');
})
.live('rails:failure', function (e, xhr, status, error) {
rails.compat.evalAttribute(this, 'onfailure');
})
.live('rails:observe', function (e) {
rails.compat.evalAttribute(this, 'onobserve');
});
});