Skip to content

Commit 894a143

Browse files
jorivermAI\jvermeylvnbaaij
authored
[Lists] Trigger field changed when in multiple mode (#3294)
* ListComponentBase : trigger fieldchanged on changes when control is multiple mode * ListComponentBase : implement missing binding expressions --------- Co-authored-by: AI\jvermeyl <joris.vermeylen@uzgent.be> Co-authored-by: Vincent Baaij <vnbaaij@outlook.com>
1 parent cd7c33e commit 894a143

File tree

4 files changed

+43
-21
lines changed

4 files changed

+43
-21
lines changed

examples/Demo/Shared/Microsoft.FluentUI.AspNetCore.Components.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6209,6 +6209,12 @@
62096209
⚠️ Only available when Multiple = false.
62106210
</summary>
62116211
</member>
6212+
<member name="P:Microsoft.FluentUI.AspNetCore.Components.ListComponentBase`1.SelectedOptionExpression">
6213+
<summary>
6214+
Gets or sets an expression that identifies the bound selected options.
6215+
⚠️ Only available when Multiple = false.
6216+
</summary>
6217+
</member>
62126218
<member name="P:Microsoft.FluentUI.AspNetCore.Components.ListComponentBase`1.Multiple">
62136219
<summary>
62146220
If true, the user can select multiple elements.
@@ -6238,6 +6244,12 @@
62386244
⚠️ Only available when Multiple = true.
62396245
</summary>
62406246
</member>
6247+
<member name="P:Microsoft.FluentUI.AspNetCore.Components.ListComponentBase`1.SelectedOptionsExpression">
6248+
<summary>
6249+
Gets or sets an expression that identifies the bound selected options.
6250+
⚠️ Only available when Multiple = true.
6251+
</summary>
6252+
</member>
62416253
<member name="M:Microsoft.FluentUI.AspNetCore.Components.ListComponentBase`1.#ctor">
62426254
<summary />
62436255
</member>

examples/Demo/Shared/Pages/List/Autocomplete/AutocompletePage.razor

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,6 @@
66

77
<h1>Autocomplete</h1>
88

9-
<blockquote>
10-
@(new MarkupString(DemoNavProvider.EditFormOffIcon))
11-
The <b>FluentAutocomplete</b> component is not yet fully compatible with the <code>EditForm</code> and <code>FluentEditForm</code> elements.
12-
Some functionalities, such as error messages, the requirement message or the validation messages are missing.
13-
</blockquote>
14-
159
<h2 id="example">Examples</h2>
1610

1711
<DemoSection Title="Default" Component="@typeof(AutocompleteDefault)" />

examples/Demo/Shared/SampleData/Starship.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ public class Starship
2020
public string? Description { get; set; }
2121

2222
[Required(ErrorMessage = "Countries are required")]
23+
[MinLength(1, ErrorMessage = "Countries are required")]
2324
public IEnumerable<Country>? Countries { get; set; }
2425

2526
[Required(ErrorMessage = "A classification is required")]

src/Core/Components/List/ListComponentBase.razor.cs

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
// ------------------------------------------------------------------------
44

55
using System.Diagnostics.CodeAnalysis;
6+
using System.Linq.Expressions;
67
using Microsoft.AspNetCore.Components;
78
using Microsoft.AspNetCore.Components.Forms;
89
using Microsoft.AspNetCore.Components.Web;
@@ -37,7 +38,7 @@ public abstract partial class ListComponentBase<TOption> : FluentInputBase<strin
3738

3839
// We cascade the _internalListContext to descendants, which in turn call it to add themselves to the options list
3940
internal InternalListContext<TOption> _internalListContext;
40-
internal override bool FieldBound => Field is not null || ValueExpression is not null || ValueChanged.HasDelegate || SelectedOptionChanged.HasDelegate || SelectedOptionsChanged.HasDelegate;
41+
internal override bool FieldBound => Field is not null || ValueExpression is not null || ValueChanged.HasDelegate || SelectedOptionChanged.HasDelegate || SelectedOptionExpression is not null || SelectedOptionsChanged.HasDelegate || SelectedOptionsExpression is not null;
4142

4243
protected override async Task OnAfterRenderAsync(bool firstRender)
4344
{
@@ -149,6 +150,13 @@ protected string? InternalValue
149150
[Parameter]
150151
public virtual EventCallback<TOption?> SelectedOptionChanged { get; set; }
151152

153+
/// <summary>
154+
/// Gets or sets an expression that identifies the bound selected options.
155+
/// ⚠️ Only available when Multiple = false.
156+
/// </summary>
157+
[Parameter]
158+
public Expression<Func<TOption>>? SelectedOptionExpression { get; set; }
159+
152160
/// <summary>
153161
/// If true, the user can select multiple elements.
154162
/// ⚠️ Only available for the FluentSelect and FluentListbox components.
@@ -183,6 +191,13 @@ protected string? InternalValue
183191
[Parameter]
184192
public virtual EventCallback<IEnumerable<TOption>?> SelectedOptionsChanged { get; set; }
185193

194+
/// <summary>
195+
/// Gets or sets an expression that identifies the bound selected options.
196+
/// ⚠️ Only available when Multiple = true.
197+
/// </summary>
198+
[Parameter]
199+
public Expression<Func<IEnumerable<TOption>>>? SelectedOptionsExpression { get; set; }
200+
186201
/// <summary />
187202
public ListComponentBase()
188203
{
@@ -295,11 +310,20 @@ public override async Task SetParametersAsync(ParameterView parameters)
295310
}
296311
}
297312

298-
if (SelectedOptionChanged.HasDelegate)
313+
314+
if (SelectedOptionExpression is not null)
315+
{
316+
FieldIdentifier = FieldIdentifier.Create(SelectedOptionExpression);
317+
}
318+
else if (SelectedOptionChanged.HasDelegate)
299319
{
300320
FieldIdentifier = FieldIdentifier.Create(() => SelectedOption);
301321
}
302-
if (SelectedOptionsChanged.HasDelegate)
322+
else if (SelectedOptionsExpression is not null)
323+
{
324+
FieldIdentifier = FieldIdentifier.Create(SelectedOptionsExpression);
325+
}
326+
else if (SelectedOptionsChanged.HasDelegate)
303327
{
304328
FieldIdentifier = FieldIdentifier.Create(() => SelectedOptions);
305329
}
@@ -529,19 +553,8 @@ protected virtual async Task OnSelectedItemChangedHandlerAsync(TOption? item)
529553
{
530554
if (!Equals(item, SelectedOption))
531555
{
532-
var value = GetOptionValue(item);
533-
534-
if (this is FluentListbox<TOption> ||
535-
this is FluentCombobox<TOption> ||
536-
(this is FluentSelect<TOption> && Value is null))
537-
{
538-
await base.ChangeHandlerAsync(new ChangeEventArgs() { Value = value });
539-
}
540-
541556
SelectedOption = item;
542-
543-
//InternalValue = Value = value;
544-
InternalValue = value;
557+
InternalValue = GetOptionValue(item);
545558
await RaiseChangedEventsAsync();
546559
}
547560
}
@@ -564,6 +577,8 @@ protected virtual async Task RaiseChangedEventsAsync()
564577
await SelectedOptionChanged.InvokeAsync(SelectedOption);
565578
}
566579
}
580+
581+
await base.ChangeHandlerAsync(new ChangeEventArgs() { Value = InternalValue });
567582
}
568583

569584
protected virtual async Task OnKeydownHandlerAsync(KeyboardEventArgs e)

0 commit comments

Comments
 (0)