#reactjs #material-ui
Вопрос:
Моя страница выглядит так, как показано ниже:
import React, { useState, useEffect } from "react";
import { getShopConfiguration, updateShopConfiguration } from '../../../api/shopConfig'
import MaterialTable from "material-table";
import Check from '@material-ui/icons/Check';
import Clear from '@material-ui/icons/Clear';
import Edit from '@material-ui/icons/Edit';
import ViewColumn from '@material-ui/icons/ViewColumn';
import { forwardRef } from 'react';
const ConfigurationTable = (props) => {
const [loadingData, setLoadingData] = useState(true);
const columns = [
{
title: "Type",
field: "flag",
editable: 'never'
},
{
title: "Value",
field: "value",
}
];
const [data, setData] = useState([]);
useEffect(() => {
if (loadingData || props.selectedShop) {
getConfiguration(props.selectedShop);
}
}, [props.selectedShop, loadingData]);
const getConfiguration = async (shop) => {
var currentShop
if (shop) {
currentShop = shop.value
}
const response = await (await getShopConfiguration(currentShop)).data;
setData(response);
setLoadingData(false);
}
const tableIcons = {
Check: forwardRef((props, ref) => <Check {...props} ref={ref} />),
Clear: forwardRef((props, ref) => <Clear {...props} ref={ref} />),
Edit: forwardRef((props, ref) => <Edit {...props} ref={ref} />),
ViewColumn: forwardRef((props, ref) => <ViewColumn {...props} ref={ref} />)
};
const updateTableData = (newData, oldData) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
const dataUpdate = [...data];
const index = oldData.tableData.id;
dataUpdate[index] = newData;
setData([...dataUpdate]);
resolve();
}, 300)
})
}
const saveConfig = async () => {
var currentShop
if (props.selectedShop) {
currentShop = props.selectedShop.value
}
await updateShopConfiguration(currentShop, data);
}
return (
<div>
<div><label className="label" >{props.configLabel}</label></div>
<div>
{
{loadingData ? (
<p>Loading Please wait...</p>
) : (
<MaterialTable
icons={tableIcons}
options={{
toolbar: false,
paging: false
}}
columns={columns}
data={data}
editable={{
onRowUpdate: (newData, oldData) => updateTableData(newData, oldData)
}}
/>
)}
</div>
<div style={{marginTop:'50px'}}>
<button onClick = {saveConfig} >Save Changes</button>
</div>
</div>
);
}
export default ConfigurationTable
Когда я нажимаю значок карандаша на любую строку в таблице, в то время как я обновляю данные столбца, я хочу, чтобы кнопка «Сохранить изменения» внизу на странице была отключена. Как мне это сделать?
В данный момент, когда я нажимаю значок карандаша и редактирую/ввожу значение в строку, в этот самый момент я могу нажать «Сохранить изменения», но мне нужно включить «Сохранить изменения» только после того , как я нажму галочку/ крестик, что означает, что я закончил редактирование записи.
Комментарии:
1. Я бы предложил добавить состояние, которое будет истинным/ложным, например «isEditing», что u обновит состояние при нажатии на значок карандаша, и когда пользователь «отменит» диалоговое окно, оно снова обновит состояние. затем передайте его на кнопку, как отключено={isEditing}
2. Пожалуйста, приведите воспроизводимый пример с codesandbox , например.
Ответ №1:
Пожалуйста, попробуйте этот код. Я добавил фиктивные строки для тестирования и прокомментировал ваш код вызова API.
import React, { useState, useEffect } from "react";
// import { getShopConfiguration, updateShopConfiguration } from '../../../api/shopConfig'
import MaterialTable from "material-table";
import { Check, Clear, Edit, ViewColumn } from "@material-ui/icons";
import { forwardRef } from "react";
const ConfigurationTable = (props) => {
const [loadingData, setLoadingData] = useState(true);
const [isSaveEnabled, setIsSaveEnabled] = useState(false);
const columns = [
{
title: "Type",
field: "flag",
editable: "never",
},
{
title: "Value",
field: "value",
},
];
const [data, setData] = useState([]);
useEffect(() => {
if (loadingData || props.selectedShop) {
getConfiguration(props.selectedShop);
}
}, [props.selectedShop, loadingData]);
const getConfiguration = async (shop) => {
var currentShop;
if (shop) {
currentShop = shop.value;
}
const response = [
{ flag: "a", value: 1 },
{ flag: "b", value: 1 },
{ flag: "c", value: 1 },
{ flag: "d", value: 1 },
];
// const response = await (await getShopConfiguration(currentShop)).data;
setData(response);
setLoadingData(false);
};
const tableIcons = {
Check: forwardRef((props, ref) => (
<Check {...props} onClick={() => setIsSaveEnabled(false)} ref={ref} />
)),
Clear: forwardRef((props, ref) => <Clear {...props} ref={ref} />),
Edit: forwardRef((props, ref) => (
<Edit {...props} onClick={() => setIsSaveEnabled(true)} ref={ref} />
)),
ViewColumn: forwardRef((props, ref) => <ViewColumn {...props} ref={ref} />),
};
const updateTableData = (newData, oldData) => {
return new Promise((resolve, reject) => {
setTimeout(() => {
const dataUpdate = [...data];
const index = oldData.tableData.id;
dataUpdate[index] = newData;
setData([...dataUpdate]);
resolve();
}, 300);
});
};
const saveConfig = async () => {
// var currentShop
// if (props.selectedShop) {
// currentShop = props.selectedShop.value
// }
// await updateShopConfiguration(currentShop, data);
};
return (
<div>
<div>
<label className="label">{props.configLabel}</label>
</div>
<div>
{loadingData ? (
<p>Loading Please wait...</p>
) : (
<MaterialTable
icons={tableIcons}
options={{
toolbar: false,
paging: false,
}}
columns={columns}
data={data}
editable={{
onRowUpdate: (newData, oldData) =>
updateTableData(newData, oldData),
}}
/>
)}
</div>
<div style={{ marginTop: "50px" }}>
<button disabled={isSaveEnabled} onClick={saveConfig}>
Save Changes
</button>
</div>
</div>
);
};
export default ConfigurationTable;
Комментарии:
1. Спасибо, это работает, но терпит неудачу, когда я пробую разные комбинации сохранения/отмены. Отключается, когда он должен быть включен. Но я постараюсь обновить его.
2. Я предполагаю, что это произойдет, когда вы попытаетесь отредактировать несколько строк, не нажимая галочку для каждой строки после редактирования.. в этом случае вместо использования логического флага вы можете использовать счетчик.. при щелчке каждого значка редактирования/пера увеличивайте счетчик. По щелчку галочки уменьшите счетчик.. кнопка сохранить должна быть включена, только если счетчик равен 0.