我正在尝试在Ruby On Rails中执行复杂的表单。它应该分组,每组应该有文本字段。我想要添加和删除组和文本字段。
我已经成功地添加了文本字段并将其删除,但是我完全无法对这些组进行相同操作。
这是对函数的调用:
<%= link_to_function 'Add group' do |page|
page.insert_html :bottom, :groups, :partial => 'group'
end %>
所以,它应该将名为“group”的部分添加到“groups”div中,对吗?好吧,它没有。这是部分:
<div id="group" class='elements'>
<p>
<g_title>Text Group</g_title>
<add><%= add_text_link 'Add a text field'%></add>
<remove><%= link_to_function 'Remove text group', "this.up('.elements').remove()" %></remove>
</p>
<%= render :partial => 'text' %>
</div>
如果我点击“添加新组”链接,Firebug告诉我有一些错误,例如某些javascript代码无效(错误在属性列表后“丢失”)。但是,如果我删除部分代码中的第四行(具有“add_text_link”功能的那一行),它就完美了!而且这个功能很完美。
那么,任何想法?
感谢您的帮助!
编辑:这是生成的源代码:
<form action="/collect/text" method="post"><div style="margin:0;padding:0"><input name="authenticity_token" type="hidden" value="b2zqh1op9oHbjQ33mMAWEhZcEqHoYhUIMV0uPH8F2ms=" /></div>
<div id= 'main_elements' class='elements'>
<p><g_title>Main elements</g_title></p>
<p><input id="Title" name="Title" size="50" type="text" />
<label class="h0" for="Title">Title</label> <options>(mandatory)</options></p>
<p><input id="Subtitle" name="Subtitle" size="50" type="text" />
<label class="h0" for="Subtitle">Subtitle</label> <options>(optional)</options></p>
</div>
<div id='groups' class="groups">
<p><add><a href="#" onclick="try {
Element.insert("groups", { bottom: "<p></p>\n<div id=\"group\" class='elements'>\n\t<p>\n\t\t<g_title>Text Group</g_title>\n\t\t<add><a href=\"#\" onclick=\"try {\nElement.insert("group", { bottom: "\\n<div class='text'>\\n\\t<p>\\n\\t\\tText <input id=\\"content\\" name=\\"content\\" size=\\"50\\" type=\\"text\\" /> Importance <select id=\\"t1\\" name=\\"t1\\"><option value=\\"notes\\">Notes</option>\\n<option value=\\"highlighted\\">Highlighted text</option>\\n<option value=\\"normal\\">Normal text</option></select>\\n\\t\\t<remove><a href=\\"#\\" onclick=\\"this.up('.text').remove(); return false;\\">Remove text field</a></remove>\\n\\t</p>\\n</div>" });\nnew Effect.Highlight("group",{duration:0.3, startcolor:'#34d85e'});\n} catch (e) { alert('RJS error:\\n\\n' + e.toString()); alert('Element.insert(\\"group\\", { bottom: \\"\\\\n<div class=\\'text\\'>\\\\n\\\\t<p>\\\\n\\\\t\\\\tText <input id=\\\\\\"content\\\\\\" name=\\\\\\"content\\\\\\" size=\\\\\\"50\\\\\\" type=\\\\\\"text\\\\\\" /> Importance <select id=\\\\\\"t1\\\\\\" name=\\\\\\"t1\\\\\\"><option value=\\\\\\"notes\\\\\\">Notes</option>\\\\n<option value=\\\\\\"highlighted\\\\\\">Highlighted text</option>\\\\n<option value=\\\\\\"normal\\\\\\">Normal text</option></select>\\\\n\\\\t\\\\t<remove><a href=\\\\\\"#\\\\\\" onclick=\\\\\\"this.up(\\'.text\\').remove(); return false;\\\\\\">Remove text field</a></remove>\\\\n\\\\t</p>\\\\n</div>\\" });\\nnew Effect.Highlight(\\"group\\",{duration:0.3, startcolor:\\'#34d85e\\'});'); throw e }; return false;\">Add a text field</a></add>\n\t\t<remove><a href=\"#\" onclick=\"this.up('.elements').remove(); return false;\">Remove text group</a></remove>\n\t</p>\n\t\n\t\n<div class='text'>\n\t<p>\n\t\tText <input id=\"content\" name=\"content\" size=\"50\" type=\"text\" /> Importance <select id=\"t1\" name=\"t1\"><option value=\"notes\">Notes</option>\n<option value=\"highlighted\">Highlighted text</option>\n<option value=\"normal\">Normal text</option></select>\n\t\t<remove><a href=\"#\" onclick=\"this.up('.text').remove(); return false;\">Remove text field</a></remove>\n\t</p>\n</div>\n</div>" });
new Effect.Highlight("group",{duration:0.3, startcolor:'#34d85e'});
} catch (e) { alert('RJS error:\n\n' + e.toString()); alert('Element.insert(\"groups\", { bottom: \"<p></p>\\n<div id=\\\"group\\\" class=\'elements\'>\\n\\t<p>\\n\\t\\t<g_title>Text Group</g_title>\\n\\t\\t<add><a href=\\\"#\\\" onclick=\\\"try {\\nElement.insert("group", { bottom: "\\\\n<div class=\'text\'>\\\\n\\\\t<p>\\\\n\\\\t\\\\tText <input id=\\\\"content\\\\" name=\\\\"content\\\\" size=\\\\"50\\\\" type=\\\\"text\\\\" /> Importance <select id=\\\\"t1\\\\" name=\\\\"t1\\\\"><option value=\\\\"notes\\\\">Notes</option>\\\\n<option value=\\\\"highlighted\\\\">Highlighted text</option>\\\\n<option value=\\\\"normal\\\\">Normal text</option></select>\\\\n\\\\t\\\\t<remove><a href=\\\\"#\\\\" onclick=\\\\"this.up(\'.text\').remove(); return false;\\\\">Remove text field</a></remove>\\\\n\\\\t</p>\\\\n</div>" });\\nnew Effect.Highlight("group",{duration:0.3, startcolor:\'#34d85e\'});\\n} catch (e) { alert(\'RJS error:\\\\n\\\\n\' + e.toString()); alert(\'Element.insert(\\\\"group\\\\", { bottom: \\\\"\\\\\\\\n<div class=\\\\\'text\\\\\'>\\\\\\\\n\\\\\\\\t<p>\\\\\\\\n\\\\\\\\t\\\\\\\\tText <input id=\\\\\\\\\\\\"content\\\\\\\\\\\\" name=\\\\\\\\\\\\"content\\\\\\\\\\\\" size=\\\\\\\\\\\\"50\\\\\\\\\\\\" type=\\\\\\\\\\\\"text\\\\\\\\\\\\" /> Importance <select id=\\\\\\\\\\\\"t1\\\\\\\\\\\\" name=\\\\\\\\\\\\"t1\\\\\\\\\\\\"><option value=\\\\\\\\\\\\"notes\\\\\\\\\\\\">Notes</option>\\\\\\\\n<option value=\\\\\\\\\\\\"highlighted\\\\\\\\\\\\">Highlighted text</option>\\\\\\\\n<option value=\\\\\\\\\\\\"normal\\\\\\\\\\\\">Normal text</option></select>\\\\\\\\n\\\\\\\\t\\\\\\\\t<remove><a href=\\\\\\\\\\\\"#\\\\\\\\\\\\" onclick=\\\\\\\\\\\\"this.up(\\\\\'.text\\\\\').remove(); return false;\\\\\\\\\\\\">Remove text field</a></remove>\\\\\\\\n\\\\\\\\t</p>\\\\\\\\n</div>\\\\" });\\\\nnew Effect.Highlight(\\\\"group\\\\",{duration:0.3, startcolor:\\\\\'#34d85e\\\\\'});\'); throw e }; return false;\\\">Add a text field</a></add>\\n\\t\\t<remove><a href=\\\"#\\\" onclick=\\\"this.up(\'.elements\').remove(); return false;\\\">Remove text group</a></remove>\\n\\t</p>\\n\\t\\n\\t\\n<div class=\'text\'>\\n\\t<p>\\n\\t\\tText <input id=\\\"content\\\" name=\\\"content\\\" size=\\\"50\\\" type=\\\"text\\\" /> Importance <select id=\\\"t1\\\" name=\\\"t1\\\"><option value=\\\"notes\\\">Notes</option>\\n<option value=\\\"highlighted\\\">Highlighted text</option>\\n<option value=\\\"normal\\\">Normal text</option></select>\\n\\t\\t<remove><a href=\\\"#\\\" onclick=\\\"this.up(\'.text\').remove(); return false;\\\">Remove text field</a></remove>\\n\\t</p>\\n</div>\\n</div>\" });\nnew Effect.Highlight(\"group\",{duration:0.3, startcolor:\'#34d85e\'});'); throw e }; return false;">Add new group</a></add></p>
<p></p>
<div id="group" class='elements'>
<p>
<g_title>Text Group</g_title>
<add><a href="#" onclick="try {
Element.insert("group", { bottom: "\n<div class='text'>\n\t<p>\n\t\tText <input id=\"content\" name=\"content\" size=\"50\" type=\"text\" /> Importance <select id=\"t1\" name=\"t1\"><option value=\"notes\">Notes</option>\n<option value=\"highlighted\">Highlighted text</option>\n<option value=\"normal\">Normal text</option></select>\n\t\t<remove><a href=\"#\" onclick=\"this.up('.text').remove(); return false;\">Remove text field</a></remove>\n\t</p>\n</div>" });
new Effect.Highlight("group",{duration:0.3, startcolor:'#34d85e'});
} catch (e) { alert('RJS error:\n\n' + e.toString()); alert('Element.insert(\"group\", { bottom: \"\\n<div class=\'text\'>\\n\\t<p>\\n\\t\\tText <input id=\\\"content\\\" name=\\\"content\\\" size=\\\"50\\\" type=\\\"text\\\" /> Importance <select id=\\\"t1\\\" name=\\\"t1\\\"><option value=\\\"notes\\\">Notes</option>\\n<option value=\\\"highlighted\\\">Highlighted text</option>\\n<option value=\\\"normal\\\">Normal text</option></select>\\n\\t\\t<remove><a href=\\\"#\\\" onclick=\\\"this.up(\'.text\').remove(); return false;\\\">Remove text field</a></remove>\\n\\t</p>\\n</div>\" });\nnew Effect.Highlight(\"group\",{duration:0.3, startcolor:\'#34d85e\'});'); throw e }; return false;">Add a text field</a></add>
<remove><a href="#" onclick="this.up('.elements').remove(); return false;">Remove text group</a></remove>
</p>
<div class='text'>
<p>
Text <input id="content" name="content" size="50" type="text" /> Importance <select id="t1" name="t1"><option value="notes">Notes</option>
<option value="highlighted">Highlighted text</option>
<option value="normal">Normal text</option></select>
<remove><a href="#" onclick="this.up('.text').remove(); return false;">Remove text field</a></remove>
</p>
</div>
</div>
</div>
<div class="button">
<p><next><a href="#" onclick="$(this).up('form').submit(); return false;">Next Step</a></next></p>
</div>
</form>
答案 0 :(得分:2)
我成功完成了这项工作。在我看来,这是Rails中的一个错误,因为使用了escape_once而不是html_escape。换句话说,第一个link_to_function被转义,但第二个不是,因为该字符串已经被转义。这使得反向操作(去逃逸或其他)不起作用。您可以将此代码添加到初始化程序以始终转义:
module ActionView
module Helpers
module TagHelper
private
def tag_options(options, escape = true)
unless options.blank?
attrs = []
if escape
options.each do |key, value|
next unless value
key = key.to_s
value = BOOLEAN_ATTRIBUTES.include?(key) ? key : ERB::Util::html_escape(value)
attrs << %(#{key}="#{value}")
end
else
attrs = options.map { |key, value| %(#{key}="#{value}") }
end
" #{attrs.sort * ' '}" unless attrs.empty?
end
end
end
end
end
此代码可能会破坏内容,因此请谨慎使用。但是,我已经读过可能在Rails 3.0中更改了escape_once,所以请保持手指交叉;)
答案 1 :(得分:0)
你做错了。这最终会在HTML属性中插入转义的部分转义和转义字符串。那简直就是邪恶。它有很多方法可以打破。
您可能想要考虑一种更简单的方法。将render :partial
置于link_to_function 'Add a group'
之上。隐藏div#group
,然后链接到$('group').show()
。
换句话说,将其隐藏起来,然后使用JavaScript显示它,而不是将其插入DOM中。更简单,更不容易出错。