基于json数据元素动态创建表单

Create a form dynamically based on the elements of json data

提问人:Hakeem Baba 提问时间:8/5/2023 更新时间:8/5/2023 访问量:63

问:

在我的 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”。我该怎么做?

JavaScript jQuery Ruby-on-Rails Ruby Ajax

评论


答: 暂无答案