4

Current customization project I'm working on has the requirement of displaying / editing a grid with a "Sort Order" for records. The "SortOrder" field is read only with up/down buttons to allow the user to re-order the items in the grid.

The "SortOrder" column in the DAC is a simple Int field.

The PXSelect statement for the grid is using a OrderBy>> to display the records.

The Grid in the ASPX is a defined with "SyncPosition= true"

I've added an Up/Down button that increments/decrements the "SortOrder" value for the current selected record.

The issue that I'm running into is that the first time "Up" or "Down" is clicked, the "SortOrder" field is updated however the rows do not move. Once I click Save to persist the update, the grid then refreshes with the right order.

I've looked through the the rest of the code but all other situations where this is used is for treeviews, not grids.

I've tried adding a View.RequestRefresh() at the end of my Action but this doesn't cause the reorder.

What would be the best way without a Persist after each move to get the Grid to update and reflect the current order from the cache values? As usual I'm assuming I'm overlooking something simple.

Any advice would be appreciated.

Jeff Williams
  • 1,016
  • 5
  • 16

1 Answers1

5

I had a look at the generic inquiry designer source code - it has an up/down button in the grid to reorder the fields. The views don't have an OrderBy clause:

public PXSelect<GIFilter, Where<GIFilter.designID, Equal<Current<GIDesign.designID>>>> Parameters;

OrderBy is not necessary because the LineNbr field is a key field - system automatically orders the records by the key fields.

    public abstract class lineNbr : IBqlField { }
    [PXDBInt(IsKey = true)]
    [PXDefault]
    [PXLineNbr(typeof(GIDesign))]
    [PXParent(typeof(Select<GIDesign,
        Where<GIDesign.designID, Equal<Current<GIFilter.designID>>>>))]
    public virtual int? LineNbr { get; set; }

The code for the button looks like this:

        [PXButton(ImageKey = Sprite.Main.ArrowUp, Tooltip = ActionsMessages.ttipRowUp)]
        [PXUIField(DisplayName = ActionsMessages.RowUp, MapEnableRights = PXCacheRights.Update)]
        protected void moveUpFilter()
        {
            if (this.Parameters.Current == null)
                return;
            GIFilter prev = PXSelect<GIFilter, Where<GIFilter.designID, Equal<Current<GIDesign.designID>>, And<GIFilter.lineNbr, Less<Current<GIFilter.lineNbr>>>>, OrderBy<Desc<GIFilter.lineNbr>>>.Select(this);
            if (prev != null)
                this.SwapItems(this.Parameters.Cache, prev, this.Parameters.Current);
        }
        [PXButton(ImageKey = Sprite.Main.ArrowDown, Tooltip = ActionsMessages.ttipRowDown)]
        [PXUIField(DisplayName = ActionsMessages.RowDown, MapEnableRights = PXCacheRights.Update)]
        protected void moveDownFilter()
        {
            if (this.Parameters.Current == null)
                return;
            GIFilter next = PXSelect<GIFilter, Where<GIFilter.designID, Equal<Current<GIDesign.designID>>, And<GIFilter.lineNbr, Greater<Current<GIFilter.lineNbr>>>>, OrderBy<Asc<GIFilter.lineNbr>>>.Select(this);
            if (next != null)
                this.SwapItems(this.Parameters.Cache, next, this.Parameters.Current);
        }

The SwapItems function is shared between all the move up / move down actions:

    private void SwapItems(PXCache cache, object first, object second)
    {
        object temp = cache.CreateCopy(first);
        foreach (Type field in cache.BqlFields)
            if (!cache.BqlKeys.Contains(field))
                cache.SetValue(first, field.Name, cache.GetValue(second, field.Name));
        foreach (Type field in cache.BqlFields)
            if (!cache.BqlKeys.Contains(field))
                cache.SetValue(second, field.Name, cache.GetValue(temp, field.Name));
        cache.Update(first);
        cache.Update(second);
    }

Finally, there's a bit of JavaScript code in the ASPX code - it may or may not be what you're missing to get the feature to work correctly; i'm not exactly sure what it's doing but would encourage you to open SM208000.aspx in an editor and look for commandResult. Also check out the CallbackCommands that are defined on the grids which support up/down - it may have something to do with it.

Gabriel
  • 3,733
  • 16
  • 29
  • 2
    Thank you for the pointer. In the end it was removing the "Order By" in the initial view and updating the move methods to be more simular to the ones above. The javascript methods simply keep the current row selected after the move so you can keep clicking up/down – Jeff Williams May 05 '16 at 16:42