Using jQuery in Oracle CPQ

Overview

ClosedWhat

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.


ClosedWhy

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.


ClosedWhere

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:


Administration

How

ClosedBefore 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: http://jQuery.com.


ClosedLearn JavaScript

jQuery is not a replacement for JavaScript, and will not protect you from many common JavaScript errors. We recommend http://eloquentjavascript.net as a resource for learning JavaScript.


ClosedCommunicate

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.


ClosedUse 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

}


ClosedCache 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();

}

}());


ClosedBeware 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:

  1. Use descriptive variable names.
  2. Document your intentions well with your comments.
  3. 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

ClosedMy 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.


ClosedThings 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

Related Topics Link IconSee Also