Skip to content

Add `parseRailsFormFields` util

Peter Hegman requested to merge peterhegman/parse-form-fields-util into master

What does this MR do?

Related to !53306 (closed)

Adds a JavaScript util for parsing Rails fields when integrating Vue components into a Rails form. This helper loops through all of the inputs and grabs the name, id, value, and placeholder attributes. These attributes can then be used in a Vue component.

Use case for this change

You have a HAML form that needs some extra functionality added to it. This could be a datepicker, a dropdown that loads projects or groups, etc. Instead of using older jQuery plugins (such as select2 or pikaday) it is better to use Vue. The tricky thing is Rails uses form helpers to generate the form inputs with a name attribute that matches the backend and currently we don't have a good way to pass that name attribute to the frontend.

Example usage

form.html.haml

= form_for user do |form|
  .js-user-form
    = form.text_field :name, class: 'form-control gl-form-input', data: { js_name: 'name' }
    = form.text_field :email, class: 'form-control gl-form-input', data: { js_name: 'email' }

index.js

import Vue from 'vue';
import { parseRailsFormFields } from '~/lib/utils/forms';
import UserForm from './components/user_form.vue';

export const initUserForm = () => {
  const el = document.querySelector('.js-user-form');

  if (!el) {
    return null;
  }

  const fields = parseRailsFormFields(el);

  return new Vue({
    el,
    render(h) {
      return h(UserForm, {
        props: {
          fields,
        },
      });
    },
  });
};

user_form.vue

<script>
import { GlFormGroup, GlFormInput, GlButton } from '@gitlab/ui';

export default {
  name: 'UserForm',
  components: { GlFormGroup, GlFormInput, GlButton },
  props: {
    fields: {
      type: Object,
      required: true,
    },
  },
};
</script>

<template>
  <div>
    <gl-form-group :label-for="fields.name.id" :label="__('Name')">
      <gl-form-input
        :id="fields.name.id"
        :name="fields.name.name"
        :value="fields.name.value"
        size="lg"
      />
    </gl-form-group>

    <gl-form-group :label-for="fields.email.id" :label="__('Email')">
      <gl-form-input
        :id="fields.email.id"
        :name="fields.email.name"
        :value="fields.email.value"
        type="email"
        size="lg"
      />
    </gl-form-group>

    <gl-button type="submit" category="primary" variant="confirm">{{ __('Update') }}</gl-button>
  </div>
</template>

Screenshots (strongly suggested)

Does this MR meet the acceptance criteria?

Conformity

Availability and Testing

Security

If this MR contains changes to processing or storing of credentials or tokens, authorization and authentication methods and other items described in the security review guidelines:

  • [-] Label as security and @ mention @gitlab-com/gl-security/appsec
  • [-] The MR includes necessary changes to maintain consistency between UI, API, email, or other methods
  • [-] Security reports checked/validated by a reviewer from the AppSec team
Edited by Peter Hegman

Merge request reports

Loading