const current = ref(props.value);
emits("change", current);
@change="changeCount"
function changeCount(value) { count.value = value; }
emits("change", current);
---> emits("change", current.value);
formatDate(date) {
const today = new Date();
return [ 'getFullYear', 'getMonth', 'getDate' ].every(n => date[n]() === today[n]())
? 'Today'
: flatpickr.formatDate(date, 'j M');
},
const groupSelector = 'fieldset.js-tree-box';
const mainSelector = 'legend input';
const itemSelector = 'legend + span input';
const activeClass = 'active';
document.addEventListener('change', ({ target: t }) => {
const group = t.closest(groupSelector);
if (group) {
const main = group.querySelector(mainSelector);
const items = [...group.querySelectorAll(itemSelector)];
if (main === t) {
items.forEach(n => n.checked = t.checked);
} else {
const numChecked = items.reduce((acc, n) => acc + n.checked, 0);
main.checked = numChecked === items.length;
main.indeterminate = 0 < numChecked && numChecked < items.length;
}
group.classList.toggle(activeClass, main.checked);
}
});
const sorted = (data, key) => Array
.from(data, n => [ n, key(n) ])
.sort((a, b) => a[1] - b[1])
.map(n => n[0]);
document.querySelector('.result').append(...sorted(
document.querySelector('.data').cloneNode(true).children,
n => +n.innerText
));
делегирование не работает
в консоли выдает "e.target.closest is not a function"
const hoverCellNum = hoverCell.getAttribute('data-tdnum');
document.addEventListener('mouseenter', ({ target: t }) => {
if (t.matches?.('td._hight-light__cell')) {
t.closest('tbody').querySelectorAll('.table-big__row').forEach(n => {
n.cells[t.cellIndex].classList.add('_hover');
});
}
}, true);
document.addEventListener('mouseleave', e => {
if (e.target.matches?.('td._hight-light__cell')) {
document.querySelectorAll('._hover').forEach(n => n.classList.remove('_hover'));
}
}, true);
document.addEventListener('click', updateCounter);
document.addEventListener('input', updateCounter);
document.querySelectorAll('.tariff__counter').forEach(n => {
const max = n.dataset.seats;
n.querySelectorAll('.tariff__counter-max').forEach(m => m.innerText = max);
n.querySelectorAll('.amount').forEach(m => m.max = max);
n.querySelectorAll('button').forEach(m => m.dataset.change = m.innerText === '+' ? 1 : -1);
});
function updateCounter({ target: t }) {
const input = t.closest('.tariff__counter-block')?.querySelector('.amount');
if (input) {
const { min, max, value } = input;
input.value = Math.max(min, Math.min(max, (value | 0) + (t.dataset.change | 0)));
}
}
const [posts, setPosts] = useState([]);
setPosts(fetchReq);
const fetchReq = fetch(`${fetchURL}/posts`).then(res => res.json());
fetch(`${fetchURL}/posts`)
.then(r => r.json())
.then(setPosts);
const amounts = [ 5, 10, 15 ];
const [ amount, setAmount ] = useState(null);
const [ isCustomAmount, setIsCustomAmount ] = useState(false);
{amounts.map(n => (
<label>
<input
type="radio"
disabled={isCustomAmount}
checked={amount === n && !isCustomAmount}
onChange={() => setAmount(n)}
/>
${n}
</label>
))}
<label>
<input
type="checkbox"
checked={isCustomAmount}
onChange={e => (setAmount(null), setIsCustomAmount(e.target.checked))}
/>
Другая сумма
</label>
{isCustomAmount && <input value={amount} onChange={e => setAmount(+e.target.value)} />}
<input type="hidden" name="amountusd" value={amount} />
const keys = [ 'id', 'secondId' ];
const result = firstArray.map(n => secondArray.find(m => keys.every(k => n[k] === m[k])) ?? n);
const arrToTree = (arr, keys) =>
arr.reduce((acc, n) => (
keys.reduce((p, c, i) => p[n[c]] ??= i + 1 === keys.length ? n : {}, acc),
acc
), {});
const keys = [ 'id', 'secondId' ];
const tree = arrToTree(secondArray, keys);
const result = firstArray.map(n => keys.reduce((p, c) => p?.[n[c]], tree) ?? n);
const arrToTree = (arr, keys) =>
arr.reduce((acc, n) => (
keys(n).reduce(
(p, c, i, a) => p.set(c, p.get(c) ?? (-~i === a.length ? n : new Map)).get(c),
acc
),
acc
), new Map);
const keys = n => [ n.id, n.secondId ];
const result = firstArray.map(function(n) {
return keys(n).reduce((p, c) => p?.get(c), this) ?? n;
}, arrToTree(secondArray, keys));
function getUrls($tree, $url = '') {
$urls = [];
foreach ($tree as $n) {
$newUrl = ($url ? $url.'/' : '').$n->url;
array_push($urls, $newUrl, ...getUrls($n->subcategories ?? [], $newUrl));
}
return $urls;
}
input
, чтобы v-model
обновил данные компонента:methods: {
removeLastChar({ target: t }) {
t.value = t.value.slice(0, -1);
t.dispatchEvent(new Event('input'));
},
...
},
<input
@focus="removeLastChar"
...
>
function getLeaves(tree) {
const result = [];
for (const stack = [...tree]; stack.length;) {
const n = stack.pop();
if (Array.isArray(n.children) && n.children.length) {
stack.push(...n.children);
} else {
result.push(n);
}
}
return result.reverse();
}
function getLeaves(tree) {
const result = [];
const stack = [];
for (let arr = tree, i = 0; i < arr.length || stack.length; i++) {
if (i === arr.length) {
[ i, arr ] = stack.pop();
} else if (arr[i].children instanceof Array && arr[i].children.length) {
stack.push([ i, arr ]);
[ i, arr ] = [ -1, arr[i].children ];
} else {
result.push(arr[i]);
}
}
return result;
}
function getLeaves([...tree]) {
for (let i = 0; i < tree.length; i++) {
const c = tree[i].children;
if (c?.constructor === Array && c.length) {
tree.splice(i--, 1, ...c);
}
}
return tree;
}
const groupSum = (arr, idKey, ...sumKeys) =>
Object.values(arr.reduce((acc, n) => (
acc[n[idKey]] ??= sumKeys.reduce((group, k) => (
group[k] = 0,
group
), Object.assign(new n.constructor, n)),
sumKeys.forEach(k => acc[n[idKey]][k] += n[k]),
acc
), {}));
// ваш случай
const result = groupSum(arr, 'product', 'price', 'selling_price', 'quantity');
// элементам исходного массива не обязательно быть объектами, это могут быть и массивы
groupSum([
[ 'A', 1, 10 ],
[ 'A', 2, 20 ],
[ 'A', 3, 30 ],
[ 'B', 1, 5 ],
[ 'B', 10, 5 ],
[ 'B', 100, 5 ],
], 0, 1, 2) // [ [ 'A', 6, 60 ], [ 'B', 111, 15 ] ]
[
[ '.btn-all', 'click', onGetDataClick ],
[ '.elem button', 'click', onPlusMinusClick ],
[ '.amount', 'input', onAmountInput ],
].forEach(([ selector, type, handler ]) => {
document.querySelectorAll(selector).forEach(n => n.addEventListener(type, handler));
});
function onGetDataClick(e) {
const data = Array.prototype.flatMap.call(
e.target.closest('.child-block').querySelectorAll('.elem'),
n => Array(+n.querySelector('.amount').value).fill(+n.dataset.id)
);
console.log(data);
}
function onPlusMinusClick({ target }) {
const input = target.closest('.elem').querySelector('.amount');
input.value -= target.innerText === '+' ? -1 : 1;
input.dispatchEvent(new Event('input'));
}
function onAmountInput({ target: t }) {
t.value = Math.max(t.min, Math.min(t.max, t.value | 0));
}