lodash#set JavaScript Examples

The following examples show how to use lodash#set. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: utils.js    From hzero-front with Apache License 2.0 7 votes vote down vote up
export function dealButtonProps({ field, context }) {
  const otherProps = {};
  forEach(field.props, (propV, propK) => {
    set(otherProps, propK, propV);
  });
  const { btn } = otherProps;
  delete otherProps.btn;
  const dealProps = dealObjectProps(otherProps, context);
  return { componentProps: dealProps, btn };
}
Example #2
Source File: utils.js    From hzero-front with Apache License 2.0 7 votes vote down vote up
/**
 * 将属性解构成 对应的
 * @param {object} config - 属性
 * @param {object} context - 上下文
 * @param {{[excludeKey: string]: true}} excludeProps - 要排除的属性
 */
export function dealObjectProps(config, context, excludeProps) {
  const dealProps = {};
  const skipProps = excludeProps || {};
  forEach(config, (v, k) => {
    if (!skipProps[k]) {
      set(dealProps, k, getContextValue(context, v));
    }
  });
  return dealProps;
}
Example #3
Source File: utils.js    From hzero-front with Apache License 2.0 7 votes vote down vote up
/**
 * 处理 table 行按钮
 * @param {object} linkButton
 // * @param {object} dynamicTable
 * @returns {object}
 */
function processDynamicTableLinkButtonField(linkButton) {
  // todo 确定 DynamicTable 的 linkButton 没有其他的属性值, 且只有一级属性
  const props = {};
  const btns = [];
  forEach(linkButton.config, attr => {
    set(props, attr.attributeName, attr);
  });
  Object.keys(props).forEach(btnKey => {
    const btnProps = props[btnKey];
    const btnConfig = [];
    let orderSeq;
    Object.keys(btnProps).forEach(btnPropKey => {
      switch (btnPropKey) {
        case 'orderSeq':
          orderSeq = btnProps[btnPropKey].value;
          break;
        default:
          break;
      }
      // 将对应的 attr 放进按钮中
      btnProps[btnPropKey].attributeName = btnPropKey;
      btnConfig.push(btnProps[btnPropKey]);
    });
    btns[orderSeq] = btnConfig;
    // btns.push(btnConfig);
  });
  linkButton.btns = btns;
  return linkButton;
}
Example #4
Source File: utils.js    From hzero-front with Apache License 2.0 7 votes vote down vote up
/**
 * 将 templates config 的值 设置到 头数据中
 */
export function dealConfig(templates) {
  forEach(templates, template => {
    forEach(template.config, attr => {
      const attrPath = toPath(attr);
      set(template, attrPath, {
        ...attr,
        [attrFlagField]: true,
        [attributeNameProp]: attrPath[attrPath.length - 1],
      });
    });
    forEach(template.fields, field => {
      forEach(field.config, attr => {
        const attrPath = toPath(attr);
        set(field, attrPath, {
          ...attr,
          [attrFlagField]: true,
          [attributeNameProp]: attrPath[attrPath.length - 1],
        });
      });
      delete field.config;
    });
    delete template.config;
  });
}
Example #5
Source File: index.js    From agenda with MIT License 6 votes vote down vote up
mergeProps = (stateProps, dispatchProps, ownProps) => {
    const {updateAssignment} = dispatchProps;
    const mergeFields = map(stateProps.fields, field => ({
        ...field,
        onChange: ({target: {value}}) => updateAssignment(set({...stateProps.assignment}, field.path, value))
    }));
    return {
        ...dispatchProps,
        ...ownProps,
        fields: mergeFields,
        assignment: stateProps.assignment
    };
}
Example #6
Source File: utils.js    From hzero-front with Apache License 2.0 6 votes vote down vote up
{ set: customizeSet, get: customizeGet } = mapCustomizeBuilder(
  'hpfm',
  'ui_dynamic_component'
)
Example #7
Source File: localeApi.js    From hzero-front with Apache License 2.0 6 votes vote down vote up
/**
 * 获取 ui 库 的多语言, 如果传了 language 和 promptKey, 那么使用传递的 多语言来覆盖 ui库多语言
 * @param {function()} loadFileIntl - 获取文件多语言的方法: () => Promise<any>
 * @param {string} language - 语言
 * @param {string} promptKey - 多语言编码前缀
 * @return {Promise<*>}
 */
export async function getFileIntl(loadFileIntl = () => {}, language, promptKey) {
  const organizationId = getCurrentOrganizationId();
  let l = {};
  try {
    // 加载文件
    l = await loadFileIntl();
    l = cloneDeep(resolveRequire(l));
  } catch (e) {
    l = {};
  }
  let iRes = {};
  if (language && promptKey && organizationId !== undefined) {
    // 加载 多语言
    iRes = await queryPromptLocale(organizationId, language, promptKey);
    const i = getResponse(iRes) || {};
    const prefixLen = promptKey.length + 1;
    // 覆盖 ui库 多语言
    Object.keys(i).forEach(intlCode => {
      set(l, intlCode.substr(prefixLen), i[intlCode]);
    });
  }
  return l;
}
Example #8
Source File: HiddenColumnsEditModal.js    From hzero-front with Apache License 2.0 6 votes vote down vote up
static getDerivedStateFromProps(nextProps, prevState) {
    const { hiddenColumns } = nextProps;
    const { hiddenColumns: prevHiddenColumns } = prevState;
    if (hiddenColumns !== prevHiddenColumns) {
      return {
        hiddenColumns,
        hiddenColumnsDataSource: map(hiddenColumns, hiddenColumn => {
          const c = {};
          set(c, hiddenColumn[attributeNameProp], hiddenColumn);
          const columnKey = Object.keys(c[hiddenColumnKey])[0];
          const [columnName, columnLabel] = hiddenColumn[attributeValueProp].split(hiddenColumnSep);
          return {
            columnKey,
            columnLabel,
            columnName,
            [editRecordField]: editEditing,
          };
        }),
      };
    }
    return null;
  }
Example #9
Source File: YupValidator.js    From HexactaLabs-NetCore_React-Initial with Apache License 2.0 6 votes vote down vote up
Validator = (schema, fieldsArray = []) => values => {
  const formErrors = {};
  try {
    schema.validateSync(values, { abortEarly: false });
  } catch (errors) {
    errors.inner.forEach(error => {
      if (fieldsArray && fieldsArray.includes(error.path)) {
        set(formErrors, error.path, { _error: error.message });
      } else {
        set(formErrors, error.path, error.message);
      }
    });
  }
  return formErrors;
}
Example #10
Source File: Mappers.js    From sampo-ui with MIT License 6 votes vote down vote up
makeObject = (obj) => {
  const o = {}
  forIn(obj, function (value, key) {
    // If the variable name contains "__", an object
    // will be created as the value
    // E.g. { place__id: '1' } -> { place: { id: '1' } }
    set(o, key.replace(/__/g, '.'), value.value)
  })
  return o
}
Example #11
Source File: FieldProp.js    From hzero-front with Apache License 2.0 5 votes vote down vote up
// 防止第一次 state 是空报错

  render() {
    const { field, form } = this.props;
    const propValues = {};
    forEach(field.config, prop => {
      propValues[prop.attributeName] = prop.value;
    });
    const btnConfigs = {};
    const btnProps = {
      btn: {},
    };
    forEach(field.config, prop => {
      if (startsWith(prop[attributeNameProp], TOOLBAR_BTN_PREFIX)) {
        // 设置 btn 的属性
        if (startsWith(prop[attributeNameProp], `${TOOLBAR_BTN_PREFIX}${modalBtnPrefix}`)) {
          btnConfigs[(prop[attributeNameProp] || '').substr(TOOLBAR_BTN_PREFIX.length)] =
            prop[attributeTypeProp];
          if (btnProps.btn.modalBtns) {
            btnProps.btn.modalBtns.push(prop);
          } else {
            btnProps.btn.modalBtns = [prop];
          }
        } else if (startsWith(prop[attributeNameProp], `${TOOLBAR_BTN_PREFIX}${subEventPrefix}`)) {
          btnConfigs[(prop[attributeNameProp] || '').substr(TOOLBAR_BTN_PREFIX.length)] =
            prop[attributeTypeProp];
          if (btnProps.btn.subEvents) {
            btnProps.btn.subEvents.push(prop);
          } else {
            btnProps.btn.subEvents = [prop];
          }
        } else {
          // 设置除了 modalBtn, subEvent 之外的属性类型
          set(btnProps, prop[attributeNameProp], prop[attributeValueProp]);
        }
      } else {
        propValues[prop[attributeNameProp]] = prop[attributeValueProp];
      }
    });

    return (
      <Form>
        {form.getFieldDecorator('btnConfigs', {
          initialValue: btnConfigs,
        })(<div />)}
        {form.getFieldDecorator('btnProps', {
          initialValue: btnProps.btn,
        })(<div />)}
        {this.renderFieldCommonProps(propValues)}
        <Divider />
        {this.renderFieldTypeProps(propValues)}
      </Form>
    );
  }
Example #12
Source File: dynamicTable.js    From hzero-front with Apache License 2.0 5 votes vote down vote up
/**
 * @param {object} template
 * @param {object} field
 * @param {object} options
 * @returns
 */
// eslint-disable-next-line no-unused-vars
function dynamicTableDirtyExtraFieldLinkButton(template, field, options) {
  // todo 确定 DynamicTable 的 linkButton 没有其他的属性值, 且只有一级属性
  const props = {};
  const btns = [];
  forEach(field.config, attr => {
    set(props, attr.attributeName, attr);
  });
  Object.keys(props).forEach(btnKey => {
    const btnProps = props[btnKey];
    const btnConfig = [];
    let orderSeq;
    Object.keys(btnProps).forEach(btnPropKey => {
      if (btnPropKey === 'orderSeq') {
        orderSeq = btnProps[btnPropKey].value;
      } else if (btnPropKey === 'modalBtns') {
        btnConfig.push({
          attributeName: 'modalBtns',
          value: btnProps.modalBtns,
        });
        return;
      } else if (btnPropKey === 'subEvents') {
        btnConfig.push({
          attributeName: 'subEvents',
          value: btnProps.subEvents,
        });
        return;
      }
      // 将对应的 attr 放进按钮中
      btnProps[btnPropKey].attributeName = btnPropKey;
      btnConfig.push(btnProps[btnPropKey]);
    });
    btns[orderSeq] = btnConfig;
    // btns.push(btnConfig);
  });
  field.btns = btns;
  return field;
}
Example #13
Source File: enrollmentReducer.js    From datapass with GNU Affero General Public License v3.0 5 votes vote down vote up
eventUpdateFactory =
  (demarches = null) =>
  ({
    previousEnrollment,
    event: {
      target: { type = null, checked = null, value: inputValue, name },
    },
  }) => {
    const value = type === 'checkbox' ? checked : inputValue;

    let futureEnrollment = cloneDeep(previousEnrollment);
    set(futureEnrollment, name, value);

    if (demarches && name === 'demarche') {
      const defaultDemarche = get(demarches, 'default', {});
      const selectedDemarche = get(demarches, value, {});

      let futureTeamMembers = futureEnrollment.team_members;
      if (
        !isEmpty(futureEnrollment.team_members) &&
        !isEmpty(defaultDemarche.team_members)
      ) {
        futureTeamMembers = futureEnrollment.team_members.map(
          (futureTeamMember) => {
            if (!defaultDemarche.team_members[futureTeamMember.type]) {
              return futureTeamMember;
            }

            if (
              !selectedDemarche.team_members ||
              !selectedDemarche.team_members[futureTeamMember.type]
            ) {
              return defaultDemarche.team_members[futureTeamMember.type];
            }

            return selectedDemarche.team_members[futureTeamMember.type];
          }
        );
      }

      futureEnrollment = merge(
        {},
        futureEnrollment,
        defaultDemarche.state,
        selectedDemarche.state,
        { team_members: futureTeamMembers }
      );
    }

    return futureEnrollment;
  }
Example #14
Source File: Integrations.js    From gutenberg-forms with GNU General Public License v2.0 5 votes vote down vote up
function Integrations(props) {
	const integrations = get(window, "cwpGlobal.settings.integrations");
	const savedIntegrations = props.data.attributes.integrations;
	const { actions } = props.data.attributes;

	// responsible for keeping the form actions and integrations synchronized
	useEffect(() => {
		each(savedIntegrations, (integration, name) => {
			const title = get(integrations[name], "title");
			const hasActionOfCurrentIntegration = includes(actions, title); // checking if the action has current integration

			if (!hasActionOfCurrentIntegration) {
				const newIntegrations = clone(savedIntegrations);
				const withoutCurrentIntegrations = omit(newIntegrations, [name]); // deleting the current integration from the list

				props.data.setAttributes({ integrations: withoutCurrentIntegrations });
			}
		});
	}, [actions]);

	useEffect(() => {
		each(integrations, (integration, name) => {
			const title = get(integration, "title");
			const hasActionOfCurrentIntegration = includes(actions, title); // checking if the action has current integration
			const isAllFieldIntegration = get(integration, "include_all_fields");

			if (isAllFieldIntegration && hasActionOfCurrentIntegration === true) {
				// if this integration support all field then the field plotter will be hidden
				// therefore updating the integration attribute manually

				const newIntegrations = clone(savedIntegrations);
				set(newIntegrations, name, new Object());
				props.data.setAttributes({ integrations: newIntegrations });
			}
		});
	}, [actions]);

	return (
		<Fragment>
			{map(integrations, (integration, name) => {
				const api_fields = get(integration, "api_fields"),
					query_fields = get(integration, "query_fields"),
					title = get(integration, "title"),
					enable = get(integration, "enable"),
					fields = get(integration, "fields"),
					type = get(integration, "type"),
					include_all_fields = get(integration, "include_all_fields");
				if (
					enable &&
					actions.includes(title) &&
					isEqual(type, "autoResponder") &&
					!include_all_fields
				) {
					return (
						<PanelBody title={__(title, "cwp-gutenberg-forms")}>
							<FieldPlotter
								fields={fields}
								title={title}
								name={name}
								data={props.data}
								clientId={props.clientId}
								api_fields={api_fields}
								query_fields={query_fields}
							/>
						</PanelBody>
					);
				}
			})}
		</Fragment>
	);
}
Example #15
Source File: Form.jsx    From kube-design with MIT License 5 votes vote down vote up
setData(name, value) {
    set(this.state.formData, name, value);
  }
Example #16
Source File: index.js    From strapi-plugins with MIT License 4 votes vote down vote up
AuthPage = ({
  hasAdminUser,
  // -- add locationState from location props
  location: { search, state: locationState },
  // -- --- --
  match: {
    params: { authType },
  },
}) => {
  const [reducerState, dispatch] = useReducer(reducer, initialState);
  const codeRef = useRef();
  const abortController = new AbortController();

  const { signal } = abortController;
  codeRef.current = getQueryParameters(search, 'code');

  // -- small hack if coming from logout
  // -- for Strapi to reload content-types
  const history = useHistory();

  useEffect(() => {
    if (locationState && locationState.reload) {
      history.replace({
        pathname: `/auth/${authType}`,
        state: {},
      });

      window.location.reload();
    }
  }, []);
  // -- --- --

  useEffect(() => {
    // Set the reset code provided by the url
    if (authType === 'reset-password') {
      dispatch({
        type: 'ON_CHANGE',
        keys: ['code'],
        value: codeRef.current,
      });
    } else {
      // Clean reducer upon navigation
      dispatch({
        type: 'RESET_PROPS',
      });
    }

    return () => {
      abortController.abort();
    };
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [authType, codeRef]);
  const { didCheckErrors, errors, modifiedData, submitSuccess, userEmail } = reducerState.toJS();
  const handleChange = ({ target: { name, value } }) => {
    dispatch({
      type: 'ON_CHANGE',
      keys: name.split('.'),
      value,
    });
  };

  const handleSubmit = async e => {
    e.preventDefault();
    const schema = forms[authType].schema;
    let formErrors = {};

    try {
      await schema.validate(modifiedData, { abortEarly: false });

      if (modifiedData.news === true) {
        request('https://analytics.strapi.io/register', {
          method: 'POST',
          body: pick(modifiedData, ['email', 'username']),
          signal,
        }).catch(() => {
          // ignore error
        });
      }

      try {
        const requestEndPoint = forms[authType].endPoint;
        const requestURL = `/admin/auth/${requestEndPoint}`;
        const body = omit(modifiedData, 'news');

        if (authType === 'forgot-password') {
          set(body, 'url', `${strapi.remoteURL}/auth/reset-password`);
        }

        const { jwt, user, ok } = await request(requestURL, {
          method: 'POST',
          body,
          signal,
        });

        if (authType === 'forgot-password' && ok === true) {
          dispatch({
            type: 'SUBMIT_SUCCESS',
            email: modifiedData.email,
          });
        } else {
          auth.setToken(jwt, modifiedData.rememberMe);
          auth.setUserInfo(user, modifiedData.rememberMe);
        }
      } catch (err) {
        const formattedError = formatErrorFromRequest(err);

        if (authType === 'login') {
          formErrors = {
            global: formattedError,
            identifier: formattedError,
            password: formattedError,
          };
        } else if (authType === 'forgot-password') {
          formErrors = { email: formattedError[0] };
        } else {
          strapi.notification.error(get(formattedError, '0.id', 'notification.error'));
        }
      }
    } catch (err) {
      formErrors = getYupInnerErrors(err);
    }

    dispatch({
      type: 'SET_ERRORS',
      formErrors,
    });
  };

  // Redirect the user to the login page if the endpoint does not exist
  if (!Object.keys(forms).includes(authType)) {
    return <Redirect to="/" />;
  }

  // Redirect the user to the homepage if he is logged in
  if (auth.getToken()) {
    return <Redirect to="/" />;
  }

  if (!hasAdminUser && authType !== 'register') {
    return <Redirect to="/auth/register" />;
  }

  // Prevent the user from registering to the admin
  if (hasAdminUser && authType === 'register') {
    return <Redirect to="/auth/login" />;
  }

  const globalError = get(errors, 'global.0.id', '');
  const shouldShowFormErrors = !isEmpty(globalError);

  return (
    <>
      <PageTitle title={upperFirst(authType)} />
      <Wrapper authType={authType} withSuccessBorder={submitSuccess}>
        <NavTopRightWrapper>
          <LocaleToggle isLogged className="localeDropdownMenuNotLogged" />
        </NavTopRightWrapper>
        <div className="wrapper">
          <div className="headerContainer">
            {authType === 'register' ? (
              <FormattedMessage id="Auth.form.header.register" />
            ) : (
                <img src={LogoStrapi} alt="strapi-logo" />
              )}
          </div>
          <div className="headerDescription">
            {authType === 'register' && <FormattedMessage id="Auth.header.register.description" />}
          </div>
          {/* TODO Forgot success style */}
          <div className="formContainer bordered">
            <form onSubmit={handleSubmit}>
              <div className="container-fluid">
                {shouldShowFormErrors && (
                  <div className="errorsContainer">
                    <FormattedMessage id={globalError} />
                  </div>
                )}
                <div className="row" style={{ textAlign: 'start' }}>
                  {submitSuccess && (
                    <div className="forgotSuccess">
                      <FormattedMessage id="Auth.form.forgot-password.email.label.success" />
                      <br />
                      <p>{userEmail}</p>
                    </div>
                  )}
                  {!submitSuccess &&
                    forms[authType].inputs.map((row, index) => {
                      return row.map(input => {
                        return (
                          <Input
                            {...input}
                            autoFocus={index === 0}
                            didCheckErrors={didCheckErrors}
                            errors={errors}
                            key={input.name}
                            noErrorsDescription={shouldShowFormErrors}
                            onChange={handleChange}
                            value={modifiedData[input.name]}
                          />
                        );
                      });
                    })}
                  <div
                    className={`${
                      authType === 'login' ? 'col-6 loginButton' : 'col-12 buttonContainer'
                      }`}
                  >
                    <Button
                      color="primary"
                      className={submitSuccess ? 'buttonForgotSuccess' : ''}
                      type="submit"
                      style={authType === 'login' ? {} : { width: '100%' }}
                    >
                      <FormattedMessage
                        id={`Auth.form.button.${
                          submitSuccess ? 'forgot-password.success' : authType
                          }`}
                      />
                    </Button>
                  </div>
                </div>
              </div>
            </form>
          </div>
          <div className="linkContainer">
            {authType !== 'register' && authType !== 'reset-password' && (
              <Link to={`/auth/${authType === 'login' ? 'forgot-password' : 'login'}`}>
                <FormattedMessage
                  id={`Auth.link.${authType === 'login' ? 'forgot-password' : 'ready'}`}
                />
              </Link>
            )}
          </div>
          {authType === 'register' && (
            <div className="logoContainer">
              <img src={LogoStrapi} alt="strapi-logo" />
            </div>
          )}
        </div>
      </Wrapper>
    </>
  );
}
Example #17
Source File: reducer.js    From jafar with MIT License 4 votes vote down vote up
export default function reducer(forms = {}, action = {}) {
  switch (action.type) {
    case Dispatches.SET_FORM:
      {
        const newForms = {
          [action.model.id]: {
            model: action.model,
            resources: action.resources,
            settings: action.settings,
          },
        };
        return newForms;
      }
    case Dispatches.REMOVE_FORM:
      {
        const newForms = cloneShallow(forms);
        delete newForms[action.formId];
        return newForms;
      }
    case Dispatches.ADD_ACTION:
      {
        const newForms = cloneShallowModel(forms, action.formId);
        newForms[action.formId].model.pendingActions = cloneShallow(newForms[action.formId].model.pendingActions);
        newForms[action.formId].model.pendingActions.push(action.action);
        return newForms;
      }
    case Dispatches.START_PROCESSING:
      {
        const newForms = cloneShallowModel(forms, action.formId);
        newForms[action.formId].model.processing = true;
        return newForms;
      }
    case Dispatches.END_PROCESSING:
      {
        if (!forms[action.formId]) return cloneShallow(forms);
        const newForms = cloneShallowModel(forms, action.formId);
        newForms[action.formId].model.processing = false;
        return newForms;
      }
    case Dispatches.SHIFT_ACTION:
      {
        const newForms = cloneShallowModel(forms, action.formId);
        newForms[action.formId].model.pendingActions = cloneShallow(newForms[action.formId].model.pendingActions);
        newForms[action.formId].model.pendingActions.shift();
        return newForms;
      }
    case Dispatches.SET_FORM_DATA:
      {
        const newForms = cloneShallowModel(forms, action.formId);
        newForms[action.formId].model.data = action.data || {};
        return newForms;
      }
    case Dispatches.SET_FORM_CONTEXT:
      {
        const newForms = cloneShallowModel(forms, action.formId);
        newForms[action.formId].model.context = action.context || {};
        return newForms;
      }
    case Dispatches.SET_FIELDS_ERRORS:
      {
        const newForms = cloneShallowModel(forms, action.formId);
        Object.keys(action.errors).forEach((fieldId) => {
          const field = cloneShallowField(newForms, { formId: action.formId, fieldId });
          const errors = action.errors[fieldId] || [];
          field.errors = errors;
          field.invalid = !isEmpty(field.errors);
        });
        return newForms;
      }
    case Dispatches.SET_FORM_ERRORS:
      {
        const newForms = cloneShallowModel(forms, action.formId);
        newForms[action.formId].model.errors = action.errors || {};
        newForms[action.formId].model.invalid = !isEmpty(action.errors);
        return newForms;
      }
    case Dispatches.SET_FORM_INITIALIZED_DATA:
      {
        const newForms = cloneShallowModel(forms, action.formId);
        newForms[action.formId].model.initializedData = action.data || {};
        return newForms;
      }
    case Dispatches.SET_FORM_EVALUATION:
      {
        const newForms = cloneShallowModel(forms, action.formId);
        newForms[action.formId].model.invalid = action.invalid || false;
        newForms[action.formId].model.dirty = action.dirty || false;
        newForms[action.formId].model.errors = action.errors || {};
        return newForms;
      }
    case Dispatches.SET_FIELD_VALUE:
      {
        const newForms = cloneShallowModel(forms, action.formId);
        const { model } = newForms[action.formId];
        const field = model.fields[action.fieldId];
        model.prevData = cloneDeep(model.data);
        model.data = cloneDeep(model.data); // need deep copy for complex deep path like "a.b.c[2]"
        set(model.data, field.path, action.value); // isFieldEmpty needs the value already set in the data for the check
        if (isFieldEmpty(action.fieldId, model)) {
          unset(model.data, field.path);
        }
        return newForms;
      }
      case Dispatches.SET_FIELD_EVALUATION:
      {
        const newForms = cloneShallowModel(forms, action.formId);
        const field = cloneShallowField(newForms, action);
        field.excluded = action.excluded;
        field.disabled = action.disabled;
        field.errors = action.errors || [];
        field.dirty = action.dirty;
        field.required = action.required;
        field.empty = action.empty;
        field.invalid = action.invalid;
        return newForms;
      }
    case Dispatches.SET_FIELD_UI:
      {
        const newForms = cloneShallowModel(forms, action.formId);
        const field = cloneShallowField(newForms, action);
        Object.assign(field, action.ui);
        return newForms;
      }
      case Dispatches.SET_FIELD_COMPONENT_STATE:
      {
        const newForms = cloneShallowModel(forms, action.formId);
        const field = cloneShallowField(newForms, action);
        field.component = cloneShallow(field.component);
        field.component.state = action.state || {};
        return newForms;
      }
      case Dispatches.SET_FIELD_COMPONENT_PREV_STATE:
      {
        const newForms = cloneShallowModel(forms, action.formId);
        const field = cloneShallowField(newForms, action);
        field.component = cloneShallow(field.component);
        field.component.prevState = cloneDeep(field.component.modelState);
        field.component.modelState = cloneDeep(field.component.state);
        return newForms;
      }
      case Dispatches.SET_FIELD_COMPONENT_VALUE:
      {
        const newForms = cloneShallowModel(forms, action.formId);
        const field = cloneShallowField(newForms, action);
        updateFieldComponentValue(field, action.value);
        return newForms;
      }
      case Dispatches.SET_FIELD_COMPONENT_VALUE_BATCH:
      {
        const newForms = cloneShallowModel(forms, action.formId);
        const { model } = newForms[action.formId];
        model.fields = cloneShallow(model.fields);
        Object.keys(action.batch).forEach((fieldId) => {
          model.fields[fieldId] = cloneShallow(model.fields[fieldId]);
          const field = model.fields[fieldId];
          updateFieldComponentValue(field, action.batch[fieldId]);
        });
        return newForms;
      }
    default:
      return forms;
  }
}
Example #18
Source File: index.js    From hzero-front with Apache License 2.0 4 votes vote down vote up
getColumnsAndScrollX() {
    const { context, fields } = this.props;
    let columnsWidth = 0;
    let hasAutoWidth = false;
    const columns = map(fields, field => {
      const dealFieldProps = dealObjectProps(field, context);
      const componentProps = preProcessComponentProps({ field, context });
      const isAutoWidth = +dealFieldProps.width === 0; // autoWidth field
      const columnWidth =
        +dealFieldProps.width || getWidthFromWord({ word: field[fieldLabelProp] });
      const column = {
        dataIndex: field[fieldNameProp],
        title: field[fieldLabelProp],
        align: dealFieldProps.align,
        render: (_, record) => getDisplayValue({ field, dataSource: record, componentProps }),
      };
      if (isAutoWidth) {
        hasAutoWidth = true;
        columnsWidth += 120;
      } else {
        column.width = columnWidth;
        columnsWidth += columnWidth;
      }
      switch (field.componentType) {
        case 'LinkButton':
          column.render = (_, record) => {
            const btns = {};
            forEach(componentProps, (prop, propKey) => {
              set(btns, propKey, prop);
            });
            // todo 按钮按钮的顺序
            const linkBtns = [];
            forEach(btns, btnProps => {
              const { btnKey } = btnProps;
              const modalProps = {};
              let onBtnClick;
              switch (btnProps.action) {
                case actionCode.page:
                  // 打开 Modal 或 页面
                  switch (btnProps.openType) {
                    case openTypeCode.inner:
                      // 跳转
                      break;
                    case openTypeCode.modal:
                      // 打开 Modal
                      modalProps.type = openTypeCode.modal;
                      modalProps.bodyStyle =
                        openPageModalBodyStyle[btnProps.openPageTypeModal].bodyStyle;
                      modalProps.width = openPageModalBodyStyle[btnProps.openPageTypeModal].width;
                      modalProps.modalBtns = btnProps.modalBtns; // modal 按钮
                      // 订阅事件
                      if (btnProps.subEvents) {
                        forEach(btnProps.subEvents, subEvent => {
                          const [subEventListenStr, subEventActionStr] = split(
                            subEvent,
                            subEventSep
                          );
                          const subEventAction = getContextValue(context, subEventActionStr);
                          if (isFunction(subEventAction)) {
                            modalProps[subEventListenStr] = subEventAction;
                          }
                        });
                      }
                      break;
                    case openTypeCode.drawer:
                      // 打开 侧滑Modal
                      modalProps.type = openTypeCode.drawer;
                      modalProps.width = btnProps.openPageTypeDrawer;
                      modalProps.modalBtns = btnProps.modalBtns; // modal 按钮
                      // 订阅事件
                      if (btnProps.subEvents) {
                        forEach(btnProps.subEvents, subEvent => {
                          const [subEventListenStr, subEventActionStr] = split(
                            subEvent,
                            subEventSep
                          );
                          const subEventAction = getContextValue(context, subEventActionStr);
                          if (isFunction(subEventAction)) {
                            modalProps[subEventListenStr] = subEventAction;
                          }
                        });
                      }
                      break;
                    default:
                      break;
                  }
                  onBtnClick = e => {
                    e.preventDefault();
                    const params = {};
                    const {
                      history: { search },
                    } = this.props;
                    const urlParams = querystring.parse(search);
                    const paramStream = (btnProps.params || '').split(',');
                    for (let i = 1; i <= paramStream.length; i++) {
                      if (i % 3 === 0) {
                        switch (paramStream[i - 2]) {
                          case paramTypeCode.fixParam:
                            params[paramStream[i - 3]] = paramStream[i - 1];
                            break;
                          case paramTypeCode.urlParam:
                            params[paramStream[i - 1]] = urlParams[paramStream[i - 3]];
                            break;
                          case paramTypeCode.columnParam:
                            params[paramStream[i - 1]] = record[paramStream[i - 3]];
                            break;
                          default:
                            break;
                        }
                      }
                    }
                    this.setState({
                      pageModalProps: {
                        pageCode: btnProps.pageCode,
                        ...modalProps,
                      },
                    });
                    if (this.pageModalRef) {
                      this.pageModalRef.init(params);
                      this.pageModalRef.show();
                    }
                  };
                  break;
                case actionCode.action:
                  // 自定义动作
                  onBtnClick = () => {
                    if (btnProps.actionEvent === internalFuncsInfo.lineRemove.code) {
                      this.handleLineRemove(record).catch((/* e */) => {
                        // console.error(e);
                      });
                    }
                  };
                  // Table 的动作, 删除行 ...
                  // 其他事件
                  break;
                default:
                  break;
              }
              linkBtns[btnProps.orderSeq] = {
                key: btnKey,
                ele: (
                  <a onClick={onBtnClick} style={linkButtonStyle}>
                    {btnProps.title}
                  </a>
                ),
                len: (btnProps.title && btnProps.title.length) || 4,
                title: btnProps.title || null,
              };
            });
            return operatorRender(linkBtns.filter(Boolean));
          };
          break;
        default:
          break;
      }
      return column;
    });
    if (hasAutoWidth) {
      return { columns };
    }
    return {
      scroll: { x: columnsWidth },
      columns,
    };
  }
Example #19
Source File: edit.js    From gutenberg-forms with GNU General Public License v2.0 4 votes vote down vote up
function edit(props) {
	const handleChange = (e) => {
		let website = e.target.value;

		props.setAttributes({ website });
	};

	const handleRequired = () => {
		const { isRequired } = props.attributes;

		props.setAttributes({ isRequired: !isRequired });
	};

	const handleLabel = (label) => {
		props.setAttributes({ label });
	};

	const {
		website,
		isRequired,
		label,
		id,
		field_name,
		requiredLabel,
		messages: { invalid, empty },
		messages,
		condition,
		enableCondition,
		adminId,
		prefix,
		suffix,
		hint,
		showHint
	} = props.attributes;

	const getRootData = () => {
		if (field_name === "" || detect_similar_forms(props.clientId)) {
			const newFieldName = getFieldName("website", props.clientId);

			props.setAttributes({
				field_name: newFieldName,
				adminId: {
					value: extract_admin_id(newFieldName, "website"),
					default: extract_admin_id(newFieldName, "website"),
				},
			});
			props.setAttributes({
				id:
					props.clientId +
					"__" +
					getEncodedData(
						"website",
						props.clientId,
						isRequired,
						get_admin_id(adminId)
					),
			});
		} else if (field_name !== "") {
			props.setAttributes({
				id:
					extract_id(field_name) +
					"__" +
					getEncodedData(
						"website",
						extract_id(field_name),
						isRequired,
						get_admin_id(adminId)
					),
			});
		}
	};

	useEffect(() => {
		let rootMessages = getRootMessages(props.clientId, "website");

		if (rootMessages) {
			const newMessages = clone(messages);

			assign(newMessages, rootMessages);

			props.setAttributes({ messages: newMessages });
		}

		getRootData();
	}, []);

	useEffect(() => getRootData(), [props]);

	const setMessages = (type, m) => {
		let newMessages = clone(messages);

		set(newMessages, type, m);

		props.setAttributes({ messages: newMessages });
	};

	const handleAdminId = (id) => {
		props.setAttributes({
			adminId: {
				...adminId,
				value: id.replace(/\s|-/g, "_"),
			},
		});
	};

	const handleInputElementChange = (type, property, value) => {
		const newSuffix = clone(suffix);
		const newPrefix = clone(prefix);

		switch (type) {
			case "suffix":
				set(newSuffix, property, value);
				props.setAttributes({ suffix: newSuffix });

				break;
			case "prefix":
				set(newPrefix, property, value);
				props.setAttributes({ prefix: newPrefix });
		}
	};

	return [
		!!props.isSelected && (
			<InspectorControls>
				<PanelBody title={__("Field Settings", "cwp-gutenberg-forms")} initialOpen={true}>
					<div className="cwp-option">
						<TextControl
							placeholder={adminId.default}
							label={__("Field ID", "cwp-gutenberg-forms")}
							value={adminId.value}
							onChange={handleAdminId}
						/>
					</div>

					<div className="cwp-option">
						<PanelRow>
							<h3 className="cwp-heading">{__("Prefix", "cwp-gutenberg-forms")}</h3>
							<FormToggle
								label="Prefix"
								checked={prefix.enable}
								onChange={() =>
									handleInputElementChange("prefix", "enable", !prefix.enable)
								}
							/>
						</PanelRow>
					</div>

					<div className="cwp-option">
						<PanelRow>
							<h3 className="cwp-heading">{__("Suffix", "cwp-gutenberg-forms")}</h3>
							<FormToggle
								label="Suffix"
								checked={suffix.enable}
								onChange={() =>
									handleInputElementChange("suffix", "enable", !suffix.enable)
								}
							/>
						</PanelRow>
					</div>

					{!enableCondition ? (
						<PanelRow>
							<h3 className="cwp-heading">{__("Required", "cwp-gutenberg-forms")}</h3>
							<FormToggle
								label="Required"
								checked={isRequired}
								onChange={handleRequired}
							/>
						</PanelRow>
					) : (
						<div className="cwp-option">
							<p>
								<Icon icon="info" />{" "}
								{__(
									"You cannot set a conditional field required!",
									"cwp-gutenberg-forms"
								)}
							</p>
						</div>
					)}
					{isRequired && (
						<div className="cwp-option">
							<h3 className="cwp-heading">
								{__("Required Text", "cwp-gutenberg-forms")}
							</h3>
							<TextControl
								onChange={(label) =>
									props.setAttributes({ requiredLabel: label })
								}
								value={requiredLabel}
							/>
						</div>
					)}
				</PanelBody>
				<PanelBody title={__("Show Hint", "cwp-gutenberg-forms")}>
					<div className="cwp-option">
						<FormToggle
							label="Show Hint"
							checked={showHint}
							onChange={() => props.setAttributes({ showHint: !showHint })}
						/>
						{showHint && (
							<Fragment>
								<TextControl
									label={__("Hint Text", "cwp-gutenberg-forms")}
									onChange={(hint) => props.setAttributes({ hint })}
									value={hint}
								/>
							</Fragment>
						)}
					</div>
				</PanelBody>
				<PanelBody title={__("Condition", "cwp-gutenberg-forms")}>
					<ConditionalLogic
						condition={condition}
						set={props.setAttributes}
						clientId={props.clientId}
						useCondition={props.attributes.enableCondition}
					/>
				</PanelBody>
				<PanelBody title={__("Messages", "cwp-gutenberg-forms")}>
					{isRequired && (
						<div className="cwp-option">
							<h3 className="cwp-heading">
								{__("Required Error", "cwp-gutenberg-forms")}
							</h3>
							<TextControl
								onChange={(label) => setMessages("empty", label)}
								value={empty}
							/>
						</div>
					)}
					<div className="cwp-option">
						<h3 className="cwp-heading">
							{__("Invalid Message Error", "cwp-gutenberg-forms")}
						</h3>
						<TextControl
							onChange={(v) => setMessages("invalid", v)}
							value={invalid}
						/>
					</div>
					<div className="cwp-option">
						<p>
							<Icon icon="info" />{" "}
							{__("Use {{value}} to insert field value!", "cwp-gutenberg-forms")}
						</p>
					</div>
				</PanelBody>
			</InspectorControls>
		),
		!!props.isSelected && <BlockControls></BlockControls>,
		<div className={`cwp-website cwp-field ${props.className}`}>
			{!!props.isSelected && !enableCondition && (
				<div className="cwp-required">
					<h3>{__("Required", "cwp-gutenberg-forms")}</h3>
					<FormToggle checked={isRequired} onChange={handleRequired} />
				</div>
			)}

			<div className="cwp-field-set">
				<div className="cwp-label-wrap">
					<RichText
						placeholder={__("Add a label", "cwp-gutenberg-forms")}
						tag="label"
						value={label}
						onChange={handleLabel}
					/>
					{!props.isSelected && isRequired && !enableCondition && (
						<div className="cwp-required cwp-noticed">
							<h3>{requiredLabel}</h3>
						</div>
					)}
				</div>
				<div className="cwp-field-with-elements">
					{prefix.enable && (
						<Prefix prefix={prefix}>
							<RichText
								placeholder={__("Prefix", "cwp-gutenberg-forms")}
								tag="span"
								value={prefix.content}
								onChange={(newContent) =>
									handleInputElementChange("prefix", "content", newContent)
								}
							/>
						</Prefix>
					)}
					<input value={website} onChange={handleChange} />
					{suffix.enable && (
						<Suffix suffix={suffix}>
							<RichText
								placeholder={__("Suffix", "cwp-gutenberg-forms")}
								tag="span"
								value={suffix.content}
								onChange={(newContent) =>
									handleInputElementChange("suffix", "content", newContent)
								}
							/>
						</Suffix>
					)}
				</div>
			</div>
			{showHint && (
                <p className="cwp-hint">{hint}</p>
            )}
		</div>,
	];
}
Example #20
Source File: edit.js    From gutenberg-forms with GNU General Public License v2.0 4 votes vote down vote up
function edit(props) {
	const handleChange = (e) => {
		let website = e.target.value;

		props.setAttributes({ website });
	};

	const handleRequired = () => {
		const { isRequired } = props.attributes;

		props.setAttributes({ isRequired: !isRequired });
	};

	const handleLabel = (label) => {
		props.setAttributes({ label });
	};

	const {
		website,
		isRequired,
		label,
		id,
		field_name,
		requiredLabel,
		messages: { invalid, empty },
		messages,
		condition,
		enableCondition,
		adminId,
	} = props.attributes;

	const getRootData = () => {
		if (field_name === "" || detect_similar_forms(props.clientId)) {
			const newFieldName = getFieldName("website", props.clientId);

			props.setAttributes({
				field_name: newFieldName,
				adminId: {
					value: extract_admin_id(newFieldName, "website"),
					default: extract_admin_id(newFieldName, "website"),
				},
			});
			props.setAttributes({
				id:
					props.clientId +
					"__" +
					getEncodedData(
						"website",
						props.clientId,
						isRequired,
						get_admin_id(adminId)
					),
			});
		} else if (field_name !== "") {
			props.setAttributes({
				id:
					extract_id(field_name) +
					"__" +
					getEncodedData(
						"website",
						extract_id(field_name),
						isRequired,
						get_admin_id(adminId)
					),
			});
		}
	};

	useEffect(() => {
		let rootMessages = getRootMessages(props.clientId, "website");

		if (rootMessages) {
			const newMessages = clone(messages);

			assign(newMessages, rootMessages);

			props.setAttributes({ messages: newMessages });
		}

		getRootData();
	}, []);

	useEffect(() => getRootData(), [props]);

	const setMessages = (type, m) => {
		let newMessages = clone(messages);

		set(newMessages, type, m);

		props.setAttributes({ messages: newMessages });
	};

	const handleAdminId = (id) => {
		props.setAttributes({
			adminId: {
				...adminId,
				value: id.replace(/\s|-/g, "_"),
			},
		});
	};

	return [
		!!props.isSelected && (
			<InspectorControls>
				<PanelBody title={__("Field Settings", "cwp-gutenberg-forms")} initialOpen={true}>
					<div className="cwp-option">
						<TextControl
							placeholder={adminId.default}
							label={__("Field ID", "cwp-gutenberg-forms")}
							value={adminId.value}
							onChange={handleAdminId}
						/>
					</div>

					{!enableCondition ? (
						<PanelRow>
							<h3 className="cwp-heading">{__("Required", "cwp-gutenberg-forms")}</h3>
							<FormToggle
								label="Required"
								checked={isRequired}
								onChange={handleRequired}
							/>
						</PanelRow>
					) : (
						<div className="cwp-option">
							<p>
								<Icon icon="info" />{" "}
								{__(
									"You cannot set a conditional field required!",
									"cwp-gutenberg-forms"
								)}
							</p>
						</div>
					)}
					{isRequired && (
						<div className="cwp-option">
							<h3 className="cwp-heading">
								{__("Required Text", "cwp-gutenberg-forms")}
							</h3>
							<TextControl
								onChange={(label) =>
									props.setAttributes({ requiredLabel: label })
								}
								value={requiredLabel}
							/>
						</div>
					)}
				</PanelBody>
				<PanelBody title={__("Condition", "cwp-gutenberg-forms")}>
					<ConditionalLogic
						condition={condition}
						set={props.setAttributes}
						clientId={props.clientId}
						useCondition={props.attributes.enableCondition}
					/>
				</PanelBody>
				<PanelBody title={__("Messages", "cwp-gutenberg-forms")}>
					{isRequired && (
						<div className="cwp-option">
							<h3 className="cwp-heading">
								{__("Required Error", "cwp-gutenberg-forms")}
							</h3>
							<TextControl
								onChange={(label) => setMessages("empty", label)}
								value={empty}
							/>
						</div>
					)}
					<div className="cwp-option">
						<h3 className="cwp-heading">
							{__("Invalid Message Error", "cwp-gutenberg-forms")}
						</h3>
						<TextControl
							onChange={(v) => setMessages("invalid", v)}
							value={invalid}
						/>
					</div>
					<div className="cwp-option">
						<p>
							<Icon icon="info" />{" "}
							{__("Use {{value}} to insert field value!", "cwp-gutenberg-forms")}
						</p>
					</div>
				</PanelBody>
			</InspectorControls>
		),
		!!props.isSelected && <BlockControls></BlockControls>,
		<div className={`cwp-website cwp-field ${props.className}`}>
			{!!props.isSelected && !enableCondition && (
				<div className="cwp-required">
					<h3>{__("Required", "cwp-gutenberg-forms")}</h3>
					<FormToggle checked={isRequired} onChange={handleRequired} />
				</div>
			)}

			<div className="cwp-field-set">
				<div className="cwp-label-wrap">
					<RichText
						placeholder={__("Add a label", "cwp-gutenberg-forms")}
						tag="label"
						value={label}
						onChange={handleLabel}
					/>
					{!props.isSelected && isRequired && !enableCondition && (
						<div className="cwp-required cwp-noticed">
							<h3>{requiredLabel}</h3>
						</div>
					)}
				</div>
				<input value={website} onChange={handleChange} />
			</div>
		</div>,
	];
}
Example #21
Source File: edit.js    From gutenberg-forms with GNU General Public License v2.0 4 votes vote down vote up
function edit(props) {
	const handleChange = (e) => {
		let text = e.target.value;

		props.setAttributes({ text });
	};

	const handleRequired = () => {
		const { isRequired } = props.attributes;

		props.setAttributes({ isRequired: !isRequired });
	};

	const handleLabel = (label) => {
		props.setAttributes({ label });
	};

	const {
		text,
		isRequired,
		label,
		id,
		field_name,
		requiredLabel,
		messages,
		messages: { invalid, empty },
		pattern,
		minimumLength,
		maximumLength,
		condition,
		adminId,
		enableCondition,
		prefix,
		suffix,
		hint,
		showHint
	} = props.attributes;

	const getRootData = () => {
		if (field_name === "" || detect_similar_forms(props.clientId)) {
			const newFieldName = getFieldName("text", props.clientId);

			props.setAttributes({
				field_name: newFieldName,
				adminId: {
					value: extract_admin_id(newFieldName, "text"),
					default: extract_admin_id(newFieldName, "text"),
				},
			});
			props.setAttributes({
				id:
					props.clientId +
					"__" +
					getEncodedData(
						"text",
						props.clientId,
						isRequired,
						get_admin_id(adminId)
					),
			});
		} else if (field_name !== "") {
			props.setAttributes({
				id:
					extract_id(field_name) +
					"__" +
					getEncodedData(
						"text",
						extract_id(field_name),
						isRequired,
						get_admin_id(adminId)
					),
			});
		}
	};

	useEffect(() => {
		let rootMessages = getRootMessages(props.clientId, "text");

		if (rootMessages) {
			const newMessages = clone(messages);

			assign(newMessages, rootMessages);

			props.setAttributes({ messages: newMessages });
		}

		getRootData();
	}, []);

	useEffect(() => getRootData(), [props]);

	const setMessages = (type, m) => {
		let newMessages = clone(messages);

		set(newMessages, type, m);

		props.setAttributes({ messages: newMessages });
	};

	const handleAdminId = (id) => {
		props.setAttributes({
			adminId: {
				...adminId,
				value: id.replace(/\s|-/g, "_"),
			},
		});
	};

	const handleInputElementChange = (type, property, value) => {
		const newSuffix = clone(suffix);
		const newPrefix = clone(prefix);

		switch (type) {
			case "suffix":
				set(newSuffix, property, value);
				props.setAttributes({ suffix: newSuffix });

				break;
			case "prefix":
				set(newPrefix, property, value);
				props.setAttributes({ prefix: newPrefix });
		}
	};

	return [
		!!props.isSelected && (
			<InspectorControls>
				<PanelBody title={__("Field Settings", "cwp-gutenberg-forms")} initialOpen={true}>
					<div className="cwp-option">
						<TextControl
							placeholder={adminId.default}
							label={__("Field ID", "cwp-gutenberg-forms")}
							value={adminId.value}
							onChange={handleAdminId}
						/>
					</div>
					<div className="cwp-option">
						<PanelRow>
							<h3 className="cwp-heading">{__("Prefix", "cwp-gutenberg-forms")}</h3>
							<FormToggle
								label="Prefix"
								checked={prefix.enable}
								onChange={() =>
									handleInputElementChange("prefix", "enable", !prefix.enable)
								}
							/>
						</PanelRow>
					</div>
					<div className="cwp-option">
						<PanelRow>
							<h3 className="cwp-heading">{__("Suffix", "cwp-gutenberg-forms")}</h3>
							<FormToggle
								label="Suffix"
								checked={suffix.enable}
								onChange={() =>
									handleInputElementChange("suffix", "enable", !suffix.enable)
								}
							/>
						</PanelRow>
					</div>
					{!enableCondition ? (
						<PanelRow>
							<h3 className="cwp-heading">{__("Required", "cwp-gutenberg-forms")}</h3>
							<FormToggle
								label={__("Required", "cwp-gutenberg-forms")}
								checked={isRequired}
								onChange={handleRequired}
							/>
						</PanelRow>
					) : (
						<div className="cwp-option">
							<p>
								<Icon icon="info" />{" "}
								{__(
									"You cannot set a conditional field required!",
									"cwp-gutenberg-forms"
								)}
							</p>
						</div>
					)}

					{isRequired && (
						<div className="cwp-option">
							<h3 className="cwp-heading">
								{__("Required Text", "cwp-gutenberg-forms")}
							</h3>
							<TextControl
								onChange={(label) =>
									props.setAttributes({ requiredLabel: label })
								}
								value={requiredLabel}
							/>
						</div>
					)}

					<div className="cwp-option">
						<RangeControl
							label={__("Minimum Length", "cwp-gutenberg-forms")}
							value={minimumLength}
							initialPosition={0}
							onChange={(value) =>
								props.setAttributes({ minimumLength: value })
							}
							min={0}
							max={100}
						/>
						<RangeControl
							label={__("Maximum Length", "cwp-gutenberg-forms")}
							value={maximumLength}
							onChange={(value) =>
								props.setAttributes({ maximumLength: value })
							}
							min={1}
							max={100}
						/>
					</div>
				</PanelBody>
				<PanelBody title={__("Condition", "cwp-gutenberg-forms")}>
					<ConditionalLogic
						condition={condition}
						set={props.setAttributes}
						clientId={props.clientId}
						useCondition={props.attributes.enableCondition}
					/>
				</PanelBody>
				<PanelBody title={__("Messages", "cwp-gutenberg-forms")}>
					{isRequired && (
						<div className="cwp-option">
							<h3 className="cwp-heading">
								{__("Required Error", "cwp-gutenberg-forms")}
							</h3>
							<TextControl
								onChange={(label) => setMessages("empty", label)}
								value={empty}
							/>
						</div>
					)}
					<div className="cwp-option">
						<h3 className="cwp-heading">
							{__("Invalid Message Error", "cwp-gutenberg-forms")}
						</h3>
						<TextControl
							onChange={(v) => setMessages("invalid", v)}
							value={invalid}
						/>
					</div>
					<div className="cwp-option">
						<p>
							<Icon icon="info" />{" "}
							{__("Use {{value}} to insert field value!", "cwp-gutenberg-forms")}
						</p>
					</div>
				</PanelBody>
				<PanelBody title={__("Validation", "cwp-gutenberg-forms")}>
					<div className="cwp-option">
						<TextControl
							label={__("Pattern (RegExp)", "cwp-gutenberg-forms")}
							onChange={(pattern) => props.setAttributes({ pattern })}
							value={pattern}
						/>
					</div>
				</PanelBody>
				<PanelBody title={__("Show Hint", "cwp-gutenberg-forms")}>
					<div className="cwp-option">
						<FormToggle
							label="Show Hint"
							checked={showHint}
							onChange={() => props.setAttributes({ showHint: !showHint })}
						/>
						{showHint && (
							<Fragment>
								<TextControl
									label={__("Hint Text", "cwp-gutenberg-forms")}
									onChange={(hint) => props.setAttributes({ hint })}
									value={hint}
								/>
							</Fragment>
						)}
					</div>
				</PanelBody>
			</InspectorControls>
		),
		!!props.isSelected && <BlockControls></BlockControls>,
		<div className={`cwp-text cwp-field ${props.className}`}>
			{!!props.isSelected && !enableCondition && (
				<div className="cwp-required">
					<h3>Required</h3>
					<FormToggle checked={isRequired} onChange={handleRequired} />
				</div>
			)}

			<div className="cwp-field-set">
				<div className="cwp-label-wrap">
					<RichText
						placeholder={__("Add a label", "cwp-gutenberg-forms")}
						tag="label"
						value={label}
						onChange={handleLabel}
					/>
					{!props.isSelected && isRequired && !enableCondition && (
						<div className="cwp-required cwp-noticed">
							<h3>{requiredLabel}</h3>
						</div>
					)}
				</div>
				<div className="cwp-field-with-elements">
					{prefix.enable && (
						<Prefix prefix={prefix}>
							<RichText
								placeholder={__("Prefix", "cwp-gutenberg-forms")}
								tag="span"
								value={prefix.content}
								onChange={(newContent) =>
									handleInputElementChange("prefix", "content", newContent)
								}
							/>
						</Prefix>
					)}
					<input value={text} onChange={handleChange} />
					{suffix.enable && (
						<Suffix suffix={suffix}>
							<RichText
								placeholder={__("Suffix", "cwp-gutenberg-forms")}
								tag="span"
								value={suffix.content}
								onChange={(newContent) =>
									handleInputElementChange("suffix", "content", newContent)
								}
							/>
						</Suffix>
					)}
				</div>
			</div>
			{showHint && (
                <p className="cwp-hint">{hint}</p>
            )}
		</div>,
	];
}
Example #22
Source File: edit.js    From gutenberg-forms with GNU General Public License v2.0 4 votes vote down vote up
function edit(props) {
	const handleChange = (e) => {
		let text = e.target.value;

		props.setAttributes({ text });
	};

	const handleRequired = () => {
		const { isRequired } = props.attributes;

		props.setAttributes({ isRequired: !isRequired });
	};

	const handleLabel = (label) => {
		props.setAttributes({ label });
	};

	const {
		text,
		isRequired,
		label,
		id,
		field_name,
		requiredLabel,
		messages,
		messages: { invalid, empty },
		pattern,
		minimumLength,
		maximumLength,
		condition,
		adminId,
		enableCondition,
	} = props.attributes;

	const getRootData = () => {
		if (field_name === "" || detect_similar_forms(props.clientId)) {
			const newFieldName = getFieldName("text", props.clientId);

			props.setAttributes({
				field_name: newFieldName,
				adminId: {
					value: extract_admin_id(newFieldName, "text"),
					default: extract_admin_id(newFieldName, "text"),
				},
			});
			props.setAttributes({
				id:
					props.clientId +
					"__" +
					getEncodedData(
						"text",
						props.clientId,
						isRequired,
						get_admin_id(adminId)
					),
			});
		} else if (field_name !== "") {
			props.setAttributes({
				id:
					extract_id(field_name) +
					"__" +
					getEncodedData(
						"text",
						extract_id(field_name),
						isRequired,
						get_admin_id(adminId)
					),
			});
		}
	};

	useEffect(() => {
		let rootMessages = getRootMessages(props.clientId, "text");

		if (rootMessages) {
			const newMessages = clone(messages);

			assign(newMessages, rootMessages);

			props.setAttributes({ messages: newMessages });
		}

		getRootData();
	}, []);

	useEffect(() => getRootData(), [props]);

	const setMessages = (type, m) => {
		let newMessages = clone(messages);

		set(newMessages, type, m);

		props.setAttributes({ messages: newMessages });
	};

	const handleAdminId = (id) => {
		props.setAttributes({
			adminId: {
				...adminId,
				value: id.replace(/\s|-/g, "_"),
			},
		});
	};

	return [
		!!props.isSelected && (
			<InspectorControls>
				<PanelBody title={__("Field Settings", "cwp-gutenberg-forms")} initialOpen={true}>
					<div className="cwp-option">
						<TextControl
							placeholder={adminId.default}
							label={__("Field ID", "cwp-gutenberg-forms")}
							value={adminId.value}
							onChange={handleAdminId}
						/>
					</div>

					{!enableCondition ? (
						<PanelRow>
							<h3 className="cwp-heading">{__("Required", "cwp-gutenberg-forms")}</h3>
							<FormToggle
								label={__("Required", "cwp-gutenberg-forms")}
								checked={isRequired}
								onChange={handleRequired}
							/>
						</PanelRow>
					) : (
						<div className="cwp-option">
							<p>
								<Icon icon="info" />{" "}
								{__(
									"You cannot set a conditional field required!",
									"cwp-gutenberg-forms"
								)}
							</p>
						</div>
					)}

					{isRequired && (
						<div className="cwp-option">
							<h3 className="cwp-heading">
								{__("Required Text", "cwp-gutenberg-forms")}
							</h3>
							<TextControl
								onChange={(label) =>
									props.setAttributes({ requiredLabel: label })
								}
								value={requiredLabel}
							/>
						</div>
					)}

					<div className="cwp-option">
						<RangeControl
							label={__("Minimum Length", "cwp-gutenberg-forms")}
							value={minimumLength}
							initialPosition={0}
							onChange={(value) =>
								props.setAttributes({ minimumLength: value })
							}
							min={0}
							max={100}
						/>
						<RangeControl
							label={__("Maximum Length", "cwp-gutenberg-forms")}
							value={maximumLength}
							onChange={(value) =>
								props.setAttributes({ maximumLength: value })
							}
							min={1}
							max={100}
						/>
					</div>
				</PanelBody>
				<PanelBody title={__("Condition", "cwp-gutenberg-forms")}>
					<ConditionalLogic
						condition={condition}
						set={props.setAttributes}
						clientId={props.clientId}
						useCondition={props.attributes.enableCondition}
					/>
				</PanelBody>
				<PanelBody title={__("Messages", "cwp-gutenberg-forms")}>
					{isRequired && (
						<div className="cwp-option">
							<h3 className="cwp-heading">
								{__("Required Error", "cwp-gutenberg-forms")}
							</h3>
							<TextControl
								onChange={(label) => setMessages("empty", label)}
								value={empty}
							/>
						</div>
					)}
					<div className="cwp-option">
						<h3 className="cwp-heading">
							{__("Invalid Message Error", "cwp-gutenberg-forms")}
						</h3>
						<TextControl
							onChange={(v) => setMessages("invalid", v)}
							value={invalid}
						/>
					</div>
					<div className="cwp-option">
						<p>
							<Icon icon="info" />{" "}
							{__("Use {{value}} to insert field value!", "cwp-gutenberg-forms")}
						</p>
					</div>
				</PanelBody>
				<PanelBody title={__("Validation", "cwp-gutenberg-forms")}>
					<div className="cwp-option">
						<TextControl
							label={__("Pattern (RegExp)", "cwp-gutenberg-forms")}
							onChange={(pattern) => props.setAttributes({ pattern })}
							value={pattern}
						/>
					</div>
				</PanelBody>
			</InspectorControls>
		),
		!!props.isSelected && <BlockControls></BlockControls>,
		<div className={`cwp-text cwp-field ${props.className}`}>
			{!!props.isSelected && !enableCondition && (
				<div className="cwp-required">
					<h3>Required</h3>
					<FormToggle checked={isRequired} onChange={handleRequired} />
				</div>
			)}

			<div className="cwp-field-set">
				<div className="cwp-label-wrap">
					<RichText
						placeholder={__("Add a label", "cwp-gutenberg-forms")}
						tag="label"
						value={label}
						onChange={handleLabel}
					/>
					{!props.isSelected && isRequired && !enableCondition && (
						<div className="cwp-required cwp-noticed">
							<h3>{requiredLabel}</h3>
						</div>
					)}
				</div>
				<input value={text} onChange={handleChange} />
			</div>
		</div>,
	];
}
Example #23
Source File: edit.js    From gutenberg-forms with GNU General Public License v2.0 4 votes vote down vote up
function edit(props) {
	let {
		options,
		isRequired,
		label,
		id,
		field_name,
		requiredLabel,
		messages: { empty },
		messages,
		condition,
		enableCondition,
		bulkAdd,
		adminId,
		hint,
		showHint
	} = props.attributes;

	const [select, setSelect] = useState([]);

	const [focus, setFocus] = useState({
		f: false,
		index: null,
	});

	const selectContainer = useRef();

	const getRootData = () => {
		if (field_name === "" || detect_similar_forms(props.clientId)) {
			const newFieldName = getFieldName("select", props.clientId);

			props.setAttributes({
				field_name: newFieldName,
				adminId: {
					value: extract_admin_id(newFieldName, "select"),
					default: extract_admin_id(newFieldName, "select"),
				},
			});
			props.setAttributes({
				id:
					props.clientId +
					"__" +
					getEncodedData(
						"select",
						props.clientId,
						isRequired,
						get_admin_id(adminId)
					),
			});
		} else if (field_name !== "") {
			props.setAttributes({
				id:
					extract_id(field_name) +
					"__" +
					getEncodedData(
						"select",
						extract_id(field_name),
						isRequired,
						get_admin_id(adminId)
					),
			});
		}
	};

	useEffect(() => {
		let rootMessages = getRootMessages(props.clientId, "select");

		if (rootMessages) {
			const newMessages = clone(messages);

			assign(newMessages, rootMessages);

			props.setAttributes({ messages: newMessages });
		}

		let { options } = props.attributes;

		setSelect(options);

		getRootData();
	}, []);

	useEffect(() => getRootData(), [props]);

	useEffect(() => {
		if (bulkAdd) return;

		let boxes = selectContainer.current.querySelectorAll(
			'.cwp-select-option input[type="text"]'
		);

		if (focus.f) {
			if (focus.index === null) {
				boxes[boxes.length - 1].focus();
			} else {
				boxes[focus.index].focus();
			}

			setFocus({ f: false, index: null });
		}
	}, [select, focus]); //subscribing to any further changes...

	const handleRequired = () => {
		const { isRequired } = props.attributes;

		props.setAttributes({ isRequired: !isRequired });
	};

	const addSelect = () => {
		let newOption = {
			label: "Option " + (select.length + 1),
		};

		let new_options = clone(select);

		new_options.push(newOption);

		props.setAttributes({ options: new_options });
		setSelect(new_options);
	};

	const handleDelete = (index) => {
		let new_options = clone(options);

		let deleted_options = pullAt(new_options, [index]); //dosen't matter :-D

		props.setAttributes({ options: new_options });
		setSelect(new_options);
	};

	const handleLabel = (label) => {
		props.setAttributes({ label });
	};

	const handleChange = (e, index) => {
		let new_options = clone(options);

		new_options[index] = {
			...new_options[index],
			label: e.target.value,
		};

		setSelect(new_options);
		props.setAttributes({ options: new_options });
	};

	let handleDuplicate = (index) => {
		let new_options = clone(options);

		new_options.splice(index, 0, new_options[index]);

		setSelect(new_options);
		props.setAttributes({ options: new_options });
	};

	let handleEnter = (index) => {
		let new_options = clone(options);

		new_options.splice(index + 1, 0, { label: "" });

		setSelect(new_options);
		props.setAttributes({ options: new_options });
		setFocus({ f: true, index: index + 1 });
	};

	let handleBackspace = (index) => {
		if (select[index].label === "") {
			handleDelete(index);

			if (select[index - 1]) {
				setFocus({ f: true, index: index - 1 });
			}
		}
	};

	const setMessages = (type, m) => {
		let newMessages = clone(messages);

		set(newMessages, type, m);

		props.setAttributes({ messages: newMessages });
	};

	let clearAll = () => {
		const reset = [
			{
				label: "Option 1",
			},
		];

		setSelect(reset);
		props.setAttributes({
			options: reset,
		});
	};

	const handleAdminId = (id) => {
		props.setAttributes({
			adminId: {
				...adminId,
				value: id.replace(/\s|-/g, "_"),
			},
		});
	};

	const editView = select.map((s, index) => {
		return (
			<div className="cwp-select-option">
				<input
					aria-label={strip_tags(label)}
					onChange={(e) => handleChange(e, index)}
					type="text"
					value={s.label}
					onKeyDown={(e) => {
						e.key === "Enter" && handleEnter(index);
						e.key === "Backspace" && handleBackspace(index);
					}}
				/>
				<Button isDefault onClick={() => handleDuplicate(index)}>
					<Icon icon="admin-page" />
				</Button>
				<Button isDefault onClick={() => handleDelete(index)}>
					<Icon icon="no-alt" />
				</Button>
			</div>
		);
	});

	const SelectView = () => {
		return (
			<select data-cwp-field>
				{select.map((s, index) => {
					return <option value={s.label}>{s.label}</option>;
				})}
			</select>
		);
	};

	return [
		<InspectorControls>
			<PanelBody title={__("Field Settings", "cwp-gutenberg-forms")} initialOpen={true}>
				<div className="cwp-option">
					<TextControl
						placeholder={adminId.default}
						label={__("Field ID", "cwp-gutenberg-forms")}
						value={adminId.value}
						onChange={handleAdminId}
					/>
				</div>

				{!enableCondition ? (
					<PanelRow>
						<h3 className="cwp-heading">{__("Required", "cwp-gutenberg-forms")}</h3>
						<FormToggle
							label={__("Required", "cwp-gutenberg-forms")}
							checked={isRequired}
							onChange={handleRequired}
						/>
					</PanelRow>
				) : (
					<div className="cwp-option">
						<p>
							<Icon icon="info" />{" "}
							{__("You cannot set a conditional field required!", "cwp-gutenberg-forms")}
						</p>
					</div>
				)}
				{isRequired && (
					<div className="cwp-option">
						<h3 className="cwp-heading">{__("Required Text", "cwp-gutenberg-forms")}</h3>
						<TextControl
							onChange={(label) =>
								props.setAttributes({ requiredLabel: label })
							}
							value={requiredLabel}
						/>
					</div>
				)}
			</PanelBody>
			<PanelBody title={__("Show Hint", "cwp-gutenberg-forms")}>
				<div className="cwp-option">
					<FormToggle
						label="Show Hint"
						checked={showHint}
						onChange={() => props.setAttributes({ showHint: !showHint })}
					/>
					{showHint && (
						<Fragment>
							<TextControl
								label={__("Hint Text", "cwp-gutenberg-forms")}
								onChange={(hint) => props.setAttributes({ hint })}
								value={hint}
							/>
						</Fragment>
					)}
				</div>
			</PanelBody>
			<PanelBody title={__("Condition", "cwp-gutenberg-forms")}>
				<ConditionalLogic
					condition={condition}
					set={props.setAttributes}
					clientId={props.clientId}
					useCondition={props.attributes.enableCondition}
				/>
			</PanelBody>
			{isRequired && (
				<PanelBody title={__("Messages", "cwp-gutenberg-forms")}>
					<div className="cwp-option">
						<h3 className="cwp-heading">{__("Required Error", "cwp-gutenberg-forms")}</h3>
						<TextControl
							onChange={(label) => setMessages("empty", label)}
							value={empty}
						/>
					</div>
				</PanelBody>
			)}
		</InspectorControls>,
		null,
		<div
			className={`cwp-select cwp-field ${
				!props.isSelected ? props.className : ""
			}`}
		>
			{bulkAdd ? (
				<Bulk_Add onChange={(c) => setSelect(c)} data={props} />
			) : (
				<Fragment>
					{!!props.isSelected && !enableCondition && (
						<div className="cwp-required">
							<h3>{__("Required", "cwp-gutenberg-forms")}</h3>
							<FormToggle checked={isRequired} onChange={handleRequired} />
						</div>
					)}

					<div className="cwp-select-set" ref={selectContainer}>
						<div className="cwp-label-wrap">
							<RichText
								placeholder={__("Add a label", "cwp-gutenberg-forms")}
								tag="label"
								value={label}
								onChange={handleLabel}
							/>
							{!props.isSelected && isRequired && !enableCondition && (
								<div className="cwp-required cwp-noticed">
									<h3>{requiredLabel}</h3>
								</div>
							)}
						</div>
						{!!props.isSelected ? editView : <SelectView />}
						{!!props.isSelected && (
							<div className="cwp-select-controls">
								<div>
									<Button isDefault onClick={addSelect}>
										{__("Add Option", "cwp-gutenberg-forms")}
									</Button>
									<Button
										isDefault
										onClick={() => props.setAttributes({ bulkAdd: true })}
									>
										{__("Bulk Add", "cwp-gutenberg-forms")}
									</Button>
								</div>
								<div>
									<Button onClick={clearAll}>
										{__("Clear All", "cwp-gutenberg-forms")}
									</Button>
								</div>
							</div>
						)}
					</div>
				</Fragment>
			)}
			{showHint && (
                <p className="cwp-hint">{hint}</p>
            )}
		</div>,
	];
}
Example #24
Source File: edit.js    From gutenberg-forms with GNU General Public License v2.0 4 votes vote down vote up
function edit(props) {
	let {
		options,
		isRequired,
		label,
		id,
		field_name,
		requiredLabel,
		messages: { empty },
		messages,
		condition,
		enableCondition,
		bulkAdd,
		adminId,
	} = props.attributes;

	const [select, setSelect] = useState([]);

	const [focus, setFocus] = useState({
		f: false,
		index: null,
	});

	const selectContainer = useRef();

	const getRootData = () => {
		if (field_name === "" || detect_similar_forms(props.clientId)) {
			const newFieldName = getFieldName("select", props.clientId);

			props.setAttributes({
				field_name: newFieldName,
				adminId: {
					value: extract_admin_id(newFieldName, "select"),
					default: extract_admin_id(newFieldName, "select"),
				},
			});
			props.setAttributes({
				id:
					props.clientId +
					"__" +
					getEncodedData(
						"select",
						props.clientId,
						isRequired,
						get_admin_id(adminId)
					),
			});
		} else if (field_name !== "") {
			props.setAttributes({
				id:
					extract_id(field_name) +
					"__" +
					getEncodedData(
						"select",
						extract_id(field_name),
						isRequired,
						get_admin_id(adminId)
					),
			});
		}
	};

	useEffect(() => {
		let rootMessages = getRootMessages(props.clientId, "select");

		if (rootMessages) {
			const newMessages = clone(messages);

			assign(newMessages, rootMessages);

			props.setAttributes({ messages: newMessages });
		}

		let { options } = props.attributes;

		setSelect(options);

		getRootData();
	}, []);

	useEffect(() => getRootData(), [props]);

	useEffect(() => {
		if (bulkAdd) return;

		let boxes = selectContainer.current.querySelectorAll(
			'.cwp-select-option input[type="text"]'
		);

		if (focus.f) {
			if (focus.index === null) {
				boxes[boxes.length - 1].focus();
			} else {
				boxes[focus.index].focus();
			}

			setFocus({ f: false, index: null });
		}
	}, [select, focus]); //subscribing to any further changes...

	const handleRequired = () => {
		const { isRequired } = props.attributes;

		props.setAttributes({ isRequired: !isRequired });
	};

	const addSelect = () => {
		let newOption = {
			label: "Option " + (select.length + 1),
		};

		let new_options = clone(select);

		new_options.push(newOption);

		props.setAttributes({ options: new_options });
		setSelect(new_options);
	};

	const handleDelete = (index) => {
		let new_options = clone(options);

		let deleted_options = pullAt(new_options, [index]); //dosen't matter :-D

		props.setAttributes({ options: new_options });
		setSelect(new_options);
	};

	const handleLabel = (label) => {
		props.setAttributes({ label });
	};

	const handleChange = (e, index) => {
		let new_options = clone(options);

		new_options[index] = {
			...new_options[index],
			label: e.target.value,
		};

		setSelect(new_options);
		props.setAttributes({ options: new_options });
	};

	let handleDuplicate = (index) => {
		let new_options = clone(options);

		new_options.splice(index, 0, new_options[index]);

		setSelect(new_options);
		props.setAttributes({ options: new_options });
	};

	let handleEnter = (index) => {
		let new_options = clone(options);

		new_options.splice(index + 1, 0, { label: "" });

		setSelect(new_options);
		props.setAttributes({ options: new_options });
		setFocus({ f: true, index: index + 1 });
	};

	let handleBackspace = (index) => {
		if (select[index].label === "") {
			handleDelete(index);

			if (select[index - 1]) {
				setFocus({ f: true, index: index - 1 });
			}
		}
	};

	const setMessages = (type, m) => {
		let newMessages = clone(messages);

		set(newMessages, type, m);

		props.setAttributes({ messages: newMessages });
	};

	let clearAll = () => {
		const reset = [
			{
				label: "Option 1",
			},
		];

		setSelect(reset);
		props.setAttributes({
			options: reset,
		});
	};

	const handleAdminId = (id) => {
		props.setAttributes({
			adminId: {
				...adminId,
				value: id.replace(/\s|-/g, "_"),
			},
		});
	};

	const editView = select.map((s, index) => {
		return (
			<div className="cwp-select-option">
				<input
					aria-label={strip_tags(label)}
					onChange={(e) => handleChange(e, index)}
					type="text"
					value={s.label}
					onKeyDown={(e) => {
						e.key === "Enter" && handleEnter(index);
						e.key === "Backspace" && handleBackspace(index);
					}}
				/>
				<Button isDefault onClick={() => handleDuplicate(index)}>
					<Icon icon="admin-page" />
				</Button>
				<Button isDefault onClick={() => handleDelete(index)}>
					<Icon icon="no-alt" />
				</Button>
			</div>
		);
	});

	const SelectView = () => {
		return (
			<select data-cwp-field>
				<option value="" disabled selected>
					Select your option
				</option>
				{select.map((s, index) => {
					return <option value={s.label}>{s.label}</option>;
				})}
			</select>
		);
	};

	return [
		<InspectorControls>
			<PanelBody title={__("Field Settings", "cwp-gutenberg-forms")} initialOpen={true}>
				<div className="cwp-option">
					<TextControl
						placeholder={adminId.default}
						label={__("Field ID", "cwp-gutenberg-forms")}
						value={adminId.value}
						onChange={handleAdminId}
					/>
				</div>

				{!enableCondition ? (
					<PanelRow>
						<h3 className="cwp-heading">{__("Required", "cwp-gutenberg-forms")}</h3>
						<FormToggle
							label={__("Required", "cwp-gutenberg-forms")}
							checked={isRequired}
							onChange={handleRequired}
						/>
					</PanelRow>
				) : (
					<div className="cwp-option">
						<p>
							<Icon icon="info" />{" "}
							{__("You cannot set a conditional field required!", "cwp-gutenberg-forms")}
						</p>
					</div>
				)}
				{isRequired && (
					<div className="cwp-option">
						<h3 className="cwp-heading">{__("Required Text", "cwp-gutenberg-forms")}</h3>
						<TextControl
							onChange={(label) =>
								props.setAttributes({ requiredLabel: label })
							}
							value={requiredLabel}
						/>
					</div>
				)}
			</PanelBody>
			<PanelBody title={__("Condition", "cwp-gutenberg-forms")}>
				<ConditionalLogic
					condition={condition}
					set={props.setAttributes}
					clientId={props.clientId}
					useCondition={props.attributes.enableCondition}
				/>
			</PanelBody>
			{isRequired && (
				<PanelBody title={__("Messages", "cwp-gutenberg-forms")}>
					<div className="cwp-option">
						<h3 className="cwp-heading">{__("Required Error", "cwp-gutenberg-forms")}</h3>
						<TextControl
							onChange={(label) => setMessages("empty", label)}
							value={empty}
						/>
					</div>
				</PanelBody>
			)}
		</InspectorControls>,
		null,
		<div
			className={`cwp-select cwp-field ${
				!props.isSelected ? props.className : ""
			}`}
		>
			{bulkAdd ? (
				<Bulk_Add onChange={(c) => setSelect(c)} data={props} />
			) : (
				<Fragment>
					{!!props.isSelected && !enableCondition && (
						<div className="cwp-required">
							<h3>{__("Required", "cwp-gutenberg-forms")}</h3>
							<FormToggle checked={isRequired} onChange={handleRequired} />
						</div>
					)}

					<div className="cwp-select-set" ref={selectContainer}>
						<div className="cwp-label-wrap">
							<RichText
								placeholder={__("Add a label", "cwp-gutenberg-forms")}
								tag="label"
								value={label}
								onChange={handleLabel}
							/>
							{!props.isSelected && isRequired && !enableCondition && (
								<div className="cwp-required cwp-noticed">
									<h3>{requiredLabel}</h3>
								</div>
							)}
						</div>
						{!!props.isSelected ? editView : <SelectView />}
						{!!props.isSelected && (
							<div className="cwp-select-controls">
								<div>
									<Button isDefault onClick={addSelect}>
										{__("Add Option", "cwp-gutenberg-forms")}
									</Button>
									<Button
										isDefault
										onClick={() => props.setAttributes({ bulkAdd: true })}
									>
										{__("Bulk Add", "cwp-gutenberg-forms")}
									</Button>
								</div>
								<div>
									<Button onClick={clearAll}>
										{__("Clear All", "cwp-gutenberg-forms")}
									</Button>
								</div>
							</div>
						)}
					</div>
				</Fragment>
			)}
		</div>,
	];
}
Example #25
Source File: edit.js    From gutenberg-forms with GNU General Public License v2.0 4 votes vote down vote up
function edit(props) {
	const handleLabel = label => {
		props.setAttributes({ label });
	};

	const {
		calculation,
		label,
		field_name,
		condition,
		styling,
		formulaBuilder,
		postfix,
		prefix,
		adminId,
		decimalPlaces
	} = props.attributes;

	const setStyling = (style, styleName) => {
		const newStyling = clone(styling);

		set(newStyling, styleName, style);

		props.setAttributes({ styling: newStyling });
	};


	const getRootData = () => {
		if (field_name === "" || detect_similar_forms(props.clientId)) {

			const newFieldName = getFieldName("calculation", props.clientId);

			props.setAttributes({
				field_name: newFieldName,
				adminId: {
					value: extract_admin_id(newFieldName, 'calculation'),
					default: extract_admin_id(newFieldName, 'calculation')
				}
			});
			props.setAttributes({
				id:
					props.clientId +
					"__" +
					getEncodedData("calculation", props.clientId, false, get_admin_id(adminId))
			});
		} else if (field_name !== "") {
			props.setAttributes({
				id:
					extract_id(field_name) +
					"__" +
					getEncodedData("calculation", extract_id(field_name), false, get_admin_id(adminId))
			});
		}
	}

	useEffect(() => {
		getRootData()
	}, []);

	useEffect(() => {
		getRootData()
	}, [props]);


	const handleAdminId = (id) => {
		props.setAttributes({
			adminId: {
				...adminId,
				value: id.replace(/\s|-/g, "_")
			}
		})
	}

	return [
		!!props.isSelected && (
			<InspectorControls>
				<PanelBody title={__("Field Settings", "cwp-gutenberg-forms")}>

					<div className="cwp-option">
						<TextControl
							placeholder={adminId.default}
							label={__("Field ID", "cwp-gutenberg-forms")}
							value={adminId.value}
							onChange={handleAdminId}
						/>
					</div>

					<div className="cwp-option">
						<h3>{__("Prefix", "cwp-gutenberg-forms")}</h3>

						<TextControl
							value={prefix}
							onChange={val => props.setAttributes({ prefix: val })}
						/>
					</div>
					<div className="cwp-option">
						<h3>{__("Postfix", "cwp-gutenberg-forms")}</h3>

						<TextControl
							value={postfix}
							onChange={val => props.setAttributes({ postfix: val })}
						/>
					</div>
					<div className="cwp-option">
						<PanelRow>
							<h3>{__("Formula Editor", "cwp-gutenberg-forms")}</h3>
							<FormToggle
								checked={formulaBuilder}
								onChange={() =>
									props.setAttributes({ formulaBuilder: !formulaBuilder })
								}
							/>
						</PanelRow>
					</div>
					<div className="cwp-option">
						<RangeControl
							value={decimalPlaces}
							min={0}
							max={10}
							label={__("Decimal Places", "cwp-gutenberg-forms")}
							onChange={decimalPlaces => props.setAttributes({ decimalPlaces })}
						/>
					</div>
				</PanelBody>
				<PanelBody title={__("Condition", "cwp-gutenberg-forms")}>
					<ConditionalLogic
						condition={condition}
						set={props.setAttributes}
						clientId={props.clientId}
						useCondition={props.attributes.enableCondition}
					/>
				</PanelBody>
				<PanelBody title={__("Styling", "cwp-gutenberg-forms")}>
					<div className="cwp-option">
						<RangeControl
							value={styling.fontSize}
							label={__("Font Size", "cwp-gutenberg-forms")}
							onChange={size => setStyling(size, "fontSize")}
						/>
					</div>
				</PanelBody>
			</InspectorControls>
		),
		!!props.isSelected && (
			<BlockControls>
				<Toolbar>
					<Tooltip
						text={__(formulaBuilder ? __("Preview Field", "cwp-gutenberg-forms") : __("Formula Editor", "cwp-gutenberg-forms"))}
					>
						<Button
							onClick={() => {
								props.setAttributes({ formulaBuilder: !formulaBuilder });
							}}
						>
							<BlockIcon icon={formulaBuilder ? "no" : "edit"} showColors />
						</Button>
					</Tooltip>
				</Toolbar>
			</BlockControls>
		),

		<div className={`cwp-calculation cwp-field ${props.className}`}>
			<div className="cwp-calc-toggle">
				<h3>{__("Formula Editor", "cwp-gutenberg-forms")}</h3>
				<FormToggle
					checked={formulaBuilder}
					onChange={() =>
						props.setAttributes({ formulaBuilder: !formulaBuilder })
					}
				/>
			</div>
			{formulaBuilder ? (
				<FormulaBuilder data={props} />
			) : (
					<div className="cwp-field-set">
						<RichText placeholder={__("Add a label", "cwp-gutenberg-forms")} tag="label" value={label} onChange={handleLabel} />
						<div className="cwp-result-wrap">
							{!isEmpty(prefix) && <span style={styling}>{prefix}</span>}
							<span className="cwp-calc-result" style={styling}>
								XX
							</span>
							{!isEmpty(postfix) && <span style={styling}>{postfix}</span>}
						</div>
					</div>
				)}
		</div>
	];
}
Example #26
Source File: index.js    From strapi-molecules with MIT License 4 votes vote down vote up
function SelectWrapper({
  componentUid,
  description,
  editable,
  label,
  isCreatingEntry,
  isFieldAllowed,
  isFieldReadable,
  mainField,
  name,
  relationType,
  slug,
  targetModel,
  placeholder,
  valueToSet,
}) {
  // Disable the input in case of a polymorphic relation
  const isMorph = relationType.toLowerCase().includes("morph");
  const {
    addRelation,
    modifiedData,
    moveRelation,
    onChange,
    onRemoveRelation,
    initialData,
  } = useDataManager();
  const { isDraggingComponent } = useEditView();

  const value =
    valueToSet && valueToSet !== "current"
      ? valueToSet
      : get(modifiedData, name, null);
  const initialValue = get(initialData, name, null);

  // This is needed for making requests when used in a component
  const fieldName = useMemo(() => {
    const fieldNameArray = getFieldName(name);
    return fieldNameArray[fieldNameArray.length - 1];
  }, [name]);

  const { pathname } = useLocation();

  const [state, setState] = useState({
    _contains: "",
    _limit: 20,
    _start: 0,
  });
  const [options, setOptions] = useState([]);
  const [isLoading, setIsLoading] = useState(true);
  const abortController = new AbortController();
  const { signal } = abortController;
  const ref = useRef();
  const startRef = useRef();

  const filteredOptions = useMemo(() => {
    return options.filter((option) => {
      if (!isEmpty(value)) {
        // SelectMany
        if (Array.isArray(value)) {
          return findIndex(value, (o) => o.id === option.value.id) === -1;
        }

        // SelectOne
        return get(value, "id", "") !== option.value.id;
      }

      return true;
    });
  }, [options, value]);

  startRef.current = state._start;

  ref.current = async () => {
    if (isMorph) {
      setIsLoading(false);

      return;
    }

    if (!isDraggingComponent) {
      try {
        const requestUrl = `/${pluginId}/explorer/${slug}/relation-list/${fieldName}`;

        const containsKey = `${mainField}_contains`;
        const { _contains, ...restState } = cloneDeep(state);
        const params = isEmpty(state._contains)
          ? restState
          : { [containsKey]: _contains, ...restState };

        if (componentUid) {
          set(params, "_component", componentUid);
        }

        const data = await request(requestUrl, {
          method: "GET",
          params,
          signal,
        });

        const formattedData = data.map((obj) => {
          return { value: obj, label: obj[mainField] };
        });

        setOptions((prevState) =>
          prevState.concat(formattedData).filter((obj, index) => {
            const objIndex = prevState.findIndex(
              (el) => el.value.id === obj.value.id,
            );

            if (objIndex === -1) {
              return true;
            }

            return (
              prevState.findIndex((el) => el.value.id === obj.value.id) ===
              index
            );
          }),
        );
        setIsLoading(false);
      } catch (err) {
        if (err.code !== 20) {
          strapi.notification.error("notification.error");
        }
      }
    }
  };

  useEffect(() => {
    if (state._contains !== "") {
      let timer = setTimeout(() => {
        ref.current();
      }, 300);

      return () => clearTimeout(timer);
    }

    if (isFieldAllowed) {
      ref.current();
    }

    return () => {
      abortController.abort();
    };
  }, [state._contains, isFieldAllowed]);

  useEffect(() => {
    if (state._start !== 0) {
      ref.current();
    }

    return () => {
      abortController.abort();
    };
  }, [state._start]);

  const onInputChange = (inputValue, { action }) => {
    if (action === "input-change") {
      setState((prevState) => {
        if (prevState._contains === inputValue) {
          return prevState;
        }

        return { ...prevState, _contains: inputValue, _start: 0 };
      });
    }

    return inputValue;
  };

  const onMenuScrollToBottom = () => {
    setState((prevState) => ({ ...prevState, _start: prevState._start + 20 }));
  };

  const isSingle = [
    "oneWay",
    "oneToOne",
    "manyToOne",
    "oneToManyMorph",
    "oneToOneMorph",
  ].includes(relationType);

  const changeRelationValueForCurrentVersion = () => {
    if (valueToSet && startRef.current != 0) {
      valueToSet !== "current"
        ? onChange({ target: { name, value: valueToSet } })
        : onChange({ target: { name, value: initialValue } });
    }
  };

  useEffect(() => {
    changeRelationValueForCurrentVersion();
  }, [valueToSet]);

  const to = `/plugins/${pluginId}/collectionType/${targetModel}/${
    value ? value.id : null
  }`;
  const link =
    value === null ||
    value === undefined ||
    [
      "plugins::users-permissions.role",
      "plugins::users-permissions.permission",
    ].includes(targetModel) ? null : (
      <Link to={{ pathname: to, state: { from: pathname } }}>
        <FormattedMessage id="content-manager.containers.Edit.seeDetails" />
      </Link>
    );
  const Component = isSingle ? SelectOne : SelectMany;
  const associationsLength = isArray(value) ? value.length : 0;

  const customStyles = {
    option: (provided) => {
      return {
        ...provided,
        maxWidth: "100% !important",
        overflow: "hidden",
        textOverflow: "ellipsis",
        whiteSpace: "nowrap",
      };
    },
  };

  const isDisabled = useMemo(() => {
    if (isMorph) {
      return true;
    }

    if (!isCreatingEntry) {
      return !isFieldAllowed && isFieldReadable;
    }

    return !editable;
  });

  if (!isFieldAllowed && isCreatingEntry) {
    return <NotAllowedInput label={label} />;
  }

  if (!isCreatingEntry && !isFieldAllowed && !isFieldReadable) {
    return <NotAllowedInput label={label} />;
  }

  return (
    <Wrapper className="form-group">
      <Nav>
        <div>
          <label htmlFor={name}>
            {label}
            {!isSingle && (
              <span style={{ fontWeight: 400, fontSize: 12 }}>
                &nbsp;({associationsLength})
              </span>
            )}
          </label>
          {isSingle && link}
        </div>
        {!isEmpty(description) && <p className="description">{description}</p>}
      </Nav>
      <Component
        addRelation={(value) => {
          addRelation({ target: { name, value } });
        }}
        id={name}
        isDisabled={isDisabled}
        isLoading={isLoading}
        isClearable
        mainField={mainField}
        move={moveRelation}
        name={name}
        options={filteredOptions}
        onChange={(value) => {
          onChange({ target: { name, value: value ? value.value : value } });
        }}
        onInputChange={onInputChange}
        onMenuClose={() => {
          setState((prevState) => ({ ...prevState, _contains: "" }));
        }}
        onMenuScrollToBottom={onMenuScrollToBottom}
        onRemove={onRemoveRelation}
        placeholder={
          isEmpty(placeholder) ? (
            <FormattedMessage id={`${pluginId}.containers.Edit.addAnItem`} />
          ) : (
            placeholder
          )
        }
        styles={customStyles}
        targetModel={targetModel}
        value={value}
      />
      <div style={{ marginBottom: 18 }} />
    </Wrapper>
  );
}
Example #27
Source File: condition.js    From gutenberg-forms with GNU General Public License v2.0 4 votes vote down vote up
function Condition(props) {
	let currentField = props.fieldName,
		{ clientId, condition } = props; // where props.set === props.setAttributes

	useEffect(() => {
		let first_field = getOptions()[1];

		if (
			!isEmpty(first_field) &&
			has(first_field, "value") &&
			isEmpty(condition.value)
		) {
			handleConditionChange(first_field.value, "field");
		}
	}, []);

	const getOptions = () => {
		let fields = [
			{
				value: null,
				label: __("Select Field", 'cwp-gutenberg-forms'),
			},
		];

		// function getSiblings( clientId ) => return the relatives of the particular field inside a parent/root block

		getSiblings(clientId).forEach((sibling) => {
			if (!has(sibling, "label") && !has(sibling, "field_name")) return;
			const { label, field_name } = sibling; //destructuring the label attribute from the sibling field..

			fields.push({ value: field_name, label: label }); //pushing the option to the select field
			//where field_name is the unique id of the field;
		});

		return fields;
	};

	const handleConditionChange = (value, type) => {
		const newCondition = clone(condition); //creating a copy of the existing condition;

		set(newCondition, type, value); //modifying the condition copy;

		props.set({ condition: newCondition }); //props.setAttributes()
	};

	let operators = [
		{
			value: "===",
			label: __("Is Equal To", 'cwp-gutenberg-forms'),
		},
		{
			value: "!==",
			label: __("Not Equal To", 'cwp-gutenberg-forms'),
		},
	];

	const getValueType = () => {
		if (isEmpty(condition.field)) return null;

		const splitted_fieldName = condition.field.split("-"),
			fieldName = splitted_fieldName[0];

		const siblings = getSiblings(clientId);

		let currentSibling = siblings.filter(
				(v) => v.field_name === condition.field
			),
			selectOptions;

		if (
			fieldName === "select" ||
			fieldName === "radio" ||
			fieldName === "checkbox"
		) {
			if (has(currentSibling[0], "options")) {
				const generatedOptions = currentSibling[0].options.map((v) => {
					return {
						...v,
						value: v.label,
					};
				});

				generatedOptions.unshift({
					label: __( "Select Value", 'cwp-gutenberg-forms'),
					value: "",
				});

				selectOptions = generatedOptions;
			}
		}

		switch (fieldName) {
			case "radio":
				return (
					<SelectControl
						value={condition.value}
						onChange={(val) => {
							handleConditionChange(val, "value");
						}}
						options={selectOptions}
					/>
				);

			case "checkbox":
				return (
					<SelectControl
						multiple
						value={condition.value}
						onChange={(val) => {
							handleConditionChange(val, "value");
						}}
						options={selectOptions}
					/>
				);

			case "select":
				return (
					<SelectControl
						value={condition.value}
						onChange={(val) => {
							handleConditionChange(val, "value");
						}}
						options={selectOptions}
					/>
				);

			default: {
				return (
					<TextControl
						value={condition.value}
						placeholder={__("value", 'cwp-gutenberg-forms')}
						onChange={(val) => handleConditionChange(val, "value")}
					/>
				);
			}
		}
	};

	return (
		<div className="cwp-form-condition-component">
			<div className="cwp-option">
				<PanelRow>
					<h3>Use Condition</h3>
					<FormToggle
						checked={props.useCondition}
						onChange={() => {
							if (props.useCondition === false) {
								props.set({ isRequired: false });
							}
							props.set({
								enableCondition: !props.useCondition,
							});
						}}
					/>
				</PanelRow>
			</div>

			{props.useCondition && (
				<Fragment>
					<h3>Show if</h3>
					<SelectControl
						value={condition.field}
						options={getOptions()}
						onChange={(field) => {
							handleConditionChange(field, "field");
						}}
					/>
					<SelectControl
						onChange={(operator) => {
							handleConditionChange(operator, "condition");
						}}
						value={condition.condition}
						options={operators}
					/>
					{getValueType()}
				</Fragment>
			)}
		</div>
	);
}
Example #28
Source File: edit.js    From gutenberg-forms with GNU General Public License v2.0 4 votes vote down vote up
function edit(props) {
	let {
		options,
		isRequired,
		label,
		id,
		field_name,
		requiredLabel,
		messages,
		messages: { empty },
		condition,
		enableCondition,
		fieldStyle,
		bulkAdd,
		adminId,
		hint,
		showHint,
	} = props.attributes;

	const [checkboxes, setCheckboxes] = useState([]);
	const [focus, setFocus] = useState({
		f: false,
		index: null,
	});

	let checkboxContainer = useRef();

	const getRootData = () => {
		if (field_name === "" || detect_similar_forms(props.clientId)) {
			const newFieldName = getFieldName("checkbox", props.clientId);

			props.setAttributes({
				field_name: newFieldName,
				adminId: {
					value: extract_admin_id(newFieldName, "checkbox"),
					default: extract_admin_id(newFieldName, "checkbox"),
				},
			});

			props.setAttributes({
				id:
					props.clientId +
					"__" +
					getEncodedData(
						"checkbox",
						props.clientId,
						isRequired,
						get_admin_id(adminId)
					) +
					"[]",
			});
		} else if (field_name !== "") {
			props.setAttributes({
				id:
					extract_id(field_name) +
					"__" +
					getEncodedData(
						"checkbox",
						extract_id(field_name),
						isRequired,
						get_admin_id(adminId)
					) +
					"[]",
			});
		}
	};

	useEffect(() => {
		let { options } = props.attributes;

		setCheckboxes(options);
		getRootData();
	}, []);

	useEffect(() => getRootData(), [props]);

	const setMessages = (type, m) => {
		let newMessages = clone(messages);

		set(newMessages, type, m);

		props.setAttributes({ messages: newMessages });
	};

	useEffect(() => {
		if (bulkAdd) return;

		let boxes = checkboxContainer.current.querySelectorAll(
			'.cwp-checkbox-option input[type="text"]'
		);

		if (focus.f) {
			if (focus.index === null) {
				boxes[boxes.length - 1].focus();
			} else {
				boxes[focus.index].focus();
			}

			setFocus({ f: false, index: null });
		}
	}, [checkboxes, focus]); //subscribing to any further changes...

	const handleRequired = () => {
		const { isRequired } = props.attributes;

		props.setAttributes({ isRequired: !isRequired });
	};

	const addCheckbox = () => {
		let newOption = {
			label: "Option " + (checkboxes.length + 1),
			checked: false,
		};

		let new_options = clone(checkboxes);

		new_options.push(newOption);

		props.setAttributes({ options: new_options });
		setCheckboxes(new_options);
	};

	const handleDelete = (index) => {
		let new_options = clone(options);

		let deleted_options = pullAt(new_options, [index]); //dosen't matter :-D

		props.setAttributes({ options: new_options });
		setCheckboxes(new_options);
	};

	const handleLabel = (label) => {
		props.setAttributes({ label });
	};

	const handleChange = (e, index) => {
		let new_options = clone(options);

		new_options[index] = {
			...new_options[index],
			label: e.target.value,
		};

		setCheckboxes(new_options);
		props.setAttributes({ options: new_options });
	};

	const handleCheck = (v, index) => {
		let new_options = clone(options);

		new_options[index].checked = v;
		setCheckboxes(new_options);
		props.setAttributes({ options: new_options });
	};

	const handleImage = (img, index, action) => {
		let new_options = clone(options);

		if (action === "add") {
			new_options[index] = {
				...new_options[index],
				image: img,
			};
		}

		if (action === "remove") {
			const checkboxToRemove = new_options[index];
			new_options[index] = {
				label: checkboxToRemove.label,
			};
		}

		setCheckboxes(new_options);
		props.setAttributes({ options: new_options });
	};

	let handleDuplicate = (index) => {
		let new_options = clone(options);

		new_options.splice(index, 0, new_options[index]);

		setCheckboxes(new_options);
		props.setAttributes({ options: new_options });
	};

	let handleEnter = (index) => {
		let new_options = clone(options);

		new_options.splice(index + 1, 0, { label: "" });

		setCheckboxes(new_options);
		props.setAttributes({ options: new_options });
		setFocus({ f: true, index: index + 1 });
	};

	let handleBackspace = (index) => {
		if (checkboxes[index].label === "") {
			handleDelete(index);

			if (checkboxes[index - 1]) {
				setFocus({ f: true, index: index - 1 });
			}
		}
	};

	let clearAll = () => {
		const reset = [
			{
				label: "Option 1",
			},
		];

		setCheckboxes(reset);
		props.setAttributes({
			options: reset,
		});
	};

	const handleAdminId = (id) => {
		props.setAttributes({
			adminId: {
				...adminId,
				value: id.replace(/\s|-/g, "_"),
			},
		});
	};

	return [
		<InspectorControls>
			<PanelBody
				title={__("Field Settings", "cwp-gutenberg-forms")}
				initialOpen={true}
			>
				<div className="cwp-option">
					<TextControl
						placeholder={adminId.default}
						label={__("Field ID", "cwp-gutenberg-forms")}
						value={adminId.value}
						onChange={handleAdminId}
					/>
				</div>

				{!enableCondition ? (
					<PanelRow>
						<h3 className="cwp-heading">
							{__("Required", "cwp-gutenberg-forms")}
						</h3>
						<FormToggle
							label="Required"
							checked={isRequired}
							onChange={handleRequired}
						/>
					</PanelRow>
				) : (
					<div className="cwp-option">
						<p>
							<Icon icon="info" />{" "}
							{__(
								"You cannot set a conditional field required!",
								"cwp-gutenberg-forms"
							)}
						</p>
					</div>
				)}
				{isRequired && (
					<div className="cwp-option">
						<h3 className="cwp-heading">
							{__("Required Text", "cwp-gutenberg-forms")}
						</h3>
						<TextControl
							onChange={(label) =>
								props.setAttributes({ requiredLabel: label })
							}
							value={requiredLabel}
						/>
					</div>
				)}
				<div className="cwp-option">
					<SelectControl
						label={__("Layout", "cwp-gutenberg-forms")}
						value={fieldStyle}
						options={[
							{ label: __("Block", "cwp-gutenberg-forms"), value: "block" },
							{ label: __("Inline", "cwp-gutenberg-forms"), value: "inline" },
						]}
						onChange={(s) => {
							props.setAttributes({ fieldStyle: s });
						}}
					/>
				</div>
			</PanelBody>
			{isRequired && (
				<PanelBody title="Messages">
					<div className="cwp-option">
						<h3 className="cwp-heading">
							{__("Required Error", "cwp-gutenberg-forms")}
						</h3>
						<TextControl
							onChange={(label) => setMessages("empty", label)}
							value={messages.empty}
						/>
					</div>
				</PanelBody>
			)}
			<PanelBody title={__("Condition", "cwp-gutenberg-forms")}>
				<ConditionalLogic
					condition={condition}
					set={props.setAttributes}
					clientId={props.clientId}
					useCondition={props.attributes.enableCondition}
				/>
			</PanelBody>
			<PanelBody title={__("Show Hint", "cwp-gutenberg-forms")}>
				<div className="cwp-option">
					<FormToggle
						label="Show Hint"
						checked={showHint}
						onChange={() => props.setAttributes({ showHint: !showHint })}
					/>
					{showHint && (
						<Fragment>
							<TextControl
								label={__("Hint Text", "cwp-gutenberg-forms")}
								onChange={(hint) => props.setAttributes({ hint })}
								value={hint}
							/>
						</Fragment>
					)}
				</div>
			</PanelBody>
		</InspectorControls>,
		null,
		<div
			className={`cwp-checkbox cwp-field ${props.className} is-style-${fieldStyle}`}
		>
			{bulkAdd ? (
				<Bulk_Add onChange={(c) => setCheckboxes(c)} data={props} />
			) : (
				<Fragment>
					{!!props.isSelected && !enableCondition && (
						<div className="cwp-required">
							<h3>{__("Required", "cwp-gutenberg-forms")}</h3>
							<FormToggle checked={isRequired} onChange={handleRequired} />
						</div>
					)}

					<div
						ref={checkboxContainer}
						className={`cwp-checkbox-set-backend cwp-checkbox-set ${
							!props.isSelected ? "cwp-checkbox-set-preview" : ""
						}`}
					>
						<div className="cwp-label-wrap">
							<RichText
								placeholder={__("Add a label", "cwp-gutenberg-forms")}
								tag="label"
								value={label}
								onChange={handleLabel}
							/>

							{!props.isSelected && isRequired && !enableCondition && (
								<div className="cwp-required cwp-noticed">
									<h3>{requiredLabel}</h3>
								</div>
							)}
						</div>
						{checkboxes.map((checkbox, index) => {
							const hasImage = has(checkbox, "image"),
								image = hasImage ? checkbox.image.url : "";

							return (
								<Fragment>
									<div className="cwp-checkbox-option">
										<input
											id={id.concat(index.toString())}
											checked={checkbox.checked}
											type="checkbox"
											onClick={() => handleCheck(!checkbox.checked, index)}
										/>
										{!!props.isSelected && (
											<label
												style={{ width: "auto" }}
												for={id.concat(index.toString())}
												onClick={() => handleCheck(!checkbox.checked, index)}
											></label>
										)}
										{!!props.isSelected ? (
											<input
												onChange={(e) => handleChange(e, index)}
												onKeyDown={(e) => {
													e.key === "Enter" && handleEnter(index);
													e.key === "Backspace" && handleBackspace(index);
												}}
												type="text"
												value={checkbox.label}
											/>
										) : (
											<label>
												{checkbox.label}{" "}
												{hasImage && (
													<ImagePreview
														onEdit={(img) => handleImage(img, index, "add")}
														onRemove={() => handleImage(null, index, "remove")}
														isSelected={props.isSelected}
														image={checkbox.image}
													/>
												)}
											</label>
										)}
										{!!props.isSelected && (
											<Fragment>
												<ImageUpload
													icon="format-image"
													value={image}
													onSelect={(img) => handleImage(img, index, "add")}
												/>
												<Button
													isDefault
													onClick={() => handleDuplicate(index)}
												>
													<Icon icon="admin-page" />
												</Button>
												<Button isDefault onClick={() => handleDelete(index)}>
													<Icon icon="no-alt" />
												</Button>
											</Fragment>
										)}
									</div>
									{hasImage && props.isSelected && (
										<ImagePreview
											onEdit={(img) => handleImage(img, index, "add")}
											onRemove={() => handleImage(null, index, "remove")}
											isSelected={props.isSelected}
											image={checkbox.image}
										/>
									)}
								</Fragment>
							);
						})}
						{!!props.isSelected && (
							<div className="cwp-checkbox-controls">
								<div>
									<Button isDefault onClick={addCheckbox}>
										{__("Add Option", "cwp-gutenberg-forms")}
									</Button>
									<Button
										isDefault
										onClick={() => props.setAttributes({ bulkAdd: true })}
									>
										{__("Bulk Add", "cwp-gutenberg-forms")}
									</Button>
								</div>
								<div>
									<Button onClick={clearAll}>
										{__("Clear All", "cwp-gutenberg-forms")}
									</Button>
								</div>
							</div>
						)}
					</div>
				</Fragment>
			)}
			{showHint && <p className="cwp-hint">{hint}</p>}
		</div>,
	];
}
Example #29
Source File: edit.js    From gutenberg-forms with GNU General Public License v2.0 4 votes vote down vote up
function edit(props) {
	const handleChange = (e) => {
		let placeholder = e.target.value;

		props.setAttributes({ placeholder });
	};

	const handleRequired = () => {
		const { isRequired } = props.attributes;

		props.setAttributes({ isRequired: !isRequired });
	};

	const handleLabel = (label) => {
		props.setAttributes({ label });
	};
	const inputField = React.useRef();

	const {
		placeholder,
		isRequired,
		label,
		id,
		field_name,
		requiredLabel,
		type,
		messages: { empty },
		messages,
		format,
		condition,
		enableCondition,
		adminId,
	} = props.attributes;

	const getRootData = () => {
		if (field_name === "") {
			const newFieldName = getFieldName("datePicker", props.clientId);

			props.setAttributes({
				field_name: newFieldName,
				adminId: {
					value: extract_admin_id(newFieldName, "datePicker"),
					default: extract_admin_id(newFieldName, "datePicker"),
				},
			});
			props.setAttributes({
				id:
					props.clientId +
					"__" +
					getEncodedData(
						"datePicker",
						props.clientId,
						isRequired,
						get_admin_id(adminId)
					),
			});
		} else if (field_name !== "") {
			props.setAttributes({
				id:
					extract_id(field_name) +
					"__" +
					getEncodedData(
						"datePicker",
						extract_id(field_name),
						isRequired,
						get_admin_id(adminId)
					),
			});
		}
	};

	useEffect(() => {
		getRootData();
	}, []);

	useEffect(() => getRootData(), [props]);

	const getTypeActive = (t) => {
		if (type === t) {
			return {
				isDefault: true,
			};
		}

		return {
			isPrimary: true,
		};
	};

	let getFieldType = () => {
		switch (type) {
			case "both":
				return "datetime-local";
			case "time":
				return "time";
			case "date":
				return "date";
		}
	};

	const setMessages = (type, m) => {
		let newMessages = clone(messages);

		set(newMessages, type, m);

		props.setAttributes({ messages: newMessages });
	};

	const handleAdminId = (id) => {
		props.setAttributes({
			adminId: {
				...adminId,
				value: id.replace(/\s|-/g, "_"),
			},
		});
	};

	return [
		!!props.isSelected && (
			<InspectorControls>
				<PanelBody title={__("Field Settings", "cwp-gutenberg-forms")} initialOpen={true}>
					<div className="cwp-option">
						<TextControl
							placeholder={adminId.default}
							label={__("Field ID", "cwp-gutenberg-forms")}
							value={adminId.value}
							onChange={handleAdminId}
						/>
					</div>

					{!enableCondition ? (
						<PanelRow>
							<h3 className="cwp-heading">{__("Required", "cwp-gutenberg-forms")}</h3>
							<FormToggle
								label={__("Required", "cwp-gutenberg-forms")}
								checked={isRequired}
								onChange={handleRequired}
							/>
						</PanelRow>
					) : (
						<div className="cwp-option">
							<p>
								<Icon icon="info" />{" "}
								{__(
									"You cannot set a conditional field required!",
									"cwp-gutenberg-forms"
								)}
							</p>
						</div>
					)}
					{isRequired && (
						<div className="cwp-option">
							<h3 className="cwp-heading">
								{__("Required Text", "cwp-gutenberg-forms")}
							</h3>
							<TextControl
								onChange={(label) =>
									props.setAttributes({ requiredLabel: label })
								}
								value={requiredLabel}
							/>
						</div>
					)}
					<div className="cwp-option">
						<SelectControl
							label={__("Format", "cwp-gutenberg-forms")}
							value={format}
							options={[
								{
									label: __("Day Month Year", "cwp-gutenberg-forms"),
									value: "DD/MM/YYYY",
								},
								{
									label: __("Month Day Year", "cwp-gutenberg-forms"),
									value: "MM/DD/YYYY",
								},
								{
									label: __("Year Month Day", "cwp-gutenberg-forms"),
									value: "YYYY/MM/DD",
								},
							]}
							onChange={(format) => {
								props.setAttributes({ format });
							}}
						/>
					</div>
				</PanelBody>
				<PanelBody title="Condition">
					<ConditionalLogic
						condition={condition}
						set={props.setAttributes}
						clientId={props.clientId}
						useCondition={props.attributes.enableCondition}
					/>
				</PanelBody>
				{isRequired && (
					<PanelBody title="Messages">
						<div className="cwp-option">
							<h3 className="cwp-heading">
								{__("Required Error", "cwp-gutenberg-forms")}
							</h3>
							<TextControl
								onChange={(label) => setMessages("empty", label)}
								value={empty}
							/>
						</div>
					</PanelBody>
				)}
			</InspectorControls>
		),
		!!props.isSelected && <BlockControls></BlockControls>,
		<div className={`cwp-field cwp-datepicker ${props.className}`}>
			{!!props.isSelected && !enableCondition && (
				<div className="cwp-required">
					<h3>{__("Required", "cwp-gutenberg-forms")}</h3>
					<FormToggle checked={isRequired} onChange={handleRequired} />
				</div>
			)}

			<div className="cwp-field-set">
				<div className="cwp-label-wrap">
					<RichText
						placeholder={__("Add a label", "cwp-gutenberg-forms")}
						tag="label"
						value={label}
						onChange={handleLabel}
					/>
					{!props.isSelected && isRequired && !enableCondition && (
						<div className="cwp-required cwp-noticed">
							<h3>{requiredLabel}</h3>
						</div>
					)}
				</div>
				{format === "DD/MM/YYYY" && (
					<DatePicker
						format={format}
						value={placeholder}
						onChange={handleChange}
						setAttributes={props.setAttributes}
					/>
				)}
				{format === "MM/DD/YYYY" && (
					<DatePicker
						format={format}
						value={placeholder}
						onChange={handleChange}
						setAttributes={props.setAttributes}
					/>
				)}
				{format === "YYYY/MM/DD" && (
					<DatePicker
						setAttributes={props.setAttributes}
						format={format}
						value={placeholder}
						onChange={handleChange}
					/>
				)}
			</div>
		</div>,
	];
}