A great way to do this, and could help in many other parts of your app is to use the knockout.validation library:
https://github.com/Knockout-Contrib/Knockout-Validation
I have created a fiddle that demonstrates how this could be applied to your scenario.
http://jsfiddle.net/jiggle/2xAS7/
HTML:
<fieldset>
<legend>User: <span data-bind='text: errors().length'></span> errors</legend>
<label>Feedback 1: <input data-bind='value: feedback1' required/></label>
<label>Feedback 2: <input data-bind='value: feedback2' required/></label>
<label>
Subscriptions:
<select data-bind='value: feedback3, options: feedback3Options, optionsCaption: "Choose one..."' required></select>
</label>
<label>Feedback 4: <input data-bind='value: feedback4' required/></label>
<label>Feedback 5: <input data-bind='value: feedback5' required/></label>
<label>Feedback 6: <input data-bind='value: feedback6' required/></label>
<label>Feedback 7: <input data-bind='value: feedback7' required/></label>
</fieldset>
<button type="button" data-bind='click: submit'>Submit</button>
<button type="button" data-bind='click: submit, enable:isComplete'>Submit (disabled if not complete)</button>
<button type="button" data-bind='click: submit, enable:errors().length===0'>Submit (disabled if not complete)</button>
<br />
<br />
Display inline error messages? <input type="checkbox" data-bind='click: toggleInlineErrors,checked:showInlineErrors'/>
Code:
ko.validation.rules.pattern.message = 'Invalid.';
ko.validation.configure({
registerExtenders: true,
messagesOnModified: true,
insertMessages: true,
parseInputAttributes: true, //this is 'true' to read the 'required' attribute in your html
messageTemplate: null
});
var viewModel = {
feedback1: ko.observable(), //required attribute is set in the HTML
feedback2: ko.observable(), //required attribute is set in the HTML
feedback3: ko.observable(), //required attribute is set in the HTML
feedback4: ko.observable(), //required attribute is set in the HTML
feedback5: ko.observable(), //required attribute is set in the HTML
feedback6: ko.observable(), //required attribute is set in the HTML
feedback7: ko.observable().extend({ required: true }), //or add the required attribute when you create the observable
feedback3Options: ['Technology', 'Music'],
submit: function () {
if (viewModel.errors().length == 0) {
alert('Thank you.');
} else {
viewModel.errors.showAllMessages(this.showInlineErrors());
alert('Please check your submission.');
}
}
};
viewModel.showInlineErrors = ko.observable(true);
viewModel.errors = ko.validation.group(viewModel);
viewModel.isComplete = ko.computed(function(){
return viewModel.errors().length === 0
});
viewModel.toggleInlineErrors = function () {
viewModel.errors.showAllMessages(false);
return true;
};
addEventListener('load', function () {
ko.applyBindings(viewModel);
});
The key is the ko.validation.group(viewModel), which groups all your observable into one group that is constantly (observable) being evaluated as you make changes to your viewmodel.
That being said, you can then data-bind: 'enable: viewModel.errors.length===0, click:yourClickHandler' or create a computed observable that returns true if there are no errors.
The fiddle demonstrates both options.
It's an excellent library, and very powerful, the fiddle I created also demonstrates how you can toggle the inline errors, and just give an overall message (when you submit), or highlight the missing entries inline so the user can see where the missing selections are (probably very helpful, if you have 44 items the user needs to complete!).
Hope it helps
(just include kendo.validation.js (from the github reference above) to your page/bundle/module and you can start using it)