示例#1
0
        public static bool Populate(HtmlSelect dropDownList, string stateCode,
                                    string countyCode, string firstEntry, string firstEntryValue,
                                    string selectedValue = null)
        {
            dropDownList.Items.Clear();

            // handle the optional first (default) entry
            if (firstEntry != null)
            {
                if (firstEntryValue == null)
                {
                    firstEntryValue = firstEntry;
                }
                dropDownList.AddItem(firstEntry, firstEntryValue,
                                     firstEntryValue == selectedValue);
            }

            var locals = GetNamesDictionary(stateCode, countyCode);

            if (locals.Count == 0)
            {
                return(false);
            }
            foreach (var local in locals.OrderBy(kvp => kvp.Value))
            {
                dropDownList.AddItem(local.Value, local.Key, local.Key == selectedValue);
            }
            return(true);
        }
示例#2
0
        public static void Populate(HtmlSelect dropDownList, string firstEntry,
                                    string firstEntryValue, string selectedValue = null, bool clear = true)
        {
            if (clear)
            {
                dropDownList.Items.Clear();
            }

            // handle the optional first (default) entry
            if (firstEntry != null)
            {
                if (firstEntryValue == null)
                {
                    firstEntryValue = firstEntry;
                }
                dropDownList.AddItem(firstEntry, firstEntryValue,
                                     firstEntryValue == selectedValue);
            }

            // Add all real states (plus DC)
            foreach (var si in StateList)
            {
                if (si.IsState)
                {
                    dropDownList.AddItem(si.Name, si.StateCode, si.StateCode == selectedValue);
                }
            }
        }
示例#3
0
        private void CreateActionMenu(HtmlContainerControl menuContainer, IList <DataRow> responses,
                                      bool isNew)
        {
            menuContainer.Controls.Clear();
            new HtmlSpan {
                InnerText = "Select action:"
            }.AddTo(menuContainer);
            var dropdown = new HtmlSelect().AddTo(menuContainer);
            var edit     = dropdown.AddItem("Edit this response", "edit");
            var add      = dropdown.AddItem("Add another response to this question", "add");
            var view     = dropdown.AddItem("View or edit other responses to this question", "view");

            if (responses.Count == 0)
            {
                menuContainer.AddCssClasses("hidden");
            }
            else
            {
                menuContainer.RemoveCssClass("hidden");
            }
            if (isNew && responses.Count > 0)
            {
                edit.Attributes.Add("disabled", "disabled");
                add.Attributes.Add("selected", "selected");
            }
            else
            {
                edit.Attributes.Add("selected", "selected");
                if (responses.Count < 2)
                {
                    view.Attributes.Add("disabled", "disabled");
                }
            }
        }
示例#4
0
        public static bool Populate(HtmlSelect dropDownList, string stateCode, string firstEntry,
                                    string firstEntryValue, string selectedValue = null)
        {
            dropDownList.Items.Clear();

            // handle the optional first (default) entry
            if (firstEntry != null)
            {
                if (firstEntryValue == null)
                {
                    firstEntryValue = firstEntry;
                }
                dropDownList.AddItem(firstEntry, firstEntryValue,
                                     firstEntryValue == selectedValue);
            }

            if (IsNullOrWhiteSpace(stateCode))
            {
                return(false);
            }
            var counties = GetCountiesByState(stateCode);

            if (counties.Count == 0)
            {
                return(false);
            }
            foreach (var countyCode in counties)
            {
                dropDownList.AddItem(GetCountyName(stateCode, countyCode), countyCode,
                                     countyCode == selectedValue);
            }
            return(true);
        }
示例#5
0
 public static void PopulateNationalParties(HtmlSelect dropDownList,
                                            bool includeSpecial = true, string selectedValue = null, bool excludeAll = false,
                                            string firstItem    = "--- Select a party ---")
 {
     dropDownList.Items.Clear();
     if (!string.IsNullOrWhiteSpace(firstItem))
     {
         dropDownList.AddItem(firstItem, " ");
     }
     foreach (var kvp in GetNationalParties(includeSpecial))
     {
         if (!excludeAll || (kvp.Key != NationalPartyAll))
         {
             dropDownList.AddItem(kvp.Value, kvp.Key, kvp.Key == selectedValue);
         }
     }
 }
示例#6
0
 public static void PopulateFromList(HtmlSelect dropDownList,
                                     IEnumerable <SimpleListItem> list, string valueToSelect = null)
 {
     dropDownList.Items.Clear();
     foreach (var item in list)
     {
         dropDownList.AddItem(item.Text, item.Value, item.Value == valueToSelect);
     }
 }
        public static void PopulateElectionTypes(HtmlSelect dropDownList,
                                                 string stateCode, string selectedValue = null)
        {
            dropDownList.Items.Clear();

            foreach (var kvp in GetElectionTypes(stateCode))
            {
                dropDownList.AddItem(kvp.Value, kvp.Key, kvp.Key == selectedValue);
            }
        }
示例#8
0
        public static void PopulateMajorParties(HtmlSelect dropDownList,
                                                string stateCode, bool includeSpecial = true, string selectedValue = null)
        {
            dropDownList.Items.Clear();

            foreach (var kvp in GetMajorParties(stateCode, includeSpecial))
            {
                dropDownList.AddItem(kvp.Value, kvp.Key, kvp.Key == selectedValue);
            }
        }
示例#9
0
        //private static void CreateActionMenu(HtmlControl menuContainer, ICollection<DataRow> responses,
        //  bool isNew)
        //{
        //  menuContainer.Controls.Clear();
        //  new HtmlDiv { InnerText = $"{responses.Count} Response{(responses.Count == 1 ? Empty : "s")}" }
        //    .AddTo(menuContainer, "response-count");
        //  new HtmlSpan { InnerText = "What do you want to do?" }.AddTo(menuContainer);
        //  var dropdown = new HtmlSelect().AddTo(menuContainer);
        //  var edit = dropdown.AddItem("Edit this response", "edit");
        //  var add = dropdown.AddItem("Add another response to this question", "add");
        //  var view = dropdown.AddItem("View or edit other responses to this question", "view");
        //  if (responses.Count == 0)
        //    menuContainer.AddCssClasses("hidden");
        //  else
        //    menuContainer.RemoveCssClass("hidden");
        //  if (isNew && responses.Count > 0)
        //  {
        //    edit.Attributes.Add("disabled", "disabled");
        //    add.Attributes.Add("selected", "selected");
        //  }
        //  else
        //  {
        //    edit.Attributes.Add("selected", "selected");
        //    if (responses.Count < 2)
        //      view.Attributes.Add("disabled", "disabled");
        //  }
        //}

        private static void CreateActionMenu2(Control menuContainer, ICollection <DataRow> responses)
        {
            menuContainer.Controls.Clear();
            new HtmlDiv {
                InnerText = $"{responses.Count} Response{(responses.Count == 1 ? Empty : "s")}"
            }
            .AddTo(menuContainer, "response-count");
            if (responses.Count > 0)
            {
                new HtmlSpan {
                    InnerText = "What do you want to do?"
                }.AddTo(menuContainer);
                var dropdown = new HtmlSelect().AddTo(menuContainer);
                var edit     = dropdown.AddItem("Edit this response", "edit");
                /*var add = */ dropdown.AddItem("Add another response to this question", "add");
                var view = dropdown.AddItem("View or edit other responses to this question", "view");
                edit.Attributes.Add("selected", "selected");
                if (responses.Count == 1)
                {
                    view.Attributes.Add("disabled", "disabled");
                }
            }
            //new HtmlSpan { InnerText = "What do you want to do?" }.AddTo(menuContainer);
            //var dropdown = new HtmlSelect().AddTo(menuContainer);
            //var edit = dropdown.AddItem("Edit this response", "edit");
            //var add = dropdown.AddItem("Add another response to this question", "add");
            //var view = dropdown.AddItem("View or edit other responses to this question", "view");
            //if (responses.Count == 0)
            //  menuContainer.AddCssClasses("hidden");
            //else
            //  menuContainer.RemoveCssClass("hidden");
            //if (isNew && responses.Count > 0)
            //{
            //  edit.Attributes.Add("disabled", "disabled");
            //  add.Attributes.Add("selected", "selected");
            //}
            //else
            //{
            //  edit.Attributes.Add("selected", "selected");
            //  if (responses.Count < 2)
            //    view.Attributes.Add("disabled", "disabled");
            //}
        }
示例#10
0
 public static ListItem AddItem(this HtmlSelect htmlSelect, string text,
                                bool selected = false)
 {
     return(htmlSelect.AddItem(text, text, selected));
 }
示例#11
0
 public static void PopulateEmpty(HtmlSelect dropDownList,
                                  string text = "<none>")
 {
     dropDownList.Items.Clear();
     dropDownList.AddItem(text, string.Empty, true);
 }
示例#12
0
        private void PopulateWinnersTree_CreateNode(Control parent,
                                                    IEnumerable <DataRow> office, string className, bool useLine2Only = false)
        {
            var officeRows          = office.ToList();
            var officeInfo          = officeRows[0];
            var officeState         = Offices.GetStateCodeFromKey(officeInfo.OfficeKey());
            var electionState       = Elections.GetStateCodeFromKey(GetElectionKey());
            var canUpdateIncumbents = StateCache.IsValidStateCode(officeState) &&
                                      StateCache.IsValidStateCode(electionState);

            var winners = officeRows.Where(row => row.IsWinner())
                          .ToList();
            var candidates = officeRows.Where(row => !row.IsIncumbentRow())
                             .ToList();
            var advancers = candidates.Where(row => row.AdvanceToRunoff())
                            .ToList();
            // if any candidates are marked as AdvanceToRunoff, we default it as a runoff
            var isRunoff   = advancers.Count > 0;
            var incumbents = officeRows.Where(row => row.IsIncumbentRow())
                             .ToList();
            var incumbentsInElectionNotMarkedWinners = officeRows
                                                       .Where(row => !row.IsIncumbentRow() && !row.IsWinner() &&
                                                              (incumbents.FirstOrDefault(i => i.PoliticianKey()
                                                                                         .IsEqIgnoreCase(row.PoliticianKey())) != null))
                                                       .ToList();
            var defaultPoliticians = winners.Select(row => row.PoliticianKey())
                                     .Union(
                incumbentsInElectionNotMarkedWinners.Select(row => row.PoliticianKey()))
                                     .ToList();

            // Creating a dropdown for each Election position
            var dropdownContents = Enumerable.Range(0, officeInfo.ElectionPositions())
                                   .Select(n => new
            {
                DefaultPolitician = n < defaultPoliticians.Count ? defaultPoliticians[n] : string.Empty,
                List = new List <DataRow>(candidates)
            })
                                   .ToList();

            // Now create the node
            // Format the office description
            var text = useLine2Only
        ? officeInfo.OfficeLine2()
        : Offices.FormatOfficeName(officeInfo);

            var addClass = "office-name";

            if (!canUpdateIncumbents)
            {
                addClass += " no-checkbox";
            }
            if (!string.IsNullOrWhiteSpace(className))
            {
                addClass += " " + className;
            }
            var data = "key:'" + officeInfo.OfficeKey();

            if (canUpdateIncumbents)
            {
                data += "',addClass:'" + addClass + "',select:true";
            }
            else
            {
                data +=
                    "',addClass:'" + addClass + "',hideCheckbox:true,unselectable:true";
            }
            var officeNode = new HtmlLi().AddTo(parent);

            officeNode.Attributes.Add("data", data);
            new HtmlDiv {
                InnerHtml = text
            }.AddTo(officeNode, "label")
            .Attributes.Add("Title", text);
            var dropdownDiv = new HtmlDiv().AddTo(officeNode,
                                                  "dropdowns idwinners-" + officeInfo.OfficeKey());

            // if there is a possible runoff, create checkbox and runoff list
            var runoffPositions = officeInfo.GeneralRunoffPositions();

            if (runoffPositions != 0)
            {
                var minCandidates = runoffPositions == -1
          ? officeInfo.ElectionPositions() + 1
          : runoffPositions + 1;
                if (candidates.Count >= minCandidates)
                {
                    // if any candidates are marked as AdvanceToRunoff, we default it as a runoff
                    isRunoff = candidates.Any(row => row.AdvanceToRunoff());

                    var runnoffId = "runoff-" + officeInfo.OfficeKey();
                    var runoffDiv = new HtmlDiv().AddTo(dropdownDiv);
                    var runoffCheckbox = new HtmlInputCheckBox {
                        Checked = isRunoff
                    }.AddTo(runoffDiv,
                            "runoff-checkbox");
                    if (runoffPositions > 0)
                    {
                        runoffCheckbox.Attributes.Add("rel",
                                                      runoffPositions.ToString(CultureInfo.InvariantCulture));
                    }
                    new HtmlLabel
                    {
                        ID        = runnoffId,
                        InnerText = "Runoff is required"
                    }.AddTo(runoffDiv)
                    .Attributes["for"] = runnoffId;
                    var runoffsDiv = new HtmlDiv().AddTo(runoffDiv, "runoff-dropdown");
                    if (!isRunoff)
                    {
                        runoffsDiv.AddCssClasses("hidden");
                    }
                    else
                    {
                        runoffsDiv.RemoveCssClass("hidden");
                    }
                    new HtmlP
                    {
                        InnerText = "Select " + (runoffPositions == -1
              ? string.Empty
              : runoffPositions.ToString(CultureInfo.InvariantCulture)) + " candidates to advance"
                    }.AddTo(runoffsDiv);

                    var runoffList =
                        new HtmlSelect
                    {
                        EnableViewState = false,
                        Size            = candidates.Count,
                        Multiple        = true
                    }.AddTo(runoffsDiv);

                    foreach (var politician in candidates)
                    {
                        var name = Politicians.FormatName(politician);
                        if (!string.IsNullOrWhiteSpace(politician.PartyCode()))
                        {
                            name += " (" + politician.PartyCode() + ")";
                        }
                        var indicators = string.Empty;

                        // Add winner indicator
                        if (politician.AdvanceToRunoff())
                        {
                            indicators += "◄";
                        }

                        if (indicators != string.Empty)
                        {
                            name += " " + indicators;
                        }

                        runoffList.AddItem(name, politician.PoliticianKey(), politician.AdvanceToRunoff());
                    }
                }
            }

            var winnersDiv = new HtmlDiv().AddTo(dropdownDiv, "winners-dropdowns");

            if (isRunoff)
            {
                winnersDiv.AddCssClasses("hidden");
            }
            else
            {
                winnersDiv.RemoveCssClass("hidden");
            }

            // Create the dropdowns
            var inx = 0;

            foreach (var dropdownContent in dropdownContents)
            {
                var dropdownList =
                    new HtmlSelect {
                    EnableViewState = false
                }.AddTo(winnersDiv);

                if (inx >= winners.Count)
                {
                    dropdownList.AddCssClasses("bold");
                }

                // The first option in each dropdown is a disabled header
                var dropDownMessage = dropdownContent.List.Count > 0
          ? "Select winner or Vacant"
          : "No candidates";
                var option = dropdownList.AddItem(dropDownMessage, string.Empty,
                                                  dropdownContent.DefaultPolitician == string.Empty);
                option.Attributes.Add("disabled", "disabled");

                // Add an option for each politician
                foreach (
                    var politician in dropdownContent.List.OrderBy(row => row.LastName())
                    .ThenBy(row => row.FirstName()))
                {
                    var name = Politicians.FormatName(politician);
                    if (!string.IsNullOrWhiteSpace(politician.PartyCode()))
                    {
                        name += " (" + politician.PartyCode() + ")";
                    }
                    var indicators = string.Empty;

                    // Add winner indicator
                    if (winners.FirstOrDefault(winner => winner.PoliticianKey()
                                               .IsEqIgnoreCase(politician.PoliticianKey())) != null)
                    {
                        indicators += "◄";
                    }

                    if (indicators != string.Empty)
                    {
                        name += " " + indicators;
                    }

                    dropdownList.AddItem(name, politician.PoliticianKey(),
                                         dropdownContent.DefaultPolitician == politician.PoliticianKey());
                }

                // Add a "Vacant" option
                dropdownList.AddItem("Vacant", "vacant");
                inx++;
            }
        }
示例#13
0
        private int PopulateWinnersBetaTree(DataTable table, Control root)
        {
            void CreateNode(Control parent,
                            IEnumerable <DataRow> office, string className = null,
                            bool useLine2Only = false)
            {
                var candidates = office.ToList();
                var officeInfo = candidates[0];
                var winners    = candidates.Where(row => row.IsWinner()).ToList();
                var advancers  = candidates.Where(row => row.AdvanceToRunoff()).ToList();
                // if any candidates are marked as AdvanceToRunoff, we default it as a runoff
                var isRunoff = advancers.Count > 0;

                // Now create the node
                // Format the office description
                var text = useLine2Only
          ? officeInfo.OfficeLine2()
          : Offices.FormatOfficeName(officeInfo);

                // Include the position slot count if > 1
                if (officeInfo.PrimaryPositions() > 1)
                {
                    text = $"{text} [{officeInfo.PrimaryPositions()}]";
                }

                var addClass = "office-name no-checkbox";

                if (!IsNullOrWhiteSpace(className))
                {
                    addClass += " " + className;
                }
                var data = "key:'" + officeInfo.OfficeKey() + "',addClass:'" + addClass +
                           "',hideCheckbox:true,unselectable:true";
                var officeNode = new HtmlLi().AddTo(parent);

                officeNode.Attributes.Add("data", data);
                new HtmlDiv {
                    InnerHtml = text
                }.AddTo(officeNode, "label");
                var dropdownDiv = new HtmlDiv().AddTo(officeNode,
                                                      "dropdowns idwinners-" + officeInfo.OfficeKey());

                // if there is a possible runoff, create checkbox and runoff list
                var runoffPositions = officeInfo.PrimaryRunoffPositions();

                if (runoffPositions != 0)
                {
                    var minCandidates = runoffPositions == -1
            ? officeInfo.PrimaryPositions() + 1
            : runoffPositions + 1;
                    if (candidates.Count >= minCandidates)
                    {
                        // if any candidates are marked as AdvanceToRunoff, we default it as a runoff
                        isRunoff = candidates.Any(row => row.AdvanceToRunoff());

                        var runnoffId      = "runoff-" + officeInfo.OfficeKey();
                        var runoffDiv      = new HtmlDiv().AddTo(dropdownDiv);
                        var runoffCheckbox =
                            new HtmlInputCheckBox {
                            Checked = isRunoff
                        }.AddTo(runoffDiv, "runoff-checkbox");
                        if (runoffPositions > 0)
                        {
                            runoffCheckbox.Attributes.Add("rel",
                                                          runoffPositions.ToString(CultureInfo.InvariantCulture));
                        }
                        new HtmlLabel {
                            ID = runnoffId, InnerText = "Runoff is required"
                        }.AddTo(runoffDiv)
                        .Attributes["for"] = runnoffId;
                        var runoffsDiv = new HtmlDiv().AddTo(runoffDiv, "runoff-dropdown");
                        if (!isRunoff)
                        {
                            runoffsDiv.AddCssClasses("hidden");
                        }
                        else
                        {
                            runoffsDiv.RemoveCssClass("hidden");
                        }
                        new HtmlP
                        {
                            InnerText = "Select " +
                                        (runoffPositions == -1
                  ? Empty
                  : runoffPositions.ToString(CultureInfo.InvariantCulture)) +
                                        " candidates to advance"
                        }.AddTo(runoffsDiv);

                        var runoffList = new HtmlSelect
                        {
                            EnableViewState = false,
                            Size            = candidates.Count,
                            Multiple        = true
                        }.AddTo(runoffsDiv);

                        foreach (var politician in candidates)
                        {
                            var name = Politicians.FormatName(politician);
                            if (!IsNullOrWhiteSpace(politician.PartyCode()))
                            {
                                name += $" ({politician.PartyCode()})";
                            }
                            var indicators = Empty;

                            // Add winner indicator
                            if (politician.AdvanceToRunoff())
                            {
                                indicators += "◄";
                            }

                            if (indicators != Empty)
                            {
                                name += " " + indicators;
                            }

                            runoffList.AddItem(name, politician.PoliticianKey(),
                                               politician.AdvanceToRunoff());
                        }
                    }
                }

                var winnersDiv = new HtmlDiv().AddTo(dropdownDiv, "winners-dropdowns");

                if (isRunoff)
                {
                    winnersDiv.AddCssClasses("hidden");
                }
                else
                {
                    winnersDiv.RemoveCssClass("hidden");
                }

                if (candidates.Count <= officeInfo.PrimaryPositions())
                {
                    // uncontested -- create a disabled dropdown for each candidate
                    foreach (var politician in candidates)
                    {
                        var dropdownList = new HtmlSelect {
                            EnableViewState = false
                        }.AddTo(winnersDiv);
                        dropdownList.Attributes.Add("disabled", "disabled");

                        var name = Politicians.FormatName(politician);
                        if (!IsNullOrWhiteSpace(politician.PartyCode()))
                        {
                            name += $" ({politician.PartyCode()})";
                        }
                        var indicators = Empty;

                        // Add winner indicator
                        if (winners.FirstOrDefault(winner => winner.PoliticianKey()
                                                   .IsEqIgnoreCase(politician.PoliticianKey())) != null)
                        {
                            indicators += "◄";
                        }

                        if (indicators != Empty)
                        {
                            name += " " + indicators;
                        }

                        dropdownList.AddItem(name, politician.PoliticianKey(), true);
                    }
                }
                else
                {
                    // contested -- create a dropdown for each already-identified winner,
                    // with the default selection as the winner
                    //// and the other winners removed from the list
                    var dropdownContents = winners.Select(winner => new
                    {
                        DefaultPolitician = winner.PoliticianKey(),
                        List = candidates.Where(row =>
                                                //  row.PoliticianKey() == winner.PoliticianKey() ||
                                                //    !row.IsWinner()
                                                true).ToList()
                    }).ToList();

                    // Create the winner dropdowns
                    foreach (var dropdownContent in dropdownContents)
                    {
                        var dropdownList = new HtmlSelect {
                            EnableViewState = false
                        }.AddTo(winnersDiv);
                        dropdownList.Attributes.Add("title", "Select one");

                        // allow unselect
                        dropdownList.AddItem("Unselect Winner", Empty);

                        // Add an option for each politician
                        foreach (var politician in dropdownContent.List.OrderBy(row => row.LastName())
                                 .ThenBy(row => row.FirstName()))
                        {
                            var name = Politicians.FormatName(politician);
                            if (!IsNullOrWhiteSpace(politician.PartyCode()))
                            {
                                name += $" ({politician.PartyCode()})";
                            }
                            var indicators = Empty;

                            // Add winner indicator
                            if (winners.FirstOrDefault(winner => winner.PoliticianKey()
                                                       .IsEqIgnoreCase(politician.PoliticianKey())) != null)
                            {
                                indicators += "◄";
                            }

                            if (indicators != Empty)
                            {
                                name += " " + indicators;
                            }

                            dropdownList.AddItem(name, politician.PoliticianKey(),
                                                 !isRunoff && dropdownContent.DefaultPolitician == politician.PoliticianKey());
                        }
                    }

                    // if there are more positions than already-identified winners and some non-winning candidates,
                    // fill out with undefaulted lists that contain all candidates
                    if (winners.Count < officeInfo.PrimaryPositions())
                    {
                        var nonWinners = candidates.Where(row => !row.IsWinner()).ToList();
                        var counter    = Math.Min(nonWinners.Count,
                                                  officeInfo.PrimaryPositions() - winners.Count);
                        while (counter-- > 0)
                        {
                            var dropdownList = new HtmlSelect {
                                EnableViewState = false
                            }.AddTo(winnersDiv)
                            .AddCssClasses("bold") as HtmlSelect;
                            Debug.Assert(dropdownList != null, "dropdownList != null");
                            dropdownList.Attributes.Add("title", "Select one");

                            // The first option in each dropdown is a disabled header
                            var option = dropdownList.AddItem("Select Winner", Empty, true);
                            option.Attributes.Add("disabled", "disabled");

                            // Add an option for each politician
                            foreach (var politician in candidates.OrderBy(row => row.LastName())
                                     .ThenBy(row => row.FirstName()))
                            {
                                var name = Politicians.FormatName(politician);
                                if (!IsNullOrWhiteSpace(politician.PartyCode()))
                                {
                                    name += $" ({politician.PartyCode()})";
                                }

                                dropdownList.AddItem(name, politician.PoliticianKey());
                            }
                        }
                    }
                }
            }

            var officeCount = 0;

            root.Controls.Clear();
            var tree = new HtmlUl().AddTo(root);

            const string rootText = "Select the Winner(s) for Each Contested Primary Office";
            const string rootData =
                "addClass:'root-node no-checkbox',hideCheckbox:true,unselectable:true";

            var rootNode = new HtmlLi {
                InnerHtml = rootText
            }.AddTo(tree);

            rootNode.Attributes.Add("data", rootData);
            var rootTree = new HtmlUl().AddTo(rootNode);

            var officeClasses = table.Rows.Cast <DataRow>().GroupBy(row => row.OfficeClass());
            var even          = false;

            foreach (var officeClass in officeClasses)
            {
                var offices = officeClass.GroupBy(row => row.OfficeKey()).ToList();
                officeCount += offices.Count;
                if (offices.Count == 1)
                {
                    CreateNode(rootTree, offices[0], "odd");
                    even = !even;
                }
                else
                {
                    // If all OfficeLine1's are identical, don't show them
                    var hasVariedLine1 = offices.Exists(row => row.First().OfficeLine1() !=
                                                        offices[0].First().OfficeLine1());
                    var text = Offices.GetOfficeClassShortDescription(officeClass.Key, StateCode);
                    var classNode = new HtmlLi {
                        InnerHtml = text
                    }.AddTo(rootTree);
                    classNode.Attributes.Add("data",
                                             "addClass:'office-class no-checkbox office-class-" + officeClass.Key +
                                             "',key:'office-class-" + officeClass.Key +
                                             "',hideCheckbox:true,unselectable:true");
                    var classSubTree = new HtmlUl().AddTo(classNode);
                    foreach (var office in offices)
                    {
                        CreateNode(classSubTree, office,
                                   /*even ? "even" :*/ "odd", !hasVariedLine1);
                        even = !even;
                    }
                }
            }
            return(officeCount);
        }