December 22, 2014
Hot Topics:

Decision Making Flags: The How and Why

  • July 12, 2006
  • By Chad A. Campbell
  • Send Email »
  • More Articles »

Good news! You are done constructing the core HTML that your flags will utilize. However, you are not yet finished. At this point, you have all of the elements in place; however, you need to implement the behavior. The behavior handles the interaction between the user and the elements.

Ultimately, you want to have a flag that drapes over other results when a user hovers over a result. The process of displaying and hiding the flag will be fulfilled via some JavaScript. There are four events that you must watch for to properly display and hide the flag. These events are:

  1. When a user moves their mouse over a search result (a.k.a. flagstaff)
  2. When a user moves their mouse over a result's details (a.k.a. the flag)
  3. When a user leaves a result's details (a.k.a. the flag)
  4. When a user leaves a search result (a.k.a. flagstaff)

Before you implement the code to handle these events, you must identify who will be responsible for employing these events. To accomplish this, you must implement some consistent naming standard that will assist you in assigning the appropriate event handlers. Revisit Snippet 2 and notice that you are using the following naming structure:

  • Each tr element that contains your important details (the odd-numbered table rows) will be given an id that adheres to a consistent naming structure. In this case, each entry will be given the name "record[recordNumber]", where recordNumber is the index of the item within the result set.
  • Each tr element that contains a flag (the even-numbered table rows) will be given a name that uses the following naming structure "hiddenRecordFlag[recordNumber]", where once again recordNumber represents the index of the item within the result set.
  • Finally, each span element that represents a flag will be given a name that adheres to the following structure: "record[recordNumber]Flag", where recordNumber once again represents the index of the item within the result set.

Now that you have implemented a naming schema for the necessary components, you are ready to add the JavaScript that will handle the events accordingly. In the example, you will place the JavaScript in an external .js file and reference it from your HTML page. The JavaScript I am referring to is listed in Snippet 3.

var selectedRowId = null;

// ==========================================================
// Adds the appropriate event handlers to the flagged entries
// ==========================================================
function Initialize()
{
   var table = document.getElementById("RecordsTable");
   for (i=1; i<table.rows.length; i++)
   {
      var tableRow = table.rows[i];

      if (tableRow.id.indexOf("hiddenRecordFlag") == -1)
      {
         tableRow.onmouseover = OnFlagStaffOver;
         tableRow.onmouseout  = OnFlagStaffOut;

         var flag = document.getElementById(tableRow.id + "Flag");
         (flag != null)
         {
            flag.onmouseover = OnFlagOver;
            flag.onmouseout  = OnFlagOut;
         }
      }
   }
}

function OnFlagStaffOver()
{
   ShowFlag(this.id);
}

function OnFlagStaffOut()
{
   HideFlag(this.id);
}

function OnFlagOver()
{
   var rowId = this.id.substring(0, this.id.length-4);
   ShowFlag(rowId);
}

function OnFlagOut()
{
      var rowId = this.id.substring(0, this.id.length-4);
      HideFlag(rowId);
}

// =======================================
// Displays the flag associated with a row
// =======================================
function ShowFlag(rowId)
{
   // Determine if anything needs to be done
   if (rowId == selectedRowId)
      return;

   // Determine if another flag needs to be hidden
   if (rowId != selectedRowId)
   {
      if (selectedRowId != null)
      {
         // Alter the flag staff
         var selectedFlagStaff =
            document.getElementById(selectedRowId);
         selectedFlagStaff.className = "";

         // Hide the flag
         var selectedFlag =
            document.getElementById(selectedRowId + "Flag");
         selectedFlag.style.display = "none";
      }
   }

   // Update the style of the flag staff that is selected
   selectedRowId = rowId;
   var flagStaff = document.getElementById(rowId);
   flagStaff.className = "flagStaffHover";

   // Display the flag of the selected flag
   var flag = document.getElementById(rowId + "Flag");
   flag.style.display = "block";
}

// ====================================
// Hides the flag affiliated with a row
// ====================================
function HideFlag(rowId)
{
   // Update the style of the flag staff that has been exited
   var flagStaff = document.getElementById(rowId);
   flagStaff.className = "flagStaff";

   // Hide the flag
   var flag = document.getElementById(rowId + "Flag");
   flag.style.display = "none";

   // Reset the selectedRowId
   selectedRowId = null;
}

Snippet 3

The comments within the JavaScript explain what is occurring. One thing to note, however, is that in the Initialize function you begin at an index of 1. This may seem a bit preternatural if you are used to 0-based indexing. The reason you do this is to prevent adding event handlers to the column heading row, which would cause a JavaScript error.

To complete your implementation of your flags, you need to perform one more little task. After providing the appropriate linking to your .js file in the head section of the HTML file, you need to add a call to initialize your table from the body element in your HTML code. You can see the additions, in blue, within Snippet 4.

<html>
<head>
   <script type='text/javascript' src='flag.js'></script>

   <style type='text/css'>
      tr.gridHeader {background-color:#3891A7;font-weight:bold;}
      tr.flagStaff  {background-color:#E7DEC9;}
      tr.flagStaffHover {background-color:#3891A7;color:white;
                         cursor:pointer;}

      td.gridHeader {color:black; border-bottom:solid 2px black;}
      td.spacer {width:6px;}

      span.flag{display:none;position:absolute;width:100%;
                background-color:#3891A7;color:white;}

   </style>
</head>

<body onload='Initialize();'>
<!-- Remainder of code from the previous snippet -->
</body>
</html>

Conclusion

Congratulations! You have put together an extremely valuable decision-centric interface. There are numerous ways you could enhance this UI component, including various style enhancements and employing AJAX to populate your hidden results (flags) more efficiently. However, the purpose of this article was to provide an introduction to this complex UI component. I hope you have enjoyed this article and I hope to see this component employed on your site soon!

Downloads

About the Author

Chad Campbell (MCSD, MCTS) is a solutions developer for mid to large-sized organizations. Chad is a thought leader with Crowe Chizek in Indianapolis, Indiana. Chad specializes in Web-based solutions. He can be reached at cacampbell@crowechizek.com.




Page 2 of 2



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Sitemap | Contact Us

Rocket Fuel