How can we get val from keyup in jquery - javascript

i want give val from keyup in jquery
my code is :
var vartest;
$( ".target" ).keyup(function() {
vartest= this.value;
console.log('in func:' + vartest);
});
console.log('out of func:' + vartest);
but vartest is undefined

Your function triggers only once your Element receives an event.
At the time you were calling vartest (outside of your function) its value is still undefined because the event (that actually attaches a value) will trigger at a later time.
Create a function getTargetsValues and call that function when needed.
Instead of "keyup" you might eventually listen for the "input" event:
// Cache your elements
const $targets = $(".target");
// Use this function to get an Array of inputs .target values
function getTargetsValues () {
return $targets.get().map(el => el.value);
}
$targets.on("input", function() {
console.log('in func: ' + getTargetsValues());
});
console.log('out of func: ' + getTargetsValues());
<input class="target" type="text" value="1. target">
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>

I’m not sure if this is what you need, but if you want to get value of input where event happened, you should take it from event target:
$(‘.target’).keyup(e => {
vartest = e.target.value;
});

Related

How to preserve old input text value after the change in Javascript? [duplicate]

I have an input text in jQuery I want to know if it possible to get the value of that input text(type=number and type=text) before the onchange happens and also get the value of the same input input text after the onchange happens. This is using jQuery.
What I tried:
I tried saving the value on variable then call that value inside onchange but I am getting a blank value.
The simplest way is to save the original value using data() when the element gets focus. Here is a really basic example:
JSFiddle: http://jsfiddle.net/TrueBlueAussie/e4ovx435/
$('input').on('focusin', function(){
console.log("Saving value " + $(this).val());
$(this).data('val', $(this).val());
});
$('input').on('change', function(){
var prev = $(this).data('val');
var current = $(this).val();
console.log("Prev value " + prev);
console.log("New value " + current);
});
Better to use Delegated Event Handlers
Note: it is generally more efficient to use a delegated event handler when there can be multiple matching elements. This way only a single handler is added (smaller overhead and faster initialisation) and any speed difference at event time is negligible.
Here is the same example using delegated events connected to document:
$(document).on('focusin', 'input', function(){
console.log("Saving value " + $(this).val());
$(this).data('val', $(this).val());
}).on('change','input', function(){
var prev = $(this).data('val');
var current = $(this).val();
console.log("Prev value " + prev);
console.log("New value " + current);
});
JsFiddle: http://jsfiddle.net/TrueBlueAussie/e4ovx435/65/
Delegated events work by listening for an event (focusin, change etc) on an ancestor element (document* in this case), then applying the jQuery filter (input) to only the elements in the bubble chain then applying the function to only those matching elements that caused the event.
*Note: A a general rule, use document as the default for delegated events and not body. body has a bug, to do with styling, that can cause it to not get bubbled mouse events. Also document always exists so you can attach to it outside of a DOM ready handler :)
Definitely you will need to store old value manually, depending on what moment you are interested (before focusing, from last change).
Initial value can be taken from defaultValue property:
function onChange() {
var oldValue = this.defaultValue;
var newValue = this.value;
}
Value before focusing can be taken as shown in Gone Coding's answer. But you have to keep in mind that value can be changed without focusing.
Just put the initial value into a data attribute when you create the textbox, eg
HTML
<input id="my-textbox" type="text" data-initial-value="6" value="6" />
JQuery
$("#my-textbox").change(function () {
var oldValue = $(this).attr("data-initial-value");
var newValue = $(this).val();
});
I have found a solution that works even with "Select2" plugin:
function functionName() {
$('html').on('change', 'select.some-class', function() {
var newValue = $(this).val();
var oldValue = $(this).attr('data-val');
if ( $.isNumeric(oldValue) ) { // or another condition
// do something
}
$(this).attr('data-val', newValue);
});
$('select.some-class').trigger('change');
}
I found this question today, but I'm not sure why was this made so complicated rather than implementing it simply like:
var input = $('#target');
var inputVal = input.val();
input.on('change', function() {
console.log('Current Value: ', $(this).val());
console.log('Old Value: ', inputVal);
inputVal = $(this).val();
});
If you want to target multiple inputs then, use each function:
$('input').each(function() {
var inputVal = $(this).val();
$(this).on('change', function() {
console.log('Current Value: ',$(this).val());
console.log('Old Value: ', inputVal);
inputVal = $(this).val();
});
my solution is here
function getVal() {
var $numInput = $('input');
var $inputArr = [];
for(let i=0; i < $numInput.length ; i++ )
$inputArr[$numInput[i].name] = $numInput[i].value;
return $inputArr;
}
var $inNum = getVal();
$('input').on('change', function() {
// inNum is last Val
$inNum = getVal();
// in here we update value of input
let $val = this.value;
});
The upvoted solution works for some situations but is not the ideal solution. The solution Bhojendra Rauniyar provided will only work in certain scenarios. The var inputVal will always remain the same, so changing the input multiple times would break the function.
The function may also break when using focus, because of the ▲▼ (up/down) spinner on html number input. That is why J.T. Taylor has the best solution. By adding a data attribute you can avoid these problems:
<input id="my-textbox" type="text" data-initial-value="6" value="6" />
If you only need a current value and above options don't work, you can use it this way.
$('#input').on('change', () => {
const current = document.getElementById('input').value;
}
My business aim was removing classes form previous input and add it to a new one.
In this case there was simple solution: remove classes from all inputs before add
<div>
<input type="radio" checked><b class="darkred">Value1</b>
<input type="radio"><b>Value2</b>
<input type="radio"><b>Value3</b>
</div>
and
$('input[type="radio"]').on('change', function () {
var current = $(this);
current.closest('div').find('input').each(function () {
(this).next().removeClass('darkred')
});
current.next().addClass('darkred');
});
JsFiddle: http://jsfiddle.net/gkislin13/tybp8skL
if you are looking for select droplist, and jquery code would like this:
var preValue ="";
//get value when click select list
$("#selectList").click(
function(){
preValue =$("#selectList").val();
}
);
$("#selectList").change(
function(){
var curentValue = $("#selectList").val();
var preValue = preValue;
console.log("current:"+curentValue );
console.log("old:"+preValue );
}
);

Why is click event handler for a submit button in a colorbox defined in a jQuery prototype method not invoked

I have added a function to jQuery prototype as below. What I want to do is when this method is invoked, generate an html form based on the arguments passed to the method and show it in a colorbox.
(function($) {
$.fn.myFunction = function(data){
var form = $('<form name="people"></form>');
var index;
for (index = 0; index < data.length; index++) {
var match = data[index];
$('<input type="radio" name="person">' + match['name'] + ' [' + match['uri'] + ']<br> ')
.attr("value", match['uri'])
.appendTo(form);
}
$('<input type="button" id="a_button" value="Add"/><br>')
.appendTo(form);
var list = $('<div>').append(form).html();
$('#a_button').click(
function(){
console.log('message from event handler');
}
);
$.colorbox({ innerWidth:420, innerHeight:315, html: list });
};
})(jQuery);
As you can see, form has a button called Add using which I hope to make an ajax request. But unfortunately click event handler attached to this button doesn't seem to be invoked.
Does anyone have any idea about what's wrong here? myFunction is actually invoked by a drupal ajax command in case if that's helpful.
You are appending the form to the DOM after attaching the event handler.
$('#a_button') searches the DOM at that specific point in time, but the form is not added to the DOM until after your call to colorbox with list as a parameter.
Try a permanent delegated event handler instead (or simply add the click handler after the colorbox line).
e.g.
$(document).on("click", "#a_button", function(){
console.log('message from event handler');
});
or
$.colorbox({ innerWidth:420, innerHeight:315, html: list });
$('#a_button').click(
function(){
console.log('message from event handler');
}
);

Attaching Event Handlers to JQuery-generated DOM Elements

I'm pulling some data from an external API and then displaying it in a dashboard page. To do this, I'm generating DOM elements once I've processed the data, like so:
for(var key in companies) {
$(document.createElement("span"))
.attr({ id: key })
.appendTo($("#someDiv"))
.click(function() {
alert(key);
});
$("#"+key).html("<b>" + key + "</b>: $"+companies[key]+"<br>");
}
However, when I click on any of the newly generated span elements, I get an alert with the last value in companies. For example, if I had declared:
var companies = {
"Google": 3,
"Apple": 4
};
then clicking on both the Google span and the Apple span would alert 4. My desired behavior is clicking on the Google span to alert 3.
How about this:-
Attach the event handler using event delagtion with on() just once. (See the class added compName). and just using its id.
See Delegated event handler reference here. If somediv already exist in DOM then you can just use $('#someDiv').on('click','.compName',function(){...
$(function(){
$(document).on('click','.compName',function(){
//.....
alert(this.id);
//....
});
....
for(var key in companies) {
$(document.createElement("span"))
.attr({ id: key, 'class':'compName' }).html("<b>" + key + "</b>: $"+companies[key]+"
<br>").html("<b>" + key + "</b>: $"+companies[key]+"<br>").
.appendTo($("#someDiv"));
}
//...
})
You need to capture the key value with a closure, since the loop will have finished by the time the click handler actually executes. Try this:
.click((function() {
return function () {
alert(key);
};
})());
Or, you can just alert its id, since that's what you set it as:
.click(function () {
alert(this.id);
});
That's because the variable key gets changed before you call the function. You need a closure around it to prevent it from modified by the outer code:
for(var key in companies) {
$(document.createElement("span"))
.attr({ id: key })
.appendTo($("#someDiv"))
.click((function(privatekey) {
return function(){
alert(privatekey);
};
})(key));
$("#"+key).html("<b>" + key + "</b>: $"+companies[key]+"<br>");
}

Passing eventobejct in jquery

I want to pass eventObject with trigger function, means when i manually trigger any event say:
$(".test").bind({ click : Testing });
$('.test').trigger("click");
function Testing(e)
{
}
When the function testing is called by mouseclick , the parameter e contains the eventobject, so i want this same thing when we trigger it manually.Can we pass eventobject when we trigger any event manually, Is this possible?
As gdoron points out (+1), jQuery will supply the event object for you. But you can create it explicitly if you like, to fill it in with information that jQuery can't fill in for you. You can create an Event object and pass it into trigger.
Here's an example of both using the default event object and creating your own: Live copy | source
jQuery(function($) {
$(".test").click(function(e) {
display("Received click on target");
display("typeof e = " + typeof e);
if (e) {
display("e.type = " + e.type);
if (e.type === "click") {
display("Coords: (" + e.pageX + "," + e.pageY + ")");
}
}
});
//Create a new jQuery.Event object without the "new" operator.
var e = $.Event("click");
// Fill in more info
e.pageX = 42;
e.pageY = 27;
// Trigger an artificial click event
display("Issuing a click via <code>$('.test').trigger('click')</code>");
$('.test').trigger("click");
// Trigger an artificial click event
display("Issuing a click creating our own event object with more info on it.");
$('.test').trigger(e);
function display(msg) {
$("<p>").html(msg).appendTo(document.body);
}
});
You don't need to do anything, the Event object is there already when you trigger an event as well....
The event object is always passed as the first parameter to an event handler
...
...
trigger docs
Live DEMO

Javascript variable scope issue with jquery click event

I am trying to assign a series of objects stored in an array to jquery click event handlers.
The problem is , when the event fires, I only ever references the last object in the array.
I have put together a simple example to show the problem:
function dothis() {
this.btns = new Array('#button1', '#button2');
}
// Add click handler to each button in array:
dothis.prototype.ClickEvents = function () {
//get each item in array:
for (var i in this.btns) {
var btn = this.btns[i];
console.debug('Adding click handler to button: ' + btn);
$(btn).click(function () {
alert('You clicked : ' + btn);
return false;
});
}
}
var doit = new dothis();
doit.ClickEvents();
The HTML form contains a couple of buttons:
<input type="submit" name="button1" value="Button1" id="button1" />
<input type="submit" name="button2" value="Button2" id="button2" />
When button1 is clicked, it says "You clicked #Button2"
It seems that both button click handlers are pointing to the same object inside var btn.
Considering the variable is inside the for loop, I cannot understand why.
Any ideas?
You need a function factory to close the loop variable, such as this:
//get each item in array:
for (var i=0; i<this.btns.length; i++) {
$(this.btns[i]).click(function(item) {
return function () {
alert('You clicked : ' + item);
return false;
}
}(this.btns[i]));
}
Another good option is to let jquery help you. Use jQuery.each(). The variable btn here is local to the handler function, and so isn't reused between iterations. This allows you to close it and have it keep its value.
$.each(this.btns, function() {
var btn = this;
$(this).click(function () {
alert('You clicked : ' + btn);
return false;
}
});
within an event handler, 'this' usually refers to the element firing the event, in this case, it would be your button
so the solution to your problem is fairly easy, instead of referencing the btn variable, which lives in a higher scope and gets mutated long before the event handler fires, we simply reference the element that fired the event and grab its ID
$(btn).click(function () {
alert('You clicked : #' + this.id);
return false;
});
Note: if your array contains other selectors that just the ID, this will obviously not reflect that and simply continue to show the ID
Lucky, the click handler (and all other event handlers afaik) take an extra parameter for eventData, useful like so:
$(btn).click(btn, function (event) {
alert('You clicked : #' + event.data);
return false;
});
User an array if you're passing multiple things:
$(btn).click(['foo', 'bar'], function (event) {
alert('this should be "foo": ' + event.data[0]);
alert('this should be "bar": ' + event.data[1]);
return false;
});
you have to use closures for this.
i'm not sure if i remember the correct syntax but you could try this:
$(btn).click(function () {
return function() {
alert('You clicked : ' + btn);
return false;
}
});
maybe you need to change just the click binding:
$(btn).click(function () {
alert('You clicked : ' + $(this).attr('id'));
return false;
});
Your problem is here:
alert('You clicked : ' + btn);
btn retains the value from the last time it was called in the loop. Read the value from the button in the event.
$(btn).data('selector', btn).click(function () {
alert('You clicked : ' + $(this).data('selector'));
return false;
});
http://jsfiddle.net/Mc9Jr/1/

Categories

Resources