Проблемы с суммой и родственниками родителей - PullRequest
0 голосов
/ 06 ноября 2019

У меня проблема с моим кодом, и я надеюсь, что вы мне поможете.

У меня есть форма, в которой вы должны выбрать максимальный размер диска и номера дисков родственника. Сумма номеров каждого диска не может быть больше, чем размер соответствующего диска. (Пожалуйста, смотрите изображение)

image explanation of the problem. 2 DISKs

Я много чего перепробовал, но у меня проблемы с формой (классы, запросы и т. Д.).

function check_number23() {
  let ProjectName = document.getElementById("resultsprojectname").innerHTML;

  var sizediskN1 = document.getElementsByClassName("sizediskN1");


  var value = Object.keys(sizediskN1).length;

  var disksizeN = document.getElementsByClassName("disksizeN");
  var disksizeNkey = Object.keys(disksizeN).length;



  for (var h = 0; h < value; h++) {
    var storagevalue = +sizediskN1[h].value;
  }
  alert(storagevalue);



  for (var j = 0; j < disksizeNkey; j++) {
    var storagemax = document.getElementsByClassName("disksizeN")[j].value;

    if (storagevalue - storagemax <= 0) {
      result = storagevalue + " GiB of Standard Partitions can be used.";
      document.getElementsByClassName("negativenumberchecker23")[h].innerHTML = result;
    } else {
      result = storagevalue + " GiB of Standard Partitions can't be used. Insert a new value.";
      alert(result);
      sizediskN1[h].value = '0';
    }
  }
}
<label>Disk Size (GiB)</label> <input class="form-control disksizeO" type='number' min="1" onchange="check_numberDSKSizeO(this)" name='disksizeO[]' oninput="validity.valid||(value='0');" value='0' />
<label>Size (GiB):</label>
<input type='number' min="0" oninput="validity.valid||(value='0' onchange=" check_number23(this) " name='sizediskN1[]'  class='sizediskN1 form-control'>

Я надеюсь, что моя проблема ясна ... Пожалуйста, помогите ..

1 Ответ

0 голосов
/ 06 ноября 2019

Вот небольшой фрагмент, который проверяет значения с двух дисков и сравнивает их с общим доступным дисковым пространством.

Обратите внимание, что его необходимо изменить для работы с ЛЮБЫМ количеством входов размера и ЛЮБОЙколичество дисков.

const inpDiskSize = document.getElementById('disk-size')
const inpSize1 = document.getElementById('size1')
const inpSize2 = document.getElementById('size2')
let checkDisplay = true

// checking values and returning TRUE/FALSE
const checkValues = (dSize, sizeArr) => {
  return dSize >= sizeArr.reduce((a, c) => a + c, 0)
}

// transforming data from UI to the checking function
const changeEvent = (inpDiskSize, inpSizeArr) => {
  return checkValues(inpDiskSize.value, inpSizeArr.map(e => Number(e.value) || 0))
}

// displaying text
const displayText = (d) => {
  let r = ''
  if (d) {
    r = "You can have these partitions."
  } else {
    r = "You can NOT have these partitions."
  }
  document.getElementById('checkDisplay').textContent = r
}

// change event listener registrations
inpDiskSize.addEventListener('change', function(e) {
  displayText(changeEvent(inpDiskSize, [inpSize1, inpSize2]))
})
inpSize1.addEventListener('change', function(e) {
  displayText(changeEvent(inpDiskSize, [inpSize1, inpSize2]))
})
inpSize2.addEventListener('change', function(e) {
  displayText(changeEvent(inpDiskSize, [inpSize1, inpSize2]))
})
<label>Disk Size (GiB)</label>
<input id="disk-size" class="form-control disksizeO" type='number' min="1" name='disksizeO[]' oninput="validity.valid||(value='0');" value='0' />
<br />
<label>Size1 (GiB):</label>
<input id="size1" type='number' min="0" oninput="validity.valid||(value='0')" name='sizediskN1[]' class='sizediskN1 form-control' />
<br />
<label>Size2 (GiB):</label>
<input id="size2" type='number' min="0" oninput="validity.valid||(value='0')" name='sizediskN1[]' class='sizediskN1 form-control' />
<br />
<br />
<div id="checkDisplay"></div>

РЕДАКТИРОВАТЬ

Я предположил, что это должно / может быть решено по-другому.

Вот фрагмент:

const msgArr = [
  'You can NOT have this configiration',
  'You can have this configiration'
]

// array of disk objects
const disks = [{
  diskId: 0,
  maxSize: 5,
  rels: [{
    size: 1
  }, {
    size: 2
  }],
  msg: 'You can have this configiration'
}, {
  diskId: 1,
  maxSize: 3,
  rels: [{
    size: 3
  }, {
    size: 4
  }],
  msg: 'You can NOT have this configiration'
}]

// displaying the disks (creating an HTML template and
// appending it to the DOM)
function render(disks) {
  let html = ''
  disks.forEach(disk => {
    html += `<h4>DISK ${disk.diskId}</h4>`
    html += `<label for="disk-${disk.diskId}">disk-${disk.diskId}<input id="disk-${disk.diskId}" class="size-input" data-diskId="${disk.diskId}" type="number" value="${disk.maxSize}"/></label><br />`
    disk.rels.forEach((rel, i) => {
      const relId = `disk-${disk.diskId}-rel-${i}`
      html += `<label for="${relId}">${relId}<input id="${relId}" class="disk-rel size-input" data-diskId="${disk.diskId}" data-relId="${i}" type="number" value="${rel.size}"/></label><br />`
    })
    html += '<br />'
    html += `<div class="message">${disk.msg}</div>`
    html += '<br />'
  })
  document.getElementById('disksContainer').innerHTML = html
  addEventListenersToInputs('.size-input')
}

// rendering the disks first time
render(disks)

// adding event listeners to input fields
function addEventListenersToInputs(selector) {
  const inputs = document.querySelectorAll(selector)
  inputs.forEach(e => {
    e.addEventListener('change', function(e) {
      const diskId = this.getAttribute('data-diskId')
      updateValues(diskId, disks)
      render(disks)
    })
  })
}

// checking a single disk
function checkValue(disk) {
  return disk.rels.reduce((a, c) => a + Number(c.size), 0) <= disk.maxSize
}

// mutate the disks object
function updateValues(diskId, disks) {
  const els = document.querySelectorAll(`[data-diskId="${diskId}"]`)
  const disk = disks.find(e => {
    return Number(e.diskId) === Number(diskId)
  })

  els.forEach(el => {
    if (el.getAttribute('id') === `disk-${disk.diskId}`) {
      disk.maxSize = el.value
    } else {
      disk.rels[Number(el.getAttribute('data-relId'))].size = el.value
    }
  })
  disk.msg = msgArr[Number(checkValue(disk))]
}
<div id="disksContainer"></div>

Основное отличие от предыдущего решения заключается в том, что диски записаны в DOM, но они «хранятся» в массиве объектов JavaScript. Отображаемый HTML-код представляет собой «шаблон» JS, который добавляется в DOM - его можно изменить проще (однако JS не полностью отделен от DOM).

Это решение работает с ЛЮБЫМ числом дисков, содержащихЛЮБОЕ число связанных разделов.

Код может быть немного длиннее, чем первое решение, и кажется, что он более сложен, но это потому, что HTML был помещен в JS, и он должен был работать с несколькими / любымколичество дисков.

РЕДАКТИРОВАТЬ 2

И еще кое-что совершенно другое: современный каркас JS.

VueJS

Vue.component('disk', {
  props: ['disk'],
  data() {
    return {
      valid: 1,
      msg: [
        'You can NOT have this configuration.',
        'You can have this configuration.'
      ]
    }
  },
  template: `
    <div>
      <button @click="$emit('remove-disk', disk.id)">REMOVE DISK</button><br />
      <input type="number" :value="disk.maxSize" @change="setValue($event.target.value, 0)"/><button @click="addRel()">Add rel</button><br />
      <div :key="rel.id" v-for="rel in disk.rels">
        <input type="number" :value="rel.size" @change="setValue($event.target.value, rel.id)"/><button @click="removeRel(disk.id, rel.id)">REMOVE THIS REL</button>
      </div><br />
      {{msg[valid]}}
    </div>`,
  methods: {
    setValue(val, relId) {
      const emitVal = {
        val: val,
        diskId: this.disk.id,
        relId: relId
      }
      this.$emit('set-value', emitVal)
      this.valid = this.checkValues()
    },
    checkValues() {
      return Number(this.disk.rels.reduce((a, c) => {
        return a + Number(c.size)
      }, 0) <= this.disk.maxSize)
    },
    addRel() {
      this.$emit('add-rel', this.disk.id)
    },
    removeRel(diskId, relId) {
      this.$emit('remove-rel', {
        diskId,
        relId
      })
      this.valid = this.checkValues()
    }
  }
})


new Vue({
  el: "#app",
  data: {
    disks: []
  },
  methods: {
    addDisk() {
      const newDisk = {
        id: Date.now(),
        maxSize: 0,
        rels: []
      }
      this.disks.push(newDisk)
    },
    addRel(id) {
      this.disks.find(e => e.id === id)
        .rels.push({
          id: Date.now(),
          size: 0
        })
    },
    removeDisk(id) {
      this.disks = this.disks.filter(e => e.id !== id)
    },
    removeRel({
      diskId,
      relId
    }) {
      const disk = this.disks.find(e => e.id === diskId)
      disk.rels = disk.rels.filter(e => e.id !== relId)
    },
    setValue({
      val,
      diskId,
      relId
    }) {
      const disk = this.disks.find(e => e.id === diskId)
      if (relId === 0) {
        disk.maxSize = val
      } else {
        const rel = disk.rels.find(e => e.id === relId)
        rel.size = val
      }
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <button @click="addDisk">ADD DISK</button>
  <div v-for="disk in disks">
    <disk :key="disk.id" :disk="disk" @add-rel="addRel($event)" @set-value="setValue($event)" @remove-disk="removeDisk($event)" @remove-rel="removeRel($event)" />
  </div>
</div>

Это полностью динамический (ОК, элементы не удаляются) : обрабатывает любое количество дисков с любым количеством разделов.

РЕДАКТИРОВАТЬ 3

Я добавил удалить диск и удалить rel функции - как и просили в комментарии ниже.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...