render(){
let { classes } = this.props;
let list = classes.map((item, index) => {
return (
<option >{item}</option>
)
})
return(
<div className="filter-bar">
<form className="sort-form">
<div className="classSelect">
<span>select class</span>
<select name="classSelect" onChange={this.handleClassChange}}>
<option selected="selected" >Please choose class</option>
{list}
</select>
</div>
</form>
</div>
)
}
};
i want to map over an array and use each element as options in select dropdown, and also have an extra blank option which defaults until dropdown is clicked.
at the moment, the extra i have is available in the list, but default is always first element from array, whereas i want the default to be "Please choose your class"
can somebody explain?
render(){
const classes = [
'Lorem',
'Ipsum',
'dolor',
'Sit',
'ames'
]
let list = classes.map((item, index) => {
return (
<option >{item}</option>
)
})
return(
<div className="filter-bar">
<form className="sort-form">
<div className="classSelect">
<span>select class</span>
<select name="classSelect" onChange={this.handleClassChange.bind(this)}>
<option value="none" selected disabled hidden>
</option>
{list}
</select>
</div>
</form>
</div>
)
Like this?
Related
<select class="custom-select"
onChange={(e) => this.subCategory(e)}>
<option hidden value="">
Select Subcategory
</option>
{subcategoryConst}
Option are from API Mapping
const subcategoryConst =
this.state.subcategory.map((Data) => {
console.log("Data", Data.student_name);
return (
<>
<option value={Data.id}>{Data.start_surah} <br/>{Data.end_surah}</option>
</>
);
});
Can not Use <br/ tag and also not /n is working
I am adding a component to the dom based on the button click.
<button onClick={() => addQuestion("Template 1")}> Template 1 </button>
<button onClick={() => addQuestion("Template 2")}> Template 3 </button>
<button onClick={() => addQuestion("Template 3")}> Template 3 </button>
Also I have a select tag with the same value as button. If the user wish to change the type of, the option component will change.
<select id="q-type" onChange={(e)=>ChangeQType(e)}>
<option value="Template 1">Template 1</option>
<option value="Template 2">Template 2</option>
<option value="Template 3">Template 3</option>
</select>
What is working : If I change the value in select tag the expected component renders.
What is not working : If I press a button , the expected components renders but the order of the dropdown is not changing. I need the rendered component value on top of the dropdown.
If I press Template 2 button I need in this order
<select id="q-type" onChange={(e)=>ChangeQType(e)}>
<option value="Template 2">Template 2</option>
<option value="Template 1">Template 1</option>
<option value="Template 3">Template 3</option>
</select>
What i get :
<select id="q-type" onChange={(e)=>ChangeQType(e)}>
<option value="Template 1">Template 1</option>
<option value="Template 2">Template 2</option>
<option value="Template 3">Template 3</option>
</select>
you need to first remove item from array and again place it in first. Here, I have place data on state hook. It would be easier to understand.
import React, { useState } from 'react';
function App() {
const [templates, setTemplates] = useState(['Template 1', 'Template 2', 'Template 3']);
const addQuestion = (item) => {
let clone = [...templates];
let objIndex = clone.indexOf(item);
clone.splice(objIndex, 1);
setTemplates([item, ...clone]);
}
const ChangeQType = () => {
}
return (
<div className="App">
<button onClick={() => addQuestion("Template 1")}> Template 1 </button>
<button onClick={() => addQuestion("Template 2")}> Template 2 </button>
<button onClick={() => addQuestion("Template 3")}> Template 3 </button>
<hr />
<select id="q-type" onChange={(e) => ChangeQType(e)}>
{templates.map((item) => <option value={item}>{item}</option>)}
</select>
</div>
);
}
export default App;
Here I however tried to make the second div visible if a value is selected in the first dropdown. But I want to make a form where there will be 3 dropdown but only the first will be visible where the user will select any value and the 2nd dropdown will be accordingly. I even need to fetch the values using API. Here's an example of the form what I'm trying to make : https://donate.alauddintrust.com Thanking you!
import React from 'react';
import Section2 from '../Sections/Section2'
class App1 extends React.Component {
//set the statte default value
constructor(props) {
super(props);
this.state = {value: 'hide'};
}
// set the state value based on select option value
divstatus = (e) =>{
this.setState({value: e.target.value});
}
render() {
return (
<>
<div className="container">
<header class="page-header">
<h1 className={['text-warning']}>Donate <i>Now</i></h1>
</header>
<form className="donation-form form-horizontal container" id="donation-form">
<div id="donation-type-group" className="form-group">
<label htmlFor="recurrence">Donation Type <span className="required">*</span></label>
<select id="donation_type" onChange={this.divstatus} name="donation_type" className="form-control">
<option value="show">Select Donation Type</option>
<option value="hide">Sadaqa</option>
<option value="2">Fitrana</option>
<option value="3">Zakat</option>
<option value="4">Fidya</option>
<option value="5">Qurbani</option>
<option value="6">Donation</option>
<option value="15">Kaffara</option>
</select>
</div>
<div className={this.state.value}>
<div id="donation-type-group" className={['form-group']}>
<label htmlFor="recurrence">Programs<span className="required">*</span></label>
<select id="donation_type" name="donation_type" className="form-control">
<option value="">Select Donation Type</option>
<option value="1">Sadaqa</option>
<option value="2">Fitrana</option>
<option value="3">Zakat</option>
<option value="4">Fidya</option>
<option value="5">Qurbani</option>
<option value="6">Donation</option>
<option value="15">Kaffara</option>
</select>
</div>
</div>
<div class="text-center">
<button type="submit" class="btn btn-lg btn-primary">Submit donation</button>
</div>
</form>
<hr/>
<Section2 />
</div>
</>
)
};
}
export default App1;
I did somthing similar a while ago, you can display the first dropdown and onChange of the first dropdown trigger the API call to update the state to hold the options for the second dropdown, and in the second dropdown section when the api results are empty dont render the second dropdown (could use a (results) ?? <GoodComponent/> will only show if results not empty)
could also add a loading state value to disable the dropdowns in between API calls and listen to its changes using a useEffect hook
I have 3 drop downs primary, secondary,ternary categories, each dependent on each other, Initially I have 3 drop downs below that I have one button " add more" , after clicking "add more" again drops will come below the ones earlier have, now the question is first row drop down selection is working fine , after clicking "add more" the second row drop down selection is not working , means it changes the value of already selected first row of the second category same with the ternary category. first I all load all the primary category, based on primary id i will fetch secondary categories, based on the secondary category id i will fetch ternary category. please me with this.
HTML CODE
<div class="row Space_2">
<div class="col-md-4">
<select class="Textfield_2" id="primary_category_id" formControlName="primary_category_id" (change)="getSecondCategory($event.target.value)" name="primaryServices" required>
<option value="">Primary Service</option>
<option *ngFor="let primaryCat of primaryCategory" [value]="primaryCat.id">{{primaryCat.name}}</option>
</select>
</div>
<div class="col-md-4">
<select class="Textfield_2" id="secondary_category_id" formControlName="secondary_category_id" (change)="getTernaryCategory($event.target.value)" name="secondaryServices" required>
<option value="">Secondary Service</option>
<option *ngFor="let secondCat of secondCategory" [value]="secondCat.id">{{secondCat.name}}</option>
</select>
</div>
<div class="col-md-4">
<select class="Textfield_2" id="ternary_category_id" formControlName="ternary_category_id" name="secondaryServices" required>
<option value="">Ternary Service</option>
<option *ngFor="let ternaryCat of ternaryCategory" [value]="ternaryCat.id">{{ternaryCat?.name}}</option>
</select>
</div>
</div>
<div *ngFor="let k of addmoreServices let i = index">
<div class="row Space_2">
<div class="col-md-4">
<select class="Textfield_2" id="primary_category" (change)="getSecondCategory($event.target.value)" name="{{k.primary_category}}" required>
<option value="">Primary Service</option>
<option *ngFor="let a of primaryCategory" [value]="a.id">{{a?.name}}</option>
</select>
</div>
<div class="col-md-4">
<select class="Textfield_2" id="secondary_category" (change)="getTernaryCategory($event.target.value)" name="{{k.secondary_category}}" required>
<option value="">Secondary Service</option>
<option *ngFor="let b of secondCategory" [value]="b.id">{{b?.name}}</option>
</select>
</div>
<div class="col-md-4">
<select class="Textfield_2" id="secondary_category" (change)="getTerId($event.target.value)" name="{{k.ternary_category}}" required>
<option value="">Ternary Service</option>
<option *ngFor="let c of ternaryCategory" [value]="c.id">{{c?.name}}</option>
</select>
</div>
</div>
</div>
TypeScript Code:
getPrimaryCategory() {
this.http.get('http://localhost:3000/api/getPrimaryCategory' ,{
})
.subscribe(
res => {
this.primaryCategory = res['data'];
console.log(this.primaryCategory);
},
err => {
}
);
}
getSecondCategory(id,i) {
this.primcatId = id;
this.http.get('http://localhost:3000/api/getsecondarycatdataforternary/'+id ,{
})
.subscribe(
res => {
this.secondCategory = res['data'];
console.log(this.secondCategory);
},
err => {
}
);
}
getTernaryCategory(id) {
console.log("The ternary ID is",id);
this.secondId = id;
this.http.get('http://localhost:3000/api/getternaryCatforServices/'+id ,{
})
.subscribe(
res => {
this.ternaryCategory = res['data'];
console.log(this.ternaryCategory);
},
err => {
}
);
}
getTerId(id){
this.terid = id;
console.log("THE TERNARY ID IS",this.terid);
}
addMoreServices() {
this.addmoreServices.push({ primary_category:this.primcatId , secondary_category:this.secondId ,ternary_category: this.terid });
console.log("the add more services",this.addmoreServices);
}
You need to add trackBy to your *ngFor directives. You can track by id and thanks you this Angular won't treat values after refreshing as new values.
I am working on a React project where a list of books will be retrieved from the server.Each book has an option to be set into different shelves, like 1) Currently reading, 2) Want to read and 3) Read based on the user's experience with the book.Each book will have a dropdown where the 3 shelves will be mentioned.Once the user clicks on a shelf from the dropdown,the book will be shown on the selected shelf.So, I am able to retrieve the books from the API, but I am stuck at the point where the books will be set to the respective shelf once it is selected.
Code to retrieve all the books from the API:
import React, { Component } from 'react';
class BooksList extends Component {
state={
showSearchPage: false,
books: [],
selectedValue: 'None'
}
handleChange =(e) => {
this.setState({ selectedValue:e.target.value })
}
render() {
return(
{<div className="book-search">
{this.props.books.map( book =>
<div className="book">
<div className="book-top">
<div className="book-cover" style={{ width: 128, height: 193,margin:10, backgroundImage: `url(${book.imageLinks.smallThumbnail})` }}></div>
<div className="book-shelf-changer">
<select
value={this.state.selectedValue}
onChange={this.handleChange}>
<option value="none" disabled> Move to...</option>
<option value="currentlyReading">✔ Currently Reading</option>
<option value="wantToRead"> Want to Read</option>
<option selected="selected" value="read"> Read</option>
<option value="none"> None</option>
</select>
</div>
</div>
<div className="book-title">{book.title}</div>
<div className="book-authors">{book.authors}</div>
<p>{this.state.selectedValue}</p>
</div>
)}
</div>
}
Code for the Currently Reading shelf:
<div className="list-books-content">
<div>
<div className="bookshelf">
<h2 className="bookshelf-title">Currently Reading</h2>
<div className="bookshelf-books">
<ol className="books-grid">
{ this.props.books.map(book =>
<li>
<div className="book">
<div className="book-top">
<div className="book-cover" style={{ width: 128, height: 193, backgroundImage: `url(${book.imageLinks.smallThumbnail})` }}></div>
<div className="book-shelf-changer">
<select
value={this.state.selectedValue}
onChange={this.handleChange}>
<option value="none" disabled> Move to...</option>
<option value="currentlyReading">✔ Currently Reading</option>
<option value="wantToRead"> Want to Read</option>
<option selected="selected" value="read"> Read</option>
<option value="none"> None</option>
</select>
<p>{this.state.selectedValue}</p>
</div>
</div>
<div className="book-title">{this.state.currentlyReadingBooks}</div>
<div className="book-authors">{book.authors}</div>
</div>
</li>
)}
So what I was thinking of as a solution is : Do we have to create 3 arrays of books for three different sections and move the books to each section.Can anyone please help me with this.I am really stuck with this.I am not able to figure out how to proceed.
Once the user clicks on a shelf from the dropdown,the book will be shown on the selected shelf
This tells me that you probably don't need to store selectedValue in the react state; as soon as a dropdown action action is selected, simply "add" it.
So yes, I think what you describe makes sense - have three seperate arrays of books stored in the react state, and then in your handleChange function, append the book to the appropriate array.
(Side note: best practice in react is to copy the only array from your state instead of directly appending/mutating it.)