How to call VieModel function on custom binding Knockout Js - javascript

How can I call a ViewModel function inside of a custom binding? I have a custom binding to apply jQuery Validate to a form and I need to call a function in the submitHandler, but nothing I've tried so far works. Can someone point me in the right direction? I've read the documentation, but it's not very clear on the subject.
Here is my custom knockout binding
// activate the jQuery Validate on the form
ko.bindingHandlers.validateEmailForm = {
update: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
$(element).validate({
errorLabelContainer: $("#updateEmailFormAlert"),
wrapper: 'li',
rules: {
email: {
required: {
depends: function(element) {
return $("#emailConfirm").is(":filled");
}
},
email: true
},
emailConfirm: {
required: {
depends: function(element) {
return $("#email").is(":filled");
}
},
email: true,
equalTo: "#email",
}
},
messages: {
email: {
required: "Email is required",
email: "Please enter a valid email address"
},
emailConfirm: {
required: "Confirm Email is required",
email: "Please enter a valid confirm email address",
equalTo: "Confirm Email must match Email"
}
},
submitHandler: function() {
bindingContext.$root.updateUserEmail;
return false;
}
});
}
};

Well, you can access the viewModel pretty easily from the custom binding. The current context's viewModel is passed in the viewModel variable, and if you need to access anything else, the bindingContext has access to all parent binding contexts, up until $root.
So if you want to call a function from the viewModel, just do viewModel.someFunction() .
It appears you are already doing something in the submitHandler (bindingContext.$root.updateUserEmail) Is this not what you were looking for?

Related

jquery choosen select validation messages are not dis-appering untill the form submit

jQuery chosen select validation messages are not disappearing until the form submit. I applied required validation if I submit the form without choosing the value error message is displaying. But after I choose it is not disappearing as normal select boxes, it is staying until the form submit.
$.validator.setDefaults({ ignore: ":hidden:not(.chosen-select)" });
$("#postJob").validate({
rules: {
skills:{
required:true,
},
});
please provide a running code snippets to understand the problem more easily.
jQuery validate messages are disappeared once the validation is fulfilled.
$(document).ready(function () {
$("#form").validate({
rules: {
"name": {
required: true,
minlength: 5
},
"email": {
required: true,
email: true
}
},
messages: {
"name": {
required: "Please, enter a name"
},
"email": {
required: "Please, enter an email",
email: "Email is invalid"
}
},
submitHandler: function (form) { // for demo
alert('valid form submitted'); // for demo
return false; // for demo
}
});
});
Here is the fiddle:
http://jsfiddle.net/amwmedia/sw87W/

How to reference form field created by AngularJS formly

I use Formly for creating my forms in angularJS
This is my field
$scope.postFields = [
{
key: 'title',
type: 'input',
templateOptions: {
label: "Title",
// required: true,
minlength: 2,
},
validation: {
messages: {
required: function(viewValue, modelValue, scope) {
return scope.to.label + ' is required'
}
}
}
}
]
and I'm trying to access my fields as follows
function failure(response) {
console.log("failure", response)
_.each(response.data, function(errors, key) {
_.each(errors, function(e) {
$scope.form[key].$dirty = true;
$scope.form[key].$setValidity(e, false);
});
});
}
my formly form
<formly-form form="postForm" model="model" fields="postFields" class="col-md-4">
<button type="submit" class="btn btn-primary" ng-click="addPost()">Submit</button>
</formly-form>
but of course I'm getting this error:
TypeError: Cannot read property 'title' of undefined
it's on this line
$scope.form[key].$dirty = true;
do anyone of you know how to reference created formly fields the right way?
If you want to be able to reference the fields from the form, you could provide a name attribute to your fields. The name is generated by default. It's one of the nice things that angular-formly provides (you don't have to think about it). But if you want to reference it directly with a specific key (as you are) then you'd be best served by providing one yourself.
So you'd do something like this:
$scope.postFields = [
{
key: 'title',
name: 'title',
type: 'input',
templateOptions: {
label: "Title",
// required: true,
minlength: 2,
},
validation: {
messages: {
required: function(viewValue, modelValue, scope) {
return scope.to.label + ' is required'
}
}
}
}
]
Alternatively, you could create a fieldTransform to do this automatically (just assign the name the same as the key). Or in your error handler, you could look up the NgModelController from the field's formControl property like this:
function handleError(fields, response) {
_.each(fields, function(field) {
if (response.data[field.key]) {
field.formControl.$setDirty()
_.each(response.data[field.key], function(e) {
field.formControl.$setValidity(e, false)
})
}
})
}
That's probably the best solution :-) Good luck!

Multiple instances of jQuery Validation Plugin on a JSP page

SOLVED: $.extend() twice in a row simply overwrites the previous object because objects are passed by reference. My fix was to do this:
var updateUserObj = $.extend({}, validationPluginDefaults);
var newUserObj = $.extend({}, validationPluginDefaults);
Then the validators are executed like this:
var whateverValidator = $.extend(updateUserObj,{new rules})
Update: Further research shows that what I'm trying to do appears to be correct but the problem may be in the object I am extending - "validationPluginDefaults"). Here it is below:
var validationPluginDefaults = {
ignore: [],
errorElement: 'p', //default input error message container <p>
errorClass: 'text-error', // default input error message class
focusInvalid: true, //focus on the first invalid field
messages: {},
invalidHandler: function (event, validator) { //display error alert on form submit
},
highlight: function (el) { // hightlight error inputs
//jQuery(el).closest('.control-group').addClass('error'); // set error class to the control group
},
success: function (err, el) {
jQuery(el).next(".text-error").hide();
jQuery(el).next(".text-error").remove();
},
errorPlacement: function (error, element) {
error.insertAfter(element);
},
onfocusin: function () {},
onfocusout: function () {}
};
From my testing it appears that even though I have two separate forms on a JSP page and each has different validation that I can still only use one jQuery Validate Plugin instance per page; is this correct?
Here's my code:
// Define validation rules for form one
var formOneValidator = $.extend(validationPluginDefaults,{
rules: {
firstName: {
minlength: 2,
onlyAlphaAndHyphen: true,
required: true,
},
lastName: {
minlength: 2,
required: true,
},
email: {
required: true,
email: true
}
}
});
var formTwoValidator = $.extend(validationPluginDefaults,{
rules: {
newFirstName: {
minlength: 2,
onlyAlphaAndHyphen: true,
required: true,
},
newLastName: {
minlength: 2,
required: true,
},
newEmail: {
required: true,
email: true,
}
}
});
$("#formOne").validate(formOneValidator);
$("#formTwo").validate(formTwoValidator);
What happens here is that formOne validator takes on all the rules of formTwoValidator after this code executes.
Is the solution to have only one validator and swap out rules depending on which form I'm in? It just seems strange that I wouldn't be able to define separate validators for each form on the page. Am I fundamentally misunderstanding something here?
you could use knockout and give each page a different view model which handles the different validation. That is how i would do it but i'm sure there will be a better answer.

Jquery validation not working second time

The problem is this jquery validation is not working in my form second time. Its working first time perfectly but second time its shows error message but form is going to submit. The code is here
(function ($, W, D) {
var JQUERY4U = {};
JQUERY4U.UTIL =
{
setupFormValidation: function () {
//form validation rules
$("#aspnetForm").validate({
rules: {
firstname: "required",
lastname: "required",
company: "required",
jobtitle: {
required: true,
},
phone: {
required: true,
number: true
},
email: {
required: true,
email: true
},
},
messages: {
firstname: "Please enter your first name",
lastname: "Please enter your last name",
company: "Please enter your company name",
jobtitle: "Please enter your job title",
phone: "Please enter a valid phone number",
email: "Please enter a valid email address",
},
submitHandler: function (form) {
$('#aspnetForm').on('submit', function (e) {
e.preventDefault();
if (flag) {
createListItem();
}
});
//form.submit(function (e) {
// e.preventDefault();
// if (flag) {
// createListItem();
// }
//});
}
});
}
}
//when the dom has loaded setup form validation rules
$(D).ready(function ($) {
JQUERY4U.UTIL.setupFormValidation();
$('#newsletterModal').on('hidden.bs.modal', '.modal', function () {
clearFields();
});
$('#newsletterModal').on('shown.bs.modal', function (e) {
$('#lblMsg').empty();
});
});
})(jQuery, window, document);
can any one help me
Your submitHandler callback function...
submitHandler: function (form) {
$('#aspnetForm').on('submit', function (e) {
e.preventDefault();
if (flag) {
createListItem();
}
});
}
Do not put a submit event handler inside of the submitHandler callback! It's unclear to me what you're trying to do but the submitHandler callback function of the plugin has already captured & replaced the default submit event of the form.
Also, whenever you declare your own submitHandler function, you are over-riding the default built into the plugin. Since I see nothing inside of your custom submitHandler that submits the form, the form will never be submitted.
You'll either need to remove the submitHandler to allow the form to be submitted (when valid) as per the default functionality OR you'll need to put $(form).submit() inside of it someplace.
submitHandler: function (form) {
if (flag) {
createListItem();
}
$(form).submit();
}
NOTE:
Wrapping up everything like this is superfluous, unnecessary, verbose, and arcane...
(function($,W,D) {
var JQUERY4U = {};
JQUERY4U.UTIL =
{
setupFormValidation: function() {
$("#aspnetForm").validate({ .... });
}
}
$(D).ready(function($) {
JQUERY4U.UTIL.setupFormValidation();
});
})(jQuery, window, document);
It serves no useful purpose other than to cause more confusion to those seeking guidance. It comes from a popular, yet poorly explained, online demo/tutorial by Sam Deering that is linked to/from many places.
The entire mess above can be removed and simply replaced by putting the .validate() method inside of the DOM ready event handler function...
$(document).ready(function() {
$("#aspnetForm").validate({ .... });
});

How to capture the type of validation error?

I am using the jQuery Validate plugin and I have this code to catch a error and apply a class (myerror) to the field that caused the validations to fail.
I would like to extend this to capture which type of error that was captured.
Example1: if you did not fill in the field. Class1 applied (css background-color:lightRed)
Example2: format of data in field wrong. Class2 applied (css background-color:lightBlue)
jQuery(function ($) {
var validator = $('#form').validate({
rules: {
ip: {
required: true,
ipv4: true
}
},
messages: {},
errorPlacement: function (error, element) {},
highlight: function (element, errorClass, validClass) {
$(element).addClass('myerror')
},
unhighlight: function (element, errorClass, validClass) {
$(element).removeClass('myerror')
}
});
});
Well it turns out you can... (sort-off) do it.
I used $(element).val(); in the validation to determine if the field is blank or not.
If the field is blank, well then its missing.
If the field is filed in but triggers the validation, then it must be formatted incorrectly.
So Ive used a bubble class to display the error in a separate div element. Not like the traditional inline error message.
The reason for this 'madness' is because the html form is small and if you allow the error message to appear inline, it pulls the poor html form to bits. I feel there is more control doing it this way.
VALIDATE CODE
var validator = $("#storeEditFrm").validate({
rules: {
"store_name": "required",
"street_name": "required",
"suburb_name": "required",
"city_name": "required",
"country_name": "required",
"phone": "required",
"store_email": {
required: true,
email: true
},
"ip_address": {
required: true,
ipv4: true
}
},
messages: {},
errorPlacement: function(error, element) {},
highlight: function (element, errorClass, validClass) {
$(element).prev().prev().addClass('bubble');
var v = $(element).val();
if(v == ''){$(element).prev().prev().html('Required field')}
if(v != ''){$(element).prev().prev().html('Please check format')}
},
unhighlight: function (element, errorClass, validClass) {
$(element).prev().prev().removeClass('bubble');
}
});
Here is a fiddle, needs a bit of CSS work, but you get the idea.
FIDDLE

Categories

Resources