Substitute com.glideapp.servicecatalog_category_view with com.glideapp.my_custom_view

Greg42
Mega Guru

Hi All,

I am trying to change the way items/categories are displayed it a catalogue - namely, to display it as a grid not a list. I don't want to change existing code from obvious reasons. I did some research and looked around the system of how those thing work together but can't see where the link item - using SNC.CatalogURLGenerator - generates com.glideapp.servicecatalog_category_view - can't see source code for it anywhere. I would like to change it to my custom view allowing me to work on it without worrying about future updates.

Is there a way to change the path generated by CatalogURLGenerator to point somewhere else than default com.glideapp.servicecatalog_category_view?

Any help will be much appreciated.

Cheers

Greg

1 ACCEPTED SOLUTION

Greg42
Mega Guru

I have managed to style the view as I wanted. Used addLoadEvent and checked for com.glideapp.servicecatalog_category_view.do then used jQuery for styling.


View solution in original post

39 REPLIES 39

Greg42
Mega Guru

I have managed to style the view as I wanted. Used addLoadEvent and checked for com.glideapp.servicecatalog_category_view.do then used jQuery for styling.


Deepak Ingale1
Mega Sage

Could you please share your code how do you manage to do it?


Sure Deepak,



NOTE: I was working with another person on this code unfortunately I don't remember that person's name - I don't have access to the original code to check it - so I shouldn't be fully credited for this solution.



addLoadEvent(function () {


  // Detect if a page is a catalog view using com.glideapp.servicecatalog_category_view.do.


  if (window.location.toString().indexOf('com.glideapp.servicecatalog_category_view.do') > -1) {


            var number_of_columns = 2;


            scSplitView(number_of_columns);


  }




  /**


  * Split the ServiceCatalog viewport into columns - normally it's a long list of items


  * @param num_of_cols integer The number of columns to split to


  */


  function scSplitView(num_of_cols) {


  /*


            tableRowElements:


            Gets all <tr> elements bypassing text nodes - which is very handy as it leaves only


            items that we are interested in.


            categoryIndex/itemsIndex:


            Indecies are used for setting the index of each category which allows us to access


            it directly from tableRowElements by index number. It also allows us to bypass it


            when necessary. It needs to be bypassed in one case when items are added to main rows.


            Without bypassing it, the header will be added to the list resulting in wrong layout.


            categoryMainRow/itemMainRow:


            Place holders for item lists - basically a parent to attach list of children elements.


            categoryRows/itemRows:


            Lists of children items.


            category/items


            Flags that indicate sections the code is currently in. Flags were used as the original


            layout had no parent->child structure, all the elements were siblings to each other.


            When code goes through each element, that element is checked and appropriate flag set


            to indicate that following items are either a category or item items.


  */


      var tableRowElements = $j("#category_description").siblings().last().find("table:first").find("> tbody > tr"),


            categoryIndex = 0,


            itemsIndex = 0,


            categoryMainRow = $j("<tr>"),


            categoryRows = $j("<tr>"),


            category = false,


            itemMainRow = $j("<tr>"),


            itemRows = $j("<tr>"),


            items = false;




  /*


  Use tableRowElements - list of siblings - to traverse the list.


  Traverse a list of tr elements, find out where categories and items


  section start and add items to correct categories into two columns.




  Challenge:


  The default html structure that is returned from the server doesn't have any


  parent->child relationship:




  <table>


            <tbody>


                      <tr></tr>


                      <tr class="header_bar_title"></tr>


                      <tr></tr>


                      ...


                      <tr class="header_bar_title"></tr>


                      ...


                      <tr></tr>


                      ...


            </tbody>


  </table>




  The only way to know that a header is hit is the class - which obviously is the same


  in both headers and it doesn't help to distinguish which header we actually looking


  at. Fortunately each header has <td> element with text in it - checking string for


  identification should be avoided but in this case we don't really have a choice.


  An index of each header can now be assigned allowing for identification in the list.




  !!! Caution !!!


  Each time a title in the header is changed, the code needs to be adjusted as well.


  Make sure the header title in html is the same as in if conditions!


  Additionally, if you work in multi language environment this code will not work


  - as checks basically work on hard-coded strings - and a workaround needs to be


  implemented to resolve this issue.


  */




  // Traverse elements.


  $j.each(tableRowElements, function (index, value) {


  // Check if this element is a category header.


  if (value.textContent.trim() === "Categories") {


  // This element is category header.


  // Add empty <tr> elements after the header.


  tableRowElements.eq(index).after(categoryMainRow);




  // At the same time two columns are added to a variable.


  categoryRows.append($j("<td width='50%' style='vertical-align: top'>").append($j("<table class='wide'>")));


  categoryRows.append($j("<td width='50%' style='vertical-align: top'>").append($j("<table class='wide'>")));


  /*


  categoryRows variable now holds a structure like this:


            <tr>


                      <td width="50%" style="vertical-align: top">


                                <table class="wide"></table>


                      </td>


                      <td width="50%" style="vertical-align: top">


                                <table class="wide"></table>


                      </td>


            </tr>


  */




  // Assign a correct index value.


  categoryIndex = index;


  // Change flag to true. This indicates to the if statement below to add items to


  // a correct header.


  category = true;


  }




  // Check if this element is an item header.


  // The principle here is the same as in Categories if statement.


  if (value.textContent.trim() === "Items") {


  tableRowElements.eq(index).after(itemMainRow);


  itemRows.append($j("<td width='50%' style='vertical-align: top'>").append($j("<table class='wide'>")));


  itemRows.append($j("<td width='50%' style='vertical-align: top'>").append($j("<table class='wide'>")));


  itemsIndex = index;



  // Only difference is that we set the categories flag to false as we don't want


  // items being added to categories as well.


  category = false;


  items = true;


  }




  /*


  Here a category index is used to bypass headers. We want to add only header's items.


  without headers themselves.


  If this item is a header, skip.


  */


  if (category && (categoryIndex !== index )) {


  // Modulo is used to decide to which column an item should be copied.


  if (index % num_of_cols) {


  categoryRows.find("table.wide").eq(1).append(value);


  } else {


  categoryRows.find("table.wide").eq(0).append(value);


  }


  }




  // Same principal here as above.


  if (items && (itemsIndex !== index)) {


  if (index % num_of_cols) {


  itemRows.find("table.wide").eq(1).append(value);


  } else {


  itemRows.find("table.wide").eq(0).append(value);


  }


  }




  // There is an additional paging html element that we don't want to consider in the list.


  // We bail out when we hit the index before that item.


  if (index === (tableRowElements.length - 2)) return false;


  });


  // Set item to false to return to default state where both flags are false.


  items = false;




  /*


  Here all the html is put together.




  categoryMainRow:


            <tr></tr>


  Two manual appends


            <td>


                      <table class="wide"></table>


            </td>


  Last append adds categoryRows plus items added for each category:


            <tr>


                      <td width="50%" style="vertical-align: top">


                                <table class="wide">


                                          <tbody>


                                                    <tr>


                                                              <td>


                                                                        <div></div>


                                                              </td>


                                                    </tr>


                                          </tbody>


                                </table>


                      </td>


                      ...


            </tr>




  Final html:


            <tr>


                      <td>


                                <table class="wide">


                                          <tbody>


                                                    <tr>


                                                              <td width="50%" style="vertical-align: top">


                                                                        <table class="wide">


                                                                                  <tbody>


                                                                                            <tr>


                                                                                                      <td>


                                                                                                                <div></div>


                                                                                                      </td>


                                                                                            </tr>


                                                                                  </tbody>


                                                                        </table>


                                                              </td>


                                                    </tr>


                                          </tbody>


                                </table>


                      </td>


            </tr>


  Div element is the actual item. This structure is for each main row.


  */


  categoryMainRow.append($j("<td>").append($j('<table class="wide">').append(categoryRows)));


  itemMainRow.append($j("<td>").append($j('<table class="wide">').append(itemRows)));


  }


});



































Indentation is a bit off but it should be readable.




Cheers



Greg


Thanks alot Greg.


I will try this out.