I'm very new to Javascript and I'm trying to filter/update data based on a checkbox. If you see below I can filter the data based on values in the data I created (dataset2). Dataset3 is the problem... I want to click on the checkboxes and update the dataset based on the values that are checked.
First, I'm not sure how to pass the array of values into the filter (e.g. how would I pass "Books" && "Supplies" into the filter. As you can see in dataset2 I can only get it to equal "Books". Second, how do I get it to update when checkboxes are checked/unchecked. I created a fiddle for this also. Thanks you. https://jsfiddle.net/at2046/mqjyjfox/8/
var dataset = [['Books','GEB'],
['Books','Decision Theory'],
['Supplies','Pencil'],
['Supplies','Paper']
];
document.getElementById("demo").innerHTML = dataset;
var dataset2 = dataset.filter(function (el) {
return el[0] == "Books";
});
document.getElementById("demo2").innerHTML = dataset2;
$(":checkbox").change(function() {
var dataset3 = dataset.filter(function(el) {
var checkboxes = document.getElementsByName('result');
for (var index = 0; index < checkboxes.length; index++) {
return el[0] == checkboxes[index].value;
}
});
document.getElementById("demo3").innerHTML = dataset3;
});
First, you added a $(:checkbox'), which is a jQuery syntax and you didn't have the library loaded in your fiddle.
Then, you use a return inside the for, which means that at the first iteration (choice Books) the script will exit returning only the elements belonging to the first item in the choice list.
An option is to replace the for for a while to check if the el[0] exists in any of the choices.
Lastly, you weren't checking if the checkboxes are checked, which means it would return everything no matter the state of the check box.
$(":checkbox").change(function() {
var dataset3 = dataset.filter(function(el) {
var checkboxes = document.getElementsByName('result');
var index = 0;
var found = false;
while (index < checkboxes.length && !found) {
if (checkboxes[index].checked && el[0] == checkboxes[index].value) found=true;
++index;
}
return found;
});
document.getElementById("demo3").innerHTML = dataset3;
});
https://jsfiddle.net/mqjyjfox/10/
Here I used cuisines for my checkbox items. The following code snippet gives the logic for checkboxes filtering. handleCuisineChange is the function that contains the logic. The length of for loop is 8 since the number of cuisines (the number of checkbox items) I have taken here is 8. Replace the cuisines here with your checkbox data. Apply this logic and your checkbox items are ready for filtering.
Inside axios I used my own backend API getCuisine and port number 7000.
axios I used my own backend API getCuisine and port number 7000.
handleCuisineChange=(cuisine_id)=>
{
const {cuisineArray}=this.state; //an empty array declared in constructor
if (cuisineArray.indexOf(cuisine_id) == -1)
{
cuisineArray.push(cuisine_id);
}
else
{
var index=cuisineArray.indexOf(cuisine_id);
cuisineArray.splice(index,1);
}
const {cuisineArray2}=this.state; //an empty array declared in constructor
let i=0;
for (i=0;i<8;i++)
{
if(cuisineArray[i]==undefined)
{
cuisineArray2[i]=cuisineArray[0];
}
else
{
cuisineArray2[i]=cuisineArray[i];
}
}
this.props.history.push(`/checking3?cuisine_id1=${cuisineArray2[0]}&cuisine_id2=${cuisineArray2[1]}&cuisine_id3=${cuisineArray2[2]}&cuisine_id4=${cuisineArray2[3]}&cuisine_id5=${cuisineArray2[4]}&cuisine_id6=${cuisineArray2[5]}&cuisine_id7=${cuisineArray2[6]}&cuisine_id8=${cuisineArray2[7]}`);
let filterObj={cuisine_id1:cuisineArray2[0],cuisine_id2:cuisineArray2[1],cuisine_id3:cuisineArray2[2],cuisine_id4:cuisineArray2[3],cuisine_id5:cuisineArray2[4],cuisine_id6:cuisineArray2[5],cuisine_id7:cuisineArray2[6],cuisine_id8:cuisineArray2[7]};
axios(
{
method:'POST',
url:`http://localhost:7000/getCuisine`,
headers:{'Content-Type':'application/json'},
data:filterObj
}
)
.then(res=>
{
this.setState({restaurants:res.data.restaurants});
})
.catch(err=>console.log(err))
}
render()
{
const {restaurants}=this.state;
return(
<div>
<input type="checkbox" name="cuisines" id={"1"} onChange={(event) => this.handleCuisineChange("1")} />
<span className="checkbox-items" > North Indian </span> <div style={{display: "block"}}> </div>
<input type="checkbox" name="cuisines" id={"2"} onChange={(event) => this.handleCuisineChange("2")} />
<span className="checkbox-items" > south indian </span> <div style={{display: "block"}}> </div>
<input type="checkbox" name="cuisines" id={"3"} onChange={(event) => this.handleCuisineChange("3")} />
<span className="checkbox-items" > chinese </span> <div style={{display: "block"}}> </div>
<input type="checkbox" name="cuisines" id={"4"} onChange={(event) => this.handleCuisineChange("1")} />
<span className="checkbox-items" > fast food </span> <div style={{display: "block"}}> </div>
<input type="checkbox" name="cuisines" id={"5"} onChange={(event) => this.handleCuisineChange("1")} />
<span className="checkbox-items" > Street food </span> <div style={{display: "block"}}> </div>
<input type="checkbox" name="cuisines" id={"6"} onChange={(event) => this.handleCuisineChange("1")} />
<span className="checkbox-items" > American </span> <div style={{display: "block"}}> </div>
<input type="checkbox" name="cuisines" id={"7"} onChange={(event) => this.handleCuisineChange("1")} />
<span className="checkbox-items" > Italian </span> <div style={{display: "block"}}> </div>
<input type="checkbox" name="cuisines" id={"8"} onChange={(event) => this.handleCuisineChange("1")} />
<span className="checkbox-items" > Mexican </span> <div style={{display: "block"}}> </div>
</div>
)
} //render end
Related
I have a react form whose data must be saved in an array (what i want) values from the form include 3 selectable values, and two input values ( a number input and textarea ) each time a user is done with entering data, they press save button to push that entered data ( converted to an object ) into the array. I expect that each time user clicks save button, they are saving different data from the previous, which is then again pushed into the same array as an object. the array has a fixed length and I expect to not accept anymore data if it reaches a certain length. this works very well each a user saves data in that array only when the values of the two input fields (number input and textarea) the challenge is that each time the user data from any of the 3 selectable (as long as a select field is touched, even if the selected value is the same as the preivous value) values, the array loses the previous data and saves the current as array[0], the select fields are customised components using react-select, I extract data selected using useState, and other input fields are customised components from regular html input fields, I extract data input, using useRef, and forwadRef.
Kindly help and suggest how I can go about this.
export const Input = forwardRef((props, ref) => {
return (
<input
min={1}
required={props.required}
type={props.type}
id={props.id}
name={props.name}
placeholder={props.placeholder}
autoComplete={props.autoComplete}
autoCapitalize="none"
autoCorrect='off'
onChange={props.onChange}
defaultValue={props.defaultValue}
ref={ref}
{...props}
/>
);
});
const MySelect = (props) => {
const MyTheme = (theme) => {
return {
...theme,
colors: {
...theme.colors,
primary25: "#bdbdbd",
color: "#000",
primary: "rgba(0, 0, 0, 0.3)",
},
};
};
return (
<div style={{ width: "80%" }}>
<Select
defaultValue={props.defaultValue}
menuPlacement="auto"
menuPosition="auto"
placeholder={props.placeholder}
value={props.value}
onChange={props.onChange}
options={props.options}
isSearchable
isDisabled={props.isDisabled}
theme={MyTheme}
name={props.name}
id={props.id}
// ref={props.ref}
required = {props.required}
/>
</div>
);
};
export default MySelect;
const TextReminder = (props) => {
const [kickStart, setKickStart] = useState("");
const TimerRef = useRef();
const [units, setUnits] = useState("");
const [tag, setTag] = useState("");
const tagRef = useRef()
const TextRef = useRef();
const maxW = props.maxW
const handleAdd = (e) => {
e.preventDefault();
};
const Reminders = []
const handleSave = (e) => {
e.preventDefault();
const TextInput = TextRef.current.value;
const TimeInput = TimerRef.current.value;
const KickStart = kickStart.value;
const Units = units.value;
const Tag = tag.value;
const Wmax = maxW.current.value
const Reminder = {
Message: TextInput,
Starter: KickStart,
SendTime: TimeInput,
TimeUnits: Units,
Id: Tag
};
if (Reminders.length !== parseInt(Wmax)) {
Reminders.push(Reminder);
console.log(Reminders);
} else {
console.log("can not save any more Reminders");
}
};
const Remove = (e) => {
e.preventDefault();
if (Reminders.length > 0) {
Reminders.pop();
console.log(Reminders);
} else {
alert("Sorry, your sms reminders basket is now empty");
console.log(Reminders);
}
};
const handleSubmit = (e) => {
e.preventDefault();
};
return (
<div>
<form onSubmit={handleSubmit}>
<div className={classes.email}>
<div className={classes.split}>
<div className={classes.left}>
<div className={classes.lefthead}>settings</div>
<div className={classes.selectors}>
<div className={classes.time}>
<div className={classes.heads}>
when{" "}
<span
className={classes.add}
title="Click to start editing your reminders. one at a time"
>
<FButton onClick={handleAdd}>add</FButton>
</span>
</div>
<MySelect
placeholder="Select Time ..."
options={Determinants}
onChange={setKickStart}
/>
</div>
<div className={classes.trigger}>
<div className={classes.heads}>select trigger</div>
<div className={classes.tips}>
<div className={classes.tip1}>
<Input type="number" defaultValue="5" ref={TimerRef} />
</div>
<div className={classes.tip2}>
<MySelect
placeholder="Units ..."
options={RideTriggers.before}
onChange={setUnits}
/>
</div>
</div>
</div>
<div className={classes.tags}>
<div className={classes.heads}>select tag</div>
<MySelect
placeholder="Select Tag ..."
options={Tags}
onChange={setTag}
ref={tagRef}
/>
</div>
</div>
</div>
<div className={classes.right}>
<div className={classes.label}>
<div className={classes.a}>
<label htmlFor="body">Body</label>
</div>
<div className={classes.b}>
<FButton>+ variables</FButton>
</div>
</div>
<div className={classes.textarea}>
<TextArea id="body" className={classes.text} ref={TextRef} />
</div>
<div className={classes.bb}>
<div
className={classes.bbf}
title="Remove the immediate previously saved reminder from your basket"
>
<FButton onClick={Remove}>remove</FButton>
</div>
<div
className={classes.bbf}
title="Add this reminder to your basket in the order of first-saved is first-sent and last-saved is last-sent"
>
<FButton onClick={handleSave}>save</FButton>
</div>
</div>
</div>
</div>
<footer>
<div className={classes.footerbtn}>
<div className={classes.close}>
<FButton type={"submit"}>done</FButton>
</div>
{/* <div className={classes.close}>
<FButton>cancel</FButton>
</div> */}
</div>
</footer>
</div>
</form>
</div>
);
};
export default TextReminder;
export const DefaultColumnFilter11 = ({
column: {
filterValue,
setFilter,
preFilteredRows: { length },
},
}) => {
const [condVal, setcondVal] = useState("");
return (
<div>
<input
type="radio"
value=">"
name="cond"
onChange={(event) => setcondVal(event.target.value)}
/>{" "}
<
<br />
<input
type="radio"
value="<"
name="cond"
onChange={(event) => setcondVal(event.target.value)}
/>
>
<br />
<Input
value={filterValue|| ""}
onChange={(e) => {
setFilter( {condVal} && (e.target.value || undefined));
}}
placeholder={`${length}`}
/>
</div>
);
};
This is the code and I want to filter the column using radio button condition greater than ">" and less than "<" that should be applied to the input search.
Essentially I have some data that I would like to filter using radio buttons.
Selecting a button of a particular value should only cause those objects with that value as their property to be rendered.
Well, maybe this is happening because of how I wrote my code. That happen because I am still learning React and all the stuff that I use in the code yesterday.
I am not yet even implementing a react tracker for the loading ui.
The purpose
I want to make a contact form for a course facilitator, but it is much more complex because I need image, checkbox for the program they choose, etc. At least for me that is complex than my blog.
Things that I have tried
I have tried it in development, it works like a charm.
The build also works seeing no problem.
The page after the build can still be visited.
The warning in Chrome
I get a violation in almost all of it. like in click handler, setTimeout, input handler.
The error that I get is three right after I click anything.
Two of the error start with error, but the last one is uncaught error. Maybe that does not matter?
Disclaimer
I may have used some Indonesian language in my code for name and stuff.
import React, { Component } from 'react';
import axios from 'axios';
import Header from "../components/Header"
import Footer from "../components/Footer"
export default class Daftar extends Component{
constructor(){
super();
this.state={
enable: false,
name:'',
email:'',
telepon:'',
program:'',
tempat_lahir:'',
tanggal_lahir:'',
selectedFile:'',
selectedFile1:'',
}
this.handleInputChange = this.handleInputChange.bind(this);
this.handleInputChange1 = this.handleInputChange1.bind(this);
}
handleChange = event =>{
this.setState({ [event.target.name]:event.target.value });
}
handleInputChange(event) {
this.setState({
selectedFile: event.target.files[0],
})
}
handleInputChange1(event) {
this.setState({
selectedFile1: event.target.files[0],
})
}
onChange(event){
let day_list = this.state.program;
let check = event.target.checked;
let checked_day = event.target.value;
if(check){
this.setState({
program: [...this.state.program, checked_day]
})
}else{
var index = day_list.indexOf(checked_day);
if (index > -1) {
day_list.splice(index, 1);
this.setState({
program: day_list
})
}
}
}
componentDidUpdate( prevState) {
if (
( prevState.email !== this.state.email )||
( prevState.name !== this.state.name )||
( prevState.telepon !== this.state.telepon) ||
prevState.program !== this.state.program
) {
if (this.state.email ||
this.state.name ||
this.state.subject ||
this.state.message
) {
this.setState({ enabled: true });
} else {
this.setState({ enabled: false });
}
}
}
handleSubmit = event =>{
event.preventDefault();
const KK = new FormData()
KK.append('kartu-keluarga', this.state.selectedFile)
console.warn(this.state.selectedFile);
const ijazah = new FormData()
ijazah.append('ijazah', this.state.selectedFile1)
console.warn(this.state.selectedFile1);
let url = `${process.env.GATSBY_DIRECTUS_API_URL}/gemaclc/items/pendaftar?access_token=${process.env.GATSBY_DIRECTUS_TOKEN}`;
let url2 = `${process.env.GATSBY_DIRECTUS_API_URL}/gemaclc/files?access_token=${process.env.GATSBY_DIRECTUS_TOKEN}`;
let id_ijazah;
let id_item;
let id_kk;
axios.post(url, {
status:"published",
nama: this.state.name,
email: this.state.email,
telepon: this.state.telepon,
program_yang_dipilih: this.state.program,
tanggal_lahir: this.state.tanggal_lahir,
tempat_lahir: this.state.tempat_lahir,
})
.then(res => {
console.log(res)
id_item = res.data.data.id;
return axios.post(url2, KK, )
})
.then(res => {
console.log(res)
console.log(res.data.data.id)
id_kk = res.data.data.id;
return axios.post(url2, ijazah, )
})
.then(res => {
console.log(res.data.data.id)
id_ijazah = res.data.data.id;
console.log(id_ijazah)
return axios( `${process.env.GATSBY_DIRECTUS_API_URL}/gemaclc/items/pendaftar/${id_item}?access_token=${process.env.GATSBY_DIRECTUS_TOKEN}`,
{
method:"patch",
data :{
kartu_keluarga: id_kk,
ijazah:id_ijazah
},
})
})
.then(res =>{
console.log(res)
})
.catch(error => {
console.log(error)
});
};
render(){
let form = "daftar-form"
let div = "daftar-div"
let div1 = "daftar-div1"
let label1 = "daftar-label1"
let label2 = "daftar-label2"
let label3 = "daftar-label3"
let checkbox = "daftar-checkbox"
let email = "daftar-email"
let nama = "daftar-nama"
let p1 = "daftar-p1"
let submitDisable = "daftar-submit-disable"
let submit = "daftar-submit"
let programDiv = "daftar-program-div"
return(
<div>
<Header/>
<div className={div}>
<div className={div1}>
<h1>Formulir Pendaftaran </h1>
<form onSubmit={this.handleSubmit} className={ form}>
<label className={label1}>
<span>
<p className={p1}> Nama : </p>
</span>
<input type="username" name="name" onChange={this.handleChange}
className={nama}
/>
</label>
<label className={label2}>
<span>
<p className={p1}> Email : </p>
</span>
<input type="email" name="email" onChange={this.handleChange}
className={email}
placeholder="name#location.com"/>
</label>
<label className={label3}>
<span>
<p className={p1}> telepon : </p>
</span>
<input type="tel" name="telepon" onChange={this.handleChange} className={nama}
/>
</label>
<label className={label3}>
<span>
<p className={p1}> Tempat Lahir : </p>
</span>
<input type="text" name="tempat_lahir" onChange={this.handleChange} className={nama}
/>
</label>
<label className={label3}>
<span>
<p className={p1}> Tanggal Lahir : </p>
</span>
<input type="date" name="tanggal_lahir" onChange={this.handleChange} className={nama}
/>
</label>
<div className={programDiv}>
<h3>Program yang Di pilih :</h3>
<label >
<input type="checkbox" onChange={this.onChange.bind(this)} name="program" className={checkbox}value="1"/>
<span>
<p className={p1}> paket A </p>
</span>
</label>
<label >
<input type="checkbox" onChange={this.onChange.bind(this)} name="program" className={checkbox}value="2"/>
<span>
<p className={p1}> paket B</p>
</span>
</label>
<label >
<input type="checkbox" onChange={this.onChange.bind(this)} name="program" className={checkbox}value={3}/>
<span>
<p className={p1}> paket C </p>
</span>
</label>
<label >
<input type="checkbox" onChange={this.onChange.bind(this)} name="program" className={checkbox}value={4}/>
<span>
<p className={p1}> English Regular 3 bulan </p>
</span>
</label>
<label >
<input type="checkbox" onChange={this.onChange.bind(this)} name="program" className={checkbox}value={5}/>
<span>
<p className={p1}> English Camp </p>
</span>
</label>
<label >
<input type="checkbox" onChange={this.onChange.bind(this)} name="program" className={checkbox}value={6}/>
<span>
<p className={p1}> English Private </p>
</span>
</label>
</div>
<div >
<div >
<br /><br />
<br />
<div >
<div >
<label className="text-white"> Kartu keluarga:</label>
<input type="file" name="upload_file"
onChange={this.handleInputChange} />
</div>
</div>
<div >
<div >
<label >ijazah :</label>
<input type="file" name="upload_file"
onChange={this.handleInputChange1} />
</div>
</div>
</div>
</div>
{this.state.enabled?<input type="submit" value="Kirim" className={submit}
/>:<input type="submit" value="Kirim" className={submitDisable} disabled/>}
</form>
<div><pre>{JSON.stringify(this.state.program) }</pre></div>;
</div>
</div>
<Footer/>
</div>
)
}
}
i found it, i just update from
componentDidUpdate( prevState) {
if (
( prevState.email !== this.state.email )||
( prevState.name !== this.state.name )||
( prevState.telepon !== this.state.telepon) ||
prevState.program !== this.state.program
) {
if (this.state.email ||
this.state.name ||
this.state.subject ||
this.state.message
) {
this.setState({ enabled: true });
} else {
this.setState({ enabled: false });
}
}
}
to this
componentDidUpdate(prevProps, prevState) {
if (
( prevState.email !== this.state.email )||
( prevState.name !== this.state.name )||
( prevState.telepon !== this.state.telepon) ||
prevState.program_yang_dipilih !== this.state.program_yang_dipilih
) {
if (this.state.email ||
this.state.name ||
this.state.telepon ||
this.state.program_yang_dipilih
) {
this.setState({ enabled: true });
} else {
this.setState({ enabled: false });
}
}
}
I have worked on this problem for quite some time and I am at a lost on how to continue forward. I am trying to return a description of a stock when a certain symbol is entered into the input field. The console.log returns the value of the description when a symbols are entered but it doesn't render it to the page. I have tried to return the whole statement including the map function but that just cancels out my other return statement. I don't know what else to do. Can someone point me in the right direction?
Here is my code:
render() {
const { stockSymbol, userInput } = this.state
stockSymbol.map((stock, i) => {
if (userInput === stock.symbol) {
return <h2 className="symboldescription" key={i}>
{stock.description}
</h2>,
console.log(stock.description + " match")
}
})
return (
<div className="enterstock">
<h1 className="title">Enter Stock Symbol</h1>
<span className="symbol">{this.state.userInput}</span>
<form className="inputfields" onSubmit={this.getSymbol}>
<input type="text" className="symfields" name="symbolname" onChange={this.typeSymbol}></input>
<button type="submit" className="btn">Send</button>
</form>
</div >
)
}
}
You should be including it as part of the return statement for the render method. For example,
render() {
const { stockSymbol, userInput } = this.state;
return (
<div className="enterstock">
<h1 className="title">Enter Stock Symbol</h1>
<span className="symbol">{this.state.userInput}</span>
<form className="inputfields" onSubmit={this.getSymbol}>
<input type="text" className="symfields" name="symbolname" onChange={this.typeSymbol}></input>
<button type="submit" className="btn">Send</button>
</form>
{stockSymbol.map((stock, i) => {
if (userInput === stock.symbol) {
return <h2 className="symboldescription" key={i}>
{stock.description}
</h2>
}
})}
</div>
)
}
the return of your map is not assigned to a variable. You can assign to a variable, and then use in your return of component. something like this:
let description = stockSymbol.map((stock, i) => {
if (userInput === stock.symbol) {
return <h2 className="symboldescription" key={i}>
{stock.description}
</h2>,
console.log(stock.description + " match")
}
})
and then use in the return of component
return (
<div className="enterstock">
<h1 className="title">Enter Stock Symbol</h1>
<span className="symbol">{this.state.userInput}</span>
<form className="inputfields" onSubmit={this.getSymbol}>
<input type="text" className="symfields" name="symbolname" onChange={this.typeSymbol}></input>
<button type="submit" className="btn">Send</button>
</form>
{description}
</div >
)
I have a dialog window (div) with a form in it and an object which holds the data from the fields, if the user forgets to fill one of the fields the border of this field becomes red. My problem is that if the user closes the dialog window and reopens it the red borders are still there and the object holds information from before the closing. I am not sure how/if I need to clear the local storage or if there is a better solution so every time the window is closed the data structure and styles are defaulted. I use Bootstrap for the components.
import React from 'react';
const variables = {
varA: '', varB: '', varC: ''
};
let emptyFields = [];
const border = {
borderColor: '#C70039',
};
const submitForm = () => {
emptyFields = [];
if (Object.values(variables).includes('')) {
for (const [key, value] of Object.entries(variables)) {
if (value === '') {
emptyFields.push(key);
}
}
}
return emptyFields;
};
const Form = empty => (
<div>
<p className="text-primary">Please provide information in all of the fields.</p>
<form>
<div className="form-group mt-4" >
<label htmlFor="formGroupExampleInput">Var A </label>
<input type="text" className='form-control' id="varA" required onChange={(e) => { variables.varA = e.target.value; } } />
</div>
<div className="form-group">
<label htmlFor="formGroupExampleInput">Var B </label>
<input type="text" id="varB" className='form-control' style={empty.empty.includes('varB') ? border : null} onChange={(e) => { variables.varB = e.target.value; }}/>
</div>
<div className="form-group">
<label htmlFor="formGroupExampleInput">Var C </label>
<input type="text" className="form-control" id="varC" style={empty.empty.includes('varC') ? border : null} onChange={(e) => { variables.varC = e.target.value; }}/>
</div>
</form>
<button className="btn btn-primary" onClick={submitForm}>Submit</button>
</div>
);
const CompleteForm = () => <Form empty = {emptyFields} />;
export default CompleteForm;