Table of Contents
What is jQuery?
Why Use jQuery and Sage CRM?
Get Started with jQuery and Sage CRM
Build a Simple jQuery and Sage CRM Example
Use DOM Traversal with jQuery for Sage CRM
Learn DOM Manipulation with jQuery for Sage CRM
Conduct Event Handling using jQuery for Sage CRM
What is jQuery?
From jquery.com: “jQuery is a fast and concise JavaScript Library that simplifies HTML document traversing, event handling, animation and Ajax interactions for rapid web development. jQuery is designed to change the way that you write JavaScript.”
So what does this mean?
jQuery is a JavaScript framework intended to make developers lives easier when writing JavaScript by simplifying a lot of mundane tasks which are usually riddled with cross-browser compatibility ‘hacks’. This results in more development time and decreases overall productivity.
jQuery won’t write code for you but it will do a lot of the work and, with the myriad of available plug-ins, will simplify the process for you.
Are there any royalties or fees associated with using jQuery?
No.
The jQuery project is part of the Software Freedom Conservancy, a non-profit dedicated to providing a home for Open Source software. jQuery is free to download and redistribute under the MIT License or GPL
What’s in jQuery?
jQuery is full of so many useful functions and methods there is no way we could cover them all in our overview, so in the interest of brevity we will pick out a couple of our favorites.
For a full list of available functions and methods you can visit jQuery Documentation.
Selectors
Our favorite thing about jQuery is the selectors. They make life so much easier when coping with some of the quarks of identifying fields on screen in Sage CRM. Sometimes Sage CRM will output both the name and id attributes of fields and other times it will only output the name and not the id attribute.
The selectors in jQuery allow you to select an element or group of elements based on any attribute you want. You can also use functions like ‘Starts With’, ‘Ends With’ or ‘Contains’ to save time.
Here’s an example:
Let’s say we have a button on the screen that needs a location change based on the result of an Ajax post. Normally, you would need to write a code similar to the following (assumes the new URL is stored in a variable named NewURL):
var elems = document.getElementsByTagName(‘a’); for(I = 0; I <= elems.length; i++){ if (String(elems[i].href).indexOf(‘mypage.asp’) >= 0) elems[i].href = NewURL; } }
While this example does not appear too daunting, keep in mind the cumbersome alternative.
Now, let’s take a look at how we can accomplish the same thing using jQuerys selectors (assumes the new URL is stored in a variable named NewURL):
$('a[href*="mypage.asp"]').attr('href', NewURL);
As you can see, our code has been greatly simplified and required a lot less coding than the previous example.
Plug-ins
jQuery limitations are rapidly being bridged by countless available plug-ins. jQuery UI is a great example that adds a lot of nice features to an already robust set including:
- Dialog A wonderful method for turning any div into either a regular dialog or modal dialog.
- Resizable Allows you to resize any element.
- Accordion Allows you to expand and collapse divs when the header is clicked.
- Datepicker Allows you to turn any textbox into a date selector with a wonderfully customizable calendar control.
For more information head over to jQuery.com or to see examples of how to use jQuery inside of Sage CRM you can read the examples on this page or on our jQuery Showcase for Sage CRM page.
Return to Top
Why Use jQuery and Sage CRM development?
jQuery is an elegant JavaScript library that greatly simplifies client-side web development — use jQuery for Sage CRM development.
Are you still using raw JavaScript for your client-side CRM customizations? If so, you definitely want to consider using jQuery for Sage CRM development.
Pardon the cliché but jQuery may very well be the best thing since sliced bread. In fact, I’m happy to slice my own bread so long as I can continue using jQuery.
If you’re not utilizing jQuery, you’re missing out on what is quite realistically the best productivity enhancer available for client-side development.
On this page, we explore several key areas of jQuery:
- selectors,
- DOM manipulation,
- node traversal,
- event handling, and
- other miscellaneous topics.
Our goal is to give you everything you need to leverage jQuery in your Sage CRM customizations.
Write Less, Do More
There is much to love about jQuery. Here are just a few reasons why you should consider leveraging jQuery within your CRM customizations.
- jQuery is included in Sage CRM – CRM pages automatically reference the jQuery library as of version 7.1. Because of this, jQuery can be used within the custom content of a screen, for instance, without any additional legwork.
- jQuery is free! – JQuery is 100% free to use in your Sage CRM customizations or any other development project. Thank you, John Resig!
- jQuery is an open book – you’re free to download the raw source code from http://jquery.com/ to investigate jQuery’s inner workings. The source code is great for understanding what jQuery does behind the scenes but is also a fantastic code base to learn from. For your customizations, simply use the minified version automatically referenced by Sage CRM for increased performance.
- jQuery has exceptional documentation – JQuery has some of the best documentation available and I find myself consulting it regularly. I highly recommend you spend some time perusing the available functions. The documentation can be viewed here: http://api.jquery.com/.
- jQuery is cross-browser – if you’ve spent any time at all developing web-based solutions, you are painfully aware of the inconsistencies between browsers. jQuery allows us to work with concise, sensibly named functions while browser quirks are automatically handled for us behind the scenes.
- jQuery is extensible – as of this moment, there are hundreds if not thousands of jQuery plugins available for use in your Sage CRM customizations. You can check out the jQuery Plugins site here: http://plugins.jquery.com/. You will also find many unofficial plugins scattered throughout the Internet.
- jQuery has a huge community – contributors far and wide develop plugins, create tutorials, answer questions, write blogs, and so on. This makes learning and using jQuery a breeze.
jQuery Exposed
As expressed above, you can learn a lot by investigating jQuery’s source code. If this is of interest to you, one option is to download the source code from http://jquery.com/. Another option is to use a jQuery source viewer. My viewer of choice is by James Padolsey and located at http://james.padolsey.com/jquery/.
Simply select the jQuery version of interest, enter the function name (e.g. post, ajax, hide, show, addClass, etc.), and hit Enter.
Return to Top
How to Get Started with jQuery and Sage CRM Development
For demonstration purposes, we have created a shared JSFiddle which can be accessed at http://jsfiddle.net/cburriss/ULAyY/7/. You may also reference the screenshot below.
In this example, the textbox’s content will automatically convert to title case as you type. If you were to type “tHiS is MY test”, the textbox content would change to “This Is My Test”. If you were to recreate this functionality with raw JavaScript, the code would be much longer and much less readable. With jQuery, the solution is concise and elegant.
The Code Explained
- $ – the dollar symbol is the most common way to access the jQuery object. You may also use the word jQuery as in jQuery(document).ready(function() { }).
- $(document).ready(function() { }) – all jQuery functionality should be used within this function. The anonymous function passed into the ready function will be called once the DOM is ready for manipulation. Images and such may still be downloading which makes this a better option than using the Load event provided by browsers. This is because the load event isn’t fired until all images have been received.
- $(‘#test’) – jQuery is based on selectors. Selectors are simply text expressions indicating which elements should be selected within the DOM. Most of jQuery’s selectors were borrowed from Cascading Style Sheets (CSS), which also uses selectors. $(selector) will return zero or more elements that match the selector expression. From here, you are able to interact with these elements. In this example, an ID selector is used to find any elements where the ID is equal to test. We will cover selectors in detail in the next article
- $(‘#test’).keyup(function(e) { } ) – this is an example of event binding. In this case, we’re binding a keyup event to the element with an ID of test (i.e. the textbox). This means that each time a key is pressed and released while the textbox has focus, the event function will be fired with details such as the key that was released.
- this – when inside of a jQuery function, the active element can always be accessed via the this keyword. Note that this is a raw DOM object. To apply jQuery functions to the element, it must be wrapped in the jQuery object like $(this).
- $(this).val() – val is a jQuery function that gets or sets the value of an element. If no parameter is passed into the function, it returns the element’s value. If a value is passed as a parameter, the value is set for the matching elements.
SayGoodbye();
Though we have merely touched upon the most basic parts of jQuery’s vast library, we hope it is becoming apparent how useful jQuery can be.
Client-side scripting can be a pain but jQuery actually makes it fun. jQuery is elegant, concise, powerful, and easy to use all at the same time.
Once you have a good handle on jQuery, don’t be surprised if you’re able to complete client-side scripting 2X as fast (or faster).
Return to Top
How to Build a Simple jQuery and Sage CRM Example
In the first section, you were introduced to jQuery as a JavaScript library that has revolutionized client-side development … and Sage CRM is no exception! Moving forward, we’ll explore key facets of the jQuery framework – selectors, DOM traversal, DOM manipulation, and event handling.
In this section, we’ll demonstrate the most common jQuery selectors using a simple snippet of HTML.
Then we’ll put this newfound knowledge to good use by implementing a common request – colorizing a CRM screen field based upon its value. The screenshot illustrates what we’ll accomplish by the end of this article.
Selector What?
At the heart of jQuery, in all of its awesomeness, is the concept of selectors.
Aptly named, selectors are what allow us to select a collection of DOM elements using a concise expression. Since we can’t do useful things until we have selected some DOM objects to do stuff with, selectors are the 1st thing you must learn in order to harness the power of jQuery in your CRM customizations.
TIP: for the full range of selectors, jQuery’s documentation (http://api.jquery.com/category/selectors/) is an excellent reference and one I advise you consult frequently!
Selecting a jQuery Selector
To interact with the demo, you can check out the JSFiddle at: http://jsfiddle.net/cburriss/WwqDZ/9/. Here’s the simple HTML we’ll use our selectors against
<div id="outerDiv" class="divClass1"> <div id="innerDiv1"><input id="input1" class="inputClass1" type="text" /> <input id="input2" class="inputClass2" type="text" /></div> <div id="innerDiv2"><input id="input3" class="inputClass1" type="text" /> <input id="input4" class="inputClass2" type="text" /></div> <input id="input5" class="inputClass3" type="text" /> </div> <input id="input6" class="inputClass3" type="text" />
Alright, let’s select some DOM elements!
- $(“#input100”) – this is an ID selector. Simply precede an HTML ID with the # symbol and pass it into the jQuery object (i.e. $) as a string. In the case of this example, 0 elements will be returned. Use the length property of the results to determine if an element was returned or not. In this instance, the length will be 0.
TIP: use the ID selector when possible as it has the fastest execution of all selectors. - $(“.inputClass2”) – this is a class selector and will return all elements that have the inputClass2 class. Simply precede the class name with a period just like when defining a CSS class. In this example, elements input2 and input4 are returned.
TIP: keep in mind that any DOM element that meets the selector criteria at the time of execution will be returned, which may or may not match the original HTML source. For instance, if inputClass2 was added to input1 after the page was loaded, input1 would also be returned when using this specific selector. - $(“input”) – this is a tag selector and will return any element that has an HTML tag of input. The selector is simply the tag name. In this case, we have several elements returned: input1, input2, input3, input4, input5, and input6.
- $(“div > div > .inputClass1”) – this is illustrative of a “child selector”… two actually. This selector can be read as “return any element that has the CSS class inputClass1 and is a direct descendant of a div element that is also itself the direct descendant of a div element.” In this case, input1 and input3 are returned.
- $(“div input”) – this demonstrates a “descendant selector” and returns all input elements except for input6 which is not a descendent of a div element. This selector can be read as “return any element that is an input tag and is a child element of a div element anywhere in the DOM hierarchy.”
- $(“div[name=’outerDiv’], *[id^=’input’], *[id$=’1′]”) – first note that multiple selectors can be combined in a single expression by delimiting them with commas. In this case, there are three selectors. This can be read as “a given DOM element is true for selector1 OR the DOM element is true for selector2 and so on…” If a DOM element meets the criteria for multiple selectors, only one instance of the element will be returned.
- $(“input:eq(1)”) – this is the index (or eq) selector. In this example, the selector can be read as “return the 2nd DOM element that is an input.” Hence, the returned element will be input2.
TIP: the index selector is zero-based. eq(0) is used to return the 1st element, eq(1) to return the 2nd element, etc.
These are also examples of attribute selectors. In the 1st case, we’re selecting for div elements where the name attribute equals outerDiv. The second selects for any DOM element where the id attribute starts with “input”. The third selects for any DOM element where the id attribute ends with “1”.
Lastly, note that there are several attribute comparisons that can be made. Common comparisons include equal to (=), not equal to (!=), starts with (^=), ends with ($=), contains (*=) and so on. For the full list of attribute selectors, see http://api.jquery.com/category/selectors/attribute-selectors/
An Opportunity for Improvement
Let’s suppose that adding some color to the opportunity certainty field based on its value would serve our sales team better. In this example, let’s assume that a certainty greater than or equal to 80% is good and should be green. If it’s 50% or less, it’s bad and should be red. Otherwise, it’s orange.
To start, we must investigate how the HTML is structured for the opportunity field on the Opportunity Summary tab. Doing a quick search in the HTML source reveals that the data value is stored in a hidden field with the attribute name equal to _HIDDENoppo_certainty. Also, the text itself is within a span element and has an ID attribute of _Dataoppo_certainty.
Considering this, add the following JavaScript to the OpportunityStatusBox screen’s content block. Once saved, opportunity certainty should be green, orange, or red based upon its value.
<script> $(document).ready(function() { var oppCertainty = $('input[name="_HIDDENoppo_certainty"]').val(); if (!isNaN(oppCertainty)) { var oppCertaintyValueText = $('#_Dataoppo_certainty'); if (oppCertainty >= 80) { oppCertaintyValueText.css('color', 'green'); } else if (oppCertainty < 80 && oppCertainty > 50) { oppCertaintyValueText.css('color', 'orange'); } else { oppCertaintyValueText.css('color', 'red'); ) } }); </script>
$(“#conclusion”)
That was easy, eh? This is the beauty of jQuery – it simplifies and unifies our interactions with the DOM. jQuery selectors have immense flexibility and will serve you well in navigating the treacherous waters that is Sage CRM development. Once you start down the road of jQuery development, you’ll likely never turn back. Take the path more frequently traveled (i.e. jQuery) for it will make all the difference.
Return to Top
How to Use jQuery for DOM Traversal in Sage CRM Development
In the previous sections, we explored jQuery as a JavaScript framework and how to select DOM elements via jQuery selectors. In this article, we will continue our discussion of jQuery by reviewing DOM traversal.
Sage CRM relies heavily on nested HTML tables making DOM traversal very tricky when using raw JavaScript. jQuery, on the other hand, has a number of functions to make DOM traversal within Sage CRM much easier.
We’ll start by reviewing common traversal techniques against a simple snippet of HTML. Then, we’ll address a common complaint among Sage CRM administrators – country and area codes are turned off within Administration > System > System Behavior yet these fields are still visible on the Phone/E-mail tabs.
Using a little jQuery magic, we’ll hide these fields from view as illustrated in the screenshot.
All this Traversing is Making Me Loopy
So that we’re clear, DOM traversal simply implies that we’re able to move around the DOM. In some cases, this implies iterating over a collection (e.g. the each function). In other cases, it implies using a pre-built function to locate DOM elements of interest (e.g. the parent or first functions).
TIP: for the full range of traversal features, the jQuery documentation has a dedicated category on DOM traversal (http://api.jquery.com/category/traversing/).
jQuery Ain’t DOM
To interact with the demo referenced here, you can check out the JSFiddle at http://jsfiddle.net/cburriss/EYgbc/6/. Here’s the simple HTML we’ll traverse.
<div id="outerDiv" class="divClass1"> <div id="innerDiv1"><input id="input1" class="inputClass1" type="text" /> <input id="input2" class="inputClass2" type="text" /></div> <div id="innerDiv2"><input id="input3" class="inputClass1" type="text" /> <input id="input4" class="inputClass2" type="text" /></div> <input id="input5" class="inputClass3" type="text" /> </div> <input id="input6" class="inputClass3" type="text" />
With prerequisites out of the way, let’s traverse some elements!
1. $(“input[id^=’input’]”) .each(…) – the each function is used to iterate over a collection of DOM elements returned from a jQuery selector. In the JSFiddle, the matching elements are printed out demonstrating that input1 through input6 were returned and made accessible on an individual basis.
The each function requires a function as a parameter. Optionally, you can include parameters within the function such as an index variable.
Of great importance, note that the element within an each iteration can be referenced via the this keyword. this is actually a raw DOM element. In other words, it doesn’t have any jQuery functionality. With jQuery, the element is converted to a jQuery object by using $(this). Passing a DOM element into the jQuery object is required to give the element jQuery superpowers.
2. $(“#outerDiv”).find(“input”) – the find function uses a selector expression to search the child elements for a jQuery object. In this case, we’re first selecting the outerDiv element. Then, we’re searching child elements for input elements. This example returns input1 through input5. Input6 is excluded since it is not a child element of outerDiv.
3. $(“#outerDiv”).find(“input”). first() / $(“#outerDiv”).find(“input”).last() – the first and last functions return the first and last element within the collection, respectively. Given this, first() returns input1 and last() returns input5.
4. $(“#outerDiv input”).first().next() / $(“#outerDiv input”).last().prev() – next returns the very next element within the hierarchy from the context of the jQuery object. prev returns the element before.
In the case, input2 is returned as it is the element immediately after input1 in the DOM hierarchy. The other example returns innerDiv2. If this comes as a surprise, pay special attention to the HTML in this demo. The last element within $(“#outerDiv input”) is input5 which is on the same DOM level as innerDiv2; input4 is actually a child of innerDiv2.
5. $(“#input4”).parent() – this function simply returns the parent of the jQuery object. innerDiv2 is the parent element of input4 and that’s exactly what is returned.
6. $(“#input2”).closest(“div.divClass1”) – the closest function is one my personal favorites when it comes to Sage CRM development. This function will traverse up the DOM hierarchy (relative to the jQuery object) and return the first (or closest, if you will) element meeting the selector criteria.
How might this be useful?
Consider that Sage CRM’s page structure is heavily reliant on nested HTML tables. With this in mind, it’s often necessary to select an element using a known caption or static attribute, and then traverse up the DOM tree to get at the element’s parent container (usually table, tr, or td).
To hide a page button on an OOTB page, for instance, we can select the button img by its href attribute then traverse up the DOM tree until we have the parent container in scope. From here, we can hide the container and the other page buttons will shift position as desired.
Hiding Phone Codes
Now that you have a handle on key traversal functions, let’s get back to issue at hand – we’ve disabled country and area codes in Sage CRM Administration but the fields are still visible on the Phone/E-mail tab! To overcome this nuisance, add the following JavaScript to the translation for the “Country” caption code.
<script> $(document).ready(function() { $('table.CONTENT').first().width(175) .find('tr').each(function () { $(this).find('td:eq(1)').hide().end() .find('td:eq(2)').hide(); }); }); </script>
$(“p”).last()
We feel compelled to say it again: jQuery is pretty darn amazing.
If you’re still not convinced, we challenge you to solve this same problem with raw JavaScript! DOM traversal is easily one of the most unproductive aspects of client-side development. With jQuery, this is no longer the case. All hail the mighty jQuery!
Return to Top
How to Use jQuery for DOM Manipulation in Sage CRM Development
In previous sections, we discussed the merits of using jQuery in Sage CRM customizations and touched upon jQuery selectors and DOM traversal. In this section, we will expand into the area of DOM manipulation.
This aspect of jQuery functionality refers to the programmatic modification of form values, page appearance, and the adding/removing of HTML elements within the DOM hierarchy.
Dynamic behavior such as this is really what drives modern, interactive user experiences within web applications. Fortunately, Sage CRM is no exception and you are free to use these techniques to make your CRM customizations even more valuable and user friendly.
A Little Magical Fairy Dust Goes a Long Way
To demonstrate the mystical power of DOM manipulation with jQuery, we’ll tackle an area of Sage CRM thought to be impossible to customize by most.
We will illustrate how to inject a new screen into the Company Summary tab while leaving all other functionality intact. For the sake of simplicity, this is a read-only screen that displays useful statistics such as # of people, # of open cases, and # of open opportunities associated with a given company.
jQuery is Manipulative… But in a Good Way
jQuery includes quite a bit of functionality around DOM manipulation.
Below, we’ve provided a brief description of the functions most likely to be of benefit in Sage CRM customizations. For a full list of available functions, the jQuery documentation includes a specific category on DOM manipulation. The documentation is located here: http://api.jquery.com/category/manipulation/.
-
1. $(‘#HtmlId’).addClass(‘MyCssClass’) – this function adds a CSS class (or classes) to the selected DOM elements. Similarly, removeClass() removes one or more CSS classes.
More than one CSS class can be added or removed by separating the class names with a space – e.g. addClass(‘Class1 Class2’).
2. $(‘#HtmlId’).css(‘width’), $(‘#HtmlId’).css(‘width’, ‘100px’) – the css() function gets or sets one or more CSS properties. To retrieve a CSS property’s value, simply pass the property name within the function. When setting property values, a single property can be set by passing the value as the 2nd parameter. Alternatively, multiple property values can be set by passing a JavaScript object with the property names and values – e.g. css({ width: ’100px’, color: ‘red’ }).
3. $(‘#HtmlId’).attr(‘’title’), $(‘#HtmlId’).attr(‘title’, ‘Click to execute.’) – the attr() function allows an attribute’s value to be retrieved or set. To retrieve the attribute value for a given DOM element, simply pass the attribute name as the 1st parameter. To set an attribute’s value, pass the value as the 2nd parameter. If the attribute doesn’t already exist on the element, it will be added.
TIP: Adding new attributes to an element – via attr() or prop() – can be useful to store metadata for a DOM element. For instance, a customization may involve an animation to expand/collapse an element. If the height isn’t automatic, for instance, the original height can be stored as an attribute/property before resizing to retain the height to return back to on element expansion.
4. $(‘#HtmlId’).val(),$(‘#HtmlId’).val(‘my new value’) – the val() function is used for form elements such as input, select and textarea to retrieve or set the value. In the case of a select (i.e. dropdown), val() can be used to change the dropdown value. The same goes for checkboxes and radio buttons.
5. text() & html() – these functions are used to set or retrieve the text or HTML of a DOM element. For instance, to overwrite the HTML of all DIV elements to include a paragraph of text, this would be used: $(‘div’).html(‘<p>This is my paragraph.</p>’). Text is very similar except that it treats the content as text instead of HTML. The differences are subtle so I advise reviewing the jQuery documentation for clarification when needed. As a general rule of thumb, use the HTML method if adding HTML content. If merely adding text to a span or div element, for instance, use the text approach.
6. append() & prepend() – use these functions to append or prepend HTML to the end of a DOM element. To inject a new table row as the first in a table, for example, this could be used: $(‘table’).prepend(‘<tr><td>I’m the 1st row</td></tr>’).
7. after() & before() – use these functions to inject HTML directly before or after a selected DOM element.
8. wrap() – this function is used wrap a particular DOM element with another. For instance, a span with ID MySpan could be wrapped with a div element like so: $( ‘#MySpan’).wrap( “<div id=”Wrapper”></div>” ).
9. clone() – this is a useful feature to copy an existing DOM element and its children. If needed, even event handlers and data can be copied. This function is very effective at cloning parts of a Sage CRM page, like in the code demonstration for this article.
Conquering CompanyBoxLong
With knowledge of DOM manipulation at our disposal, let’s add a read-only screen to the bottom of the Company Summary tab. Simply add the below code to the Custom Content block of the CompanyBoxLong screen.
For simplicity, this code uses hard-coded values for the company statistics. Outside of this demonstration, these values would need to be retrieved via an AJAX call. Our page on Sage CRM Ajaxification demonstrates how to accomplish this.
<script> $(document).ready(function () { // get table rows that make up existing Contact screen var rowForScreenTab = $("a.PANEREPEAT:contains('Contact')").closest('table').closest('tr'); var rowForScreenGap = rowForScreenTab.prev(); var rowForScreenContent = rowForScreenTab.next(); var rowForScreenBorder = rowForScreenContent.next(); // get table that holds screen rows var screenContainer = rowForScreenTab.closest('table'); // modify table rows before adding to DOM var rowForScreenGapMod = rowForScreenGap.clone(); var rowForScreenTabMod = rowForScreenTab.clone(); rowForScreenTabMod.find('a.PANEREPEAT').text('Company Statistics'); var rowForScreenContentMod = rowForScreenContent.clone(); rowForScreenContentMod.find('table.CONTENT > tbody') .html('<span># of People:</span> <span id="CountOfPeople"></span> <span># of Open Cases:</span> <span id="CountOfOpenCases"></span> <span># of Open Opportunities:</span> <span id="CountOfOpenOpportunities"></span> '); var rowForScreenBorderMod = rowForScreenBorder.clone(); // append HTML to the end of the selected element screenContainer.append(rowForScreenGapMod) .append(rowForScreenTabMod) .append(rowForScreenContentMod) .append(rowForScreenBorderMod); var contentTableCells = rowForScreenContentMod.find('td'); // apply CSS property contentTableCells.css('vertical-align', 'top'); // add CSS class contentTableCells.find('span:eq(0)').addClass('VIEWBOXCAPTION'); // set width - alternative to css('width', '100px') contentTableCells.find('span:eq(1)').addClass('VIEWBOX').width(100); // retrieve values via AJAX call - see https://www.azamba.com/sage-crm/sage-crm-and-ajax/ var countOfPeople = 5; var countOfOpenCases = 8; var countOfOpenOpps = 3; // change inner text; for input controls, use val() $('#CountOfPeople').text(countOfPeople); $('#CountOfOpenCases').text(countOfOpenCases); $('#CountOfOpenOpportunities').text(countOfOpenOpps); // apply CSS property for color if (countOfOpenCases <= 3) $('#CountOfOpenCases').css('color', 'green'); else $('#CountOfOpenCases').css('color', 'red'); if (countOfOpenOpps >= 3) $('#CountOfOpenOpportunities').css('color', 'green'); else $('#CountOfOpenOpportunities').css('color', 'red'); }); </script>
$(“p:last-child”).after()
When it comes to client-side development with raw JavaScript, we could go either way as to which is most painful – DOM traversal or DOM manipulation.
To the great fortune of web developers everywhere, jQuery has come to the rescue again and saved hundreds of thousands of computers from being tossed out the window. The cure for JavaScript-induced madness is now within your grasp!
Return to Top
How to Use jQuery for Event Handling in Sage CRM Development
In previous sections, we explored key facets of jQuery – DOM selection, traversal, and manipulation. In this section, we’ll introduce you to event handling in jQuery.
At the conclusion of this article, you’ll have everything you need to leverage jQuery in your CRM customizations.
Almost as Cool as a Hovercraft
In the last section, we demonstrated how to inject company statistics as a separate CRM screen on the Company Summary tab.
In this section, we’ll show the same information but not as a CRM screen. Instead, this information will only display when the mouse is “hovered” over the company name field (see screenshot below). Upon moving the cursor away from the company name field, the information will disappear.
With this approach, useful information can be shown on demand without consuming more real estate or redirecting the user to a different CRM page.
Hover behavior combines two events: “mouseenter” (i.e. when the mouse cursor is initially positioned over a DOM element) and “mouseleave” (i.e. when the mouse cursor is initially moved off of a DOM element). These two are a small sampling of the various events that can be fired within a web page.
This is a Public Service Announcement
“Events” are notifications that occur from various actions – from the browser, user, or code – that can be subscribed within code.
To subscribe to an event, a “listener” is added which binds one or more functions to a particular event. When the event occurs, all listeners are notified and the associated functions are executed.
In the case of client-side development, there are pre-defined events for window, form, keyboard, and mouse among others. Like in other languages, it’s also possible to add custom events. Also, of great use, events can be triggered via code; this can be used to emulate the user clicking a button with their mouse, for instance.
Is Anyone Listening?
As with everything else, jQuery excels in the area of event handling. Below are some of the key functions and objects related to events but there is much more available to you. The full list can be viewed in the jQuery documentation here: http://api.jquery.com/category/events/.
- $( “#HtmlId” ).on( “click”, myFunction) / $( “#HtmlId” ).off( “click”, myFunction) – on is the main jQuery function for adding an event listener. In this case, we’re binding a function (assigned to the variable myFunction) to the click event for an element with an ID of HtmlId. Upon clicking this DOM element (by the user or triggered via code), the function will be executed. The off function is used to remove the event listener.
- $( “#HtmlId” ).click(myFunction), $( “#HtmlId” ).dblclick(myFunction), $( “#HtmlId” ).focus(myFunction), etc. – jQuery provides many wrapper functions that serve as shortcuts to on/off for pre-defined events (see screenshot below). In the code example in the next section, on is being used to illustrate the general concept of event handling. Outside of this example, I prefer using the shortcut functions because it increases code readability.
- $(“#HtmlId”).click(function(event) { event.preventDefault(); … } – event.preventDefault() is used to prevent the default behavior of a DOM element. For instance, this would prevent clicked anchors from taking the browser to a new URL. As a general rule of thumb, it’s a good idea to add this to the top of your event handler when you’re not unsure if default behavior will cause unintended consequences.
- $(“#HtmlId”).click(function(event) { event.stopPropagation(); … } – event.stopPropagation() is used stop propagation of an event. For instance, if you have several nested elements with click events, you may not want the parent elements’ click events to be fired when the inner element is clicked. In this case, event.stopPropagation() would be used to prevent the event from “bubbling”.
- Event object – all jQuery event functions support an optional event object passed as a parameter. The event object includes a number of useful properties describing the event itself. A few of the properties used most often are:
a. event.which –indicates the specific key or button that was pressed for key or mouse events.
b. event.type – indicates the type (e.g. click).
c. event.target – indicates which DOM element initiated the event.
d. event.pageX / event.pageY – indicates the mouse position relative to the top edge of the document.
e. Event.data – an optional object passed to an event method.
- $(“#HtmlId” ).trigger( “click” ) – the trigger function is used to invoke an event. For instance, a mouse click can be invoked via code.
- $( “#HtmlId” ).click(), $( “#HtmlId” ).dblclick(), $( “#HtmlId” ).focus() – when a function is not provided within a shortcut event function, the event is triggered on the selected DOM elements. Note the click below in the jQuery source code; if no arguments are present; trigger is executed.
Events in Action
Now that you have a handle on events (pun intended), let’s display a box with company statistics on mouseover, then remove it on mouseout. Simply add the below code to the Custom Content block of the CompanyBoxLong screen.
As before, this code uses hard-coded values for the company statistics. Outside of this demonstration, these values would need to be retrieved via an AJAX call. Our prior article on Sage CRM Ajaxification demonstrates how to accomplish this.
<script> $(document).ready(function() { // bind the "mouseenter" event handler; note the "event" parameter $('#_Captcomp_name').closest('td').on('mouseenter', function(event) { $(this).css('cursor', 'default'); var extraContentHtml = '<div id="extraContent"> <div class="VIEWBOX" style="font-weight: bold; border-bottom: 1px solid black; padding-bottom: 5px; margin-bottom: 5px;"> Company Stats</div> <table class="CONTENT" style="width: 100%;"> <tbody> <tr class="VIEWBOX"> <td><span style="font-weight: bold;"># of People:</span></td> <td style="align: right;"><span id="CountOfPeople"></span></td></tr> <tr class="VIEWBOX"><td> <span style="font-weight: bold;"># of Open Cases:</span></td> <td><span id="CountOfOpenCases"></span></td></tr> <tr class="VIEWBOX"> <td><span style="font-weight: bold;"># of Open Opps:</span></td> <td><span id="CountOfOpenOpportunities"></span></td> </tr></tbody> </table> </div>' $('body').append(extraContentHtml); // make an AJAX call here var countOfPeople = 5; var countOfOpenCases = 8; var countOfOpenOpps = 3; $('#CountOfPeople').text(countOfPeople); $('#CountOfOpenCases').text(countOfOpenCases); $('#CountOfOpenOpportunities').text(countOfOpenOpps); if (countOfOpenCases <= 3) $('#CountOfOpenCases').css('color', 'green'); else $('#CountOfOpenCases').css('color', 'red'); if (countOfOpenOpps >= 3) $('#CountOfOpenOpportunities').css('color', 'green'); else $('#CountOfOpenOpportunities').css('color', 'red'); // note the use of the event parameter $('#extraContent') .offset({ top: event.pageY, left: event.pageX}) .css({ 'width': '175px', 'padding': '10px', 'border': '1px solid gray', 'background-color': 'rgb(242,242,242)' }); }); // bind the "mouseleave" event handler $('#_Captcomp_name').closest('td').on('mouseleave', function() { $('#extraContent').remove(); }); }); </script>
$(“p:last-child”).trigger( “paragraphStarted” )
Congrats, you are well on your way to becoming a jQuery master!
This has been an exciting topic to share with you because jQuery provides such amazing possibilities for Sage CRM customizations. At the heart of modern client-side development is DOM selection, traversal, manipulation, event handling, and AJAX (covered on our page on Sage CRM Ajaxification).
These are the pillars of jQuery functionality and comprise everything you need to leverage jQuery in your CRM customizations.
For us, learning and using jQuery has provided an enormous boost in my productivity (and sanity). Not to mention, jQuery is fun to work with and makes it really easy to create better user experiences.
By putting what you’ve learned in this series to practice, we are fully confident your CRM development efforts will benefit just as ours have.