How to import Bootstrap components in React? - javascript

I'm trying to integrate checkboxes from bootstrap or reactstrap in React. I'm getting a common error, looked into relevant posts, still cannot figure it out. How do I fix this error:
Error Element type is invalid: expected a string (for built-in
components) or a class/function (for composite components) but got:
undefined. You likely forgot to export your component from the file
it's defined in, or you might have mixed up default and named imports.
Source of Error
The problem should be here in these two lines, which I'm not sure what it is.
import { InputGroup, InputGroupAddon, InputGroupText } from 'reactstrap';
import FormControl from 'react-bootstrap/FormControl';
If we'd remove these lines and the HTML copied below, it does not give any Error.
HTML
<div>
<InputGroup className="mb-3">
<InputGroup.Prepend>
<InputGroup.Checkbox aria-label="Checkbox for following text input" />
</InputGroup.Prepend>
<FormControl aria-label="Text input with checkbox" />
</InputGroup>
<InputGroup>
<InputGroup.Prepend>
<InputGroup.Radio aria-label="Radio button for following text input" />
</InputGroup.Prepend>
<FormControl aria-label="Text input with radio button" />
</InputGroup>
</div>
Demo
[Thanks! I'm new to React.]

prepend is one value of the addonType prop of InputGroupAddOn or InputGroupButton. it's not a property of the InputGroup import. InputGroup.Prepend is undefined, which is why React is complaining.
according to the reactstrap docs, you want this:
InputGroupAddOn.propTypes = {
tag: PropTypes.oneOfType([PropTypes.func, PropTypes.string]),
addonType: PropTypes.oneOf(['prepend', 'append']).isRequired,
className: PropTypes.string
};
InputGroupButton.propTypes = {
tag: PropTypes.oneOfType([PropTypes.func, PropTypes.string]),
addonType: PropTypes.oneOf(['prepend', 'append']).isRequired,
children: PropTypes.node,
groupClassName: PropTypes.string, // only used in shorthand
groupAttributes: PropTypes.object, // only used in shorthand
className: PropTypes.string
};

In your component you camelcase inputGroupAddOn when declaring the prop types. When you imported it you didn't camel case the add on part, you're importing InputGroupAddon. That might be another issue you're having.

The Latest version of reactstrap doesn't support the use of InputGroupAddon. Use it directly from bootstrap.
<div className="input-group-append">
<span className="input-group-text" id="basic-addon2">Search</span>
</div>

Related

VeeValidate 3.x get specific classes from ValidationProvider by name

I'm using Vee Validte 3.x in my Nuxt JS/Vue project. I need to be able to get the classes from a particular Validation Provider element by it's name or some unique identifier and output the classes object somewhere else on my page.
I'm struggling to figure out how, and thought a ref would work but didn't.
Here's my code:
<!-- Data Source (Table) (Validation Workaround) -->
<validation-provider
tag="div"
name="data source"
:rules="{ required: { allowFalse: false } }"
v-slot="{ errors, classes }"
>
<CustomInput
class="hidden-spans"
:options="editor.sources"
v-model="mockedCheckboxes.source.isChecked" />
<span class="block text-xs text-red-500 mt-1">{{ errors[0] }}</span>mockedCheckboxes.source.classes = classes" />
</validation-provider>
I'd like to be able to do something like:
this.$validator('data source').classes
Somewhere in my Vue file so that I can use the classes from one input elsewhere, this isn't working though.
this.$validator was actually removed in favor of ValidationObserver: https://vee-validate.logaretm.com/v3/migration.html#migrating-from-2-x-to-3-0
So far, if you try to validate something that is not directly in the component you're working on, you should watch the flags of the validation (errors) and update the status on a Vuex store. Then access Vuex back to decide if the input is valid and proceed further.
There is no global validation to my knowledge.

why selected option is hidden in react?

I made a simple demo of form using react material, in which I have only one select field .I used this link to make select option
https://material-ui.com/demos/selects/
using api I am able to show label at top (using this shrink={true})and show disabled value using this displayEmpty.
so my form look like this without any validation
https://codesandbox.io/s/8x4wnjnrz8
Now i try to validate my form using this plugin
https://www.npmjs.com/package/react-material-ui-form-validator
but my default option is hidden and select box label is also look awkward and with become small
here is my code
https://codesandbox.io/s/8x4wnjnrz8
import ReactDOM from "react-dom";
import React from "react";
import PropTypes from "prop-types";
import { withStyles } from "#material-ui/core/styles";
import Input from "#material-ui/core/Input";
import InputLabel from "#material-ui/core/InputLabel";
import MenuItem from "#material-ui/core/MenuItem";
import FormHelperText from "#material-ui/core/FormHelperText";
import { FormControl, Button } from "#material-ui/core";
import Select from "#material-ui/core/Select";
import "./styles.css";
import {
ValidatorForm,
TextValidator,
SelectValidator
} from "react-material-ui-form-validator";
function App() {
return (
<div className="App">
<ValidatorForm onSubmit={() => {}} className="" autoComplete="off">
<FormControl>
<InputLabel shrink={true} htmlFor="age-simple">
Age
</InputLabel>
<SelectValidator
required
value=""
name="name"
displayEmpty
validators={["required"]}
errorMessages={["this field is required", "email is not valid"]}
inputProps={{
name: "age",
id: "age-simple"
}}
input={<Input id="age-simple" />}
className=""
>
<MenuItem value="">
<em>None</em>
</MenuItem>
<MenuItem value={10}>Ten</MenuItem>
<MenuItem value={20}>Twenty</MenuItem>
<MenuItem value={30}>Thirty</MenuItem>
</SelectValidator>
</FormControl>
<Button type="submit"> submit</Button>
</ValidatorForm>
</div>
);
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
You have three issues that are preventing your select component from working properly.
You've created a functional (stateless) component. Learn More.
The dropdown component is not provided an onChange, so when you're selecting an option, the component is not doing anything to register this new state.
Even if you were storing the dropdown state using an onChange, you're passing a null value={} to your component.
Here's a working solution which contains solutions to those three issues:
https://codesandbox.io/s/j2855wrmq5
Notice that I've converted your functional component to a Class. You can read more about the conversion process here.
Now that your component is a Class, it can have state. This means two things, we're now handling the onChange event by setting our state to the provided value, and we're injecting this value into our component so it can display your selection value.
If I understand your issue correctly,
You are unable to see the default value (i.e. None) as selected.
Label is messed up.
Below are the reason(s):
The selected value you have mentioned is empty string (""). Change it to a valid value (Non Empty).
But the tweak here is if you have a default value, the validator passes as the set has a valid value. Not sure why you are trying to get the validator in this situation.
The way the validator works is slightly different. It accepts TextField component and renders it as select.
So label needs to be sent as props.
Below is the sample code (Adding external link as inbuilt snippet runner doesn't support)
Hope this helps

Vue.js component method "not defined on the instance"

I'm learning vue.js and used vue-cli to setup a new project. Now I tried adding a method to a component but something is wrong:
<template>
<div>
<div v-for="task in $state.settings.subtasks">
<input type="text" v-model="task.text">
<input type="text" v-model="task.assignedTo">
<input type="button" v-on:click="removeTask(task)">
</div>
</div>
</template>
<script>
export default {
name: 'settings',
methods:{
removeTask:function(task){
console.log("remove task");
}
}
}
Clicking the button should call the removeTask function but it just outputs an error in the console:
[Vue warn]: Property or method "removeTask" is not defined on the instance but referenced during render. Make sure that this property is reactive, either in the data option, or for class-based components, by initializing the property. See: https://v2.vuejs.org/v2/guide/reactivity.html#Declaring-Reactive-Properties.
found in
---> <Settings> at src/views/Settings.vue
<App> at src/App.vue
<Root>
What is wrong here?
When I went back to my question I noticed I was missing the </script> end tag. Adding that solved my problem.

Where is the datepicker in material ui next?

I am try use next branch of material ui https://github.com/callemall/material-ui/tree/next. Because i want use layout component. But i can not find DatePicker component!
How use DatePicker in next branch?
import {DatePicker} from 'material-ui'
WARNING in ./app/Resources/js/components/FormConstructor/Field.js
208:47-57 "export 'DatePicker' was not found in 'material-ui'
Firstly, I am in the same boat. And I dearly miss the DatePicker from the stable release of material-ui (dated 10/04/2018). I too upgraded to the #next, at the moment at v1.0.0-beta.41 and reached the state of shock to not have found the elegant DatePicker.
This is what I have noticed and now changing to -
https://material-ui-next.com/demos/pickers/
It has a date picker, which is actually based out of the TextField component having the type set to "date".
Copying as is -
<TextField
id="date"
label="Birthday"
type="date"
defaultValue="2017-05-24"
className={classes.textField}
InputLabelProps={{
shrink: true,
}}
/>
A small suggestion would be to check if the path exists under the local node_modules. You can also quickly check the component catalogue (at https://material-ui-next.com/) for the version you are using.
Hope this helps.
At the moment to write this answer (2017-06-12) it's still not supported. See https://material-ui-1dab0.firebaseapp.com/getting-started/supported-components
As an alternative to the native controls you can use the Mobiscroll Calendar and Date picker.
Pretty customizable and comes with material styling that fits well with the general look & feel.
Calendar component
Date picker component
Full disclosure: this is a commercial component, and I am one of the makers, just though it could help someone looking for a solution.
Import as DatePickers, TimePickers, DateAndTimePickers in latest material-ui version V1.0.0-beta.26.
Eg:
import {DatePickers, TimePickers, DateAndTimePickers} from 'material-ui';
Importing Datepicker as like below is no more valid in latest version.
Eg:
import DatePicker from 'material-ui/DatePicker';
You can check out here where I did an example of creating a datepicker using material-ui (next branch)
You can either import the component or just check out the source code to learn how to create a datepicker on your own
use this
import DatePicker from 'material-ui/DatePicker';
also visit this link for completed details about material-ui date-picker.
Don't forget to install material-ui i.e npm install --save material-ui
sample code below
const DatePickerExampleSimple = () => (
<div>
<DatePicker hintText="Portrait Dialog" />
<DatePicker hintText="Landscape Dialog" mode="landscape" />
<DatePicker hintText="Dialog Disabled" disabled={true} />
</div>
);
export default DatePickerExampleSimple;

Aurelia-dialog using attach-focus on custom element

I'm trying to pass attach-focus="true" to one of the inner elements of a custom element so that the correct element will receive the focus when aurelia-dialog opens.
Custom element: enum-list.html
<template>
<label class="control-label">${label} DEBUG: ${attach-focus}</label>
<select class="form-control" value.bind="value" attach-focus.bind="attach-focus">
<option if.bind="data" repeat.for="code of data | keys" value="${code}">${data[code]}</option>
</select>
</template>
Custom element: enum-list.js
import { bindable, bindingMode } from 'aurelia-framework';
export class EnumListCustomElement {
#bindable label;
#bindable data;
#bindable attach-focus; // <-- Maybe the source of the error?
#bindable({ defaultBindingMode: bindingMode.twoWay }) value;
}
Dialog template: edit-locale.html:
<template>
<ai-dialog>
<ai-dialog-header class="modal-header modal-header-success">
<h4 class="modal-title">Edit Locale</h4>
</ai-dialog-header>
<ai-dialog-body>
<form>
<enum-list attach-focus="true" label="Language" data.bind="core.enums.SystemLanguage" value.bind="sch_lang"></enum-list>
<enum-list label="Currency" data.bind="core.enums.CurrencyCode" value.bind="sch_currency"></enum-list>
</form>
</ai-dialog-body>
<ai-dialog-footer>
<button type="button" click.trigger="dialogController.cancel()">Cancel</button>
<button type="button" click.delegate="dialogController.ok()">Save</button>
</ai-dialog-footer>
</ai-dialog>
</template>
Instantiation (from my VM js):
this.dialogService.open({ viewModel: EditLocale, model: this.record, lock: true }).then(response => {
The modal dialog loads fine if I remove the dashes from attach-focus in edit-locale.js and inside the custom element. But with the dash, I'm getting an error: Uncaught SyntaxError: Unexpected token import. I think the dash is interfering but I don't know how to fix it.
My preference is to fix it so that the instantiation of the custom control has the standard parameter attach-focus="true" (with the dash) so that it's consistent with normal elements like INPUT and SELECT.
You are right about the source of the error, you can't have a property-name containing a dash. Because it reads as property - name.
There is a convention in aurelia (link to docs, search for dash-case) to map attributes and elements name from dash notation to camelCase notation, so if in your model you will name your bindable property as #bindable attachFocus - you will be able to use it in you views as attach-focus.bind="true".
Also make sure that you <require> your custom elements/attributes in your views or make them globally available when configuring aurelia.

Categories

Resources