Overview
Once you have enabled the customizations feature, you can add client-side JavaScript and CSS to the application, use JS code and stylesheets to tweak the UI to your liking and to support your specific workflow and needs.
Introduction
This article attempts to serve as a quick start guide and explain how to write customizing JavaScript and CSS for FogBugz, considering the two types of FogBugz pages: Ocelot and "old UI".
Description
Enabling the FogBugz Customization feature
Customizations can be added only if the FogBugz customization feature is enabled for your instance, whether it is On-Demand or On-Premise. Please read this article about Enabling, Configuring, and Creating New Customizations for FogBugz.
Please also note the disclaimer mentioned in the article.
Writing the Customization
When writing your code for a FogBugz customization you can do it directly in FogBugz right after you added it as a new customization, or you can do it in a separate editor and once finished, copy it into FogBugz new customization editor.
Structure of the Customization Code
A FogBugz customization's code has three mandatory sections: the header, the JavaScript body (js:
), and the CSS body (cs:
). We recommend keeping this order of the sections when writing your customization's code.
The header and later sections must be formatted correctly to save the customization.
Header
Each customization has a header where you set the name, description, author, and version:
name: A Quick Thing description: This script does X, Y and Z author: Ada Lovelace version: 1.1.0.0
The name and description are mandatory items, and must be changed from the default “Customization” and “Does not do anything,” which FogBugz fills in for you.
The heading section is mandatory and should be always the first section within the code.
We recommend adding also the version and author, just for traceability.
Body - JavaScript and CSS
After the header, there is a section for JavaScript code and one for CSS code.
The start of the JavaScript section is marked by js:
.
The start of the CSS section is marked by css:
.
It is not mandatory to have both sections present, and also not mandatory to have code if a marker is present.
Within the different sections (JavaScript and CSS), make sure you use the valid syntax for each type. For example, the JavaScript section allows comments using // this formatting
, but make sure to wrap your CSS comments in /* the correct characters */
.
Sample Code
js: // re-name the "Wiki" drop-down to "Wikis" $(function() { var isOcelot = function() { return (typeof fb.config != 'undefined'); }; var changeIt = function() { $('li.wiki.dropdown a.section-link').text("Wikis"); } if (isOcelot()) { fb.pubsub.subscribe({ '/nav/end': function(event) { changeIt(); } }); } else { changeIt(); } }); css: li.wiki.dropdown a.section-link { font-weight: bold !important; }
Guidelines for the JavaScript code and the Stylesheets
Using the example above, follow the details and guidelines for customizations below.
Javascript Code (js:)
-
Wrap your code in
$(function() { … });
so that it runs once the page is ready. -
There are two types of pages in FogBugz: Ocelot and "old UI." Over the last few years, we have transitioned the core portions of the app from our old UI to a new single-page-app we call Ocelot. The old UI pages are generally old-fashioned full-page loads. Ocelot pages load a mostly blank framework when you first hit enter in the URL, but every transition after that is done AJAXily.
NOTE: If you go from Ocelot to an old page and back, that “back” will be a full-page load.
-
The case list page, case page (view and edit), the iteration planner, kanban board, user options page, and activity feed/notification center are Ocelot pages. Generally, any page with
/f/
in it, is an Ocelot page. -
The wiki, discussion groups, all configuration pages (other than user options), evidence-based scheduling, and anything else not listed above are the old UI.
The jQuery we are running in this example is
$('li.wiki.dropdown a.section- link').text("Wikis")
. If we just put that in our script by itself, the old UI pages would run it after the entire page loaded in the user's browser, and it would work fine. On Ocelot pages, like the list (search and filter results) and case page, nothing would happen. The code would run in the user’s browser when all they had was our header and footer. We need to run it after all of the single-page-app magic is done. To do that, use pubsub to subscribe to the'/nav/end'
event. That event fires at the end of every page in Ocelot.The simplest way to detect if the code is running in Ocelot is to look for
fb.config
, as shown in the sample code above. -
-
DRY (Do not repeat yourself). In our example, we are working with the main header. Since it is shown on pages in both UIs, we use a function to avoid having to write the same code in two places. As of this writing, the bulk edit page can also be a reason to write DRY code. If you want to make changes to the case edit page, the main one is in Ocelot, but bulk edit is still running in the old UI. You will need to handle both situations.
Stylesheets (css:)
The CSS you enter is pulled into FogBugz on page load in both UIs (see below). If it is shorter than 1024
characters, it is added inline on the page after FogBugz's main CSS. If it is larger, it is pulled into your browser using an @import
rule.
Customizations Code Sample Repository
Check-out the customizations code sample repository for further example scripts.