Change text in radio button dynamically in react-native using Hooks - javascript

Today i want to create something like form in react native that looks like
It's pretty simple. i used this lib for radio button. However i want to change this text in the button when i click button next. I used following code.
import React, { useState, useRef } from "react";
import { StyleSheet, View, Button } from "react-native";
import RadioButtonRN from "radio-buttons-react-native";
export default function App() {
const numRef = useRef(0);
const questions = [
{
question: "What is localhost's IP address?",
answers: [
{ id: "1", text: "192.168.1.1" },
{ id: "2", text: "127.0.0.1", correct: true },
{ id: "3", text: "209.85.231.104" },
{ id: "4", text: "66.220.149.25" },
],
},
{
question: "What kind of11 fruit was used to name a computer in 1984?",
answers: [
{ id: "1", text: "Blackberry" },
{ id: "2", text: "Blueberry" },
{ id: "3", text: "Pear" },
{ id: "4", text: "Apple", correct: true },
],
},
];
return (
<View>
<RadioButtonRN
data={questions[numRef.current].answers.map((item) => ({
label: item.text,
correct: item.correct,
}))}
selectedBtn={(e) => {
console.log(e);
}}
/>
<Button
title="Next"
onPress={() => {
numRef.current = numRef.current + 1;
}}
/>
</View>
);
}
So right now when i clicked on the next button, the only thing thats updated is variable
numRef
But questions[numRef.current] doesn't update text in the button.
How can i fix that?

Changing the value of a ref doesn't result in a re-render. For data that, when it gets changed, should result in a re-render, you should use state instead.
export default function App() {
const [num, setNum] = useState(0);
// ...
data={questions[num].answers.map((item) => ({
// ...
onPress={() => {
setNum(num + 1)l
}}

Related

how can i solve a key value select input problem

im just testing this reactjs npm but when i use the select input it just show up de value pair insted of the label pair
this is the piece of the code:
import "./styles.css";
import React, { useState, useEffect } from "react";
import { FormField } from "react-form-input-fields";
import "react-form-input-fields/dist/index.css";
export default function App() {
let [type, setType] = useState("All");
const types = [
{ label: "All", value: "All" },
{ label: "Skins", value: "outfit" },
{ label: "Banners", value: "banner" },
{ label: "Wraps", value: "wrap" },
{ label: "Sprays", value: "spray" },
{ label: "Emoji", value: "emoji" },
{ label: "Pickaxe", value: "pickaxe" },
{ label: "Gliders", value: "glider" },
{ label: "Loading screens", value: "loadingscreen" },
{ label: "Emotes", value: "emote" }
];
function handletype(e) {
setType(e);
}
return (
<div className="App">
{/* <h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2> */}
<FormField
type="select"
value={type}
option={types}
label={"Select your type"}
keys={"country"}
handleOnChange={(value) => handletype(value)}
/>
</div>
);
}
here is the link from codesanbox
https://codesandbox.io/s/select-problem-ykplcm
i have trid using map and filter functions on value property component and i still dont get what i want.
Store the whole selected type in the state.
Then use type.label as the value.
import "./styles.css";
import React, { useState, useEffect } from "react";
import { FormField } from "react-form-input-fields";
import "react-form-input-fields/dist/index.css";
export default function App() {
let [type, setType] = useState({ label: "All", value: "All" }); // The state contains an object.
const types = [
{ label: "All", value: "All" },
{ label: "Skins", value: "outfit" },
{ label: "Banners", value: "banner" },
{ label: "Wraps", value: "wrap" },
{ label: "Sprays", value: "spray" },
{ label: "Emoji", value: "emoji" },
{ label: "Pickaxe", value: "pickaxe" },
{ label: "Gliders", value: "glider" },
{ label: "Loading screens", value: "loadingscreen" },
{ label: "Emotes", value: "emote" }
];
function handletype(e) {
// Find the selected object based on the returned value
const selected = types.filter((type) => type.value === e)[0]
console.log(selected)
// Set state with it.
setType(selected);
}
return (
<div className="App">
{/* <h1>Hello CodeSandbox</h1>
<h2>Start editing to see some magic happen!</h2> */}
<FormField
type="select"
value={type.label} // The label property of the stored state is used here
option={types}
label={"Select your type"}
keys={"country"}
handleOnChange={(value) => handletype(value)}
/>
</div>
);
}

AG Grid TypeScript in-line cell editing testing jest

I'm trying to create jest tests in order to test the functionality of my ag-grid table.
I currently have tests for expecting the default data in the grid, and testing the functionality of a button which adds an extra row of data to the grid.
I'm trying to edit one of my cells using in-line editing by simulating a double click on the cell I want to be edited. Then followed by a userEvent.type. However the cell never seems to update. I'm not sure if this is because the data hasn't been updated yet due to the asynchronous behaviour or if the simulated typing/click isn't working.
This is my test which is failing:
test("tests the inline cell editing", async () => {
const onClick = jest.fn();
render(<DummyGrid onClick={onClick} />);
const row = screen
.getAllByRole("row")
.filter((item) => item.getAttribute("row-id") === "1");
fireEvent.doubleClick(row[1]);
userEvent.type(row[1], "GT{enter}");
await waitFor(() => {
expect(screen.getByText("GT")).toBeInTheDocument();
});
});
And the following is the DummyGrid ag-grid component:
import React, { useState } from "react";
import { AgGridReact } from "ag-grid-react/lib/agGridReact";
import { ColDef, ValueSetterParams } from "ag-grid-community";
import GridButton from "./GridButton";
import Car from "./car";
import { Button } from "react-bootstrap";
import "ag-grid-community/dist/styles/ag-grid.css";
import "ag-grid-community/dist/styles/ag-theme-alpine-dark.css";
const initialState: Array<Car> = [
{ id: "0", make: "Toyota", modelName: "Celica", price: 35000 },
{ id: "1", make: "Ford", modelName: "Mondeo", price: 32000 },
{ id: "2", make: "Porsche", modelName: "Boxter", price: 70000 },
];
const fieldName = (name: keyof Car) => name;
function getRowNodeId(data: Car) {
return data.id;
}
function onGridReady(params: object) {
// console.log(params);
}
function onRowDataChanged(data: object) {
// console.log(data);
}
const columnDefs: ColDef[] = [
{
headerName: "Make",
field: fieldName("make"),
editable: true,
},
{
headerName: "Model",
field: fieldName("modelName"),
editable: true,
// valueSetter: (params: ValueSetterParams) => {
// onRowDataChanged(params);
// },
},
{
headerName: "Price",
field: fieldName("price"),
editable: true,
},
{
field: "Button",
cellRenderer: "gridButton",
cellRendererParams: {
onClicked: function (
id: string,
make: string,
modelName: string,
price: number
) {
// console.log(id, make, modelName, price);
},
},
},
];
const gridOptions = {
immutableData: true,
suppressScrollOnNewData: true,
columnDefs: columnDefs,
frameworkComponents: {
gridButton: GridButton,
},
};
interface Props {
onClick: () => void;
}
const DummyGrid: React.FC<Props> = ({ onClick }) => {
const [rowData, setRowData] = useState(initialState);
function addData() {
console.log("test");
const newRow: Car = {
id: "3",
make: "Land Rover",
modelName: "Defender",
price: 40000,
};
// console.log(rowData);
setRowData((oldData) => [...oldData, newRow]);
onClick();
}
return (
<div>
<Button data-testid="myButton" onClick={addData}>
Add New Value
</Button>
<div
className="ag-theme-alpine-dark"
style={{ height: "300px", width: "802px" }}
>
<AgGridReact
columnDefs={columnDefs}
defaultColDef={{
sortable: true,
}}
rowData={rowData}
gridOptions={gridOptions}
onGridReady={onGridReady}
onRowDataChanged={onRowDataChanged}
getRowNodeId={getRowNodeId}
suppressColumnVirtualisation={true}
></AgGridReact>
</div>
</div>
);
};
export default DummyGrid;
Any help or advice would be much appreciated. I have researched and found a very small amount of help on testing ag-grid with jest, and nothing on testing in-line ag-grid editing with jest, only the testing of separate buttons which update the grid content.

How do I get hover effect on rows with material-table react?

I have used material-table with react to render my data. I want to show the hover effect and cursor pointer effect when I hover on rows. But I couldn't find this even in the documentation.
IN SHORT- I want to highlight some colors on a row when the cursor hovers to that row.
Note: I also found a similar question and answer here, but they used another state just to hover which downgrades the performance if I increase the data like thousands rows. Hence it's bad practice so here I am asking for alternate solutions for the same.
Here is my codesandbox link
Below I also pasted my code.
App.js
import React, { useState } from 'react';
import './App.css';
import MaterialTable from 'material-table'
const empList = [
{ id: 1, name: "Neeraj", email: 'neeraj#gmail.com', phone: 9876543210, city: "Bangalore" },
{ id: 2, name: "Raj", email: 'raj#gmail.com', phone: 9812345678, city: "Chennai" },
{ id: 3, name: "David", email: 'david342#gmail.com', phone: 7896536289, city: "Jaipur" },
{ id: 4, name: "Vikas", email: 'vikas75#gmail.com', phone: 9087654321, city: "Hyderabad" },
]
function App() {
const [data, setData] = useState(empList)
const columns = [
{ title: "ID", field: "id", editable: false },
{ title: "Name", field: "name" },
{ title: "Email", field: "email" },
{ title: "Phone Number", field: 'phone', },
{ title: "City", field: "city", }
]
return (
<div className="App">
<h1 align="center">React-App</h1>
<h4 align='center'>Material Table with CRUD operation</h4>
<MaterialTable
title="Employee Data"
data={data}
columns={columns}
editable={{
onRowAdd: (newRow) => new Promise((resolve, reject) => {
const updatedRows = [...data, { id: Math.floor(Math.random() * 100), ...newRow }]
setTimeout(() => {
setData(updatedRows)
resolve()
}, 2000)
}),
onRowDelete: selectedRow => new Promise((resolve, reject) => {
const index = selectedRow.tableData.id;
const updatedRows = [...data]
updatedRows.splice(index, 1)
setTimeout(() => {
setData(updatedRows)
resolve()
}, 2000)
}),
onRowUpdate:(updatedRow,oldRow)=>new Promise((resolve,reject)=>{
const index=oldRow.tableData.id;
const updatedRows=[...data]
updatedRows[index]=updatedRow
setTimeout(() => {
setData(updatedRows)
resolve()
}, 2000)
})
}}
options={{
actionsColumnIndex: -1, addRowPosition: "first"
}}
/>
</div>
);
}
export default App;
add in your inside of your CSS
tbody tr:hover {
background-color: blue;
color: white;
cursor: pointer;
}

How can I change the color of material-table icons of onRowAdd, onRowUpdate, onRowDelete?

I tried to the material-table the library for basic crud operation. By using onRowAdd, onRowUpdate, onRowDelete, I get the icons for the same but I would like to know that how can I change the color of each of these three icons?
You can see my table has few icons and I am focusing on add, edit, delete icons I want to change color of these icons.
Here is the link to my codesandbox.
App.js file
import React, { useState } from 'react';
import './App.css';
import MaterialTable from 'material-table'
const empList = [
{ id: 1, name: "Neeraj", email: 'neeraj#gmail.com', phone: 9876543210, city: "Bangalore" },
{ id: 2, name: "Raj", email: 'raj#gmail.com', phone: 9812345678, city: "Chennai" },
{ id: 3, name: "David", email: 'david342#gmail.com', phone: 7896536289, city: "Jaipur" },
{ id: 4, name: "Vikas", email: 'vikas75#gmail.com', phone: 9087654321, city: "Hyderabad" },
]
function App() {
const [data, setData] = useState(empList)
const columns = [
{ title: "ID", field: "id", editable: false },
{ title: "Name", field: "name" },
{ title: "Email", field: "email" },
{ title: "Phone Number", field: 'phone', },
{ title: "City", field: "city", }
]
return (
<div className="App">
<h1 align="center">React-App</h1>
<h4 align='center'>Material Table with CRUD operation</h4>
<MaterialTable
title="Employee Data"
data={data}
columns={columns}
editable={{
onRowAdd: (newRow) => new Promise((resolve, reject) => {
const updatedRows = [...data, { id: Math.floor(Math.random() * 100), ...newRow }]
setTimeout(() => {
setData(updatedRows)
resolve()
}, 2000)
}),
onRowDelete: selectedRow => new Promise((resolve, reject) => {
const index = selectedRow.tableData.id;
const updatedRows = [...data]
updatedRows.splice(index, 1)
setTimeout(() => {
setData(updatedRows)
resolve()
}, 2000)
}),
onRowUpdate:(updatedRow,oldRow)=>new Promise((resolve,reject)=>{
const index=oldRow.tableData.id;
const updatedRows=[...data]
updatedRows[index]=updatedRow
setTimeout(() => {
setData(updatedRows)
resolve()
}, 2000)
})
}}
options={{
actionsColumnIndex: -1, addRowPosition: "first"
}}
/>
</div>
);
}
export default App;
You can override the icons and provide custom styles by setting the icons props. It accepts an object where the key is a type of operation (Add, Edit, Delete,...) and the value is an icon component. For reference, see the all-props section here.
<MaterialTable
{...props}
icons={{
Edit: () => <EditIcon style={{ color: "orange" }} />,
Delete: () => <DeleteIcon style={{ color: "red" }} />
}}
>
Live Demo
It's Simple. Inspect on the page and Select the Icon and Copy its style Name in Styles Tab.
Now, Go to App.css file and Create New Style with the icon style name shown on Inspect-styles area and there you can enter your desired color.
It will work.
In your App.css File,
Add below code
.MuiIconButton-colorInherit {
color: red;
}
change to any color

How can change boolean type icons to oposite

I'm want the empty key called archive has the check and with the values "true" has the line icon.
Here is the example: I want the opposite to the column status. Without change the tableIcons.js
Here is the code and codesandbox example:
import React, { useState } from "react";
import { render } from "react-dom";
import MaterialTable from "material-table";
import SaveAltIcon from "#material-ui/icons/SaveAlt";
import tableIcons from "./TableIcons.js";
const rando = max => Math.floor(Math.random() * max);
const rawData = [
{ id: 1111111111, archive: "true", type: "CC" },
{ id: 2222222222, archive: "", type: "RR" },
{ id: 3333333333, archive: "true", type: "CC" },
{ id: 4444444444, archive: "", type: "PS" },
{ id: 5555555555, archive: "true", type: "II" }
];
const columns = [
{ title: "Id", field: "id" },
{ title: "Type", field: "type" },
{ title: "Status", field: "archive", type: "boolean" }
];
const App = () => {
const [data, setData] = useState(rawData);
return (
<MaterialTable
data={data}
columns={columns}
title="Starter Template"
icons={tableIcons}
/>
);
};
render(<App />, document.querySelector("#root"));
https://codesandbox.io/s/material-table-starter-template-0s0np?file=/src/index.js
First of all I modified the archive prop value from "true" to true in order to make conditional checks easier, this way the type is boolean instead of string.
Then I imported Check and Remove icons from the depency you were already using:
import { Check, Remove } from "#material-ui/icons";
And finally where the columns const is defined, I pass a function to the render prop, like this:
render: rowdata => rowdata.archive !== true ? <Check /> : <Remove />
Ofcourse you can change the conditional if needed. Link to the Material-Table documentation on this topic here.
This is your code after the modifications:
import React, { useState } from "react";
import { render } from "react-dom";
import MaterialTable from "material-table";
import SaveAltIcon from "#material-ui/icons/SaveAlt";
import tableIcons from "./TableIcons.js";
import { Check, Remove } from "#material-ui/icons";
const rando = (max) => Math.floor(Math.random() * max);
const rawData = [
{ id: 1111111111, archive: true, type: "CC" },
{ id: 2222222222, archive: "", type: "RR" },
{ id: 3333333333, archive: true, type: "CC" },
{ id: 4444444444, archive: "", type: "PS" },
{ id: 5555555555, archive: true, type: "II" },
];
const columns = [
{ title: "Id", field: "id" },
{ title: "Type", field: "type" },
{
title: "Status",
field: "archive",
type: "boolean",
render: (rowdata) => (rowdata.archive !== true ? <Check /> : <Remove />),
// the ternary expression above is the same as:
// if (rowdata.archive !== true) {
// return <Check />;
// } else {
// return <Remove />;
// }
},
//
];
const App = () => {
const [data, setData] = useState(rawData);
return (
<MaterialTable
data={data}
columns={columns}
title="Starter Template"
icons={tableIcons}
/>
);
};
render(<App />, document.querySelector("#root"));
Here is the link to the sandbox. I hope this works for you!

Categories