locked
How to refresh Table List after post submit RRS feed

  • Question

  • User1231912896 posted

    Hi guys,

    I'm implementing a razor page in which there is a bootstrap DateTimePicker and a Table to list my datas. When someone select a date in the DateTimePicker, it is visualized the corresponding data list in the table.

    In the Index.cshtml.cs file, I have implemented the OnGetAsync method as follow:

        public class IndexModel : PageModel
        {        
            
            [BindProperty(SupportsGet = true)]
            public List<Estrazioni> dtElencoEstrazioni { get; set; } = new List<Estrazioni>();
            
            private DateTime dtDataEstrazione;
            
            [BindProperty(SupportsGet = true)]
            public string strDataEstrazione { get; set; }        
            
            public async Task OnGetAsync()
            {
                try
                {
                    // Read selected date
                    //
                    strDataEstrazione = Request.Query["strDataEstrazione"];
                    //
                    if (string.IsNullOrEmpty(strDataEstrazione))
                    {
                        // Set last date
                        //
                        dtElencoEstrazioni = (await _estrazioniService.GetUltimaEstrazione()).ToList();
                        dtDataEstrazione = dtElencoEstrazioni.First().DataEstrazione;
                        strDataEstrazione = dtDataEstrazione.ToString("dd/MM/yyyy");
                    }
                    //
                    dtDataEstrazione = Convert.ToDateTime(strDataEstrazione);
                    dtElencoEstrazioni = (await _estrazioniService.GetEstrazioniPerData(dtDataEstrazione)).ToList();
    
                }
                catch (Exception ex)
                {
                    errorMessage = "OnGetAsync - " + ex.Message;
                }
    
            }
        }
    

    This is the Index.cshtml file:

        <form method="post">
            <div class="row h-100">
                <div style="text-align:left" class="col my-auto">
                    <div class="card-text">
                        <h4 class="card-title">Estrazione del @Model.strDataEstrazione</h4>
                    </div>
                </div>
                <div style="text-align:right" class="col my-auto">
                    <!--  CALENDARIO (DataPicker)   -->
                    <label>Data estrazione &nbsp; &nbsp; </label>
                    <input type="text" class="datetimepicker" id="datetimepicker" value="@Model.strDataEstrazione" />
                </div>
            </div>
    
            <!--  Impostazioni DataPicker   -->
            <script type="text/javascript">$(function () {
            $('.datetimepicker').datetimepicker({
                icons: {
                    time: "fa fa-clock-o",
                    date: "fa fa-calendar",
                    up: "fa fa-chevron-up",
                    down: "fa fa-chevron-down",
                    previous: 'fa fa-chevron-left',
                    next: 'fa fa-chevron-right',
                    today: 'fa fa-screenshot',
                    clear: 'fa fa-trash',
                    close: 'fa fa-remove'
                },
                enabledDates: @Html.Raw(@Model.strDataEstrazioneDisabilitate),
                inline: false,
                locale: 'it',
                minDate: '1930-01-01',
                format: 'DD/MM/YYYY'
            });
            $('.datetimepicker').on('dp.change', function (e) {
    
                $.ajax({
                    type: 'GET',
                    data: {strDataEstrazione : $('#datetimepicker').val() },
                    url: 'Index',
                    dataType: 'json'
                });
    
            });
        });</script>
    
        </form>
    
        @if (Model.dtElencoEstrazioni.Count != 0)
        {
            <table class="table table-striped table-hover">
                <thead>
                    <tr>
                        <th scope="col">Ruota</th>
                        <th scope="col">1° estratto</th>
                        <th scope="col">2° estratto</th>
                        <th scope="col">3° estratto</th>
                        <th scope="col">4° estratto</th>
                        <th scope="col">5° estratto</th>
                    </tr>
                </thead>
                <tbody>
                    @foreach (var obj in Model.dtElencoEstrazioni)
                    {
                        <tr>
                            <th style="text-align:left" scope="row">@obj.Ruota</th>
                            <td>@obj.Estrazione01</td>
                            <td>@obj.Estrazione02</td>
                            <td>@obj.Estrazione03</td>
                            <td>@obj.Estrazione04</td>
    						<td>@obj.Estrazione05</td>
                        </tr>
                    }
                </tbody>
            </table>
        }
    

    I notice that, when I select a new date in the DateTimePicker the OnGetAsync method is called and the new list of datas is readed from the DB, but the Model is not updated.

    So in the cshtml the Mode.dtElencoEstrazioni is not passed, and the new datas are not listed at all.

    I have tried many things, but I don't undestand if I need to change the Ajax call inside the DateTimePicker OnChange event in order to have a post submit or somethings similar.

    Please could someone help me?

    Thank you.

    Igor.

    Sunday, February 21, 2021 3:01 PM

Answers

  • User475983607 posted

    IMHO, the problem you are facing is not understanding how website and browsers work.  Razor Pages is a framework that is supposed to make programming web site easier but you managed to over complicate Razor Pages.  Why are you using AJAX?  What problem does AJAX  solve in your design?  As recommended in your other posts, a better design is calling an Web API end point.  Why are you ignoring this advice?

    Read the following...

    https://www.learnrazorpages.com/razor-pages/ajax.

    https://www.learnrazorpages.com/web-api

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Sunday, February 21, 2021 6:22 PM
  • User-474980206 posted

    As you are using asp.net core you should change the table to a ViewCompontent

    https://docs.microsoft.com/en-us/aspnet/core/mvc/views/view-components?view=aspnetcore-5.0

    then the Ajax action should return a view component as shown above. Then the ajax call can use the response html to display a new table.

    another approach is to render the table in JavaScript and the ajax call uses response data To render the table.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Sunday, February 21, 2021 7:04 PM
  • User1686398519 posted

    Hi igorbaldacci, 

    1. I want to explain to you briefly what Ajax is.
      1. Simply put, ajax does not refresh the entire page.
      2. In addition, we can understand this:
        1. Ajax request is to use JS to initiate a request and get the content returned by the server.
        2. You can see that the method (Index/OnGet) requested in the code you provided does not return data.
    2. According to your needs, I have a solution, you can send the request without ajax. You can check my demo below.
      • I wrote this demo based on the code you provided.
    3. You can click on the links below, they can help you learn Razor pages.
      1. Model Binding
      2. Model Binding in ASP.NET Core
      3. add search to ASP.NET Core Razor Pages

    Model

        public class Estrazioni
        {
            public int Id { get; set; }
            public string Ruota{ get; set; }
            public string Estrazione01{ get; set; }
            public string Estrazione02{ get; set; }
            public string Estrazione03{ get; set; }
            public string Estrazione04{ get; set; }
            public string Estrazione05{ get; set; }
            public DateTime DataEstrazione { get; set; }
        }

    UpdatePage.cshtml.cs

        public class UpdatePageModel : PageModel
        {
            public DailyRazorPageDemoContext db;
            public UpdatePageModel(DailyRazorPageDemoContext _db)
            {
                db = _db;
            }
            [BindProperty(SupportsGet = true)]
            public List<Estrazioni> dtElencoEstrazioni { get; set; } = new List<Estrazioni>();
            private DateTime dtDataEstrazione;
            [BindProperty(SupportsGet = true)]
            public string strDataEstrazione { get; set; }
            [BindProperty(SupportsGet = true)]
            public string errorMessage { get; set; }
            public void OnGet()
            {
                try
                {
                    if (string.IsNullOrEmpty(strDataEstrazione))
                    {
                        dtElencoEstrazioni = db.Estrazionis.OrderByDescending(m => m.DataEstrazione).ToList();
                        dtDataEstrazione = dtElencoEstrazioni.First().DataEstrazione;
                        strDataEstrazione = dtDataEstrazione.ToString("dd/MM/yyyy");
                    }
                    CultureInfo provider = CultureInfo.InvariantCulture;
                    dtDataEstrazione = DateTime.ParseExact(strDataEstrazione, "dd/MM/yyyy", provider);
                    dtElencoEstrazioni = db.Estrazionis.Where(m => m.DataEstrazione == dtDataEstrazione).ToList();
                }
                catch (Exception ex)
                {
                    errorMessage = "OnGetAsync - " + ex.Message;
                }
    
            }
        }

    UpdatePage.cshtml

    @model DailyRazorPageDemo.Pages.UpdatePageModel
    <form>
        <div class="row h-100">
            <div style="text-align:left" class="col my-auto">
                <div class="card-text">
                    <h4 class="card-title">Estrazione del @Model.strDataEstrazione</h4>
                </div>
            </div>
            <div style="text-align:right" class="col my-auto">
                <!--  CALENDARIO (DataPicker)   -->
                <label>Data estrazione &nbsp; &nbsp; </label>
                <input type="text" class="datetimepicker" id="datetimepicker" asp-for="strDataEstrazione" />
            </div>
        </div>
    </form>
    
    @if (Model.dtElencoEstrazioni.Count != 0)
    {
        <table class="table table-striped table-hover">
            <thead>
                <tr>
                    <th scope="col">Ruota</th>
                    <th scope="col">1° estratto</th>
                    <th scope="col">2° estratto</th>
                    <th scope="col">3° estratto</th>
                    <th scope="col">4° estratto</th>
                    <th scope="col">5° estratto</th>
                </tr>
            </thead>
            <tbody>
                @foreach (var obj in Model.dtElencoEstrazioni)
                {
                    <tr>
                        <th style="text-align:left" scope="row">@obj.Ruota</th>
                        <td>@obj.Estrazione01</td>
                        <td>@obj.Estrazione02</td>
                        <td>@obj.Estrazione03</td>
                        <td>@obj.Estrazione04</td>
                        <td>@obj.Estrazione05</td>
                    </tr>
                }
            </tbody>
        </table>
    }
    @section scripts{
        <script src="~/moment.js/moment.js"></script>
        <script src="~/bootstrap-datetimepicker/js/bootstrap-datetimepicker.min.js"></script>
        <script type="text/javascript">
        $(function () {
            $('.datetimepicker').datetimepicker({
                icons: {
                    time: "fa fa-clock-o",
                    date: "fa fa-calendar",
                    up: "fa fa-chevron-up",
                    down: "fa fa-chevron-down",
                    previous: 'fa fa-chevron-left',
                    next: 'fa fa-chevron-right',
                    today: 'fa fa-screenshot',
                    clear: 'fa fa-trash',
                    close: 'fa fa-remove'
                },
                inline: false,
                locale: 'it',
                minDate: '1930-01-01',
                format: 'DD/MM/YYYY'
            });
            $('.datetimepicker').on('dp.change', function (e) {
                $("form").submit();
            });
        });
        </script>
    }

    Best Regards,

    YihuiSun

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, February 22, 2021 5:54 AM

All replies

  • User475983607 posted

    The code you've shared indicates you do not understand how AJAX works.  The page is not refreshed automatically. The response is returned to the AJAX function and it is up to you to write code (JavaScript) to update the page.

    You'll need to learn the fundamentals before moving forward because you are guessing how the technology works both Razor Pages and AJAX.

    Sunday, February 21, 2021 3:24 PM
  • User1231912896 posted

    Thank you mgebhard,

    you are right I'm new in razor page.

    I have read a lot but I need to clarify "how" to write javascript code to update the page. This is the help I need.

    Also a link will be an help for me.

    Sunday, February 21, 2021 5:15 PM
  • User475983607 posted

    IMHO, the problem you are facing is not understanding how website and browsers work.  Razor Pages is a framework that is supposed to make programming web site easier but you managed to over complicate Razor Pages.  Why are you using AJAX?  What problem does AJAX  solve in your design?  As recommended in your other posts, a better design is calling an Web API end point.  Why are you ignoring this advice?

    Read the following...

    https://www.learnrazorpages.com/razor-pages/ajax.

    https://www.learnrazorpages.com/web-api

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Sunday, February 21, 2021 6:22 PM
  • User-474980206 posted

    As you are using asp.net core you should change the table to a ViewCompontent

    https://docs.microsoft.com/en-us/aspnet/core/mvc/views/view-components?view=aspnetcore-5.0

    then the Ajax action should return a view component as shown above. Then the ajax call can use the response html to display a new table.

    another approach is to render the table in JavaScript and the ajax call uses response data To render the table.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Sunday, February 21, 2021 7:04 PM
  • User1686398519 posted

    Hi igorbaldacci, 

    1. I want to explain to you briefly what Ajax is.
      1. Simply put, ajax does not refresh the entire page.
      2. In addition, we can understand this:
        1. Ajax request is to use JS to initiate a request and get the content returned by the server.
        2. You can see that the method (Index/OnGet) requested in the code you provided does not return data.
    2. According to your needs, I have a solution, you can send the request without ajax. You can check my demo below.
      • I wrote this demo based on the code you provided.
    3. You can click on the links below, they can help you learn Razor pages.
      1. Model Binding
      2. Model Binding in ASP.NET Core
      3. add search to ASP.NET Core Razor Pages

    Model

        public class Estrazioni
        {
            public int Id { get; set; }
            public string Ruota{ get; set; }
            public string Estrazione01{ get; set; }
            public string Estrazione02{ get; set; }
            public string Estrazione03{ get; set; }
            public string Estrazione04{ get; set; }
            public string Estrazione05{ get; set; }
            public DateTime DataEstrazione { get; set; }
        }

    UpdatePage.cshtml.cs

        public class UpdatePageModel : PageModel
        {
            public DailyRazorPageDemoContext db;
            public UpdatePageModel(DailyRazorPageDemoContext _db)
            {
                db = _db;
            }
            [BindProperty(SupportsGet = true)]
            public List<Estrazioni> dtElencoEstrazioni { get; set; } = new List<Estrazioni>();
            private DateTime dtDataEstrazione;
            [BindProperty(SupportsGet = true)]
            public string strDataEstrazione { get; set; }
            [BindProperty(SupportsGet = true)]
            public string errorMessage { get; set; }
            public void OnGet()
            {
                try
                {
                    if (string.IsNullOrEmpty(strDataEstrazione))
                    {
                        dtElencoEstrazioni = db.Estrazionis.OrderByDescending(m => m.DataEstrazione).ToList();
                        dtDataEstrazione = dtElencoEstrazioni.First().DataEstrazione;
                        strDataEstrazione = dtDataEstrazione.ToString("dd/MM/yyyy");
                    }
                    CultureInfo provider = CultureInfo.InvariantCulture;
                    dtDataEstrazione = DateTime.ParseExact(strDataEstrazione, "dd/MM/yyyy", provider);
                    dtElencoEstrazioni = db.Estrazionis.Where(m => m.DataEstrazione == dtDataEstrazione).ToList();
                }
                catch (Exception ex)
                {
                    errorMessage = "OnGetAsync - " + ex.Message;
                }
    
            }
        }

    UpdatePage.cshtml

    @model DailyRazorPageDemo.Pages.UpdatePageModel
    <form>
        <div class="row h-100">
            <div style="text-align:left" class="col my-auto">
                <div class="card-text">
                    <h4 class="card-title">Estrazione del @Model.strDataEstrazione</h4>
                </div>
            </div>
            <div style="text-align:right" class="col my-auto">
                <!--  CALENDARIO (DataPicker)   -->
                <label>Data estrazione &nbsp; &nbsp; </label>
                <input type="text" class="datetimepicker" id="datetimepicker" asp-for="strDataEstrazione" />
            </div>
        </div>
    </form>
    
    @if (Model.dtElencoEstrazioni.Count != 0)
    {
        <table class="table table-striped table-hover">
            <thead>
                <tr>
                    <th scope="col">Ruota</th>
                    <th scope="col">1° estratto</th>
                    <th scope="col">2° estratto</th>
                    <th scope="col">3° estratto</th>
                    <th scope="col">4° estratto</th>
                    <th scope="col">5° estratto</th>
                </tr>
            </thead>
            <tbody>
                @foreach (var obj in Model.dtElencoEstrazioni)
                {
                    <tr>
                        <th style="text-align:left" scope="row">@obj.Ruota</th>
                        <td>@obj.Estrazione01</td>
                        <td>@obj.Estrazione02</td>
                        <td>@obj.Estrazione03</td>
                        <td>@obj.Estrazione04</td>
                        <td>@obj.Estrazione05</td>
                    </tr>
                }
            </tbody>
        </table>
    }
    @section scripts{
        <script src="~/moment.js/moment.js"></script>
        <script src="~/bootstrap-datetimepicker/js/bootstrap-datetimepicker.min.js"></script>
        <script type="text/javascript">
        $(function () {
            $('.datetimepicker').datetimepicker({
                icons: {
                    time: "fa fa-clock-o",
                    date: "fa fa-calendar",
                    up: "fa fa-chevron-up",
                    down: "fa fa-chevron-down",
                    previous: 'fa fa-chevron-left',
                    next: 'fa fa-chevron-right',
                    today: 'fa fa-screenshot',
                    clear: 'fa fa-trash',
                    close: 'fa fa-remove'
                },
                inline: false,
                locale: 'it',
                minDate: '1930-01-01',
                format: 'DD/MM/YYYY'
            });
            $('.datetimepicker').on('dp.change', function (e) {
                $("form").submit();
            });
        });
        </script>
    }

    Best Regards,

    YihuiSun

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, February 22, 2021 5:54 AM
  • User1231912896 posted

    Hi YihuiSun,

    thank you for your help. I have followed your suggestions and now my page works.

    In my intent there was the idea to use Ajax, but I was not able to do it! I stardted with the intent to use an Ajax call inside the DateTimePicker OnChange event, but maybe the incorrect use of the Razor concept did the wrong things.
     
    I can understand the difference to use Ajax, now with the use of your idea the entire page is refresh.
    I'll study your links and the others links sended me in other answers abowe to understand the correct use of Razor Pages with Ajax.

    Thanks a lot.

    Monday, February 22, 2021 8:46 AM