0

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.

tereško
  • 58,060
  • 25
  • 98
  • 150
Stelios
  • 45
  • 8

1 Answers1

1

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.

Pavel Kutakov
  • 971
  • 1
  • 7
  • 11
  • Thank you for your help. I did it following your suggestion. But now I' facing the problem of inserting decimals. The unobtrusive validation deny both . And , – Stelios Dec 19 '13 at 21:50
  • As for me - i've created custom binding class for decimals to accept both . and , Here is the good link for that approach: http://stackoverflow.com/questions/793459/how-to-set-decimal-separators-in-asp-net-mvc-controllers/5117441#5117441 – Pavel Kutakov Dec 20 '13 at 05:55
  • @PavelKutakov, I have a question. If form is not strongly typed, does ajax.beginform still persist the values? Means if I use plain html like then will values be retained? – Jass Apr 23 '21 at 14:48
  • If yes, how to implement that? – Jass Apr 23 '21 at 14:49
  • If your form is not strongly typed you have to put default values in your inputs from viewmodel data or ViewBag variables. – Pavel Kutakov Apr 25 '21 at 11:06