dotnet / aspnetcore

ASP.NET Core is a cross-platform .NET framework for building modern cloud-based web applications on Windows, Mac, or Linux.
https://asp.net
MIT License
35.21k stars 9.95k forks source link

Blazor Web Assembly Application - input field binding is not working after calling JavaScript document ready for Select2, Calendar and other plugins from blazor component #27844

Closed linktoaqeel closed 3 years ago

linktoaqeel commented 3 years ago

I am using the AdminLTE template in my Blazor wasm application. The template is working fine but I am having an issue with input fields binding. I have a data filtering form and the application should apply the selected filter values to fetch the new data. I have to change the "on document ready" function to the below code in the index.html file to make the jquery plugin working.

<script>
    function onBlazorReady() {
        //Initialize Select2 Elements
        $('.select2').select2();
        //Initialize Select2 Elements
        $('.select2bs4').select2({
            theme: 'bootstrap4'
        }); 

        //Date range picker
        $('#reservation').daterangepicker();
    }
</script>

In my razor component, I am calling the above-mentioned function as shown below:

private string DepartmentIdList { get; set; }
private string EmployeeId { get; set; }
private string Daterange { get; set; }

protected override void OnAfterRender(bool firstRender)
{
    if (firstRender)
    {
        JS.InvokeVoidAsync("onBlazorReady");
    }
}

I have bind the HTML tags in my razor component with C# variables:


<div class="col-md-3">
                        <div class="form-group">
                            <label>Employee</label>
                            <select id="ddEmployee" class="form-control select2bs4" style="width: 100%;" @bind="EmployeeId">
                                <option value="-1" selected="selected">All</option>
                                <option value="1">Aqeel</option>
                                <option value="2">Ehsan</option>
                                <option value="3">Shajar</option>
                                <option value="4">Salman</option>
                                <option value="5">Noman</option>
                            </select>
                        </div>

If I don't call the "onBlazorReady" function then data binding is working but the plugins are not reflecting as expected. I am using different controls such as date range control with the calendar and multiple selections for choosing departments. So I need to call the "onBlazorReady" function. But when I invoke this function then data binding stops working.

When the user clicks on the "Apply" button, I want to get the selected values and load data based on applied filters.

Blazor-Model-Binding-Select2-plugin

mkArtakMSFT commented 3 years ago

Thank you for filing this issue. In order for us to investigate this issue, please provide a minimalistic repro project (ideally a GitHub repo) that illustrates the problem. Please note, that if a library you're using is trying to mutate the DOM on its own, that can break Blazor. You can read more about this at: https://docs.microsoft.com/en-us/aspnet/core/blazor/call-javascript-from-dotnet?view=aspnetcore-5.0#use-of-javascript-libraries-that-render-ui-dom-elements

linktoaqeel commented 3 years ago

Thank you, @mkArtakMSFT for checking this thread.

I have uploaded my sample repository on Github. As I have mentioned that I am using the Select2 jquery plugin in my project and because of this plugin Blazor model variable is not updating if the user makes any selection from the drop-down list or changes the date range from the calendar plugin.

I hope the uploaded repo would replicate the same issue and help to resolve this issue. Waiting for your feedback

SteveSandersonMS commented 3 years ago

Hi @linktoaqeel

In general, jQuery plugins that mutate the DOM shouldn't be expected to work automatically with any SPA framework (whether that's Blazor, React, Angular, Vue, etc.). This is because SPA frameworks take control over their own DOM rendering and if some external code mutates the DOM, they don't know what's going on with it. This is covered in the docs at https://docs.microsoft.com/en-us/aspnet/core/blazor/call-javascript-from-dotnet?view=aspnetcore-5.0#use-of-javascript-libraries-that-render-ui-dom-elements

Rather than relying on jQuery plugins, it's recommended to build the UI you want using components from the SPA framework you're using (e.g., for Blazor, use Blazor components, or for React use React components).

In more advanced cases you can use JS interop to render DOM contents using external JS libraries but you will have to take care of keeping that independent of the DOM contents rendered by your SPA framework, and write your own logic to keep the two in sync. This is how people implement SPA-framework-specific wrappers for libraries like Select2.

ghost commented 3 years ago

This issue has been resolved and has not had any activity for 1 day. It will be closed for housekeeping purposes.

See our Issue Management Policies for more information.