index.ts 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. import { FormBuilder, FormControl } from '@angular/forms';
  2. import { reduce } from 'lodash/fp';
  3. /*
  4. * FORM UTILITIES
  5. *
  6. * Exports
  7. * -------
  8. * buildFormGroup(metadata) - builds FormGroups from metdata, recursively if necessary
  9. * addMissingNames(metadata) - adds any missing 'name' properties to Fields and Groups using property's key, recursively
  10. *
  11. * Variable names
  12. * --------------
  13. * metaF = metadata for Field
  14. * metaG = metadata for Group (possibly nested)
  15. * metaFoG = metadata for Field Or Group
  16. *
  17. */
  18. const fb = new FormBuilder();
  19. const addProp = (obj, key, val) => { obj[key] = val; return obj; };
  20. // Helper function to distinguish group from field
  21. const isGroup = metaFoG => metaFoG.meta && !metaFoG._field;
  22. // Add names to both Fields and Groups if missing, using property's key
  23. const addNameIfMissing = (metaFoG, key) => metaFoG.name ? metaFoG : addProp(metaFoG, 'name', key);
  24. const addNameToSelfAndChildren = ( [key, metaFoG] ) => {
  25. metaFoG = addNameIfMissing(metaFoG, key);
  26. if (isGroup(metaFoG)) {
  27. metaFoG.meta = addMissingNames(metaFoG.meta); // Recursion
  28. }
  29. return [key, metaFoG];
  30. };
  31. const addMissingNames = metaG => Object.entries(metaG)
  32. .map(addNameToSelfAndChildren)
  33. .reduce((res, [key, val]) => { res[key] = val; return res; }, {});
  34. // Build Form Control
  35. // TODO: Flesh out function to build validators
  36. const buildControlState = metaF => ({ value: metaF.value || '', disabled: metaF.isDisabled });
  37. const buildValidators = metaF => ({
  38. validators: null,
  39. asyncValidators: null,
  40. updateOn: 'blur'
  41. });
  42. const buildFormControl = metaF => new FormControl(buildControlState(metaF) /*, buildValidators(metaF) */);
  43. // Build Form Group Member
  44. const buildFormGroupMember = metaFoG => isGroup(metaFoG) ? buildFormGroup(metaFoG.meta) : buildFormControl(metaFoG);
  45. // Build Form Group
  46. const buildFormGroupReducerIteree = (res, metaFoG) => Object.assign(res, { [metaFoG.name]: buildFormGroupMember(metaFoG) });
  47. const buildFormGroup = metaG => fb.group(reduce(buildFormGroupReducerIteree, {}, metaG));
  48. // ---------------------------------------------------------------------------------------------------------------------
  49. // Exports
  50. export { addMissingNames, buildFormGroup };