Home > Enterprise >  Razor Pages - Updating a Model with AJAX and PartialView
Razor Pages - Updating a Model with AJAX and PartialView

Time:12-30

I'm starting to study Razor Pages and using MongoDB as my database.

I finished my CRUD operations, and now I'm working on my main page.

Main Page

But I can't understand how to update partially my page

the first search (Default taking DateTime.Now) is already working as expected, but when I change the month selector, my page doesn't update with the current list I'm working with.

I'm using AJAX for this POST method on my View:

(ContaView.cshtml)

@page
@using System.Globalization
@model ControleContas.Pages.Contas.ContasViewModel
@{
}

<script>
    function changeDateSelector(date){
        var dataAtualizada = date.value;
        $.ajax({
            type: "POST",
            url: '/Contas/ContaView?handler=MonthSelector',
            contentType: "application/json; charset=utf-8",
            dataType: "json",
            data: JSON.stringify(dataAtualizada),
            headers:
            {
                "RequestVerificationToken": $('input:hidden[name="__RequestVerificationToken"]').val()
            }
        });
    }
</script>

<div>
    <a  asp-area="" asp-page="/Contas/ContaCadastro"><button type="button" >Cadastrar Cartão</button></a>
</div>

<th scope="row"><button type="button"  data-bs-toggle="modal" data-bs-target="#CreateModal">Criar</button></th>
<br />
<div id="titleMonth">@Model.dataCorrente.ToString("MMMM", CultureInfo.CreateSpecificCulture("pt-br"))</div>
<br />
<button type="button" >&larr;</button>
<input min="@(DateTime.Now.AddYears(-10).ToString("yyyy-MM"))" max="@(DateTime.Now.AddYears(10).ToString("yyyy-MM"))" onchange="changeDateSelector(this)" asp-for="dataCorrente" type="month">
<button type="button" >&rarr;</button>

<!-- Modal -->
<div  id="CreateModal" tabindex="-1" role="dialog" aria-labelledby="CreateTitle" aria-hidden="true">
    <div  role="document">
        <div >
            <div >
                <h5  id="CreateTitle">Criar Conta</h5>
                <button type="button"  data-bs-dismiss="modal" aria-label="Close">
                    <span aria-hidden="true">&times;</span>
                </button>
            </div>
            <form method="post">
                <div >
                    <input id="UserModal" hidden="hidden"></input>
                    <div >
                        <label>Nome da Conta</label>
                        <input id="ValorCreateModal" asp-for="conta.Nome" type="text"  placeholder="Nome" />
                    </div>
                    <div >
                        <label>Valor</label>
                        <input id="ValorCreateModal" asp-for="conta.Valor" type="text"  placeholder="Valor" />
                    </div>
                    <div >
                        <label>Data</label>
                        <input id="DataCreateModal" asp-for="conta.Data" type="date"  placeholder="Data da Conta" />
                    </div>
                    <div >
                        <label>Prestações</label>
                        <input id="PrestacoesCreateModal" asp-for="conta.TotalPrestacoes" type="number"  placeholder="Insira aqui a Quantidade de Prestações (1 - à Vista)" />
                    </div>
                    <div >
                        <label>Pago?</label>
                        <input id="DespesaCreateModal" asp-for="conta.Pago" type="checkbox"  />
                    </div>
                    <div >
                        <label>Despesa?</label>
                        <input id="DespesaCreateModal" asp-for="conta.Despesa" type="checkbox"  />
                    </div>
                    <!--
                        TODO: Criar um CheckBox para identificar se é uma conta para cartão, se for habilitar Selection para apresentar os cartões e assim vincular ele se não, vincular ao identity Logado.
                     <div >
                        <label>Cartão?</label>
                        <input id="FimCartaoModal" type="text"  placeholder="Fim Cartão" />
                    </div>-->
                </div>
                <div >
                    <button type="button"  data-bs-dismiss="modal">Close</button>
                    <button type="submit" asp-page-handler="create" >Save</button>
                </div>
            </form>
        </div>
    </div>
</div>

<table >
    <tr>
        <th>Id</th>
        <th>Nome</th>
        <th>Valor</th>
        <th>Data</th>
        <th>Prestação</th>
        <th>Cartão</th>
        <th>Pago?</th>
        <th>Despesa?</th>
        <th></th>
        <th></th>
    </tr>
    @foreach (var conta in Model.contas)
    {
        <tr>
            <th>@conta._id</th>
            <th>@conta.Nome</th>
            <th>@conta.Valor</th>
            <th>@conta.Data.ToShortDateString()</th>
            <th>@(conta.TotalPrestacoes == 1 ? "" : $"{conta.PrestacaoAtual}/{conta.TotalPrestacoes}")</th>
            <th>@conta.CartaoId</th>
            <th>@(conta.Pago ? "Sim" : "Não")</th>
            <th>@(conta.Despesa ? "Sim" : "Não")</th>
            <th><button type="button"  data-bs-toggle="modal" data-bs-target="#CreateModal">Editar</button></th>
            <th><button type="button" >Deletar</button></th>
        </tr>
    }
</table>

ContaView.cshtml.cs

using ControleContas.DTO.Contas;
using ControleContas.Models.Contas;
using ControleContas.Services;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.RazorPages;
using System.ComponentModel.DataAnnotations;

namespace ControleContas.Pages.Contas
{
    public class ContasViewModel : PageModel
    {
        private readonly ContaDTO contaDTO;

        [BindProperty]
        public List<Conta> contas { get; set; }

        [BindProperty]
        public Conta conta { get; set; }

        [BindProperty]
        [DataType(DataType.Date)]
        public DateTime dataCorrente { get; set; } = DateTime.Now;

        public ContasViewModel(IConfiguration config)
        {
            this.contaDTO = new ContaDTO(config);
        }

        public void OnGet()
        {
            contas = BuscarContasUsuarioMes(User.Identity.Name, dataCorrente);
        }

        public IActionResult OnPostCreate()
        {
            conta.NomeUsuario = User.Identity.Name;
            if(conta.TotalPrestacoes > 1)
            {
                var dataBase = conta.Data;
                List<Conta> prestacoesContas = new List<Conta>();
                for (int i = 0; i < conta.TotalPrestacoes; i  )
                {
                    var contaPrestacao = new Conta
                    {
                        CartaoId = conta.CartaoId,
                        Despesa = conta.Despesa,
                        NomeUsuario = conta.NomeUsuario,
                        Nome = conta.Nome,
                        Pago = false,
                        PrestacaoAtual = i   1,
                        Valor = conta.Valor,
                        TotalPrestacoes = conta.TotalPrestacoes,
                        Data = dataBase
                    };
                    dataBase = dataBase.AddMonths(1);
                    prestacoesContas.Add(contaPrestacao);
                }
                contaDTO.CreateMany(prestacoesContas, contaDTO.Database, contaDTO.ContaCollection);
            }
            else
            {
                conta.PrestacaoAtual = 1;
                conta.Pago = false;
                contaDTO.Create(conta, contaDTO.Database, contaDTO.ContaCollection);
            }
            return Redirect("ContaView?data="   dataCorrente.Year   dataCorrente.Month);
        }

        public PartialViewResult OnPostMonthSelector([FromBody] string dataAtualizada)
        {
            dataCorrente = DateTime.ParseExact(dataAtualizada, "yyyy-MM", null);
            contas = BuscarContasUsuarioMes(User.Identity.Name, dataCorrente);
            return Partial("ContaView", contas);
        }

        private List<Conta> BuscarContasUsuarioMes(string user, DateTime data)
        {
            return contaDTO.buscaContasUsuario(user).Where(c => c.Data.Month == dataCorrente.Month && c.Data.Year == dataCorrente.Year).ToList();
        }
    }
}

I'm trying with the Partial() found around some sites, but Im not figuring out how to update my List of object <Conta> on my page.

Would like some help to understand this process

I know how to do this with the normal <form> processo on my month selector, but I'd like to learn how to do properly this ajax call (starter in front end, worked as only Back-end dev 3 years)

Using .NET Core 6.0

Make the page update the list with the date passed through ajax

Update: I did the changes to use the partial view but when the page loads it not recognize my model list, it finds the page on my project but still having null pointer, even tried passing manually a new List on the partial tag on HTML, but it does not find it.

I'm curious if Identity can interfere in any way

I checked some forums about, but I couldn't make it work

Prints:

Values on list

HTML TAG

Page location

Exception

CodePudding user response:

You can try to use a partial view in Pages/Shared,replace the html in ajax success:

Pages/Shared/Partial:

@model List<Conta>
<table >
    <tr>
        <th>Id</th>
        <th>Nome</th>
        <th>Valor</th>
        <th>Data</th>
        <th>Prestação</th>
        <th>Cartão</th>
        <th>Pago?</th>
        <th>Despesa?</th>
        <th></th>
        <th></th>
    </tr>
    @foreach (var conta in Model)
    {
        <tr>
            <th>@conta._id</th>
            <th>@conta.Nome</th>
            <th>@conta.Valor</th>
            <th>@conta.Data.ToShortDateString()</th>
            <th>@(conta.TotalPrestacoes == 1 ? "" : $"{conta.PrestacaoAtual}/{conta.TotalPrestacoes}")</th>
            <th>@conta.CartaoId</th>
            <th>@(conta.Pago ? "Sim" : "Não")</th>
            <th>@(conta.Despesa ? "Sim" : "Não")</th>
            <th><button type="button"  data-bs-toggle="modal" data-bs-target="#CreateModal">Editar</button></th>
            <th><button type="button" >Deletar</button></th>
        </tr>
    }
</table>

ajax:

 function changeDateSelector(date){
        var dataAtualizada = date.value;
        $.ajax({
            type: "POST",
            url: '/Contas/ContaView?handler=MonthSelector',
            contentType: "application/json; charset=utf-8",
            data: JSON.stringify(dataAtualizada),
            headers:
            {
                "RequestVerificationToken": $('input:hidden[name="__RequestVerificationToken"]').val()
            },
            success:function(data){
                $("#test").html(data);
            }
        });
    }

ContaView.cshtml:

<div id="test">
    <partial name="Partial" [email protected] />
</div>

ContaView.cshtml.cs:

public PartialViewResult OnPostMonthSelector([FromBody] string dataAtualizada)
        {
            dataCorrente = DateTime.ParseExact(dataAtualizada, "yyyy-MM", null);
            contas = BuscarContasUsuarioMes(User.Identity.Name, dataCorrente);
            return Partial("Partial", contas);
        }
  • Related