Results 1 to 2 of 2

Thread: Grid store filtering while highlighting cell

  1. #1
    Sencha User
    Join Date
    Mar 2013
    Posts
    3
    Vote Rating
    0
      0  

    Default Grid store filtering while highlighting cell

    Here's some context before I dive into the problem:

    We have a webpage where there is a Single ExtJs grid, the grid is editable,(cellEditing plugin) and changed data can be saved / persisted.
    There is also a Find and replace feature on the same grid, by using which the user can directly search a particular string, highlight the matches and replace a matched cell wiScreen Shot 2013-05-21 at 2.47.58 PM.jpgScreen Shot 2013-05-21 at 2.47.58 PM.jpgth a different value.

    Here is a screen shot :




    The design to implement Find & Replace feature is:
    While the user types a value in the find text-box, (in this case "AMR"), the store of the grid is filtered and the coordinates of the filtered cells {row index, column name}, are stored in a an array in global scope so that when user clicks on the next/previous button, the array can be looped through to get the coordinates of the desired cell to be highlighted, then get the DOM of the cell concerned and add a class to highlight the cell.

    The logic to get the coordinates of the matched records :
    Code:
    searchGrid:function(Text,e){
            var controller=this;
            $('.highlightMatch').removeClass('highlightMatch');
            var findVal=Ext.getCmp('find').getValue();<-----------------------Get the input by the user
            var matchedRecords=[];
            var grid=Ext.getCmp('dataGridViewId');
            console.log(grid,"Records in store right now:",grid.getStore());
            grid.getStore().each(function(record){
                $.each(appLocalStore.data.get('columnMetadata'),function(){
                    
                    if(null!=record.raw[this.columnName] && null!=record.raw[this.columnName].toLowerCase()){
                        var n=record.raw[this.columnName].toLowerCase().indexOf(findVal.toLowerCase());
                        if(n!=-1){
                            matchedRecords.push({<-----------------------Add matched record index and column name in an array
                            field:this.columnName,
                            rowIndex:record.index
                          });
                        }
                    }
    
                });
            });
            appLocalStore.data.set('matchedRecords',matchedRecords);<-----------------------Set the record in global scope
    
            var cursorPosition={<-----------------------Set the cursor position to start
                    index:-1,
                    direction:'start'
            };
            appLocalStore.data.set('cursorPosition',cursorPosition);
        }
    While clicking on the next button, the logic is :
    Code:
    findNext:function(){
            var controller=this;
            var findVal=Ext.getCmp('find').getValue();
            var matchs=appLocalStore.data.get('matchedRecords');<--------------------------Get the coordinates of matched record from global scope
            if(findVal!==''){
                var cursorPosition=appLocalStore.data.get('cursorPosition');<-----------------------Get the current index of the record where match is found
                  var cols=Ext.getCmp('dataGridViewId').getView().getGridColumns();
                //to unhighlight last match
                $('.highlightMatch').removeClass('highlightMatch');
    
                if(cursorPosition.index<0 || cursorPosition.index==appLocalStore.data.get('matchedRecords').length-1){
                    cursorPosition.index=0;
                }else{
                    cursorPosition.index=cursorPosition.index+1;
                }
    
                //to highlight current match
                var recordToHighlight=appLocalStore.data.get('matchedRecords')[cursorPosition.index];<---------Get the coordinates of the next record to be highlighted
                  var currentMatchedRecord=Ext.getCmp('dataGridViewId').getStore().getAt(recordToHighlight.rowIndex);<---------Get the matched record from the store
                var column;
                var cell;
                $.each(cols,function(index){
                    if(this.dataIndex===recordToHighlight.field){
                        column=this;
                    }
                });
                cell=Ext.getCmp('dataGridViewId').getView().getCell(currentMatchedRecord,column);<--------------Get the DOM of matched cell of the record 
    
                 cell.addCls('highlightMatch');<---------------------------------------------Get the DOM of matched cell of the record 
    
                cursorPosition.direction='forward';
                appLocalStore.data.set('cursorPosition',cursorPosition);
                
                //adjust scroll position<---------------------------------------------Set scroll position of the highlighted cell to the middle of the grid
                var c2 = $('#dataGridViewId .x-grid-view'); 
                var row=Ext.getCmp('dataGridViewId').getView().getNode(currentMatchedRecord);
                var top=0;
                if((row.offsetTop-40)<0){
                    top=0;
                }else{
                    top=row.offsetTop-40;
                }
                $(c2[1]).scrollTop(top);
                $(c2[1]).scrollLeft((cell.dom.offsetLeft)/2);
            }
            }
    And here is the problem:

    The matches are done against all the records that are there in the store, but in the browser, the grid structure doesnt have all the records in the DOM, extJs dynamically appends DOM of records in the grid as and when scrolling is done.
    And if a record is not yet present in the Dom and an attempt is made to get the cell of that record from the dom(cell=Ext.getCmp('dataGridViewId').getView().getCell(currentMatchedRecord,column); ), it throws an error and the functionality breaks.
    Screen Shot 2013-05-21 at 2.47.58 PM.jpg

    So what we need here is to know the indices of the records in the store, which are the in the DOM, so that we can restrict the find next functionality not look beyond the range of indices after which records are not there in the DOM.

    Please let me know if I am not clear enough while explaining the issue.
    Attached Images Attached Images

  2. #2
    Sencha User slemmon's Avatar
    Join Date
    Mar 2009
    Location
    Boise, ID
    Posts
    6,165
    Answers
    505
    Vote Rating
    255
      0  

    Default

    I'm not seeing a public method to get the loaded range, but you might look at bufferedRenderer's getViewRange() method to get some ideas.

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •