Comments (25)
@vnbaaij my comment is strictly with regards to binding properties, not about binding to checkboxes, etc. There are other ways to solve that.
from fluentui-blazor.
@nicholasrice Is this bug a result of Blazor trying to update through the attribute and not the property (and special casing for built-ins around this scenario)? This has come up in the community again and we need to pick back up that discussion thread and drive for a resolution. We may need @chrisdholt to help with that as it may involve changes in our components to help work around the missing Blazor feature (binding to properties).
from fluentui-blazor.
This is also being discussed in dotnet/aspnetcore#27030. There is a solution in the PR which might be able to be baked into .NET 6
from fluentui-blazor.
Yea that's my understanding of the issue. I think making components work with attributes or properties is the most pragmatic approach at this point, though I do wish Blazor (and other lacking UI systems) provided explicit property and attribute bindings.
If we do end up doing the work to make components work with properties or attributes, we'll need to make sure that form-associated controls still behave correctly in some of the edge-case scenarios like form resets and form-state restoration
from fluentui-blazor.
I do wish Blazor provided explicit property and attribute bindings.
@SteveSandersonMS @javiercn Is this something we should consider in Blazor?
from fluentui-blazor.
@danroth27 Today Blazor only works with attributes.
We've discussed this in the past, however its not something to be done lightly since it has an impact on the language and the runtime. If we think this is important we can put it on the list for 7.0, since this needs design and time to bake as the consequences of getting it wrong are bad.
from fluentui-blazor.
@danroth27 Today Blazor only works with attributes.
We've discussed this in the past, however its not something to be done lightly since it has an impact on the language and the runtime. If we think this is important we can put it on the list for 7.0, since this needs design and time to bake as the consequences of getting it wrong are bad.
While I understand that you want this to be done right, waiting till 7.0 means there won't be a compelling reason to release this library until then. Ability to bind checkboxes etc is crucial.
Can an interim solution like mentioned in dotnet/aspnetcore#27030 be used to make binding possible sooner (and maybe even backported to 5.x)?
from fluentui-blazor.
Good to hear. Thanks! For solving this binding problem, what would be the best option, you think?
from fluentui-blazor.
@javiercn @vnbaaij regarding model binding with Blazor bind syntax, you have mentioned, "There are other ways to solve that." What are these other ways? How can we use the workaround in .NET 5 to model bind to FAST radio, checkbox, select, etc. …. Right now, we are stuck in our evaluation for FAST components with balzor/asp.net core model binding?
from fluentui-blazor.
What are these other ways?
I expect this refers to solutions like dotnet/aspnetcore#27030
from fluentui-blazor.
The components can also be updated to also update the DOM attribute, or some additional JS interop can be used to setup a callback on the element and trigger the attribute update (which should in turn trigger the event?)
from fluentui-blazor.
Is there some way we can plug into Blazor's JS bridge? In that code there's some conditional logic that handles built-in inputs and chooses to set their properties instead of their attributes. Could the FAST team write some JS code that hooks into that to add our elements to a "list" of special cases? That would let us teach Blazor how to handle all these scenarios without introducing special syntax in Blazor or needing to make changes in the web components themselves. Thoughts? Does Blazor provide a JS global we could monkey patch or could you provide an official JS API for this case? My team is happy to contribute that work directly to Blazor if that seems like a reasonable solution. /cc @SteveSandersonMS @javiercn
from fluentui-blazor.
@javiercn , @EisenbergEffect , I am not a DOM expert but i tried few solutions on hooking up some JS code with Blazor components. And Model binding now seems to work. It is definitely a hack but is this something that can work reliably till you guys provide a long term solution. Do you see any issues with the approach below ?
BlazorFastCheckBox.razor
<fast-checkbox @ref="_element" id="@Id" checked="@CurrentValue" @onchange="@OnChangeHandlerAsync" disabled="@Disabled">
@ChildContent
</fast-checkbox>
/// <summary>
/// The @onchange handler for the fast-checkbox. We are introducing a hack here to force model bind with the underlying field.
// We rely on the checked class being applied when user changes the checked state.
// Verify with ms team that this is reliable and an acceptable work around.
/// <param name="args"></param>
/// <returns></returns>
/// </summary>
/// <param name="args"></param>
/// <returns></returns>
private async Task OnChangeHandlerAsync(ChangeEventArgs args)
{
if (Disabled)
{
return;
}
if (Id == null)
{
await JsInteropService.AlertAsync("Id not provided for check box. Model binding requires a unique id.");
return;
}
// TODO:
// https://github.com/microsoft/fast/issues/4782
// https://github.com/microsoft/fast/issues/4248
// https://github.com/microsoft/fast-blazor/issues/39
// There are known issues around checkbox not model binding. For now we use the onchange event to get the HTML element and check it class list.
// Fast component adds checked to class list to indicate checked state.
bool checkedState = await JsInteropService.HasClass(Id, "checked");
// For prerendering onchange event is called before the HTML is updated with checked class !
if (RenderMode == "ServerPrerendered" || RenderMode == "WebAssemblyPrerendered")
{
// TODO: HACK
// Another issue is for prerendering, onchange event is called before the updated HTML is rendered. So HasClass returns the previous 'checked' state.
// Since this is a toggle and value is true or false just flip the checkedState to indicate the new value.
checkedState = !checkedState;
}
// Update the model bind value.
await ValueChanged.InvokeAsync(checkedState);
// Make sure the edit context is notified of field change.
EditContext.NotifyFieldChanged(FieldIdentifier);
}
from fluentui-blazor.
Interesting. It could be a little brittle basing it on the presence of a class. I think that might go away eventually. I'd like to get @nicholasrice's opinion on that as well as @chrisdholt. Does the JsInteropService provide a way to get a property value? Maybe that could be added and we could use that API. We could make this backward compatible with some conditional compilation to fall back to the class check too.
For the checking by Id, could we generate one if one isn't provided so that we don't have to pass that cost along to the developer?
In general, I'm not opposed to adding this sort of code in the few places it's needed if that enables the key scenario.
from fluentui-blazor.
The async nature of DOM updates in FAST concerns me with this approach, where the class might not have changed prior to event emission depending on implementation details. We also generally try to not hoist classes onto the host element because it's very easy for libraries to clobber those classes (obviously checkbox is an exception), though in those cases we use attribute selectors which could theoretically be leveraged.
At some point we hope to use custom states / pseudo classes instead of real classes for some cases like this, at which point classes and attributes will go away, but it is unclear how long we'll be waiting for browser-support.
from fluentui-blazor.
Updating this thread with a link to our RFC which we believe will address all the form binding issues: microsoft/fast#5119
We'll be discussing this next week. Please weigh in on the RFC with any relevant feedback. Thank you everyone for your patience in this!
from fluentui-blazor.
Not sure if this is same issue or new, but the FluentSelect component does not work for setting the current value.
Looking at source it's binding to the fluent-select value
attribute:
- The fluent-select is thin wrapper around the fast-select component in fast-foundation.
- fast-select shows no Attribute for value, only a Property for setting / viewing the value in the spec.
- I see fast-select extends
FormAssociated
which may have an attribute for value but doesn't seem to do anything:
var select = document.querySelector('fast-select');
select.value = "value"; // works!
select.setAttribute("value", "value") // does nothing, not sure if this would work anyway after component created
Might be making some incorrect assumptions as I'm not familiar with how blazor binds data to native webcomponents, working with the base fast-component doesn't work either with value:
<fast-select value="xxx"> <!-- does not show xxx as value -->
<fast-option value="yyy">yyy</fast-option>
<fast-option value="xxx">xxx</fast-option>
</fast-select>
Is this a blazor implementation issue or is the fast-select supposed to work with a value attribute?
from fluentui-blazor.
@plaisted A few different things to note here:
- This library currently only has wrappers for the
fluent-
components, not thefast-
components. They are both based on the same foundation components though, so fixes we make in foundation should correct both design systems, regardless of whether these wrappers are being used or not. - The above RFC is absolutely related to the bugs with the
select
in general. The fix proposed should correct all our form components. - There is likely an additional issue with the select. A couple of people from our team have been talking about making some improvements around selected values for the
select
. I think those would either happen shortly after implementing the rfc or at the same time, depending on resources.
from fluentui-blazor.
Thanks, I crisscrossed fluent-
with fast-
but the the issue occurs in both components for the select. Sounds like something not working with select
since other form controls work with the value
attribute. I'll keep an eye on the RFC progress but for now will use another select implementation as blazor is very tedious to interop with web component properties.
from fluentui-blazor.
@javiercn , @EisenbergEffect , I am not a DOM expert but i tried few solutions on hooking up some JS code with Blazor components. And Model binding now seems to work. It is definitely a hack but is this something that can work reliably till you guys provide a long term solution. Do you see any issues with the approach below ?
BlazorFastCheckBox.razor
<fast-checkbox @ref="_element" id="@Id" checked="@CurrentValue" @onchange="@OnChangeHandlerAsync" disabled="@Disabled"> @ChildContent </fast-checkbox>
/// <summary> /// The @onchange handler for the fast-checkbox. We are introducing a hack here to force model bind with the underlying field. // We rely on the checked class being applied when user changes the checked state. // Verify with ms team that this is reliable and an acceptable work around. /// <param name="args"></param> /// <returns></returns> /// </summary> /// <param name="args"></param> /// <returns></returns> private async Task OnChangeHandlerAsync(ChangeEventArgs args) { if (Disabled) { return; } if (Id == null) { await JsInteropService.AlertAsync("Id not provided for check box. Model binding requires a unique id."); return; } // TODO: // https://github.com/microsoft/fast/issues/4782 // https://github.com/microsoft/fast/issues/4248 // https://github.com/microsoft/fast-blazor/issues/39 // There are known issues around checkbox not model binding. For now we use the onchange event to get the HTML element and check it class list. // Fast component adds checked to class list to indicate checked state. bool checkedState = await JsInteropService.HasClass(Id, "checked"); // For prerendering onchange event is called before the HTML is updated with checked class ! if (RenderMode == "ServerPrerendered" || RenderMode == "WebAssemblyPrerendered") { // TODO: HACK // Another issue is for prerendering, onchange event is called before the updated HTML is rendered. So HasClass returns the previous 'checked' state. // Since this is a toggle and value is true or false just flip the checkedState to indicate the new value. checkedState = !checkedState; } // Update the model bind value. await ValueChanged.InvokeAsync(checkedState); // Make sure the edit context is notified of field change. EditContext.NotifyFieldChanged(FieldIdentifier); }
I would have done this at the JS layer directly by capturing a reference to the element with a @ref
and attaching a handler to update the value attribute and trigger the event.
from fluentui-blazor.
PR is now up with the new current-value
feature which will solve this issue for all form controls: microsoft/fast#5298 Once that is merged, we'll add the new property to the wrappers. Thank you everyone for your patience on this. We needed to find a solution that would work best with multiple libraries and frameworks, which we could also bring to W3C as a recommendation to help improve the built-in form elements in the future (without breaking the web).
from fluentui-blazor.
We've merged and released the first fix to improve form components in general. We're now working on a couple of additional fixes for checkboxes and radios. We believe those will go in this week.
from fluentui-blazor.
In terms of the Blazor integration, we're close to merging the .NET 6 work. After that we'll update the Blazor components to take advantage of the new features.
from fluentui-blazor.
One more PR related to this is under review here: microsoft/fast#5326
from fluentui-blazor.
Both core FAST PRs are now merged. We're also about to merge an update to the Blazor wrappers. We'll have one more Blazor wrapper update after that and then we should be able to close this as done.
from fluentui-blazor.
Related Issues (20)
- Communication Toast MissingMethodException after deployment to Static Web site HOT 4
- fix: @bind-Value doesn't update the UI when changing Items at the same time in FluentCombobox HOT 2
- feat: add the ability to specify a column width at the column level for the FluentDataGrid HOT 5
- Please create Rich Text Editor HOT 1
- fix: Button for responsive menu overlaps with profile menu in demo website HOT 1
- GlobalState is set to default on wasm startup HOT 16
- feat: Provide fragment to extend Profile Menu Button HOT 5
- Add DI Registration for IToastService, IMesssageService, IDialogServicedocs to the documentation HOT 1
- fix: FluentHorizontalScroll shows all elements and has no scroll button HOT 2
- fix: KeyCodeService in Microsoft.FluentUI.AspNetCore.Components.FluentDataGrid HOT 2
- fix: DataGrid GridTemplateColumns not working HOT 6
- Hello, some suggestions, hope to get discussion and help.
- fix: `Virtualize=true` conflicts with `Class="multiline-text"` in FluentDataGrid HOT 4
- fix: broken Disabled flag in FluentNavLink HOT 1
- Regression in Theme sample after update to 4.7,1 HOT 6
- feat: add horizontal nav menu component HOT 3
- Javascript error when loading Data Grid items with Virtualize Interactive server side rendering HOT 1
- fix(Microsoft.FluentUI.AspNetCore.Components): missing LEGAL.txt HOT 4
- Allow for FluentTextField to inherit font-weight HOT 7
- fix: Selected option retained ordinal position after items changed in FluentSelect HOT 2
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from fluentui-blazor.