Вот небольшой фрагмент, который проверяет значения с двух дисков и сравнивает их с общим доступным дисковым пространством.
Обратите внимание, что его необходимо изменить для работы с ЛЮБЫМ количеством входов размера и ЛЮБОЙколичество дисков.
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 функции - как и просили в комментарии ниже.