在Javascript表单生成器中动态设置输入字段名称和ID

时间:2017-05-26 17:33:52

标签: javascript forms generator hierarchy

我正在创建一个非常简单的表单生成器,它接受字段模式和数据并输出HTML。我已经有一个工作代码,即使在嵌套时也能正确显示字段,但现在我想根据层次结构和当前迭代设置每个字段idname

这是代码的小提琴: https://jsfiddle.net/vboanh4d/

层次结构实现效果不佳,因为 - 例如 - 图像字段同时获得幻灯片图片(本身?!)父母,虽然它应该只有幻灯片。我认为问题在于递归,但是我不能理解它,我也无法想到一种有效的方法来将当前索引添加到id / name以使它们成为唯一且与之相关的他们的父母。

模板和渲染功能:

// Templates
const templates = {
  group: (field) => {
    field.value = field.value || {}

    // Render sub-fields
    let fields = render(field.fields, field.value, field)

    return `
      <div class="t-field t-field--group">
        <div class="t-field-label">
          ${field.id}: ${JSON.stringify(field.hierarchy)}
        </div>
        <div class="t-field-content">
          ${fields}
        </div>
      </div>
    `
  },
  text: (field) => {
    field.value = field.value || ''

    return `
      <div class="t-field t-field--text">
        <div class="t-field-label">
          ${field.id}: ${JSON.stringify(field.hierarchy)}
        </div>
        <div class="t-field-content">
          <input type="text" id="${field.id}" value="${field.value}">
        </div>
      </div>
    `
  }
}

// Render field(s)
// field: (field object || array of field objects)
const render = (field, data, parent) => {
  let template = templates[field.type]

  // Handle multiple fields
  if (field.length) {
    data = data || {}
    return field.map(field => render(field, data[field.id], parent)).join('')
  }

  // Render the template
  if (template) {
    field.value = data || field.value

    // If a parent is set, add it to the current field's hierarchy
    // This is not working properly for some reason...
    if (parent) {
      field.hierarchy = parent.hierarchy || []
      if (field.hierarchy.indexOf(parent.id) < 0) {
        field.hierarchy.push(parent.id)
      }
    }

    if (field.type === 'group' || field.fields || field.repeat || field.multiple) {
      let values = field.value || []
      let output = ''
      for (let i in values) {
        field.value = values[i]
        output += template(field) // Recursion
        field.value = null // Reset field value for next iterations
      }

      return output
    } else {
      return template(field)
    }
  }

  // Return an empty string if no template is available for the current field type
  return ''
}

字段架构和数据:

// Fields schema
var fields = [
  {
    id: 'slides',
    type: 'group',
    repeat: true,
    fields: [
      {
        id: 'title',
        type: 'text'
      },
      {
        id: 'images',
        type: 'group',
        repeat: true,
        fields: [
          {
            id: 'imageTitle',
            type: 'text'
          }
        ]
      }
    ]
  }
]

// Fields data
var data = {
  slides: [
    { title: 'Title 1', images: [{imageTitle: 'one'}, {imageTitle: 'two'}, {imageTitle: 'three'}] },
    { title: 'Title 2' },
    { title: 'Title 3' },
  ]
}

var output = render(fields, data)

output包含字段HTML,我的目的是将字段ID / name正确设置为具有如下所示的表单post对象:

slides[0]
  slides[0][title]
  slides[0][images]
  slides[0][images][imageTitle][0]
  slides[0][images][imageTitle][1]
  slides[0][images][imageTitle][2]

slides[1]
  slides[1][title]

slides[2]
  slides[2][title]

0 个答案:

没有答案