Setting options of a select option from API - javascript

I'm trying to read my options from an API so I made a Const InputResponse as follow:
const inputResponse = [
{
key: 'news',
value: "news",
datagrid:{
w:2,
h:9,
x:0,
y:0,
minW:2,
minH:5
}
},
{
key: 'clock',
value: "clock",
datagrid:{
w:2,
h:5,
x:5,
y:0,
minW:2,
minH:5
}
}
]
but I have no clue how to effect my select option
<Select defaultValue="" style={{ width: 120 }} onChange={this.handleChange} >
<Option value="Clock" className="options">Clock</Option>
<Option value="News" className="options">News</Option>
<Option value="Yiminghe" className="options">yiminghe</Option>
</Select>
the capital starting letters in jsx tags are for ant design

You have to iterate the array and just render it as is.
Like this:
<Select style={{ width: 120 }} onChange={this.handleChange}>
{
this.inputResponse.map((item) => {
return <Option value={item} key={item.key} className="options">{item.value}</Option>
})
}
</Select>

Related

How to use onChange in multi-select react form?

In case of multi-select , can someone help me with the onChange function ?
What can I pass inside updateFormState( ) to make the code work. Thanks.
const formState = {
fruits: "",
};
function updateFormState(key, value) {
formState[key] = value;
}
const [fruits] = useState([]);
<Form.Label>fruits</Form.Label>
<MultiSelect
options={[
{ label: "Grapes 🍇", value: "grapes" },
{ label: "Mango 🥭", value: "mango" },
{ label: "Strawberry 🍓", value: "strawberry", disabled: true },
]}
id="fruits"
labelledBy="Select"
value={fruits}
onChange={(e) => updateFormState( )}
/>
</Form.Group>
hi try this i hope it usefull
const [fruits, setFruits] = useState();
console.log("fruits",fruits);
return (
<div>
<select onChange={(e) => setFruits(e.target.value)} value={fruits}>
<option value='' selected disabled hidden>
select a fruits
</option>
<option value='apple'>apple</option>
<option value='banana'>banana</option>
<option value='orange'>orange</option>
</select>
</div>
);

How to update value in dropdown based on text selection

I am working on a React-based Google Docs clone as a side project. I'm using TipTap as the base.
I wanted to try to mimic the functionality in Google Docs where the select field would update with the appropriate value based on whatever text the user selects (ex., "heading 1" would show up on
the select field if a user highlights text with <h1></h1> styling).
Here's a small video of the functionality I want to mimic: https://i.gyazo.com/18cc57f0285c8c5cd80d5dd6051f0ee7.mp4
This is the code I have so far with the React Hook used for the select fields:
const [font, setFont] = useState('sans-serif')
const handleFontChange = (e) => {
setFont(e.target.value)
editor.chain().focus().setFontFamily(e.target.value).run()
}
return (
<select value={font} onChange={handleFontChange}>
{fontFamilies.map((item) => <option key={item.value} value={item.value}>{item.label}</option>)}
</select>
)
I've tried to wrap my head around React Hooks and the Selection API, but I'm stuck. Is this at all possible in Javascript/React?
EDIT:
I found a function from Tiptap's API that does exactly what I'm looking for. I guess now the problem is how do I update that value into the select? Here's my new code:
const font = [
{ value: 'sans-serif', label: 'Sans-serif' }, ...
]
const [selectedFont, setSelectedFont] = useState([])
const handleFontChange = (obj) => {
setSelectedFont(obj)
editor.chain().focus().setFontFamily(obj.value).run()
console.log(editor.isActive('textStyle', {fontFamily: selectedFont.value})) // prints true if the user clicked on text with the property active, otherwise prints false
}
return (
<Select
name="fontFamily"
options={font}
isClearable="true"
isSearchable="true"
value={selectedFont}
onChange={(option) => handleFontChange(option)}
/>
)
It feels like the solution is really simple but I'm just overthinking it.
So I finally figured out what to do. I needed to pass a function in value that iterated over the array:
const fontList = [
{ label: 'Sans-serif', value: 'sans-serif' },
...
]
<Select
name="fontFamily"
placeholder="Select font..."
value={
editor.isActive('textStyle', {fontFamily: font}) ? (
selectedFont.find(index => fontList[index])
) : ''
}
options={fontList}
onChange={({value: fontSel}) => {
setFont(fontSel)
editor.chain().focus().setFontFamily(fontSel).run()
}}
/>
It only took me a whole week of tearing my hair out... Glad to finally get this done.
Just to add to this, I was able to do the following in Vue to select headings with a dropdown.
<select
:value="editor.isActive('heading') ? editor.getAttributes('heading').level : 0"
#input="setSelectedHeading"
>
<option
v-for="heading in headings"
:key="heading.value"
:label="heading.label"
:value="heading.value"
/>
</select>
headings: [
{ value: 0, label: 'Normal text' },
{ value: 1, label: 'Heading 1' },
{ value: 2, label: 'Heading 2' },
{ value: 3, label: 'Heading 3' },
{ value: 4, label: 'Heading 4' },
{ value: 5, label: 'Heading 5' },
{ value: 6, label: 'Heading 6' }
]
setSelectedHeading (selected) {
if (selected === 0) {
const selectedLevel = this.editor.getAttributes('heading').level
return this.editor.chain().focus().toggleHeading({ level: selectedLevel }).run()
}
return this.editor.chain().focus().setHeading({ level: selected }).run()
}
In case someone wants to create a simple dropdown menu with vue and tiptap, since this doesn't seem to work:
<select class="font-type">
<option #click="editor.chain().focus().setParagraph().run()" selected>Paragraph</option>
<option #click="editor.chain().focus().toggleHeading({level: 1}).run()">Heading 1</option>
<option #click="editor.chain().focus().toggleHeading({level: 2}).run()">Heading 2</option>
<option #click="editor.chain().focus().toggleHeading({level: 3}).run()">Heading 3</option>
</select>
you can do this:
<select class="font-type" #change="toggleType(editor, $event)">
<option value="p" selected>Paragraph</option>
<option value="1">Heading 1</option>
<option value="2">Heading 2</option>
<option value="3">Heading 3</option>
</select>
and add this to your <script>:
const toggleType = (editor, event) => {
if (event.target.value == 'p') {
editor.chain().focus().setParagraph().run()
} else {
editor.chain().focus().toggleHeading({level: Number(event.target.value)}).run()
}
}

Selector from material-ui doesn't work for me?

I try to implement example of material-ui selector and got code-fragment from github example
import React from "react";
import {withStyles} from "material-ui/styles";
import Select from "material-ui/Select";
import styles from "../../overtimesStyles";
class DivisionReport extends React.Component {
state = {
selectedOption: "",
}
handleChange = (selectedOption) => {
this.setState({selectedOption});
// selectedOption can be null when the `x` (close) button is clicked
if (selectedOption) {
console.log(`Selected: ${selectedOption.label}`);
}
}
render() {
const {selectedOption} = this.state;
return (
<Select
name="form-field-name"
value={selectedOption}
onChange={this.handleChange}
options={[
{value: "one", label: "One"},
{value: "two", label: "Two"},
{value: "333", label: "One"},
{value: "444", label: "444"},
{value: "555", label: "555"},
{value: "666", label: "666"},
]}
/>
);
}
}
export default withStyles(styles)(DivisionReport);
But there is no items for selection which I expected to see:
Can you suggest why I met with this issue?
p.s. top component, which use DivisionReport is:
const OvertimesReport = ({handleChangeSelection, selectedOption, classes}) => (
<div className={classes.workarea}>
<Card>
<CardContent className="overtimes">
<DivisionReport handleChangeSelection={handleChangeSelection} selectedOption={selectedOption}/>
</CardContent>
</Card>
</div>
);
style is:
workarea: {
margin: "0px 5%",
},
You are trying to import the Select component from material-ui/Select, but you should import if from the react-select package instead:
import Select from "react-select";
Also note that the value key of an option is named value and the label key is named label, not valueKey and labelKey.
<Select
name="form-field-name"
value={selectedOption}
onChange={this.handleChange}
options={[
{value: "one", label: "One"},
{value: "two", label: "Two"},
{value: "333", label: "One"},
{value: "444", label: "444"},
{value: "555", label: "555"},
{value: "666", label: "666"},
]
}
/>
import Select from '#material-ui/core/Select';
Then in the render:
<Select
native
name="form-field-name"
value={selectedOption}
onChange={this.handleChange}
>
<option key="1" value="1"> 1 </option>
<option key="2" value="2"> 2 </option>
<option key="3" value="3"> 3 </option>
</Select>
Try this way, and let me know how it works

Vue js populate new selects when changing the main one

I need your help about populating or loading new select with vue js, I know how to do this with jquery but in vue i don't know how because i'm new with this library.
i have the main select :
<select>
<option value='3'>FRANCE</option>
<option value='5'>USA</option>
<option value='6'>CANADA</option>
<option value='8'>MOROCCO</option>
</select>
I want that if i choose FRANCE i get a select of FRANCE cities from database, and also when i select USA i get an other select of USA cities from database.
So for example i will get :
<select>
<option value='6'>CANADA</option>
<option value='8'>MOROCCO</option>
</select>
<select>
<option value='34'>France city one</option>
<option value='35'>France city two</option>
</select>
<select>
<option value='3'>Usa city one</option>
<option value='5'>Usa city two</option>
</select>
When choosing France and USA i will populate select of cities with an array
I appreciate any help, I don't realy know how can i do this with vue js,
I don't want add all select of cities in my html because i don't know how much countries i have.
I tried this but this not resolve my probleme :
const addProduct = new Vue({
el: '#addProduct',
data: {
name: '',
name_url: '',
cities: '',
countries: [],
range: 0
},
created: function () {
this.$http.get('/api/countries').then(response => {
this.countries = response.data
}, response => {
});
},
methods: {
addForm: function(val, data) {
this.range += 1;
alert(this.range)
var index = _.findIndex(this.countries,{city_id: val});
this.countries.splice(index, 1)
}
},
watch: {
'cities' (val, oldVal) {
this.$http.post('/api/cities/values', {city_id:val}).then(response => {
this.addForm(val, response.data);
}, response => {
});
}
}
});
in html :
<div class="uk-grid" data-uk-grid-margin>
<div class="uk-width-medium-1-4">
<label for="attribute">Countries</label>
<md-select name="country" id="country" v-model="country">
<md-option v-for="country in countries" :value="country.country_id">#{{ country.name }}</md-option>
</md-select>
</div>
</div>
<div class="uk-grid" data-uk-grid-margin>
<my-cities v-for="n in range"></my-cities>
</div>
<script type="x-template" id="my-cities">
<div class="uk-width-medium-1-4">
<label for="attr">Cities</label>
<md-select name="attr" id="attr" v-model="attr">
<md-option value="">Select </md-option>
<md-option value="val in values">Select</md-option>
</md-select>
</div>
</script>
an example like this on Jsfiddle : http://jsfiddle.net/pu8pp62v/3/
This is an example that you can maybe use (but need some modifications to use your API call) :
new Vue({
el: "#app",
data: function() {
return {
selectedCountries: [],
selectOptionsCountries: [
{ value: 3, name: 'FRANCE' },
{ value: 5, name: 'USA' },
{ value: 6, name: 'CANADA' },
{ value: 8, name: 'MOROCCO' }
],
selectedCities: [],
selectOptionsCities: []
}
},
methods: {
},
watch: {
selectedCountries: function(newValue, oldValue) {
this.selectOptionsCities = [];
this.selectedCities = [];
for( var i = 0, length = newValue.length; i < length; i++ ){
this.selectedCities[i] = [];
if( newValue[i] === 3 ){
this.selectOptionsCities.push(
[{ value: 31, name: 'Paris' },
{ value: 32, name: 'Marseille' }]
)
}
if( newValue[i] === 5 ){
this.selectOptionsCities.push(
[{ value: 51, name: 'New-York' },
{ value: 52, name: 'Boston' }]
)
}
if( newValue[i] === 6 ){
this.selectOptionsCities.push(
[{ value: 61, name: 'Montreal' },
{ value: 62, name: 'Vancouver' },
{ value: 63, name: 'Ottawa' },
{ value: 64, name: 'Toronto' }]
)
}
if( newValue[i] === 8 ){
this.selectOptionsCities.push(
[{ value: 81, name: 'Rabat' },
{ value: 82, name: 'Casablanca' },
{ value: 83, name: 'Fes' }]
)
}
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.2.5/vue.js"></script>
<div id="app">
Selected countries : {{ selectedCountries }}
<br />
Selected cities : {{ selectedCities }}
<br />
<select v-model="selectedCountries" multiple>
<option v-for="(option, index) in selectOptionsCountries" :value='option.value'>
{{ option.name }}
</option>
</select>
<select v-for="(optionsCities, index) in selectOptionsCities" v-model="selectedCities[index]" multiple>
<option v-for="(option, index) in optionsCities" :value='option.value'>
{{ option.name }}
</option>
</select>
</div>
Added after author's comment:
Check this fiddle: http://jsfiddle.net/jjpfvx5q/1/
Inside 'chosenCities' array you have all selected cities by country (one city per country.)
Original answer:
Here is an example for you: fiddle
Is that what you are trying to achieve?
setTimeout functions are just pretending a real data fetching.
<script src="//unpkg.com/vue/dist/vue.js"></script>
<div id="app">
<template>
<div>
<select v-model="country">
<option disabled value="">Please select one</option>
<option
v-for="c in countries"
:value="c.id">{{ c.name }}</option>
</select>
<span>Selected: {{ country }}</span>
<span v-if="cities.length">Cities:</span>
<ul v-if="cities.length">
<li v-for="c in cities">{{ c }}</li>
</ul>
</div>
</template>
</div>
<script>
var Main = {
data() {
return {
country: {},
countries: [],
cities: [],
coInit: [{ id: '3', name: 'France' }, { id: '2', name: 'USA' }],
cFrance: ['Paris', 'Whatever'],
cUSA: ['NY', 'LA']
}
},
methods: {
loadCountries: function () {
setTimeout(() => { this.countries = this.coInit }, 500);
},
getCities: function() {
if(this.country) {
switch (this.country) {
case '3':
setTimeout(() => { this.cities = this.cFrance }, 500);
break;
case '2':
setTimeout(() => { this.cities = this.cUSA }, 500);
break;
}
}
}
},
mounted() {
this.loadCountries();
},
watch: {
country: function() {
this.getCities();
}
}
}
var Ctor = Vue.extend(Main);
new Ctor().$mount('#app');
</script>

Dynamically change select input options in vuejs 2

How to change dynamically the options in a select dropdown v-model ?
I have 2 select inputs, one should change according to the others.
For example, if i select "fruits" the select display the fruits, if i select "vegetables" it displays the vegetables.
I don't use Vuejs, but after looking at the documentation:
var TypesArr = {
Fruit: [{ text: 'Apple', value: 'Apple' }, { text: 'Orange', value: 'Orange' }, { text: 'Mango', value: 'Mango' }],
Meat: [{ text: 'Steak', value: 'Steak' }, { text: 'Pork', value: 'Pork' }]
}
var selectTwo = new Vue({
el: '#select2',
data: {
selected: TypesArr['Fruit'][0],
options: TypesArr['Fruit']
},
methods: {
update: function (value)
{
this.options = TypesArr[value]
}
}
})
new Vue({
el: '#select1',
data: {
selected: 'Fruit',
options: [ { text: 'Fruit', value: 'Fruit' }, { text: 'Meat', value: 'Meat' } ]
},
methods: {
onChange: function (event)
{
selectTwo.update(event.srcElement.value)
}
}
})
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<select v-on:change="onChange" id="select1">
<option v-for="option in options" v-bind:value="option.value">
{{ option.text }}
</option>
</select>
<select id="select2">
<option v-for="option in options" v-bind:value="option.value">
{{ option.text }}
</option>
</select>
The other answers are not really 'Vue' answers.
How you handle this depends on what you want to do with the select box. I'm assuming you'll to handle the input on a form.
Two options:
Use a Computed property
Use v-if to show different select boxes. This would be ideal if each select box has a different v-model
Computed Property
<template>
<div class="container">
<select id="firstInput" v-model="selected">
<option v-for="option in firstInputOptions" :value="option">
{{ option }}
</option>
</select>
<select id="secondInput" v-model="secondInputSelected">
<option v-for="option in secondInputOptions" :value="option">
{{ option }}
</option>
</select>
</div> <!-- /container -->
</template>
<script>
export default {
computed: {
secondInputOptions(){
return this.selected === 'fruit' ? this.fruit : this.vegetables
}
},
data () {
return {
fruit: ['apple', 'banana', 'orange'],
vegetables: ['carrot', 'beet', 'celery'],
firstInputOptions: ['fruit', 'vegetables']
selected: 'fruit',
secondInputSelected: ''
}
},
}
</script>
Conditional Rendering
<template>
<div class="container">
<select id="firstInput" v-model="selected">
<option v-for="option in firstInputOptions" :value="option">
{{ option }}
</option>
</select>
<select id="secondInputFruit" v-model="selected" v-if="selected == 'fruit'">
<option v-for="option in secondInputOptions" :value="option">
{{ option }}
</option>
</select>
<select id="secondInputVegetables" v-model="vegetableSelected" v-else-if="selected == 'vegetables'">
<option v-for="option in secondInputOptions" :value="option">
{{ option }}
</option>
</select>
</div> <!-- /container -->
</template>
<script>
export default {
data () {
return {
fruits: ['apple', 'banana', 'orange'],
fruitSelected: '',
vegetables: ['carrot', 'beet', 'celery'],
vegetableSelected: '',
firstInputOptions: ['fruit', 'vegetables']
selected: 'fruit'
}
},
}
</script>
Using pure javascript
var typesArr = {fruit: ['Apple', 'Orange', 'Mango'], meat: ['Steak', 'Pork']}
function changeContext(value)
{
if (typesArr.hasOwnProperty(value)) {
var out = ''
for (var i = 0; i < typesArr[value].length; i++) {
out += '<option value="' + typesArr[value][i] + '">' + typesArr[value][i] + '</option>'
}
document.getElementById('select2').innerHTML = out
}
}
changeContext('fruit')
<select onchange="changeContext(this.value)">
<option value="fruit">Fruit</option>
<option value="meat">Meat</option>
</select>
<select id="select2"></select>

Categories