Signed-off-by: Ohad Levy <ohadlevy@gmail.com>
···
--- app/helpers/application_helper.rb | 49 ++-- app/views/layouts/application.html.erb | 4 +- public/javascripts/application.js | 39 +++ public/javascripts/jquery.jeditable.js | 556 ++++++++++++++++++++++++++++++++ 4 files changed, 624 insertions(+), 24 deletions(-) create mode 100644 public/javascripts/jquery.jeditable.jsdiff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index de731d6…90a7e7a 100644
— a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -68,29 +68,6 @@ module ApplicationHelper
link_to_function(“Uncheck all”, “checkAll(’##{form_name}’, false)”)
end
- def searchtab title, search, options
- opts = {:action => params[:action], :tab_name => title, :search => search}
- selected_class = options[:selected] ? “selectedtab” : “”
- content_tag(:li) do
-
link_to opts, :class => selected_class do
-
h(title) + (options[:no_close_button] ? "": (link_to "x", opts.merge(:remove_me => true), :class => "#{selected_class} close"))
-
end
- end
- end
- def toggle_searchbar
- update_page do |page|
-
page['search'].toggle
-
page['tabs'].toggle
- end
- end
- def fact_name_select
- param = params[:search]["#{@via}fact_name_id_eq"] if params[:search]
- return param.to_i unless param.empty?
- return @fact_name_id if @fact_name_id
- end
-
Return true if user is authorized for controller/action, otherwise false
+controller+ : String or symbol for the controller
+action+ : String or symbol for the action
@@ -166,4 +143,30 @@ module ApplicationHelper
auto_complete_field_jquery(method, “#{path}/auto_complete_#{method}”, completion_options)
end
- def edit_textfield(object, property, options={})
- edit_inline(object, property, options.merge({:type => “edit_textfield”}))
- end
- def edit_textarea(object, property, options={})
- edit_inline(object, property, options.merge({:type => “edit_textarea”}))
- end
- protected
- def edit_inline(object, property, options={})
- name = “#{type}[#{property}]”
- helper = options[:helper]
- value = helper.nil? ? object.send(property) : self.send(helper, object)
- klass = options[:type]
- update_url = options[:update_url] || url_for(object)
- opts = { :title => “Click to edit”, “data-url” => update_url, :class => klass,
-
:name => name, "data-field" => property, :value => value}
- content_tag_for :span, object, opts do
-
h(value)
- end
- end
end
diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb
index ca88fbe…61079df 100644
— a/app/views/layouts/application.html.erb
+++ b/app/views/layouts/application.html.erb
@@ -7,7 +7,9 @@
<title> <%= h(yield(:title) || "Foreman") %></title>
<%= stylesheet_link_tag 'reset', 'style', 'typography', 'grid', 'jquery-ui', 'jquery.jnotify' %>
- <%= javascript_include_tag :defaults, ‘menu’, ‘highcharts’, ‘jquery.jnotify’ %>
- <%= javascript_include_tag :defaults, ‘menu’, ‘highcharts’, ‘jquery.jnotify’, ‘jquery.jeditable’ %>
- <%= javascript_tag “var AUTH_TOKEN = #{form_authenticity_token.inspect};” if protect_against_forgery? %>
- <%= yield(:head) %>
diff --git a/public/javascripts/application.js b/public/javascripts/application.js
index 8057ae0…04fcb6f 100644
— a/public/javascripts/application.js
+++ b/public/javascripts/application.js
@@ -157,3 +157,42 @@ function pie_chart(div, title, data) {
}]
});
};
+
+$(document).ready(function() {
- var common_settings = {
- method : ‘PUT’,
- submit : ‘Save’,
- indicator : “
”,
- tooltip : ‘Click to edit…’,
- placeholder : ‘Click to edit…’,
- submitdata : {authenticity_token: AUTH_TOKEN, format : “json”},
- onsuccess : function(data) {
-
var parsed = $.parseJSON(data);
-
$(this).html(parsed[$(this).attr('name').split("[")[0]][$(this).attr('data-field')]);
- },
- onerror : function(settings, original, xhr) {
-
original.reset();
-
var error = $.parseJSON(xhr.responseText)["errors"]
-
$.jnotify(error, { type: "error", sticky: true });
- }
- };
- $(’.edit_textfield’).each(function() {
- var settings = {
-
type : 'text',
-
name : $(this).attr('name'),
- };
- $(this).editable($(this).attr(‘data-url’), $.extend(common_settings, settings));
- });
- $(’.edit_textarea’).each(function() {
- var settings = {
-
type : 'textarea',
-
name : $(this).attr('name'),
-
rows : 8,
-
cols : 36
- };
- $(this).editable($(this).attr(‘data-url’), $.extend(common_settings, settings));
- });
+});
\ No newline at end of file
diff --git a/public/javascripts/jquery.jeditable.js b/public/javascripts/jquery.jeditable.js
new file mode 100644
index 0000000…ae07c8e
— /dev/null
+++ b/public/javascripts/jquery.jeditable.js
@@ -0,0 +1,556 @@
+/*
-
- Jeditable - jQuery in place edit plugin
-
-
- Copyright © 2006-2009 Mika Tuupola, Dylan Verheul
-
-
- Licensed under the MIT license:
-
-
- Project home:
-
-
- Based on editable by Dylan Verheul <dylan_at_dyve.net>:
-
- */
+/**
-
- Version 1.7.1
-
-
- ** means there is basic unit tests for this parameter.
-
-
- @name Jeditable
-
- @type jQuery
-
- @param String target (POST) URL or function to send edited content to **
-
- @param Hash options additional options
-
- @param String options[method] method to use to send edited content (POST or PUT) **
-
- @param Function options[callback] Function to run after submitting edited content **
-
- @param String options[name] POST parameter name of edited content
-
- @param String options[id] POST parameter name of edited div id
-
- @param Hash options[submitdata] Extra parameters to send when submitting edited content.
-
- @param String options[type] text, textarea or select (or any 3rd party input type) **
-
- @param Integer options[rows] number of rows if using textarea **
-
- @param Integer options[cols] number of columns if using textarea **
-
- @param Mixed options[height] ‘auto’, ‘none’ or height in pixels **
-
- @param Mixed options[width] ‘auto’, ‘none’ or width in pixels **
-
- @param String options[loadurl] URL to fetch input content before editing **
-
- @param String options[loadtype] Request type for load url. Should be GET or POST.
-
- @param String options[loadtext] Text to display while loading external content.
-
- @param Mixed options[loaddata] Extra parameters to pass when fetching content before editing.
-
- @param Mixed options[data] Or content given as paramameter. String or function.**
-
- @param String options[indicator] indicator html to show when saving
-
- @param String options[tooltip] optional tooltip text via title attribute **
-
- @param String options[event] jQuery event such as ‘click’ of ‘dblclick’ **
-
- @param String options[submit] submit button value, empty means no button **
-
- @param String options[cancel] cancel button value, empty means no button **
-
- @param String options[cssclass] CSS class to apply to input form. ‘inherit’ to copy from parent. **
-
- @param String options[style] Style to apply to input form ‘inherit’ to copy from parent. **
-
- @param String options[select] true or false, when true text is highlighted ??
-
- @param String options[placeholder] Placeholder text or html to insert when element is empty. **
-
- @param String options[onblur] ‘cancel’, ‘submit’, ‘ignore’ or function ??
-
-
- @param Function options[onsubmit] function(settings, original) { … } called before submit
-
- @param Function options[onreset] function(settings, original) { … } called before reset
-
- @param Function options[onsuccess] function(result, status, xhr) { … } called on success
-
- @param Function options[onerror] function(settings, original, xhr) { … } called on error
-
-
- @param Hash options[ajaxoptions] jQuery Ajax options. See docs.jquery.com.
-
- */
+(function($) {
+
- $.fn.editable = function(target, options) {
-
if ('disable' == target) {
-
$(this).data('disabled.editable', true);
-
return;
-
}
-
if ('enable' == target) {
-
$(this).data('disabled.editable', false);
-
return;
-
}
-
if ('destroy' == target) {
-
$(this)
-
.unbind($(this).data('event.editable'))
-
.removeData('disabled.editable')
-
.removeData('event.editable');
-
return;
-
}
-
var settings = $.extend({}, $.fn.editable.defaults, {target:target}, options);
-
/* setup some functions */
-
var plugin = $.editable.types[settings.type].plugin || function() { };
-
var submit = $.editable.types[settings.type].submit || function() { };
-
var buttons = $.editable.types[settings.type].buttons
-
|| $.editable.types['defaults'].buttons;
-
var content = $.editable.types[settings.type].content
-
|| $.editable.types['defaults'].content;
-
var element = $.editable.types[settings.type].element
-
|| $.editable.types['defaults'].element;
-
var reset = $.editable.types[settings.type].reset
-
|| $.editable.types['defaults'].reset;
-
var callback = settings.callback || function() { };
-
var onedit = settings.onedit || function() { };
-
var onsubmit = settings.onsubmit || function() { };
-
var onreset = settings.onreset || function() { };
-
var onsuccess = settings.onsuccess || function() { };
-
var onerror = settings.onerror || reset;
-
var oneditcomplete = settings.oneditcomplete || function() { };
-
var onresetcomplete = settings.onresetcomplete || function() { };
-
/* show tooltip */
-
if (settings.tooltip) {
-
$(this).attr('title', settings.tooltip);
-
}
-
settings.autowidth = 'auto' == settings.width;
-
settings.autoheight = 'auto' == settings.height;
-
return this.each(function() {
-
/* save this to self because this changes when scope changes */
-
var self = this;
-
/* inlined block elements lose their width and height after first edit */
-
/* save them for later use as workaround */
-
var savedwidth = $(self).width();
-
var savedheight = $(self).height();
-
/* save so it can be later used by $.editable('destroy') */
-
$(this).data('event.editable', settings.event);
-
/* if element is empty add something clickable (if requested) */
-
if (!$.trim($(this).html())) {
-
$(this).html(settings.placeholder);
-
}
-
$(this).bind(settings.event, function(e) {
-
/* abort if disabled for this element */
-
if (true === $(this).data('disabled.editable')) {
-
return;
-
}
-
/* prevent throwing an exeption if edit field is clicked again */
-
if (self.editing) {
-
return;
-
}
-
/* abort if onedit hook returns false */
-
if (false === onedit.apply(this, [settings, self])) {
-
return;
-
}
-
/* prevent default action and bubbling */
-
e.preventDefault();
-
e.stopPropagation();
-
/* remove tooltip */
-
if (settings.tooltip) {
-
$(self).removeAttr('title');
-
}
-
/* figure out how wide and tall we are, saved width and height */
-
/* are workaround for http://dev.jquery.com/ticket/2190 */
-
if (0 == $(self).width()) {
-
//$(self).css('visibility', 'hidden');
-
settings.width = savedwidth;
-
settings.height = savedheight;
-
} else {
-
if (settings.width != 'none') {
-
settings.width =
-
settings.autowidth ? $(self).width() : settings.width;
-
}
-
if (settings.height != 'none') {
-
settings.height =
-
settings.autoheight ? $(self).height() : settings.height;
-
}
-
}
-
//$(this).css('visibility', '');
-
/* remove placeholder text, replace is here because of IE */
-
if ($(this).html().toLowerCase().replace(/(;|")/g, '') ==
-
settings.placeholder.toLowerCase().replace(/(;|")/g, '')) {
-
$(this).html('');
-
}
-
self.editing = true;
-
self.revert = $(self).html();
-
$(self).html('');
-
/* create the form object */
-
var form = $('<form />');
-
/* apply css or style or both */
-
if (settings.cssclass) {
-
if ('inherit' == settings.cssclass) {
-
form.attr('class', $(self).attr('class'));
-
} else {
-
form.attr('class', settings.cssclass);
-
}
-
}
-
if (settings.style) {
-
if ('inherit' == settings.style) {
-
form.attr('style', $(self).attr('style'));
-
/* IE needs the second line or display wont be inherited */
-
form.css('display', $(self).css('display'));
-
} else {
-
form.attr('style', settings.style);
-
}
-
}
-
/* add main input element to form and store it in input */
-
var input = element.apply(form, [settings, self]);
-
/* set input content via POST, GET, given data or existing value */
-
var input_content;
-
if (settings.loadurl) {
-
var t = setTimeout(function() {
-
input.disabled = true;
-
content.apply(form, [settings.loadtext, settings, self]);
-
}, 100);
-
var loaddata = {};
-
loaddata[settings.id] = self.id;
-
if ($.isFunction(settings.loaddata)) {
-
$.extend(loaddata, settings.loaddata.apply(self, [self.revert, settings]));
-
} else {
-
$.extend(loaddata, settings.loaddata);
-
}
-
$.ajax({
-
type : settings.loadtype,
-
url : settings.loadurl,
-
data : loaddata,
-
async : false,
-
success: function(result) {
-
window.clearTimeout(t);
-
input_content = result;
-
input.disabled = false;
-
}
-
});
-
} else if (settings.data) {
-
input_content = settings.data;
-
if ($.isFunction(settings.data)) {
-
input_content = settings.data.apply(self, [self.revert, settings]);
-
}
-
} else {
-
input_content = self.revert;
-
}
-
content.apply(form, [input_content, settings, self]);
-
input.attr('name', settings.name);
-
/* add buttons to the form */
-
buttons.apply(form, [settings, self]);
-
/* add created form to self */
-
$(self).append(form);
-
/* attach 3rd party plugin if requested */
-
plugin.apply(form, [settings, self]);
-
/* focus to first visible form element */
-
$(':input:visible:enabled:first', form).focus();
-
/* highlight input contents when requested */
-
if (settings.select) {
-
input.select();
-
}
-
/* discard changes if pressing esc */
-
input.keydown(function(e) {
-
if (e.keyCode == 27) {
-
e.preventDefault();
-
//self.reset();
-
reset.apply(form, [settings, self]);
-
}
-
});
-
/* discard, submit or nothing with changes when clicking outside */
-
/* do nothing is usable when navigating with tab */
-
var t;
-
if ('cancel' == settings.onblur) {
-
input.blur(function(e) {
-
/* prevent canceling if submit was clicked */
-
t = setTimeout(function() {
-
reset.apply(form, [settings, self]);
-
}, 500);
-
});
-
} else if ('submit' == settings.onblur) {
-
input.blur(function(e) {
-
/* prevent double submit if submit was clicked */
-
t = setTimeout(function() {
-
form.submit();
-
}, 200);
-
});
-
} else if ($.isFunction(settings.onblur)) {