Skip to content

Instantly share code, notes, and snippets.

@ahoward
Created April 7, 2009 23:24
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 ahoward/91531 to your computer and use it in GitHub Desktop.
Save ahoward/91531 to your computer and use it in GitHub Desktop.
<fieldset>
<legend><%= @company.new_record? ? "New company" : "Company #{ @company.id }" %></legend>
<% form_for([:q, @company], :html => {:class => 'standard'}) do |f| %>
<%= f.error_messages %>
<p>
<%= f.label :user %>
<br />
<%=
users = User.all
options = users.map{|u| [u.name, u.id ]}
has_user = !!@company.user_id
f.select(:user_id, options, {:include_blank => true}, {:disabled => has_user})
%>
</p>
<p>
<%= f.label :name %>
<br />
<%= f.text_field :name, :style => 'width:30%' %>
</p>
<% @company.nested_attributes.each do |nested_attribute| %>
<p>
<%= f.label nested_attribute.to_s.split(/_/).first %>
<%=
link_to(
icon_tag('add', 'class' => 'inline'),
'javascript:{}',
'data-nested_attribute' => nested_attribute,
'class' => 'add_nested_attribute',
'tabindex' => -1
)
%>
<%=
link_to(
icon_tag('delete', 'class' => 'inline'),
'javascript:{}',
'data-nested_attribute' => nested_attribute,
'class' => 'delete_nested_attribute',
'tabindex' => -1
)
%>
<% f.fields_for nested_attribute do |nf, *a| %>
<%=
if input_type = nested_attribute.to_s == 'mail_addresses'
nf.text_area(:value, :style => 'width:30%;overflow:hidden;display:block;', :rows => 4)
else
nf.text_field(:value, :style => 'width:30%;display:block')
end
%>
<% end %>
</p>
<% end %>
<p>
<%= label_tag('edit') unless action_name=='new' %>
<%= check_box_tag('edit', '1', checked=false, 'tabindex'=>1, 'style'=>"display:#{ (action_name=='new'?'none':'inline') }") %>
<%= f.submit 'Submit' %>
</p>
<% end %>
<br />
<%= link_to 'Back', q_companies_path %>
</fieldset>
<script type="text/javascript">
<!--
jq(function(){
/*
* code to append form fields
*/
var nested_attributes =
<%= @company.nested_attributes.to_json %>;
// finds the 'value-y' nested attributes
//
var find_nested_attribute_elements =
function(a){
var nested_attribute = a.attr("data-nested_attribute");
var id_pattern = sprintf("_%s_attributes_", nested_attribute);
var selector = sprintf("[id*='%s'][id$='_value']", id_pattern);
var elements = jq(selector);
return(elements);
};
// add one
//
var add_nested_attribute =
function(a){
var elements = find_nested_attribute_elements(a);
var last = jq(elements.get(elements.size() - 1));
var clone = last.clone();
var attrs = ['id', 'name'];
jq.each(attrs, function(idx){
var attr = attrs[idx];
var succ = last.attr(attr).replace(/(\d+)/g, function(n){ return(Number(n) + 1) });
clone.attr(attr, succ);
});
clone.css({'display':'block', 'margin-top':'0.5em'});
clone.val('');
last.after(clone)
clone.focus();
return(clone);
};
// nuke one
//
var delete_nested_attribute =
function(a){
var elements = find_nested_attribute_elements(a);
var size = elements.size();
var last = jq(elements.get(size - 1));
var next_to_last = jq(elements.get(size - 2));
// build up the form element to affect a delete
//
var clone = last.clone();
var name = last.attr('name');
var key = '_delete';
name = name.replace(/\[value\]$/, sprintf('[%s]', key));
var id = last.attr('id');
id = id.replace(/value$/, key);
clone.attr('name', name);
clone.attr('id', id);
clone.val('true');
clone.css('style', 'display:none');
clone.hide();
last.after(clone);
if(size > 1 ){
last.remove();
} else {
last.val('');
};
try{ next_to_last.focus() }catch(e){};
};
// give the + and - buttons add/delete behaviour
//
jq('.add_nested_attribute').each(function(){
var a = jq(this);
a.click(function(){ add_nested_attribute(a) });
});
jq('.delete_nested_attribute').each(function(){
var a = jq(this);
a.click(function(){ delete_nested_attribute(a) });
});
/*
* code to enable/disable the form
*/
var form = jq('form');
var submit = form.find('input[type=submit]');
var edit = form.find('input[name=edit][type=checkbox]');
var element_selectors = ['input[type=text]', 'input[type=submit]', 'textarea', 'select'];
var icons = []
var icon_selectors = ['.add_nested_attribute', '.delete_nested_attribute'];
// mark elements that should be permenantly disabled
//
jq.each(element_selectors, function(index){
jq.each(element_selectors, function(index){
var selector = element_selectors[index];
form.find(selector).each(function(){
var element = jq(this);
var disabled = Boolean(element.attr('disabled'));
element.data('disabled', disabled);
});
});
});
// scrape the form for it's elements, adding some behaviour
//
var elements = function(){
var list = [];
jq.each(element_selectors, function(index){
var selector = element_selectors[index];
form.find(selector).each(function(){
var element = jq(this);
var disabled = element.data('disabled');
if(disabled){
element.disable = function(){};
element.enable = function(){};
} else {
element.disable = function(){ element.attr('disabled', true) };
element.enable = function(){ element.removeAttr('disabled') };
};
list.push(element);
});
});
list.disable = function(){ jq.each(list, function(i){ list[i].disable() }) };
list.enable = function(){ jq.each(list, function(i){ list[i].enable() }) };
return list;
}
// scrape the form for it's icons, adding some behaviour
//
jq.each(icon_selectors, function(index){
var selector = icon_selectors[index];
form.find(selector).each(function(){
var icon = jq(this);
icon.disable = function(){ icon.hide() };
icon.enable = function(){ icon.show() };
icons.push(icon);
});
icons.disable = function(){ jq.each(icons, function(i){ icons[i].disable() }) };
icons.enable = function(){ jq.each(icons, function(i){ icons[i].enable() }) };
});
// give the form the ability to apply focus
//
form.focus = function(){
var list = elements();
jq.each(list, function(index){
if(list[index].attr('disabled')) return true;
list[index].focus();
return false;
});
};
// give the form the ability to be disabled
//
form.disable = function(){
elements().disable();
icons.disable();
};
// give the form the ability to be enabled
//
form.enable = function(){
elements().enable();
icons.enable();
form.focus();
};
// give checkbox ability to toggle form state editable|non-editable
//
edit.change(
function(){
var checked = edit.attr('checked');
checked ? form.enable() : form.disable();
return true;
}
);
// setup initial form state
//
var disabled = <%= (!!@disabled).to_json %>;
if(disabled){
form.disable();
} else {
form.enable();
edit.attr('checked', true);
};
});
// -->
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment