Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

typeUserAttrs, doesn't render checkbox checked property correctly #571

Closed
joerou opened this issue Aug 4, 2017 · 15 comments · Fixed by #1026
Closed

typeUserAttrs, doesn't render checkbox checked property correctly #571

joerou opened this issue Aug 4, 2017 · 15 comments · Fixed by #1026
Labels

Comments

@joerou
Copy link

joerou commented Aug 4, 2017

Description:

Perhaps I am missing something but if I create a new custom attribute using typeUserAttr of type checkbox, when I render the form with existing data the checkbox is not checked if the value is true. This seems to work correctly for the required field.

Environment Details:

  • formBuilder Version:
  • Browser: Chrome
  • OS:

Expected Behavior

Inserting formData for custom attributed will correctly check checkboxes.

Actual Behavior

The value attribute of the custom field is set to true but the box is not checked

Steps to Reproduce

jQuery(function($) {
  var fbTemplate = document.getElementById('build-wrap');
var options = {
      disabledActionButtons: [
        'data',
        'clear'
      ],
      disableFields: [
        'button',
        'autocomplete',
        'hidden',
        'file',
        'date',
        'header',
        'number'
      ],
      disabledAttrs: [
        'access',
        'multiple',
        'toggle',
        'placeholder',
        'className',
        'inline',
        'other',
        'subtype',
        'description',
        'maxlength',
        'rows'
      ],
      typeUserAttrs: {
        'radio-group': {
          randomize: {
            label: 'Randomize',
            type: 'checkbox'
          },
          feedback: {
            label: 'Feedback',
            type: 'text',
            placeholder: 'Insert feedback for this question here'
          }
        },
        'textarea': {},
        'checkbox-group': {
          randomize: {
            label: 'Randomize',
            type:"checkbox"
          },
          feedback: {
            label: 'Feedback',
            type: 'text',
            placeholder: 'Insert feedback for this question here'
          }
        },
        'select': {
          randomize: {
            label: 'Randomize',
            type: 'checkbox'
          },
          feedback: {
            label: 'Feedback',
            type: 'text',
            placeholder: 'Insert feedback for this question here'
          }
        },
        'text': {
          content: {
            label: 'Content',
            type: 'textArea',
            placeholder: 'Insert feedback for this question here'
          },
          feedback: {
            label: 'Feedback',
            type: 'text',
            placeholder: 'Insert feedback for this question here'
          }
        },
        'paragraph': {
          name: {
            label: 'Name',
            type: 'text'
          }
        }
      },
      formData: '[{"type":"checkbox-group","label":"Checkbox Group","name":"checkbox-group-1501853553952","feedback":"","randomize":true,"values":[{"label":"Option 1","value":"option-1","selected":true}]}]',
      dataType: 'json',
      layoutTemplates: {
        label: function (label, data) {
          return $('<label class="bright"/>')
            .attr('for', data.id)
            .append(label);
        }
      }
    };

  $(fbTemplate).formBuilder(options);
});

The value of the field randomize is set to true, but the box is not checked on load

Screenshot - (optional)

screen shot 2017-08-04 at 5 23 10 pm

@jjleavitt
Copy link

I didn't even know you could add a checkbox with typeUserAttr, so thank you, will help me on my project.

if you add a 'checked' prop with any value it looks like it will default as checked ie:

'select': {
          randomize: {
            label: 'Randomize',
            type: 'checkbox',
            checked: ''  /*<-----  here*/
          },
          feedback: {
            label: 'Feedback',
            type: 'text',
            placeholder: 'Insert feedback for this question here'
          }
        }

@joerou
Copy link
Author

joerou commented Aug 4, 2017

Yep that works! Thanks!

** update **
Looks like I spoke too soon. This doesn't take into account that the checked property no matter what it is set to even if checked=false on a checkbox element still renders a checkbox field as "checked". So though adding the default property checked to the definition will render the field as checked, it will also render it always as checked, even if the value is == false. :D

@jjleavitt
Copy link

yeah... for now the workaround will be if you want it to be defaulted true, add the checked prop. If you want to be defaulted false, leave checked prop out.

In the form data, when the box is checked the randomize property will be there. If you don't have it checked, it will be removed.

Looks like missing logic in the inputUserAttrs function, to check the value prop for true or false on non type='text' inputs to set checked.

Also in the utils.trimObj function it looks like if a value is bool or string false, it gets removed which is why the prop disappears. I can understand on null or undefined, but anyone know if that's intentional?

  /**
   * Remove null or undefined values
   * @param  {Object} attrs {attrName: attrValue}
   * @return {Object}       Object trimmed of null or undefined values
   */
  utils.trimObj = function(attrs) {
    let xmlRemove = [
      null,
      undefined,
      '',
      false,    //JL: intentional?
      'false'   //JL: intentional?
    ];
    for (let attr in attrs) {
      if (utils.inArray(attrs[attr], xmlRemove)) {
        delete attrs[attr];
      } else if (Array.isArray(attrs[attr])) {
        if (!attrs[attr].length) {
          delete attrs[attr];
        }
      }
    }

    return attrs;
  };

@joerou
Copy link
Author

joerou commented Aug 7, 2017

The current use case for the project at hand is that it should default to false and when building the form builder with data from the database, (basically edit mode for a previously created form) then it should render already checked if that was what it was in the database. So I am not sure that solution will work for my use case, for now I added a function that will add the checked property to the element based on the "value" being true or false and then added this function to the onAdd hook for the limited elements that I am using that require a randomize answer property.

In the coming month, perhaps I will have a bit more time to also look into this further, but for now this will be my solution.

Thanks for all the additional information btw and the prompt responses!

@AvKhushbu
Copy link

@joerou can you please share your logic to set checkbox property using a function? I am facing the same issue

@joerou
Copy link
Author

joerou commented Oct 11, 2017

@AvKhushbu of course!

First I added the attributes to the type as below:

typeUserAttrs: {
  'radio-group': {
    randomize_values: {
      label: 'Randomize',
      type: 'checkbox'
    },
    always_correct: {
      label: 'Always correct',
      type: 'checkbox'
    },
  }
}

Then I created a function to check what the property was equal to and add the checked property accordingly

function fixCheckedProps(fld) {
    var randomizeField = $(fld).find('input.fld-randomize_values');

    // Also if the value is not set, because I wanted checked by default as well
    if ($(randomizeField).val() === 'on' || $(randomizeField).val() === ''){
      $(randomizeField).attr('checked', true);
    } else {
      $(randomizeField).attr('checked', false);
    }

    var alwaysCorrectField = $(fld).find('input.fld-always_correct');

    if ($(alwaysCorrectField).val() === 'on'){
      $(alwaysCorrectField).attr('checked', true);
    } else {
      $(alwaysCorrectField).attr('checked', false);
    }
  }

Then I added the function to the onAdd event

typeUserEvents: {
  'radio-group': {
    onadd: function (fld) {
      fixCheckedProps(fld);
    }
  },
}

Let me know if something isn't clear or if I forgot something, and I can always elaborate a bit more!

@AvKhushbu
Copy link

@joerou thanks a lot, buddy! your example is very clear and it works perfectly fine in my code. Once again thank you so much!

@alexsergeibichy
Copy link

Dear @joerou, I am gonna add color picker in typeuserattr by using the text, but I can't get info about this, so if you have a solution, I hope your help.

@joerou
Copy link
Author

joerou commented Jan 25, 2020

@alexsergeibichy I'm not exactly sure what you mean, and I haven't used this package in a while. I'm happy to try to help, but maybe you can give an example of the code you already wrote with an explanation of what you are trying to do and what is not working?

@kevinchappell
Copy link
Owner

kevinchappell commented Jan 25, 2020

@alexsergeibichy you can use the same pattern but need to add a value to the color picker config.
https://codepen.io/kevinchappell/pen/gObEKEj

kevinchappell added a commit that referenced this issue Jan 26, 2020
fix: typeUserAttr checkbox behavior, resolves #571
kevinchappell added a commit that referenced this issue Jan 26, 2020
fix: typeUserAttr checkbox behavior, resolves #571
@kevinchappell
Copy link
Owner

kevinchappell commented Jan 26, 2020

Also, I just reviewed the original issue. There was a bug in how the checked value for was interpreted. The order of precedence for how custom checkbox attributes value is resolved is now:

formData[fieldData][attributeName] > typeUserAttr[attributeName].value || typeUserAttr[attributeName].checked > false

kevinchappell pushed a commit that referenced this issue Jan 26, 2020
# [3.3.0](v3.2.6...v3.3.0) (2020-01-26)

### Bug Fixes

* **demo:** clear current id when removed from stage ([e0c0f2e](e0c0f2e))

### Features

* getCurrentFieldId ([c0148b3](c0148b3)), closes [#571](#571)
@kevinchappell
Copy link
Owner

🎉 This issue has been resolved in version 3.3.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

@sarika624
Copy link

I want to add a custom dropdown attribute and bind dropdown options with the help of database
please help me to find out solution

@sid046
Copy link

sid046 commented Nov 5, 2020

how to customize the sequence of attributes

@vividansari
Copy link

@kevinchappell I have to add a new radio button with images and need to add an option to add more options is it possible?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants