Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
Last revision Both sides next revision
tutorial:dev:how_to_create_eav_face_type [2017/09/13 12:59]
tomiskar
tutorial:dev:how_to_create_eav_face_type [2019/02/04 09:26]
tomiskar
Line 1: Line 1:
 +====== Dynamic form - creating a new attribute renderer ======
 +
 +In this tutorial we will describe how to create a new [[devel:documentation:application_configuration:dev:dynamic-forms|attribute renderer]] for a dynamic form attribute.
 +
 +A new render will be used for a persistent type ''INT''. Renderer define a new face ''PRIORITY-SELECT'' and an input will be represented as five radio buttons.
 +
 +===== What do you need before you start =====
 +
 +  * You need to install CzechIdM 7.4.0 (and higher). We have CzechIdM installed for this tutorial on server ''http://localhost:8080/idm-backend''.
 +
 +===== 01 Create a renderer component =====
 +
 +We will use ''AbstractFormAttributeRenderer'' component as superclass - contains some default method implementations. And define / override methods for getting / setting form value from radio buttons.
 +Radio form component is not implemented in core components yet, so we are using simple radio inputs.
 +
 +<code javascript>
 +import React from 'react';
 +//
 +import { Advanced } from 'czechidm-core';
 +
 +/**
 + * Priority form value component. Doesn't support:
 + * - multiple
 + * - confidential
 + * - placeholder
 + * - helpBlock
 + * - validation
 + * - required
 + */
 +export default class PrioritySelectFormAttributeRenderer extends Advanced.AbstractFormAttributeRenderer {
 +
 +  constructor(props, context) {
 +    super(props, context);
 +    // prepare radio value
 +    this.state = {
 +      value: null
 +    };
 +  }
 +
 +  /**
 +   * Fill form value field by persistent type from input value
 +   *
 +   * @param  {FormValue} formValue - form value
 +   * @param  {object} formComponent value
 +   * @return {FormValue}
 +   */
 +  fillFormValue(formValue, rawValue) {
 +    formValue.longValue = rawValue;
 +    // TODO: validations for numbers
 +    return formValue;
 +  }
 +
 +  /**
 +   * Returns value to ipnut from given (persisted) form value
 +   *
 +   * @param  {FormValue} formValue
 +   * @return {object} value by persistent type
 +   */
 +  getInputValue(formValue) {
 +    return formValue.longValue;
 +  }
 +
 +  /**
 +   * Filled form value
 +   *
 +   * @return {FormValue}
 +   */
 +  toFormValue() {
 +    const { values } = this.props;
 +    //
 +    return this.fillFormValue(this.prepareFormValue(values ? values[0] : null), this.state.value);
 +  }
 +
 +  /**
 +   * Set value on radio is clicked (changed)
 +   *
 +   * @param {event} event
 +   */
 +  setValue(event) {
 +    this.setState({
 +      value: event.target.value
 +    });
 +  }
 +
 +  renderSingleInput() {
 +    const { attribute, readOnly, values } = this.props;
 +    const singleValue = this.state.value || this.toInputValue(values);
 +    // create radio inputs
 +    const inputs = [];
 +    for (let i = 1; i <= PrioritySelectFormAttributeRenderer.RADIO_COUNT; i++) {
 +      inputs.push(
 +        <label className="radio-inline">
 +          <input
 +            name={ attribute.name }
 +            type="radio"
 +            readOnly={ readOnly || attribute.readonly }
 +            value={ i }
 +            defaultChecked={ singleValue === i }/> { i }
 +        </label>
 +      );
 +    }
 +    // raw bootstrap styles are used in this example (Basic radio component should be created instead)
 +    return (
 +      <div className="form-group">
 +        <label className="control-label">{ attribute.name }</label>
 +        <div className="radio" onChange={this.setValue.bind(this)}>
 +          { inputs }
 +        </div>
 +      </div>
 +    );
 +  }
 +}
 +
 +PrioritySelectFormAttributeRenderer.RADIO_COUNT = 5;
 +</code>
 +
 +===== 02 Register renderer component =====
 +
 +Component is created, now we need to register her in [[https://github.com/bcvsolutions/CzechIdMng/tree/develop/Realization/frontend/czechidm-core#component-descriptor|component descriptor]] for start using her in application. New renderer will be available as new face type on form attribute detail page too, when persistent type ''INT'' will be selected.
 +
 +Add component into module's ''component-descriptor.js'':
 +
 +<code javascript>
 +...
 +module.exports = {
 +  ...
 +  'components': [
 +    ...
 +    {
 +      'id': 'priority-select-form-value',
 +      'type': 'form-attribute-renderer',
 +      'persistentType': 'INT',
 +      'faceType': 'PRIORITY-SELECT',
 +      'component': require('./src/components/PrioritySelectFormAttributeRenderer'),
 +      'labelKey': 'Priority radio select'
 +    }
 +    ...
 +  ]
 +};
 +...
 +</code>
 +
 +===== 03 Define form attribute =====
 +
 +We can select renderer for some dynamic form atribute with peristent type ''INT'' in form definitions agenda - e.g. we will add new attribute to default identity form definition:
 +
 +{{ :tutorial:dev:priority-select-definition.png |}}
 +
 +On identity detail in tab more information, we can see, how result's look like: 
 +
 +{{:tutorial:dev:priority-select-use.png|}}
 +
 +===== Advanced =====
 +
 +Renderer name can be localized. See ''labelKey'' attribute in component definition. You can add localization key here instead text.
  
  • by tomiskar