首页 > 解决方案 > 根据 jQuery 在对象中写入的属性,将生成的元素从 Object 中放入正确的 div

问题描述

有一个对象。Order,block并且Position是这样为对象元素编写的:

var formObj = {
  username: {
    value: null,
    type: 'text',
    label: 'Username',
    placeholder: 'Enter username',
    position: 'left',
    block: 'firstRow',
    order: 1,
    additionalClass: 'user'
  },
  message: {
    value: null,
    type: 'textarea',
    label: 'Message',
    placeholder: 'type your message',
    position: 'left',
    block: 'secondRow',
    order: 3,
  },
}

输入从对象生成并存储在名为的变量中html

var html = '';
$.each(formObj, function(key, value) { 
   var html = '';
   html += '<input name="' + key + '" type="' + value.type + '" value="' + value.value + '" placeholder="' + value.placeholder + '"' + classMarkup + addedAttrs + '/>';
return html;
})

在我的 html 中,有两行名为first-rowsecond-row。每行有两列:left-colright-col

生成的输入元素需要根据block, position&放置order。所以,如果一个对象有order: 2, position: 'left', block: 'firstRow' 而另一个对象有order: 1, position: 'left', block: 'firstRow',那么这两个对象都在下面div.first-rowdiv.left-col第二个对象进入一阶,第一个对象进入二阶。我试图以这种方式生成它:

var firstLeft = [],
    firstRight = [],
    secondLeft = [],
    secondRight = [];
function columnPosition(row, column) {
    if (row === 'firstRow' && column === 'left') {
       firstLeft.push(html);
       $('.first-row .left-col').append(firstLeft);
  } else if (row === 'firstRow' && column === 'right') {

  } else if (row === 'secondRow' && column === 'left') {

  } else if (row === 'secondRow' && column === 'left') {

  }

}
// sort by order function
function sortByOrder (array,key) {
    return array.sort(function (a, b) {
    var x = a[key];
    var y = b[key];
    return ((x < y) ? -1 : ((x > y) ? 1 : 0));
});
}

但是,我无法正确编写此函数。如何实现这个功能?

小提琴演示

标签: jquery

解决方案


我没有重复使用你所有的小提琴,我只是以你给我们的为例。

当你可以做的更简单时,你变得复杂了:

  • 使用数组而不是对象,更容易对其进行排序。for...in在这里,我编写了一个函数来使用语句切换到排序数组。

  • 然后我用 . 遍历每个表单对象Array#forEach。我在函数字段类型的每次迭代中创建了相应的元素(我没有你自己的函数,但是当你调整我的代码片段时使用它)。最后,我找到了将创建的元素附加到jQuery#find.

const formObj = {
  username: {
    value: null,
    type: 'text',
    label: 'Username',
    placeholder: 'Enter username',
    position: 'left',
    block: 'firstRow',
    order: 1,
    additionalClass: 'user'
  },
  password: {
    value: null,
    type: 'password',
    label: 'Password',
    placeholder: 'enter password',
    position: 'left',
    block: 'firstRow',
    order: 2
  },
  country: {
    value: null,
    type: 'select',
    label: 'Where are you form?',
    defaultText: 'Choose here',
    position: 'right',
    block: 'firstRow',
    order: 2,
    option: [{
        value: '1',
        label: 'Australia'
      },
      {
        value: '2',
        label: 'USA'
      },
      {
        value: '3',
        label: 'UK'
      }
    ]
  },
  gender: {
    value: 'other',
    type: 'select',
    label: 'Gender',
    defaultText: null,
    position: 'right',
    block: 'firstRow',
    order: 1,
    option: [{
        value: 'male',
        label: 'Male'
      },
      {
        value: 'female',
        label: 'Female'
      },
      {
        value: 'other',
        label: 'Other',
        additionalAttr: 'disabled'
      }
    ]
  },
  decision: {
    value: 'not sure',
    type: 'radio',
    label: 'Have you enjoyed it?',
    position: 'left',
    block: 'secondRow',
    order: 1,
    option: [{
        value: 'yes',
        label: 'Yes',
        additionalAttr: 'disabled'
      },
      {
        value: 'no',
        label: 'No',
      },
      {
        value: 'not sure',
        label: 'I am not sure',
      }
    ]
  },
  message: {
    value: null,
    type: 'textarea',
    label: 'Message',
    placeholder: 'type your message',
    position: 'left',
    block: 'secondRow',
    order: 3,
  },
  vehicle: {
    value: null,
    type: 'checkbox',
    label: 'Preferred vehicles',
    position: 'left',
    block: 'secondRow',
    order: 2,
    option: [{
        value: 'car',
        label: 'I like car'
      },
      {
        value: 'bike',
        label: 'I prefer bike'
      },
      {
        value: 'boat',
        label: 'Boat is my favorit'
      }
    ]
  },
  email: {
    value: null,
    type: 'text',
    label: 'Email',
    placeholder: 'Enter email',
    position: 'right',
    block: 'secondRow',
    order: 2,
    additionalAttr: 'disabled',
    additionalClass: 'emailbox custom'
  }
};

fieldListObjectToArray(formObj).forEach((field) => {
  const jForm = $('.form'),
    jElement = createElement(field);
  
  // Appends the newly created element to the right place.
  jForm
    .find(`.${field.block.replace('Row', '-row')}`)
    .find(`.${field.position}-col`)
    .append(jElement);
});

/**
 * Transforms your form object into an array one for easier usage.
 */
function fieldListObjectToArray(fieldObj) {
  let fieldArr = [];
  
  for (let key in fieldObj) {
    const field = fieldObj[key];
    
    // Adds to the array the original object with more one key "id" (= to the object key).
    fieldArr.push({
      id: key,
      ...field
    });
    
    // Sorts in ASC order.
    fieldArr.sort((a, b) => (a.order - b.order));
  }
  
  return fieldArr;
}

/**
 * Creates an element in function of the given {field}'s type.
 */
function createElement(field) {
  let jElement;

  switch (field.type) {
    case 'select':
      jElement = createSelectElement(field);
      break;
  
    case 'textarea':
      jElement = createTextareaElement(field);
      break;
  
    case 'radio':
    case 'checkbox':
      jElement = createCheckboxRadioElement(field);
      break;
  
    default:
      jElement = createInputElement(field);
  }
  
  if(!['checkbox', 'radio'].includes(field.type)) {
    jElement.addClass(field.additionalClass || '');
  }
  
  if (field.additionalAttr) {
    for (let attr of field.additionalAttr.split(' ')) {
      jElement.attr(attr, attr);
    }
  }
  
  return $('<label>').text(field.label).append(jElement);
}

/**
 * Creates an <input> element from object.
 */
function createInputElement(field) {
  return $('<input>')
    .attr('type', field.type)
    .attr('name', field.id)
    .attr('placeholder', field.placeholder)
    .val(field.value);
}

/**
 * Creates an <input type="checkbox/radio"> element from object.
 */
function createCheckboxRadioElement(field) {
  const jElements = [];
    
  // Inputs.
  for (let option of field.option) {
    const jElement = $('<input>')
      .attr('type', field.type)
      .attr('name', field.id)
      .val(option.value);
      
    if (field.type === 'checkbox') {
      jElement.attr('name', `${field.id}[]`);
    }
      
    if (option.additionalAttr) {
      for (let attr of option.additionalAttr.split(' ')) {
        jElement.attr(attr, attr);
      }
    }
    
    if (field.value === option.value) {
      jElement.prop('checked', true);
    }
    
    jElements.push($('<span>').text(option.label).prepend(jElement));
  }
  
  return jElements;
}

/**
 * Creates a <textarea> element from object.
 */
function createTextareaElement(field) {
  return $('<textarea>')
    .attr('name', field.id)
    .attr('placeholder', field.placeholder)
    .val(field.value);
}

/**
 * Creates a <select> element from object.
 */
function createSelectElement(field) {
  const jElement = $('<select>')
    .attr('name', field.id);
    
  // Default option.
  if (field.defaultText) {
    $('<option>')
      .text(field.defaultText)
      .prop('selected', true)
      .prop('disabled', true)
      .appendTo(jElement);
  }
  
  // Options.
  for (let option of field.option) {
    const jOption = $('<option>')
      .val(option.value)
      .text(option.label);
      
    if (option.additionalAttr) {
      for (let attr of option.additionalAttr.split(' ')) {
        jOption.attr(attr, attr);
      }
    }
    
    if (field.value === option.value) {
      jOption.prop('selected', true);
    }
    
    jOption.appendTo(jElement);
  }
  
  return jElement;
}
.second-row {
  border-top: 1px solid #aaa;
  margin-top: 50px;
  padding-top: 30px;
}

button {
  margin-top: 30px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script>
<div class="container">
  <h2>Form</h2>
  <form class="form">
    <div class="row first-row">
      <div class="col-sm-6">
        <div class="left-col">
          <h4>Left Column</h4>
        </div>
      </div>
      <div class="col-sm-6">
        <div class="right-col">
          <h4>right Column</h4>
        </div>
      </div>
    </div>
    
    <div class="row second-row">
      <div class="col-sm-6">
        <div class="left-col">
          <h4>Left Column</h4>
        </div>
      </div>
      <div class="col-sm-6">
        <div class="right-col">
          <h4>right Column</h4>
        </div>
      </div>
    </div>
    <button type="submit" class="btn btn-primary">Submit</button>
  </form>
</div>


推荐阅读