Mohammed Atef’s Technical blog

IBM Case Manager Custom search Widget

Introduction

In this post I am going to share with you how to build your custom search widget to override and customize you case manager built in search widget.

use case

Here, we will implement custom search for customer management project.
actually, user will have list of checkboxes for customers, then he can select customers and click find customers and he will see the result into CaseList Widget, also he can see customer information and related documents in the Case Information Widget.

Create customer management solution

Actually, I will create new solution named customer management to have a complete tutorial about custom search widget, and since creating project is not our target for this post, so I will quickly write done steps to build this project.

  1. Login to case manager build, then select add solution
  2. Set solution name : customer management and the prefix cust
  3. Add two string properties named as follow (customer name, customer no)
  4. Create new role named admin role
  5. Create new case named relation management
  6. Select case properties from left menu > add properties > Existing > select all > ok all
  7. Go to views and add both customer name and no to all views ( case summery, case search , properties)
  8. Create new take named task1
  9. Design the new task follows

image

Build custom search project

let’s start building our custom search project, actually this project will have the following files

(web.xml, CustomSearch.js, CustomSearch.xml) , for more information about this files visit this link

Review CustomSearch.xml

Now, We’re going to take a look at CustomSearch.xml file

  • here we will see bulk of xml elements about events as shown below
   1: <iw:eventDescription id="receiveWorkItem" payloadType="WorkItem"    description="Event to receive work item" lang="en" />        
   2:     <iw:event id="receiveEvent" eventDescName="receiveWorkItem" handled="true" onEvent="onreceiveWorkItem" />
   3:     <iw:event id="Send Payload" published="true" eventDescName="SendPayload"/>
   4:     <iw:eventDescription id="SendPayload" payloadType="CaseSearch" description="search for projects" lang="en"/>

  • if you’re familiar with xml, you can understand this, here we have two eventdecription and other two events, you may notice that each event has a reference to the event description. i need just to focus in very important attribute here payload type which used to determine the recipient or sender event type.
  • in our post we are interested with sender event type ‘CaseSearch’, this payload is responsible to descript the case search object that will sent to CaseList widget and in same xml will and immediately after above code snippet, you will find casesearch payload definition as shown below
   1: <iw:payloadDef name="CaseSearch">
   2:     <iw:payloadDef name="CaseType" type="string" defaultValue="" description=""/>
   3:     <iw:payloadDef name="ObjectStore" type="string" defaultValue="" description=""/>
   4:     <iw:payloadDef name="SortingProperties" type="any" defaultValue=""  description=""/>
   5:     <iw:payloadDef name="SystemProperties" type="any" defaultValue="" description=""/>
   6:     <iw:payloadDef name="SummaryProperties" type="any" defaultValue="" description=""/>
   7:     <iw:payloadDef name="SearchProperties" type="any" defaultValue=""  description=""/>
   8:     <iw:payloadDef name="QuerySQL" type="string" defaultValue=""   description=""/>
   9: </iw:payloadDef>

  • the above payload definition has different sections to decrepit name and type of each object in our casesearch payload, it shows details about (casetype, objectstore, sortingproerties, systemproperties, summaryproperties, searchproperties and querysql)
  • finally we will see below mentioned code this line
    • <iw:resource src="CustomSearch.js"/> , which is used to reference to our JavaScript file resource that will deal with above events.
Review CustomSearch.js

here i am not going deeply because most of you are familiar with JavaScript, i will focus only in JavaScript functions and the JavaScript code that sends cases

arch payload to the event.

let’s see now the list of functions in this file

  1. RenderCustomersLst : it is used to render customer list found in json data object as checkboxes.
  2. SelectedProjLST : it is used to find out selected customers to send it to caselist for search
  3. Servletcall : actually it is not used but i build it, for future use if you have servlet that retrieve list of customers in the mention json format.
  4. onreceiveWorkItem : this is event implementation when our custom widget receive event of type workitem.

finally, lets see this line of code

   1: this.iContext.iEvents.fireEvent("Send Payload", "CaseSearch", payload);
  • it is using icontext to get our custom widget context and then fire event of type casesearch
  • above this line of code you will see a JavaScript object named data, which used to build the casesearch payload, here i have static json object that descript (casetype, objectstore, sortingproerties, systemproperties, summaryproperties, searchproperties and querysql) objects in the payload, later we will see how to get this static information.
  • but there is another dynamic value that i use it to modify the search query based on selected customers from the widget.

Now our project is ready, so you can go a head and export it as war then deploy and register it to Case Client, for more information about this topic visit this link .

Duplicate Cases Page

since we finished all development effort let’s move now to Case Client and do some customization.

first we have to create new page to use our new custom search widget there,so please follow below steps to do this.

  1. Manage Spaces > Customers Management > Actions (for cases) > Duplicate
  2. Actions (for cop of cases) > setting
  3. Rename it to be > Custom Search

Modify Custom search page

now we are going to modify our new page to use the new custom search widget, and this task has two phases, first to find our the casesearch payload to extract basic information about (casetype, objectstore, sortingproerties, systemproperties, summaryproperties, searchproperties and querysql) as mentioned above and then modify same page to finalize the custom search.

Prepare the search case payload

we can get the casesearch payload by following the below steps:

  1. Click Edit Page link
  2. Add script adapter to the page
  3. Wire script adapter as follows

    a. Add incoming wire to Search Widget > select search cases event name

    b. Add outgoing wire to case list > select search cases event name

  4. Use the built in search widget and apply search shown belowimage 
  5. Once result shown in case list, open the script adapter and take copy of its payload.
  6. Below list of json script should be found in payload object
  7.    1: {"CaseType":"","ObjectStore":"DTargetOS",
       2: "SortingProperties":[{"symbolicName":"cmis:lastModificationDate","type":"datetime","displayName":"Date Modified"},{"symbolicName":"cmis:lastModifiedBy","type":"string","displayName":"Modified By"}]
       3: ,"SystemProperties":[{"symbolicName":"p8ext:ClassDisplayName","type":"string","displayName":"Case Type"},{"symbolicName":"cmis:lastModifiedBy","type":"string","displayName":"Modified By"},{"symbolicName":"CmAcmCaseState","type":"string","displayName":"Case State"},{"symbolicName":"cmis:lastModificationDate","type":"datetime","displayName":"Date Modified"}]
       4: ,"SearchProperties":[{"symbolicName":"CUST_customername","displayName":"customer name","type":"string","orderable":true}],"SummaryProperties":[{"symbolicName":"CmAcmCaseIdentifier","displayName":"Case Identifier","type":"string","orderable":true},{"symbolicName":"CUST_customername","displayName":"customer name","type":"string","orderable":true},{"symbolicName":"CUST_customerno","displayName":"customer no","type":"string","orderable":true}],
       5: "QuerySQL":"SELECT cmis:objectId, cmis:objectTypeId, cmis:lastModifiedBy, CmAcmCaseState, cmis:lastModificationDate, CmAcmCaseIdentifier, CUST_customername, CUST_customerno FROM CmAcmCaseFolder WHERE CmAcmParentSolution = 'ido_40C02E31-7631-4C2E-9EB6-1E0D4676507F:idt_616EA2CB-2F81-4AE7-8E9E-A787A0B224AF:idx_A992C31D-31D8-41EE-8E65-4DC64608357D' AND CmAcmCaseState > 1 
       6: AND (CUST_customername LIKE 'cust%') "}

    Add customer list widget
    • Now we are going to delete the script adapter widget and before that make sure you have cleared all wire linked to it.
    • Then we will add our new custom widget by following below steps

                a. Click edit page link

                b. Select customer list widget as shown below

    image

    • Drag it above case list widget as shown below

    image

    • Drag the in basket widget to the hidden area beside the command widget as shown below

    image

    • Configure in basket wires as shown below

    image

    • Configure customer list widget as shown below

    image 

    Testing the widget

    • eventually we finished all tasks related to development, deployment, customization, wiring and our custom search widget is ready now for testing
    • i will assume that you have entered two customers using Case client with the following details

      1- customer name : customer 1    , customer number : 111

      2- customer name : customer 2    , customer number : 2

    • Click the refresh button into customer list widget
    • Then check customer 1 and customer 2
    • Click find customers , select customer 1
    • Now you should have result as shown below
    • image

    Conclusion

    since we have ended this post let’s recap activities we went throw, we learned in this post customizing built in widget, configurations, and building new solutions and customizing pages and finally wiring widget with each others.

    Download source code

    you can find out the project war file and all other resources related to this post here , hope that helped.

    May 31, 2013 Posted by | Developement, ECM, FileNet, IBM Case Manager, XML,XSL,XSLT,DHTML,HML,CSS | , , , , , , , , , , , , , , | Leave a comment

    Build and register a IBM Case Manager custom Widget

    Introduction

    As a user interface developer for IBM Case Manager, you need to customize Case Manager Client by creating your custom Widgets. Here I am going to share with you basics for developing, deploying and registering Custom Widgets.
    Our use case for this post is creating custom widget to print hello world message.

    Application structure

    we know that each application should have known structure, Below table shows the application files structure.

    File or folder name Description
    HelloWorld Web project name and folder
    HelloWorld.xml Widget definition file
    Web.xml Configuration file

    Create a web project

    First, we have to create new project using Eclipse, so please follow this procedures to create a new web project

    1- Open Eclipse, Click File > New > Dynamic web project

    2- Follow the wizard to create project, but do not forget to set project name HelloWorld and to tick Generate web.xml deployment descriptor check box.

    3- Open Project Explorer pane, expand the HelloWorld node and expand the WebContent > WEB-INF folder, then Open the web.

    4- Add the following entry to include the BasicWidget.xml to the welcome file:
    <welcome-file> HelloWorld.xml</welcome-file>       , then save the file.
    5- Add new file with the following names HelloWorld.xml

    Modify Widget Definition file

    • Open the HellowWrold.xml file and add the following lines of codes, then save the file.
       1: <?xml version="1.0" encoding="UTF-8" ?>
       2: <iw:iwidget id="HelloWorld" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       3: xmlns:iw="http://www.ibm.com/xmlns/prod/iWidget"
       4: supportedModes="view edit" iScope=" HelloWorldScope">
       5: <iw:content mode="view">
       6: <![CDATA[ <h1>Hello World</h1> ]]>
       7: </iw:content>
       8: </iw:iwidget>

    • Above code is very clear but we need to highlight some attributes here
      • supportedModes: this attribute used to determine if users can view or edit the widget.
      • iScope: The iScope is a Dojo wrapper class for the Custom widget
      • iw:content: it is content area for the edit or view mode in your Widget.

    Create Catalog file

    • Create new xml file name it catalog_HelloWorld.xml and add the following list of code to it then save.
       1: <?xml version="1.0" encoding="UTF-8"?>
       2: <catalog id="Demo"> <resource-type>Catalog</resource-type>
       3: <category name="Demo">
       4:     <title> <nls-string lang="en">HelloWorld</nls-string></title>
       5:     <description> <nls-string lang="en">HelloWorld</nls-string>    </description>    
       6:     <entry id="iWidget.widgets.HelloWorld" unique-name="iWidget.widgets.HelloWorld">                <title> <nls-string lang="en">HelloWorld</nls-string> </title>
       7:         <description> <nls-string lang="en">HelloWorld</nls-string> </description>                <definition>endpoint://com.ibm.im.HelloWorldRootId/HelloWorld.xml</definition>
       8: <preview>
       9: endpoint://com.ibm.im.HelloWorldRootId/HelloWorld/image/thumbnails/viewer_preview.gif
      10: </preview>
      11: <icon>endpoint://com.ibm.im.HelloWorldRootId/HelloWorld/image/viewer_18.gif</icon>
      12: <previewThumbnail>endpoint://com.ibm.im.HelloWorldRootId/HelloWorld/image/thumbnails/viewer_thumb.gif</previewThumbnail>            <help>endpoint://{com.ibm.bspace}bspaceWidgetHelpRootId/topic/com.ibm.p8.widgetsref.doc/viewer_widget.htm</help>
      13: <shortDescription> <nls-string lang="en">HelloWorld</nls-string></shortDescription>        <metadata name="com.ibm.bspace.version">1.0.0.0</metadata>            <metadata name="com.ibm.bspace.owner">International Business Machines Corp.</metadata>
      14: </entry></category></catalog>

    • now let’s talk a look at this file
      • entry ID: is the widget id for the business space and it should be unique
      • category name: used to add this widget to an exist category or and new category for the new widget if not exist.
      • Other attributes used for determine widget title, description, icons, images.

    Create End point file

    • It is the last file, we need to build end point file, actually it is very short.so please create new xml file and name it HelloWorldEndPoint.xml and add the following lines of code there.
       1: <?xml version="1.0" encoding="UTF-8"?>
       2: <tns:BusinessSpaceRegistry xmlns:tns="http://com.ibm.bspace/BusinessSpaceRegistry" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://com.ibm.bspace/BusinessSpaceRegistry BusinessSpaceRegistry.xsd ">    <tns:Endpoint>    <tns:id>com.ibm.im.HelloWorldRootId</tns:id>    <tns:type>com.ibm.im.HelloWorldRootId</tns:type>
       3:     <tns:version>1.0.0.0</tns:version>
       4:     <tns:url>/HelloWorld/</tns:url>
       5:     <tns:description>Location of Hello World</tns:description>
       6:   </tns:Endpoint>    </tns:BusinessSpaceRegistry>

    Deploy and register the Widget

    We have finished all development effort and we are going forward to deploy and register the new widget to case manager client.

    However, we have can follow two options to do this, I will share with both of them now

    • First option: export project as war and register the catalog and endpoint xml files
    • Second option: export project as ear and zip it with the catalog and endpoint xml files
    Export project as war and register the catalog and endpoint files

    Here we are going to export the HelloWorld project as war file, let’s see procedures to do this

    1. Click File > export > war file
    2. select war file path for exporting and then finish
    3. Go to websphere and deploy the war file and keep the web application name HelloWorld
    4. Register the catalog file by following the below steps
      1. Open windows command and go to the web sphere bin folder
      2. Run the below commands
        1. wsadmin -user user1 -password pwd1 -lang jython
        2. AdminTask.updateBusinessSpaceWidgets(‘[-nodeName node1 -serverName server1

          -catalogs C:\HellowWolrd\catalog_ HellowWolrd.xml]’)
        3. AdminConfig.save()
    5. Register the End point file by following the below steps
      1. Open windows command and go to the web sphere bin folder
      2. Run the below commands
        1. wsadmin -user user1 -password pwd1 -lang jython
        2. AdminTask.updateBusinessSpaceWidgets(‘[-nodeName node1 -serverName server1 –endpoints C:\HellowWolrd\HellowWolrdEndPoint.xml]’)
        3. AdminConfig.save()
    Export project as ear and zip it with catalog and endpoint files

    Here we are going to export our project as ear file and without deploying it to Websphere, we will create one package and with couple of command lines we will deploy and register our widget.

    Let’s see how it goes here:

    1. 1- Open Eclipse and create new Enterprise application project
    2. 2- Select HelloWorld from Java EE module dependencies, then click finish
    3. 3- Click File > Export EAR , set the ear file name helloworld
    4. 4- Create folder named HelloWorld and copy the following files to it (HelloWorld.ear, catalog_HelloWorld.xml, HelloWorldEndpoints.xml)
    5. Zip the HelloWorld folder
    6. Open windows command and go to the web sphere bin folder
    7. Run the following commands
      1. wsadmin -user user1 -password pwd1 -lang jython
      2. AdminTask installBusinessSpaceWidgets {-serverName server1 -nodeName node1 -widgets C:\HellowWolrd\ HellowWolrd.zip}

    Testing Widget

    Eventually, we have finished developing, deploying and registering the Hello World widget now you can open any page in your case client and click Edit page link then drag the hello world widget there.

    Conclusion

    In this post I tried to share with you how to build and deploy IBM case manager widget and also to register it in two different ways, hope that helped.

    Now you can download all resources related to this post from here .

    May 31, 2013 Posted by | Developement, ECM, FileNet, IBM Case Manager, XML,XSL,XSLT,DHTML,HML,CSS | , , , , , , , , , , , , , | 8 Comments

    Complete JS & Jquery popup Div solution

    Introduction

    Actually, I have write this post to collect list of common features for Popup div in one solution.

    Main Features

    • Popup Div
    • Dynamic content using asp .net handler (.ashx)
    • Items click on the Div
    • Close or hide div after clicking outside it.

    Brief about the Sample

    This is very light sample that shows list of countries retrieved from Database.
    once user has select any country from the Div, it shows a message box confirming the selected country.
    wherever user click outside this div, it is going to hidden mode.

    List of files used

    • testmulticolumnmenu.htm : this file has all html codes that draw the Div and JS codes that bind the div, handle selected item, and finally handle clicking outside the div.
    • BindcmbHandler.ashx : this is asp.net handler to retrieve countries list from database .
    • web.config : this file has common configuration for the web application but it has only connection string to our test Database .
    • jquery-ui.min.js, jquery.min.js : this is common Jquery files.

    Sample of source Code

     

     

       1: <html xmlns="http://www.w3.org/1999/xhtml">

       2: <head>

       3:     <title></title>

       4:    <script src="jquery.min.js" type="text/javascript"></script>
       1:

       2:    <script src="jquery-ui.min.js" type="text/javascript">

       1: </script>

       2:    <script type="text/javascript">

       3:

       4:        function bindsub() {

       5:            var objJs;

       6:            $.ajax({

       7:                type: "POST",

       8:                url: "BindcmbHandler.ashx?sub=1",

       9:                async: false,

      10:                cache: false,

      11:                success: function (_result) {

      12:                    objJs = _result.toString();

      13:                },

      14:                error: function (_msg) { }

      15:            });

      16:            var dropdownMenuDiv = document.getElementById("container3");

      17:            dropdownMenuDiv.innerHTML = objJs;

      18:        }

      19:        document.onclick = check;

      20:        function check(e) {

      21:            var target = (e && e.target) || (event && event.srcElement);

      22:            var dropdownMenuDiv = document.getElementById("container3");

      23:            var dropdownMenu = document.getElementById("lnk");

      24:            if (!checkParent(target, "popup1")) {

      25:                // click NOT on the menu

      26:                if (checkParent(target, "lnk")) {

      27:                    // click on the link

      28:                    if (dropdownMenuDiv.style.display == "none" || dropdownMenuDiv.style.display =="") {

      29:                        dropdownMenuDiv.style.display = "block";

      30:                        bindsub();

      31:                    } else { dropdownMenuDiv.style.display = "none"; }

      32:                } else {

      33:                    // click both outside link and outside menu, hide menu

      34:                    dropdownMenuDiv.style.display = "none";

      35:                }

      36:            }

      37:        }

      38:        function checkParent(t, id) {

      39:            while (t.parentNode) {

      40:                if (t == document.getElementById(id)) { return true; }

      41:                t = t.parentNode;

      42:            }

      43:            return false;

      44:        }

      45:          function openpopup(id) {

      46:       //Calculate Page width and height 

      47:       var pageWidth = window.innerWidth;

      48:       var pageHeight = window.innerHeight;

      49:       if (typeof pageWidth != "number"){

      50:       if (document.compatMode == "CSS1Compat"){

      51:             pageWidth = document.documentElement.clientWidth;

      52:             pageHeight = document.documentElement.clientHeight;

      53:       } else {

      54:             pageWidth = document.body.clientWidth;

      55:             pageHeight = document.body.clientHeight;

      56:       }

      57:       }

      58:       //Make the background div tag visible...           

      59:       var divobj = document.getElementById(id);

      60:       if (navigator.appName=="Microsoft Internet Explorer")

      61:       computedStyle = divobj.currentStyle;

      62:       else computedStyle = document.defaultView.getComputedStyle(divobj, null);

      63:       //Get Div width and height from StyleSheet 

      64:       var divWidth = computedStyle.width.replace('px', '');

      65:       var divHeight = computedStyle.height.replace('px', '');

      66:       var divLeft = (pageWidth - divWidth) / 2;

      67:       var divTop = (pageHeight - divHeight) / 2;

      68:       //Set Left and top coordinates for the div tag 

      69:       divobj.style.left = divLeft + "px";

      70:       divobj.style.top = divTop + "px";

      71: }

      72: function closepopup(txt){

      73:     var divobj = document.getElementById('container3');

      74:     divobj.style.display = "none";

      75:     alert('You have select :'+txt+' Country');

      76: }

      77:

    </script>

       5:     <style type="text/css">

       6: .popup {

       7:       background-color: white;

       8:       height: 500px; width: 800px;

       9:       border: 1px solid #d3d3d3;

      10:       position: absolute; display: none;

      11:       font-family: Verdana, Geneva, sans-serif;

      12:       font-size: small; text-align: justify;

      13:       padding: 5px; overflow: auto;

      14:       z-index: 1050;

      15: }

      16: </style>

      17: </head>

      18: <body>

      19: <a href="#" onclick="openpopup('container3')" id="lnk">Open Popup Div #1</a>

      20: <div id="container3" class="popup">

      21: alsd;asdkas

      22: </div>

      23: </body>

      24: </html>

    Finally you can Download all source code and complete asp.net web site from here

    September 4, 2012 Posted by | XML,XSL,XSLT,DHTML,HML,CSS | Leave a comment

    http status 407 proxy authentication required

    Did you ever see this exception http 407 proxy authentication required?
    now you can solve this issue if you click here. just add the configuration in the post into your app.config or web.config
    I would like to thank my freiend Usman for this nice help.
    Regards,

    April 8, 2009 Posted by | XML,XSL,XSLT,DHTML,HML,CSS | Leave a comment