private static HtmlGenericControl CreateDropdownMenu() { var ul = new HtmlUl(); ul.Attributes.Add("class", "admin-dropdown"); return(ul); }
//private int PopulateWinnersTreeOld(DataTable table, Control parent, // bool isPrimary) //{ // var officeCount = 0; // parent.Controls.Clear(); // var tree = new HtmlUl().AddTo(parent); // var rootText = isPrimary // ? "Cannot update incumbents for primary election" // : "Check to update incumbents in addition to recording winners"; // var rootData = isPrimary // ? "addClass:'root-node no-checkbox',hideCheckbox:true,unselectable:true" // : "addClass:'root-node'"; // 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()); // foreach (var officeClass in officeClasses) // { // var offices = officeClass.GroupBy(row => row.OfficeKey()) // .ToList(); // officeCount += offices.Count; // if (offices.Count == 1) // PopulateWinnersTree_CreateNodeOld(rootTree, offices[0], false, false); // 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 office-class-" + officeClass.Key + // "',key:'office-class-" + officeClass.Key + "'"); // var classSubTree = new HtmlUl().AddTo(classNode); // foreach (var office in offices) // PopulateWinnersTree_CreateNodeOld(classSubTree, office, !hasVariedLine1, isPrimary); // } // } // return officeCount; //} //private void PopulateWinnersTree_CreateNodeOld(Control parent, // IEnumerable<DataRow> office, bool useLine2Only = false, // bool isPrimary = 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) && !isPrimary; // var winners = officeRows.Where(row => row.IsWinner()) // .ToList(); // var candidates = officeRows.Where(row => !row.IsIncumbentRow()) // .ToList(); // var incumbents = officeRows.Where(row => row.IsIncumbentRow()) // .ToList(); // // We begin by creating a dropdown for each already-identified winner, // // with the default selection as the winner. // var dropdownContents = // winners.Select( // winner => // new // { // DefaultPolitician = winner.PoliticianKey(), // List = new List<DataRow>(candidates) // }) // .ToList(); // if (dropdownContents.Count < officeInfo.Incumbents()) // // We need additional dropdowns // // If this is a single incumbent office, we add incumbent as // // default selection only if a candidate // if (officeInfo.Incumbents() == 1) // dropdownContents.AddRange(incumbents.Where( // incumbent => // candidates.FirstOrDefault(candidate => candidate.PoliticianKey() // .IsEqIgnoreCase(incumbent.PoliticianKey())) != null) // .Select( // incumbent => // new // { // DefaultPolitician = incumbent.PoliticianKey(), // List = new List<DataRow>(candidates) // })); // else // // There are multiple incumbent slots // if (winners.Count > 0) // // There were winners, but not enough to fill all slots. // // We add any incumbents NOT in the election as defaults, along // // with all candidates // dropdownContents.AddRange(incumbents.Where( // incumbent => // candidates.FirstOrDefault(candidate => candidate.PoliticianKey() // .IsEqIgnoreCase(incumbent.PoliticianKey())) == null) // .Select( // incumbent => // new // { // DefaultPolitician = incumbent.PoliticianKey(), // List = // new List<DataRow>( // candidates.Union(new List<DataRow> { incumbent })) // })); // else // // No winners were identified. Add all incumbents as defaults, // // whether in the election or not. The Where on candidates is to // // prevent a duplicate entry when the incumbent is in the election // dropdownContents.AddRange( // incumbents.Select( // incumbent => // new // { // DefaultPolitician = incumbent.PoliticianKey(), // List = // new List<DataRow>(candidates.Where( // candidate => candidate.PoliticianKey() // .IsNeIgnoreCase(incumbent.PoliticianKey())) // .Union(new List<DataRow> { incumbent })) // })); // // If there are still office slots to fill, fill them out with undefaulted // // candidate lists. // while (dropdownContents.Count < officeInfo.Incumbents()) // dropdownContents.Add( // new // { // DefaultPolitician = String.Empty, // List = new List<DataRow>(candidates) // }); // // Now create the node // // Format he office description // var text = useLine2Only // ? officeInfo.OfficeLine2() // : Offices.FormatOfficeName(officeInfo); // // Include the incumbent slot count if > 1 // if (officeInfo.Incumbents() > 1) // text = String.Format("{0} [{1}]", text, officeInfo.Incumbents()); // var data = "key:'" + officeInfo.OfficeKey(); // if (canUpdateIncumbents) // data += "',addClass:'office-name'"; // else // data += // "',addClass:'office-name no-checkbox',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()); // // Create the dropdowns // foreach (var dropdownContent in dropdownContents) // { // var dropdownList = // new HtmlSelect { EnableViewState = false }.AddTo(dropdownDiv); // // The first option in each dropdown is a disabled header // var dropDownMessage = officeInfo.Incumbents() == 1 // ? "Select winner or Vacant" // : "Select winner, incumbent or Vacant"; // 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 += "◄"; // // Add incumbent indicator // if (incumbents.FirstOrDefault(incumbent => incumbent.PoliticianKey() // .IsEqIgnoreCase(politician.PoliticianKey())) != null) // if (candidates.FirstOrDefault(candidate => candidate.PoliticianKey() // .IsEqIgnoreCase(politician.PoliticianKey())) != null) // indicators += "■"; // else // indicators += "□"; // if (indicators != String.Empty) // name += " " + indicators; // dropdownList.AddItem(name, politician.PoliticianKey(), // dropdownContent.DefaultPolitician == politician.PoliticianKey()); // } // // Add a "Vacant" option // dropdownList.AddItem("Vacant", "vacant"); // } //} private int PopulateWinnersTree(DataTable table, Control parent) { var officeCount = 0; parent.Controls.Clear(); var tree = new HtmlUl().AddTo(parent); const string rootText = "Check to update incumbents in addition to recording winners"; const string rootData = "addClass:'root-node'"; 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) { PopulateWinnersTree_CreateNode(rootTree, offices[0], /*even ? "even" :*/ "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 office-class-" + officeClass.Key + "',key:'office-class-" + officeClass.Key + "'"); var classSubTree = new HtmlUl().AddTo(classNode); foreach (var office in offices) { PopulateWinnersTree_CreateNode(classSubTree, office, /*even ? "even" :*/ "odd", !hasVariedLine1); } even = !even; } } return(officeCount); }
public static int PopulateOfficeTree(IList <DataRow> table, Control parent, string stateCode, bool withCheckboxes = false, bool includeVirtual = false, bool integrateVirtual = false, bool stateLevel = false, Control relatedJurisdictionsNodes = null) { parent.Controls.Clear(); var tree = new HtmlUl().AddTo(parent); var officeCount = 0; // exclude virtual unless integrated var officeClasses = table .Where(row => !row.IsVirtual() || integrateVirtual) .GroupBy(row => stateLevel ? row.OfficeClass() : OfficeClass.Undefined).ToList(); if (officeClasses.Count == 0) { new HtmlLi { InnerHtml = "No offices were found for this jurisdiction" }.AddTo(tree); } else { officeCount = PopulateOfficeTree_CreateNodes(stateCode, withCheckboxes, officeClasses, officeCount, tree); } if (includeVirtual) { if (!table.Any(row => row.IsVirtual())) { new HtmlLi { InnerHtml = "No county or local office templates for this state" }.AddTo(tree); } else { var countyTemplates = table .Where(row => row.IsVirtual() && string.IsNullOrWhiteSpace(Offices.GetLocalCodeFromKey(row.OfficeKey()))) .GroupBy(row => row.OfficeClass()).ToList(); officeCount = PopulateOfficeTree_CreateNodes(stateCode, withCheckboxes, countyTemplates, officeCount, tree, true); var localTemplates = table .Where(row => row.IsVirtual() && !string.IsNullOrWhiteSpace(Offices.GetLocalCodeFromKey(row.OfficeKey()))) .GroupBy(row => row.OfficeClass()).ToList(); officeCount = PopulateOfficeTree_CreateNodes(stateCode, withCheckboxes, localTemplates, officeCount, tree, true); } } relatedJurisdictionsNodes?.AddTo(tree); return(officeCount); }
public static Control CreateRelatedJurisdictionsNodes(string href, string tab, string stateCode, string countyCode, string localKey) { if (!StateCache.IsValidStateCode(stateCode)) { return(new PlaceHolder()); } var mainNode = new HtmlLi { InnerHtml = "Related Jurisdictions" }; var data = "addClass:'related-jurisdictions office-class',hideCheckbox:true,unselectable:true"; // start this node expanded if county or local if (!IsNullOrWhiteSpace(countyCode) || !IsNullOrWhiteSpace(localKey)) { data += ", expand:true"; } mainNode.Attributes.Add("data", data); var subTree = new HtmlUl().AddTo(mainNode); if (!IsNullOrWhiteSpace(localKey)) { // For Locals, the state, the county, and all other locals CreateRelatedJurisdictionsNode(subTree, StateCache.GetStateName(stateCode), href, tab, stateCode, Empty, Empty); CreateRelatedJurisdictionsNode(subTree, MakeJurisdictionName(CountyCache.GetCountyName(stateCode, countyCode), countyCode, "County {0}"), href, tab, stateCode, countyCode, Empty); foreach (var l in LocalDistricts.GetLocalsForCounty(stateCode, countyCode).Rows .OfType <DataRow>().OrderBy(l => l.LocalDistrict(), new AlphanumericComparer())) { if (l.LocalKey() != localKey) { CreateRelatedJurisdictionsNode(subTree, MakeJurisdictionName(l.LocalDistrict(), l.LocalKey(), "Local District {0}"), href, tab, stateCode, countyCode, l.LocalKey()); } } } else if (!IsNullOrWhiteSpace(countyCode)) { // For Counties, the state and all other counties (in sub-tree) plus all locals for the county CreateRelatedJurisdictionsNode(subTree, StateCache.GetStateName(stateCode), href, tab, stateCode, Empty, Empty); var subNode = new HtmlLi { InnerHtml = "Counties" }; const string subData = "addClass:'office-class',hideCheckbox:true,unselectable:true"; subNode.Attributes.Add("data", subData); subNode.AddTo(subTree); var subSubTree = new HtmlUl().AddTo(subNode); foreach (var c in CountyCache.GetCountiesByState(stateCode)) { if (c != countyCode) { CreateRelatedJurisdictionsNode(subSubTree, MakeJurisdictionName(CountyCache.GetCountyName(stateCode, c), c, "County {0}"), href, tab, stateCode, c, Empty); } } foreach (var l in LocalDistricts.GetLocalsForCounty(stateCode, countyCode).Rows .OfType <DataRow>().OrderBy(l => l.LocalDistrict(), new AlphanumericComparer())) { CreateRelatedJurisdictionsNode(subTree, MakeJurisdictionName(l.LocalDistrict(), l.LocalKey(), "Local District {0}"), href, tab, stateCode, countyCode, l.LocalKey()); } } else { // For State, a list of counties foreach (var c in CountyCache.GetCountiesByState(stateCode)) { CreateRelatedJurisdictionsNode(subTree, MakeJurisdictionName(CountyCache.GetCountyName(stateCode, c), c, "County {0}"), href, tab, stateCode, c, Empty); } } return(mainNode); }
public static int PopulateOfficeTree(IList <DataRow> table, Control root, string stateCode, bool withCheckboxes = false, bool includeVirtual = false, bool integrateVirtual = false, bool stateLevel = false, Control relatedJurisdictionsNodes = null) { root.Controls.Clear(); var tree = new HtmlUl().AddTo(root); var officeCount = 0; // ReSharper disable once ImplicitlyCapturedClosure void CreateNode(Control parent, DataRow office, bool useLine2Only = false, bool isTemplates = false) { useLine2Only &= office.OfficeClass() != OfficeClass.USPresident; var text = useLine2Only && !IsNullOrWhiteSpace(office.OfficeLine2()) ? office.OfficeLine2() : Offices.FormatOfficeName(office); var candidateCount = office.Table.Columns.Contains("CandidateCountForOffice") ? office.CandidateCountForOffice() : 0; var isOfficeInElection = office.Table.Columns.Contains("IsOfficeInElection") && office.IsOfficeInElection(); int?positions = null; if (office.Table.Columns.Contains("ElectionType") && office.Table.Columns.Contains("ElectionPositions") && office.Table.Columns.Contains("PrimaryPositions") && office.Table.Columns.Contains("PrimaryRunoffPositions") && office.Table.Columns.Contains("GeneralRunoffPositions")) { positions = Elections.GetOfficePositions(office); } var classes = "office-name"; if (isTemplates) { classes += " template-node"; } if (office.IsInactiveOptional()) { classes += " inactive-node"; text += " (inactive)"; } var data = "key:'" + office.OfficeKey() + "',addClass:'" + classes + "',desc:'" + Offices.FormatOfficeName(office.OfficeKey()).JavascriptEscapeString() + "'"; if (candidateCount > 0 || isOfficeInElection) { text = $"{text} [{candidateCount}]"; if (withCheckboxes) { data += ",candidates:" + candidateCount; } } var officeNode = new HtmlLi { InnerHtml = text, ID = "officekey-" + office.OfficeKey() } .AddTo(parent); if (withCheckboxes && isOfficeInElection) { data += ",select:true"; } //disable "undeletable" //if (office.Undeletable()) data += ",undeletable:true"; if (positions != null) { data += ",positions:" + positions; } officeNode.Attributes.Add("data", data); } void CreateNodes(IEnumerable <IGrouping <OfficeClass, DataRow> > classes, bool isTemplates = false) { foreach (var officeClass in classes) { var offices = officeClass.OrderBy(row => Offices.FormatOfficeName(row), MixedNumericComparer.Instance).ToList(); // If there is only one office in the class, don't create a class node // Also, no class node for county and local (indicated by OfficeClass.Undefined) officeCount += offices.Count; if (offices.Count == 1 && !isTemplates || officeClass.Key == OfficeClass.Undefined) { foreach (var office in offices) { CreateNode(tree, office, withCheckboxes); } } else { bool useLine2Only; switch (officeClass.Key) { case OfficeClass.USSenate: case OfficeClass.USHouse: case OfficeClass.StateSenate: case OfficeClass.StateHouse: { // For these office classes, if all OfficeLine1's are identical and no // OfficeLine2's are blank, don't the OfficeLine1's var hasVariedLine1 = offices.Exists(row => row.OfficeLine1() != offices[0].OfficeLine1()); useLine2Only = !hasVariedLine1 && !offices.Exists(row => IsNullOrWhiteSpace(row.OfficeLine2())); break; } default: useLine2Only = false; break; } var text = Offices.GetOfficeClassShortDescription(officeClass.Key, stateCode); if (isTemplates) { text += " templates"; } var classNode = new HtmlLi { InnerHtml = text }.AddTo(tree); var classNames = "office-class"; if (isTemplates) { classNames += " template-node"; } if (offices.All(o => o.IsInactiveOptional())) { classNames += " inactive-node"; } var data = "addClass:'" + classNames + "'"; if (!withCheckboxes) { data += ",unselectable:true"; } classNode.Attributes.Add("data", data); var classSubTree = new HtmlUl().AddTo(classNode); foreach (var office in offices) { CreateNode(classSubTree, office, useLine2Only, isTemplates); } } } } // exclude virtual unless integrated var officeClasses = table.Where(row => !row.IsVirtual() || integrateVirtual) .GroupBy(row => stateLevel ? row.OfficeClass() : OfficeClass.Undefined).ToList(); if (officeClasses.Count == 0) { new HtmlLi { InnerHtml = "No offices were found for this jurisdiction" } }
private int PopulateWinnersTree(DataTable table, Control root) { void 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] : 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 (!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 ? 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"); } // 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, Empty, dropdownContent.DefaultPolitician == 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 (!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(), dropdownContent.DefaultPolitician == politician.PoliticianKey()); } // Add a "Vacant" option dropdownList.AddItem("Vacant", "vacant"); inx++; } } var officeCount = 0; root.Controls.Clear(); var tree = new HtmlUl().AddTo(root); const string rootText = "Check to update incumbents in addition to recording winners"; const string rootData = "addClass:'root-node'"; 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], /*even ? "even" :*/ "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 office-class-" + officeClass.Key + "',key:'office-class-" + officeClass.Key + "'"); var classSubTree = new HtmlUl().AddTo(classNode); foreach (var office in offices) { CreateNode(classSubTree, office, /*even ? "even" :*/ "odd", !hasVariedLine1); } even = !even; } } return(officeCount); }
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); }
private void BuildMainMenu(Control parent) { var ul = new HtmlUl(); _Root = ul; parent.Controls.Add(ul); ul.Attributes.Add("class", "main-admin-menu"); if (SecurePage.IsMasterUser) { AddMenuItem(ul, "Master Panel", "/master/"); AddJurisdictionsMenu(ul); AddMenuItem(ul, "States", GetStatesMenu()); AddCountiesMenu(ul); AddLocalsMenu(ul); AddElectionsMenu(ul); AddMasterOfficesMenu(ul); AddMenuItem(ul, "Parties", GetPartiesMenu()); AddMenuItem(ul, "Politicians", GetPoliticiansMenu()); AddPoliticianMenu(ul); AddMenuItem(ul, "Issues", GetIssuesMenu()); AddMenuItem(ul, "Master Only", GetSiteAdminMenu()); AddMenuItem(ul, "Help", GetMasterHelpMenu()); } else if (SecurePage.IsStateAdminUser) { AddMenuItem(ul, SecurePage.UserStateCode + " State Admin", "/admin/"); AddCountiesMenu(ul); AddLocalsMenu(ul); AddJurisdictionsMenu(ul); AddElectionsMenu(ul); AddMenuItem(ul, "Offices", GetOfficesMenu()); AddMenuItem(ul, "Issues", "/admin/issues.aspx"); AddMenuItem(ul, "Parties", "/admin/parties.aspx"); AddMenuItem(ul, "Politicians", "/admin/politicians.aspx"); AddMenuItem(ul, "Help", GetAdminHelpMenu()); } else if (SecurePage.IsCountyAdminUser) { AddMenuItem(ul, Counties.GetCounty(SecurePage.UserStateCode, SecurePage.UserCountyCode) + " Admin", "/admin/"); AddLocalsMenu(ul); AddJurisdictionsMenu(ul); AddElectionsMenu(ul); AddMenuItem(ul, "Offices", GetOfficesMenu()); AddMenuItem(ul, "Help", GetAdminHelpMenu()); } else if (SecurePage.IsLocalAdminUser) { AddMenuItem(ul, LocalDistricts.GetLocalDistrictByStateCodeLocalKey(SecurePage.UserStateCode, SecurePage.UserLocalKey) + " Admin", "/admin/"); AddJurisdictionsMenu(ul); AddElectionsMenu(ul); AddMenuItem(ul, "Offices", GetOfficesMenu()); AddMenuItem(ul, "Help", GetAdminHelpMenu()); } else if (SecurePage.IsPoliticianUser) { AddPoliticianMenuItems(ul); } else if (SecurePage.IsPartyUser) { AddMenuItem(ul, "Help", GetPartyHelpMenu()); } // remove an empty menu if (ul.Controls.Count == 0) { parent.Controls.Remove(ul); } }
private static void CreateAnswerControls(HtmlControl parent, IList <DataRow> responses, int duplicate) { var row = responses.First(); var responsesAsDataRow = responses.Where(r => r.SequenceOrNull() != null).ToList(); parent.AddCssClasses("answer-panel " + (IsPoliticianUser ? "politician-answer-panel" : "master-answer-panel")); var questionId = row.QuestionId(); var questionIdUnique = $"{questionId}-{duplicate}"; // The panel title var heading = AddContainer(parent, null, null); // Add undo button as next sibling to heading var undo = CreateUndoButton("Undo" + questionIdUnique, "undo" + questionId, $"Revert \"{row.Question()}\" to the latest saved version"); heading.AddAfter(undo); // Same for clear button var clear = CreateClearButton("Clear" + questionIdUnique, "clear" + questionId, $"Clear \"{row.Question()}\""); heading.AddAfter(clear); var container = AddContainer(parent, "Container" + questionIdUnique, $"container{questionId} update-all updated answer-container" ); container.Attributes.Add("data-id", questionId.ToString()); AddHiddenField(container, "Description" + questionIdUnique, "description" + questionId, row.Question()); AddHiddenField(container, "SubTab" + questionIdUnique, "subtab subtab-" + questionId); var hasNoResponses = row.SequenceOrNull() == null; var sequenceItem = AddHiddenField(container, "Sequence" + questionIdUnique, $"answer-sequence sequence{questionId}", hasNoResponses ? "?" : row.SequenceOrNull()?.ToString(CultureInfo.InvariantCulture)); SetResponseData(questionId, responsesAsDataRow, sequenceItem); // the action menu var menuOuter = new HtmlDiv().AddTo(container, "menu-outer"); var menuContainer = AddContainer(menuOuter, "Action" + questionIdUnique, $"action-menu action{questionId}"); CreateActionMenu2(menuContainer, responsesAsDataRow /*, row.SequenceOrNull() == null*/); new HtmlP { InnerHtml = "To completely delete a response (Text and YouTube Video), use the Clear button (red <span>X</span> upper right) then Save Changes." }.AddTo(container, "delete-message"); var subTabs = new HtmlDiv { ID = "answer-subtabs-" + questionIdUnique, ClientIDMode = ClientIDMode.Static }.AddTo(container, $"answer-subtabs-{questionId} answer-sub-tabs shadow"); var subTabsTabs = new HtmlUl().AddTo(subTabs, "htabs unselectable"); var textSubTab = new HtmlLi { EnableViewState = false }.AddTo(subTabsTabs, "tab htab"); new HtmlAnchor { HRef = "#tab-textanswer-" + questionIdUnique, InnerHtml = "Text<br />Response", EnableViewState = false }.AddTo(textSubTab); var youTubeSubTab = new HtmlLi { EnableViewState = false }.AddTo(subTabsTabs, "tab htab"); new HtmlAnchor { HRef = "#tab-youtubeanswer-" + questionIdUnique, InnerHtml = "YouTube<br />Response", EnableViewState = false }.AddTo(youTubeSubTab); var textSubTabContent = new HtmlDiv { ID = "tab-textanswer-" + questionIdUnique, ClientIDMode = ClientIDMode.Static }.AddTo(subTabs, $"tab-textanswer-{questionId}"); var youTubeSubTabContent = new HtmlDiv { ID = "tab-youtubeanswer-" + questionIdUnique, ClientIDMode = ClientIDMode.Static }.AddTo(subTabs, $"tab-youtubeanswer-{questionId}"); AddHiddenField(container, "HasValue" + questionIdUnique, $"hasvalue{questionId}", IsNullOrWhiteSpace(row.Answer()) && IsNullOrWhiteSpace(row.YouTubeUrl()) && (IsNullOrWhiteSpace(row.FacebookVideoUrl()) || !AllowFacebookVideos) ? Empty : "Y"); CreateTextSubTabContent(textSubTabContent, row, duplicate); CreateYouTubeSubTabContent(youTubeSubTabContent, row, duplicate); AddClearBoth(container); }
private static int PopulateOfficeTree_CreateNodes(string stateCode, bool withCheckboxes, IEnumerable <IGrouping <OfficeClass, DataRow> > officeClasses, int officeCount, Control tree, bool isTemplates = false) { foreach (var officeClass in officeClasses) { var offices = officeClass .OrderBy(row => Offices.FormatOfficeName(row), MixedNumericComparer.Instance) .ToList(); // If there is only one office in the class, don't create a class node // Also, no class node for county and local (indicated by OfficeClass.Undefined) officeCount += offices.Count; if (((offices.Count == 1) && !isTemplates) || (officeClass.Key == OfficeClass.Undefined)) { foreach (var office in offices) { PopulateOfficeTree_CreateNode(tree, office, withCheckboxes); } } else { bool useLine2Only; switch (officeClass.Key) { case OfficeClass.USSenate: case OfficeClass.USHouse: case OfficeClass.StateSenate: case OfficeClass.StateHouse: { // For these office classes, if all OfficeLine1's are identical and no // OfficeLine2's are blank, don't the OfficeLine1's var hasVariedLine1 = offices.Exists(row => row.OfficeLine1() != offices[0].OfficeLine1()); useLine2Only = !hasVariedLine1 && !offices.Exists(row => string.IsNullOrWhiteSpace(row.OfficeLine2())); break; } default: useLine2Only = false; break; } var text = Offices.GetOfficeClassShortDescription(officeClass.Key, stateCode); if (isTemplates) { text += " templates"; } var classNode = new HtmlLi { InnerHtml = text }.AddTo(tree); var classes = "office-class"; if (isTemplates) { classes += " template-node"; } if (offices.All(o => o.IsInactiveOptional())) { classes += " inactive-node"; } var data = "addClass:'" + classes + "'"; if (!withCheckboxes) { data += ",unselectable:true"; } classNode.Attributes.Add("data", data); var classSubTree = new HtmlUl().AddTo(classNode); foreach (var office in offices) { PopulateOfficeTree_CreateNode(classSubTree, office, withCheckboxes, useLine2Only, isTemplates); } } } return(officeCount); }
private void BuildMainMenu(Control parent) { var ul = new HtmlUl(); _Root = ul; parent.Controls.Add(ul); ul.Attributes.Add("class", "main-admin-menu"); if (SecurePage.IsMasterUser) { AddMenuItem(ul, "Master Panel", "/master"); AddJurisdictionsMenu(ul); //AddMenuItem(ul, "State Admin", GetStatesMenu("/admin?state={StateCode}")); AddMenuItem(ul, "States", GetStatesMenu()); AddCountiesMenu(ul); AddLocalsMenu(ul); AddElectionsMenu(ul); AddOfficesMenu(ul); AddMenuItem(ul, "Parties", GetPartiesMenu()); //AddMenuItem(ul, "Federal", GetFederalMenu()); AddMenuItem(ul, "Politicians", GetPoliticiansMenu()); AddPoliticianMenu(ul); AddMenuItem(ul, "Issues", GetIssuesMenu()); AddMenuItem(ul, "Master Only", GetSiteAdminMenu()); AddMenuItem(ul, "Help", GetMasterHelpMenu()); } else if (SecurePage.IsStateAdminUser) { AddJurisdictionsMenu(ul); //AddStateAdminItem(ul, SecurePage.UserStateCode + " State Admin", // "/admin?state={StateCode}"); AddMenuItem(ul, SecurePage.UserStateCode + " Admin", GetStatesMenu()); AddCountiesMenu(ul); AddLocalsMenu(ul); AddElectionsMenu(ul); AddOfficesMenu(ul); AddMenuItem(ul, "Issues", "/admin/issues.aspx?state=" + SecurePage.UserStateCode); AddMenuItem(ul, "Offices", "/admin/offices.aspx?state=" + SecurePage.UserStateCode); AddMenuItem(ul, "Parties", "/admin/parties.aspx?state=" + SecurePage.UserStateCode); AddMenuItem(ul, "Politicians", "/admin/politicians.aspx"); AddMenuItem(ul, "Help", GetAdminHelpMenu()); } else if (SecurePage.IsCountyAdminUser) { AddJurisdictionsMenu(ul); AddLocalsMenu(ul); AddElectionsMenu(ul); AddOfficesMenu(ul); AddMenuItem(ul, "Help", GetAdminHelpMenu()); } else if (SecurePage.IsLocalAdminUser) { AddJurisdictionsMenu(ul); AddElectionsMenu(ul); AddOfficesMenu(ul); AddMenuItem(ul, "Help", GetAdminHelpMenu()); } else if (SecurePage.IsPoliticianUser) { AddPoliticianMenuItems(ul); } else if (SecurePage.IsPartyUser) { AddMenuItem(ul, "Help", GetPartyHelpMenu()); } // remove an empty menu if (ul.Controls.Count == 0) { parent.Controls.Remove(ul); } }