enhance_search

This commit is contained in:
Mohamed Eltayar 2025-09-02 16:26:23 +03:00 committed by GitHub
parent 74d34ae915
commit 23459a1364
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 230 additions and 135 deletions

View File

@ -162,7 +162,6 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) {
}).then(function() {
return self.update({}, {reload: false});
}).then(function() {
// ✅ الإضافة البسيطة الوحيدة: إعادة Focus بعد الـ reload
setTimeout(function() {
if (self.renderer && self.renderer.$) {
var $input = self.renderer.$('.oe_search_input');
@ -170,7 +169,7 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) {
$input.focus();
}
}
}, 100); // تأخير بسيط للتأكد من اكتمال الـ rendering
}, 100);
}).finally(function() {
if (self.renderer) {
self.renderer.$('.oe_search_loading').hide();
@ -348,38 +347,47 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) {
});
ListRenderer.include({
events: _.extend({}, ListRenderer.prototype.events, {
'keyup .oe_search_input': '_onCustomSearchKeyUp',
'input .oe_search_input': '_onCustomSearchInput',
'click .oe_clear_search': '_onCustomClearSearch',
'keydown .oe_search_input': '_onCustomSearchKeyDown'
}),
// **إزالة events من class definition لتجنب التعارضات**
// سيتم ربط events programmatically عند الحاجة فقط
init: function() {
this._super.apply(this, arguments);
this._searchTimer = null;
this._customSearchReady = false;
this._lastInputValue = '';
this._customEventsbound = false; // تجنب double binding
},
_renderView: function () {
var self = this;
return this._super.apply(this, arguments).then(function (result) {
if (self._shouldAddSearchBox()) {
self._addCustomSearchBox();
self._customSearchReady = true;
self._restoreSearchState();
}
// تأخير قليل للتأكد من DOM readiness
setTimeout(function() {
try {
if (self._shouldAddSearchBox()) {
self._addCustomSearchBox();
self._bindCustomEvents();
self._customSearchReady = true;
self._restoreSearchState();
}
} catch (error) {
console.error('FIMS Search: Error in _renderView:', error);
}
}, 50); // تأخير أكبر قليلاً للاستقرار
return result;
});
},
_restoreSearchState: function() {
var controller = this.getParent();
if (controller && controller._customSearchState) {
try {
var controller = this.getParent();
if (!controller || !controller._customSearchState) {
return;
}
var state = controller._customSearchState;
if (state.value) {
if (state.value && this.$('.oe_search_input').length) {
var $input = this.$('.oe_search_input');
$input.val(state.value);
var length = state.value.length;
@ -396,151 +404,238 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) {
.removeClass('text-danger')
.show();
}
} catch (error) {
console.error('FIMS Search: Error in _restoreSearchState:', error);
}
},
_shouldAddSearchBox: function() {
// التحقق من المتطلبات الأساسية
if (!this.arch ||
this.arch.tag !== 'tree' ||
!this.$el ||
!this.$el.hasClass('o_list_view') ||
this.$el.find('.oe_search_container').length > 0) {
try {
// **فحوصات الأمان الأساسية**
if (!this.arch ||
this.arch.tag !== 'tree' ||
!this.$el ||
!this.$el.length ||
!this.$el.hasClass('o_list_view') ||
this.$el.find('.oe_search_container').length > 0) {
return false;
}
// **الحل النهائي المؤكد: فحص hasSelectors**
// embedded tree views: hasSelectors = false أو undefined
// standalone tree views: hasSelectors = true
if (this.hasSelectors === false) {
console.log('FIMS Search: Hidden - embedded tree view (hasSelectors = false)');
return false;
}
// **فحوصات إضافية للأمان:**
// فحص DOM structure كـ backup
if (this.$el.closest('.o_form_view').length > 0) {
console.log('FIMS Search: Hidden - inside form view');
return false;
}
// فحص field widget
if (this.$el.closest('.o_field_widget').length > 0) {
console.log('FIMS Search: Hidden - inside field widget');
return false;
}
console.log('FIMS Search: Shown - standalone tree view (hasSelectors:', this.hasSelectors, ')');
return true;
} catch (error) {
console.error('FIMS Search: Error in _shouldAddSearchBox:', error);
return false;
}
// **الحل النهائي البسيط والمؤكد 100%:**
// فحص 1: إذا كان داخل form view، فهو embedded
if (this.$el.closest('.o_form_view').length > 0) {
return false;
}
// فحص 2: إذا كان داخل field widget، فهو embedded
if (this.$el.closest('.o_field_widget').length > 0) {
return false;
}
// فحص 3: إذا كان داخل notebook page، فهو embedded
if (this.$el.closest('.tab-pane').length > 0) {
return false;
}
// إذا وصل هنا، فهو standalone tree view
return true;
},
_addCustomSearchBox: function() {
var controller = this.getParent();
var savedValue = '';
var savedCount = 0;
var isFiltered = false;
if (controller && controller._customSearchState) {
savedValue = controller._customSearchState.value || '';
savedCount = controller._customSearchState.filteredCount || 0;
isFiltered = controller._customSearchState.isFiltered || false;
}
var countText = isFiltered ?
_t('عدد السجلات: ') + savedCount : '';
var html =
'<div class="oe_search_container d-flex align-items-center">' +
'<input type="text" class="oe_search_input form-control flex-grow-1" ' +
'placeholder="' + _.escape(_t('البحث في جميع الأعمدة المرئية...')) + '" ' +
'value="' + _.escape(savedValue) + '" ' +
'autocomplete="off">' +
'<button class="btn btn-secondary oe_clear_search ml-2" style="display: ' +
(savedValue ? 'inline-block' : 'none') + ';">' +
'<i class="fa fa-times mr-1"></i>' + _t('مسح') +
'</button>' +
'<span class="oe_search_count badge badge-success ml-2" style="display: ' +
(isFiltered ? 'inline-block' : 'none') + ';">' +
countText +
'</span>' +
'<span class="oe_search_loading ml-2" style="display: none;">' +
'<i class="fa fa-spinner fa-spin"></i>' +
'</span>' +
'</div>';
this.$el.prepend($(html));
this._lastInputValue = savedValue;
if (savedValue) {
var $input = this.$('.oe_search_input');
$input.focus();
var length = savedValue.length;
if ($input[0] && $input[0].setSelectionRange) {
setTimeout(function() {
$input[0].setSelectionRange(length, length);
}, 0);
try {
// **التحقق من DOM validity**
if (!this.$el || !this.$el.length) {
console.warn('FIMS Search: Invalid DOM element');
return;
}
var controller = this.getParent();
var savedValue = '';
var savedCount = 0;
var isFiltered = false;
if (controller && controller._customSearchState) {
savedValue = controller._customSearchState.value || '';
savedCount = controller._customSearchState.filteredCount || 0;
isFiltered = controller._customSearchState.isFiltered || false;
}
var countText = isFiltered ?
_t('عدد السجلات: ') + savedCount : '';
var html =
'<div class="oe_search_container d-flex align-items-center">' +
'<input type="text" class="oe_search_input form-control flex-grow-1" ' +
'placeholder="' + _.escape(_t('البحث في جميع الأعمدة المرئية...')) + '" ' +
'value="' + _.escape(savedValue) + '" ' +
'autocomplete="off">' +
'<button class="btn btn-secondary oe_clear_search ml-2" style="display: ' +
(savedValue ? 'inline-block' : 'none') + ';">' +
'<i class="fa fa-times mr-1"></i>' + _t('مسح') +
'</button>' +
'<span class="oe_search_count badge badge-success ml-2" style="display: ' +
(isFiltered ? 'inline-block' : 'none') + ';">' +
countText +
'</span>' +
'<span class="oe_search_loading ml-2" style="display: none;">' +
'<i class="fa fa-spinner fa-spin"></i>' +
'</span>' +
'</div>';
this.$el.prepend($(html));
this._lastInputValue = savedValue;
if (savedValue) {
var $input = this.$('.oe_search_input');
$input.focus();
var length = savedValue.length;
if ($input[0] && $input[0].setSelectionRange) {
setTimeout(function() {
$input[0].setSelectionRange(length, length);
}, 0);
}
}
} catch (error) {
console.error('FIMS Search: Error in _addCustomSearchBox:', error);
}
},
// **ربط Events programmatically**
_bindCustomEvents: function() {
if (this._customEventsbound) {
return; // تجنب double binding
}
try {
var self = this;
// bind events to the search container
this.$el.on('keyup', '.oe_search_input', function(e) {
self._onCustomSearchKeyUp(e);
});
this.$el.on('input', '.oe_search_input', function(e) {
self._onCustomSearchInput(e);
});
this.$el.on('click', '.oe_clear_search', function(e) {
self._onCustomClearSearch(e);
});
this.$el.on('keydown', '.oe_search_input', function(e) {
self._onCustomSearchKeyDown(e);
});
this._customEventsbound = true;
} catch (error) {
console.error('FIMS Search: Error binding events:', error);
}
},
// **تنظيف Events عند destroy**
destroy: function() {
if (this._customEventsbound) {
this.$el.off('keyup', '.oe_search_input');
this.$el.off('input', '.oe_search_input');
this.$el.off('click', '.oe_clear_search');
this.$el.off('keydown', '.oe_search_input');
}
this._super.apply(this, arguments);
},
_onCustomSearchInput: function(e) {
var currentValue = $(e.currentTarget).val();
var hasValue = !!currentValue.trim();
if (currentValue === this._lastInputValue) return;
this._lastInputValue = currentValue;
this.$('.oe_clear_search').toggle(hasValue);
if (!hasValue) {
this.$('.oe_search_count').hide();
try {
var currentValue = $(e.currentTarget).val();
var hasValue = !!currentValue.trim();
if (currentValue === this._lastInputValue) return;
this._lastInputValue = currentValue;
this.$('.oe_clear_search').toggle(hasValue);
if (!hasValue) {
this.$('.oe_search_count').hide();
}
} catch (error) {
console.error('FIMS Search: Error in _onCustomSearchInput:', error);
}
},
_onCustomSearchKeyUp: function(e) {
var self = this;
var value = $(e.currentTarget).val().trim();
var ignoreKeys = [13, 27, 16, 17, 18, 91, 93, 37, 38, 39, 40,
33, 34, 35, 36, 9, 20, 144, 145,
112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123];
if (ignoreKeys.indexOf(e.which) !== -1) return;
if (value === this._lastSearchValue) return;
this._lastSearchValue = value;
if (this._searchTimer) {
clearTimeout(this._searchTimer);
}
this._searchTimer = setTimeout(function() {
if (self.getParent() && self.getParent()._handleCustomSearch) {
self.getParent()._handleCustomSearch(value);
}
}, 500);
},
_onCustomSearchKeyDown: function(e) {
if (e.which === 13) {
e.preventDefault();
try {
var self = this;
var value = $(e.currentTarget).val().trim();
var ignoreKeys = [13, 27, 16, 17, 18, 91, 93, 37, 38, 39, 40,
33, 34, 35, 36, 9, 20, 144, 145,
112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123];
if (ignoreKeys.indexOf(e.which) !== -1) return;
if (value === this._lastSearchValue) return;
this._lastSearchValue = value;
if (this._searchTimer) {
clearTimeout(this._searchTimer);
}
var value = $(e.currentTarget).val().trim();
if (this.getParent() && this.getParent()._handleCustomSearch) {
this.getParent()._handleCustomSearch(value);
this._searchTimer = setTimeout(function() {
var parent = self.getParent();
if (parent && parent._handleCustomSearch) {
parent._handleCustomSearch(value);
}
}, 500);
} catch (error) {
console.error('FIMS Search: Error in _onCustomSearchKeyUp:', error);
}
},
_onCustomSearchKeyDown: function(e) {
try {
if (e.which === 13) {
e.preventDefault();
if (this._searchTimer) {
clearTimeout(this._searchTimer);
}
var value = $(e.currentTarget).val().trim();
var parent = this.getParent();
if (parent && parent._handleCustomSearch) {
parent._handleCustomSearch(value);
}
} else if (e.which === 27) {
e.preventDefault();
this._onCustomClearSearch();
}
} else if (e.which === 27) {
e.preventDefault();
this._onCustomClearSearch();
} catch (error) {
console.error('FIMS Search: Error in _onCustomSearchKeyDown:', error);
}
},
_onCustomClearSearch: function() {
this.$('.oe_search_input').val('').focus();
this.$('.oe_clear_search').hide();
this.$('.oe_search_count').hide();
this._lastInputValue = '';
this._lastSearchValue = '';
if (this.getParent() && this.getParent()._clearCustomSearch) {
this.getParent()._clearCustomSearch();
try {
this.$('.oe_search_input').val('').focus();
this.$('.oe_clear_search').hide();
this.$('.oe_search_count').hide();
this._lastInputValue = '';
this._lastSearchValue = '';
var parent = this.getParent();
if (parent && parent._clearCustomSearch) {
parent._clearCustomSearch();
}
} catch (error) {
console.error('FIMS Search: Error in _onCustomClearSearch:', error);
}
}
});