【问题标题】:Knockout Validation Highlighting DropDown fields on page load敲除验证在页面加载时突出显示下拉字段
【发布时间】:2015-07-17 03:57:51
【问题描述】:

我们正在使用剔除验证和两个下拉字段 - 国家和州在页面加载后立即突出显示。我们只希望它在用户尝试保存页面后验证和突出显示。

<!-- Add/Edit Template -->
<script id="editTemplate" type="text/html">
    <fieldset style="position: relative;" data-bind="with: $root.currentGraduateEducationNonMed">
        <legend>@ViewBag.Title</legend>

        <div style="margin-bottom: 20px;">
            Please enter non-medical graduate education information.
        </div>

        <!-- ko template: "errorsTemplate" -->
        <!-- /ko -->

        <ul class="input_group">
            <li>
                <label class="required_label">School Name</label>
                <input type="text" data-bind="value: schoolName" maxlength="80">
            </li>
            <li>
                <label class="required_label">City</label>
                <input type="text" data-bind="value: city" maxlength="40">
            </li>
            <li>
                <label class="required_label">Country:</label>
                <select data-bind="options: $root.countries, optionsText: 'countryName', optionsValue: 'countryId', optionsCaption: 'Please Select', value: $root.selectedCountryId, event: { change: $root.countryChanged }"></select>
            </li>
            <li>
                <label class="required">State / Province</label>
                <select data-bind="options: $root.states, optionsText: 'stateOrProvinceDescription', optionsValue: 'stateOrProvinceId', optionsCaption: $root.statesCaption, value: stateOrProvinceId"></select>
            </li>
            <li>
                <label class="required_label">Area of Study</label>
                <input type="text" data-bind="value: areaOfStudy" maxlength="50">
            </li>
            <li>
                <label class="required_label">Date Degree Conferred</label>
                <input type="text" data-bind="date: dateDegreeConferred" style="width: 140px;">
            </li>
        </ul>
        <div class="actions">
            <button data-bind="click: $root.save">Save</button>
            <button data-bind="click: $root.closeEditor">Cancel</button>
        </div>

    </fieldset>
</script>

module Models.Addendums {

    export interface IWyomingGraduateEducationNonMed {
        //DEFN - Add property to interface
        graduateEducationId: number;
        schoolName: string;
        city: string;
        stateOrProvinceId: number;
        stateOrProvince: Models.IStateOrProvinceLookup;
        areaOfStudy: string;
        dateDegreeConferred: Date;

    }

    export class WyomingGraduateEducationNonMed extends BaseObject {

        constructor(options?: {
            graduateEducationId: number;
            schoolName: string;
            city: string;
            stateOrProvinceId: number;
            stateOrProvince: Models.StateOrProvinceLookup;
            areaOfStudy: string;
            dateDegreeConferred: Date;
        }) {
            super();

            if (options) {
                this.graduateEducationId(options.graduateEducationId);
                this.schoolName(options.schoolName);
                this.city(options.city);
                this.stateOrProvinceId(options.stateOrProvinceId);
                this.stateOrProvince(options.stateOrProvince);
                this.areaOfStudy(options.areaOfStudy);
                this.dateDegreeConferred(options.dateDegreeConferred);
            }

            // Set the initial state
            this.setState();
        }


        graduateEducationId: KnockoutObservable<number> = ko.observable(null);
        schoolName: KnockoutObservable<string> = ko.observable(null).extend({ required: { message: "Please enter a school name." } });
        city: KnockoutObservable<string> = ko.observable(null).extend({ required: { message: "Please enter a city." } });
        stateOrProvinceId: KnockoutObservable<number> = ko.observable(null).extend({ required: { message: "Please select a state/province." } });
        stateOrProvince: KnockoutObservable<Models.StateOrProvinceLookup> = ko.observable(null);
        areaOfStudy: KnockoutObservable<string> = ko.observable(null).extend({ required: { message: "Please enter an area of study." } });
        dateDegreeConferred: KnockoutObservable<Date> = ko.observable(null).extend({ required: { message: "Please enter a date degree conferred." } });

        fromData = (data: IWyomingGraduateEducationNonMed) => {

            this.graduateEducationId(data.graduateEducationId);
            this.schoolName(data.schoolName);
            this.city(data.city);
            this.stateOrProvinceId(data.stateOrProvinceId);
            if (data.stateOrProvince != null) {
                // Load data for Fsmb_StateOrProvinceLookup
                var stateOrProvince = new Models.StateOrProvinceLookup();
                stateOrProvince.fromData(data.stateOrProvince);
                this.stateOrProvince(stateOrProvince);
            }
            this.areaOfStudy(data.areaOfStudy);
            this.dateDegreeConferred(data.dateDegreeConferred);

            // Set the initial state
            this.setState();
        }

    }




} 

module ViewModels.Addendums {
    export class WyomingGraduateEducationNonMedViewModel {

        //-----------------------------------------------------------------------------------
        // Constructor / Initial Setup

        constructor() {
            ko.validation.init({
                insertMessages: false,
                decorateElement: true,
                errorElementClass: "input-validation-error"
            });

            Q.all([
                this.loadGraduateEducationNonMed(),
                this.loadCountries()
            ]).fail((error: any) => {
                    this.errors([error]);
                }).fin(() => {
                    $("#loading").css("display", "none");
                });
        }


        //-----------------------------------------------------------------------------------
        // Properties

        template = ko.observable<string>("mainTemplate");
        errors = ko.observableArray<string>([]);

        graduateEducationNonMed = ko.observableArray<Models.Addendums.WyomingGraduateEducationNonMed>([]);
        currentGraduateEducationNonMed = ko.observable<Models.Addendums.WyomingGraduateEducationNonMed>(null);

        countries = ko.observableArray<Models.CountryLookup>([]);
        selectedCountryId = ko.observable<number>(null).extend({ required: { message: "Please select a country" } });
        //countriesCaption = ko.observable<string>("Please Select");

        states = ko.observableArray<Models.StateOrProvinceLookup>();
        statesCaption = ko.observable<string>("Please Select");


        //-----------------------------------------------------------------------------------
        // Functions / Event Handlers

        //log = (message: string) => {
        //    if (window && window.console && window.console.log) {
        //        var dt = new Date();
        //        var ts = (dt.toString()).substr(16, 2) + (dt.toISOString()).substr(13, 10);
        //        console.log(ts + ' - ' + message);
        //    }
        //}

        loadGraduateEducationNonMed = (): Q.Promise<void> => {
            var service = new Services.Addendums.WyomingGraduateEducationNonMedService();
            return service.getByFid()
                .then((graduateEducationNonMed: Array<Models.Addendums.WyomingGraduateEducationNonMed>) => {
                    graduateEducationNonMed = graduateEducationNonMed.sort(function (a: Models.Addendums.WyomingGraduateEducationNonMed, b: Models.Addendums.WyomingGraduateEducationNonMed) {
                        var keyA = a.dateDegreeConferred();
                        var keyB = b.dateDegreeConferred();
                        return ((keyA < keyB) ? -1 : ((keyA > keyB) ? 1 : 0));
                    });
                    this.graduateEducationNonMed(graduateEducationNonMed);
                });
        }

        loadCountries = (): Q.Promise<void> => {
            var countryService = new Services.CountryLookupService();
            return countryService.getAll()
                .then((countries: Array<Models.CountryLookup>) => {
                    this.countries(countries);
                });
        }

        formatDate = (date: Date): string => {
            if (date == null) { return "";}
            return moment(date).format("MM/DD/YYYY");
        }

        create = () => {
            this.currentGraduateEducationNonMed(new Models.Addendums.WyomingGraduateEducationNonMed());
            this.template("editTemplate");
        }

        edit = (graduateEducationNonMed: Models.Addendums.WyomingGraduateEducationNonMed) => {

            // Select current country in list
            var country: Models.CountryLookup = this.getCountry(graduateEducationNonMed.stateOrProvince().countryId());
            this.selectedCountryId(country.countryId());


            this.currentGraduateEducationNonMed(graduateEducationNonMed);

            // Retrieve StateOrProvinces; select current stateOrProvince in list
            this.populateStates(country.countryId(), graduateEducationNonMed.stateOrProvinceId());

            this.template("editTemplate");
        }

        getCountry = (countryId: number) => {
            var country: Models.CountryLookup = null;
            $.each(this.countries(), (index: number, c: Models.CountryLookup) => {
                if (c.countryId() === countryId) {
                    country = c;
                }
            });
            return country;
        }

        countryChanged = () => {
            // Load states by country
            var countryId = this.selectedCountryId();
            this.populateStates(countryId);
        }

        populateStates = (countryId: number, stateId?: number) => {
            // Display busy
            $("#loadingCover").css("display", "block");

            this.states(new Array<Models.StateOrProvinceLookup>());

            // Load states
            if (countryId == null) {
                $("#loadingCover").css("display", "none");
            } else {
                this.statesCaption("Loading...");

                var stateService = new Services.StateOrProvinceLookupService();

                stateService.getByCountry(countryId)
                    .then((states: Array<Models.StateOrProvinceLookup>) => {
                        this.states(states);

                        if (stateId != null) {
                            // Re-select stateOrProvince
                            //  (model value is blanked out when model is bound to template when StateOrProvince is missing from dropdown)
                            this.currentGraduateEducationNonMed().stateOrProvinceId(stateId);
                        }
                        this.statesCaption("Please Select");
                    })
                    .fail((error: any) => {
                        // Add this error to errors
                        this.errors([error]);
                    })
                    .fin(() => {
                        // Hide spinner
                        $("#loadingCover").css("display", "none");
                    });
            }
        }

        save = (graduateEducationNonMed: Models.Addendums.WyomingGraduateEducationNonMed) => {

            // Check to see if elements are valid
            var errors = ko.validation.group(this.currentGraduateEducationNonMed());

            if (errors().length > 0) {
                // Errors have been found, stop processing
                this.errors(errors());
                errors.showAllMessages();
                return;
            } else {
                this.errors([]);
            }

            if (graduateEducationNonMed.isDirty()) {

                // Display spinner
                $("#loadingScreen").css("display", "block");

                var service = new Services.Addendums.WyomingGraduateEducationNonMedService();

                service.update(graduateEducationNonMed)
                    .then(() => {
                        this.loadGraduateEducationNonMed();
                        this.closeEditor();
                    })
                    .fail((error: any) => {
                        this.errors([error]);
                    })
                    .fin(() => {
                        $("#loadingScreen").css("display", "none");
                    });

            } else {
                // Nothing has changed; close edit mode
                this.closeEditor();
            }
        }

        // Called when cancelling changes, and also to reset after saving changes
        closeEditor = () => {
            var graduateEducationNonMed = this.currentGraduateEducationNonMed();

            // Unbind, to allow reverting lookup values not included in select options
            this.currentGraduateEducationNonMed(null);

            if (graduateEducationNonMed.isDirty())
                graduateEducationNonMed.revertState();

            this.selectedCountryId(null);
            //this.countriesCaption("Please Select");

            this.states.removeAll();

            this.errors([]);
            this.template("mainTemplate");
        }

        remove = (graduateEducationNonMed: Models.Addendums.WyomingGraduateEducationNonMed) => {
            $("#loadingScreen").css("display", "block");

            var service = new Services.Addendums.WyomingGraduateEducationNonMedService();

            service.remove(graduateEducationNonMed.graduateEducationId())
                .then(() => {
                    this.loadGraduateEducationNonMed();
                    this.template("mainTemplate");
                })
                .fail((error: any) => {
                    this.errors([error]);
                }).fin(() => {
                    $("#loadingScreen").css("display", "none");
                });
        }

        next = () => {
            $("#loadingCover").css("display", "block");
            var redirectUri = Application.Settings.baseUrl + "Addendum/StaffPrivileges";
            window.location.href = redirectUri;
        }
    }
}

$(document).ready(() => {
    var graduateEducationNonMedViewModel = new ViewModels.Addendums.WyomingGraduateEducationNonMedViewModel();
    ko.applyBindings(graduateEducationNonMedViewModel);
}); 

【问题讨论】:

    标签: asp.net-mvc-4 knockout.js knockout-validation


    【解决方案1】:

    在您的代码中不清楚您调用 loadCountries 以填充国家/地区可观察数组的位置,但在您执行此操作后尝试调用:

    this.selectedCountryId.isModified(false);
    

    每次以编程方式将此值设置为 null 并且不想触发验证消息时,您都需要调用它。

    State 下拉菜单的原理相同。

    【讨论】:

      猜你喜欢
      • 2014-12-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-13
      • 1970-01-01
      • 1970-01-01
      • 2018-02-18
      • 1970-01-01
      相关资源
      最近更新 更多