Friday 1 April 2011

Accessing selected entity Ids from Silverlight

I am opening Silverlight application from contextual custom tab's custom ribbon button.
In this case Xrm.Page.ui and Xrm.Page.data are null as I am not showing Silverlight app as iframe on entity form. Please read Updated post at (http://crm2001andsilverlight.blogspot.com/2011/04/accessing-selected-entity-ids-from.html")

In order to access selected sub grid Ids in Silverlight .

private List<Guid> GetSelectedRecords()
        {
            List<Guid> selectedIds = new List<Guid>();

            HtmlElement gridBodyTable = (HtmlElement)HtmlPage.Window.Eval("dialogArguments.window.document.getElementById(\"gridBodyTable\")");
            if (gridBodyTable != null)
            {
                foreach (var record in gridBodyTable.Children)
                {
                    HtmlElement section = (HtmlElement)record;
                    if (section.TagName.Equals("tbody"))
                    {
                        foreach (var tableRow in section.Children)
                        {
                            HtmlElement row = (HtmlElement)tableRow;
                            if (row.TagName.Equals("tr"))
                            {
                                if (tableRow.GetProperty("selected") != null && (bool) tableRow.GetProperty("selected"))
                                {
                                    var id = tableRow.GetProperty("oid");
                                    if (id != null)
                                    {
                                        selectedIds.Add(new Guid(id as string));
                                    }
                                }
                            }
                        }
                    }
                }
            }
            return selectedIds;
        }


Or if anyone interested only in subgrids html from silverlight app  using javascript use
window.dialogArguments.window.document.activeElement.document.body.innerHTML.

Here is another useful link

http://social.microsoft.com/Forums/en/crm2011beta/thread/22d2c422-35c2-43ee-b33a-4bb7f8c36155

Accessing selected entity Ids from Silverlight (Updated)

I was recently involved in implementing a customization of CRM 2011 where I had to perform some actions on displayed subgrid's selected items.

1. Created a new solution and imported entity/ies on which I had to perform action.
2. Imported Application Ribbon
3. Added images as web resources (image being displayed on custom button)
4. Exported solution as unmanaged.

In customizations.xml file of solution,  added following xml to show custom button when subgrid is selected.
<ImportExportXml>
  <Entities>
    <Entity>

        <RibbonDiffXml>
           <CustomActions>
                <CustomAction Id="publishername.Homepage.entityname.CustomTab.Groups" Sequence="40" Location="Mscrm.SubGrid.entityname.MainTab.Workflow.Controls._children">
                  <CommandUIDefinition>
        <Button Id="publishername.Homepage.entityname.CustomTab.FirstGroup.FirstButton" Sequence="11" TemplateAlias="o1" Image32by32="$webresource:publishername_clientemail16.gif" Image16by16="$webresource:publishername_clientemail32.gif" Alt="$LocLabels:publishername.entityname.CustomTab.FirstGroup.FirstButton.LabelText" LabelText="$LocLabels:publishername.entityname.CustomTab.FirstGroup.FirstButton.LabelText" Command="publishername.Homepage.entityname.FirstButton" ToolTipDescription="$LocLabels:publishername.entityname.CustomTab.FirstGroup.FirstButton.ToolTipDescription" ToolTipTitle="$LocLabels:publishername.entityname.CustomTab.FirstGroup.FirstButton.LabelText"/>
      </CommandUIDefinition>
    </CustomAction>
  </CustomActions> -<Templates>
    <RibbonTemplates Id="Mscrm.Templates"/>
  </Templates>
  <CommandDefinitions>
    <CommandDefinition Id="publishername.Homepage.entityname.FirstButton">
      <EnableRules>
        <EnableRule Id="Mscrm.Enabled "/>
      </EnableRules>
      <DisplayRules>
        <DisplayRule Id="publishername.contact.WebClient.DisplayRule"/>
      </DisplayRules>
      <Actions>
        <JavaScriptFunction Library="$webresource:new_javascript" FunctionName="SelectedGridIds">
          <CrmParameter Value="SelectedControlSelectedItemIds"></CrmParameter>
        </JavaScriptFunction>
      </Actions>
    </CommandDefinition>
  </CommandDefinitions> -<RuleDefinitions>
    <TabDisplayRules/> -<DisplayRules>
      <DisplayRule Id="publishername.contact.WebClient.DisplayRule">
        <CrmClientTypeRule Type="Web"/>
      </DisplayRule>
    </DisplayRules> <EnableRules/>
  </RuleDefinitions> -<LocLabels>
    <LocLabel Id="publishername.entityname.CustomTab.FirstGroup.FirstButton.LabelText">
      <Titles>
        <Title languagecode="1033" description="Do Action"/>
      </Titles>
    </LocLabel> -<LocLabel Id="publishername.entityname.CustomTab.FirstGroup.FirstButton.ToolTipDescription">
      <Titles>
        <Title languagecode="1033" description="Perform action on selected items in subgrid"/>
      </Titles>
    </LocLabel>
  </LocLabels>
</RibbonDiffXml>


Above Xml creates a custom button on ribbon when entity subgrid is selected. Sequence defines position of button, and location defines where to show this button on main enity form, grid or subgrid. When button is clicked SelectedGridIds function is executed on new_javascript webresource, all selected ids of subgrids are passed to function defined in Value attribute of CrmParameter.
        <Actions>            
              <JavaScriptFunction Library="$webresource:new_javascript" FunctionName="SelectedGridIds">
                <CrmParameter Value="SelectedControlSelectedItemIds"></CrmParameter>
              </JavaScriptFunction>
            </Actions>

here is javascript I added as webresource 

function SelectedGridIds(selectedIds)
{
  var serverUrl =  Xrm.Page.context.getServerUrl();
   if (serverUrl.match(/\/$/)) {
        serverUrl = serverUrl.substring(0, serverUrl.length - 1);
      }

   //Set features for how the window will appear
    var features = "location=no,menubar=no,status=no,toolbar=no";
  
    var ids="";
    for(var i in selectedIds)
    {
        ids = ids + selectedIds[i] + ",";
    }
     
   if(ids.length >0)
   {
      ids= ids.substring(0,ids.length -1);
   }

    // Open the window
    window.open("/WebResources/new_/SilverlightPage.html#/ViewPage/"+ids, "_blank", features, false);
}

My silverlight application is using Navigation framework, to pass parameters from javascript function to silverlight application I used following mapping
 <uriMapper:UriMapping Uri="/PageView/{ids}" MappedUri="/Views/PageView.xaml?guid={ids}"/>
and finally in order to reterive values with in javascript use Navigation context. NavigationContext.QueryString["ids"].

I am not a blogger, apologies for that.
Suggestions and comments are welcome.