/**************************************************************************** * Copyright 2017 EPAM Systems * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ***************************************************************************/ import jsonschema from 'jsonschema'; import { h, Component } from 'preact'; import { connect } from 'preact-redux'; /** @jsx h */ import Input from './input'; import { updateFormState } from '../state/form'; class Form extends Component { constructor({ onUpdate, schema, init, ...props }) { super(); this.schema = propSchema(schema, props); if (init) { let { valid, errors } = this.schema.serialize(init); const errs = getErrorsObj(errors); init = Object.assign({}, init, { init: true }); onUpdate(init, valid, errs); } } updateState(newstate) { const { instance, valid, errors } = this.schema.serialize(newstate); const errs = getErrorsObj(errors); this.props.onUpdate(instance, valid, errs); } getChildContext() { const { schema } = this.props; return { schema, stateStore: this }; } field(name, onChange) { const { result, errors } = this.props; const value = result[name]; const self = this; return { dataError: errors && errors[name] || false, value: value, onChange(value) { const newstate = Object.assign({}, self.props.result, { [name]: value }); self.updateState(newstate); if (onChange) onChange(value); } }; } render(props) { const { result, children, schema, ...prop } = props; if (schema.key && schema.key !== this.schema.key) { this.schema = propSchema(schema, prop); this.schema.serialize(result); // hack: valid first state this.updateState(result); } return (
); } } Form = connect( null, dispatch => ({ onUpdate: function (result, valid, errors) { dispatch(updateFormState({ result, valid, errors })); } }) )(Form); function Label({ labelPos, title, children, ...props }) { return ( ); } class Field extends Component { render(props) { const { name, onChange, className, component, ...prop } = props; const { schema, stateStore } = this.context; const desc = prop.schema || schema.properties[name]; const { dataError, ...fieldOpts } = stateStore.field(name, onChange); return ( ); } } const SelectOneOf = (props) => { const { title, name, schema, ...prop } = props; const selectDesc = { title: title, enum: [], enumNames: [] }; Object.keys(schema).forEach(item => { selectDesc.enum.push(item); selectDesc.enumNames.push(schema[item].title || item); }); return