问题描述
我有一个用于@profile
实例的edit.html.erb
表单。
通常,当我加载表单时,表单内的输入会预先填充有实例的相应属性。
例如, <%= f.text_field :name %>
将从@profile.name
预先填充其值。
我想使用jQuery在运行时添加其他字段,该字段允许用户使用其他动态添加的输入来输入其他数据。
即@profile.subjects
是一个包含主题及其描述的哈希(例如,它可以是{"math" => "I teach calculus", "science" => "I have a physics degree"}
)
我从@profile.subjects
检索主题列表,并使用jQuery中的append()
将textarea
元素插入每个主题的表单中。
因此,如果@profile.subjects
包含“数学”和“科学”,我将在jQuery中执行以下操作:
var subject = *string containing subject*;
parent.append("<textarea id='profile_" + subject + "_desc' name='profile[" + subject + "_desc]'></textarea");
就我所知,这将模仿创建<%= f.text_area :math_desc %>
和<%= f.text_area :science_desc %>
。
但是,当我将math_desc
和science_desc
属性math_desc
给控制器中的实例变量@profile
时,与静态表单输入不同,输入不会预先填充其值。
我可以在视图中访问@profile.math_desc
和@profile.science_desc
,但我希望输入在视图加载时具有这些值。
我不知道如何将红宝石变量添加到带有变量作为属性名称的append()
参数中。
例如append("<textarea><%= @profile.send('math_desc') %></textarea>")
有效,但是append("<textarea><%= @profile.send('" + subject + "_desc') %></textarea>")
没有。
编辑1:
这是我为实例分配其他属性的方式:
# NOTE: @profile.subjects contains a string representation of {"Math" => "I teach calculus", "Science" => "I have a physics degree", ...}
def edit
@tutor = current_tutor
@profile = @tutor.profile
# Call method to parse subjects JSON
subject_parsing(@profile)
end
private
# Decode JSON subject field into a hash
def subject_parsing(profile)
unless profile.subjects.blank?
# Decode subjects into a hash
parsed_subjects = ActiveSupport::JSON.decode(profile.subjects)
# Extract subject names from hash into a string separated by commas
profile.subject_names = parsed_subjects.keys.join(', ')
parsed_subjects.each do |subj, desc|
subj = subj.downcase
profile.class_eval do
attr_accessor "#{subj}_desc"
end
profile.send("#{subj}_desc=", desc)
end
end
end
1楼
Richard
0
已采纳
2015-07-26 22:11:49
因此,我的解决方法是使用gon
gem将Rails哈希发送到Javascript,然后根据subject_names数组调用主题描述。
将此添加到控制器中(请参阅EDIT 1代码)
# Decode JSON subject field into a hash
def subject_parsing(tutor_profile)
unless tutor_profile.subjects.blank?
# Decode subjects into a hash TODO: change this because it is very slow
gon.subjects = ActiveSupport::JSON.decode(tutor_profile.subjects)
# Extract subject names from hash into a string separated by commas
tutor_profile.subject_names = gon.subjects.keys.join(', ')
end
end
然后以Javascript结尾:
var subjectNamesInput = $('#tutor_profile_subject_names');
// Initialize subject description input boxes
$.each(subjectNamesInput.tagsinput('items'), function(i, subject){
updateSubjectInputs(subject, 'add');
});
function updateSubjectInputs(subject, action){
var parent = $('#subject-description-inputs');
var subject = escape(subject);
var text = "";
if (gon.subjects[subject] != undefined)
text = gon.subjects[subject];
if (action == 'add'){
parent.append("<textarea id='tutor_profile_" + subject.toLowerCase() + "_description' name='tutor_profile[" +
subject.toLowerCase() + "_description]' class='form-control form-text-area' rows='5' placeholder='Add some detail about your experience with " + subject +
" (optional)'>" + text + "</textarea>");
}
else if (action == 'remove'){
$('#tutor_profile_' + subject.toLowerCase() + '_description').remove();
}
}
我认为这是:
<%= f.text_field :subject_names, class: 'form-control tagsinput typeahead', placeholder: 'Subjects you teach' %>
<div id="subject-description-inputs">
</div>