Dropdown tag helper

pull/279/head
yekalkan 8 years ago
parent 50e00ed827
commit 7db033e727

@ -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}}";

@ -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)
{
}
}
}

@ -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;
}
}
}

@ -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)
{
}
}
}

@ -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;
}
}
}

@ -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)
{
}
}
}

@ -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;
}
}
}

@ -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)
{
}
}
}

@ -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");
}
}
}
}

@ -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)
{
}
}
}

@ -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;
}
}
}
}

@ -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)
{
}
}
}

@ -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;
}
}
}
}

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

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

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

File diff suppressed because it is too large Load Diff

@ -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>

@ -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()
{
}
}
}

@ -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