toggleRow(index) {
this.setState(({ productsList, history }) => ({
productsList: productsList.map((n, i) => i === index
? { ...n, deleted: !n.deleted }
: n
),
history: [
...history,
{
currentDateInfo: new Date().toLocaleDateString(),
deleted: !productsList[index].deleted,
index,
},
],
}));
}
<ul className="list-group">
{this.state.history.map(n =>
<li className="list-group-item">
Row {n.index} {n.deleted ? 'deleted' : 'restored'} at {n.currentDateInfo}
</li>
)}
</ul>
document.querySelectorAll('tbody > tr').forEach(n => n.parentNode.prepend(n));
// или
const tbody = document.querySelector('tbody');
tbody.append(...Array.from(tbody.children).reverse());
// или
for (const n of [...document.querySelector('tbody').rows].reverse()) {
n.parentNode.appendChild(n);
}
// или
const tbody = document.querySelector('tbody');
for (let i = tbody.rows.length; i--;) {
tbody.insertAdjacentElement('beforeend', tbody.rows[i]);
}
Как я думал сделать:
По клику наdelete
делать поля Name и Idvisibility: none
и в стейте сделать переменнуюisDeleted: true
, если true то рендерить кнопку Restor'а, по клику на нее полям возвращатьvisibility
.
const ProductItem = ({ product, toggleRow }) => {
return (
<tr>
<th>{product.deleted || product.id}</th>
<td>{product.deleted || product.name}</td>
<td>
<button onClick={toggleRow}>
{product.deleted ? 'Restore' : 'Delete'}
</button>
</td>
</tr>
);
};
class Products extends React.Component {
state = {
products: [ 'Apple', 'Peanut', 'Tomato', 'Cucumber', 'Banana', 'Lemon' ].map((n, i) => ({
id: i + 1,
name: n,
deleted: false,
})),
}
toggleRow(index) {
this.setState(({ products }) => ({
products: products.map((n, i) => i === index
? { ...n, deleted: !n.deleted }
: n
),
}));
}
render() {
return (
<table>
<thead>
<tr>
<th>#</th>
<th>Product Name</th>
<th>Delete / Restore</th>
</tr>
</thead>
<tbody>
{this.state.products.map((n, i) => (
<ProductItem
key={n.id}
product={n}
toggleRow={() => this.toggleRow(i)}
/>
))}
</tbody>
</table>
);
}
}
return {
...state,
[action.title]: {
...state[action.title],
title: action.title,
},
};
Как из этого массива, создать новый массив, и чтобы в нем были значения из массива user, что-то типа такого массива должно получиться res = [5,12,2,22,'5,23',cost,'5',numbers,1,5,33,count,props,4,area,7];
const getKeysAndPrimitives = val =>
val instanceof Object
? [].concat(...(val instanceof Array
? val
: Object.entries(val)
).map(getKeysAndPrimitives))
: [ val ];
const result = getKeysAndPrimitives(user);
function* getKeysAndPrimitives(val) {
for (const stack = [ val ]; stack.length;) {
const n = stack.pop();
if (Object(n) === n) {
stack.push(...(Array.isArray(n)
? [...n]
: Array.prototype.concat.call([], Object.entries(n))
).reverse());
} else {
yield n;
}
}
}
const result = [...getKeysAndPrimitives(user)];
Есть ли способ для снятия чекбоксов таким же способом, если делать по аналогии выходит коряво ?
вот аналогия и вот почему коряво
https://codepen.io/sasha1998dmitalex/pen/OZbyYo
Попробовала показать работу тут.
Что делаю не так?
Как правильно подставить параметры в запрос
db.query(`
SELECT *
FROM table
WHERE id NOT IN ($(list:csv))
LIMIT $(limit)
`, obj)
Причем, если поле уже чем-то уже заполнено по умолчанию, то этот текст уже должен быть транслирован в параграф. Так-что ввод с клавиатуры отслеживать не подходит.
$('input').on('input', function() {
$('p').text($(this).val());
}).trigger('input');
// или
const input = document.querySelector('input');
const p = document.querySelector('p');
input.addEventListener('input', e => p.textContent = e.target.value);
input.dispatchEvent(new Event('input'));
что делать, если параграф содержит текст по умолчанию, который должен отображаться пока в поле ввода не начали что-то вводить?
Проще говоря, когда инпут пустой, надо отображать текст параграфа.
<p data-default-text="Текст по умолчанию"></p>
.$('p').text($(this).val() || $('p').data('default-text'));
// или
p.textContent = e.target.value || p.dataset.defaultText
Помогите пожалуйста написать учебный пример чтобы было видно действие и выгода инкапсуляции стилей. Мой вариант тут.
непонятно какое действие осуществляет метааргумент encapsulation: ViewEncapsulation.None
Есть корневой элемент и есть вложенный элемент. В каждом из них я отключил инкапсуляцию, но в результате к обоим применяются стили из первого. Где логика?
computed: {
categories() {
return this.$store.state.main_page.NEWS.map(n => ({
value: n.id,
label: n.name,
}));
},
},
deleteRow={() => this.deleteRow(i)}
deleteRow(index) {
const productsList = [...this.state.productsList];
productsList.splice(index, 1);
this.setState({
productsList,
});
}
const grouped = data
.reduce((acc, n, i, a) => {
if (i && n.id === a[i - 1].id + 1) {
acc[acc.length - 1][1][1] = n.id;
} else {
acc.push([ [], [ n.id ] ]);
}
acc[acc.length - 1][0].push(n);
return acc;
}, [])
.reduce((acc, n) => {
acc[n[1].join('-')] = n[0];
return acc;
}, {});
dateStart: {
get() {
return moment().subtract(1, this.selectedPeriod).toDate();
},
set(value) {
// ну, тут вам виднее, какой должен код быть
},
},
modalRun = (modalState) => {
this.setState((prevState) => {
return {
modal: {
...prevState.modal,
state: modalState,
},
};
});
}
$('input').on('input', function() {
const
$this = $(this),
newVal = +$this.val(),
oldVal = +$this.data('oldVal') || 0;
if (oldVal !== newVal) {
console.log(`новое ${['больше', 'меньше'][+(oldVal > newVal)]}`);
}
$this.data('oldVal', newVal);
});