none
Views - multiple column sort on load

    Question

  • Is there a way to sort on more than one column on load?  Currently when you are designing a  view it only asks what column to sort by
    Withers
    Monday, October 12, 2009 11:04 PM

Answers

  • I'll do my previous effort one better:  instead of dealing with all the muck of making your own SOAP calls and plugging into the grid's functions... how about simply editing the HTML?

    Here's what I found buried within the HTML of the grid page:

    <table class="ms-crm-ListControl" id="crmGrid" cellSpacing="0" cellPadding="0">
      <tbody>
        <tr>
          <td>
            <div id="divGridProps" style="display: none;">
              <div id="sortColumns" value="createdon:0"/>
            </div>
          </td>
        </tr>
      </tbody>
    </table>
    
    So, if I run this JS on the main CRM window (viewing the Cases):

    var stageFrame = document.getElementsByName("stage")[0];
    var stageFrameDoc = stageFrame.contentWindow.document;

    crmGrid = stageFrameDoc.all.crmGrid;
    crmGrid.all.divGridProps.children["sortColumns"].value = "statuscode:0;casetypecode:1";
    crmGrid.Refresh()

    It performs the proper sorting.  Unfortunately, it does not update the sorting icon on the columns.  There's a call being made somewhere, and I think it has to do with analyzing the keypress+click event, that updates the image... whereas my code does not follow that code path.

    But, the multisort does work!

    Dave Berry
    Tuesday, October 13, 2009 8:37 PM
    Moderator

All replies

  • Hi, Withers.

    It seems that there no supported way to sort on more than one column on view's load.
    Truth is opened the prepared mind My blog - http://a33ik.blogspot.com
    Tuesday, October 13, 2009 6:04 AM
    Moderator
  • It can be done.  But you have to simulate a Refresh command upon the grid.


    Dave Berry
    Tuesday, October 13, 2009 3:45 PM
    Moderator
  • I found the following code being sent to the server, wrapped in a SOAP call, by the grid when a new sort/multisort was performed:

    <grid>
    
      <sortColumns>createdon&#58;1&#59;casetypecode&#58;0</sortColumns>
    
      <pageNum>1</pageNum>
    
      <recsPerPage>250</recsPerPage>
    
      <dataProvider>Microsoft.Crm.Application.Controls.AppGridDataProvider</dataProvider>
    
      <uiProvider>Microsoft.Crm.Application.Controls.AppGridUIProvider</uiProvider>
    
      <cols/>
    
      <max>-1</max>
    
      <refreshAsync>False</refreshAsync>
    
      <pagingCookie/>
    
      <enableMultiSort>true</enableMultiSort>
    
      <enablePagingWhenOnePage>true</enablePagingWhenOnePage>
    
      <parameters>
    
        <autorefresh>1</autorefresh>
    
        <viewid>&#123;00000000-0000-0000-00AA-000010001028&#125;</viewid>
    
        <viewtype>1039</viewtype>
    
        <otc>112</otc>
    
        <preview>1</preview>
    
      </parameters>
    
      <columns>
    
        <column width="150" isHidden="false" isMetadataBound="true" isSortable="true" label="Title" fieldname="title" entityname="incident">title</column>
    
        <column width="150" isHidden="false" isMetadataBound="true" isSortable="true" label="Case Number" fieldname="ticketnumber" entityname="incident">ticketnumber</column>
    
        <column width="100" isHidden="false" isMetadataBound="true" isSortable="true" label="Priority" fieldname="prioritycode" entityname="incident">prioritycode</column>
    
        <column width="150" isHidden="false" isMetadataBound="true" isSortable="true" label="Customer" fieldname="customerid" entityname="incident">customerid</column>
    
        <column width="100" isHidden="false" isMetadataBound="true" isSortable="true" label="Status Reason" fieldname="statuscode" entityname="incident">statuscode</column>
    
        <column width="125" isHidden="false" isMetadataBound="true" isSortable="true" label="Case Type" fieldname="casetypecode" entityname="incident">casetypecode</column>
    
        <column width="125" isHidden="false" isMetadataBound="true" isSortable="true" label="Created On" fieldname="createdon" entityname="incident">createdon</column>
    
      </columns>
    
    </grid>

    The noticable part is the data in the <sortColumns> element.  Here is the string "createdon&#58;1&#59;casetypecode&#58;0 "  which, when parsed through an html decoder ends up being "createdon:1;casetypecode:0" which translates to:

    Sort first by 'createdon' in descending order, then by 'casetypecode' in ascending order.

    But there seems to still be a requirement for <enableMultiSort> . The SOAP call issues the "Refresh" command, after which the server responds with:

    <xml version="1.0" encoding="utf-8"?>
    
    <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
    
      <soap:Body>
    
        <RefreshResponse xmlns="http://schemas.microsoft.com/crm/2006/WebServices">
    
          <RefreshResult>&lt;gridXml&gt;&lt;gridHtml&gt;&lt;![CDATA[&lt;table id="gridBodyTable" class="ms-crm-List-Message" oname="112" morerecords="0"&gt;&lt;tr&gt;&lt;td&gt;No Case records are available in this view.&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;div id="divMenu" class="ms-crm-Standard-Popup" style="display:none;" onselectstart="return false;"&gt;&lt;div class="ms-crm-Standard-Item" onclick="if(!disabled){parentRow.fireEvent&amp;#40;&amp;#39;ondblclick&amp;#39;&amp;#41;&amp;#59;parentPopup.hide&amp;#40;&amp;#41;&amp;#59;}" disableonemptygrid="yes" &gt;&lt;nobr&gt;Open&lt;nobr&gt;&lt;/div&gt;&lt;div class="ms-crm-Standard-Item" onclick="if(!disabled){parentDataArea.SendShortcut&amp;#40;&amp;#32;false,&amp;#32;&amp;#39;112&amp;#39;&amp;#41;&amp;#59;parentPopup.hide&amp;#40;&amp;#41;&amp;#59;}" disableonemptygrid="yes" &gt;&lt;nobr&gt;Copy Shortcut&lt;nobr&gt;&lt;/div&gt;&lt;div class="ms-crm-Standard-Item" onclick="if(!disabled){parentDataArea.SendShortcut&amp;#40;&amp;#32;true,&amp;#32;&amp;#39;112&amp;#39;&amp;#41;&amp;#59;parentPopup.hide&amp;#40;&amp;#41;&amp;#59;}" disableonemptygrid="yes" &gt;&lt;nobr&gt;Send Shortcut...&lt;nobr&gt;&lt;/div&gt;&lt;div class="ms-crm-Standard-Item" onclick="if(!disabled){parentDataArea.PrintRow&amp;#40;parentRow&amp;#41;&amp;#59;}" disableonemptygrid="yes" &gt;&lt;nobr&gt;Print...&lt;nobr&gt;&lt;/div&gt;&lt;hr class="ms-crm-Standard-Item"&gt;&lt;div class="ms-crm-Standard-Item" onclick="if(!disabled){parentGrid.Refresh&amp;#40;&amp;#41;&amp;#59;parentPopup.hide&amp;#40;&amp;#41;&amp;#59;}" disableonemptygrid="no" &gt;&lt;nobr&gt;Refresh List&lt;nobr&gt;&lt;/div&gt;&lt;/div&gt;]]&gt;&lt;/gridHtml&gt;&lt;pagingCookie /&gt;&lt;/gridXml&gt;</RefreshResult>
    
        </RefreshResponse>
    
      </soap:Body>
    
    </soap:Envelope>


    This is the responseXML from the XMLHTTP object passed to the follwing function in the 'oXmlHttp ' argument:

    var result = RemoteCommandResult(oRemoteCommand, oXmlHttp);       (source:  /_static/_controls/remotecommands/remotecommand.js)

    The result of the function is in turn passed along to the grid's function:

    onRefreshComplete(result);

    So, if you could construct your own SOAP call, use the RemoteCommandResult() on the return, and pass the resulting object to onRefreshComplete(), you could specify some default sorting.  Naturally, you could probably achieve this from any form's onLoad(), but how this could be accomplished upon any view on the main CRM window would be beyond my abilities.  It might be easier to write your own grid page to perform this.


    Dave Berry
    Tuesday, October 13, 2009 6:06 PM
    Moderator
  • I'll do my previous effort one better:  instead of dealing with all the muck of making your own SOAP calls and plugging into the grid's functions... how about simply editing the HTML?

    Here's what I found buried within the HTML of the grid page:

    <table class="ms-crm-ListControl" id="crmGrid" cellSpacing="0" cellPadding="0">
      <tbody>
        <tr>
          <td>
            <div id="divGridProps" style="display: none;">
              <div id="sortColumns" value="createdon:0"/>
            </div>
          </td>
        </tr>
      </tbody>
    </table>
    
    So, if I run this JS on the main CRM window (viewing the Cases):

    var stageFrame = document.getElementsByName("stage")[0];
    var stageFrameDoc = stageFrame.contentWindow.document;

    crmGrid = stageFrameDoc.all.crmGrid;
    crmGrid.all.divGridProps.children["sortColumns"].value = "statuscode:0;casetypecode:1";
    crmGrid.Refresh()

    It performs the proper sorting.  Unfortunately, it does not update the sorting icon on the columns.  There's a call being made somewhere, and I think it has to do with analyzing the keypress+click event, that updates the image... whereas my code does not follow that code path.

    But, the multisort does work!

    Dave Berry
    Tuesday, October 13, 2009 8:37 PM
    Moderator
  • Posted relevant explanation here:  http://crmentropy.blogspot.com/2009/10/default-multi-column-sort.html
    Dave Berry
    Tuesday, October 13, 2009 8:54 PM
    Moderator
  • I'll do my previous effort one better:  instead of dealing with all the muck of making your own SOAP calls and plugging into the grid's functions... how about simply editing the HTML?

    Here's what I found buried within the HTML of the grid page:

    <table class="ms-crm-ListControl" id="crmGrid" cellSpacing="0" cellPadding="0">
    
      <tbody>
    
        <tr>
    
          <td>
    
            <div id="divGridProps" style="display: none;">
    
              <div id="sortColumns" value="createdon:0"/>
    
            </div>
    
          </td>
    
        </tr>
    
      </tbody>
    
    </table>
    
    
    So, if I run this JS on the main CRM window (viewing the Cases):

    var stageFrame = document.getElementsByName("stage")[0];
    var stageFrameDoc = stageFrame.contentWindow.document;

    crmGrid = stageFrameDoc.all.crmGrid;
    crmGrid.all.divGridProps.children["sortColumns"].value = "statuscode:0;casetypecode:1";
    crmGrid.Refresh()

    It performs the proper sorting.  Unfortunately, it does not update the sorting icon on the columns.  There's a call being made somewhere, and I think it has to do with analyzing the keypress+click event, that updates the image... whereas my code does not follow that code path.

    But, the multisort does work!

    Dave Berry
    Hi there,
    I'm trying to do multi column sorting on associated view(from left nav)..
    How can achieve that? Thannks.
    Wednesday, January 20, 2010 6:39 AM
  • That is a lot easier to manage with an associated view, primarily because you can be sure the code will run when the parent entity's form loads.  Basically, you'd have to take my code and drop it into a handler function that fires when the Iframe containing your associated view is first loaded.  The implementation would be identical to Dave Hawes utility to hide buttons on the Associated View.  You attach a custom function to the onreadystatechange event for the Iframe.  The function would basically need to contain only the following:

    document.all.crmGrid.all.divGridProps.children["sortColumns"].value = "statuscode:0;casetypecode:1";
    crmGrid.Refresh()
    crmGrid is a local member of the document contained by the Iframe, so you shouldn't need the first parts of my code to locate it.  To your users, it will appear as if the grid loads, and then loads again with the automatic multi-sort.
    Dave Berry
    Saturday, January 23, 2010 12:39 AM
    Moderator