chris.w.mclean
chris.w.mclean

Reputation: 1821

How to hook into the save method via javascript on CRM2011 from Silverlight

We've built a silverlight grid which allows for editing of sub entities from a primary entity form. Works like a champ. But we have to have a separate save button on the silverlight control to push the updates back to CRM. What we'd like to do is allow the CRM form to call a method on the silverlight control to alert us that the form is saving and then save the data in the silverlight form at the same time. But it's just not working. What we've tried so far is this:

In the Silverlight control we've got a public class:


[ScriptableType]
    public class JSModel
    {
       [ScriptableMember]
       public void Save()
       {
           if (OnSave != null)
           {
               OnSave(this, new EventArgs());
           }
       }

   public event EventHandler OnSave;

   public JSModel()
   {

       HtmlPage.RegisterScriptableObject("JSModel", this);

       HtmlPage.Window.Eval(
           @"
           function CallSLSave()

{var sl = Xrm.Page.ui.controls.get('" + HtmlPage.Plugin.TagName + @"');

sl.content.JSModel.Save();} ");

       ScriptObject xrm = (ScriptObject)HtmlPage.Window.GetProperty("Xrm");
       ScriptObject Page = (ScriptObject)xrm.GetProperty("Page");
       ScriptObject data = (ScriptObject)Page.GetProperty("data");
       ScriptObject entity = (ScriptObject)data.GetProperty("entity");
       entity.Invoke("addOnSave", new object[] { "CallSLSave" });


   }

}

But it's not calling the javascript method . Anyone have any ideas what we're doing wrong?

Upvotes: 2

Views: 2847

Answers (2)

Mark
Mark

Reputation: 1894

Thanks to the magic of the HTML bridge, you can use a delegate as the parameter to the addOnSave method. There is no need for a Javascript bootstrap function, or a scriptable object on the page. This simplifies the solution to this:

    void SetupHook()
    {
        var xrm = (ScriptObject)HtmlPage.Window.GetProperty("Xrm");
        var page = (ScriptObject)xrm.GetProperty("Page");
        var data = (ScriptObject)page.GetProperty("data");
        var entity = (ScriptObject)data.GetProperty("entity");

        entity.Invoke("addOnSave", new Func<bool>(SaveHook));
    }

    private bool SaveHook()
    {
        // ... Do save stuff here ...
        return true;
    }

Also, note: The function to call doesn't need to be a scriptable member.

Upvotes: 1

TynaP
TynaP

Reputation: 29

I think what is you doing wrong is :Invoke("addOnSave"... Invoke's first argument is the JavaScript function. As I gather your addOnSave is C#.

You could simply have a regular button on MainPage with Save click EventHandler.

In MainPage.cs:

  [ScriptableMember]
    private void Save(object sender, RoutedEventArgs e)
    {
    HtmlPage.RegisterScriptableObject("scriptableControl", this); 
        HtmlPage.Window.Eval(@"function CallSLSave()
       { var sl = document.getElementById('silverlightControl');  sl.Content.scriptableControl.addOnSave();}");
    HtmlPage.Window.Invoke("CallSLSave");


//or the way you do except for entity.Invoke("addOnSave" should be  entity.Invoke("CallSLSave");
    }

    [ScriptableMember]
    public void addOnSave()
    {
        ...
    }

Upvotes: 1

Related Questions