<span> cannot appear as a child of <select> in react - javascript

I have created a select dropdown component, which I am using in a redux-form in a react-redux app. The dropdown works great, and I have no impact to performance, but in the browser I receive the following warning.
Warning: validateDOMNesting(...): <span> cannot appear as a child of <select>.
I am not sure why I recieve this error, as I am not passing in any <span> elements. Here is the code I am using to create the select dropdown (options is an array of object that contains each option's attributes. option.text is a string value that will be viewed by the user. so it could be something like 'Option 1' or 'Option 2'.)
return (
<select {...other}>
<option /> {
options.map((option) => {
return <option key={option.value} value={option.value}>{option.text}</option>
})
} </select>
)
Any ideas on why I would be receiving this warning, and how I can rectify this. I am using react 0.14.3

It seems that some extra spaces in your jsx syntax have created a span.
I've tested your code, and after a correct re-indentation the error disappeared.
Before with the error: https://jsfiddle.net/snahedis/69z2wepo/28561/
And after re-indentation: https://jsfiddle.net/snahedis/69z2wepo/28564/

You have a variable re-definition issue. Your map function parameter is called "option", so when you write <option>, react would try to treat the object referred by the variable option as a react class. Try this instead -
return (
<select {...other}>
<option /> {
options.map((optionNode) => {
return <option key={optionNode.value} value={optionNode.value}>{optionNode.text}</option>
})
} </select>
)

Related

React-select deletes every selected option by mistake

I created a drop-down select with react-select. I import some defaultValues with this.returnLayers (an array with value/label couples) and I add the possible options from the state this.state.completeData.
Code :
<SettingRow>
<div className="selection">
<p>Sélectionner des couches</p>
<Select
defaultValue={this.returnLayers}
isMulti
name="layers"
onChange={(e) => { this.getLayers(e, this.state.categName) }}
className="basic-multi-select"
classNamePrefix="select"
options={this.state.completeData}
/>
</div>
</SettingRow>
Everything works well, until I try to delete one of the defaultValues. When I click on one of those options, all of the defaultValues disappear. The newly selected values stay though.
I followed exactly the code from the documentation, so I don't really understand what could be wrong. Is it impossible to delete the defaultValues ? Is there a workaround ?

VueJS two same components in a file, data change in one changes other's data?

I have created a VueJS component for dropdown.
<template>
<div>
<select v-bind:value="value" v-on:input="$emit('input', $event.target.value)">
<option v-for="(option, index) in dropdownOptions"
v-bind:key="index">
{{ option }}
</option>
</select>
</div>
</template>
<script>
export default {
props: {
dropdownOptions: Array,
value: String
},
mounted() {
this.value = this.dropdownOptions? this.dropdownOptions[0] : "";
}
}
</script>
And I have used it in parent as -
<div id="selectvideodropdown" class="col">
<Dropdown v-bind:dropdown-options="allVideos" v-model="selectedVideo">
</Dropdown>
</div>
<div id="selectvideodisplaymode" class="col">
<Dropdown v-bind:dropdown-options="allDisplayMode" v-model="selectedDisplayMode">
</Dropdown>
</div>
Parent's script -
<script>
import VideoPlayer from "./Videoplayer.vue"
import Dropdown from "../shared/Dropdown.vue"
export default {
components: {
VideoPlayer,
Dropdown
},
data() {
return {
allVideos: ["Video 1", "Video 2", "Video 3"],
allDisplayMode: ["With Bounding Box", "Without Bounding Box"],
selectedVideo: "",
selectedDisplayMode: "",
}
}
};
</script>
Weirdly, when I select the dropdown, it changes the current value of other dropdown to empty string. It only happens once after page load, and is not repeated again.
There are several issues here.
So, first, I’d recommend reading this which should help illuminate how v-model works.
Now, notice that v-model basically creates a two-way binding between data and a value attribute.
There’s a lot going on all at once, but the basic gist of it is that you’ve got data in your parent component that’s being bound to the value, but when you initialise each component you’re manually setting the value. When Vue updates everything, it ends up resetting the bound attribute in the other dropdown to the value being passed in from its v-model, which happens to be the empty string.
However, as a commenter mentioned, you’re also altering a property in the child component as if it were a data attribute, which is a very bad idea. Make that a separate data value.

React and Material CSS

I am using React and Material CSS.
I have a drop-down component ,like so
return (
<div>
<label>{label}</label>
<select {...input} className="browser-default">
<option />
{this.generateValues(indexes)}
</select>
</div>
);
}
}
I want to use the material-css look and feel ,but this component does not seem to work if I remove the "browser-default" className. How do I get around this ?
Try adding the Select initialization code into the componentDidMount() method.
componentDidMount(){
$('select').formSelect();
}
The better option would be to use the Input component with type 'select' from MaterializeCSS React component library.
You can use more than one className e.g.
className={"browser-default another-class"}

AngularJS ng-repeat filter function not filtering properly

I have ui-select2 dropdown that depends on the selection of a parent. I have a array of options for the first ui-select2, then when something is selected from that dropdown, the next dropdown will appear. The available options for the 2nd dropdown will depend on what is selected in the first dropdown. The ng-repeat directive is iterating over an array of choices. Here is the html and the js code.
HTML:
<select name="application" placeholder="Select a Tenant"
ng-disabled="!sharedObj.tenantApplications ||
sharedObj.tenantApplications.length == null"
class="form-control" id="application"
ng-change="vmOrderItem.vmNameUSI=null" ui-select2
ng-model="vmOrderItem.tenantApplication" title="Select tenant application"
data-style="btn-default" required><option></option>
<option ng-repeat="tenantApplication in sharedObj.tenantApplications |
filter:tenantFilter()" value="{{tenantApplication.id}}">{{tenantApplication.name}}
</option>
</select>
JS:
/** Filters the tenant depending on what domain is selected */
$scope.tenantFilter = function(tenantApplication) {
$scope.sharedObj.tenantApplications;
tenantApplication.name;
tenantApplication.id;
return true;
/* return $scope.vmOrderItem.domain.id == tenantApplication.domainId;*/
}
The issue I get is that even if I return true, nothing ever shows up on the dropdown. I did this to test the logic. I don't know why the tenantApplication parameter is always undefined in the function. I used google chrome inspect element to insert a breakpoint and it complains that the argument is undefined. But I don't see why it wouldn't work properly when I return true. I'm a newbie to JavaScript and AngularJS so any help is greatly appreciated. I've worked through all the AngularJS examples and read their docs but I'm still just a beginner.
Think this should be:
<option ng-repeat="tenantApplication in sharedObj.tenantApplications |
filter:tenantFilter" value="{{tenantApplication.id}}">

Select2 options in MeteorJS

I am trying to instantiate a multi-select box with Meteor JS and Select2. My html resides in a template as follows:
<template name="selectbox">
<select id="testbox">
<option value="AL">Alabama</option>
<option value="AL">Washington</option>
</select>
</template>
Within my client js I have the following code:
Template.selectbox.rendered = function(){
var options = { allowClear : true, multiple : true }
$("#testbox").select2(options);
};
Unfortunately my browser's console produces the following error:
Exception from Deps afterFlush function: Error: Option 'multiple' is not allowed for Select2 when attached to a <select> element.
I have also tried placing the following code directly in my client js file (as well as within Template.selectbox.create):
$(document).ready(function(){
var options = { allowClear : true, multiple : true }
$("#testbox").select2(options);
});
Unfortunately I receive the same error. The peculiar thing is I receive no error if my options are simply:
var options = { allowClear : true, placeholder : 'test' }
Neither option appears to take affect. However, The rendering of the select box is that of selct2.
Any idea what could be the issue? Thanks in advanced.
See how the example on select2 website is made. According to that code, you should add multiple attribute to the select tag, not to js method parameters.
So in your template replace <select id="testbox"> with <select multiple id="testbox">.

Categories

Resources