Merge pull request #4431 from expsa/eltayar
🔥 RADICAL FIX: Simplify and always re-render for reliable results
This commit is contained in:
commit
3d7122d4c9
|
|
@ -128,7 +128,7 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) {
|
|||
},
|
||||
|
||||
/**
|
||||
* Handle search input keyup - FIXED FOR EMPTY SEARCH
|
||||
* Handle search input keyup - ALWAYS TRIGGER SEARCH
|
||||
*/
|
||||
_onSearchKeyUp: function(e) {
|
||||
var self = this;
|
||||
|
|
@ -145,8 +145,7 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) {
|
|||
// Store value
|
||||
this._search.value = value;
|
||||
|
||||
// CRITICAL FIX: Always trigger search, even for empty values
|
||||
// This ensures clearing the last character works properly
|
||||
// ALWAYS trigger search - no exceptions
|
||||
this._search.timer = setTimeout(function() {
|
||||
self._performSearch(value);
|
||||
}, 500);
|
||||
|
|
@ -160,7 +159,7 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) {
|
|||
},
|
||||
|
||||
/**
|
||||
* Perform search - ENHANCED WITH LOOP PREVENTION
|
||||
* Perform search - SIMPLIFIED AND FIXED
|
||||
*/
|
||||
_performSearch: function(value) {
|
||||
var self = this;
|
||||
|
|
@ -171,13 +170,18 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) {
|
|||
return Promise.resolve();
|
||||
}
|
||||
|
||||
console.log('=== PERFORM SEARCH ===');
|
||||
console.log('Search value:', value);
|
||||
console.log('Value length:', value ? value.length : 0);
|
||||
|
||||
// Use mutex to prevent concurrent searches
|
||||
return this._searchMutex.exec(function() {
|
||||
// Set flag to prevent loops
|
||||
self._searchInProgress = true;
|
||||
|
||||
// Clear if empty - FIXED: Proper handling of empty search
|
||||
// CRITICAL FIX: Handle empty search properly
|
||||
if (!value || value.length === 0) {
|
||||
console.log('Empty search - clearing');
|
||||
return self._clearSearch().finally(function() {
|
||||
self._searchInProgress = false;
|
||||
});
|
||||
|
|
@ -190,7 +194,7 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) {
|
|||
return Promise.resolve();
|
||||
}
|
||||
|
||||
console.log('=== Starting search for:', value, '===');
|
||||
console.log('Starting server search for:', value);
|
||||
|
||||
// Store original data on first search
|
||||
if (!self._search.originalData && !self._search.isFiltered) {
|
||||
|
|
@ -253,137 +257,44 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) {
|
|||
_processSearchResults: function(records) {
|
||||
var count = records.length;
|
||||
|
||||
console.log('Processing search results:', count, 'records');
|
||||
console.log('=== PROCESS SEARCH RESULTS ===');
|
||||
console.log('Records found:', count);
|
||||
|
||||
// Update search state
|
||||
this._search.isFiltered = true;
|
||||
this._search.allFilteredRecords = records;
|
||||
this._search.filteredIds = records.map(function(r) { return r.id; });
|
||||
|
||||
console.log('Filtered IDs:', this._search.filteredIds);
|
||||
|
||||
// Show count
|
||||
this.$('.oe_search_count').text(_t('Found: ') + count + _t(' records')).show();
|
||||
|
||||
if (count === 0) {
|
||||
this._showNoResults();
|
||||
// Update main pager for empty results - WITHOUT RELOAD
|
||||
this._updatePagerOnly(0);
|
||||
return;
|
||||
}
|
||||
|
||||
// Update the view with filtered results
|
||||
this._updateViewWithFilteredData(records);
|
||||
// CRITICAL FIX: Always re-render with filtered data
|
||||
// Don't rely on DOM filtering - just re-render every time
|
||||
this._forceRerenderWithFilteredData(records);
|
||||
},
|
||||
|
||||
/**
|
||||
* CRITICAL FIX: Update view - TRY DOM FILTERING FIRST, THEN FALLBACK
|
||||
* CRITICAL FIX: Always re-render with filtered data
|
||||
*/
|
||||
_updateViewWithFilteredData: function(records) {
|
||||
console.log('=== _updateViewWithFilteredData ===');
|
||||
console.log('Records count:', records.length);
|
||||
console.log('Filtered IDs:', this._search.filteredIds);
|
||||
|
||||
// CRITICAL FIX: Try DOM filtering first (this usually works and is fast)
|
||||
var domFilterWorked = this._filterExistingRows();
|
||||
console.log('DOM filtering worked:', domFilterWorked);
|
||||
|
||||
if (domFilterWorked) {
|
||||
// DOM filtering worked - just update pager
|
||||
this._updatePagerOnly(records.length);
|
||||
return;
|
||||
}
|
||||
|
||||
// DOM filtering failed - need to re-render
|
||||
console.log('DOM filtering failed, re-rendering with proper Odoo methods...');
|
||||
this._updateStateAndRerenderProperly(records);
|
||||
},
|
||||
|
||||
/**
|
||||
* CRITICAL FIX: Filter existing rows in DOM - ENHANCED
|
||||
*/
|
||||
_filterExistingRows: function() {
|
||||
if (!this._search.filteredIds || this._search.filteredIds.length === 0) {
|
||||
console.log('No filtered IDs to work with');
|
||||
return false;
|
||||
}
|
||||
|
||||
var self = this;
|
||||
var $allRows = this.$('.o_data_row');
|
||||
var limit = this.state.limit || 80;
|
||||
var visibleCount = 0;
|
||||
var foundAnyMatch = false;
|
||||
var availableRowIds = [];
|
||||
|
||||
console.log('=== DOM Filtering Debug ===');
|
||||
console.log('Total rows in DOM:', $allRows.length);
|
||||
console.log('Looking for IDs:', this._search.filteredIds);
|
||||
|
||||
if ($allRows.length === 0) {
|
||||
console.log('No rows in DOM to filter');
|
||||
return false;
|
||||
}
|
||||
|
||||
// First, collect all available row IDs for debugging
|
||||
$allRows.each(function(index) {
|
||||
var $row = $(this);
|
||||
var rowId = self._getRowId($row);
|
||||
if (rowId) {
|
||||
availableRowIds.push(rowId);
|
||||
}
|
||||
});
|
||||
|
||||
console.log('Available row IDs in DOM:', availableRowIds);
|
||||
|
||||
// Check if we have ANY matching IDs
|
||||
var intersection = this._search.filteredIds.filter(function(id) {
|
||||
return availableRowIds.includes(id);
|
||||
});
|
||||
|
||||
console.log('Intersection (IDs that exist in DOM):', intersection);
|
||||
|
||||
// If we have at least some matches, proceed with DOM filtering
|
||||
if (intersection.length > 0) {
|
||||
// Hide all rows first
|
||||
$allRows.hide();
|
||||
|
||||
// Show matching rows up to limit
|
||||
$allRows.each(function(index) {
|
||||
var $row = $(this);
|
||||
var rowId = self._getRowId($row);
|
||||
|
||||
if (rowId && self._search.filteredIds.includes(rowId)) {
|
||||
if (visibleCount < limit) {
|
||||
$row.show();
|
||||
visibleCount++;
|
||||
foundAnyMatch = true;
|
||||
console.log('✓ Showing row', index, 'with ID', rowId);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
console.log('DOM filtering completed - Visible rows:', visibleCount);
|
||||
return visibleCount > 0;
|
||||
}
|
||||
|
||||
// No matches found - need to re-render
|
||||
console.log('No matching IDs found in DOM - need to re-render');
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* ENHANCED: Update state and re-render using proper Odoo methods
|
||||
*/
|
||||
_updateStateAndRerenderProperly: function(records) {
|
||||
_forceRerenderWithFilteredData: function(records) {
|
||||
var self = this;
|
||||
var limit = this.state.limit || 80;
|
||||
var pageRecords = records.slice(0, limit);
|
||||
|
||||
console.log('=== Proper Re-rendering ===');
|
||||
console.log('=== FORCE RE-RENDER ===');
|
||||
console.log('Total records:', records.length);
|
||||
console.log('Page records:', pageRecords.length);
|
||||
|
||||
// Update state with filtered data - PROPERLY
|
||||
// Update state with filtered data
|
||||
if (this.state) {
|
||||
// Store original state for restoration
|
||||
if (this.state.data) {
|
||||
this.state.data.records = pageRecords;
|
||||
}
|
||||
|
|
@ -391,60 +302,17 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) {
|
|||
this.state.res_ids = this._search.filteredIds;
|
||||
}
|
||||
|
||||
// Clear existing content
|
||||
// Clear existing content completely
|
||||
this.$('tbody .o_data_row').remove();
|
||||
this.$('.oe_no_results').remove();
|
||||
|
||||
// Try to use Odoo's native rendering methods first, then fallback to manual
|
||||
if (pageRecords.length > 0) {
|
||||
var renderSuccess = this._tryOdooRenderingMethods(pageRecords);
|
||||
if (!renderSuccess) {
|
||||
// Fallback to manual creation with proper formatting
|
||||
this._createEnhancedRows(pageRecords);
|
||||
}
|
||||
} else {
|
||||
this._showNoResults();
|
||||
}
|
||||
// Always create new rows manually with proper formatting
|
||||
this._createEnhancedRows(pageRecords);
|
||||
|
||||
// Update pager
|
||||
this._updatePagerOnly(records.length);
|
||||
},
|
||||
|
||||
/**
|
||||
* NEW: Try Odoo rendering methods with fallbacks
|
||||
*/
|
||||
_tryOdooRenderingMethods: function(records) {
|
||||
try {
|
||||
// Method 1: Try _renderRows
|
||||
if (typeof this._renderRows === 'function') {
|
||||
console.log('Trying _renderRows method');
|
||||
var $rows = this._renderRows();
|
||||
if ($rows && $rows.length > 0) {
|
||||
this.$('tbody').append($rows);
|
||||
console.log('✓ _renderRows succeeded');
|
||||
return true;
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn('_renderRows failed:', err);
|
||||
}
|
||||
|
||||
try {
|
||||
// Method 2: Try _renderBody
|
||||
if (typeof this._renderBody === 'function') {
|
||||
console.log('Trying _renderBody method');
|
||||
this._renderBody();
|
||||
console.log('✓ _renderBody completed');
|
||||
return true;
|
||||
}
|
||||
} catch (err) {
|
||||
console.warn('_renderBody failed:', err);
|
||||
}
|
||||
|
||||
console.log('All Odoo rendering methods failed, using manual fallback');
|
||||
return false;
|
||||
},
|
||||
|
||||
/**
|
||||
* ENHANCED: Create rows with proper Odoo formatting and event handlers
|
||||
*/
|
||||
|
|
@ -473,9 +341,11 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) {
|
|||
var self = this;
|
||||
var $row = $('<tr class="o_data_row"></tr>');
|
||||
|
||||
// Set proper Odoo attributes
|
||||
// Set proper Odoo attributes - MULTIPLE FORMATS FOR COMPATIBILITY
|
||||
$row.attr('data-id', record.id);
|
||||
$row.attr('data-res-id', record.id);
|
||||
$row.data('id', record.id);
|
||||
$row.data('res-id', record.id);
|
||||
|
||||
// CRITICAL: Add proper record data that Odoo expects
|
||||
var recordData = {
|
||||
|
|
@ -486,6 +356,8 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) {
|
|||
};
|
||||
$row.data('record', recordData);
|
||||
|
||||
console.log('Created row for record ID:', record.id);
|
||||
|
||||
// Add cells for each visible column using proper field rendering
|
||||
if (self.columns && self.columns.length > 0) {
|
||||
self.columns.forEach(function(col) {
|
||||
|
|
@ -621,51 +493,6 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) {
|
|||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Get row ID from DOM element - ENHANCED METHOD
|
||||
*/
|
||||
_getRowId: function($row) {
|
||||
// Method 1: data-id attribute
|
||||
var id = $row.attr('data-id');
|
||||
if (id && !isNaN(parseInt(id))) {
|
||||
return parseInt(id);
|
||||
}
|
||||
|
||||
// Method 2: data-res-id attribute
|
||||
id = $row.attr('data-res-id');
|
||||
if (id && !isNaN(parseInt(id))) {
|
||||
return parseInt(id);
|
||||
}
|
||||
|
||||
// Method 3: jQuery data id
|
||||
id = $row.data('id');
|
||||
if (id && !isNaN(parseInt(id))) {
|
||||
return parseInt(id);
|
||||
}
|
||||
|
||||
// Method 4: jQuery data res-id
|
||||
id = $row.data('res-id');
|
||||
if (id && !isNaN(parseInt(id))) {
|
||||
return parseInt(id);
|
||||
}
|
||||
|
||||
// Method 5: Check for record object in data
|
||||
var record = $row.data('record');
|
||||
if (record) {
|
||||
if (record.res_id && !isNaN(parseInt(record.res_id))) {
|
||||
return parseInt(record.res_id);
|
||||
}
|
||||
if (record.id && !isNaN(parseInt(record.id))) {
|
||||
return parseInt(record.id);
|
||||
}
|
||||
if (record.data && record.data.id && !isNaN(parseInt(record.data.id))) {
|
||||
return parseInt(record.data.id);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* SAFE PAGER UPDATE - WITHOUT RELOAD TRIGGERS
|
||||
*/
|
||||
|
|
@ -746,7 +573,7 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) {
|
|||
},
|
||||
|
||||
/**
|
||||
* Client-side search fallback - ENHANCED
|
||||
* Client-side search fallback - SIMPLIFIED
|
||||
*/
|
||||
_clientSideSearch: function(value) {
|
||||
var self = this;
|
||||
|
|
@ -756,7 +583,7 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) {
|
|||
var limit = this.state.limit || 80;
|
||||
var matchedIds = [];
|
||||
|
||||
console.log('Using client-side search fallback');
|
||||
console.log('Using client-side search fallback for:', value);
|
||||
|
||||
this.$('.o_data_row').each(function() {
|
||||
var $row = $(this);
|
||||
|
|
@ -797,19 +624,18 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) {
|
|||
// Update pager safely
|
||||
this._updatePagerOnly(visible);
|
||||
|
||||
console.log('Client-side search completed. Visible:', visible, 'IDs:', matchedIds);
|
||||
console.log('Client-side search completed. Visible:', visible);
|
||||
},
|
||||
|
||||
/**
|
||||
* Clear search - ENHANCED WITH LOOP PREVENTION
|
||||
* Clear search - ENHANCED AND FIXED
|
||||
*/
|
||||
_clearSearch: function() {
|
||||
console.log('=== Clearing search ===');
|
||||
console.log('=== CLEARING SEARCH ===');
|
||||
|
||||
// PREVENT LOOPS during clear
|
||||
if (this._searchInProgress) {
|
||||
console.log('Search in progress during clear, setting flag to clear after');
|
||||
this._pendingClear = true;
|
||||
console.log('Search in progress during clear, ignoring');
|
||||
return Promise.resolve();
|
||||
}
|
||||
|
||||
|
|
@ -832,7 +658,7 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) {
|
|||
|
||||
// Restore original data
|
||||
if (this._search.originalData) {
|
||||
console.log('Restoring original data:', this._search.originalData);
|
||||
console.log('Restoring original data');
|
||||
|
||||
// Restore state
|
||||
if (this.state) {
|
||||
|
|
@ -886,6 +712,51 @@ odoo.define('fims_general_search_tree_view.list_search', function (require) {
|
|||
return promise;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get row ID from DOM element - ENHANCED METHOD
|
||||
*/
|
||||
_getRowId: function($row) {
|
||||
// Method 1: data-id attribute
|
||||
var id = $row.attr('data-id');
|
||||
if (id && !isNaN(parseInt(id))) {
|
||||
return parseInt(id);
|
||||
}
|
||||
|
||||
// Method 2: data-res-id attribute
|
||||
id = $row.attr('data-res-id');
|
||||
if (id && !isNaN(parseInt(id))) {
|
||||
return parseInt(id);
|
||||
}
|
||||
|
||||
// Method 3: jQuery data id
|
||||
id = $row.data('id');
|
||||
if (id && !isNaN(parseInt(id))) {
|
||||
return parseInt(id);
|
||||
}
|
||||
|
||||
// Method 4: jQuery data res-id
|
||||
id = $row.data('res-id');
|
||||
if (id && !isNaN(parseInt(id))) {
|
||||
return parseInt(id);
|
||||
}
|
||||
|
||||
// Method 5: Check for record object in data
|
||||
var record = $row.data('record');
|
||||
if (record) {
|
||||
if (record.res_id && !isNaN(parseInt(record.res_id))) {
|
||||
return parseInt(record.res_id);
|
||||
}
|
||||
if (record.id && !isNaN(parseInt(record.id))) {
|
||||
return parseInt(record.id);
|
||||
}
|
||||
if (record.data && record.data.id && !isNaN(parseInt(record.data.id))) {
|
||||
return parseInt(record.data.id);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Store original data (only once per search session)
|
||||
*/
|
||||
|
|
|
|||
Loading…
Reference in New Issue