Toggle between two functions when button clicked. - javascript

I have the following button which i am using as a toggle.
<button ng-click="togglefunction()">Toggle Data</button>
Here is the toggle part which should work
$scope.toggleToolPanel = function () {
// need to put below 2 functions here so that when user clicks 1st time, function 1 executes. when user clicks again, function 2 executes and so on.
};
These are 2 functions which should get executed alternatively inside the toggleFunction
function function1(params) {
return '<span >' + data + '</span>';
}
function function2(params) {
return '<span >' + data *100 + '</span>';
}

Add this to your controller:
$scope.firstFunction = false;
Then change your toggleToolPanel to the following:
$scope.toggleToolPanel = function() {
$scope.firstFunction = !$scope.firstFunction;
if($scope.firstFunction) {
function1(params);
} else {
function2(params);
}
};

Toggle a class on the button element each time it's clicked. See classList.toggle. In your click event handler, use classList.contains to look for the presence of toggle. If there do x, if not do y.

Cleaner code is attached below:
angular.module('mainModule', [])
.controller('MainCtrl', ['$scope', function($scope) {
$scope.toggle = function() {
$scope.isToggled = !$scope.isToggled;
var params = $scope.isToggled;
$scope.isToggled ? toggleIn(params) : toggleOut(params);
};
function toggleIn(params) {
console.log(params);
}
function toggleOut(params) {
console.log(params);
}
}]);
<body ng-app="mainModule">
<div ng-controller="MainCtrl">
<input type="button" value="Toggle" ng-click="toggle()" />
</div>
</body>

Related

onclick generates invalid function

I have a variable that is attached to a function. I am trying to use that variable in an onclick event.
This is what I am doing
var show = function() {
console.log("hello");
};
$(container).append(
"<div class='info' onclick=" + show + ">Show</div>"
);
However the generated html comes out like this
<div class="info" onclick="function()" {="" console.log("hello");="" }="">
Show
</div>
Any idea how I can fix this so that when I click the div my function gets called ?
You can simply do like this, Just make show a function and call it on click.
This will work
<script>
function show() {
console.log("hello");
}
$(container).append(
'<div class="info" onclick="show()">Show</div>'
);
</script>
This is kind of an unusual approach to what you're trying to do. I think it would be more idiomatic in jQuery to either
a) define the element first, with event handler, and then append it,
$("<div>Show</div>", {
"class": "info",
on: {
click: function(e) {
console.log("Hello");
}
}
}).appendTo($(container));
or
b) append a new element and then add an event handler to it after appending it.
$(container).append("<div class='info'>Show</div>");
$(container).children('.info').last().on('click', function(e) { console.log("Hello"); });
Between those two, I'd recommend the first in this case.
The variable show is a function, Then how can you bind it with string?
The code should be like,
$(container).append("<div class='info' onClick='show()'>Show</div>");
try using :
var show = function() {
console.log("hello");
};
$(container).append("<div class='info' onclick="+'show()'+">Show</div>");
This will work.
The reason why your code
var show = function() {
console.log("hello");
};
$(container).append("<div class='info' onclick=" + show + ">Show</div>");
was not working as required as show is an object of type function, so when one uses the function name without the () the variable is replaced bu the code that it consists.
Hope it helps.

Have to click twice to execute onclick

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>

Click anywhere on body to perform a function: directive

I have created a directive, which will enable a user to click on a word
to edit it in a text box and then whenever and wherever on body is clicked it should get back to the edited word.
html
<div markdown>bineesh</div>
JS Directive
app.directive('markdown',function () {
/*var htmlText='<textarea cols="20" rows="10" ng-show="isEditMode" ng-dblclick="previewSwitch()" ng-model="markdown"></textarea>';*/
var htmlText='<input type="text" class="form-control" ng-hide="isEditMode" ng-dblclick="backToTextarea()" ng-model="markdown"/>';
var newHtml='<div ng-click="previewSwitch()" ng-show="isEditMode" >{{markdown}}</div>'
var dir={
restrict:'A',
compile:function (tElement,tAttrs,transclude) {
var markdown=tElement.text();
tElement.html(htmlText);
tElement.append(newHtml);
return function (scope,element,attrs) {
scope.isEditMode=true;
scope.markdown=markdown;
scope.previewSwitch=function () {
scope.isEditMode=false;
}
scope.backToTextarea=function () {
scope.isEditMode=true;
}
};
}
}
return dir;
});
I know that something needs to be added in the directive, but I am not getting into it properly, as I am new to Angular
angular.element(document).on('click', function() {
scope.isEditMode = false;
});
element.on('click', function(e) {
e.stopPropagation();
return false;
});

Getting the collection in a jQuery plugin

Basically, what I am trying to do is create a bbcode editor with a textbox, some buttons and jQuery. Here is my form:
<div class="form-group">
<div class="btn-group btn-group-sm">
<button type="button" class="btn glyphicon bbcode" rel="bold"><b>B</b></button>
<button type="button" class="btn glyphicon bbcode" rel="italic"><i>I</i></button>
</div>
</div>
<div class="form-group">
<textarea class="bbcode" rel="editor" cols="100" rows="12"></textarea>
</div>
and my plugin is called using:
<script>
$('document').ready(function() {
$('.bbcode').bbcode();
});
</script>
and the plugin itself, I am just trying to get the basics done at the minute to update the textbox data when a button is clicked:
(function($) {
"use strict";
$.fn.bbcode = function() {
this.click(function() {
var rel = $(this).attr('rel');
if (rel == 'editor') {
return this;
} else {
alert($(this).attr('rel')); // I can see this pop up so the click event is firing
$('.bbcode[rel=editor]').val('test');
return this;
}
});
}
} (jQuery));
This seems to be the only way I can pick up the textbox, I don't really want to hardcode the class I want like that. I think what I am looking for is a way to get the collection from the function call in the script tags.
This is more than likely something stupid/obvious I have overlooked.
The value of this in the immediate function refers to the collection. However, it is shadowed by the this inside your click handler (which refers to the element being clicked) so you cannot access it.
Create a variable to store this and that'll be your collection.
(function ($) {
"use strict";
$.fn.bbcode = function () {
var $editors = this;
this.click(function () {
var rel = $(this).attr('rel');
if (rel == 'editor') {
return this;
} else {
alert($(this).attr('rel')); // I can see this pop up so the click event is firing
$editors.val('test');
return this;
}
});
}
}(jQuery));

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