utils.ts 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. // Utility functions for Dyynaform consumers
  2. import { FormControl, FormGroup, ValidationErrors } from '@angular/forms';
  3. import { ValueTransformer } from './interfaces';
  4. import { Observable, of, merge } from 'rxjs';
  5. import { filter, map, mapTo, switchMap, } from 'rxjs/internal/operators';
  6. // Dropdown Modified Input - Starts With / Contains / Matches
  7. const standardModifiers = ['Starts with', 'Contains', 'Matches'];
  8. const standardTransformer: ValueTransformer = {
  9. inputFn: val => {
  10. let modifier = 'Starts with';
  11. if (/^%.*?%$/.test(val)) {
  12. modifier = 'Contains';
  13. } else if (/^[^%].*?[^%]$/.test(val)) {
  14. modifier = 'Matches';
  15. } else if (/^%.*/.test(val)) {
  16. modifier = 'Starts with';
  17. }
  18. const transformedVal = val.replace(/%/g, '').trim();
  19. return { modifier, value: transformedVal };
  20. },
  21. outputFn: (mod, val) => {
  22. let transformedValue;
  23. switch (mod) {
  24. case 'Starts with':
  25. transformedValue = `${val}%`;
  26. break;
  27. case 'Contains':
  28. transformedValue = `%${val}%`;
  29. break;
  30. case 'Matches':
  31. default:
  32. transformedValue = val;
  33. break;
  34. }
  35. return transformedValue;
  36. }
  37. };
  38. // Generate array from CSV string
  39. const toArrTag = (str: TemplateStringsArray): string[] => str[0].split(',').map(key => key.trim());
  40. // Pad array
  41. const arrayPad = (length: number) => (arr: string[]): any[] => [...arr, ...Array(length - arr.length).fill('')];
  42. // Utility function for casting an array to metadata (useful for components that render FormGroups)
  43. const arrayToMeta = array => array.map(val => ({ name: val, 'value' : val }));
  44. // Exclude 'fieldsToExclude' from obj, returning a new object
  45. // fieldsToExclude can be an array of field keys or a CSV of field keys
  46. const excludeFields = (obj: StringMap<any>, fieldsToExclude: string | string[]) => {
  47. const ex = Array.isArray(fieldsToExclude) ? fieldsToExclude : fieldsToExclude.split(',').map(key => key.trim());
  48. return Object.entries(obj).reduce(
  49. (res, [key, val]) => ex.includes(key) ? res : { ...res, [key]: val },
  50. {}
  51. );
  52. };
  53. // Higher order function that takes a bound test function and failure flag
  54. // and returns an AsyncValidator-compatible function
  55. // that in turn returns an Observable of ValidationErrors
  56. const makeAsyncTest = (boundFnName: string, failureFlag: string): (fc: FormControl | FormGroup) => Observable<ValidationErrors> => {
  57. let initialValue;
  58. return function(fc: FormControl | FormGroup | 'RESET'): Observable<ValidationErrors> {
  59. if (fc === 'RESET') {
  60. // Special value that resets the initial value
  61. initialValue = '';
  62. return of({});
  63. }
  64. if (fc.pristine) {
  65. initialValue = fc.value;
  66. }
  67. return merge(
  68. of(fc).pipe(
  69. filter(_fc => _fc.value !== initialValue),
  70. switchMap(_fc => this[boundFnName](_fc.value, _fc.root)),
  71. map(res => res ? {} : { [failureFlag]: true } )
  72. ),
  73. of(fc).pipe(
  74. filter(_fc => _fc.value === initialValue),
  75. mapTo({})
  76. )
  77. );
  78. };
  79. };
  80. export { standardModifiers, standardTransformer, toArrTag, arrayPad, arrayToMeta, excludeFields, makeAsyncTest };