Detect changes made to input through code - javascript

Somewhere in my page I have an button that when clicked changes the value of another input. However I don't have control over the code where the click event is defined (on a clients' CDN) and I didn't bother to look. I just want to capture the event when my inputs' value is change through the code. Here's an example:
HTML
<input type="text" id="myinput" />
<input type="button" id="theonechanging" value="Click Me" />
<br />
<p id="message"></p>
JS
var i = 0;
$("#theonechanging").click(function(e) {
// YOU CAN NOT CHANGE THIS FUNCTION
$("#myinput").val("changed via button " + i++);
});
$("#myinput").on("input change bind",function(e) {
$("#message").text("changed " + i++);
});
Here's a fiddle where you can test the situation: http://jsfiddle.net/fourat05/t9x6uhoh/
Thank you for your help !

There's an incredibly hacky way to do this.
What you do is replace the jQuery.fn.val function with your own implementation, and call the old implementation from the new one. This technique is a kind of Monkey patching.
The implementation is as follows:
var i = 0;
$("#theonechanging").click(function(e) {
// YOU CAN NOT CHANGE THIS FUNCTION
$("#myinput").val("changed via button " + ++i);
});
var handleChanges = function(){
$("#message").text("changed " + i);
}
var oldval = jQuery.fn.val;
jQuery.fn.val = function(){
oldval.apply(this,arguments);
if(this.attr('id') === 'myinput'){ //and possibly add a check for changes
handleChanges();
}
}
$("#myinput").on("input change bind",function(e) {
i++;
handleChanges();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<input type="text" id="myinput" />
<input type="button" id="theonechanging" value="Click Me" />
<br />
<p id="message"></p>
However, I strongly recommend against using it, because:
This alters the behaviour of a widespread library, thus creating possible pitfalls for the developers producing code for the same page
It will quickly become complicated to detect multiple events on multiple elements.
Please understand the side effects of this method before implementing it.

Values changed directly in the DOM dont trigger those events, but since you have an action that is called to change the value, you can trigger the input change event.
$("#theonechanging").on("click", function(e) {
$("#myinput").trigger("change");
});
fiddle

use triggers
var i = 0;
$("#theonechanging").click(function(e) {
// YOU CAN NOT CHANGE THIS FUNCTION
$("#myinput").val("changed via button " + i++);
});
$("#theonechanging").on("click", function(e) {
$("#myinput").trigger("change");
});
$("#myinput").on("input change bind",function(e) {
$("#message").text($("#myinput").val());
});
Fiddle

I think it is not possible without changing the script for BUTTON.
When the user click the 'Button', you should trigger another function to catch the change in 'Input'.
If you don't want to change the 'Button' script, you can try something like the code below, seeking for the correct combination of events:
(check the list of events here: http://www.w3schools.com/tags/ref_eventattributes.asp)
<html>
<body>
<input type="text" id="myinput" onchange="change_Message('onchange')"
onclick="change_Message('onclick')"
oninput="change_Message('oninput')"
onkeypress="change_Message('onkeypress')"/>
<input type="button" id="theonechanging" value="Click Me" onclick="change_Input()"/>
<br />
<p id="message"></p>
<script>
var input_value = document.getElementById('myinput').value; // as global variable
function Test_if_Change()
{
if ( document.getElementById('myinput').value != input_value )
{
change_Message('Test_if_Change');
}
}
setInterval(Test_if_Changed, 10);
function change_Input() { document.getElementById('myinput').value = 'input changed by button'; }
function change_Message(event) { document.getElementById('message').innerHTML = 'message changed by '+event+' to: ' + document.getElementById('myinput').value; }
</script>
</body>
</html>

There is no perfect way to detect input value changes through code but if you you are using jquery ,you can hook the val function and trigger change event manually.
jQuery.fn._val = jQuery.fn.val;
jQuery.fn.val = function(){
jQuery.fn._val.apply(this,arguments);
if(arguments.lenght==1){
this.trigger('code-change');
}
}
}

Related

How to enable a button on pasting something using mouse?

I have a textbox and a button. The functionality is that whenever textbox is empty, button is disabled and if not empty then button is enabled. I am doing this using following jQuery code:
$('#user_field').keyup(function(){
if($(this).val().length !=0){
$('#btn_disabled').removeAttr('disabled');
$('#btn_disabled').attr('class', 'upload_button_active');
}
else{
$('#btn_disabled').attr('disabled',true);
$('#btn_disabled').attr('class','upload_button_inactive');
}
})
However, when I am trying to paste input using mouse, the button is not enabling. I have tried binding other mouse events like mousemove, but for that to work we have to move the mouse after pasting. I want to avoid that. Suggest something else.
You should use 'input'
$("#tbx").on('input',function(){
var tbxVal=$(this).val();
if(tbxVal.length===0){
$("#btn").prop("disabled",true);
}else{
$("#btn").prop("disabled",false);
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="tbx">
<button id="btn" disabled>Button</button>
You can use the paste event and retrieve the value of the input inside a setTimeout
$('#user_field').on('paste input', function() {
setTimeout(() => {
if ($(this).val().length !== 0) {
$('#btn_disabled').removeAttr('disabled');
$('#btn_disabled').attr('class', 'upload_button_active');
} else {
$('#btn_disabled').attr('disabled', true);
$('#btn_disabled').attr('class', 'upload_button_inactive');
}
}, 1000)
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type='text' id='user_field'>
<button id='btn_disabled' disabled='disabled'>Click</button>
Just Call the function on change.
It will take your input event from mouse as well.
$("#textBox").change(function(
var val=$(this).val();
if(val.length===0){
$("#btn").prop("disabled",true);
}else{
$("#btn").prop("disabled",false);
}
});

Jquery on keyup once

How to trigger another alert when I input some text on next time?
For example:
1. put some text
2. alert triggered
3. put some text again
4. alert trigger again
EDIT: I don't want to keep trigger the alert for every time i input, what i trying to do is... lets say I key in "abcd", the function should just trigger once. Then I click everywhere on the screen. Later, I key in "dddd" again in the textbox, the function trigger again for once
EDIT 2: Sry guys, maybe my requirement a bit confusing, i just edit the code and re-explain to illustrate my real case. So, first, i key in "abcd" on textbox, the tooltip should trigger once on first letter of "a". Then i click everywhere of the screen, the tooltip disappear. Next, I key in again "gfffee", the tooltip should appear again on first letter of "g".
<input type="text" id="test">
<input type="button" id="tool">
$('#test').one("keyup", function(){
$('#tool').tooltip("show");
});
$('#tool').tooltip({
placement: "bottom",
trigger: "focus",
title: "Click here",
});
ANSWER:
Thanks everyone for helping me, I managed solve it based on combination of everyone answer.
count = 0;
$('#test').on("change", function(){
count = 0;
});
$('#test').on("keyup", function(){
if(count == 0)
{
$('#tool').tooltip("show");
count = 1;
}
});
$('#tool').tooltip({
placement: "bottom",
trigger: "focus",
title: "Click here",
});
<input type="text" id="test">
<input type="button" id="tool">
Try this
var triggered = 0; // or false
$('#test').on('input', function() {
if(triggered == 0) {
alert('whatever message here');
triggered++;
}
});
$('#test').on('blur', function() {
// reset the triggered value to 0
triggered = 0;
});
I think there is no deterministic way to figure out when you are done with your input, using just the keyup event. But you can try debounce. I've added underscore.js to use debouce, but feel free to use your own implementation or another library. From the debounce docs of underscore
Useful for implementing behavior that should only happen after the input has stopped arriving
You can play around with the wait time to suit your needs. I've made it 500 ms
$('#test').on("keyup", _.debounce(function() {
alert("test");
}, 500));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
<input type="text" id="test">
An excellent explanation of debounce here
Alternate solution
Another possible solution is to attach a blur handler, which will execute if clicked outside your input
$("#test").on("blur", function(e) {
alert("Test")
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type="text" id="test">
Can't you just use the onchange function? From your edit it seems like this would be more appropriate for your use case.
So
$('#test').on("change", function(){
alert("test");
});
on input clear the timer with clearTimeout(userTimer); then start new timer with setTimeout(doneType, maxTimer*1000); the maxTimer is in sec of your choose (2s here) if timeout call the function doneType
var userTimer;
var maxTimer = 2;
//on input, clear the timer and start new timer
$('#test').on('input', function () {
clearTimeout(userTimer);
userTimer = setTimeout(doneType, maxTimer*1000);
});
function doneType() {
alert('keep type?');
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="test">

Copy value from input 1 to input 2 onclick

Looking for a script that copies input value 1 to input 2 on button click and add +1 to sets text box.
b = document.getElementById('tussenstand').value;
var theTotal1 = b;
$(document).on("click", "#button1", function(){
theTotal1 = Number(theTotal2)
$('#eindstand').val(theTotal2);
});
$('#eindstand').val(theTotal2);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input id="tussenstand"></input>
<input id="eindstand"></input>
<input id="sets"></input>
<button id="button1">click</button>
Thanks in advance.
I think this will do it.
$(document).on("click", "#button1", function(){
var total = document.getElementById('tussenstand').value;
$('#eindstand').val(total);
var sets = parseInt($('#sets').val());
$('#sets').val( (sets || 0) + 1);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input id="tussenstand"></input>
<input id="eindstand"></input>
<input id="sets"></input>
<button id="button1" onclick="">click</button>
$('#button1').click(function(){
$('#eindstand').val($('#tussenstand').val());
$('#sets').val(Number($('#sets').val())+1);
});
check here : jsfiddle
Edited as you commented
The code below should work. There are several issues that will help you in the future. In the HTML the function that is triggered via the onclick will interfere with the jQuery onclick. You may want to remove it.
onclick="bereken();
The way that you have your code the b variable is not declared.
b=document.getElementById('tussenstand').value;
The way that the jQuery onclick is written should have a narrower scope (not the document). The way that it is now every time you click any were in the document it fires. I changed this:
$(document).on("click", "#button1", function(){
to this:
$("#button1").on("click", function() {
The full edited code is here.
var count = 0;
$("#button1").on("click", function(){
if ( typeof b === 'number') {
count++;
$("#eindstand").val(b);
$("#sets").val(count);
}
});
Look at the JQuery API Documentation for the .on() method. The function doesn't take the target as a parameter, but as the caller object! EDIT: well, it would actually still work the other way around, but that makes event delegation. Only do that if you know what you're doing. I prefer changing this:
$(document).on("click", "#button1", function(){ ... });
into this:
$("#button1").on("click", function() { ... });
Which in vanilla JS would be:
document.getElementById("button1").addEventListener("click", function() { ... });
Next, you shouldn't need to define variables outside of your function, and naming variables with numbers in them is a bad practice. Try to make the names as clear as possible.
Now that this is clear, here's how I'd write it:
$("#button1").on("click", function() {
$("#eindstand").val($("#tussenstand").val());
$("#sets").val(parseInt($("#sets").val())+1);
});
To achieve that use:
$(function() { //on DOM ready
$('#button1').click(function(){ //Attach event
//Get value safe - can use parseFloat() too:
val1 = parseInt($('#tussenstand').val());
val2 = parseInt($('#eindstand').val());
sets = parseInt($('#sets').val());
//Make sure we are using integers:
if (isNaN(val1) || isNaN(val2) || isNaN(sets)) return;
//Add
$('#eindstand').val(val1 + val2);
//Increment:
$('#sets').val(sets+1);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input id="tussenstand" type='number' />
<input id="eindstand" value='0' type='number' />
<input id="sets" value='0' type='number' />
<button id="button1">click</button>

Two plugins in a textarea

I need to use two plug-ins in one element on my page. I've never needed to do this and tried as it is in the code below. Most did not work!
<script type="text/javascript">
$(document).ready(function()
{
var wbbOpt = {buttons: "bold,italic,underline,|,img,link,|,code,quote"}
// plugin one wysibb
$("#editor").wysibb(wbbOpt);
// plugin two hashtags
$("#editor").hashtags();
//the two plugin worked in textarea #editor
});
</script>
Can anyone help me? Thank you.
So you can't use them because each of them take control and wrap the textarea. Since the editor is the most complex of the two the best thing to do is to take the code of the hashtag and adapt it at your need.
So here's a working example, but if you want you can trigger the function I use to the change event (adding it) or some way else
<div id="higlighter" style="width;1217px;"></div>
<textarea id="editor"></textarea>
<br />
<input id="btn" type="button" value="HASH">
<br />
$(document).ready(function() {
var wbbOpt = {
buttons: "bold,italic,underline,|,img,link,|,code,quote"
};
$("#editor").wysibb(wbbOpt);
$('#btn').click(function () { report() });
});
function report() {
$("#hashtag").val($("#editor").htmlcode());
var str = $("#editor").htmlcode();
str = str.replace(/\n/g, '<br>');
if(!str.match(/(http|ftp|https):\/\/[\w-]+(\.[\w-]+)+([\w.,#?^=%&:\/~+#-]*[\w#?^=%&\/~+#-])?#([a-zA-Z0-9]+)/g)) {
if(!str.match(/#([a-zA-Z0-9]+)#/g)) {
str = str.replace(/#([a-zA-Z0-9]+)/g,'<span class="hashtag2">#$1</span>');
}else{
str = str.replace(/#([a-zA-Z0-9]+)#([a-zA-Z0-9]+)/g,'<span class="hashtag2">#$1</span>');
}
}
$("#editor").htmlcode(str);
}
you can check a working code here on jsfiddle.
http://jsfiddle.net/4kj7d6mh/2/
You can type your text and use the editor, and when you want to higlight the hastag you click the button. If you want that to happen automatically you have to change this line:
$('#btn').click(function () { report() });
And attach the function to the keypress for example (experiment a bit)

Day/Night mode - CSS + JQuery - Cookies?

I'm testing javascript code for day/light background switch and I don't know how to do something. I'm newbie to javascript, so I'm learning new stuff.
So what I want to do?
When I click for example on button "Day" (which change background to yellow), I want that style for yellow background stay in the code after page is refreshed. I heard something about Cookies/LocalStorage, but I don't know how to implement it for this code.
Feel free to change whole code if you know easier way to do this, but please explain why it's better or why it should be like that.
Thanks in advance for your help.
Here is the code:
HTML:
<body id="body">
<input type="button" onclick="day();" value="Day" />
<input type="button" onclick="night();" value="Night" />
<input type="button" onclick="reset();" value="Reset" />
</body>
CSS:
.darkSwitch {
background: #808080;
}
.lightSwitch {
background: #ffff99;
}
JavaScript:
function day() {
body.className = "lightSwitch";
};
function night() {
body.className = "darkSwitch";
};
function reset() {
body.className = "";
};
$(function() {
var button = $('input[type=button]');
button.on('click', function() {
button.not(this).removeAttr('disabled');
$(this).attr('disabled', '');
});
});
Last edit: now disabling selected button on page load, CODE NOT IN THIS POST, see the latest JSFiddle
Explanation
What I did:
The code is put in between<script> tags at the end of the <body> (personnal preference)
I added the parameter event to the onClick event of the button element.
I added event.preventDefault() at the start of the onclick event of the button element: ensuring the page is NOT refreshed on the click of a button.
Warning: ALL the buttons will behave the same in your page. If you have other buttons, I suggest you add another class for those three buttons and bind the event on the button.myClass element.
I added a condition on the button state change, so the reset button won't get disabled.
eval($(this).val().toLowerCase()+"();"); gets the value of the the clicked button and executes the function attached to it.
Solution
HTML
<body id="body">
<input type="button" class="changeBg" onclick="day();" value="Day" />
<input type="button" class="changeBg" onclick="night();" value="Night" />
<input type="button" class="changeBg" onclick="reset();" value="Reset" />
</body>
JavaScript
(JSFiddle) <-- Check this out Updated with classes & cookies
function day() {
body.className = "lightSwitch";
};
function night() {
body.className = "darkSwitch";
};
function reset() {
body.className = "";
};
$(function () {
/* RegEx to grab the "bgColor" cookie */
var bgColor = document.cookie.replace(/(?:(?:^|.*;\s*)bgColor\s*\=\s*([^;]*).*$)|^.*$/, "$1");
var button = $('input[type=button].changeBg');
button.on('click', function (event) {
event.preventDefault();
/* Executing the function associated with the button */
eval($(this).val().toLowerCase() + "();");
button.not($(this)).removeAttr('disabled');
if ($(this).val() != "Reset") {
$(this).attr('disabled', '');
/* Here we create the cookie and set its value, does not happen if it's Reset which is fired. */
document.cookie = "bgColor="+$(this).val();
}
});
/* If the cookie is not empty on page load, execute the function of the same name */
if(bgColor.length > 0)
{
eval(bgColor.toLowerCase()+'()');
/* Disable the button associated with the function name */
$('button[value="'+bgColor+'"]').attr("disabled","disabled");
}
});
I recommend you don't use cookies unless localStorage is not supported. They slow your site down.
if(localStorage){
localStorage.setItem("bgColor", "lightSwitch");
}else{
document.cookie = "bgColor=lightSwitch";
}

Categories

Resources