Programming, technology, and CRM – from a Belgian programmer exiled to Missouri
  • rss
  • Home
  • Soft Gallery
    • autosvnbackup.sh
    • VBScript Snippets
  • Contact Me
  • Welcome

AJAX Script Services on SlxWeb

Nicolas Galler | March 12, 2009

From my user perspective one of the most dreadful aspect of the "QuickForms" is how slow they are.  If you want to associate a piece of custom logic to a control, typically you will have to set it to auto-postback.  At this point whenever the user changes it Saleslogix will have to post the entire form and (since it does not know what may have changed) pull the entire form back over the network and render it in the browser.  This is noticeable even on a local network connection but can easily take 1 to 3 seconds over a WAN, which really breaks the flow of the form.

In a custom smart part there are a couple ways to get around that.  One of them and often the easiest is to put smaller updatepanels around the controls that you know are going to be updated.  It is not the most efficient, and it requires a basic understanding of ASP.NET Ajax (because there are a few workarounds that need to be used to disable the default handling from the top-level SalesLogix container page), but it does not usually affect the page lifecycle so the code-behind does not need to be touched.  This is not the subject here though.

As an alternative to the Microsoft ASP.NET Ajax controls it is perfectly possible to use 100% custom, client-side Javascript.  For example it is easy to perform basic calculations in the page and display the results.  If they are saved to a bound control they can be saved to the database when the form is actually posted.  This is very fast because it is done entirely on the client but it does not let us access the database or any of the business rules defined in C# on the server side.

A middle-ground option is to have the client-side Javascript call a custom web service and display the results in the form controls.  This can be quite a bit faster than using an UpdatePanel, especially if a lot of controls need to be updated, and it also offers greater control over the flow of the code.  Sometimes the UpdatePanel’s behavior can become rather annoying and the custom Javascript actually be easier to use.  This is the method that I want to write about here.

On the client side, traditionally this approach would have required coding of the Javascript XmlHttpRequest and possibly parsing of the resulting XML (unless JSON was used).  However with ASP.NET it is a lot simpler, you can have a Javascript proxy generated automatically by using code like this:

<asp:ScriptManagerProxy runat="server" ID="scriptManagerProxy">
    <Services>
        <asp:ServiceReference Path="~/SmartParts/QuickTicket/InsertQuickTicketScriptService.asmx" />
    </Services>
</asp:ScriptManagerProxy>

By the way the ScriptManagerProxy means that it will use the ScriptManager on the main page, which is created by the Saleslogix framework.  You can’t just add a ScriptManager on your custom smart part as it will conflict with Saleslogix’.  In the Javascript code the methods from the web service will appear as method under an "InsertQuickTicketScriptService" object:

InsertQuickTicketScriptService.GetAccountInfo(accId, function(accInfo){
  alert(accInfo.AccountName);
})

Note they are called in an asynchronous fashion with a callback function.

Assuming the GetAccountInfo method returns an object containing a list of contacts the following code can be used to populate a list of contacts for the selected account:

InsertQuickTicketScriptService.GetAccountInfo(accId, function(accInfo){
        var cbo = $get("<%= cboContacts.ClientID %>");
        cbo.options.length = 0;
        for (var i = 0; i < accInfo.Contacts.length; i++) {
            cbo.options[cbo.options.length] =
                    new Option(accInfo.Contacts[i].ContactName,
                        accInfo.Contacts[i].Id);
        }
        if (cbo.options.length > 0)
            cbo.options[0].selected = true;
})

On the server side things are pretty easy thanks to the flexibility of the Saleslogix Entity service… In this case I used something similar to this:

[WebMethod(EnableSession = true)]
public AccountInfo GetAccountInfo(string accId)
{
    IAccount account = Sage.Platform.EntityFactory.GetById<IAccount>(accId);
    if (account == null)
        throw new InvalidOperationException("Account id not found " + accId);

    return new AccountInfo
    {
        Contacts = (from c in account.Contacts
                    select new ContactInfo
                    {
                        ContactId = (String)c.Id,
                        FullName = c.FullName
                    }).OrderBy(c => c.FullName).ToArray()
    };
}

Don’t forget the EnableSession=true… Saleslogix uses sessions to store the current user’s connection data and by default won’t be able to access it from an asmx.  By the way if you need to access it from an ashx you need to look for the similar option.  AccountInfo and ContactInfo are just locally defined classes, with the minimum properties that need to be passed down to the client script.

If you are writing a custom smart part ASP.NET truly makes it easy to call the web service from your Javascript.

Categories
Uncategorized
Comments rss
Comments rss
Trackback
Trackback

« My SalesLogix Web Development Setup IE8 “Define with Wiktionary” Accelerator »

4 Responses to “AJAX Script Services on SlxWeb”

  1. Elizabeth says:
    December 15, 2009 at 3:03 pm

    Hi Nico,

    I read the “AJAX Script Services on SlxWeb” article, it is amazing!!!!. But I need to ask you if you can help me because my javascript code is throwing me errors about that my webservice is not being declared. I attached it into the ScriptManager and everything but it doesn’t work.

    Could you help me please?

    Liz.

  2. Nicolas Galler says:
    December 15, 2009 at 9:13 pm

    Hi, Liz,

    It can be a little bit touchy about what your web service looks like. Do make sure you have the ScriptService attribute on your web service class (in the asmx) – the class should look like this:

    [WebService(Namespace = "http://sssworld.com/InsertQuickTicketScriptService")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    // To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
    [System.Web.Script.Services.ScriptService]
    public class InsertQuickTicketScriptService : System.Web.Services.WebService

    If it still does not work, try debugging with fiddler. You should see at one point the browser trying to download the script reference. It will look like Get /SlxClient/SmartParts/QuickTicket/InsertQuickTicketScriptService.asmx/js – watch for any error in that download, they might shed some light. You can also try downloading it yourself from the browser: http://myserver.com/SlxClient/SmartParts/QuickTicket/MyScriptService.asmx/js – and make sure you get some Javascript back.

    Finally, as this Javascript may be cached by the browser, be sure to clear your temporary files while you are debugging.

    Hope this helps!

  3. Elizabeth says:
    December 16, 2009 at 3:57 pm

    Thank you so much Nick!!,

    I discovered the problem, I declared the service in a static way on the ascx page (custom page) like this:

    And I want to declare this on the “Page_Load” event in a dynamic way, like this:
    ScriptManagerProxy service = new ScriptManagerProxy();
    service.ID = “serviceid”;
    ServiceReference item = new ServiceReference();
    item.Path = “~/SmartParts/C_TicketActivityLog/AJAXWebService.asmx”;
    service.Services.Add(item);
    this.Page.Controls.Add(service);

    I want to do this because I don’t want to convert my current usercontrols into “custom pages”, but if I do this dynamically it doesn’t work, do you know why?

    Thank you so much for your help always!!!

    Lyz.

  4. Elizabeth says:
    December 16, 2009 at 4:03 pm

    Sorry, I didn’t attach you the static code:

    And I need this on the “Page_Load” event, because we only have the “Load_Actions” in the CRM pages.

    Thank you Nico!!!

Leave a Reply

Click here to cancel reply.

Categories

  • Dojo (1)
  • Experiments (4)
  • Force.com (2)
  • Interesting (1)
  • Javascript (3)
  • MSCRM (1)
  • Programming (63)
  • Rant (3)
  • Saleslogix (41)
  • Tricks (8)
  • Uncategorized (32)

Post History

  • 2011
    • January (3)
    • February (2)
    • March (1)
  • 2010
    • January (3)
    • March (3)
    • April (2)
    • August (2)
    • October (4)
    • November (1)
    • December (2)
  • 2009
    • March (2)
    • April (1)
    • May (3)
    • June (3)
    • July (1)
    • September (3)
    • October (2)
    • December (5)
  • 2008
    • January (9)
    • February (4)
    • March (9)
    • April (1)
    • May (5)
    • June (8)
    • July (1)
    • August (2)
    • September (1)
    • November (1)
    • December (3)
  • 2007
    • January (3)
    • February (7)
    • March (1)
    • April (3)
    • May (6)
    • June (2)
    • July (1)
    • August (2)
    • September (5)
    • October (3)
    • November (5)
    • December (4)
  • 2006
    • January (2)
    • September (1)
    • November (3)
    • December (4)
  • 2005
    • April (1)

Meta

  • Log in
  • Entries RSS
  • Comments RSS
  • WordPress.org
rss Comments rss valid xhtml 1.1 design by jide powered by Wordpress get firefox