提问人:Hakeem Baba 提问时间:8/5/2023 更新时间:8/5/2023 访问量:63
基于json数据元素动态创建表单
Create a form dynamically based on the elements of json data
问:
在我的 rails 应用程序中。我有一个新的.html.erb,内容如下
<div class="container align-items-center">
<br>
<br>
<div class="col-sm-9">
<label for="workspaceSelect" class="form-label">Workspace</label>
<select id="workspaceSelect" class="form-select form-select-lg mb-3" aria-label=".form-select-lg example">
<option value="" disabled selected>Select your workspace</option>
<% @workspaces.each do |workspace| %>
<option value="<%= workspace['gid'] %>"><%= workspace['name'] %></option>
<% end %>
</select>
<div id="projectsFormContainer" style="display: none;">
<label for="projectsSelect" class="form-label">Projects</label>
<select id="projectsSelect" class="form-select form-select-lg mb-3" aria-label=".form-select-lg example">
</select>
</div>
<div id="formForProjectContainer" style="display: none;">
<label for="selectOption" class="form-label">Name</label>
<select id="selectOption" class="form-select form-select-lg mb-3" aria-label=".form-select-lg example">
<option value="" disabled selected>Select an option</option>
<option value="madrid">Madrid</option>
<option value="milan">Milan</option>
</select>
<label for="selectDueDate" class="form-label">Due Date</label>
<select id="selectDueDate" class="form-select form-select-lg mb-3" aria-label=".form-select-lg example">
<option value="" disabled selected>Select an option</option>
<option value="date_created">Created At</option>
</select>
<label for="selectAssignee" class="form-label">Assignee</label>
<select id="selectAssignee" class="form-select form-select-lg mb-3" aria-label=".form-select-lg example">
<option value="" disabled selected>Select an assignee</option>
<!-- Options will be dynamically populated from the 'fields_for_project' endpoint -->
</select>
</div>
</div>
</div>
<script>
document.addEventListener('DOMContentLoaded', function() {
const workspaceSelect = document.getElementById('workspaceSelect');
const projectsFormContainer = document.getElementById('projectsFormContainer');
const projectsSelect = document.getElementById('projectsSelect');
const formForProjectContainer = document.getElementById('formForProjectContainer');
const selectDueDate = document.getElementById('selectDueDate');
const selectAssignee = document.getElementById('selectAssignee');
function fetchProjectsForWorkspace(workspaceId) {
return fetch(`/projects_for_workspace?workspace_id=${workspaceId}`)
.then(response => response.json());
}
function populateProjectsSelect(data) {
projectsSelect.innerHTML = '<option value="" disabled selected>Select a project</option>';
data.forEach(project => {
const option = document.createElement('option');
option.value = project.gid;
option.textContent = project.name;
projectsSelect.appendChild(option);
});
}
function fetchMembersForProject(projectId) {
return fetch(`/fields_for_project?project_id=${projectId}`)
.then(response => response.json());
}
function populateMemberSelect(data) {
selectAssignee.innerHTML = '<option value="" disabled selected>Select an assignee</option>';
data.forEach(member => {
const option = document.createElement('option');
option.value = member.gid;
option.textContent = member.name;
selectAssignee.appendChild(option);
});
}
workspaceSelect.addEventListener('change', function() {
const selectedWorkspaceId = workspaceSelect.value;
if (selectedWorkspaceId) {
fetchProjectsForWorkspace(selectedWorkspaceId)
.then(data => {
populateProjectsSelect(data);
projectsFormContainer.style.display = 'block';
})
.catch(error => {
console.error('Error fetching projects:', error);
});
} else {
projectsFormContainer.style.display = 'none';
formForProjectContainer.style.display = 'none';
}
});
projectsSelect.addEventListener('change', function() {
const selectedProjectValue = projectsSelect.value;
if (selectedProjectValue) {
formForProjectContainer.style.display = 'block';
fetchMembersForProject(selectedProjectValue)
.then(data => {
populateMemberSelect(data);
selectAssignee.style.display = 'block'; // Show the Assignee select element
})
.catch(error => {
console.error('Error fetching members:', error);
});
} else {
formForProjectContainer.style.display = 'none';
selectAssignee.style.display = 'none'; // Hide the Assignee select element
}
});
});
</script>
我在控制器中有这个方法,
def custom_fields
project_id = params[:project_id]
response = HTTParty.get(
"https://app.asana.com/api/1.0/projects/#{project_id}",
headers: {
'Content-Type': 'application/json',
'Authorization': "Bearer #{access_token}"
}
)
custom_fields_data = JSON.parse(response.body)['data']['custom_field_settings']
custom_fields = custom_fields_data.map do |custom_field|
{
gid: custom_field['custom_field']['gid'],
name: custom_field['custom_field']['name']
}
end
render json: custom_fields
end
呈现的自定义字段 json 如下所示
{:gid=>"redacted_id", :name=>"Task Progress"}
{:gid=>"redacted_id", :name=>"Fulfilment Status"}
为了从控制器派生自定义字段,我将将其添加到视图脚本中
function fetchCustomFieldsForProject(projectId) {
return fetch(`/custom_fields?project_id=${projectId}`)
.then(response => response.json());
}
现在,当用户选择一个项目时,我将尝试遍历custom_fields json,并使用 :name 作为表单的标签为 json 中的每个元素创建一个表单,并选择输入为“madrid”、“milan”。我该怎么做?
答: 暂无答案
评论