Knockout-Validation Show Template before input - knockout-validation

I have a simple JSFiddle example http://jsfiddle.net/b625zeL5/6/
<script>
ko.validation.init({
registerExtenders: true,
messagesOnModified: true,
insertMessages: false,
parseInputAttributes: true,
messageTemplate: 'errorTemplate',
decorateInputElement: true,
errorElementClass: 'error'
}, true);
var ViewModel = function(){
this.email = ko.observable("")
.extend({ required: true })
.extend({ email: true });
this.password = ko.observable("")
.extend({ required: true });
};
var viewModel = new ViewModel();
viewModel.errors = ko.validation.group(viewModel);
ko.applyBindings(viewModel);
</script>
<form>
<span data-bind="validationMessage: email"></span>
<input type="text" id="email" data-bind="value: email, validationElement: email, valueUpdate:'keyup'" /> <br/>
<span data-bind="validationMessage: password"></span>
<input type="text" id="password" data-bind="value: password, validationElement: password, valueUpdate:'keyup'"/>
</form>
<script type="text/html" id="errorTemplate">
Error: <span data-bind="validationMessage: field">X</span>
</script>
As you can see - I disabled insertMessages because I need error messages to show before input field. Thus I added span with "data-bind="validationMessage: email"" before each text input.
I defined in validation config
messageTemplate: 'errorTemplate'
but error messages still plain text. How can I get messageTemplate to work?

Because you turned off insertMessages, knockout validation won't use your error message template and it will use what you inserted above each field.
You have two options:
For each observable that has a validation, add a custom error message.
Example 1:
this.password = ko.observable("")
.extend({ required: {
params: true,
message: "Error: This is required"
}
});
Change your error template to something like this:
Example 2:
<script type="text/html" id="errorTemplate">
Error: <span data-bind="validationMessage: error_field"></span>
</script>
.. and inside the form, you can call the template like:
<form>
<!-- ko template: { name: 'errorTemplate', data: { error_field: email } }-->
<!-- /ko -->
<input type="text" id="email" data-bind="value: email, validationElement: email, valueUpdate:'keyup'" /> <br/>
...
...
see jsfiddle here with example 2 in action : http://jsfiddle.net/mhgv48e8/
Hope it helps :)

Related

Recaptcha image challenge always occurs in Microsoft Edge after form submission (Invisible recaptcha)

I've just implemented invisible recaptcha into a web form. Everything works fine with Chrome. But with Microsoft Edge, the image challenge always occurs with every form submission. Which is embarrassing for the users of the website. An idea?
Thanks a lot for your insights and advice :o)
Laurent
Javascript code:
window.onScriptLoad = function () {
var htmlEl = document.querySelector('.g-recaptcha');
var captchaOptions = {
'sitekey': 'xxxxxxxxxxxxxxxxxxxxxxxxxxx',
'size': 'invisible',
'badge': 'inline',
callback: window.onUserVerified
};
var inheritFromDataAttr = true;
recaptchaId = window.grecaptcha.render(htmlEl, captchaOptions, inheritFromDataAttr);
};
window.onUserVerified = function (token) {
$.ajax({
url: 'process.php',
type: 'post',
dataType: 'json',
data : {
'lastname' : $("#lastnameField").val(),
'firstname' : $("#firstnameField").val(),
'city' : $("#cityField").val(),
'postalCode' : $("#postalcodeField").val(),
'g-recaptcha-response' : token
},
success:function(data) {
// informs user that form has been submitted
// and processed
},
error: function(xhr, textStatus, error){
// informs user that there was a problem
// processing form on server side
}
});
};
function onSubmitBtnClick () {
window.grecaptcha.execute;
}
HTML code:
<html>
<head>
<script src="https://www.google.com/recaptcha/api.js?render=explicit&onload=onScriptLoad" async defer></script>
<script type="text/javascript" src="js/petition.js"></script>
...
</head>
<body>
<form id="petitionForm" onsubmit="return false;">
<input id="lastnameField" type="text" name="lastname" placeholder="Lastname" required value="Doe">
<input id="firstnameField" type="text" name="firstname" placeholder="Firstname" required value="John">
<input id="postalcodeField" type="text" name="postalCode" placeholder="Postal Code" required value="ABCDEF">
<input id="cityField" type="text" name="city" placeholder="City" value="Oslo">
....
<input type="submit" name="login" class="g-2" data-sitekey="xxxxxxxxxxxxxxxxxxxxxxx" id="signButton" data-callback='' value="Signer" onclick="onSubmitBtnClick();">
<div class="g-recaptcha" id="recaptchaElement" style="align-content: center"></div>
</form>
...
</body>
</html>

Validate on Blur

I've created a JSFiddle to help demonstrate my question: http://jsfiddle.net/jeffreyrswenson/CrYWn/5/
Here's what I'd like to see:
Messages should not appear when page loads.
Messages should appear when submit button is pushed.
Messages should appear after input value is changed and user leaves element. (Tabs or clicks to next field)
Messages should appear after user leave an input without changing.(For example a field is required and the user tabs through the field, but doesn't enter a value. I'd like the validation message to appear when this happens.)
The first four work as I'd expect. Is the last item possible and if so, what do I need to change to enable that behavior?
HTML:
<label>First name:
<input data-bind='value: firstName' />
</label>
<br/>
<label>Last name:
<input data-bind='value: lastName' />
</label>
<br/>
<button type="button" data-bind='click: submit'>Submit</button>
<br/>
<span data-bind='text: errors().length'></span> errors
ViewModel:
var viewModel = function () {
ko.validation.configure({
decorateElement: true,
registerExtenders: true,
messagesOnModified: true,
insertMessages: true,
parseInputAttributes: true,
messageTemplate: null
});
this.firstName = ko.observable().extend({
required: true
});
this.lastName = ko.observable().extend({
required: true,
pattern: {
message: 'Hey this doesnt match my pattern',
params: '^[A-Z0-9]+$'
}
});
this.submit = function () {
if (this.errors().length == 0) {
alert('Thank you.');
} else {
this.errors.showAllMessages();
}
};
this.errors = ko.validation.group(this);
};
You just need to use the standard valueUpdate option of the value binding where you can specify additional events to trigger your property change and with that the validation.
So you just need to add the valueUpdate: "blur" setting on your bindings:
<label>First name:
<input data-bind='value: firstName, valueUpdate: "blur"' />
</label>
<br/>
<label>Last name:
<input data-bind='value: lastName, valueUpdate: "blur"' />
</label>
Demo JSFiddle.
In my case, I needed the value to update after key down because I was making some fields visible if the input had a value. I wanted the underlying value to update but didn't want the validation to show until the user tabbed to the next input.
A bit of CSS and a couple of bindings is what worked for me:
CSS:
div.validationWrapper.standard-focus.has-focus .validationMessage
{
display: none;
}
HTML:
<div class="validationWrapper standard-focus" data-bind="css: { 'has-focus': MyObservableHasFocus() }">
<input class="standard-focus" type="text" data-bind="hasFocus: MyObservableHasFocus, value: MyObservable, valueUpdate: 'afterkeydown'" />
</div>
Knockout:
self.MyObservable = ko.observable('').extend({/* Your validation here */});
self.MyObservableHasFocus = ko.observable(false);
The result is an observable that updates it's value after key up and shows the validation message after it loses focus.

How to put a Kendo control into a Kendo template?

I'm trying to put a NumericTextBox into a Kendo template.
Here is the code:
<script type="text/x-kendo-template" id="clone-wizard-template">
<p>Bitte wählen Sie, wie viele Male Sie möchten <br />die Aktionsgruppe fortschreiben:
</p>
#(Html.Kendo().NumericTextBox()
.Name("custom")
.Value(10)
.ToClientTemplate())
<br />
/*some other lines*/
</script>
Which is strangely rendered into this:
<script type="text/x-kendo-template" id="clone-wizard-template">
<p>Bitte wählen Sie, wie viele Male Sie möchten <br />die Aktionsgruppe fortschreiben:
</p>
<input class="k-input" id="custom" name="custom" type="number" value="10" /><script>
jQuery(function(){jQuery("\#custom").kendoNumericTextBox({});});
<\/script>
<br />
/*some other lines*/
</script>
I cannot understand from where comes </script> tag...
I'm loading a template into a modal window by using this code:
editAktionsgruppen.kendoWindow = $("<div />").kendoWindow({
title: "Bestätigen",
resizable: false,
visable: false,
modal: true
}).html($("#clone-wizard-template").html()).data("kendoWindow");
Isn't this a correct way to input a control in the template?
I would probably write it like this:
var popUpWindow = $("<div />").kendoWindow({
title: "Bestätigen",
resizable: false,
content: {
template: kendo.toString($('#clone-wizard-template').html())
},
visable: false,
modal: true
});
//add kendo validation to popup window
$('#my-form').kendoValidator();
//initialise the numeric textbox (you could specify a class on the input and find
//by that instead instead of using an id)
$('#NumInput').kendoNumericTextBox();
//wire-up an ok/submit button
$(popUpWindow).find('.t-button').on('click', function() {
var validator = $('#my-form').data('kendoValidator');
if(valiator.validate())
{
// do stuff
}
});
//show the window
$(popUpWindow).data('kendoWindow').center().open();
then the client template:
<script type="text/x-kendo-template" id="clone-wizard-template">
<form id="my-form">
<p>Bitte wählen Sie, wie viele Male Sie möchten <br />die Aktionsgruppe fortschreiben:
</p>
<input id="NumInput" name="NumInput" type="number" required data-required-msg="number required" />
<br />
/*some other lines*/
<button type="button" class="t-button">my button</button>
</form>
</script>

Validating with knockout-validation

Working with knockout.js (and knockout-validation) I have this:
self.nickname = ko.observable("").extend({
required: true,
minLength: 3
});
and
<input type="text" data-bind="value: nickname" class="short" maxlength="30" />
<div class="formRow rowErrorMsg" data-bind="visible: nickname.isValid() == false"><span class="staticImages staticImagesError"></span> <?php text("Enter a valid username") ?></div>
but the problem is that when "nickname" its not valid then apper a text next to the input control. The DIV with the error message start visible and then work fine.
I need to do this:
when "nickname" is not valid then just display the DIV with my custom message and format.
when page is loaded then the DIV have to stay hidden.
You need to configure knockout-validation to not show the error-messages. There are two ways.
The first is via binding:
<div data-bind='validationOptions: { insertMessages: false }'>
<input type="text" data-bind="value: nickname" class="short" maxlength="30" />
<div class="formRow rowErrorMsg" data-bind="visible: nickname.isValid() == false">
</div>
The second one is via code:
Use the ko.validation.init({ insertMessages: false }); function
Use the ko.applyBindingsWithValidation(viewModel, rootNode, { insertMessages: false }); function **contextual
A description of all configuration options can be found at: https://github.com/ericmbarnard/Knockout-Validation/wiki/Configuration
If you have many fields you have to validate you could use an messageTemplate template instead of manually creating all the errorMessage divs.

How do I postback from a JQuery dialog to another ASP .NET page?

I am using ASP .NET to display a JQuery dialog that has a few input fields. I now need these fields to submitted to an action method like how a normal HTML submit button would work on an ASP .NET MVC application. How do I accomplish this?
This is my form data:
All form fields are required.
<%Html.BeginForm("AddUser", "User"); %>
<fieldset>
<label for="name">Name</label>
<input type="text" name="name" id="name" />
<label for="email">Email</label>
<input type="text" name="email" id="email" value="" />
<label for="password">Password</label>
<input type="password" name="password" id="password" value="" />
</fieldset>
<%Html.EndForm(); %>
"
And this is my script:
$(function() {
$("#dialog").dialog({
bgiframe: true,
height: 400,
width: 600,
modal: true,
buttons: {
'Create user account': function() {
$(this).dialog('close');
},
Cancel: function() {
$(this).dialog('close');
}
}
});
});
Add a line to your code that submits the form:
$(function() {
$("#dialog").dialog({
bgiframe: true,
height: 400,
width: 600,
modal: true,
buttons:
{
'Create user account': function() {
$('#yourDialogFormID').submit(); // add this line
$(this).dialog('close');
},
Cancel: function() {
$(this).dialog('close');
}
}
});
});
You can set the ID by giving the Html.BeginForm() method an argument for htmlAttributes (type object if I remember the structure correctly - look for it in the overload methods in IntelliSense).
You can harvest the data from your form and post it using jQuery.post
$.post("someform.aspx", { name: $("#name").val(), email: $("#email").val() } );

Resources