Search code examples
javascriptalloy-ui

How can I save and restore AlloyUI FormBuilder fields?


I want to save the user selected and predefined fields of an AlloyUI FormBuilder. I have tried to use JSON.stringify(formBuilder.get('fields')), but I get the following error:

Uncaught TypeError: Converting circular structure to JSON

How can I save (and restore) the fields of an AlloyUI FormBuilder?


Solution

  • In order to save the fields of an AlloyUI FormBuilder, you can use field.getAttributesForCloning() to obtain the important field attributes. Then you can combine those attributes into an array. Finally, you can convert the array to JSON to save it with JSON.stringify():

    var fields = [];
    formBuilder.get('fields').each(function(field) {
        fields.push(field.getAttributesForCloning());
    });
    fields = JSON.stringify(fields);
    

    If you want to restore the fields, you can use JSON.parse() on the JSON:

    new Y.FormBuilder({
        /* ...your code here... */
        fields: JSON.parse(fields)
    }).render();
    

    Here's a runnable example using AlloyUI's example FormBuilder code:

    YUI().use('aui-form-builder', function(Y) {
      var formBuilder = new Y.FormBuilder({
        availableFields: [{
          iconClass: 'form-builder-field-icon-text',
          id: 'uniqueTextField',
          label: 'Text',
          readOnlyAttributes: ['name'],
          type: 'text',
          unique: true,
          width: 75
        }, {
          hiddenAttributes: ['tip'],
          iconClass: 'form-builder-field-icon-textarea',
          label: 'Textarea',
          type: 'textarea'
        }, {
          iconClass: 'form-builder-field-icon-checkbox',
          label: 'Checkbox',
          type: 'checkbox'
        }, {
          iconClass: 'form-builder-field-icon-button',
          label: 'Button',
          type: 'button'
        }, {
          iconClass: 'form-builder-field-icon-select',
          label: 'Select',
          type: 'select'
        }, {
          iconClass: 'form-builder-field-icon-radio',
          label: 'Radio Buttons',
          type: 'radio'
        }, {
          iconClass: 'form-builder-field-icon-fileupload',
          label: 'File Upload',
          type: 'fileupload'
        }, {
          iconClass: 'form-builder-field-icon-fieldset',
          label: 'Fieldset',
          type: 'fieldset'
        }],
        boundingBox: '#myFormBuilder',
        fields: [{
          label: 'City',
          options: [{
            label: 'Ney York',
            value: 'new york'
          }, {
            label: 'Chicago',
            value: 'chicago'
          }],
          predefinedValue: 'chicago',
          type: 'select'
        }, {
          label: 'Colors',
          options: [{
            label: 'Red',
            value: 'red'
          }, {
            label: 'Green',
            value: 'green'
          }, {
            label: 'Blue',
            value: 'blue'
          }],
          type: 'radio'
        }]
      }).render();
    
      Y.one('#resetFormBuilder').on('click', function(event) {
        var fields = [];
        formBuilder.get('fields').each(function(field) {
          fields.push(field.getAttributesForCloning());
        });
        fields = JSON.stringify(fields);
        formBuilder.destroy();
        event.target.set('style', 'display: none;');
        new Y.FormBuilder({
          /* ...your code here... */
          boundingBox: '#myFormBuilder',
          fields: JSON.parse(fields)
        }).render();
      });
    });
    <script src="http://cdn.alloyui.com/3.0.1/aui/aui-min.js"></script>
    <link href="http://cdn.alloyui.com/3.0.1/aui-css/css/bootstrap.min.css" rel="stylesheet"></link>
    <div class="yui3-skin-sam">
      <button id="resetFormBuilder" class="btn btn-primary">
        Reset <code>FormBuilder</code>
      </button>
      <div id="wrapper">
        <div id="myFormBuilder"></div>
      </div>
    </div>