KaribbeanDev
KaribbeanDev

Reputation: 11

Knockout and ASP.NET MVC edit form display duplicate rows after mapping

Good morning everyone I searched for the problem but I can't find it. I'm trying to edit a quote in an asp.net mvc application with knockout, with a nested collection and computed variables

The creation is going well. But the edit form display duplicate lines. As if the server displays its data and KNOCKOUT also displays its own.

When I look in the console my knockout pattern is called the correct number of times I am working with an editortemplates.

My knockout :

var QuotationDetail = function (data) {

        var self = this;

                var productsData = @Html.Raw(Json.Encode(ViewBag.Products));
        self.productCategories = ko.observableArray(productsData);


        if (data != null) {
            self.QuotationId = ko.observable();
            self.Id = ko.observable();


            self.Quantity = ko.observable(data.Quantity);
            self.Discount = ko.observable(data.Discount);
            self.UniteQuotation = ko.observable(data.UniteQuotation);
            self.Description = ko.observable(data.Description);
            self.ProductCategory = ko.observable();
            self.Product = ko.observable();
            self.PriceUnit = ko.observable(data.PriceUnit);

            self.ProductName = ko.observable(data.ProductName);
            self.PriceHT = ko.pureComputed(function () {
                return self.PriceUnit() ? self.PriceUnit() * parseInt("0" + self.Quantity(), 10) - ((self.PriceUnit() * parseInt("0" + self.Quantity(), 10) * parseFloat("0" + self.Discount()) / 100)) : 0;
            });
     

        } else {
            self.QuotationId = ko.observable();
            self.Id = ko.observable();

            console.log('pas de données');
            self.Quantity = ko.observable(1);
            self.Discount = ko.observable(0);
            self.UniteQuotation = ko.observable();
            self.Description = ko.observable();
            self.ProductCategory = ko.observable();
            self.Product = ko.observable();
            self.PriceUnit = ko.observable();

            self.ProductName = ko.observable();
            self.PriceHT = ko.pureComputed(function () {
                return self.PriceUnit() ? self.PriceUnit() * parseInt("0" + self.Quantity(), 10) - ((self.PriceUnit() * parseInt("0" + self.Quantity(), 10) * parseFloat("0" + self.discount()) / 100)) : 0;
            });
            self.Product.subscribe(function () {
                if (self.Product()) {
                    self.PriceUnit(self.Product().ProductPrice);
                    self.ProductName(self.Product().Title);
                    self.Description(self.Product().Description);
                }
                else {
                    self.priceunit(0);
                }

            });
        }
       
            // fin

    };

    var mapping = {

        create: function (options) {
            return new QuotationDetail(options.data);
        }
    }
    var Quotation = function () {

        var self = this;
      
         var data = @Html.Raw(Json.Encode(Model.QuotationDetails));
        console.log('Lancement du mapping des détails : ' + JSON.stringify(data));

        self.lines = ko.mapping.fromJS(data, mapping);

        //self.lines = ko.observableArray(ko.utils.arrayMap(appdatas, function (line) {
        //    return new QuotationDetail(line);
        //}));
           //self.lines = ko.utils.arrayMap(appdatas, function (data) { return new QuotationDetail(data); });
      


        self.discountgeneral = ko.observable(0);

        var dataTvas = @Html.Raw(Json.Encode(ViewBag.TVAs));
        console.log(JSON.stringify(dataTvas));
        self.tvas = ko.observableArray(dataTvas);

        self.tva = ko.observable();
        self.grandTotalService = ko.pureComputed(function () {
            var totalService = 0;
            $.each(self.lines(), function () { totalService += this.PriceHT() })
            return totalService;
        });
        // Put one line in by default
        self.grandTotalHT = ko.pureComputed(function () {
            var totalHT = 0;
            $.each(self.lines(), function () { totalHT += this.PriceHT() - (this.PriceHT() * parseFloat("0" + self.discountgeneral()) / 100) })
            return totalHT;
        });

        self.grandTotalDisc = ko.pureComputed(function () {
            var totalDisc = 0;
            $.each(self.lines(), function () { totalDisc += (this.PriceHT() * parseFloat("0" + self.discountgeneral()) / 100) })
            return totalDisc;
        });
        self.grandTotalTVA = ko.pureComputed(function () {
            var totalTVA = 0;
            $.each(self.lines(), function () { totalTVA += this.PriceHT() * parseFloat("0" + self.tva().Pourcentage) / 100 })
            return totalTVA;
        });
        self.grandTotal = ko.pureComputed(function () {
            var total = 0;
            $.each(self.lines(), function () { total += this.PriceHT() - (this.PriceHT() * parseFloat("0" + self.discountgeneral()) / 100) + (this.PriceHT() * parseFloat("0" + self.tva().Pourcentage) / 100) })
            return total;
        });


        // Operations
        self.addDetail = function () {
            self.lines.push(new QuotationDetail())
        };
        self.removeDetail = function (line) { self.lines.remove(line) };

    };



    $(document).ready(function () {
        ko.applyBindings(new Quotation());
    });

My editortemplates view

<div class="detail">
    <div class="row" data-bind="ifnot: ProductName">
        <div class="form-group col-md-6">
            <label>Catégorie</label>
            <select class="form-control" data-bind="options: productCategories, optionsText: 'Title',optionsCaption: 'Catégorie...', value: ProductCategory"> </select>
        </div>
        <div class="form-group col-md-6" data-bind="with:ProductCategory">
            <label>Produit</label>
            <select class="form-control" data-bind="options : Products,optionsText: 'Title',optionsCaption: 'Produit...',value:$parent.Product"> </select>

        </div>
        <div data-bind="with:Product">
           
            <input type="hidden" data-bind="value: Id, attr: {name: 'QuotationDetails[' + $index() + '].ProductId'}" />

        </div>
    </div>
    <div class="form-row">
        <div class="form-group col-md-2">
            <label>Type</label>
            @Html.EnumDropDownListFor(model => model.UniteQuotation, new { data_bind = "value : UniteQuotation", @class = "form-control", placeholder = "Type" })
        </div>

        <div class="form-group col-md-4">
            <label>Produit</label>
            @Html.TextBoxFor(model => model.ProductName, new { data_bind = "text:ProductName", @class = "form-control", @readonly = "readonly"  })
    
        </div>
        <div class="form-group col-md-1">

            <h5> Quantité <span class="text-danger">*</span></h5>
            <div class="controls">
                @Html.TextBoxFor(model => model.Quantity, new
                {
                    data_bind = "textInput :Quantity,valueUpdate:'afterkeydown'",
                    @class = "form-control",
                    required = "required",
                    data_validation_required_message = "Veuillez renseigner une quantité"
                })

            </div>
        </div>

        <div class="form-group col-md-2">

            <h5> Prix unitaire <span class="text-danger">*</span></h5>
            <div class="controls">

                @Html.TextBoxFor(model => model.PriceUnit, new { data_bind = "textInput:PriceUnit,valueUpdate: 'afterkeydown'", @class = "form-control", required = "required", data_validation_required_message = "Veuillez renseigner un prix unitaire" })

            </div>
        </div>


        <div class="form-group col-md-1">
            <label>Remise (%)</label>
            @Html.TextBoxFor(model => model.Discount,
                                                        new { data_bind = "textInput: Discount", @class = "form-control" })
        </div>
        <div class="form-group col-md-1">
            <label>Total HT</label>
            € @Html.TextBoxFor(model => model.PriceHT, new { data_bind = "value:formatCurrencyDouble(PriceHT())", @class = "form-control", @readonly = "readonly" })

        </div>

        <div class="form-group col-md-1">
            <label></label>
            <a href='#' data-bind='click: $parent.removeDetail'><i class="far fa-times-circle" style="font-size:40px"></i></a>

        </div>
    </div>
    <div class="form-group col-md-12">
        @Html.TextAreaFor(model => model.Description, new { data_bind = "value:Description , summernote: { height: 250 },valueUpdate: 'afterkeydown'", rows = "10", @class = "form-control summernote", placeholder = "Description" })
        @Html.ValidationMessageFor(model => model.Description, "", new { @class = "text-danger" })

    </div>


</div>

I have been going crazy for 2 weeks. Can you help me please?

Upvotes: 1

Views: 49

Answers (0)

Related Questions