I have page when I have input and a button.
<div>
<div class="input-group">
<span class="input-group-addon">Enter test</span>
<input type="Text" class="form-control" data-bind="value:Test, event: { keypress: searchKeyboardCmd}" required />
</div>
</div>
<button data-bind=' event:{click:foo}' class="btn btn-default">Submit</button>
and my code:
var ViewModel = function () {
var self = this;
self.Test = ko.observable();
self.data = ko.observableArray([]);
self.DeviceId = ko.observable();
self.number = ko.observable(1);
self.MeUser = ko.observable(true);
self.searchKeyboardCmd = function (data, event) {
if (event.keyCode == 13)
alert("Znalazlem enter " + ko.toJSON(self));
return true;
};
self.foo = function () {
alert("foo");
}
};
ko.applyBindings(new ViewModel());
});
And I have problems with my code. I catch enter with this code:
self.searchKeyboardCmd = function (data, event) {
if (event.keyCode == 13)
alert("Znalazlem enter " + ko.toJSON(self));
return true;
};
It's catches perfectly but binded object is updated after calling alert. So in the first enter I null in value Test. After second enter I have first value and so on. Can anyone suggest me how to modify this code?
The problem is that the event is executed before the blur event (which is when the value is updated. You can make sure the update gets updated after every keystroke by adding valueupdate: 'afterkeydown' to the input:
<div>
<div class="input-group">
<span class="input-group-addon">Enter test</span>
<input type="Text" class="form-control"
data-bind="valueUpdate: 'afterkeydown', value:Test, event: { keypress: searchKeyboardCmd}" required />
</div>
</div>
<button data-bind=' event:{click:foo}' class="btn btn-default">Submit</button>
Related
I am trying to create a javscript method that will allow moving to the next field by hitting the enter key. This mostly works fine, except that when you hit enter to click a button, it creates a new row identical to the previous one (which is normal), but then it doesn't move to the next field straight away. You need to hit tab to go to the next one.
I would really appreciate some help on this, as I cannot get it to move to the next box and go straight to it.
quickAddViewModel.prototype.addItemLine = function() {
var self = this;
var itemLine = {
ItemNumber: ko.observable(''),
ItemQuantity: ko.observable(0),
Error: ko.observable(false)
};
self.itemsToAdd.push(itemLine);
}
ko.bindingHandlers.nextFieldOnEnter = {
init: function(element, valueAccessor, allBindingsAccessor) {
$(element).on('keydown', 'input, select', function(e) {
var self = $(this),
form = $(element),
focusable, next;
if (e.keyCode == 13) {
focusable = form.find('input,a,select,button,textarea').filter(':visible');
var nextIndex = focusable.index(this) == focusable.length - 1 ? 0 : focusable.index(this) + 1;
next = focusable.eq(nextIndex);
next.focus();
this.addItemLine();
return true;
}
});
}
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div class="row form-group" data-bind="css: { 'has-error': Error() }, nextFieldOnEnter:true">
<div class="col-xs-7">
<input type="text" class="form-control" placeholder="Eg K000_ASAHI" data-bind="itemCodes: ItemNumber, value: ItemNumber, valueUpdate: 'input'">
</div>
<div class="col-xs-3">
<input type="number" class="form-control" placeholder="0" data-bind="numericInput: ItemQuantity, value: ItemQuantity">
</div>
<div class="col-xs-2">
<button type="button" class="icon-circle-minus" data-bind="visible: $index() + 1 < $parent.itemsToAdd().length, click: function() { $parent.removeItemLine($index()) }, clickBubble: false"></button>
<button type="button" class="icon-circle-plus" data-bind="visible: $index() + 1 == $parent.itemsToAdd().length, click: function() { $parent.addItemLine() }"></button>
</div>
</div>
I would like to call the JavaScript function when I either hit enter or press the button. Also, I want the function to retrieve the value.
Here is my form:
<form>
Farm Number:<br>
<input id="fnumber" type="text" value="" onKeyDown="findfarm2(event)">
<input type="button" value="Find Farm" onclick="findfarm();">
</form>
And here is my JavaScript function:
function findfarm2(event) {
if (event.keyCode == 13){
cqlfilter = 'Farm =' + document.getElementById('fnumber').value;
unregistered.getSource().updateParams({'LAYERS': 'NCSPCTest:Unreported_Names','CQL_FILTER': cqlfilter});
alert(cqlfilter)
}
}
function findfarm() {
cqlfilter = 'Farm =' + document.getElementById('fnumber').value;
unregistered.getSource().updateParams({'LAYERS': 'NCSPCTest:Unreported_Names','CQL_FILTER': cqlfilter});
alert(cqlfilter)
}
The button is working but the enter function is not. The 'findfarm2' function can pop out an alert but it isn't passing the value to 'updateParams'.
Your function (findfarm2) do not work, because your form is submitting when you press ENTER button (keyCode = 13).
<form id="form" active="#">
<!-- get value (using parameters) -->
<input id="first" type="text" value="" onkeydown="find(event, this.value)">
<input id="last" type="button" value="Find Farm" onclick="findfarm();">
</form>
<script type="text/javascript">
document.querySelector('#form').addEventListener('submit', function(e) {
e.preventDefault(); // stop form from submitting
console.log('You need stop form from submitting!')
});
function find(e, val) {
if (e.keyCode == 13) {
console.log('enter')
}
var value = document.getElementById('first').value;
console.log('My value (using getElementById)' , value)
console.log('My value (using parameters)' , val)
// resume your code here...
}
function findfarm() {
console.log('Find Farm clicked!');
}
</script>
Contact form variables are not passing into javascript. basically javascript fail on validation. On debug, I am getting "undefined is not a function." I have several seperators on this page. If i put identical code inside a seperate page like "contact.html" variables pass into javascript.
My understanding is that HTML tag id="contact-form" for some reason does not pass into the function.
Java Script
function code_contactvalidation() {
// Add form.special data (required for validation)
$('form.special input, form.special textarea').each(function() {
this.data = {};
this.data.self = $(this);
var val = this.data.self.val();
this.data.label = (val && val.length) ? val : null;
this.data.required = this.data.self.attr('aria-required') == 'true';
});
// Special form focus & blur
$('form.special input, form.special textarea').focus(function() {
with (this.data) {
console.log('focusing');
if ( label && self.val() == label) self.val('');
else return;
}
}).blur(function() {
with (this.data) {
if ( label && self.val().length == 0 ) self.val(label)
else return;
}
});
// initialize captcha
var randomcaptcha = function() {
var random_num1=Math.round((Math.random()*10));
var random_num2=Math.round((Math.random()*10));
document.getElementById('num1').innerHTML=random_num1;
document.getElementById('num2').innerHTML=random_num2;
var n3 = parseInt(random_num1) * parseInt(random_num2);
$('#captcharesult').attr('value', n3);
$('#buttonsubmit').attr('value','Submit');
};
randomcaptcha();
//initialize vars for contact form
var sending = false,
sent_message = false;
$('#contact-form').each(function() {
var _this = this;
this.data = {};
this.data.self = $(this);
this.data.fields = {};
this.data.labels = {};
this.data.notification = this.data.self.find('.notification');
_.each(['name','email','subject'], function(name) {
_this.data.fields[name] = _this.data.self.find(_.sprintf('input[name=%s]', name));
_this.data.labels[name] = _this.data.fields[name].val();
});
}).validate({
errorPlacement: function() {},
highlight: function(element) { $(element).addClass('invalid'); },
unhighlight: function(element) { $(element).removeClass('invalid'); },
submitHandler: function(form) {
if (sending) return false;
if ( sent_message ) { alert('Your message has been sent, Thanks!'); return false; }
var field, valid = true;
with (form.data) {
_.each(fields, function(field, name) {
if ( $.trim(field.val()) == labels[name] ) { valid = false; field.addClass('invalid'); } else { field.removeClass('invalid'); }
});
}
if (valid) {
sending = true;
$('#ajax-loader').show();
form.data.self.ajaxSubmit({
error: function(errorres) {
$('#ajax-loader').hide();
randomcaptcha();
form.data.notification.removeClass('sucess').addClass('error').find('span:first-child').html('Unable to send message (Unknown server error)');
form.data.notification.animate({opacity: 100}).fadeIn(500);
},
success: function(res) {
sending = false;
$('#ajax-loader').hide();
if (res == 'success') {
sent_message = true;
form.data.notification.removeClass('error').addClass('success').find('span:first-child').html('Your message has been sent!');
form.data.notification.animate({opacity: 100}).fadeIn(500);
$('#formName').val("");
$('#formEmail').val("");
$('#formSubject').val("");
$('#formMessage').val("");
$('#formcheck').val("");
} else if (res == 'captchaerror') {
randomcaptcha();
form.data.notification.removeClass('sucess').addClass('error').find('span:first-child').html('Captcha Error');
form.data.notification.animate({opacity: 100}).fadeIn(500);
} else {
randomcaptcha();
form.data.notification.removeClass('sucess').addClass('error').find('span:first-child').html('Unable to send message (Unknown server error)');
form.data.notification.animate({opacity: 100}).fadeIn(500);
}
}
});
}
return false;
}
});
}
HTML
<section id="contact">
<div class="container">
<div class="row text-center">
<div id="principal" data-align="left">
<div class="form_group_contact">
<script type="text/javascript" src="js/jquery.validate.pack.js"></script>
<script type="text/javascript" src="js/jquery.form.js"></script>
<form class="contactForm special validate" id="contact-form" action="sendmsg.php" method="post">
<p><input id="formName" name="name" type="text" value="Name" class="required" /></p>
<p><input id="formEmail" name="email" type="text" value="Email" class="required email" /></p>
<p><input id="formSubject" name="subject" class="last required" type="text" value="Subject" /></p>
<p><textarea id="formMessage" name="message" class="required margin20" rows="4" cols="83"></textarea></p>
<div class="form_captcha margin20">
<p>Captcha Recognition (<span id="num1"></span> * <span id="num2"></span>) =
<input type="hidden" id="captcharesult" name="captcha_result" value=""/>
<input type="text" class="required number" maxlength="3" size="3" id="formcheck" name="captcha" value=""/>
</p>
</div>
<p class="notification" style="display: none;"><span></span> <span class="close" data-action="dismiss"></span></p>
<p><input type="submit" value="" class="margin20" id="buttonsubmit" /><img id="ajax-loader" alt="" src="./images/ajax-loader.gif" /></p>
</form>
</div>
</div>
</div>
</div>
</section>
if ( label && self.val().length == 0 ) self.val(label)
There needs to be a semicolumn (;) to end that line ;)
Also, you call "each" on the contact-form which makes me think you expect more than one contact-form. You will need to set the identifier as "class" rather than "id" in the HTML and use "." in the jQuery selector rather than "#".
Now you got those little things fixed, please try it out in Firefox. Google is very vague with javascript errors, Firefox will give you a better error message. Please share it with us so I can edit this post with a final solution.
I am trying to do everthing I can in KnockoutJS however I am having a hard time getting this to convert to knockoutjs.
I have an input box that upon enter press I need to call addInputName(). This is kind of the old school way I think to do it. Is there a way to do this all in knockout?
<input id="inputName" onkeypress="addInputName(this, event);" />
<input id="addInputName" type="button" data-bind="event: { click: addInputName }" value="Add" />
self.addInputName = function (inputElement, event) {
if (event.keyCode == 13) {
$('#addInputName').click();
}
};
// View
<input id="inputName" data-bind="value: name, enterKey: addInputName" />
<input id="addInputName" type="button" data-bind="click: addInputName" value="Add" />
// ViewModel
function ViewModel() {
var self = this;
self.name = ko.observable();
self.names = ko.observableArray();
self.addInputName = function () {
self.names.push(self.name());
self.name("");
};
}
// Custom Binding
ko.bindingHandlers.enterKey = {
init: function (element, valueAccessor, allBindings, data, context) {
var wrapper = function (data, event) {
if (event.keyCode === 13) {
valueAccessor().call(this, data, event);
}
};
ko.applyBindingsToNode(element, { event: { keyup: wrapper } }, context);
}
};
Custom Bindings #20:05
Look into Custom Bindings. It's an invaluable tool to help get UI logic out of your ViewModel's business logic.
Why not just wrap the inputs inside a form? Then you can change your HTML to
<form data-bind="submit: addInputName">
<input id="inputName" type="text" data-bind="value: name" />
<input id="addInputName" type="submit" value="Submit" />
</form>
Then your KO viewmodel looks something like
var ViewModel = function()
{
var self = this;
self.name = ko.observable();
self.addInputName = function() {
// do stuff
}
}
I would like to show error message on user button click (in case user open page and click on directly just on button).
But Visible state workin just if user edit fields
How to fire methods to change visible state ?
<body>
<input type="text" data-bind="value: can" id="txtcan" />
<span ID="lblCANerror" data-bind="visible:(viewModel.can()=='')" class="error">Mesasage 1</span>
<input type="text" data-bind="value: login" id="txtusername" />
<span ID="lblUsernameError" data-bind="visible:(viewModel.login()=='')" class="error">Mesasage 2</span>
<input type="password" data-bind="value: password" name="txtpassword" />
<span ID="lblPasswordError" data-bind="visible:(viewModel.password()=='')" class="error">Mesasage 3</span>
<button ID="lnkLogin" data-bind="click: ClickBtn"> Click</button>
</body>
<script type='text/javascript'>
var ViewModel = function () {
this.can = ko.observable();
this.login = ko.observable();
this.password = ko.observable();
this.isValidForm = ko.computed(function () {
return ($.trim(this.can) != "") && ($.trim(this.login) != "") && ($.trim(this.password) != "");
}, this);
this.ClickBtn = function(data, e)
{
if (!this.isValidForm())
{
e.stopImmediatePropagation();
};
};
};
var viewModel = new ViewModel();
ko.applyBindings(viewModel);
</script>
<style type='text/css'>
.error
{
color: #FF0000;
}
</style>
I don't want write to write code for change span visible state manually (like if () then span.show) is it possible to use just knockoutjs FW ?
I have tried subscribe to event with JQuery but result is the same.
$().ready(function () {
$("#lnkLogin").click(function (event) {
if (!viewModel.isValidForm()) {
event.preventDefault();
};
})
});
Thanks.
Remove user defined error span it is not needed.
option 1 (recommended)
1.) import ko validation js.
2.)extend validation
this.can = ko.observable().extend({required:true});
3.)set initial show validation error msg == false
4.) set value == true to show error
Check this fiddle how to show validation error msg when button click
Option2
1.)Add another observable
this.showError = ko.observable(false);
2.)modify condition
data-bind="visible:(can()=='' && showError())"
3.)Changes in click
$().ready(function () {
$("#lnkLogin").click(function (event) {
//check contions here
if(!true){
viewModel.showError(true); // to show error msg
}
if (!viewModel.isValidForm()) {
event.preventDefault();
};
})
});