CCF (Component Communication Framework)

On this page



Purpose

  • CCF allows components to encapsulate their client-side code into independent requirejs modules
  • Through requirejs's dependency loading, components have a clean way of defining dependencies
  • Through the Event Manager interface, components can send messages to each other without tight coupling
  • Allow Content Authors to configure how components use Event Manager via rendering parameters

Modules

  • moduleLoader - Initializes js modules for the components on the current page
  • eventManager - Used by components to send/receive event data (This is how components "talk")
  • score_ccf/extensions - Contains helpful utility functions

Usage

To use Score CCF in your project, you need to...

  1. load Score CCF's configuration
  2. load your project's custom configuration
  3. load an "entry point" file (typically named main.js) which kicks off the module loading

Example - Main.cshtml layout file
<script type="text/javascript" src="@Url.Content("~/Areas/ScoreCCF/js/require.config.js")"></script>
<script type="text/javascript" src="@Url.Content("~/Areas/YourCustomArea/js/require.config.js")"></script>
<script type="text/javascript" data-main="path/to/your/main.js" src="@Url.Content("~/Areas/ScoreCCF/js/Vendor/require.js")"></script>


Create a require.config.js file in Your.Solution.Web/Areas/YourCustomArea/js to house your project's custom configuration. The most important property to define here is the "baseUrl", which should point to your js root directory. Everything else is optional. Reference this page for all possible configuration options: http://requirejs.org/docs/api.html#config

Example - your site's custom configuration
window.require = window.require || {};
window.require.baseUrl = "/Areas/RenameMeArea/js";

window.require.paths = window.require.paths || {};

window.require.shim = window.require.shim || {};
window.require.shim.bootstrap                 = { deps: ["jquery"] };
window.require.shim.matchHeight               = { deps: ["jquery"] };
window.require.shim.jqueryValidate            = { deps: ["jquery"] };
window.require.shim.jqueryUnobtrusiveAjax     = { deps: ["jquery"] };
window.require.shim.jqueryValidateUnobtrusive = { deps: ["jqueryValidate"] };
window.require.shim.scorevalidation           = { deps: ["jqueryUnobtrusiveAjax", "jqueryValidateUnobtrusive"] };


The js files referenced in a layout file will run for all pages that use this layout. So, you can use main.js for global code (code that applies to all pages).

Example - main.js
define([
    "jquery",
    "underscore",
    "score_ccf/ModuleLoader",
    "scorebootstrap",
    "matchHeight"
],
function ($, _, moduleLoader, scorebootstrap) {
    "use strict";

    //prevents dropdown from closing when clicked inside
    $(document).on("click", ".score-megamenu .dropdown-menu", function (e) {
        e.stopPropagation();
    });

    // match height style boxes within a container with a special "signal" class
    $(".matchheight-stylebox .score-style-box").matchHeight(true);

    // if you need to monkey patch anything in Score Bootstrap Initialization logic
    // here's where you would do it. Before calling to init(). Something like:
    // scorebootstrap.Accordion.init = function() { ... }

    // init SCORE Bootstrap components (Tabsets, Accordions, Carousels, etc.)
    scorebootstrap.init();

    // loads all modules on the current page and calls a function when finished
    moduleLoader.loadPendingModules().done(function() {
        // anything that neeeds to run globally when all modules are loaded goes here
    });
});

To create a js module for your custom component...

  1. Create a js file named with your component name
  2. In your js file, define a requirejs module, and return a function that initializes the module.
  3. Use Score.UI's HTML Helper to wrap your component's Razor code. This tells the Module Loader what portion of the page's HTML should be associated with what js module.


Example - YourComponent.cshtml
@model YourModelClass
using (Html.BeginUXModule(
    // string name of your requirejs module, relative to baseUrl
    "Components/MyComponent",
    // object containing data you want to pass to the requirejs module. This data is serialized into HTML.
    new { Sitecore.Context.PageMode.IsExperienceEditorEditing, UniqueId = Model.Rendering.UniqueId.ToString() },
    // DOM properties that should be appended to the DOM element that wraps this component
    new { @class = Model.Classes }))
{

    <div> .... code for your component ... </div>
}


In this example, we assume that component js files are placed in Your.Solution.Web/Areas/YourCustomArea/js/Components

Example - Your.Solution.Web/Areas/YourCustomArea/js/Components/MyComponent.js
define(function () {


   function MyComponent(scope, uniqueId) {
      // Do something with 'scope' (your component's DOM element)
   }


   // 'args' is an object containing the data passed to the BeginUXModule HTML Helper in the component's Razor view.
   // The Module Loader deserializes this data from HTML, and adds a reference to the component's outer-most DOM element as args.scope
   return function initMyComponent(args) {
       // Do not initialize the module if we are in Experience Editor
       if (args.IsExperienceEditorEditing === true) {
           return null;
       }


       return new MyComponent(args.scope, UniqueId);
   };
})


Minifying/Bundling js with CCF

Reference this page if you are also using javascript minification/bundling in your project: JavaScript Bundling (Alpha version)


Paths Defined in Score

Score.UI defines shortcut names for common modules and libraries. If your components depend on these modules/libraries, use the shortcut name to define dependency.


path namedescription

score_ccfThe root location of score ccf scripts

jqueryNoConflict

A wrapper for jquery that uses jquery's noConflict method. Behind the scenes, CCF maps all requests for "jquery" to "jqueryNoConflict"

jqueryjQuery JavaScript Library v2.1.4. Behind the scenes, CCF maps all requests for "jquery" to "jqueryNoConflict"

jqueryTouchA jQuery plugin for unifying mouse/touch events across different browsers. Reference: http://a-fung.github.io/jQueryTouch/

underscoreA js helper library. Provides 80+ functions that support both the usual functional suspects: map, filter, invoke — as well as more specialized helpers. Reference: http://underscorejs.org/ Exports the global variable "_"

eventManagerScore CCF's EventManager module

moduleLoaderScore CCF's ModuleLoader module
requirejs extensionsasyncAn extension for requirejs for resolving asynchronous dependencies.
depend

Artem Loboda- what does this do?

fontLoads font files
googLoads google API files
imageLoads image files
jsonLoads json files
mdownLoads markdown files
noextLoads files with no extension
propertyParser

Artem Loboda - what does this do?

textLoads text files