Stelios
Stelios

Reputation: 45

How can I preserve the form values when I use MVC with Knockout

I'm developing (for the first time) an MVC application using ajax call and knockout MVVM to fill 2 cascading dropdown lists. The question is, How can I preserve the values I selected in the dropdown lists, when I post the web page? The web page I'm developing makes calculations when is posted to the controller and the controller must return the calculated result. When the result is returned, the values of the form must be preserved.

a part of the View

    @using (Html.BeginForm("Calculate", "Entypo", FormMethod.Post, new { role = "form" }))
{
     @Html.AntiForgeryToken()
    @Html.ValidationSummary(false)

    <fieldset>
        <legend>Printers</legend>
        <div class="row">
            <div class="form-group col-md-6">
                <select id="printers" name="printers" class="form-control" data-bind="options: printers, optionsValue: 'ID', optionsText: 'BrandModelName', value: selectedPrinter, optionsCaption: 'Choose Printer...'"></select>
             </div>
            <div class="form-group col-md-6">
                <select id="sheets" name="sheets" class="form-control" data-bind="options: sheets, optionsValue: 'ID', optionsText: 'Description', optionsCaption: 'Choose Sheet...', enable: sheets().length, value: sheet">
                </select>
            </div>
        </div>
    </fieldset>
    <div class="row">
            <div class="col-md-12" style="padding-bottom:10px;">
                <input type="submit" value="Calculate" class="btn btn-primary" />
            </div>
        </div>
    }
    @section Scripts {
    @Scripts.Render("~/bundles/jqueryval")
    <script src="~/Scripts/knockout-3.0.0.js"></script>
    <script>
        $(document).ready(function () {
            // MVVM
            viewModel = {
                printer: ko.observable(),
                printers: ko.observableArray(),
                sheet: ko.observable(),
                sheets:ko.observableArray(),
                paper: ko.observable(),
                papers: ko.observableArray(),
                weight: ko.observable(),
                weights: ko.observableArray(),
                size: ko.observable(),
                sizes: ko.observableArray(),
                lamA: ko.observableArray(),
                lamAvalue: ko.observable(),
                lamB: ko.observableArray(),
                lamBvalue: ko.observable(),
                chkCut: ko.observable(false),
                chkFold: ko.observable(false),
                chkPick: ko.observable(false),
                chkPerfore: ko.observable(false),
                standardSize: ko.observable(),
                x: ko.observable(),
                y: ko.observable(),
                bleed: ko.observable(2.5),
                qty: ko.observable(1)
            };

            viewModel.standardSize.subscribe(function () {
                var st = viewModel.standardSize();

                var res = st.split("x");
                viewModel.x(res[0]);
                viewModel.y(res[1]);
            });

            $.ajax({
                url: '/Entypo/getPrinters',
                type: 'GET',
                dataType: 'json',
                data: {},
                success: function (data) {
                    viewModel.printers(data);
                }
            });

            viewModel.selectedPrinter = ko.dependentObservable({
                read: viewModel.printer,
                write: function (printer) {
                    this.printer(printer);
                    $.ajax({
                        url: '/Entypo/getSheets',
                        type: 'GET',
                        dataType: 'json',
                        data: { id: viewModel.selectedPrinter() },
                        success: function (data) {
                            viewModel.sheets(data);
                        }
                    });
                },
                owner: viewModel
            });

            $.ajax({
                url: '/PaperSize/getPapers',
                type: 'GET',
                dataType: 'json',
                data: {},
                success: function (data) {
                    viewModel.papers(data);
                }
            });

            viewModel.selectedPaper = ko.dependentObservable({
                read: viewModel.paper,
                write: function (paper) {
                    this.paper(paper);
                    $.ajax({
                        url: '/Entypo/getWeights',
                        type: 'GET',
                        dataType: 'json',
                        data: { id: viewModel.selectedPaper() },
                        success: function (data) {
                            viewModel.weights(data);
                        }
                    });
                },
                owner: viewModel
            });

            viewModel.selectedWeight = ko.dependentObservable({
                read: viewModel.weight,
                write: function (weight) {
                    this.weight(weight);
                    $.ajax({
                        url: '/Entypo/getSizes',
                        type: 'GET',
                        dataType: 'json',
                        data: { id: viewModel.selectedWeight() },
                        success: function (data) {
                            viewModel.sizes(data);
                        }
                    });
                },
                owner: viewModel
            });

            $.ajax({
                url: '/Entypo/getLamination',
                type: 'GET',
                dataType: 'json',
                data: {},
                success: function (data) {
                    viewModel.lamA(data);
                    viewModel.lamB(data);
                }
            });

            ko.applyBindings(viewModel);
        });


    </script>

The Controller

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using QVNet_v2.Models;

namespace QVNet_v2.Controllers
{
    public class EntypoController : Controller
    {
        private QVNetEntities db = new QVNetEntities();

        //
        // Calc: /Entypo/
        [HttpGet]
        public ActionResult Calculate()
        {

            return View();
        }

        [HttpPost]
        public ActionResult Calculate()
        {
            return View();
        }


        //GET PRINTERS
        public JsonResult getPrinters()
        {
            var printers = db.Printers.Select(s => new { s.ID, s.BrandModelName }).OrderBy(s=>s.BrandModelName).ToList();
            return Json(printers, JsonRequestBehavior.AllowGet);
        }
        //GET SHEETS USED FROM SELECTED PRINTER
        public JsonResult getSheets(int id)
        {
            var sheets = db.Sheets.Select(s => new { s.ID, s.Description, s.PrinterID }).Where(s=>s.PrinterID ==id).OrderBy(s=>s.Description).ToList();
            return Json(sheets, JsonRequestBehavior.AllowGet);
        }
        // GET PAPERS
        public JsonResult getPapers()
        {
            var papers = db.Papers.Select(s => new { s.ID, s.Description }).OrderBy(s => s.Description).ToList();
            return Json(papers, JsonRequestBehavior.AllowGet);
        }
        // GET WEIGHTS OF SELECTED PAPER
        public JsonResult getWeights(int id)
        {
            var weights = db.PaperWeights.Select(s => new { s.ID, s.Weight, s.PaperID }).Where(s => s.PaperID == id).OrderBy(s => s.Weight).ToList();
            return Json(weights, JsonRequestBehavior.AllowGet);
        }
        //GET SIZES OF SELECTED PAPER AND WEIGHT
        public JsonResult getSizes(int id)
        {
            var sizes = db.PaperSizes.Select(s => new { s.ID, s.Description, s.PaperWeightID }).Where(s => s.PaperWeightID == id).OrderBy(s => s.Description).ToList();
            return Json(sizes, JsonRequestBehavior.AllowGet);
        }
        //GET LAMINATION
        public JsonResult getLamination()
        {
            var lam = db.SheetLaminations.Select(s => new { s.ID, s.Description }).OrderBy(s => s.Description).ToList();
            return Json(lam, JsonRequestBehavior.AllowGet);
        }
        //Dispose db
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                db.Dispose();
            }
            base.Dispose(disposing);
        }
    }
}

When the user click the submit value, the controller must take the data from the form and return the results of a calculation while keeping intact the form fields.

Sorry for my English.

Upvotes: 0

Views: 1727

Answers (1)

Pavel Kutakov
Pavel Kutakov

Reputation: 971

You have two possible ways.

  1. Submit your form using ajax. You will keep your form open thus all values will be unchanged. You can use @using (Ajax.BeginForm) or create knockout method that will call $.ajax to save your data and assing this method to submit button.

  2. Second approach - make your form strongly typed. Create viewmodel class that will hold all values needed to construct the form. In your saving action (Calculate method annotated with [HttpPost]) you shoud recreate viewmodel based on actual form values and send it back to the view.

Upvotes: 1

Related Questions