Browse Source

Dropdown tag helper

pull/279/head
yekalkan 8 years ago
parent
commit
7db033e727
  1. 1
      src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs
  2. 27
      src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownButtonTagHelper.cs
  3. 139
      src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownButtonTagHelperService.cs
  4. 11
      src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownDividerTagHelper.cs
  5. 16
      src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownDividerTagHelperService.cs
  6. 11
      src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownHeaderTagHelper.cs
  7. 16
      src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownHeaderTagHelperService.cs
  8. 15
      src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownItemTagHelper.cs
  9. 34
      src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownItemTagHelperService.cs
  10. 13
      src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownMenuTagHelper.cs
  11. 30
      src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownMenuTagHelperService.cs
  12. 13
      src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownTagHelper.cs
  13. 43
      src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownTagHelperService.cs
  14. 8
      src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/DropdownAlign.cs
  15. 10
      src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/DropdownDirection.cs
  16. 8
      src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/DropdownStyle.cs
  17. 3444
      test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Logs/logs.txt
  18. 74
      test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Dropdowns.cshtml
  19. 17
      test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Dropdowns.cshtml.cs
  20. 1
      test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Index.cshtml

1
src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/AbpTagHelperService.cs

@ -16,6 +16,7 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers
where TTagHelper : TagHelper
{
protected const string FormGroupContents = "FormGroupContents";
protected const string DropdownButtonsAsHtml = "DropdownButtonsAsHtmlContent";
protected const string TabItems = "TabItems";
protected const string TabItemsDataTogglePlaceHolder = "{{data_toggle}}";
protected const string TabItemsVerticalPillPlaceHolder = "{{vertical_pill}}";

27
src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownButtonTagHelper.cs

@ -0,0 +1,27 @@
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Button;
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Dropdown
{
public class AbpDropdownButtonTagHelper : AbpTagHelper<AbpDropdownButtonTagHelper, AbpDropdownButtonTagHelperService>
{
public string Text { get; set; }
public AbpButtonSize Size { get; set; } = AbpButtonSize.Default;
public DropdownStyle DropdownStyle { get; set; } = DropdownStyle.Single;
public AbpButtonType ButtonType { get; set; } = AbpButtonType.Default;
public string Icon { get; set; }
public FontIconType IconType { get; set; } = FontIconType.FontAwesome;
public bool? Link { get; set; }
public AbpDropdownButtonTagHelper(AbpDropdownButtonTagHelperService tagHelperService)
: base(tagHelperService)
{
}
}
}

139
src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownButtonTagHelperService.cs

@ -0,0 +1,139 @@
using System;
using System.Linq;
using System.Text;
using System.Text.Encodings.Web;
using Microsoft.AspNetCore.Mvc.ViewFeatures;
using Microsoft.AspNetCore.Razor.TagHelpers;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers;
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Button;
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Dropdown
{
public class AbpDropdownButtonTagHelperService : AbpTagHelperService<AbpDropdownButtonTagHelper>
{
private readonly HtmlEncoder _htmlEncoder;
private readonly IHtmlGenerator _htmlGenerator;
private readonly IServiceProvider _serviceProvider;
public AbpDropdownButtonTagHelperService(
HtmlEncoder htmlEncoder,
IHtmlGenerator htmlGenerator,
IServiceProvider serviceProvider)
{
_htmlEncoder = htmlEncoder;
_htmlGenerator = htmlGenerator;
_serviceProvider = serviceProvider;
}
public override void Process(TagHelperContext context, TagHelperOutput output)
{
var buttonsAsHtml = GetButtonsAsHtml(context,output);
output.PreElement.SetHtmlContent(buttonsAsHtml);
output.TagName = "div";
output.TagMode = TagMode.StartTagAndEndTag;
output.Attributes.Clear();
}
protected virtual string GetButtonsAsHtml(TagHelperContext context, TagHelperOutput output)
{
var buttonBuilder = new StringBuilder("");
var mainButton = GetMainButton(context, output);
buttonBuilder.AppendLine(mainButton);
if (TagHelper.DropdownStyle == DropdownStyle.Split)
{
var splitButton = GetSplitButton(context, output);
buttonBuilder.AppendLine(splitButton);
}
return buttonBuilder.ToString();
}
protected virtual string GetMainButton(TagHelperContext context, TagHelperOutput output)
{
var abpButtonTagHelper = _serviceProvider.GetRequiredService<AbpButtonTagHelper>();
abpButtonTagHelper.Icon = TagHelper.Icon;
abpButtonTagHelper.Text = TagHelper.Text;
abpButtonTagHelper.IconType = TagHelper.IconType;
abpButtonTagHelper.Size = TagHelper.Size;
abpButtonTagHelper.ButtonType = TagHelper.ButtonType;
var attributes = new TagHelperAttributeList();
if (TagHelper.DropdownStyle == DropdownStyle.Single)
{
attributes.AddClass("dropdown-toggle");
attributes.Add("data-toggle", "dropdown");
attributes.Add("aria-haspopup", "true");
attributes.Add("aria-expanded", "false");
}
if (output.Attributes.Any(at => at.Name == "href"))
{
attributes.Add("href", output.Attributes["href"].Value);
}
var mainButtonAsHtml = "";
if (!TagHelper.Link??true)
{
mainButtonAsHtml = RenderTagHelper(attributes, context, abpButtonTagHelper, _htmlEncoder, "button", TagMode.StartTagAndEndTag);
}
else
{
var buttonTag = GetInnerTagHelper(attributes, context, abpButtonTagHelper, "button", TagMode.StartTagAndEndTag);
var linkTag = ConvertButtonToLink(buttonTag);
mainButtonAsHtml = RenderTagHelperOutput(linkTag, _htmlEncoder);
}
return mainButtonAsHtml;
}
protected virtual string GetSplitButton(TagHelperContext context, TagHelperOutput output)
{
var abpButtonTagHelper = _serviceProvider.GetRequiredService<AbpButtonTagHelper>();
abpButtonTagHelper.Size = TagHelper.Size;
abpButtonTagHelper.ButtonType = TagHelper.ButtonType;
var attributes = new TagHelperAttributeList();
attributes.AddClass("dropdown-toggle");
attributes.AddClass("dropdown-toggle-split");
attributes.Add("data-toggle", "dropdown");
attributes.Add("aria-haspopup", "true");
attributes.Add("aria-expanded", "false");
var splitButtonAsHtml = "";
if (true)
{
splitButtonAsHtml = RenderTagHelper(attributes, context, abpButtonTagHelper, _htmlEncoder, "button", TagMode.StartTagAndEndTag);
}
else
{
var buttonTag = GetInnerTagHelper(attributes, context, abpButtonTagHelper, "button", TagMode.StartTagAndEndTag);
var linkTag = ConvertButtonToLink(buttonTag);
splitButtonAsHtml = RenderTagHelperOutput(linkTag, _htmlEncoder);
}
return splitButtonAsHtml;
}
protected virtual TagHelperOutput ConvertButtonToLink(TagHelperOutput buttonTag)
{
buttonTag.TagName = "a";
buttonTag.Attributes.RemoveAll("type");
buttonTag.Attributes.Add("roles", "button");
return buttonTag;
}
}
}

11
src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownDividerTagHelper.cs

@ -0,0 +1,11 @@
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Dropdown
{
public class AbpDropdownDividerTagHelper : AbpTagHelper<AbpDropdownDividerTagHelper, AbpDropdownDividerTagHelperService>
{
public AbpDropdownDividerTagHelper(AbpDropdownDividerTagHelperService tagHelperService)
: base(tagHelperService)
{
}
}
}

16
src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownDividerTagHelperService.cs

@ -0,0 +1,16 @@
using Microsoft.AspNetCore.Razor.TagHelpers;
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers;
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Dropdown
{
public class AbpDropdownDividerTagHelperService : AbpTagHelperService<AbpDropdownDividerTagHelper>
{
public override void Process(TagHelperContext context, TagHelperOutput output)
{
output.TagName = "div";
output.Attributes.AddClass("dropdown-divider");
output.TagMode = TagMode.StartTagAndEndTag;
}
}
}

11
src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownHeaderTagHelper.cs

@ -0,0 +1,11 @@
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Dropdown
{
public class AbpDropdownHeaderTagHelper : AbpTagHelper<AbpDropdownHeaderTagHelper, AbpDropdownHeaderTagHelperService>
{
public AbpDropdownHeaderTagHelper(AbpDropdownHeaderTagHelperService tagHelperService)
: base(tagHelperService)
{
}
}
}

16
src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownHeaderTagHelperService.cs

@ -0,0 +1,16 @@
using Microsoft.AspNetCore.Razor.TagHelpers;
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers;
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Dropdown
{
public class AbpDropdownHeaderTagHelperService : AbpTagHelperService<AbpDropdownHeaderTagHelper>
{
public override void Process(TagHelperContext context, TagHelperOutput output)
{
output.TagName = "h6";
output.Attributes.AddClass("dropdown-header");
output.TagMode = TagMode.StartTagAndEndTag;
}
}
}

15
src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownItemTagHelper.cs

@ -0,0 +1,15 @@
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Dropdown
{
public class AbpDropdownItemTagHelper : AbpTagHelper<AbpDropdownItemTagHelper, AbpDropdownItemTagHelperService>
{
public bool? Active { get; set; }
public bool? Disabled { get; set; }
public AbpDropdownItemTagHelper(AbpDropdownItemTagHelperService tagHelperService)
: base(tagHelperService)
{
}
}
}

34
src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownItemTagHelperService.cs

@ -0,0 +1,34 @@
using Microsoft.AspNetCore.Razor.TagHelpers;
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers;
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Dropdown
{
public class AbpDropdownItemTagHelperService : AbpTagHelperService<AbpDropdownItemTagHelper>
{
public override void Process(TagHelperContext context, TagHelperOutput output)
{
output.TagName = "a";
output.Attributes.AddClass("dropdown-item");
output.TagMode = TagMode.StartTagAndEndTag;
SetActiveClassIfActive(context,output);
SetDisabledClassIfDisabled(context,output);
}
protected virtual void SetActiveClassIfActive(TagHelperContext context, TagHelperOutput output)
{
if (TagHelper.Active??false)
{
output.Attributes.AddClass("active");
}
}
protected virtual void SetDisabledClassIfDisabled(TagHelperContext context, TagHelperOutput output)
{
if (TagHelper.Disabled??false)
{
output.Attributes.AddClass("disabled");
}
}
}
}

13
src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownMenuTagHelper.cs

@ -0,0 +1,13 @@
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Dropdown
{
public class AbpDropdownMenuTagHelper : AbpTagHelper<AbpDropdownMenuTagHelper, AbpDropdownMenuTagHelperService>
{
public DropdownAlign Align { get; set; } = DropdownAlign.Left;
public AbpDropdownMenuTagHelper(AbpDropdownMenuTagHelperService tagHelperService)
: base(tagHelperService)
{
}
}
}

30
src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownMenuTagHelperService.cs

@ -0,0 +1,30 @@
using Microsoft.AspNetCore.Razor.TagHelpers;
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers;
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Dropdown
{
public class AbpDropdownMenuTagHelperService : AbpTagHelperService<AbpDropdownMenuTagHelper>
{
public override void Process(TagHelperContext context, TagHelperOutput output)
{
output.TagName = "div";
output.Attributes.AddClass("dropdown-menu");
output.TagMode = TagMode.StartTagAndEndTag;
SetAlign(context, output);
}
protected virtual void SetAlign(TagHelperContext context, TagHelperOutput output)
{
switch (TagHelper.Align)
{
case DropdownAlign.Right:
output.Attributes.AddClass("dropdown-menu-right");
return;
case DropdownAlign.Left:
return;
}
}
}
}

13
src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownTagHelper.cs

@ -0,0 +1,13 @@
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Dropdown
{
public class AbpDropdownTagHelper : AbpTagHelper<AbpDropdownTagHelper, AbpDropdownTagHelperService>
{
public DropdownDirection Direction { get; set; } = DropdownDirection.Down;
public AbpDropdownTagHelper(AbpDropdownTagHelperService tagHelperService)
: base(tagHelperService)
{
}
}
}

43
src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/AbpDropdownTagHelperService.cs

@ -0,0 +1,43 @@
using System.Threading.Tasks;
using Microsoft.AspNetCore.Razor.TagHelpers;
using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Microsoft.AspNetCore.Razor.TagHelpers;
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Dropdown
{
public class AbpDropdownTagHelperService : AbpTagHelperService<AbpDropdownTagHelper>
{
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
{
output.TagName = "div";
output.Attributes.AddClass("btn-group");
SetDirection(context, output);
output.TagMode = TagMode.StartTagAndEndTag;
}
protected virtual string GetButtonsAsHtml(TagHelperContext context, TagHelperOutput output)
{
return context.Items[DropdownButtonsAsHtml] as string;
}
protected virtual void SetDirection(TagHelperContext context, TagHelperOutput output)
{
switch (TagHelper.Direction)
{
case DropdownDirection.Down:
return;
case DropdownDirection.Up:
output.Attributes.AddClass("dropup");
return;
case DropdownDirection.Right:
output.Attributes.AddClass("dropright");
return;
case DropdownDirection.Left:
output.Attributes.AddClass("dropleft");
return;
}
}
}
}

8
src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/DropdownAlign.cs

@ -0,0 +1,8 @@
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Dropdown
{
public enum DropdownAlign
{
Left,
Right
}
}

10
src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/DropdownDirection.cs

@ -0,0 +1,10 @@
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Dropdown
{
public enum DropdownDirection
{
Down,
Up,
Right,
Left
}
}

8
src/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap/TagHelpers/Dropdown/DropdownStyle.cs

@ -0,0 +1,8 @@
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Dropdown
{
public enum DropdownStyle
{
Single,
Split
}
}

3444
test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Logs/logs.txt

File diff suppressed because it is too large

74
test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Dropdowns.cshtml

@ -0,0 +1,74 @@
@page
@model Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components.DropdownsModel
@{
ViewData["Title"] = "Dropdowns";
}
<h2>Dropdowns</h2>
<p>Based on <a href="https://getbootstrap.com/docs/4.1/components/dropdowns/" target="_blank"> Bootstrap button</a>.</p>
<h4># Example</h4>
<div class="demo-with-code">
<div class="demo-area">
<abp-dropdown direction="Right">
<abp-dropdown-button dropdown-style="Split" link="true" href="#" button-type="Primary" text="Dropdown"/>
<abp-dropdown-menu>
<abp-dropdown-header>Dropdown header</abp-dropdown-header>
<abp-dropdown-item href="#" active="true">Action</abp-dropdown-item>
<abp-dropdown-item href="#" disabled="true">Another disabled action</abp-dropdown-item>
<abp-dropdown-item href="#">Something else here</abp-dropdown-item>
<abp-dropdown-divider/>
<abp-dropdown-item href="#">Separated link</abp-dropdown-item>
</abp-dropdown-menu>
</abp-dropdown>
</div>
<div class="code-area">
<pre>
&lt;abp-dropdown direction=&quot;Right&quot;&gt;
&lt;abp-dropdown-button dropdown-style=&quot;Split&quot; button-type=&quot;Danger&quot; text=&quot;Dropdown&quot; size=&quot;Large&quot;/&gt;
&lt;abp-dropdown-menu&gt;
&lt;abp-dropdown-header&gt;Dropdown header&lt;/abp-dropdown-header&gt;
&lt;abp-dropdown-item href=&quot;#&quot; active=&quot;true&quot;&gt;Action&lt;/abp-dropdown-item&gt;
&lt;abp-dropdown-item href=&quot;#&quot; disabled=&quot;true&quot;&gt;Another disabled action&lt;/abp-dropdown-item&gt;
&lt;abp-dropdown-item href=&quot;#&quot;&gt;Something else here&lt;/abp-dropdown-item&gt;
&lt;abp-dropdown-divider/&gt;
&lt;abp-dropdown-item href=&quot;#&quot;&gt;Separated link&lt;/abp-dropdown-item&gt;
&lt;/abp-dropdown-menu&gt;
&lt;/abp-dropdown&gt;
</pre>
</div>
</div>
<h4># Example</h4>
<div class="demo-with-code">
<div class="demo-area">
<div class="btn-group">
<button type="button" class="btn btn-secondary btn-lg">
Split dropup
</button>
<button type="button" class="btn btn-secondary dropdown-toggle dropdown-toggle-split" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="sr-only">Toggle Dropdown</span>
</button>
<div class="dropdown-menu">
<abp-dropdown-header>Dropdown header</abp-dropdown-header>
<abp-dropdown-item href="#" active="true">Action</abp-dropdown-item>
<abp-dropdown-item href="#" disabled="true">Another disabled action</abp-dropdown-item>
<abp-dropdown-item href="#">Something else here</abp-dropdown-item>
<abp-dropdown-divider/>
<abp-dropdown-item href="#">Separated link</abp-dropdown-item>
</div>
</div>
</div>
<div class="code-area">
<pre>
</pre>
</div>
</div>

17
test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Components/Dropdowns.cshtml.cs

@ -0,0 +1,17 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
namespace Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo.Pages.Components
{
public class DropdownsModel : PageModel
{
public void OnGet()
{
}
}
}

1
test/Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.Demo/Pages/Index.cshtml

@ -12,5 +12,6 @@
<li><a asp-page="Components/Cards">Cards</a></li>
<li><a asp-page="Components/DynamicForms">Dynamic Forms</a></li>
<li><a asp-page="Components/Tabs">Tabs</a></li>
<li><a asp-page="Components/Dropdowns">Dropdowns</a></li>
</ul>

Loading…
Cancel
Save