<div id="ips_table_div"> <%= render "ips_table" %> </div>
Then, we create the table and the javascript code in our partial view (app/views/ips/_ips_table.html.erb).
<table cellpadding="10"><tbody>
<% unless @ips.nil? %>
<tr>
<td id="ip_new_ip_td_div">
<%= form_tag url_for(:controller => :ips,
:action => :create_ip),
:remote => true,
:id => "new_ip" %>
<%= text_field_tag "ip" %>
<%= submit_tag t(:add_button, :scope => [:application]), :id => "new_ip_submit" %>
</form>
</td>
<td>
</td>
</tr>
<% @ips.each do |ip| %>
<tr>
<td id="ip_ip_td_div_<%=ip.id %>">
<div id="ip_ip_text_div_<%=ip.id %>"><%= ip.ip %></div>
</td>
<td>
<%= link_to t(:delete_link, :scope => [:application]),
url_for(:controller => :ips,
:action => :delete_ip,
:id => ip.id),
:remote => true,
:confirm => t(:ip_delete_confirm, :scope => [:application])%>
</td>
</tr>
<% end %>
<% end %>
</tbody></table>
<script type="text/javascript">
var ip_validate_background_color_error = "#fff999";
var ip_validate_border_color_error = "#f80000";
var ip_validate_background_color = "#ffffff";
var ip_validate_border_color = "#999999";
var ipModifyFormOptions= $H({
cancelText:'<%=t :cancel_link, :scope => [:application] %>',
okText: 'ok',
savingText: '<%=t :saving_text, :scope => [:application] %>',
loadingText: '<%=t :loading_text, :scope => [:application] %>',
clickToEditText: '<%=t :click_to_edit_text, :scope => [:application] %>',
});
<% unless @ips.nil? %>
Form.findFirstElement('new_ip').style.borderColor = ip_validate_border_color;
Form.findFirstElement('new_ip').style.backgroundColor = ip_validate_background_color;
Form.findFirstElement('new_ip').setAttribute("onkeypress","return input_filter_exact(event, 'ip')");
$('new_ip_submit').disabled=true;
new Form.Observer('new_ip', 0.3, function(form, value) {
if(validateIpAddress(Form.findFirstElement('new_ip').value, false) == true) {
Form.findFirstElement('new_ip').style.borderColor = ip_validate_border_color;
Form.findFirstElement('new_ip').style.backgroundColor = ip_validate_background_color;
$('new_ip_submit').disabled=false;
} else {
Form.findFirstElement('new_ip').style.borderColor = ip_validate_border_color_error;
Form.findFirstElement('new_ip').style.backgroundColor = ip_validate_background_color_error;
$('new_ip_submit').disabled=true;
}
});
<% @ips.each do |ip| %>
new Ajax.InPlaceEditor('ip_ip_text_div_<%=ip.id %>', '<%= url_for :controller => :ips, :action => :modify_ip, :id => ip.id %>', ipModifyFormOptions.merge({
formId: 'ip_ip_form_<%=ip.id %>',
onEnterEditMode: function(form, value) {
setTimeout(function() {
Form.findFirstElement('ip_ip_form_<%=ip.id %>').style.borderColor = ip_validate_border_color;
Form.findFirstElement('ip_ip_form_<%=ip.id %>').style.backgroundColor = ip_validate_background_color;
Form.findFirstElement('ip_ip_form_<%=ip.id %>').setAttribute("onkeypress","return input_filter_exact(event, 'ip')");
new Form.Observer('ip_ip_form_<%=ip.id %>', 0.3, function(form, value) {
if(validateIpAddress(Form.findFirstElement('ip_ip_form_<%=ip.id %>').value, false) == true) {
Form.findFirstElement('ip_ip_form_<%=ip.id %>').style.borderColor = ip_validate_border_color;
Form.findFirstElement('ip_ip_form_<%=ip.id %>').style.backgroundColor = ip_validate_background_color;
$('ip_ip_form_<%=ip.id %>').elements[1].disabled=false;
} else {
Form.findFirstElement('ip_ip_form_<%=ip.id %>').style.borderColor = ip_validate_border_color_error;
Form.findFirstElement('ip_ip_form_<%=ip.id %>').style.backgroundColor = ip_validate_background_color_error;
$('ip_ip_form_<%=ip.id %>').elements[1].disabled=true;
}
});
}, 1000);
}
}).toObject());
<% end %>
<% end %>
</script>Then we should make the controller (app/controllers/ips_controller.rb):
respond_to :js, :only => [:delete_ip, :create_ip]
respond_to :html, :except => [:delete_ip, :create_ip]
layout :application, :except => [:delete_ip, :create:ip, :modify_ip]
layout false, :only => [:delete_ip, :create:ip, :modify_ip]
def index
@ips=Ip.all
respond_with(@ips)
end
def delete_ip
Ip.destroy(params[:id])
# it will returns a javascript code by default, so have to do the
# app/views/ips/delete_ip.js.erb, what will loads the table completely
@ips=Ip.all
respond_with(@ips)
end
def create_ip
ip=Ip.new(params[:ip]).save
# it will returns a javascript code, so have to do the
# app/views/ips/create_ip.js.erb, what will loads the table completely
@ips=Ip.all
respond_with(@ips)
end
def modify_ip
ip=Ip.find(params[:id])
ip.update_attribute(:ip, params[:value])
# don't forget some validations here also
# it will returns a html code, so have to do the
# app/views/ips/modify_ip.html.erb, what will contains the new text only, or:
respond_to do |format|
format.html { render :text => ip.ip }
end
endThen we can create returned javascript codes app/views/ips/create_ip.js.erb and delete_ip.js.erb:
$("ips_table_div").innerHTML='';
$("ips_table_div").update("<%=escape_javascript(render(:template => "/ips/_ips_table.html.erb", :locals => {:ips => @ips})) %>");
Finally we must define javascipt validation functions in public/apllication.js:
function validateIpAddress(value, can_be_empty) {
if (arguments.length == 1) {
can_be_empty = false;
}
if (can_be_empty == true) {
if (value == null) {
return false;
}
if (value == "") {
return true;
}
}
if (value.match(/\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/))
{
if (value.length>0 && value.length<256)
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
function input_filter_exact(e, type) {
var enabled_chars;
switch (type)
{
case "ip": enabled_chars="0123456789.";
break;
default: enabled_chars="-/.,_?[]()!abcdefghijklmnopqrstvuwxyzABCDEFGHIJKLMNOPQRSTVUWXYZ0123456789éáőúűóüöíÉÁŐÚÓÜÖÍ ";
}
var key;
var keychar;
if (window.event)
key = window.event.keyCode;
else if (e)
key = e.which;
else
return true;
keychar = String.fromCharCode(key);
if ((key==null) || (key==0) || (key==8) || (key==9) || (key==13) || (key==27) )
return true;
else if (((enabled_chars).indexOf(keychar) > -1))
return true;
else
return false;
} That's all. Works with Rails 3.0.9, Prototype 1.7 and script.aculo.us v1.8.3
Thanks for post, but it seems too hard to implement and have much custom javascript and lots of non-restful actions in controller
ReplyDeleteI'm sure there's an easier way.
ReplyDelete