Using jQuery in Oracle CPQ
Overview
What
jQuery is a fast and concise JavaScript Library that simplifies HTML document traversing, event handling, animating, and Ajax interactions for rapid web development. jQuery is designed to change the way that you write JavaScript.
Why
Adding custom JavaScript to a site at all is risky. Before adding a custom JavaScript solution, make sure that you have performed a proper risk assessment. Everyone involved in the project needs to be aware of the maintenance issues that customized development causes before moving forward.
Once the decision to use JavaScript has been made, we recommend using jQuery to perform any necessary DOM operations.
Proper use of jQuery can make your code more robust and safer, and also help deal with cross-browser compatibility issues.
Where
JavaScript should only be put in the Oracle CPQ JavaScript Framework. This means that you will be writing your code in the File Manager. jQuery 1.4.2 is available in Oracle CPQ in the following places:
- Home Page
- Parts Search
- Configuration
-
Commerce Quotes
- jQuery is not available on the admin side. Invoking jQuery directly from a site-wide context will cause errors in the Oracle CPQ application.
- The worst place to put JavaScript is directly in the header and footer.
- Code spread across a large number of HTML/Read Only Attributes is very hard to maintain.
Administration
How
Before you begin
This is not a tutorial in use of jQuery, but just a discussion of best practices when using it within CPQ. For a tutorial on jQuery, visit the jQuery home page at: .
Learn JavaScript
jQuery is not a replacement for JavaScript, and will not protect you from many common JavaScript errors. We recommend as a resource for learning JavaScript.
Communicate
A lot of times you will be able to do things with JavaScript that work in the immediate term, even though the solution is brittle, flimsy, and dangerous. If, as an engineer, you come across this, communicate it upwards as clearly as possible. Make sure that everyone involved knows exactly what the risks and issues with the solution are. Initiate a discussion to find an alternate solution.
Be aware that JavaScript development calls for extra rigor and attention. Take your time and do it right. Custom JavaScript is time consuming and difficult enough to maintain already.
Use jQuery, not $
The $ symbol is used by a number of different libraries, and is not safe to use directly in CPQ. If you want to, you can map the globally available jQuery to a scoped variable:
function($) {
//$ is safe to use here
}(jQuery);
function my_function() {
var $ = jQuery;
//$ is safe to use here
}
Cache jQuery objects
The following code example crawls the DOM several times to find a form and some of its inputs:
(function() {
function crawl() {
var action, method, country;
action = jQuery("form.my-class").attr("action");
method = jQuery("form.my-class").attr("method");
country = jQuery("input[name='country']").val();
}
}());
The problem with this code is that it unnecessarily crawls the DOM over and over - sometimes for the same element. A cleaner and faster way to accomplish this task is to cache the jQuery objects ahead of time:
(function() {
function crawl_less(){
var action, method, country, $form;
// dollar sign prefix is a convention for jQuery objects
$form = jQuery("form.my-class");
action = $form.attr("action");
method = $form.attr("method");
// passing "$form" as a parameter, this limits the search
// to the selected form, rather than the whole document
country = jQuery("input[name='country']", $form).val();
}
}());
Beware of complicated selectors
There are times when the only way to select an element that is nested within a table in Oracle CPQ is to use a convoluted selector. For instance, you might see something like:
var $element = jQuery("table:first td.form-input:last").parent().parent().parent().parent().parent();
These kind of selectors are especially flimsy and dangerous to use. It is very difficult to predict what the DOM will look like in future versions of CPQ, and code that is heavily reliant on it will be difficult to fix when an upgrade rolls around. Take the following steps to mitigate this problem:
- Use descriptive variable names.
- Document your intentions well with your comments.
-
Wrap the complicated selectors in their own functions.
(function() {
// the function name gives me a hint what we're selecting
var get_array_part_column = function() {
return jQuery("table:first td.form-input:last").parent().parent().parent().parent().parent();
}
//fires when the page is loaded
jQuery(document).ready(function() {
// cache into descriptive variable name
var $part_number = get_array_part_column();
});
}());
Troubleshooting
My code doesn't always run
If you find that your code intermittently fails to run, it's possible that it is actually running before the page is loaded, so your selectors don't find anything. Make sure that you are taking advantage of jQuery.ready. This is your way to guarantee that the page has been loaded entirely before running your code.
Things are happening out of order
Watch out for asynchronous events in JavaScript. A common mistake looks like this:
(function() {
function ajax_call() {
var done;
jQuery.get("http://google.com/", null, function() {
done = true;
});
return done;
}
alert(ajax_call());
}());
If you run this code, it will always appear as "undefined". The reason is that jQuery.get is asynchronous: it runs in a separate thread and won't be executed in time to populate the "done" variable before alert is called. Once you recognize this you can write your code to take advantage of it:
(function() {
function ajax_call() {
jQuery.get("http://google.com/", null, function() {
when_done(true);
});
}
function when_done(value) {
alert(value);
}
ajax_call();
}());
Animation, AJAX, and some other jQuery functions are asynchronous and might surprise you if you expect everything to run in order.
Related Topics
See Also