vitalets / x-editable

In-place editing with Twitter Bootstrap, jQuery UI or pure jQuery
http://vitalets.github.io/x-editable
MIT License
6.51k stars 1.72k forks source link

Disable checkboxes in checklist #994

Open zwiebelspaetzle opened 7 years ago

zwiebelspaetzle commented 7 years ago

I need to be able to disable a checkbox within a checklist. As it appears that functionality doesn't exist, I've forked the repo and worked out a solution, but it's incredibly hacky. I'd appreciate suggestions on how to better solve this.

Dataset:

source: [
  {value: 'a', text: 'disabled', disabled: true},
  {value: 'b', text: 'enabled', disabled: false},
  {value: 'c', text: 'disabled', disabled: true},
  {value: 'd', text: 'enabled'}
]

First try:

// src/inputs/checklist.js

var $input = $('<input>', {
  type: 'checkbox',
  value: this.sourceData[i].value,
  disabled: this.sourceData[i].disabled ? true : false
});

When this renders, the disabled property is dropped from the DOM. Strangely, it does work if the type is radio or text. Also, other properties will persist, such as the misspelled disabld.

Second try:

Since the disabled property is being dropped, change it to data-disbled, and handle afterwards:

for(var i=0; i<this.sourceData.length; i++) {
    var $input = $('<input>', {
      type: 'checkbox',
      value: this.sourceData[i].value,
      "data-disabled": this.sourceData[i].disabled ? true : false
    });
    $label = $('<label>').append($input);
    var $option = $('<span>');
    $option[this.options.escape ? 'text' : 'html'](' '+this.sourceData[i].text);
    $label.append($option);

    $('<div>').append($label).appendTo(this.$tpl);
}

this.$input = this.$tpl.find('input[type="checkbox"]');
this.setClass();

var disabled = this.$tpl.find('input[type="checkbox"][data-disabled=true]');
console.log(disabled);
$.each(disabled, (d) => {
    $(disabled[d]).prop('disabled', true);
});

In this case, the data-disabled property persists, and the console.log(disabled) shows that the query found them, but they are still not disabled.

Third try:

Perhaps is was some race condition:

var disabled = this.$tpl.find('input[type="checkbox"][data-disabled=true]');
$.each(disabled, (d) => {
    setTimeout(function() {
      $(disabled[d]).prop('disabled', true);
    }, 0);
});

Now it works, but how it makes me cringe. Also, the unit test does not find the disabled checkboxes in its query:

equal(p.find('input[type="checkbox"]:disabled').length, 2, 'disabled count ok');

Any suggestions on how to better solve this would be much appreciated!

lohxx commented 5 years ago

Is there any updates on this issue?