Have to click twice to execute onclick - javascript

I have problem where I have to click twice to swap button text and class on the first time I click it. All the other times it changes on first click.
I already tried removing click inside changeUnits() function but in this case I can change to Celcius once and cannot swap values anymore. I'm assigning value and class because I'm going to use it later in another api call to retrieve weather in specified units.
Does anyone see what am I doing wrong?
html
<button id="units" class="Fahrenheit" onclick="changeUnits();callWeather()">F</button>
javascript
function changeUnits() {
if($("#units").hasClass("Fahrenheit")) {
$(".Fahrenheit").click(function() {
$(".Fahrenheit").text("C");
$(this).removeClass('Fahrenheit').addClass('Celcius');
});
}
else if($("#units").hasClass("Celcius")) {
$(".Celcius").click(function() {
$(".Celcius").text("F");
$(this).removeClass('Celcius').addClass('Fahrenheit');
});
}
}

try this .. No need to check for class you only need toggleClass() and just check for .text() to change the text to C or F
function changeUnits(el) { // pass el here
var ThisText = $(el).text(), // get text from this element
fah_or_ce = $(el).text().trim() == 'C' ? 'F' : 'C'; // set fah_or_ce as a variable and check if C return F and if else return C
$(el).text(fah_or_ce ); // change text with new text
$(el).toggleClass('Fahrenheit Celcius'); // toggle between classes
}
and use it onclick = "changeUnits(this)"
Demo 1
function changeUnits(el) {
var ThisText = $(el).text(),
fah_or_ce = $(el).text().trim() == 'C' ? 'F' : 'C';
$(el).text(fah_or_ce );
$(el).toggleClass('Fahrenheit Celcius');
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="units" class="Fahrenheit" onclick="changeUnits(this)">F</button>
And for me I prefer to use .on(click) event instead of inline onclick
Demo 2
$(document).ready(function(){
$('#units').on('click' , function(){
changeUnits(this);
// you can use callWeather() as well
//callWeather();
});
});
function changeUnits(el) {
var ThisText = $(el).text(),
fah_or_ce = $(el).text().trim() == 'C' ? 'F' : 'C';
$(el).text(fah_or_ce );
$(el).toggleClass('Fahrenheit Celcius');
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button id="units" class="Fahrenheit">F</button>

I don't understand what why you use the function changeUnits only when button is click. For me it should be more when $("#units") change class. But it will be better to use this code for you :
<button id="units" class="Fahrenheit" onclick="changeUnits();callWeather()">F</button>
<button id="units" class="Celsius" onclick="changeUnits();callWeather()" style="display: none;">C</button>
function changeUnits() {
if($("#units").hasClass("Fahrenheit")) {
$(".Fahrenheit").hide();
$(".Celcius").show();
}else if($("#units").hasClass("Celcius")) {
$(".Fahrenheit").show();
$(".Celcius").hide();
}
}

There you go :
Explanation:
Your problem is quite simple, the fact that you have to press twice is due to the fact that your function that really does the swap is affected once you click,
a simple idea is to assign your function when the document loads
Working code, that is really similar to yours:
function initialize()
{
if($("#units").hasClass("Fahrenheit"))
{
$(".Fahrenheit").click(function()
{
$(".Fahrenheit").text("C");
$(this).removeClass("Fahrenheit").addClass("Celcius");
$(this).click(initialize());
});
}
else if($("#units").hasClass("Celcius"))
{
$(".Celcius").click(function()
{
$(".Celcius").text("F");
$(this).removeClass("Celcius").addClass("Fahrenheit");
$(this).click(initialize());
});
}
}
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
</head>
<body onload="initialize()">
<button id="units" class="Fahrenheit">F</button>
</body>
</html>

Related

Get value from textbox not working in JavaScript

I want to alert the value of the textbox topValue, but when solve () is called, a textbox does appear, but with no text / value / number
Here is my code:
var topValue = document.getElementById('topValue').value
function solve() {
alert(topValue);
}
$('#solveButton').click(function () {
solve();
});
The value of the textbox is first fetched from DOM. But, when clicked on button, the same cached value is used.
This can be solved by moving the statement that read value from DOM in the function.
function solve() {
var topValue = document.getElementById('topValue').value
alert(topValue);
}
Note that
$('#solveButton').click(function () {
solve();
});
can also be written as
$('#solveButton').click(solve);
But, there is a better way.
I'll suggest you to use jQuery to get the value from the textbox.
// When DOM is completely loaded
$(document).ready(function () {
// On click of the `solveButton`
$('#solveButton').click(function () {
// Get the value of the `#topValue`
var topValue = $('#topValue').val();
// For debugging use `console.log` instead of `alert`
console.log('topValue', topValue)
});
});
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script>
$(document).ready(function () {
var topValue = document.getElementById('topValue').value; // have the initial value
function solve() {
alert(topValue);
alert(document.getElementById('topValue').value) // current value
}
$('#solveButton').click(function () {
solve();
});
});
</script>
</head>
<body style="width:50%;">
<input type="text" id="topValue" value="ssss"/>
<input type="button" value="Solve" id="solveButton" />
</body>
</html>

Detect changes made to input through code

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');
}
}
}

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>

Change the text of clicked element with 'this' in JavaScript / jQuery callback

Can anybody explain is this in the callback.
Example.
Web page.
<html>
<head>
<script src="https://code.jquery.com/jquery-1.11.2.js"></script>
<script src="myApp.js"></script>
</head>
<body>
<button type="button" id="btn001">Show</button><br/>
<p id="p001" class="article">Some contents...</p>
<button type="button" id="btn002">Show</button><br/>
<p id="p002" class="article">Other content...</p>
<!-- more paragraphs -->
</body>
</html>
First, I had written a function for each paragraph. Source code of the myApp.js.
$(document).ready(function () {
// hide all articles at the begining
$(".article").hide();
// button 1 hides/shows first paragraph
$("#btn001").click(function () {
if ($(this).html() === "Show") {
$(this).html("Hide");
} else {
$(this).html("Show");
}
$("#p001").toggle();
});
// button 2 hides/shows second paragraph
$("#btn002").click(function () {
if ($(this).html() === "Show") {
$(this).html("Hide");
} else {
$(this).html("Show");
}
$("#p002").toggle();
});
// repeat code for next paragraphs
});
I get angry with the code repetition, so I tried excluding code to function.
function handleHideShow(par) {
if ($(this).html() === "Show") {
$(this).html("Hide");
} else {
$(this).html("Show");
}
par.toggle();
}
$(document).ready(function () {
// hide all articles at the begining
$(".article").hide();
// button 1 hides/shows first paragraph
$("#btn001").click(function () {
handleHideShow($("#p001"));
});
// button 2 hides/shows second paragraph
$("#btn002").click(function () {
handleHideShow($("#p002"));
});
});
Toggling paragraphs works, but the text on the button is not changing. Can anybody explain what happens to this?
Why in the first example $(this) selects the clicked element?
What is $(this) in the second example?
And how to solve this problem?
Your first function is an event handler. With Event handlers $(this) automatically refers to the element that was clicked, changed, hovered, etc.. jQuery creates $(this) for you and, while you can't explicitly see it passed into the function it is available to all the code within the click handler's callback.
Your second function is a simple function and is not an event handler therefore jQuery does not create the $(this) reference for you
In your code, you could pass $(this) from your event handler like handleHideShow($(this),$("#p002")); and reference it in your function like function handleHideShow(btn, par). Then, inside handleHideShow, btn will refer to the same element as $(this) referred to in your click handler (see the second snippet below).
But, I would simplify the code alltogether by giving the buttons and paragraphs classes instead of ids and doing this:
$(document).ready(function () {
$('.article').hide();
$('.myBtn').click(function(){
$(this).html( $(this).html() == 'Show' ? 'Hide' :'Show' );
$(this).nextAll('.article').first().toggle();
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<html>
<head>
<script src="https://code.jquery.com/jquery-1.11.2.js"></script>
<script src="myApp.js"></script>
</head>
<body>
<button type="button" class="myBtn">Show</button><br/>
<p class="article">Some contents...</p>
<button type="button" class="myBtn">Show</button><br/>
<p class="article">Other content...</p>
<!-- more paragraphs -->
</body>
</html>
Now, one could argue that this is less efficient as jQuery has to search through more elements to find the paragraph but I believe it to be more robust as you can add as many buttons and paragraphs as you like without worrying about all the sequential ids. And honestly, you'd have to have a pretty giant webpage to see any performance issues.
$(document).ready(function () {
// hide all articles at the begining
$(".article").hide();
// button 1 hides/shows first paragraph
$("#btn001").click(function () {
handleHideShow($(this),$("#p001"));
});
// button 2 hides/shows second paragraph
$("#btn002").click(function () {
handleHideShow($(this),$("#p002"));
});
});
function handleHideShow(btn, par) {
if (btn.html() === "Show") {
btn.html("Hide");
} else {
btn.html("Show");
}
par.toggle();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.0/jquery.min.js"></script>
<html>
<head>
<script src="https://code.jquery.com/jquery-1.11.2.js"></script>
<script src="myApp.js"></script>
</head>
<body>
<button type="button" id="btn001">Show</button><br/>
<p id="p001" class="article">Some contents...</p>
<button type="button" id="btn002">Show</button><br/>
<p id="p002" class="article">Other content...</p>
<!-- more paragraphs -->
</body>
</html>
You need to pass the object of button in the function:
Try this:
function handleHideShow(par,that) {
if ($(that).html() === "Show") {
$(that).html("Hide");
} else {
$(that).html("Show");
}
par.toggle();
}
$(document).ready(function () {
// hide all articles at the begining
$(".article").hide();
// button 1 hides/shows first paragraph
$("#btn001").click(function () {
handleHideShow($("#p001"),this);
});
// button 2 hides/shows second paragraph
$("#btn002").click(function () {
handleHideShow($("#p002"),this);
});
});
Or you try this also:
$(document).ready(function () {
// hide all articles at the begining
$(".article").hide();
// button 1 hides/shows first paragraph
$("button[id^='btn']").click(function () {
if ($(this).html() === "Show") {
$(this).html("Hide");
} else {
$(this).html("Show");
}
$(this).next().toggle();
});
});
The above code is optimal and you can add buttons as many as you want.
The function is called with no special context, and this is not the element.
Reference the function instead
$("#btn001").click(handleHideShow);
$("#btn002").click(handleHideShow);
function handleHideShow() {
$(this).html(function (_, html) {
return html === "Show" ? "Hide" : "Show";
});
$('#' + this.id.replace('btn', 'p')).toggle();
}
FIDDLE

how to make ngclick work like toggle?

i have taken a span and after clicking the span, it adds 1 to it. but what i need is, ngclick should add only once to whatever value is inside the span. Again for another click it should subtract 1 from it. It should not iterate continuously.
i am getting {{tvshow.episode.ratings.loved}} from json data.
pls help.
//html
<html>
<body>
<span class="label likeme" ng-click="tvshow.episode.ratings.loved = tvshow.episode.ratings.loved + 1" ng-init="{{tvshow.episode.ratings.loved}}">
<i class="icon-thumbs-up"></i> {{tvshow.episode.ratings.loved}}</span>
</body>
</html>
//view.html
<span ng-click="doOneTimeOnly();">{{tvshow.episode.ratings.loved}}</div>
//controller.js
$scope.times = 0;
$scope.doOneTimeOnly = function () {
if ( $scope.times < 1) {
//do my stuff with the tvshow.episode.ratings.loved
//.................
$scope.times += 1;
}
}
Actually i dont think this makes sense but is what you are asking for :P
this can also be easily moved to a custom directive like directive('ngOneClickOnly'); for example
now here you have one option ng-disabled with this you can click only once.
<script>
angular.module("my_app",[])
.controller("my_ctr",function($scope){
$scope.skm=true;
$scope.mmmmmm=function()
{
if($scope.skm==false)
{
alert("first time you clicked");
}
else
{
alert("now you cant click");
$scope.skm=false;
}
}
})
</script>
<body ng-app="my_app" ng-controller="my_ctr">
<button ng-click="mmmmmm()" ng-disabled="!skm">hii</button>
</body>

Categories

Resources