How can I determine which checkbox is checked? - javascript

<table>
<tbody>
<tr>
<th>Select</th>
<th>User Id</th>
<th>Id</th>
<th>Is Banned?</th>
<th>registration_date</th>
</tr>
{data.map((item, i) => (
<tr key={i}>
<td><input type="checkbox" checked={isChecked} /></td>
<td>{item.user_id}</td>
<td>{item.user_name}</td>
<td className="isbanned">{item.isbanned}</td>
<td>{item.registration_date}</td>
</tr>
))}
</tbody></table>
this is my code as you see in up. My question is:
How can I detect user_id 1 checbox is checked?
How should I change my code? or what I can use for that?

You can do something like this
const data = [
{
user_id: "some-id",
user_name: "Me",
isbanned: "no",
registration_date: "2000",
},
]
function StackOverflow() {
const [selectedUserIds, setSelectedUserIds] = useState([])
const addOrRemoveId = (id) => {
setSelectedUserIds((state) => {
if (state.includes(id)) {
// If new id exists in current list then we remove it from state
return selectedUserIds.filter((currentId) => currentId !== id)
}
// Else we add the item id to our state
return [...state, id]
})
}
return (
<table>
<tbody>
<tr>
<th>Select</th>
<th>User Id</th>
<th>Id</th>
<th>Is Banned?</th>
<th>registration_date</th>
</tr>
{data.map(({ user_id, ...item }) => (
<tr key={user_id}>
<td>
<input
checked={selectedUserIds.includes(user_id)}
onChange={() => addOrRemoveId(user_id)}
type="checkbox"
/>
</td>
<td>{user_id}</td>
<td>{item.user_name}</td>
<td className="isbanned">{item.isbanned}</td>
<td>{item.registration_date}</td>
</tr>
))}
</tbody>
</table>
)
}
To consider: Never use an index or a combination string of them as component keys. Keys are intended to be unique, if you have an userId already, then use it as that key id

Related

Rendering an object into a table in React

I am a React beginner and I am having trouble with rendering an object into a table. I can access the ctx object with console.log but I cannot display it on the browser in the table.
If anyone can help me please give me your advice. the code is below.
The goal is to display data from the object(ctx) into the table.
function AllData(){
const ctx = {users:[{name:'john', email:'john#email.com', passwords:'password'},{name:'smith', email:'smith#email.com', passwords:'password']};
const userdata = ctx.users.map((user)=>{
(
<tr>
<td>{user.name}</td>
<td>{user.email}</td>
<td>{user.password}</td>
</tr>
)
});
return (
<table className="table">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Email</th>
<th scope="col">Password</th>
</tr>
</thead>
<tbody>
{userdata}
</tbody>
</table>
);
}
You need to return something from the .map like
const userdata = ctx.users.map((user) => {
return (
<tr key={user.name}>
<td>{user.name}</td>
<td>{user.email}</td>
<td>{user.password}</td>
</tr>
)
});
Or even just
const userdata = ctx.users.map((user) => (
<tr key={user.name}>
<td>{user.name}</td>
<td>{user.email}</td>
<td>{user.password}</td>
</tr>
));
Another option would be like
return (
<table className="table">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Email</th>
<th scope="col">Password</th>
</tr>
</thead>
<tbody>
{
ctx.users.map((user) => (
<tr key={user.name}>
<td>{user.name}</td>
<td>{user.email}</td>
<td>{user.password}</td>
</tr>
))
}
</tbody>
</table>
)
Also added the key property, since you are using an array.
Add return inside map
const userdata = ctx.users.map((user)=>{
return (
<tr>
<td>{user.name}</td>
<td>{user.email}</td>
<td>{user.password}</td>
</tr>
)
});
There are a couple of issues with your code, the main one being that the function that you use in the .map does not return anything.
Other issues:
Missing } in the definition of ctx.
Mismatch in property name: passwords vs password.
No key property present in the JSX elements that are returned by the map function.
Below is a runnable sample with all these issues fixed.
function AllData() {
const ctx = {
users: [
{ name: 'john', email: 'john#email.com', password: 'password' },
{ name: 'smith', email: 'smith#email.com', password: 'password' }
]
};
const userdata = ctx.users.map((user)=>{
return (
<tr key={user.name}>
<td>{user.name}</td>
<td>{user.email}</td>
<td>{user.password}</td>
</tr>
)
});
return (
<table className="table">
<thead>
<tr>
<th scope="col">Name</th>
<th scope="col">Email</th>
<th scope="col">Password</th>
</tr>
</thead>
<tbody>
{userdata}
</tbody>
</table>
)
}
ReactDOM.render(<AllData />, document.getElementById('react'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="react"></div>

How can I re-render a view after deleting an object from an array, in Svelte?

I am working on a small Svelte application, for learning purposes (Im new to Svelte). The application uses an array of objects displayed in a view as an HTML table:
let countries = [
{ code: "AF", name: "Afghanistan" },
{ code: "AL", name: "Albania" },
{ code: "IL", name: "Israel" }
];
<table class="table table-bordered">
<thead>
<tr>
<th>#</th>
<th>Code</th>
<th>Name</th>
<th class="text-right">Actions</th>
</tr>
</thead>
<tbody>
{#if countries.length}
{#each countries as c, index}
<tr>
<td>{index+1}</td>
<td>{c.code}</td>
<td>{c.name}</td>
<td class="text-right">
<button data-code="{c.code}" on:click="{deleteCountry}" class="btn btn-sm btn-danger">Delete</button>
</td>
</tr>
{/each}
{:else}
<tr>
<td colspan="4">There are no countries</td>
</tr>
{/if}
</tbody>
</table>
I am doing a delete operation this way:
function deleteCountry(){
let ccode = this.getAttribute('data-code');
let itemIdx = countries.findIndex(x => x.code == ccode);
countries.splice(itemIdx,1);
console.log(countries);
}
There is a REPL here.
The problem
I have been unable to render the table (view) again, after the countries array is updated (an element is deleted from it).
How do I do that?
add
countries = countries;
after this line
countries.splice(itemIdx,1);
since reactivity/rerendering/UI update only marked after assignment.
For svelte to pick up the change to your array of countries, you need to create a new reference of the array. For this you could use the Array.filter method.
<script>
let countries = [
{ code: "AF", name: "Afghanistan" },
{ code: "AL", name: "Albania" },
{ code: "IL", name: "Israel" }
];
function deleteCountry(code) {
countries = countries.filter(c => c.code !== code)
}
</script>
<table class="table table-bordered">
<thead>
<tr>
<th>#</th>
<th>Code</th>
<th>Name</th>
<th class="text-right">Actions</th>
</tr>
</thead>
<tbody>
{#if countries.length}
{#each countries as c, index}
<tr>
<td>{index+1}</td>
<td>{c.code}</td>
<td>{c.name}</td>
<td class="text-right">
<button on:click="{() => deleteCountry(c.code)}" class="btn btn-sm btn-danger">Delete</button>
</td>
</tr>
{/each}
{:else}
<tr>
<td colspan="4">There are no countries</td>
</tr>
{/if}
</tbody>
</table>
Also you can directly use the country code as an argument for the deleteCountry method.

how to filter with reactJS?

im using React in my app i have table i want to filter the gender by Male or Female. I want to a filter for the gender so I can search the employees by their genders if it is possible to do.
+++++ IM TOTALY NEW TO PROGRAMMING
export default class EmployeeList extends React.Component {
constructor(props) {
super(props);
this.state = {
employees: []
};
}
componentDidMount() {
this.employeesTracker = Tracker.autorun(() => {
Meteor.subscribe('employees');
const employees = Employees.find().fetch();
this.setState({ employees });
});
}
componentWillUnmount() {
this.employeesTracker.stop();
}
renderEmployeesListItems() {
return this.state.employees.map(employee => {
return (
<tr key={employee._id}>
<td>{employee.name}</td>
<td>{employee.email}</td>
<td>{employee.age}</td>
<td>{employee.gender}</td>
<td>{employee.city}</td>
<td><Link className="link button" to={`/employee-detail/${employee._id}`}>EDIT</Link></td>
<td><button className="button pointer" onClick={() => Employees.remove({_id: employee._id})}>DELETE</button></td>
</tr>
);
});
}
render() {
return (
<div>
<table className="employeeTable">
<tbody>
<tr>
<th>NAME</th>
<th>EMAIL</th>
<th>AGE</th>
<th>GENDER</th>
<th>CITY</th>
<th></th>
<th></th>
</tr>
{this.renderEmployeesListItems()}
</tbody>
</table>
</div>
);
}
}
Hey you should use React workflow
function RenderEmployees(props: Employee[]) {
const [sexe, setSexe] = useState('male');
renderEmployeesListItems = () => {
props.filter((employee: Employee)=> employee.sexe === sexe)
.map((employee)=>
<tr>
<td>{employee.name}</td>
<td>{employee.email}</td>
<td>{employee.age}</td>
<td>{employee.gender}</td> // who egal with sexe
<td>{employee.city}</td>
<td></td>
<td></td>
</tr>
)
}
return (
<div>
<div>
<h2>Filter</h2>
<button onClick={setSexe('male')}>
Male
</button>
<button onClick={setSexe('female')}>
Female
</button>
</div>
<table className="employeeTable" id="myTable">
<tbody>
<tr>
<th>NAME</th>
<th>EMAIL</th>
<th>AGE</th>
<th>GENDER</th>
<th>CITY</th>
<th></th>
<th></th>
</tr>
{renderEmployeesListItems()}
</tbody>
</table>
</div>
);
}

How can I display a clickable table from a nested array of objects?

I have an array of objects that contain some variable information, but also another array of objects with some more information.
I'm trying to display a table that shows the initial array, and when the user clicks on the row of that particular object, it would render a new table with the objects inside that specific array selected.
startCreateEventHandler = () => {
this.setState({ creating: true });
};
modalCancelHandler = () => {
this.setState({ creating: false });
};
render() {
return (
<div>
{this.state.creating && (
<Table>
<thead>
<tr>
<th>Details</th>
</tr>
</thead>
<tbody>
{this.props.archives.map(archive =>
archive.ticketRequests.map(request => (
<tr>
<td>{request.details}</td>
</tr>
))
)}
</tbody>
</Table>
)}
{this.state.creating ? null : (
<Table hover className="table table-striped">
<thead>
<tr>
<th>Title</th>
</tr>
</thead>
<tbody>
{this.props.archives.map(archive => (
<tr onClick={this.startCreateEventHandler}>
<td>{archive.title}</td>
</tr>
))}
</tbody>
</Table>
)}
</div>
);
}
What I get with this is the table set up correctly, but once I click on a row it displays all* rows objects in the next table instead of just that specific archive.
If I understood your problem then You also need to set the current clicked archive on the state and need to parse that selected archive
startCreateEventHandler = (archive) => {
this.setState({ creating: true, selectedArchive: archive });
};
modalCancelHandler = () => {
this.setState({ creating: false, selectedArchive: undefined });
};
render() {
return (
<div>
{this.state.creating && (
<Table>
<thead>
<tr>
<th>Details</th>
</tr>
</thead>
<tbody>
{this.state.selectedArchive.map(archive =>
<tr>
<td>{archive.details}</td>
</tr>
)}
</tbody>
</Table>
)}
{this.state.creating ? null : (
<Table hover className="table table-striped">
<thead>
<tr>
<th>Title</th>
</tr>
</thead>
<tbody>
{this.props.archives.map(archive => (
<tr onClick={(event)=>this.startCreateEventHandler(archive.ticketRequests)}>
<td>{archive.title}</td>
</tr>
))}
</tbody>
</Table>
)}
</div>
);
};

Map array object inside map - ReactJS

I am planning to map each item in the object (contact numbers) for every Person
Putting it inside and seperate them in comma ','
When I use data.contact_number, output is combined all fields in array.
const ContactList = (props) => (
<div>
<table>
<thead>
<tr>
<th>Name</th>
<th>Contact Numbers</th>
<th>Address</th>
<th>Email</th>
<th>Note</th>
</tr>
</thead>
<tbody>
{props.data.map(data =>
<tr key={data.id}>
<td>{data.name}</td>
{props.data[data.id].contact_number.map(cn =>
<td>{cn}</td>
)}
<td>{data.address}</td>
<td>{data.email}</td>
<td>{data.note}</td>
</tr>
)}
</tbody>
</table>
</div>
)
This is my data:
{
"id": 7,
"name": "sd",
"email": "ajot#qwe.com",
"address": "testAddress",
"note": "testNote",
"contact_number": [
"11",
"12",
"31",
"41",
"51",
"61"
]
}
Error :
Uncaught (in promise) TypeError: Cannot read property 'contact_number'
of undefined
Try this:
const ContactList = (props) => (
<div>
<table>
<thead>
<tr>
<th>Name</th>
<th>Contact Numbers</th>
<th>Address</th>
<th>Email</th>
<th>Note</th>
</tr>
</thead>
<tbody>
{props.data.map(data =>
<tr key={data.id}>
<td>{data.name}</td>
<td>{data.contact_number.map(cn => cn).join(', ')}</td>
<td>{data.address}</td>
<td>{data.email}</td>
<td>{data.note}</td>
</tr>
)}
</tbody>
</table>
</div>
)
This line which I have changed should give you your desired effect:
{data.contact_number.map(cn => cn).join(', ')} by writing all the contact_number values to a string separated by commas.
Replace this :
{props.data[data.id].contact_number.map(cn =>
<td>{cn}</td>
)}
by this :
{data.contact_number.map(cn =>
<td>{cn}</td>
)}
props.data[data.id] is undefined because props.data[data.id] is not equal to data
The data-path is wrong:
props.data[data.id].contact_number
or the data have to be structured like
[7 : {
"name": "sd",
"email": "ajot#qwe.com",
"address": "testAddress",
"note": "testNote",
"contact_number": [
"11",
"12"
]
},
8 : { ... },
0 : { ... }
]
You need to parse your json.
JSON.parse(yourJson) turns the data into a JavaScript object.
JSON.parse(props.data).map(data => ...
If you see properly data is not an array so you can't use map on that. You can simply choose this.
const ContactList = (props) => (
<div>
<table>
<thead>
<tr>
<th>Name</th>
<th>Contact Numbers</th>
<th>Address</th>
<th>Email</th>
<th>Note</th>
</tr>
</thead>
<tbody>
<tr key={this.props.data.id}>
<td>{this.props.data.name}</td>
{this.props.data.contact_number.map((contact_number)=>{
<td>{contact_number}</td>
})}
</tr>
</tbody>
</table>
</div>
)

Categories

Resources