templates/js/library/json_form_saver/json_form_saver.js.twig line 1

Open in your IDE?
  1. class JsonFormSaver {
  2.     EVENTS = {
  3.         ON_CHANGE: 'onChange',
  4.         ON_SAVE: 'onSave',
  5.         ON_SAVE_ERROR: 'onSaveError',
  6.     };
  7.     options = {
  8.         jsonObject: null,
  9.         /** @type {JsonObjectToComponentsDataBinder} */
  10.         componentsDataBinder: null,
  11.         symfonyFormDataBuilder: null,
  12.         url: null,
  13.         csrfToken: null,
  14.         saveOnChanges: false,
  15.     };
  16.     constructor(options = null) {
  17.         this.options = { ...this.options, ...options };
  18.         this.eventDispatcher = new EventDispatcher();
  19.     }
  20.     init() {
  21.         const componentsBinder = this.options.componentsDataBinder;
  22.         const formBuilder = this.options.symfonyFormDataBuilder;
  23.         const doSave = () => {
  24.             if (this.options.saveOnChanges) {
  25.                 this.save(() => {
  26.                     this.eventDispatcher.emit(this.EVENTS.ON_SAVE);
  27.                 });
  28.             }
  29.         };
  30.         const saveDebounced = (new Debouncer2()).debounce(() => {
  31.             doSave();
  32.         }, 3000);
  33.         const handler = (data) => {
  34.             const json = this.options.jsonObject;
  35.             Object.keys(json).forEach((key) => {
  36.                 const value = json[key];
  37.                 if (Array.isArray(value)) {
  38.                     formBuilder.setTextArrayField(key, value);
  39.                 } else if (typeof value === 'string') {
  40.                     formBuilder.setField(key, value);
  41.                 } else if (typeof value === 'number') {
  42.                     formBuilder.setField(key, String(value));
  43.                 } else if (typeof value === 'boolean') {
  44.                     if (value) {
  45.                         formBuilder.setField(key, "1");
  46.                     } else {
  47.                         formBuilder.removeField(key);
  48.                     }
  49.                 } else if (value === null || typeof value === 'undefined') {
  50.                     formBuilder.setField(key, '');
  51.                 } else if (typeof value === 'object') {
  52.                     try {
  53.                         formBuilder.setField(key, JSON.stringify(value));
  54.                     } catch (e) {
  55.                         formBuilder.setField(key, '');
  56.                     }
  57.                 } else {
  58.                     formBuilder.setField(key, String(value));
  59.                 }
  60.             });
  61.             if (this.options.csrfToken) {
  62.                 formBuilder.setField('_token', this.options.csrfToken);
  63.             }
  64.             if (data.saveDebounced) {
  65.                 saveDebounced();
  66.             } else {
  67.                 doSave();
  68.             }
  69.         };
  70.         componentsBinder.eventDispatcher.on(componentsBinder.EVENTS.ON_CHANGE, handler);
  71.     }
  72.     save(onSuccess = null) {
  73.         const formBuilder = this.options.symfonyFormDataBuilder;
  74.         const formData = formBuilder.getFormData();
  75.         const url = this.options.url;
  76.         (async () => {
  77.             try {
  78.                 const response = await fetch(url, {
  79.                     method: 'POST',
  80.                     body: formData,
  81.                     credentials: 'same-origin'
  82.                 });
  83.                 if (!response.ok) {
  84.                     const text = await response.text();
  85.                     console.error('Ошибка при сохранении данных:', response.status, text);
  86.                     this.eventDispatcher.emit(this.EVENTS.ON_SAVE_ERROR, { response: response });
  87.                 } else {
  88.                     onSuccess && onSuccess();
  89.                 }
  90.                 const contentType = response.headers.get('content-type') || '';
  91.                 if (contentType.includes('application/json')) {
  92.                     const data = await response.json();
  93.                     console.log('Response JSON:', data);
  94.                     if (data.redirect) {
  95.                         window.location = data.redirect;
  96.                     }
  97.                 }
  98.             } catch (e) {
  99.                 console.error(e);
  100.             }
  101.         })();
  102.     }
  103. }