Inline Editable Related Records

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • abhilash.kumar.niit
    Member
    • Sep 2024
    • 38

    Inline Editable Related Records

    Hi i have a requirement of inline edit of related records after hours of working i have find out the way and it is working fine. But the problem i am facing is it is working only for the 1st time and as soon as i save one record it stops working it might be a silly mistake but unfortunately i am unable to fix this can someone help??

    define(['views/fields/enum'], function (Dep) {
    return Dep.extend({
    setup: function () {
    Dep.prototype.setup.call(this);
    this.elementId = 'inline-edit-' + this.model.entityType + '-' + this.name + '-' + this.model.id;
    this.listenTo(this.model, 'change:' + this.name, function () {
    if (this.mode === 'list') {
    this.reRender();
    }
    }, this);

    this.handleSelectClick = this.handleSelectClick.bind(this);
    this.handleSelectChange = this.handleSelectChange.bind(this);
    this.handleSelectBlur = this.handleSelectBlur.bind(this);
    },

    afterRender: function () {
    Dep.prototype.afterRender.call(this);
    if (this.mode === 'list' && this.$el) {
    this.$el.attr('id', this.elementId);
    this.$el.off('click').on('click', function (e) {
    e.preventDefault();
    e.stopPropagation();
    this.inlineEdit();
    }.bind(this));
    }
    },

    inlineEdit: function () {
    if (!this.$el) {
    console.error('inlineEdit: $el is not defined');
    return;
    }
    if (this.mode === 'edit') {
    console.log('Already in edit mode, skipping');
    return;
    }
    console.log('Switching to edit mode, clearing previous state');
    this.$el.removeClass('inline-editing').empty(); // Clear DOM contents
    this.mode = 'edit';
    this.clearView('edit');
    this.createEditView();
    },

    createEditView: function () {
    var viewName = this.getMetadata().get(['clientDefs', this.model.entityType, 'fields', this.name, 'view']) || 'views/fields/enum';
    console.log('Creating fresh edit view for:', this.elementId, 'with view:', viewName);

    this.createView('edit', viewName, {
    model: this.model,
    name: this.name,
    mode: 'edit',
    el: '#' + this.elementId,
    inlineEdit: true
    }, function (view) {
    console.log('Rendering edit view');
    view.render();
    view.once('after:render', function () {
    console.log('Edit view HTML after render:', view.$el.html());
    var $select = view.$el.find('select');
    if ($select.length) {
    console.log('Select element found, count:', $select.length, 'value:', $select.val());
    $select.css({
    'position': 'absolute',
    'z-index': 1001,
    'min-width': this.$el.width() + 'px'
    });
    $select.focus();

    $select.off('click').on('click', this.handleSelectClick);
    $select.off('change').on('change', this.handleSelectChange.bind(this, view));
    $select.off('blur').on('blur', this.handleSelectBlur);

    // Log bound events (if jQuery is used)
    console.log('Bound events after binding:', $select.data('events') || 'No jQuery events data available');
    } else {
    console.error('No select element found after rendering');
    this.mode = 'list';
    this.clearView('edit');
    this.$el.removeClass('inline-editing');
    this.reRender();
    }
    }.bind(this));
    }.bind(this));
    },

    handleSelectClick: function (e) {
    console.log('Select clicked, stopping propagation');
    e.stopPropagation();
    },

    handleSelectChange: function (view, e) {
    e.preventDefault();
    var value = e.target.value;
    console.log('Change event triggered, new value:', value);
    if (value) {
    this.saveInlineChange(view, value);
    } else {
    console.log('No value selected, skipping save');
    }
    },

    handleSelectBlur: function () {
    console.log('Select blurred, switching to list mode');
    this.mode = 'list';
    this.clearView('edit');
    this.$el.removeClass('inline-editing').empty(); // Clear DOM contents
    this.reRender();
    },

    saveInlineChange: function (view, value) {
    console.log('Attempting to save value:', view.name, value);
    view.model.set(view.name, value);
    this.showLoader();

    console.log('Model state before save:', view.model.attributes);
    view.model.save({ [view.name]: value }, { patch: true })
    .then(function () {
    console.log('Save successful, new value:', view.model.get(view.name));
    this.hideLoader();
    this.mode = 'list';
    this.clearView('edit');
    this.$el.removeClass('inline-editing').empty(); // Clear DOM contents
    this.reRender();
    }.bind(this))
    .catch(function (xhr) {
    console.error('Save failed:', xhr.responseText || xhr);
    this.hideLoader();
    view.model.set(view.name, view.model.previous(view.name));
    this.mode = 'list';
    this.clearView('edit');
    this.$el.removeClass('inline-editing').empty(); // Clear DOM contents
    this.reRender();
    }.bind(this));
    },

    showLoader: function () {
    if (!this.$el) return;
    this.$el.find('.inline-loader').remove();
    this.$el.append('<span class="inline-loader"></span>');
    console.log('Loader shown');
    },

    hideLoader: function () {
    if (!this.$el) return;
    this.$el.find('.inline-loader').remove();
    console.log('Loader hidden');
    },

    fetch: function () {
    var data = {};
    var $select = this.$el.find('select');
    data[this.name] = $select.length ? $select.val() : this.model.get(this.name);
    return data;
    }
    });
    });
Working...