Insert record on specific position in flex grid

Posted by: petr.somek on 13 October 2020, 5:34 pm EST

  • Posted 13 October 2020, 5:34 pm EST

    Hello,

    I’m using flexgrid and I need to add a new record to grid on specified position in button’s onlick handler.

    This code works well, but appends new record on the tail of grid

    
            var itemToAdd={ID:'1',failureMode:'abc'};
    	me._itemsSource.addNew(itemToAdd);
    
    

    So I have tried this one, which I have found on this forum

    
    	var itemToAdd={ID:'1',failureMode:'abc'};
    	me._itemsSource.items.splice(0,0,itemToAdd);
    				
    	me._itemsSource.commitNew();						
    	me._itemsSource.refresh();
    
    

    And this code do nothing. As a datasource I’m using: ODataCollectionView. Does ODataCollectionView need some specific way how to insert new record?

    Thanks much

  • Posted 14 October 2020, 7:09 pm EST

    Hi Petr,

    Sorry but this solution cannot be used with Odata because the addNew and commitNew methods are designed in such a way that they will send the updated data to the OData server as soon as the new item is committed, which is not available in the splice method. So, we cannot add a new item to the view at any desired position.

    Moreover, even if there was a way to add the item at any desired position, the OData server will still add the new item at the last position.

    Regards,

    Ashwin

  • Posted 15 October 2020, 12:19 am EST

    Hi Ashwin,

    I think you miss our use case:

    • we understand that the sort of ODATA is independent
    • actually you have on that a good support via “RefreshOnEdit=false” , we mimic the excel behaviour, so the visual order stays even if i change the data
    • we use defferedCommits - there is a “save” action on the page to save

    The main reason why we cannot go live with “Add on Top” or “Add on Bottom” is that the “Insert Row” will actually actual expand a block of merged rows …

    Of course we understand that after collection.refresh or after commit to server (we use defferedCommits), the visual order will change…

    So what we plan:

    
    ---------------------------
    ABC | Row1
        |--------------------
        | Row 2
    ---------------------------
    XYZ | ...
    --------------------------
    
    

    We need to be able to add a new row under “Row 1”, having the first column merged over this new row, so Row2 will appear Row 3 and we understand that after “refresh” (i.e. resort/refilter) or after save (even though in our case not much will change as the table is ordered based on 1st column.

    We already find out we can call RowCollection.move

    theGrid.rows.moveElement(me._theGrid.rows.length-1,rowIndex+1);

    It works as expected - almost - but then the _idxData is computed wrongly (it is set to -1). As an impact, we cannot navigate well around the cell, after “refresh” the data get fixed.

    So our questions are:

    • Do you understand our use case?

    • Do you have any guidance for how to achieve the use case (actually this is really a prerequisite to buy the license to have this implemented in PoC)

    • How is moveElement supposed to work?

    Thanks!

    Jiri

  • Posted 15 October 2020, 2:04 am EST

    Why do we think that there is a problem with _idxData?

    The RowCollection._update method updates the _idxData to point Row to index of element in (OData)Collection.

    But it somehow does not find the right object, if we change the method to:

    (let’s suppose there is a grid on the top)

    
    top.grid.rows._update=function(){
      var t=top.grid.rows;
      if(t.__proto__._update.call(t)){
    	var i=t.grid?t.grid.collectionView:null,o=i?i.items:null,n=0;
    	t._maxLevel=-1;
    	t.forEach((function(e){
    		//we do not use GroupRow
    		//e instanceof GroupRow&&e.level>t._maxLevel&&(t._maxLevel=e.level);
        	e._idxData=-1;
        	var i= e.dataItem;
          	if(i && o ){
    	       e._idxData=(i===o[n]?n:i===o[n+1]?++n:-1);
    			//so far it is same code, only if idxData == -1, try to find it differently....
    		   if(e._idxData==-1){
    		   var rn = 0;
               //iterate over collection elements
    	       o.forEach(function(od){
    		      if(od===i){
    			    // return index in this collection
                    e._idxData=rn;
                  }
                  rn++;
    	      });
    		}
           }
    	}))
    	return!0
      }
      return!1
    };
    
    

    We do it just to proof that the issues is there. As you can see we iterate over a collection to find the right object, if your code return -1.

    Once we do that, the system works correct and we can insert row in the middle of the grid …

    We just need you to confirm the issue… and possibly fix it well.

    (Or give us other way how to achieve our must-have use case)

  • Posted 16 October 2020, 12:27 am EST

    Hi Jiri,

    Thanks for the detailed information. We are investigating this and we will update you on this as soon as possible.

    ~regards

  • Posted 18 October 2020, 9:59 pm EST

    Hello Jiri,

    Sorry for the delayed response.

    I was able to understand your issue and it seems that the moveElement will work for you in this scenario because if you will move the item using the CollectionView then you will have to call the refresh method (which I don’t think you want to). Otherwise, the items will not be updated.

    Now, for the _idxData issue, I have forwarded a bug report to the developers regarding this with internal tracking id 467403. I will update you once I will hear from them.

    The _idxData is private property and we can get its value by using the dataIndex property which is publicly accessible. So, as a workaround for this issue, you can override the dataIndex property to get the correct index of the data. Please refer to the sample link below for reference:

    https://stackblitz.com/edit/js-hrreq2

    In this sample, when you will click on the Add New button, a new item will be added using the addNew method so that it is added to the itemsAdded array. Now, the moveElement method is used to move this new item to its proper position. You can use the dataIndex or dataItem property to get the data bound to the row. If you will commit the changes to the server, you will observe that the newly added item will be sent to the server as expected.

    Note that the item will not be added to the server because the OData server used in this sample has not implemented any kind of editing but you can use the Network tab of the Browser to check that the correct query is sent to the server.

    Let me know if this resolves your issue.

    ~regards

  • Posted 17 November 2020, 9:38 pm EST

    Hello Jiri/Petr,

    Regarding #467403, the developers have said that this is by design. The rows of the grid have references to the data objects they represent; if they move, they become out of sync with the data source.

    Furthermore, data sources are often sorted, and in this case the row order is determined by the sorting algorithm, which is not compatible with explicit positions set by dragging or moving the rows.

    So, the workaround may be your best solution for this scenario.

    ~regards

Need extra support?

Upgrade your support plan and get personal unlimited phone support with our customer engagement team

Learn More

Forum Channels