Step by Step Guide to Custom Form Development with Visual Studio
Posted By: nicocrm on December 15th, 2009 in Uncategorized
No Gravatar

I think I just made the longest post ever on the SalesLogix Journal. It is a fairly complete guide on how to get started writing custom smart parts for SalesLogix in Visual Studio. I think it is a bit scary to get started with those but it is a must to provide rich functionality (for better or worse – but I think it is a good thing that Sage is not trying to cram every possible functionality into the QuickForms – their job is not to create a Visual Studio replacement!!)

Anyway, I might start writing most of the SalesLogix content through that channel so this blog does not look so much like a SalesLogix reference guide :)


How to refresh tabs, from the client side (SalesLogix 7.5.2)
Posted By: nicocrm on December 11th, 2009 in Saleslogix
No Gravatar

As part of the many performance enhancement brought by this latest service pack, tabs are no longer automatically refreshing when a dialog closes. I think we can all agree that the gained performance is worth it :) But this has a few consequences:

  • First of all, if you are using a quickform as an insert form, you are all good. Yes, this is one of these cases where using a quickform actually paid off! Congratulate yourself for the good choice.
  • If you are using a custom smart part processed on the server side, it is quite straightforward, but requires a manual addition of this little piece of code to your server side script (right before or after closing the dialog):

    PanelRefresh.RefreshTabWorkspace();
  • If you are using a client-side customization (and I do use those once in a while for interactive or time-consuming processes), it is only slightly more complex – you need to trigger a refresh from the client side. Assuming you are closing the dialog with this type of code:
    DialogWorkspace._dialog.close();

    In that case I had to use a slight subterfuge to get the panel to refresh correctly. I added a hidden (server-side) button on the page:

    <asp:Button runat="server" ID="btnProcessServer" CssClass="btnProcess_server" style="display: none" />

    And then in the code-behind:

    /// <summary>
    /// This is called by the Javascript when processing is complete.
    /// Close the dialog, and ensure tab is refreshed.
    /// </summary>
    /// <param name="sender"></param>
    /// <param name="e"></param>
    void btnProcessServer_Click(object sender, EventArgs e)
    {
        DialogService.CloseEventHappened(sender, e);
        PanelRefresh.RefreshTabWorkspace();
    }

    Finally I just had to replace my javascript with the following to cause a postback and have the dialog closed from the code-behind from the button:

    $(".btnProcess_Server").click();

    Note that I am using the CSS class instead of the id, as the id is going to be transformed a bit by ASP.NET. It’s a bit of a cheat. There might be a creative way to do it entirely from client side, using the window.TabControl object (a reference to the tab workspace), however experience taught me creatively discovering hidden Sage Javascript API is a good way to waste my afternoon (and also get my butt kicked during upgrades!)


Automatically importing default SalesLogix namespaces for C# code snippets
Posted By: nicocrm on December 8th, 2009 in Saleslogix
No Gravatar

When working on web client forms you may have seen this error:


e:\inetpub\wwwroot\PhysicianLiaison\SlxClient\SmartParts\Contact\ContactDetails.ascx(678): error CS0246: The type or namespace name 'IContact' could not be found (are you missing a using directive or an assembly reference?)

For example this happens when you use an unqualified reference in a C# code snippet, such as:


var myContact = (IContact)BindingSource.Current

You can’t add a “using” statement so the work around is to qualify all references:


var myContact = (Sage.Entity.Interfaces.IContact)BindingSource.Current

To save on the typing, you can add a default import to your web.config file. Simply do a search for “<pages>” and add the following under that tag (or if you don’t see a <pages> tag at all, add it under <system.web>):


<namespaces>
<add namespace="Sage.Entity.Interfaces"/>
</namespaces>

Of course this can be used with your custom namespaces as well. If you are using extension methods to define business rules (as explained in Easy Business Rules with Extension Methods) it will let you use those too.


Make sure you disable debugging in production!
Posted By: nicocrm on December 2nd, 2009 in Saleslogix
No Gravatar

Here is a quickie… Several times I have made the mistake of shipping a web.config with debugging enabled (fortunately always caught it at the last minute so far). This has a horrible affect on performance because it prevents caching. It can also cause some serious memory issues under heavy load. So I made myself a big warning on the login page:

Big old warning

The code for it looks like this (in Login.aspx):

    </asp:Login>
    <asp:Label style="clear: both; display: block; width: 100%; text-align: center; color: red; font-size: 24pt" runat="server" id="lblDebugWarning"
                Text="Debugging Enabled in web.config - Set to False for Production" />
</asp:Content>

And under Page_Load, very simple:

    protected void Page_Load(object sender, EventArgs e)
    {
        lblDebugWarning.Visible = HttpContext.Current.IsDebuggingEnabled;
        System.Web.UI.WebControls.CheckBox rememberMe = (System.Web.UI.WebControls.CheckBox)slxLogin.Controls[0].FindControl("chkRememberMe");

By the way it slightly funks up the display for IE6 – but only when the label is actually displayed, so not a big deal.