Open Closed

Questions regarding the Vue JS integration with ABP #7628


User avatar
0
henrry.araujo created

ABP Framework version: v8.2.0 UI Type: MVC Database System: EF Core (PostgreSQL) Tiered (for MVC): no

I am using Vue.js in the ABP Create Modal to post the data from the razor page to the UI elements for create and edit. Instead of submitting the data using the ABP save button, I'm posting the data to the razor page using vue js. Due to this once the razor page returns the data, the index page is not recognizing the success message and it is not refreshing the index page.

I am trying to handle the success message to refresh the page using the createmodal. Onresult() event handler. Is there any other way to handle the success message from the create modal in the index page.

Is there a way to reuse the same create modal for edit also using vuejs. In that case how to populate the data from the razor page code behind to the UI elements for edit.

Or, is there a end to end sample using vue.js connected to with ABP framework model manager that I can use as a guide?

Or are there any other mechanism to build responsive UIs on top of MVC pages aside from Vue that I can explore?

any answers will be greatly appreciated


6 Answer(s)
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    I am using Vue.js in the ABP Create Modal to post the data from the razor page to the UI elements for create and edit.

    Can you share some demo code of this case?

    The vue and the razor.cshtml and razor.cs

    Thanks.

  • User Avatar
    0
    henrry.araujo created

    this is the logic for each file: CreateModal.cshtml

    @page
    @using Microsoft.Extensions.Localization
    @using KnoroomsPayments.Localization
    @using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal
    @inject IStringLocalizer<KnoroomsPaymentsResource> L
    @model KnoroomsPayments.Web.Pages.Products.CreateModalModel
    @{
        Layout = null;
    }
    @section scripts {
    
        <abp-script src="/libs/vue/vue.min.js" />
        <abp-script src="/Pages/Products/createModal.js" />
    }
    
    @section styles {
        <abp-style src="/Pages/Products/CreateModal.css" />
    }
    
    <script>
        var app = new Vue({
            el: '#createProductApp',
            data: {
                currentStep: 1,
                activeTab: 'tab2',
                pricingModelsList:[
                    {
                        "value": "",
                        "text": "--- select ---"
                    },
                    {
                        "value": "",
                        "text": "Flat rate"
                    },
                    {
                        "value": "",
                        "text": "Package pricing"
                    },
                    {
                        "value": "",
                        "text": "Customer chooses price"
                    }
                ],
                currencyCodesList: [
                    {
                        "value": "",
                        "text": "--- select ---"
                    },
                    {
                        "value": "dop",
                        "text": "DOP"
                    },
                    {
                        "value": "cad",
                        "text": "CAD"
                    },
                    {
                        "value": "usd",
                        "text": "USD"
                    }
                ],
                billingPeriodList: [
                    {
                        "value": "",
                        "text": "--- select ---"
                    },
                    {
                        "value": "day",
                        "text": "Daily"
                    },
                    {
                        "value": "week",
                        "text": "Weekly"
                    },
                    {
                        "value": "month",
                        "text": "Monthly"
                    },
                    {
                        "value": "year",
                        "text": "Yearly"
                    }
                ],
                product: {
                    name: '',
                    description: '',
                    unitAmount:'',
                    currency:'',
                    billingScheme: ''
                }
            },
            methods: {
                createProduct() {
                    fetch('/products/CreateModal', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json',
                            'RequestVerificationToken': document.getElementsByName("__RequestVerificationToken")[0].value
                        },
                        body: JSON.stringify(this.product)
                    })
                        .then(response => {
                            if (response.ok) {
                                abp.notify.success('Data saved successfully');                            
                                $('#productModal').modal('hide');   
                            }
                            else {
                                abp.notify.error('Data not saved');
                            }
                        })
                        .catch(error => {
                            abp.notify.error('network error');
                        });
                },
                nextStep() {
                    this.currentStep = 2;
                },
                previousStep() {
                    this.currentStep = 1;
                }
            }
        });
    
    </script>
    
    <form data-ajaxForm="true" asp-page="/Products/CreateModal" autocomplete="off">
        <abp-modal id="productModal">
            <abp-modal-header title="@L["NewProduct"].Value"></abp-modal-header>
    
            <abp-modal-body id="createProductApp">
                <div v-if="currentStep === 1">
                    <div>
                        <label class="form-label">Name(required)</label>
                        <input type="text" v-model="product.name" class="form-control" />
                    </div>
    
                    <div>
                        <label class="form-label">Description</label>
                        <input type="text" v-model="product.description" class="form-control" />
                    </div>
    
                    <div class="buttonDiv">
                        <input type="button" class="btn btn-primary" v-on:click="nextStep" value="Next">
                    </div>
                </div>
    
                <div v-if="currentStep === 2">
                    <div class="tabDiv">
                        <button class="button" type="button" :class="{ active: activeTab === 'tab1'}" v-on:click="activeTab = 'tab1'">
                            <span class="first-line">Recurring</span>
                            <br/>
                            <span class="second-line">Charge on ongoing fee</span>
                        </button>
                        <button class="button" type="button" :class="{ active: activeTab === 'tab2'}" v-on:click="activeTab = 'tab2'">
                            <span class="first-line">One-off</span>
                            <br />
                            <span class="second-line">Charge a one time fee</span>
                        </button>
                    </div>
                    <div>
                        <label class="form-label">Choose your pricing model:</label>
                        <div>
                            <select class="form-select form-control" v-model="product.billingScheme">
                                <option v-for="item in pricingModelsList" :value="item.value">{{item.text}}</option>
                            </select>
                        </div>
                    </div>
    
    
                    <div v-if="activeTab === 'tab1'">
                        <label class="form-label">Billing Scheme</label>
                        <input type="text" v-model="product.billingScheme" class="form-control" />
                    </div>
    
    
                    <div v-if="activeTab === 'tab2'">
                         <div>
                             <h4>Price</h4>
                         </div>
                         <div>
                            <label class="form-label">Amount (required)</label>
                            <div class="currencyDiv">
                                <input type="text" class="form-control currencyInput" v-model="product.unitAmount" />
                                <select class="form-select form-control currencySelect" v-model="product.currency">
                                    <option v-for="item in currencyCodesList" :value="item.value">{{item.text}}</option>
                                </select>
                            </div>
                        </div>
                    </div>
    
                    <div class="modal-footer">
                        <input type="button" class="btn btn-secondary" v-on:click="previousStep" value="Back">
                        <input type="button" class="btn btn-primary" data-busy-text="Saving..." v-on:click="createProduct" value="Create Product">
                    </div>
                </div>
            </abp-modal-body>
        </abp-modal>
    </form>
    

    CreateModal.cshtml.cs

    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.AspNetCore.Mvc.Rendering;
    using KnoroomsPayments.Products;
    using Stripe;
    using System.Data;
    using KnoroomsPayments.Migrations;
    using System;
    using KnoroomsPayments.Price;
    
    namespace KnoroomsPayments.Web.Pages.Products
    {
        public class CreateModalModel : KnoroomsPaymentsPageModel
        {
            [BindProperty]
            public Stripe.Price Price { get; set; } = new Stripe.Price();
    
            [HiddenInput]
            [BindProperty(SupportsGet = true)]
            public List<SelectListItem> ListPriceTypes { get; set; }
    
            [HiddenInput]
            [BindProperty(SupportsGet = true)]
            public List<SelectListItem> ListPricingModels { get; set; }
    
            [HiddenInput]
            [BindProperty(SupportsGet = true)]
            public List<SelectListItem> ListCurrencyCodes { get; set; }
    
            [HiddenInput]
            [BindProperty(SupportsGet = true)]
            public List<SelectListItem> ListRecurringInterval { get; set; }
    
            private readonly ProductsAppService _productsAppService;
            private readonly StripeProductAppService _stripeProductAppService;
            private readonly PriceAppService _stripePriceAppService;
            
            public SelectList ProductGroupSelectList;
    
            public CreateModalModel(
                ProductsAppService productsAppService,
                StripeProductAppService stripeProductAppService,
                PriceAppService stripePriceAppService)
            {
                _productsAppService = productsAppService;
                _stripeProductAppService = stripeProductAppService;
                _stripePriceAppService = stripePriceAppService;
            }
    
            public async Task OnGetAsync()
            {
                ListPriceTypes = new List<SelectListItem> {
                    new SelectListItem {
                        Value = "",
                        Text = "--- select ---"
                    },
                    new SelectListItem {
                        Value = "recurring",
                        Text = "Recurring"
                    },
                    new SelectListItem {
                        Value = "one_time",
                        Text = "One-off"
                    }
                }.ToList();
    
                ListPricingModels = new List<SelectListItem> {
                    new SelectListItem {
                        Value = "",
                        Text = "--- select ---"
                    },
                    new SelectListItem {
                        Value = "per_unit",
                        Text = "Flat Rate"
                    },
                    new SelectListItem {
                        Value = "tiered",
                        Text = "Tiered"
                    }
                }.ToList();
    
                ListCurrencyCodes = new List<SelectListItem> {
                    new SelectListItem {
                        Value = "",
                        Text = "--- select ---"
                    },
                    new SelectListItem {
                        Value = "CAD",
                        Text = "Canadian dollar"
                    },
                    new SelectListItem {
                        Value = "USD",
                        Text = "United States dollar"
                    }
                }.ToList();
    
                ListRecurringInterval = new List<SelectListItem> {
                    new SelectListItem {
                        Value = "",
                        Text = "--- select ---"
                    },
                    new SelectListItem {
                        Value = "day",
                        Text = "Daily"
                    },
                    new SelectListItem {
                        Value = "month",
                        Text = "Monthly"
                    },
                    new SelectListItem {
                        Value = "week",
                        Text = "Weekly"
                    },
                    new SelectListItem {
                        Value = "year",
                        Text = "Yearly"
                    }
                }.ToList();
            }
    
            public async Task<IActionResult> OnPostAsync([FromBody] StripeProduct uXProduct)
            {
                Product productToCreate = new Product();
                Stripe.Price priceToCreate = new Stripe.Price();
    
                productToCreate.Name = uXProduct.Name;
                productToCreate.Description = uXProduct.Description;
    
                productToCreate = await _productsAppService.CreateProductAsync(productToCreate);
    
                if (productToCreate != null)
                {
                    priceToCreate.BillingScheme = "per_unit";
                    priceToCreate.UnitAmount = uXProduct.UnitAmount;
                    priceToCreate.UnitAmountDecimal = uXProduct.UnitAmount;
                    priceToCreate.Currency = uXProduct.Currency;
                    priceToCreate.Product = new Product();
                    priceToCreate.Product.Id = productToCreate.Id;
                    priceToCreate = await _stripePriceAppService.CreatePriceAsync(priceToCreate);
                }
    
                if (priceToCreate != null &&
                    productToCreate != null)
                {
                    CreateUpdateStripeProductDto stripeProduct = new CreateUpdateStripeProductDto();
                    stripeProduct.Name = productToCreate.Name;
                    stripeProduct.Description = productToCreate.Description;
                    stripeProduct.StripeProductId = productToCreate.Id;
                    stripeProduct.DefaultPriceId = priceToCreate.Id.ToString();
                    stripeProduct.Object = "product";
    
                    stripeProduct.StripePriceId = priceToCreate.Id;
                    stripeProduct.BillingScheme = "per_unit";
                    stripeProduct.UnitAmount = priceToCreate.UnitAmount;
                    stripeProduct.UnitAmountDecimal = priceToCreate.UnitAmount;
                    stripeProduct.Currency = priceToCreate.Currency;
                    _stripeProductAppService.CreateAsync(stripeProduct);
                }
    
                return NoContent();
            }
        }
      }
    

    CreateModal.css

    .buttonDiv {
        padding: 5px;
        display: flex;
        flex-shrink: 0;
        flex-wrap: wrap;
        align-items: center;
        justify-content: flex-end;
    }
    .tabDiv {
        display: flex;
    }
    .button {
        margin: 5px;
        flex: 1;
        display: inline-block;
        font-weight: 400;
        text-align: left;
        border: 1px solid transparent;
        padding: .375rem .75rem;
        font-size: 12px;
        line-height: 1.5;
        border-radius: 8px;
        color: black;
        background: #fcfffe;
        border-color: #eeeeee;
    }
    .active {
        border-color: #3DB9F5;
        box-shadow: 0 -1px 5px 0 #3DB9F5, 0 2px 10px 0 #3DB9F5;
        border-width: 2px;
        background: #f5f6fd;
        color: #3DB9F5;
    }
    .first-line {
        font-weight: bold;
    }
    .second-line {
        color:black;
    }
    .currencyDiv {
        display: flex;
    }
    .currencySelect {
        flex: 25%;
    }
    .currencyInput {
        flex: 75%;
    }
    
  • User Avatar
    0
    henrry.araujo created

    this is the logic for each file: CreateModal.cshtml

    @page
    @using Microsoft.Extensions.Localization
    @using KnoroomsPayments.Localization
    @using Volo.Abp.AspNetCore.Mvc.UI.Bootstrap.TagHelpers.Modal
    @inject IStringLocalizer<KnoroomsPaymentsResource> L
    @model KnoroomsPayments.Web.Pages.Products.CreateModalModel
    @{
        Layout = null;
    }
    @section scripts {
    
        <abp-script src="/libs/vue/vue.min.js" />
        <abp-script src="/Pages/Products/createModal.js" />
    }
    
    @section styles {
        <abp-style src="/Pages/Products/CreateModal.css" />
    }
    
    <script>
        var app = new Vue({
            el: '#createProductApp',
            data: {
                currentStep: 1,
                activeTab: 'tab2',
                pricingModelsList:[
                    {
                        "value": "",
                        "text": "--- select ---"
                    },
                    {
                        "value": "",
                        "text": "Flat rate"
                    },
                    {
                        "value": "",
                        "text": "Package pricing"
                    },
                    {
                        "value": "",
                        "text": "Customer chooses price"
                    }
                ],
                currencyCodesList: [
                    {
                        "value": "",
                        "text": "--- select ---"
                    },
                    {
                        "value": "dop",
                        "text": "DOP"
                    },
                    {
                        "value": "cad",
                        "text": "CAD"
                    },
                    {
                        "value": "usd",
                        "text": "USD"
                    }
                ],
                billingPeriodList: [
                    {
                        "value": "",
                        "text": "--- select ---"
                    },
                    {
                        "value": "day",
                        "text": "Daily"
                    },
                    {
                        "value": "week",
                        "text": "Weekly"
                    },
                    {
                        "value": "month",
                        "text": "Monthly"
                    },
                    {
                        "value": "year",
                        "text": "Yearly"
                    }
                ],
                product: {
                    name: '',
                    description: '',
                    unitAmount:'',
                    currency:'',
                    billingScheme: ''
                }
            },
            methods: {
                createProduct() {
                    fetch('/products/CreateModal', {
                        method: 'POST',
                        headers: {
                            'Content-Type': 'application/json',
                            'RequestVerificationToken': document.getElementsByName("__RequestVerificationToken")[0].value
                        },
                        body: JSON.stringify(this.product)
                    })
                        .then(response => {
                            if (response.ok) {
                                abp.notify.success('Data saved successfully');                            
                                $('#productModal').modal('hide');   
                            }
                            else {
                                abp.notify.error('Data not saved');
                            }
                        })
                        .catch(error => {
                            abp.notify.error('network error');
                        });
                },
                nextStep() {
                    this.currentStep = 2;
                },
                previousStep() {
                    this.currentStep = 1;
                }
            }
        });
    
    </script>
    
    <form data-ajaxForm="true" asp-page="/Products/CreateModal" autocomplete="off">
        <abp-modal id="productModal">
            <abp-modal-header title="@L["NewProduct"].Value"></abp-modal-header>
    
            <abp-modal-body id="createProductApp">
                <div v-if="currentStep === 1">
                    <div>
                        <label class="form-label">Name(required)</label>
                        <input type="text" v-model="product.name" class="form-control" />
                    </div>
    
                    <div>
                        <label class="form-label">Description</label>
                        <input type="text" v-model="product.description" class="form-control" />
                    </div>
    
                    <div class="buttonDiv">
                        <input type="button" class="btn btn-primary" v-on:click="nextStep" value="Next">
                    </div>
                </div>
    
                <div v-if="currentStep === 2">
                    <div class="tabDiv">
                        <button class="button" type="button" :class="{ active: activeTab === 'tab1'}" v-on:click="activeTab = 'tab1'">
                            <span class="first-line">Recurring</span>
                            <br/>
                            <span class="second-line">Charge on ongoing fee</span>
                        </button>
                        <button class="button" type="button" :class="{ active: activeTab === 'tab2'}" v-on:click="activeTab = 'tab2'">
                            <span class="first-line">One-off</span>
                            <br />
                            <span class="second-line">Charge a one time fee</span>
                        </button>
                    </div>
                    <div>
                        <label class="form-label">Choose your pricing model:</label>
                        <div>
                            <select class="form-select form-control" v-model="product.billingScheme">
                                <option v-for="item in pricingModelsList" :value="item.value">{{item.text}}</option>
                            </select>
                        </div>
                    </div>
    
    
                    <div v-if="activeTab === 'tab1'">
                        <label class="form-label">Billing Scheme</label>
                        <input type="text" v-model="product.billingScheme" class="form-control" />
                    </div>
    
    
                    <div v-if="activeTab === 'tab2'">
                         <div>
                             <h4>Price</h4>
                         </div>
                         <div>
                            <label class="form-label">Amount (required)</label>
                            <div class="currencyDiv">
                                <input type="text" class="form-control currencyInput" v-model="product.unitAmount" />
                                <select class="form-select form-control currencySelect" v-model="product.currency">
                                    <option v-for="item in currencyCodesList" :value="item.value">{{item.text}}</option>
                                </select>
                            </div>
                        </div>
                    </div>
    
                    <div class="modal-footer">
                        <input type="button" class="btn btn-secondary" v-on:click="previousStep" value="Back">
                        <input type="button" class="btn btn-primary" data-busy-text="Saving..." v-on:click="createProduct" value="Create Product">
                    </div>
                </div>
            </abp-modal-body>
        </abp-modal>
    </form>
    

    CreateModal.cshtml.cs

    using System.Collections.Generic;
    using System.Linq;
    using System.Threading.Tasks;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.AspNetCore.Mvc.Rendering;
    using KnoroomsPayments.Products;
    using Stripe;
    using System.Data;
    using KnoroomsPayments.Migrations;
    using System;
    using KnoroomsPayments.Price;
    
    namespace KnoroomsPayments.Web.Pages.Products
    {
        public class CreateModalModel : KnoroomsPaymentsPageModel
        {
            [BindProperty]
            public Stripe.Price Price { get; set; } = new Stripe.Price();
    
            [HiddenInput]
            [BindProperty(SupportsGet = true)]
            public List<SelectListItem> ListPriceTypes { get; set; }
    
            [HiddenInput]
            [BindProperty(SupportsGet = true)]
            public List<SelectListItem> ListPricingModels { get; set; }
    
            [HiddenInput]
            [BindProperty(SupportsGet = true)]
            public List<SelectListItem> ListCurrencyCodes { get; set; }
    
            [HiddenInput]
            [BindProperty(SupportsGet = true)]
            public List<SelectListItem> ListRecurringInterval { get; set; }
    
            private readonly ProductsAppService _productsAppService;
            private readonly StripeProductAppService _stripeProductAppService;
            private readonly PriceAppService _stripePriceAppService;
            
            public SelectList ProductGroupSelectList;
    
            public CreateModalModel(
                ProductsAppService productsAppService,
                StripeProductAppService stripeProductAppService,
                PriceAppService stripePriceAppService)
            {
                _productsAppService = productsAppService;
                _stripeProductAppService = stripeProductAppService;
                _stripePriceAppService = stripePriceAppService;
            }
    
            public async Task OnGetAsync()
            {
                ListPriceTypes = new List<SelectListItem> {
                    new SelectListItem {
                        Value = "",
                        Text = "--- select ---"
                    },
                    new SelectListItem {
                        Value = "recurring",
                        Text = "Recurring"
                    },
                    new SelectListItem {
                        Value = "one_time",
                        Text = "One-off"
                    }
                }.ToList();
    
                ListPricingModels = new List<SelectListItem> {
                    new SelectListItem {
                        Value = "",
                        Text = "--- select ---"
                    },
                    new SelectListItem {
                        Value = "per_unit",
                        Text = "Flat Rate"
                    },
                    new SelectListItem {
                        Value = "tiered",
                        Text = "Tiered"
                    }
                }.ToList();
    
                ListCurrencyCodes = new List<SelectListItem> {
                    new SelectListItem {
                        Value = "",
                        Text = "--- select ---"
                    },
                    new SelectListItem {
                        Value = "CAD",
                        Text = "Canadian dollar"
                    },
                    new SelectListItem {
                        Value = "USD",
                        Text = "United States dollar"
                    }
                }.ToList();
    
                ListRecurringInterval = new List<SelectListItem> {
                    new SelectListItem {
                        Value = "",
                        Text = "--- select ---"
                    },
                    new SelectListItem {
                        Value = "day",
                        Text = "Daily"
                    },
                    new SelectListItem {
                        Value = "month",
                        Text = "Monthly"
                    },
                    new SelectListItem {
                        Value = "week",
                        Text = "Weekly"
                    },
                    new SelectListItem {
                        Value = "year",
                        Text = "Yearly"
                    }
                }.ToList();
            }
    
            public async Task<IActionResult> OnPostAsync([FromBody] StripeProduct uXProduct)
            {
                Product productToCreate = new Product();
                Stripe.Price priceToCreate = new Stripe.Price();
    
                productToCreate.Name = uXProduct.Name;
                productToCreate.Description = uXProduct.Description;
    
                productToCreate = await _productsAppService.CreateProductAsync(productToCreate);
    
                if (productToCreate != null)
                {
                    priceToCreate.BillingScheme = "per_unit";
                    priceToCreate.UnitAmount = uXProduct.UnitAmount;
                    priceToCreate.UnitAmountDecimal = uXProduct.UnitAmount;
                    priceToCreate.Currency = uXProduct.Currency;
                    priceToCreate.Product = new Product();
                    priceToCreate.Product.Id = productToCreate.Id;
                    priceToCreate = await _stripePriceAppService.CreatePriceAsync(priceToCreate);
                }
    
                if (priceToCreate != null &&
                    productToCreate != null)
                {
                    CreateUpdateStripeProductDto stripeProduct = new CreateUpdateStripeProductDto();
                    stripeProduct.Name = productToCreate.Name;
                    stripeProduct.Description = productToCreate.Description;
                    stripeProduct.StripeProductId = productToCreate.Id;
                    stripeProduct.DefaultPriceId = priceToCreate.Id.ToString();
                    stripeProduct.Object = "product";
    
                    stripeProduct.StripePriceId = priceToCreate.Id;
                    stripeProduct.BillingScheme = "per_unit";
                    stripeProduct.UnitAmount = priceToCreate.UnitAmount;
                    stripeProduct.UnitAmountDecimal = priceToCreate.UnitAmount;
                    stripeProduct.Currency = priceToCreate.Currency;
                    _stripeProductAppService.CreateAsync(stripeProduct);
                }
    
                return NoContent();
            }
        }
      }
    

    CreateModal.css

    .buttonDiv {
        padding: 5px;
        display: flex;
        flex-shrink: 0;
        flex-wrap: wrap;
        align-items: center;
        justify-content: flex-end;
    }
    .tabDiv {
        display: flex;
    }
    .button {
        margin: 5px;
        flex: 1;
        display: inline-block;
        font-weight: 400;
        text-align: left;
        border: 1px solid transparent;
        padding: .375rem .75rem;
        font-size: 12px;
        line-height: 1.5;
        border-radius: 8px;
        color: black;
        background: #fcfffe;
        border-color: #eeeeee;
    }
    .active {
        border-color: #3DB9F5;
        box-shadow: 0 -1px 5px 0 #3DB9F5, 0 2px 10px 0 #3DB9F5;
        border-width: 2px;
        background: #f5f6fd;
        color: #3DB9F5;
    }
    .first-line {
        font-weight: bold;
    }
    .second-line {
        color:black;
    }
    .currencyDiv {
        display: flex;
    }
    .currencySelect {
        flex: 25%;
    }
    .currencyInput {
        flex: 75%;
    }```
    
  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi Please try to set data-ajaxForm to false.

    data-ajaxForm="false"

  • User Avatar
    0
    henrry.araujo created

    Thanks for the recommendation, we will try. If you have any code sample that you can share using vue calling the backend APIs and interacting with the middleware that will be helpful. Having a sample of the functionalities working will help us in the long run (rising less questions as we try to solve our business need).

    Some of the cases we want to know how to cover with vue are:

    • add dynamic behaviour in the modal popup: completing a form as a wizzad passing to the next page when the current page is complete and validated
    • a shopping cart / invoice page where I can add a new row of an item, and recalculate realtime values such as quantity and amount, etc.
    • interaction with App Services either calling the Rest API or calling the method using dependency injection in the on post method of the index form.

    again, if you have any code sample available that may how us how to cover some of these, it will be greatly appreciated

  • User Avatar
    0
    maliming created
    Support Team Fullstack Developer

    hi

    Sorry. Our team is only familiar with MVC and Angular. We don't have experience with VUE.

Made with ❤️ on ABP v9.1.0-preview. Updated on December 10, 2024, 06:38