Skip to content

Commit 7cbb332

Browse files
Updated to include card footer tag helper
1 parent f4b88e8 commit 7cbb332

File tree

9 files changed

+130
-165
lines changed

9 files changed

+130
-165
lines changed

src/AspNetCore.Utilities.Bootstrap5TagHelpers.Sample/Views/Home/Index.cshtml

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -253,21 +253,27 @@
253253
<tr>
254254
<td>
255255
<card>
256-
<card-header></card-header>
256+
<card-header title="Testing Header"></card-header>
257+
<card-body>
258+
This is my card body
259+
</card-body>
257260
</card>
258261
</td>
259262
<td>
260263
<code>
261264
&lt;card&gt;
262-
&lt;card-header &gt;&lt;/card-header&gt;
265+
&lt;card-header title=&quot;Testing Header&quot;&gt;&lt;/card-header&gt;
266+
&lt;card-body&gt;
267+
This is my card body
268+
&lt;/card-body&gt;
263269
&lt;/card&gt;
264270
</code>
265271
</td>
266272
</tr>
267273
<tr>
268274
<td>
269-
<card class="bg-success text-white">
270-
<card-header title="With Title"></card-header>
275+
<card class="bg-success text-white" id="testing-card-id">
276+
<card-header title="With Title and Id"></card-header>
271277
</card>
272278
</td>
273279
<td>
@@ -290,6 +296,9 @@
290296
<card-body>
291297
<p>This is my body</p>
292298
</card-body>
299+
<card-footer>
300+
This is my footer
301+
</card-footer>
293302
</card>
294303
</td>
295304
<td>
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
using ICG.AspNetCore.Utilities.Bootstrap5TagHelpers.Card;
2+
using Microsoft.AspNetCore.Razor.TagHelpers;
3+
4+
namespace ICG.AspNetCore.Utilities.Bootstrap5TagHelpers.Tests.Card;
5+
6+
public class CardFooterTagHelperTests : AbstractTagHelperTest
7+
{
8+
[Fact]
9+
public async Task Should_Render_As_Div()
10+
{
11+
//Arrange
12+
var context = MakeTagHelperContext();
13+
var output = MakeTagHelperOutput(" ");
14+
15+
//Act
16+
var helper = new CardFooterTagHelper();
17+
await helper.ProcessAsync(context, output);
18+
19+
//Assert
20+
Assert.Equal("div", output.TagName);
21+
}
22+
23+
[Fact]
24+
public async Task Should_Render_With_ProperClasses()
25+
{
26+
//Arrange
27+
var context = MakeTagHelperContext();
28+
var output = MakeTagHelperOutput(" ");
29+
30+
//Act
31+
var helper = new CardFooterTagHelper();
32+
await helper.ProcessAsync(context, output);
33+
34+
//Assert
35+
Assert.Equal("card-footer text-muted", output.Attributes["class"].Value.ToString());
36+
}
37+
38+
[Fact]
39+
public async Task Should_Render_With_ClassAdded_PreservingCustomClasses()
40+
{
41+
//Arrange
42+
var customClass = "testing-out";
43+
var expectedClass = $"{customClass} card-footer text-muted";
44+
var existingAttributes = new TagHelperAttributeList(new List<TagHelperAttribute>
45+
{new("class", customClass)});
46+
var context = MakeTagHelperContext();
47+
var output = MakeTagHelperOutput(" ", attributes:existingAttributes);
48+
49+
//Act
50+
var helper = new CardFooterTagHelper();
51+
await helper.ProcessAsync(context, output);
52+
53+
//Assert
54+
Assert.Equal(expectedClass, output.Attributes["class"].Value.ToString());
55+
}
56+
}

src/AspNetCore.Utilities.Bootstrap5TagHelpers.Tests/Card/CardHeaderActionsTagHelperTests.cs

Lines changed: 0 additions & 74 deletions
This file was deleted.

src/AspNetCore.Utilities.Bootstrap5TagHelpers.Tests/Card/CardHeaderTagHelperTests.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -90,9 +90,9 @@ public async Task Should_Render_With_ClassAdded_PreservingCustomClasses()
9090
}
9191

9292
[Theory]
93-
[InlineData("", "", "<div class=\"d-md-flex align-items-center w-100\"></div>")]
94-
[InlineData("Testing", "", "<div class=\"d-md-flex align-items-center w-100\"><h5>Testing</h5></div>")]
95-
[InlineData("Testing", "myCard", "<div class=\"d-md-flex align-items-center w-100\"><h5 id=\"myCardLabel\">Testing</h5></div>")]
93+
[InlineData("", "", "")]
94+
[InlineData("Testing", "", "Testing")]
95+
[InlineData("Testing", "myCard", "<span id=\"myCardLabel\">Testing</span>")]
9696
public async Task Should_Render_WithProper_InnerHtmlContent(string title, string contextId, string expectedOutput)
9797
{
9898
//Arrange

src/AspNetCore.Utilities.Bootstrap5TagHelpers.Tests/Card/CardTagHelperTests.cs

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,28 @@ public async Task Should_Not_Error_With_Missing_Id_Attribute()
2121
Assert.Null(exception);
2222
}
2323

24+
[Fact]
25+
public async Task Should_Add_Context_Object_Without_Id_If_Missing()
26+
{
27+
//Arrange
28+
var context = MakeTagHelperContext();
29+
var output = MakeTagHelperOutput(" ");
30+
31+
//Act
32+
var helper = new CardTagHelper();
33+
await helper.ProcessAsync(context, output);
34+
35+
//Assert
36+
var generatedContext = Assert.IsType<CardContext>(context.Items[typeof(CardContext)]);
37+
Assert.Null(generatedContext.Id);
38+
}
39+
2440
[Fact]
2541
public async Task Should_Add_Context_Object_With_Provided_Id()
2642
{
2743
//Arrange
2844
var context = MakeTagHelperContext();
29-
var providedId = "testingCarg";
45+
var providedId = "testingCard";
3046
var existingAttributes = new TagHelperAttributeList(new List<TagHelperAttribute>
3147
{new("id", providedId)});
3248
var output = MakeTagHelperOutput(" ", existingAttributes);
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
using Microsoft.AspNetCore.Mvc.TagHelpers;
2+
using Microsoft.AspNetCore.Razor.TagHelpers;
3+
using System.Text.Encodings.Web;
4+
using System.Threading.Tasks;
5+
6+
namespace ICG.AspNetCore.Utilities.Bootstrap5TagHelpers.Card;
7+
8+
/// <summary>
9+
/// Tag Helper for rendering the header for a card
10+
/// </summary>
11+
public class CardFooterTagHelper : TagHelper
12+
{
13+
/// <summary>
14+
/// Renders the card
15+
/// </summary>
16+
/// <param name="context"></param>
17+
/// <param name="output"></param>
18+
/// <returns></returns>
19+
public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
20+
{
21+
output.TagName = "div";
22+
output.AddClass("card-footer", HtmlEncoder.Default);
23+
output.AddClass("text-muted", HtmlEncoder.Default);
24+
25+
var content = (await output.GetChildContentAsync()).GetContent();
26+
27+
output.Content.AppendHtml(content);
28+
}
29+
}

src/AspNetCore.Utilities.Bootstrap5TagHelpers/Card/CardHeaderActionsTagHelper.cs

Lines changed: 0 additions & 48 deletions
This file was deleted.

src/AspNetCore.Utilities.Bootstrap5TagHelpers/Card/CardHeaderTagHelper.cs

Lines changed: 11 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,12 @@
44
using Microsoft.AspNetCore.Razor.TagHelpers;
55
using System;
66
using System.Text.Encodings.Web;
7-
using System.Threading.Tasks;
87

98
namespace ICG.AspNetCore.Utilities.Bootstrap5TagHelpers.Card
109
{
1110
/// <summary>
1211
/// Tag Helper for rendering the header for a card
1312
/// </summary>
14-
[RestrictChildren("card-header-actions")]
1513
public class CardHeaderTagHelper : TagHelper
1614
{
1715
/// <summary>
@@ -26,49 +24,28 @@ public class CardHeaderTagHelper : TagHelper
2624
/// <param name="output"></param>
2725
/// <returns></returns>
2826
/// <exception cref="ArgumentException"></exception>
29-
public override Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
27+
public override void Process(TagHelperContext context, TagHelperOutput output)
3028
{
3129
//Get the context information
3230
if (context.Items[typeof(CardContext)] is not CardContext cardContext)
3331
throw new ArgumentException("CardContext is not specified in context parameter");
3432

35-
return ProcessAsyncInternal(output, cardContext);
36-
}
37-
38-
private async Task ProcessAsyncInternal(TagHelperOutput output, CardContext cardContext)
39-
{
4033
//Setup basic tag information
4134
output.TagName = "div";
4235
output.AddClass("card-header", HtmlEncoder.Default);
4336

44-
//Get sub controls if we need them
45-
var body = (await output.GetChildContentAsync()).GetContent();
46-
body = body.Trim();
47-
48-
var headerContent = new TagBuilder("div");
49-
headerContent.AddCssClass("d-md-flex");
50-
headerContent.AddCssClass("align-items-center");
51-
headerContent.AddCssClass("w-100");
52-
53-
// Render title if given
54-
if (!string.IsNullOrEmpty(Title))
37+
//If we have an id make a custom span
38+
if (!string.IsNullOrEmpty(cardContext.Id))
5539
{
56-
var titleTag = new TagBuilder("h5");
57-
58-
//Add custom id value if we can, otherwise it will not be unique
59-
if (!string.IsNullOrEmpty(cardContext.Id))
60-
titleTag.Attributes.Add("id", $"{cardContext.Id}Label");
61-
titleTag.InnerHtml.Append(Title);
62-
63-
headerContent.InnerHtml.AppendHtml(titleTag);
40+
var wrapper = new TagBuilder("span");
41+
wrapper.Attributes.Add("id", $"{cardContext.Id}Label");
42+
wrapper.InnerHtml.Append(Title);
43+
output.Content.AppendHtml(wrapper);
44+
}
45+
else
46+
{
47+
output.Content.AppendHtml(Title);
6448
}
65-
66-
//Add sub-content after our title
67-
if (!string.IsNullOrEmpty(body))
68-
headerContent.InnerHtml.AppendHtml(body);
69-
70-
//Add to the display
71-
output.Content.AppendHtml(headerContent);
7249
}
7350
}
7451
}

src/AspNetCore.Utilities.Bootstrap5TagHelpers/Card/CardTagHelper.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ namespace ICG.AspNetCore.Utilities.Bootstrap5TagHelpers.Card;
99
/// <summary>
1010
/// A tag helper for rendering a bootstrap card to a view
1111
/// </summary>
12-
[RestrictChildren("card-header", "card-body")]
12+
[RestrictChildren("card-header", "card-body", "card-footer")]
1313
public class CardTagHelper : TagHelper
1414
{
1515
/// <summary>

0 commit comments

Comments
 (0)