I have a text input element that I want user to enter city or zip code and I want to trigger a javascript function as the user types text. My html is as follows
<input type="text"
placeholder="Zip Code Or City Name"
class="input-block-level"
data-bind="value: searchterm, valueUpdate: 'afterkeydown', event: { keyup: getZipCodes }" />
in my viewmodel I have
var getZipCodes = function () {
if (searchterm().length < 2) {
return;
}
datacontext.getZips(searchterm(), zipcodes);
return true;
};
But it turns out that the getZipCodes is never invoked.
I tried data-binding to "onkeyup" but no go, I am sure there is some subtle error I am making. Can someone help me find what I am doing wrong?
I tried changing getZipCodes to getZipCodes = function(data, event) {...} but that does not work either. The function just does not get invoked.
By the way I am trying to do pretty much same as Knockout event binding for input keypress causes weird behavior
but does not work for me.
After changing the definition of getZipCodes as follows it started working.
function getZipCodes(data, event) {
if (searchterm().length < 2) {
return true;
}
datacontext.getZips(searchterm(), zipcodes);
return true;
};
Instead of
var getZipCodes = function()
if I use
function getZipCodes()....
it works, not really sure what the difference is.
Related
I'm working on my web application using NodeJS, EJS and JQuery. Using JQuery I'am able to detect click event on checkbox but checkbox doesn't appeare checked.
<input type="checkbox" id="myCheck2" class="myClass">
JQuery
function checkboxDefault(){
$("#myCHeck1").attr("checked", false);
$("#myCHeck2").attr("checked", true);
}
$(function() {
$(document).on('click', ".myClass", function (e) {
e.preventDefault();
var event = $(this).attr("id");
if(event == "myCheck1")
$("#myCheck1").attr("checked", true);
else
$("#myCheck2").attr("checked", false);
});
});
I tried using $("#myCheck*").prop, instead .attr() but it doesn't work. Click event and right checkbox ID are rightly detected. Can you help me please? Thanks
prop('checked', true) // to check the box
prop('checked', false) // to uncheck the box
Also #myCHeck1 isn't it a typo?
H is big
I have an HTML5/Bootstrap form with hidden fields:
style="display: none"
which i show/hide via jQuery:
show() | hide()
For field validation i use the attribute required.
I want to have all my hidden fields as required but when some of them don't appear then the form can't proceed to submission.
Any thoughts about how can i have validation enabled only to fields displayed by user selections?
You can use this trick:
inside HTML form:
<input type="text" name="username" required="required" class="input-hidden">
CSS class:
.input-hidden{
height:0;
width:0;
visibility: hidden;
padding:0;
margin:0;
float:right;
}
You can add a class name for all the required attributes in the html:
<input type="text" name="first_name" class="card-payment-info" required>
<input type="text" name="last_name" class="card-payment-info" required>
and, from js event like a click, you can enable or disable the required attributes:
// disable require:
$(".card-payment-info").attr('required', false);
// enable require
$(".card-payment-info").attr('required', true);
Add a class .hideable to your hideable required inputs.
Then use these functions instead of your show() and hide():
function show1() {
//Your show() code here
$('.hideable').attr('required', 'required');
}
function hide1() {
//Your hide() code here
$('.hideable').removeAttr('required');
}
1 - Change the form to "novalidate"
2 - Catch the submit event
3 - Force the browser to check individually each visible input with input.reportValidity()
$('form')
.attr('novalidate', true)
.on('submit', function(){
var isValid = true;
$('input:visible,select:visible,textarea:visible', this).each(function() {
// report validity returns validity of input and display error tooltip if needed
isValid = isValid && this.reportValidity();
// break each loop if not valid
return isValid;
});
// do not submit if not valid
return isValid;
})
I've made a JQuery tool for this that also uses a mutation observer to automatically apply on dynamically created forms.
https://github.com/severinmoussel/VisibilityFormValidator/blob/master/VisibilityFormValidator.js
I wrote a drop-in replacement for the built-in show() and hide() that removes required on hide and restores them back on show (for all child elements).
(function ($) {
var oldShow = $.fn.show;
$.fn.show = function () {
oldShow.apply(this, arguments); //run the original "show" method
this.find("[notrequired]").prop("required", true).removeAttr("notrequired");
return this;
};
var oldHide = $.fn.hide;
$.fn.hide = function () {
oldHide.apply(this, arguments); //run the original "hide" method
this.find("[required]").prop("required", false).attr("notrequired", "1");
return this;
};
})(jQuery);
UPD: published as a gist here in case anyone wants to add anything https://github.com/alex-jitbit/jquery-required-visibility/blob/main/showhide.js
You can add pointer-events: none;, so the user can't click on the hidden element and also the cursor doesn't change when you hover it. As #DeadApe answered in this question
https://stackoverflow.com/a/65356856/6938902
One solution is to write your own validation-function:
This function checks all textareas and inputs in the default way, but first check if the input is displayed.
function validateFormOnlyVisableInputs(elForm) {
var inputs = elForm.querySelectorAll("input, textarea");
for (var i = 0; i < inputs.length; i++) {
console.log(i);
// display:none inputs ignorieren
if (inputs[i].offsetParent === null) continue;
if (!inputs[i].checkValidity()){
inputs[i].reportValidity();
return false;
}
}
return true;
}
You have to add an eventlistener to the submit-button and call the valdation function:
// this is out of a class, so you have to remove this...
// if you have problems you can write me ;)
this.elSendButton = this.elForm.querySelector("Button");
this.elSendButton.addEventListener("click", async (e) => {
e.preventDefault();
if (validateFormOnlyVisableInputs(this.elForm)) {
this.elForm.submit();
...
I have select list in my html binded to observable array
<select data-bind="options: myData, optionsText: 'Name', value: selectedId"></select>
When i load my page i set value to observable selectedId
But when i set value it immediately calls its subscribe event
selectedId.subscribe(function (row) {
// some logic for retrieving data
});
I dont want subscribe event to call when value is being set programatically but only want to call when user selects something from list.
Is it possible to do? Cant find any good examples.
Update1
i set value to my observable selectedId in this way
selectedId(ko.utils.arrayFirst(data(), function(item) {
return item.id=== 5;
}));
I think because of this its firing subscribe event
If you set the initial value before you actually subscribe, then you shouldn't get a subscription event firing. For example:
function ViewModel() {
var self = this;
self.selectedID = ko.observable();
self.selectedID(10); // this won't fire the event because we haven't subscribed yet
self.selectedID.subscribe(function(value) {
alert("value changed by user");
});
}
ko.applyBindings(new ViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<input type="number" data-bind="value: selectedID" />
Now if you want to solve the general case, where the value might change programmatically later and you don't want the subscribe to fire then, you might want to have a flag that you can use to simply skip the processing of the subscribe handler. Something like:
function ViewModel() {
var self = this;
self.selectedID = ko.observable();
self.selectedID(10); // this won't fire the event because we haven't subscribed yet
var _skipNotification = false; // this tells us whether or not we should process subscribe
// putting this logic in a function makes it easier if you have multiple places
// where you need to programmatically set the id.
function setSelectedID(value) {
_skipNotification = true;
self.selectedID(value);
_skipNotification = false;
}
self.selectedID.subscribe(function(value) {
if (!_skipNotification) {
alert("value changed by user");
}
});
self.changeProgrammatically = function() {
setSelectedID(1);
};
}
ko.applyBindings(new ViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<input type="number" data-bind="value: selectedID" />
<input type="button" data-bind="click: changeProgrammatically" value="change programmatically" />
Here's your fiddle fixed to use the technique above. A local variable _skipNotification is defined in the view model and checked in the subscribe event. Then the importData function that is called from the mouse click looks like this:
this.importData = function () {
skipNotification = true;
self.selectedGroup(ko.utils.arrayFirst(self.availableGroups(), function (val) {
//debugger;
return val.GroupId == 8;
}));
skipNotification = false;
console.log("Lets see if it hits me first");
};
This will set the selectedGroup without causing the body of the selectedGroup.subscribe to execute. Note that as a result the selectedGroupId doesn't get set so your one span will still say You have chosen Nothing despite the fact that something is selected in the drop-down. I'm not sure if that was what you were actually going for, but it seems pretty misleading. Especially since the only way to now get it to correctly read You have chosen Football Team is to select something else first and then reselect Football Team.
So I'm basically developing an automated click-paste-and-upload system for mutiple texts and files inside a google page.
This method helped me get the instances of objects that I'm looking for: buttons, textboxes, richtextboxes, etc.
Now I want to work with them.
So for example I know the id of a button , and the function subscribed to its click event. How do I trigger the click event from the extension ? I've tried injecting a script with the click event handler (discovered with DOM inspector) at "document_startup" but I don't get an error or anything else.
Here's the content script! The loggerhead function should have inserted the script but I don't think it did. What might be the reason for the blow code not giving anything?
// Runs a function for every added DOM element that matches a filter
// filter -- either function(DOM_node){/*...*/}, returns true or false
// OR a jQuery selector
// callback -- function(DOM_node){/*...*/}
function watchNodes(filter, callback){
observer = new MutationObserver( function (mutations) {
mutations.forEach( function (mutation){
if(typeof filter === "function"){
$(mutation.addedNodes).filter(
function(i){ return filter(this); }
).each(
function(i){ callback(this); }
);
} else {
$(mutation.addedNodes).filter(filter).each(
function(i){ callback(this); }
);
}
});
});
// For every added element, a mutation will be processed
// with mutation.taget == parent
// and mutation.addedNodes containing the added element
observer.observe(document, { subtree: true, childList: true });
}
function loggerhead(node) {
console.log("passhead");
//also inject jquery
var jqueryEl = document.createElement('script');
jqueryEl.setAttribute('src', chrome.extension.getURL('jquery-1.11.1.min.js'));
jqueryEl.setAttribute('type', 'text/javascript');
var scriptEl = document.createElement('script');
scriptEl.setAttribute('src', chrome.extension.getURL('script.js'));
scriptEl.setAttribute('type', 'text/javascript');
node.appendChild(jqueryEl);
node.appendChild(scriptEl);
}
watchNodes("head", loggerhead);
// method not working
//var gmailHead = jQuery("head", document).get(0);
script.js contains the function of subscribed to the click event of the button that I've managed to find through the DOM inspector:
function Cdb(b){return function(){if(Vbb()){return Ddb(b,this,arguments)}else{var a=Ddb(b,this,arguments);a!=null&&(a=a.val);return a}}}
You should try to call the existing click handler like
buttonElement.click()
I read here and there about touch but I can't get to it completely. I have an app where I am blocking all touch events on the document.
document.addEventListener('touchstart', function (e) { e.preventDefault(); }, false);
document.addEventListener('touchend', function (e) { e.preventDefault(); }, false);
Now I have somewhere in the document which was working fine before adding above lines but now not.
<form onsubmit="search(event)">
<input id="q" type="text" placeholder="Search.." />
</form>
Blocking document touch are very needed. How can I recitfy the problem and please if you know of any guide that describes touch events in detail that would be wonderful.
Right now you are blocking ALL touch events, but what you really want to do is block all touch events EXCEPT: x, y and z;
You'll just have to make your preventDefault() conditional.
e.g.
document.addEventListener('touchstart', function (e) {
e=e||window.event;
var recip=e.target||e.srcElement;
if(recip.nodeName.toLowerCase()=='input'){return true;}
e.preventDefault();
}, false);