SalesLogix 8 – Dialog Action on Form Load
Posted By: Alex.Cottner on June 25th, 2013 in Dojo, Javascript, Saleslogix
No Gravatar

I ran into an issue last week where I needed to load a dialog window in a quickform load action in SalesLogix 8.0 web. In 7.5.4 this wasn’t an issue and it worked fine using the normal method or a C# code snippet. However in 8.0 the dialog windows were never showing up, probably because it was trying to load them before dojo was finished initializing. Solving this was pretty simple but may not be straight forward for anybody who isn’t familiar with Dojo, so I thought it would be nice to post an example.
(more…)


Adding Keyboard Input to Dojo Select Controls (dijit.form.select)
Posted By: Alex.Cottner on November 15th, 2012 in Dojo, General, Javascript
No Gravatar

I ran into a situation yesterday where I needed to extend the functionality of the dijit.form.select control so it could have proper keyboard input. Power users want to be able to tab through their forms and use the keyboard to get work done quickly. The stock select control from dojo only allows for use with a mouse and some pretty basic keyboard input. To change this, I just needed to override a couple methods on my controls and setup a new property.

Here is an example creating a new select control.
(more…)


Defaulting Picklists in the SLX Mobile Client
Posted By: Alex.Cottner on October 1st, 2012 in General, Javascript, SLX Mobile
No Gravatar

I had a request that required me to default several picklist fields throughout the SLX Mobile client. Normally this would mean hard coding the fields to populate with a certain value. But I wanted the client to be able to manage their default picklists values by marking items as “Default” in the client, just like they always have. After looking at the picklist control I realized this was actually pretty simple to do. All I needed to do was add a couple methods to the picklist object to pull down and set the default values, then I could call this from the “applyContext” methods on the forms I wanted this on.
(more…)


Developing on the New Sage SalesLogix Mobile – Completing an Unscheduled Activity
Posted By: Alex.Cottner on September 28th, 2011 in General, Javascript, Programming, Saleslogix
No Gravatar

One of the big pushes in technology in this day and age are mobile and tablet applications. The new mobile client Sage SalesLogix offers is built for just that. It is built off of HTML5 and works hand-in-hand with their SData feeds.

In this post I am going to demonstrate a functionality request that we receive from a lot of our users.

Completing an Unscheduled Activity

One of the most frustrating things for end-users is the amount of clicks they have to do to complete a certain task regardless of what software or web site they are using. In this example if a user wanted to complete an unscheduled meeting with a contact in the new mobile client they would first have to:
(more…)


Enhancing a lengthy process with a progress bar
Posted By: nicocrm on January 29th, 2011 in Javascript, Programming, Saleslogix
No Gravatar

At any time we need to perform a lengthy process such as an import or a batch update, one of the elements necessary to provide a good user experience will be to give them a feedback on the progress. I have experimented with a few of them and wanted to show the one that I have found the most versatile and easy to implement.

First of all note that if you have a lengthy process you will need to configure the request timeout in the web.config. It would be something like (assuming your page is called Import.aspx):

<location path="Import.aspx">
  <system.web>
    <httpRuntime executionTimeout="3600" />
  </system.web>
</location>

Also, do take a look at the note on potential performance problems, at the end of this post.

Now, a quick review of the options:

  • There is a progress bar control called RadProgressManager which is actually included as part of SalesLogix (they use it in the lead import screen). It works relatively well once you have it configured properly but I have found a few challenges when trying to use it. First of all, it works by polling, which means it makes repeated requests to the page to find out the progress – this is relatively inefficient, though usually not a big concern. Secondly, the control takes some work to properly configure – it is rather sensitive to the order in which components are loaded, where it is placed respectively to the update panels, whether the postback is asynchronous or not, etc. If everything is not “just right” it will fail, often with an obscure error message (or no message at all). Thirdly, the default look is absolutely hideous, so you usually have to replace the whole thing with a custom template – quite a bit of work. Finally it gives little options other than just reporting a progress percentage and a step description, so if you want to for example report errors as they happen you may be out of luck. For these reasons I have not used it very often.
  • One other way is doing repeated refresh of the page (or just the update panel that contains the progress bar) to refresh the status. This works pretty well if the processing happens on a separate service (other than being inefficient as it requires a reload every time) but not if it is done on the same page of course as it would not be able to reload itself until the process was finished! Note that you can’t do the process on a handler and refresh the page either, as a page in SalesLogix always requires an exclusive access to the session.
  • Finally there is an option recently called “pushlet” but which was already used years ago before Javascript even came of age. The idea is to post the data to the page which does the process, but instead of reporting the process “out of band” it just writes it out as it happens. Now, the idea is that instead of just writing the process to a blank screen, this page outputs a snippet of Javascript which gets executed and (via the method of your choosing) reports a progress or an error. The advantages are that it uses only one connection unlike the previous 2, reports the progress in real-time (unlike the other ones which will have a lag imposed by the polling rate), offers complete control of the UI, and is rather easy to implement, even more so if the UI is driven mostly from Javascript.

So, the basic concept of the “pushlet” is to post the form’s data into a hidden iframe. This can be done either by setting the SRC of the iframe (if no post data is required), by stuffing the form’s data into a form on the iframe itself and posting it, or by setting the TARGET of the current page’s form and posting it. The last one is most powerful as it will let you post files, but unfortunately also a bit more complex as you have to fight with ASP.NET to obtain a reference to the form and make sure you don’t interfere with the rest of the page. Here is a post that describes it though, and by a happy coincidence was posted right after I finished this one: Changing an HTML Form’s Target with jQuery – it’s for a vanilla ASP.NET scenario but should mostly apply to SalesLogix as well. An example of the second method, which works well enough as long as there is no need to upload a file:

var root = document.getElementById("bulkRequestSubmitFrame");
var rootDoc = root.contentDocument || root.contentWindow.document;
var baseUrl = location.href.replace(new RegExp("/[^/]*$"), "");
var url =  baseUrl + "/SmartParts/LitRequest/LitRequestBulkSubmit.ashx";
var scriptParts = [];
var doc = rootDoc.createDocumentFragment();
function createElement(tagName, attrs) {
	var elem = document.createElement(tagName);
	for (var a in attrs) {
		elem[a] = attrs[a];
	}
	return elem;
}

// this is the actual form data
doc.appendChild(createElement("input", { name: 'submission', value: Ext.util.JSON.encode(submission) }));
doc.appendChild(createElement("input", { name: 'itemSelection', value: Ext.util.JSON.encode(itemSelection) }));

rootDoc.body.innerHTML = "<form id='theform' action='" + url + "' method='POST'></form>";
var form = rootDoc.getElementById('theform');
form.appendChild(doc);
form.submit();

As the handler for the form processes the data, it will output snippets of javascript, such as:

<script type="text/javascript">
parent.reportSubmissionProgress(50);
</script>

Or to report an error:

<script type="text/javascript>
parent.reportSubmissionError("Unable to process contact id XYZ");
</script>

And the final piece on the client side is how to report the progress – this is made easy by the fact that ExtJS includes a decent-looking progress bar:

  • To initialize it:
  • _percent = 0;
    _errorText = "";
    _progressText = "Contacting server...";
    _progress = Ext.MessageBox.show({
      title: "Sync Progress",
      width: $(window).width() * .6,
      progress: true,
      progressText: _progressText
    });
    
  • To report progress:
  • function reportSubmissionProgress(percent, description){
      _percent = percent / 100;  // Ext % goes from 0 to 1
      _progressText = description;
      Ext.MessageBox.updateProgress(percent, description);
    }
    
  • To report an error:
  • function reportSubmissionError(error){
      _errorText += (error + "
    "); Ext.MessageBox.updateProgress(_percent, _progressText, _errorText); }
  • And finally to hide it:
  • function reportSubmissionComplete() {
      Ext.MessageBox.hide();
    }
    // this will ensure the progress bar gets hidden once the iframe finishes loading
    document.getElementById("bulkRequestSubmitFrame").onload = reportSubmissionComplete;
    

    It looks like this:

    Progress Bar

    The last piece of the puzzle is the handler on the server side, but this is also the easiest one. You can use a generic ASP.NET handler (ASHX) and just make sure you turn off buffering (context.Response.Buffer = false) and set an HTML content type (context.Response.ContentType = “text/html”) then use context.Response.Write to report the progress… to test it out, try something like:

    public class TestHandler : IHttpHandler, IReadOnlySessionState
    {
      public bool IsReusable { get { return false; } }
      public void ProcessRequest(HttpContext context) {
        context.Response.ContentType = "text/html";
        context.Response.Buffer = false;
        for(int i=0; i < 100; i++){
          context.Response.Write(String.Format(@"<script type='text/javascript'>
              parent.reportSubmissionProgress({0}, 'Reporting progress {0}...');
          </script>", i));
          Thread.Sleep(300);
        }
        context.Response.Write(@"<script type='text/javascript'>
             parent.reportSubmissionComplete();
          </script>");
      }
    }
    

    That's about it. It ends up being a good fit if you already have some javascript to drive some of the UI on your page. It's quite flexible and the way it works makes it easy to understand and troubleshoot using a tool like Fiddler or Firebug.

    Remember that if the process is really lengthy, or if it is likely that many people will be doing it at the same time, you'll want to do that outside of the web client, because it will consume an ASP.NET thread and a connection handle as long as that connection is open. Then you have to use a separate service and use a polling mechanism to check on the progress, otherwise your server will grind to a halt as all its processes are stuck serving users - FYI, yes, this is based on first-hand experience. I recommend reading Improving ASP.NET Performance on the Microsoft P&P site, especially the section on threading (the whole thing is worth a read though).