defaultValue in AOR-dependent-input - admin-on-rest

I want to set defaultValue for field in aor-dependent-input,
I already set defaultValue for ReferenceInput, but how can I set defaultValue for DependentInput using SubGenreInput
Here is my code:
<Create {...propsEdit} title=" " actions="">
<SimpleForm redirect={"/caregiver/" + cid}>
{/*<ReferenceArrayInput>*/}
<DisabledInput source="user" defaultValue={cid} label="Caregiver ID"/>
<ReferenceInput label="Centre" source="centre" defaultValue={this.props.record.student.centre.id} reference="centre" sort={{ field: 'name', order: 'ASC' }} allowEmpty>
<SelectInput optionText="name" />
</ReferenceInput>
<DependentInput dependsOn="centre">
<SubGenreInput source="current_group" optionText="label" optionValue="id" type="classgroup"/>
</DependentInput>
<DependentInput dependsOn="current_group" defaultValue={this.props.record.student.id}>
<SubGenreInput source="student_id" optionText="fullname" optionValue="id" type="student"/>
</DependentInput>
{/*</ReferenceArrayInput>*/}
<RadioButtonGroupInput source="account_type" defaultValue={10} choices={[
{ id: 10, name: 'Caregiver' },
{ id: 20, name: 'Guardian' },
]} optionText="name" optionValue="id" />
<TextInput source="relationship" label="Relationship"/>
</SimpleForm>
Interface:
https://i.stack.imgur.com/wFHKC.png
// I'm not allow to post the images :(

This is a known issue which will be addressed by version 1.3.0 of admin-on-rest. In the mean time you can use this workaround:
<DependentInput source="appointmentTimeslot" dependsOn="planned" defaultValue={1}>
<ReferenceInput source="appointmentTimeslot" reference="timeslots" allowEmpty={true} >
<SelectInput optionText="name" optionValue="id" />
</ReferenceInput>
</DependentInput>
Note that we specified source on both the DependentInput component and its child. The defaultValue, however, is specified on the DependentInput component only.
This workaround won't work if you pass multiple children to the DependentInput component.

Related

How can I check react-datepicker value with react-hook-form?

I have a register form and use react-hook-form for validation. I want to give an error message if under 15 years old. Is this possible?
here is the picker code
<DatePicker ref={ref} name="birthday" dateFormat="dd/MM/yyyy" disabled={disabled}
selected={startDate || value}
onChange={date => onChangePicker(date)}
maxDate={addDays(new Date()), 1)}
onFocus={() => { focusInput() }}
onBlur={(e) => { blurInput(e) }}
autoComplete="off"
customInput={
<MaskedInput
mask={[/\d/, /\d/, '/', /\d/, /\d/, '/', /\d/, /\d/, /\d/, /\d/]}
/>
}
/>
and here in form
{errors.birthday && <span className="input__error-message birthday-error">Birthday is required</span>}
<Controller
name="birthday"
control={control}
defaultValue={false}
render={({ onChange, value }) => <Calendar label="Birthday" onChange={onChange} value={value} />}
rules={{ required: true }}
register={register}
/>
Yes, this is possible. You just have to use the validate function provided by the rules prop object.
const isOlderThan15Years = date => {...}
rules={{ required: true, validate: date => isOlderThan15Years(date) }}
Check the register section in the documentation for more information.

Edit without passing id as identifier

Suppose I have a List and and Edit of items of the following schema:
STRING key UNIQUE PRIMARY
STRING value
The problem is that when using admin-on-rest, the Edit uses the id by default to generate the request, if it does not have one, it passes undefined. How can I change that on the SimpleForm so it uses another parameter instead of id - in my case, key -.
Example of the List and Edit:
export const ParamList = props => (
<List title = "All params" { ...props} >
<Datagrid >
<TextField source = "key" sortable={false} />
<TextField source = "value" sortable={false} />
<EditButton />
</Datagrid>
</List>
);
export const ParamEdit = props => (
<Edit title = {< ParamTitle />} { ...props } >
<SimpleForm >
<TextInput source = "key" />
<TextInput source = "value" />
</SimpleForm>
</Edit >
);
When I send the editing, the following request is made:
PUT www.randomurl.com/param/undefined
But i wished it was something like:
PUT www.randomurl.com/param/<item's key>
I have seen that on the documentation that is possible to set customize the requests as a whole. But was thinking if there is something easier, like adding a parameter on SimpleForm:
export const ParamEdit = props => (
<Edit title = {< ParamTitle />} { ...props } >
<SimpleForm id={"key"}>
<TextInput source = "key" />
<TextInput source = "value" />
</SimpleForm>
</Edit >
);
Thanks in advance.
As explained in the documentation, the correct and only way to do that is to write a custom restClient. See https://marmelab.com/admin-on-rest/FAQ.html#can-i-have-custom-identifiersprimary-keys-for-my-resources

How to solve this issue with redux form? It shows syntax error

We are going to use redux form for all our app's forms. The app may have 5 different forms for different purposes. The trouble with this first form is that it shows syntax error. But before implementing redux form it was worked with the same syntax. What is the problem with this code?
import React, {Component} from "react";
import {Text, Image, KeyboardAvoidingView, Platform,View} from "react-native";
import {
Content,
Form,
Item,
Input,
Icon,
Button,
ListItem,
Row,
Col,
Grid,
Toast,
Container,
Left,
Right,
Body
} from "native-base";
import styles from "../styles/formstyle";
import { Field, reduxForm } from "redux-form";
const required = value => (value ? undefined : "Required");
const maxLength = max => value => (value && value.length > max ? `Must be ${max} characters or less` : undefined);
const maxLength15 = maxLength(15);
const minLength = min => value => (value && value.length < min ? `Must be ${min} characters or more` : undefined);
const minLength8 = minLength(8);
const email = value =>
value && !/^[A-Z0-9._%+-]+#[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(value) ? "Invalid email address" : undefined;
const alphaNumeric = value => (value && /[^a-zA-Z0-9 ]/i.test(value) ? "Only alphanumeric characters" : undefined);
class SigninScreen extends Component {
static navigationOptions = {
gesturesEnabled: false,
};
renderInput({ input, label, type, meta: { touched, error, warning } }) {
return (
<Item style={styles.item}
error={error && touched}
>
<Icon
active
name="mail"
style={styles.icon}
/>
<Input
{...input.name="email"}
ref={c => (this.textInput = c)}
placeholder="Email"
placeholderTextColor="#a4916d"
style={styles.input}
/>
</Item>
<Item style={styles.item} error={error && touched}>
<Icon
active
name="lock"
style={styles.icon}
/>
<Input
{...input.name="password"}
ref={c => (this.textInput = c)}
secureTextEntry={true}
placeholder="Password"
placeholderTextColor="#a4916d"
style={styles.input}
/>
</Item>
);
}
login() {
if (this.props.valid) {
this.props.navigation.navigate("Drawer");
} else {
Toast.show({
text: "Enter Valid Username & password!",
duration: 2000,
position: "top",
textStyle: { textAlign: "center" },
});
}
}
render() {
return (
<Image style={background.img} source={require("../img/cover.jpg")}>
<Container style={styles.content}>
<Form>
<Field name="email"
validate={[email, required]} />
<Field
name="password"
component={this.renderInput}
validate={[alphaNumeric, minLength8, maxLength15, required]}
/>
</Form>
<ListItem
style={styles.list}
>
<Left>
<Button
primary
full
style={{width:"90%"}}
onPress={() => this.props.navigation.navigate("Signup")}
>
<Text style={{color: "#0dc49d"}}>fb</Text>
</Button>
</Left>
<Body/>
<Right>
<Button
danger
full
onPress={() =>
this.props.navigation.navigate("Forgetpass")}
>
<Text style={{color: "#0dc49d"}}>google</Text>
</Button>
</Right>
</ListItem>
<Button
full
style={{backgroundColor: "#0dc49d", width:"90%"}}
onPress={() => this.login()}
>
<Text style={{color:"#ffffff"}}>Sign In</Text>
</Button>
</Container>
</Image>
);
}
}
export default reduxForm({
form: 'test'
})(SigninScreen)
It says JSX elements must be wrapped an enclosing tag. Eslint shows the second component inside the renderinput. I am using it with native-base. What can cause this error? Also, can you check please if the communication within renderinput and fields component is right? I am not sure that after solving the syntax error this code will work :(
Thanks in advance!
renderInput method is returning two different items. You need to wrap them into a single wrapped component like the error is saying.
Example
renderInput({ input, label, type, meta: { touched, error, warning } }) {
return (
<View>
<Item style={styles.item} error={error && touched}>
<Icon active name="mail" style={styles.icon} />
<Input {...input.name="email"} ref={c => (this.textInput = c)} placeholder="Email" placeholderTextColor="#a4916d" style={styles.input} />
</Item>
<Item style={styles.item} error={error && touched}>
<Icon active name="lock" style={styles.icon} />
<Input {...input.name="password"} ref={c => (this.textInput = c)} secureTextEntry={true} placeholder="Password" placeholderTextColor="#a4916d" style={styles.input} />
</Item>
</View>
);
}

Independent "Submit" button for tabbed form in Create

I already made 2 types of create page:
Create single record.
Import multiple records from xlsx file.
Now I want to implement 2 independent buttons:
Save
Import
meaning that when I click on button 1, only button 1 works.
Here is my code:
<Create {...this.props}>
<TabbedForm toolbar="">
<FormTab label="Single record">
<ReferenceInput label="Centre" source="centre" reference="centre" sort={{ field: 'name', order: 'ASC' }} allowEmpty>
<SelectInput optionText="name" />
</ReferenceInput>
<TextInput source="fullname" />
<TextInput source="serial " />
<TextInput source="birthday" />
<TextInput source="join_date" />
<TextInput source="remark" />
<SaveButton label="Save" redirect="show" submitOnEnter={true} />
</FormTab>
<FormTab label="Import from xlsx">
<ReferenceInput label="Centre" source="centre_import" reference="centre" sort={{ field: 'name', order: 'ASC' }} allowEmpty>
<SelectInput optionText="name" />
</ReferenceInput>
<label id="customLabel">
<input id="upload" ref={(input) => { this.textInput = input; }} type="file" hidden
onClick={(event)=> {
event.target.value = null;
}}
onChange={
(event) => {
this.fileName.textContent = event.target.files[0].name;
}
}
/>
<FlatButton primary label="Select file" icon={<ActionFile />} onClick={() => {
this.textInput.click();
}}/>
<span id="fileName" ref={(span) => { this.fileName = span; }}></span>
</label>
<SaveButton label="Import" redirect={false} submitOnEnter={true} />
</FormTab>
</TabbedForm>
</Create>
The easiest way would be to keep a single button here. You may add a text inside the importation tab explaining that clicking on save will import the file.
However, you still have to deal with the redirection. To do so, you'll have to implement a custom SaveButton:
Copy the code of the default SaveButton into a SaveOrImportButton file.
Update its mapStateToProps function and use redux-form getFormValues selector to inspect the form values and determine whether its an importation.
Use this knowledge to customize the button:
You may update the label to Import if the user selected a file. The label will update immediately after the file field gets dirty.
You can change the redirect value at L22.
Use this button inside a Toolbar component and pass this component to the toolbar prop of the Create component.

How can I create a SaveButton which returns to me to a special URL

I know that I can use an url as redirect parameter for an SaveButton like this:
const ResourcePropertyEditToolbar = props => <Toolbar {...props} >
<SaveButton />
<SaveButton label="save and resource" redirect={"/resource/21"}
submitOnEnter={false} raised={false} />
</Toolbar>;
As you see the "/resource/21" is hard coded and it works (for this entry ;-) How can I dynamically create the url? The value itself is included in the current data set which is edited, like this:
export const ResourcePropertyEdit = (props) => (
<Edit {...props} >
<SimpleForm toolbar={<ResourcePropertyEditToolbar />}>
<NumberInput source="position" defaultValue="1"/>
<TextInput source="property_name" validate={required}/>
<ReferenceInput label="Resource" source="fk_resource"
reference="resource">
<AutocompleteInput optionText="shortname"/>
</ReferenceInput>
</SimpleForm>
</Edit>
);
It is the value of the selected fk_resource.
Here is the code snippet for the base Form with the ReferenceManyField Entry, the target is to jump back to this view after editing a resource_property.
export const ResourceEdit = (props) => (
<Edit {...props}>
<SimpleForm>
<TextInput source="shortname" validate={required}/>
<ReferenceManyField target="fk_resource"
reference="resource_property" >
<Datagrid>
<NumberField source="position"/>
<TextField source="property_name"/>
<ReferenceField label="Property" source="fk_property" reference="property" allowEmpty>
<TextField source="shortname"/>
</ReferenceField>
<EditButton/>
</Datagrid>
</ReferenceManyField>
</SimpleForm>
</Edit>
);
Thanks for any help
The current data set is called the record in AOR. If the URL is in the record you can access it simply by
const ResourcePropertyEditToolbar = props => <Toolbar {...props} >
<SaveButton />
<SaveButton label="save and resource" redirect={props.record.url ? props.record.url : null}
submitOnEnter={false} raised={false} />
</Toolbar>

Resources