У меня есть этот странный неудачный кофе, из этой демонстрации . Демо-код отлично работает на моей локальной машине. И я вопиюще скопировал это, оптом, в мое собственное приложение rails 3.1. Нет полезных сообщений об ошибках, но кнопки работают так, как будто они кнопки, которые не знают, что к ним прикреплен скрипт - они обновляют страницу.
app / assets / application.js содержит скомпилированный кофейный скрипт.
Скомпилированный HTML-код идентичен между двумя приложениями.
Другие JavaScript работают.
Я удалил все CSS и JavaScript, кроме этого, и он не работает.
Coffeescript в порядке, так как работает на демонстрационном приложении на моей машине.
Я что-то упускаю из виду, как вы используете сценарий кофе в конвейере ресурсов?
Код:
application.rb:
# Enable the asset pipeline
config.assets.enabled = true
Search.js.coffee:
class @Search
constructor: (@templates = {}) ->
remove_fields: (button) ->
$(button).closest('.fields').remove()
add_fields: (button, type, content) ->
new_id = new Date().getTime()
regexp = new RegExp('new_' + type, 'g')
$(button).before(content.replace(regexp, new_id))
nest_fields: (button, type) ->
new_id = new Date().getTime()
id_regexp = new RegExp('new_' + type, 'g')
template = @templates[type]
object_name = $(button).closest('.fields').attr('data-object-name')
sanitized_object_name = object_name.replace(/\]\[|[^-a-zA-Z0-9:.]/g, '_').replace(/_$/, '')
template = template.replace(/new_object_name\[/g, object_name + "[")
template = template.replace(/new_object_name_/, sanitized_object_name + '_')
$(button).before(template.replace(id_regexp, new_id))
Помощник по применению:
def setup_search_form(builder)
fields = builder.grouping_fields builder.object.new_grouping, object_name: 'new_object_name', child_index: "new_grouping" do |f|
render('grouping_fields', f: f)
end
content_for :document_ready, %Q{
var search = new Search({grouping: "#{escape_javascript(fields)}"});
$('button.add_fields').live('click', function() {
search.add_fields(this, $(this).data('fieldType'), $(this).data('content'));
return false;
});
$('button.remove_fields').live('click', function() {
search.remove_fields(this);
return false;
});
$('button.nest_fields').live('click', function() {
search.nest_fields(this, $(this).data('fieldType'));
return false;
});
}.html_safe
end
def button_to_remove_fields(name, f)
content_tag :button, name, class: 'remove_fields'
end
def button_to_add_fields(name, f, type)
new_object = f.object.send "build_#{type}"
fields = f.send("#{type}_fields", new_object, child_index: "new_#{type}") do |builder|
render(type.to_s + "_fields", f: builder)
end
content_tag :button, name, :class => 'add_fields', 'data-field-type' => type, 'data-content' => "#{fields}"
end
def button_to_nest_fields(name, type)
content_tag :button, name, :class => 'nest_fields', 'data-field-type' => type
end
advanced_search.html.erb
<h1>Advanced ISBN Search</h1>
<%= link_to 'Simple mode', isbns_path %>
<%= search_form_for @search, url: advanced_search_isbns_path, html: {method: :post} do |f| %>
<% setup_search_form f %>
<fieldset>
<legend>Sorting</legend>
<%= f.sort_fields do |s| %>
<%= render 'sort_fields', f: s %>
<% end %>
<%= button_to_add_fields "Add Sort", f, :sort %>
</fieldset>
<fieldset>
<legend>Condition Groups</legend>
<%= f.grouping_fields do |g| %>
<%= render 'grouping_fields', f: g %>
<% end %>
<%= button_to_add_fields "Add Condition Group", f, :grouping %>
</fieldset>
<%= label_tag :distinct, 'Return distinct records?' %>
<%= check_box_tag :distinct, '1', params[:distinct].to_i == 1 %>
<%= f.submit %>
<% end %>
<%= render 'results' %>
Пример частичного: _grouping_fields.html.erb
<fieldset class="fields" data-object-name="<%= f.object_name %>">
<legend>Match <%= f.combinator_select %> conditions <%= button_to_remove_fields "remove", f %></legend>
<%= f.condition_fields do |c| %>
<%= render 'condition_fields', f: c %>
<% end %>
<%= button_to_add_fields "Add Condition", f, :condition %>
<%= f.grouping_fields do |g| %>
<%= render 'grouping_fields', f: g %>
<% end %>
<%= button_to_nest_fields "Add Condition Group", :grouping %>
</fieldset>
Обновление / решение.
Firebug указал, что есть конфликт с некоторыми другими js, в жемчужине Кокон. Вот его код:
$('.add_fields').live('click', function() {
var assoc = $(this).attr('data-association');
var assocs = $(this).attr('data-associations');
var content = $(this).attr('data-template');
var insertionPosition = $(this).attr('data-association-insertion-position');
var insertionNode = $(this).attr('data-association-insertion-node');
var insertionCallback = $(this).data('insertion-callback');
var regexp_braced = new RegExp('\\[new_' + assoc + '\\]', 'g');
var regexp_underscord = new RegExp('_new_' + assoc + '_', 'g');
var new_id = new Date().getTime();
var newcontent_braced = '[' + new_id + ']';
var newcontent_underscord = '_' + new_id + '_';
var new_content = content.replace(regexp_braced, '[' + new_id + ']');
if (new_content == content) {
regexp_braced = new RegExp('\\[new_' + assocs + '\\]', 'g');
regexp_underscord = new RegExp('_new_' + assocs + '_', 'g');
new_content = content.replace(regexp_braced, '[' + new_id + ']');
}
new_content = new_content.replace(regexp_underscord, newcontent_underscord);
if (insertionNode) {
insertionNode = $(insertionNode);
}
else {
insertionNode = $(this).parent();
}
var contentNode = $(new_content);
if (insertionPosition == 'after'){
insertionNode.after(contentNode);
} else {
insertionNode.before(contentNode);
}
if(insertionCallback){
insertionCallback.call(contentNode);
}
return false;
});
Конфликтующая строка
var new_content = content.replace(regexp_braced, '[' + new_id + ']');
Переименование add_fields в add_s_fields в application_helper, и coffeescript разобрался с ним.