Implementation notes and documentation on how I have implemented client side widgets on this site and AKC in general. At a high level I use aspire, jquery, jquery jsrender, akc xmltojson, and plain html divs.

The jsrender termplate file for widgets is in the control folder

Control files hold important files that critical for the functionality of the framework.


<script type="text/javascript" src="/akc/js/jquery.js">
</script>
<script type="text/javascript" src="/akc/js/json2.js">
</script>
<script type="text/javascript" src="/akc/js/jsrender.js">
</script>
<script type="text/javascript" src="/akc/js/akc-xmltojson.js">
</script>
<script type="text/javascript" src="/akc/js/akc-widget.js">
</script>

/*
**************************
* support for widgets
**************************
*/
.akc_expand
{
    display:none;
    border:orange solid 2px;
}

At the moment this is in my personal master page.


<div class="akc_expand" type="folderWidget">
        <folder_id>347</folder_id>
</div>

<div class="akc_expand" type="taggedMenuWidget">
        <tagnames>menu1,menu2</tagnames>
</div>

The keys are lowercased when I create xml to json


<?xml version="1.0" encoding="UTF-8"?>
<AspireDataSet>
   <tagnames>android</tagnames>
   <url>getFoldersForTagsURL</url>
   <profile_user_email>[email protected]</profile_user_email>
   <aspire.loops.folders>true</aspire.loops.folders>
   <aspire_output_format>object-xml</aspire_output_format>
   <profile_user_first_name>Satya</profile_user_first_name>
   <profile_aspire_loggedin_status>true</profile_aspire_loggedin_status>
   <profile_user_last_name>Komatineni</profile_user_last_name>
   <aspirecontext>akc</aspirecontext>
   <profile_user>satya</profile_user>
   <folders>
      <row>
         <f_relationship_id>83</f_relationship_id>
         <folder_name>CS-JavaScript</folder_name>
         <folder_id>63</folder_id>
         <f_tagname>android</f_tagname>
         <f_tagid>4053</f_tagid>
         <f_tag_owner_userid>satya</f_tag_owner_userid>
      </row>
   </folders>
</AspireDataSet>

tagnames
url
....etc
folders - an array

tagnames
url
....etc
folders - an array
..
inputDivData - an array

<div class="akc_expand" type="taggedMenuWidget">
        <tagnames>menu1,menu2</tagnames>
        <menuHeader>menuname</menuHeader>
</div>

....Aspireset goes here
inputDivData - an array
  tagnames
  menuheader
notice the lowercasing...

<div class="menu">
<p class="header">{{:inputDivData.menuheader}}</p>
{{for folders}}
<p><a href="/akc/display?url=NotesIMPTitlesURL&downerUserId={{:f_tag_owner_userid}}&folderId={{:folder_id}}&order_by_format=news">
{{:folder_name}}</a></p>
{{/for}}
</div>

of course you may want to check for an empty loop with an if statement and print the output accordingly!


/*
******************************************************
* Expected div structure

<div class="akc_expand" type="taggedMenuWidget">
        <tagnames>menu1,menu2</tagnames>
        <menuHeader>menuname</menuHeader>
</div>

* <div
* Future architecture may move this in
******************************************************
*/
function akcExpand_taggedMenuWidget_function(divObject)
{
    //alert("I am in taggedmenuwidget");
    //Get the inner html of your div
    var expandDivData = $(divObject).html();
    dataxml = "<root>" + expandDivData + "</root>";
    dataxmlobj = $.parseXML(dataxml);
    var dataObj = AKC.getJSONAtNode(dataxmlobj,"root");
    //alert(JSON.stringify(dataObj));

    var dataUrl = "/akc/display?url=getFoldersForTagsURL&tagnames=android&aspire_output_format=embedded-xml";
    var templateUrl =  "/akc/display?url=DisplayNoteBodyURL&reportId=4058";
    
    var menuWidget = new AKC.AkcWidget(dataUrl,templateUrl,divObject,dataObj);
    //populate the menu widget
    menuWidget.populate();
}

My notes on jsrender can be found at

My notes on jquery can be found at