Skip to content

Commit 223091b

Browse files
Merge pull request #27 from IowaComputerGurus/feature/updated-for-required
Added Ability to Designate Required Fields
2 parents 32548d2 + 942b401 commit 223091b

File tree

8 files changed

+58
-35
lines changed

8 files changed

+58
-35
lines changed

.github/workflows/ci-build.yml

Lines changed: 10 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -24,28 +24,6 @@ jobs:
2424
- uses: actions/checkout@v4
2525
with:
2626
fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis
27-
28-
- name: Cache SonarCloud packages
29-
uses: actions/cache@v3.3.2
30-
with:
31-
path: ~\sonar\cache
32-
key: ${{ runner.os }}-sonar
33-
restore-keys: ${{ runner.os }}-sonar
34-
35-
- name: Cache SonarCloud scanner
36-
id: cache-sonar-scanner
37-
uses: actions/cache@v3.3.2
38-
with:
39-
path: .\.sonar\scanner
40-
key: ${{ runner.os }}-sonar-scanner
41-
restore-keys: ${{ runner.os }}-sonar-scanner
42-
43-
- name: Install SonarCloud scanner
44-
if: steps.cache-sonar-scanner.outputs.cache-hit != 'true'
45-
shell: powershell
46-
run: |
47-
New-Item -Path .\.sonar\scanner -ItemType Directory
48-
dotnet tool update dotnet-sonarscanner --tool-path .\.sonar\scanner
4927

5028
- name: Install GitVersion
5129
run: dotnet tool install --global GitVersion.Tool
@@ -62,8 +40,16 @@ jobs:
6240
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
6341
shell: powershell
6442
run: |
65-
.\.sonar\scanner\dotnet-sonarscanner begin /k:"IowaComputerGurus_aspnetcore.utilities.bootstrap5taghelpers" /o:"iowacomputergurus-github" /d:sonar.login="${{ secrets.SONAR_TOKEN }}" /d:sonar.host.url="https://sonarcloud.io" /n:"AspNetCore Utilities Bootstrap5 Tag Helpers"
6643
dotnet restore "${{ env.solution-path }}"
6744
dotnet build "${{ env.solution-path }}" --no-restore --configuration Release -p:version=${{ steps.gitversion.outputs.majorMinorPatch }}
6845
dotnet test "${{ env.solution-path }}" --no-build --configuration Release --collect "XPlat Code Coverage" -- DataCollectionRunSettings.DataCollectors.DataCollector.Configuration.Format=opencover --logger "trx;LogFileName=unittests.trx"
69-
.\.sonar\scanner\dotnet-sonarscanner end /d:sonar.login="${{ secrets.SONAR_TOKEN }}"
46+
47+
- name: Push Coverage to Codacy
48+
shell: bash
49+
env:
50+
CODACY_ORGANIZATION_PROVIDER: ${{ secrets.CODACY_ORGANIZATION_PROVIDER }}
51+
CODACY_USERNAME: ${{ secrets.CODACY_USERNAME }}
52+
CODACY_PROJECT_NAME: ${{ secrets.CODACY_PROJECT_NAME }}
53+
CODACY_API_TOKEN: ${{ secrets.CODACY_API_TOKEN }}
54+
run: |
55+
bash <(curl -Ls https://coverage.codacy.com/get.sh) report $(find . -name '*.opencover.xml' -printf '-r %p ')

README.md

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,7 @@ A collection of TagHelpers for ASP.NET Core that make utilizing the Bootstrap 5.
66

77
![](https://img.shields.io/nuget/v/icg.aspnetcore.utilities.bootstrap5taghelpers.svg) ![](https://img.shields.io/nuget/dt/icg.aspnetcore.utilities.bootstrap5taghelpers.svg)
88

9-
## SonarCloud Analysis
10-
11-
[![Quality Gate Status](https://sonarcloud.io/api/project_badges/measure?project=IowaComputerGurus_aspnetcore.utilities.bootstrap5taghelpers&metric=alert_status)](https://sonarcloud.io/dashboard?id=IowaComputerGurus_aspnetcore.utilities.bootstrap5taghelpers)
12-
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=IowaComputerGurus_aspnetcore.utilities.bootstrap5taghelpers&metric=coverage)](https://sonarcloud.io/dashboard?id=IowaComputerGurus_aspnetcore.utilities.bootstrap5taghelpers)
13-
[![Security Rating](https://sonarcloud.io/api/project_badges/measure?project=IowaComputerGurus_aspnetcore.utilities.bootstrap5taghelpers&metric=security_rating)](https://sonarcloud.io/dashboard?id=IowaComputerGurus_aspnetcore.utilities.bootstrap5taghelpers)
14-
[![Technical Debt](https://sonarcloud.io/api/project_badges/measure?project=IowaComputerGurus_aspnetcore.utilities.bootstrap5taghelpers&metric=sqale_index)](https://sonarcloud.io/dashboard?id=IowaComputerGurus_aspnetcore.utilities.bootstrap5taghelpers)
9+
[![Codacy Badge](https://app.codacy.com/project/badge/Grade/6bfab3e64b8d4138aefc6152d39bd753)](https://app.codacy.com/gh/IowaComputerGurus/aspnetcore.utilities.bootstrap5taghelpers/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)
1510

1611
## Usage Expectations
1712

@@ -77,4 +72,13 @@ At this time tag helpers have been implemented for the following elements.
7772

7873
If you find that we are missing a particular tag helper, we welcome contributions!
7974

80-
##
75+
## Special Features
76+
77+
The tag helpers automatically inspect form elements and add a "required" css class in addition to the `form-label` class default allowing for indication of required fields easily with CSS such as the following.
78+
79+
```` css
80+
label.required:after {
81+
content: " *";
82+
color: red;
83+
}
84+
````

src/AspNetCore.Utilities.Bootstrap5TagHelpers.Sample/Models/SampleModel.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,6 @@ public class SampleModel
3838
public string ReadOnlyField { get; set; } = "Readonly Field Example";
3939

4040
[Display(Name = "Select List Item")]
41-
public SampleEnum SelectedListItem { get; set; }
41+
public SampleEnum? SelectedListItem { get; set; }
4242
}
4343
}

src/AspNetCore.Utilities.Bootstrap5TagHelpers.Sample/Views/Shared/_Layout.cshtml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,13 @@
77
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0-alpha1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-GLhlTQ8iRABdZLl6O3oVMWSktQOp6b7In1Zl3/Jr59b6EGGoI1aFkw7cmDA6j6gD" crossorigin="anonymous">
88
<link rel="stylesheet" href="~/css/site.css" asp-append-version="true" />
99
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css" integrity="sha512-9usAa10IRO0HhonpyAIVpjrylPvoDwiPUiKdWk5t3PyolY1cOd4DSE0Ga+ri4AuTroPR5aQvXU9xC6qOPnzFeg==" crossorigin="anonymous" referrerpolicy="no-referrer" />
10-
</head>
10+
<style>
11+
label.required:after {
12+
content: " *";
13+
color: red;
14+
}
15+
</style>
16+
</head>
1117
<body>
1218
<header>
1319
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">

src/AspNetCore.Utilities.Bootstrap5TagHelpers.Tests/Form/FormInputTagHelperTests.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,18 @@ public async Task Renders_PlainTextReadOnly()
8585
await VerifyTagHelper(output);
8686
}
8787

88+
[Fact]
89+
public async Task Renders_RequiredClassWhenNeeded()
90+
{
91+
var metadataProvider = new TestModelMetadataProvider();
92+
var htmlGenerator = new TestableHtmlGenerator(metadataProvider);
93+
94+
var tagHelper = GetTagHelper(htmlGenerator, model: new TestModel(), propertyName: nameof(TestModel.RequiredIntField));
95+
tagHelper.PlainTextReadOnly = true;
96+
var output = await tagHelper.Render();
97+
await VerifyTagHelper(output);
98+
}
99+
88100
internal override FormInputTagHelper TagHelperFactory(IHtmlGenerator htmlGenerator, ModelExpression modelExpression, ViewContext viewContext)
89101
=> new(htmlGenerator) { For = modelExpression, ViewContext = viewContext };
90102
}
Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1-
namespace ICG.AspNetCore.Utilities.Bootstrap5TagHelpers.Tests.Form;
1+
using System.ComponentModel.DataAnnotations;
2+
3+
namespace ICG.AspNetCore.Utilities.Bootstrap5TagHelpers.Tests.Form;
24
public class TestModel
35
{
46
public string TextField { get; set; }
7+
8+
[Required]
9+
public int? RequiredIntField { get; set; }
510
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+

2+
<div class="mb-3">
3+
<label class="HtmlEncode[[form-label required]]" for="HtmlEncode[[RequiredIntField]]">HtmlEncode[[RequiredIntField]]</label>
4+
<input type="HtmlEncode[[number]]" id="HtmlEncode[[RequiredIntField]]" name="HtmlEncode[[RequiredIntField]]" value="HtmlEncode[[ICG.AspNetCore.Utilities.Bootstrap5TagHelpers.Tests.Form.TestModel]]" class="HtmlEncode[[form-control-plaintext]]" readonly="HtmlEncode[[readonly]]">
5+
</div>

src/AspNetCore.Utilities.Bootstrap5TagHelpers/Form/FormElementMixin.cs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using Microsoft.AspNetCore.Mvc.Rendering;
22
using Microsoft.AspNetCore.Mvc.ViewFeatures;
33
using Microsoft.AspNetCore.Razor.TagHelpers;
4+
using System.ComponentModel.DataAnnotations;
5+
using System.Linq;
46

57
namespace ICG.AspNetCore.Utilities.Bootstrap5TagHelpers.Form;
68

@@ -34,12 +36,15 @@ public static void EndFormGroup(this IFormElementMixin element, TagHelperOutput
3436

3537
public static void AddLabel(this IFormElementMixin element, TagHelperOutput output)
3638
{
39+
//Find out if required to add special class
40+
var isRequired = element.For.ModelExplorer.Metadata.ValidatorMetadata.Any(o => o is RequiredAttribute);
41+
var targetClass = isRequired ? "form-label required" : "form-label";
3742
//Generate our label
3843
var label = element.HtmlGenerator.GenerateLabel(
3944
element.ViewContext,
4045
element.For.ModelExplorer,
4146
element.For.Name, null,
42-
new { @class = "form-label" });
47+
new { @class = targetClass });
4348
output.PreElement.AppendHtml(label);
4449
}
4550

0 commit comments

Comments
 (0)