I've tried to make my own case function, but I cannot get it to "show stuff" once I've hidden them on first click. So my question is what am I doing wrong, how can I solve it, and how should I've done it instead?
My only requirement is that multiple buttons can use the same code to show/hide the same object – hence things like oddClick won't work since that'll require unnecessary clicks to get even/odd again (I think?).
$('.boxbtn').on('click', function () {
var boxwidth = $('.box').width();
console.log(boxwidth);
console.log('-'+boxwidth+'px');
var state = 1;
if(state == 0) { // I think we are trying to compare value here.
/* alert("foo"); */
var state = 1;
console.log(state);
/*show stuff here*/
}
else {
/* alert("bar"); */
var state = 0;
console.log(state);
/*hide stuff here*/
}
});
this line 5: var state = 1; causes it to always go into "else
var state = 1; //placed on global scope
$('.boxbtn').on('click', function () {
var boxwidth = $('.box').width();
console.log(boxwidth);
console.log('-'+boxwidth+'px');
//var state = 1; removed from function scope
if(state == 0) {
/* alert("foo"); */
state = 1;
console.log(state);
/*show stuff here*/
}
else {
/* alert("bar"); */
state = 0;
console.log(state);
/*hide stuff here*/
}
});
Fiddle: http://jsfiddle.net/8ubk5c0f/
For detecting the state of your object, you should use the object properties (instead of a parallel state variable).
Using the value of boxwidth for instance.
In more simple way:
$('.boxbtn').on('click', function () {
var boxwidth = $('.box').width(); //Not sure why you want this
console.log(boxwidth);
console.log('-'+boxwidth+'px');
var btnVal=$(this).text(); //get the button text
if(btnVal=="Show Stuff") //if it is show stuff
{
$(this).text('Hide Stuff'); //change its text
alert('stuff shown');
/*show stuff here*/ //do the functionality
}
else {
$(this).text('Show Stuff'); //change back to normal
alert('stuff hidden');
/*hide stuff here*/ //hide functionality
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button type="button" class="boxbtn">Show Stuff</button>
Declare state variable outside click function.
var state = 1; // Do not write inside click function scope
var state = 0; //placed on global scope
$('.boxbtn').on('click', function () {
var boxwidth = $('.box').width();
console.log(boxwidth);
console.log('-'+boxwidth+'px');
if(state == 0) {
state=1;
console.log(state);
}
else {
state = 0;
console.log(state);
}
});
Related
I want different buttons with id and a unique function for toggle, but i can set the variable.
var clicked = false;
var abcElements = document.querySelectorAll('.cellInput');
// Set their ids
for (var i = 0; i < abcElements.length; i++){
abcElements[i].id = 'target-' + i;
$("#target-"+i).click(function () {
if (!clicked) {
// do something
} else {
// do something
}
clicked = !clicked;
})
}
If you want to keep track of the click for each element, you cannot use a shared global variable. You can, however, toggle a class to keep track of state on each element.
$('.cellInput').on('click', function(e){
var $this = $(e.target);
if (!$this.hasClass('clicked')) {
$this.addClass('clicked');
// do something
} else {
$this.removeClass('clicked');
// do something
}
});
I am trying to create an event that fires some functions depending on the id of an input[type=radio]. If the Id clicked is different to maybe_evtDiag, it should call this.applySubConditionalRequired(); and this.bindUISubActions();. Why is my code not working?
var SubFormStuff = {
init: function()
this.applySubConditionalRequired();
this.bindUISubActions();
},
bindUISubActions: function() {
// when a radio or checkbox changes value, click or otherwise
$("input[type='radio'].stepThreeDiag").change(function() {
if($(this).attr("id") == "maybe_evtDiag") {
$(this).prop('checked', false);
}else{
//this is not working //
applySubConditionalRequired(this);
displaySubFormRequired(this);
}
});
},
applySubConditionalRequired: function() {
$(".require-if-subevent-active").each(function() {
var el = $(this);
// does something
});
},
displaySubFormRequired: function() {
$(".div-subevent-class").each(function() {
var el = $(this);
// does something else
});
}
};
SubFormStuff.init();
Like you did in the init(), add a reference to the object (this) to call a sibling function (not to lose the context):
bindUISubActions: function() {
var _SubFormStuff = this;
// when a radio or checkbox changes value, click or otherwise
$("input[type='radio'].stepThreeDiag").change(function() {
if($(this).attr("id") == "maybe_evtDiag") {
$(this).prop('checked', false);
} else{
_SubFormStuff.applySubConditionalRequired();
_SubFormStuff.displaySubFormRequired();
}
});
More details on scope and context in JavaScript
You should call the methods like this:
bindUISubActions: function() {
// Store the reference to the current object
var self = this;
// when a radio or checkbox changes value, click or otherwise
$("input[type='radio'].stepThreeDiag").change(function() {
if($(this).attr("id") == "maybe_evtDiag") {
$(this).prop('checked', false);
} else{
self.applySubConditionalRequired();
self.displaySubFormRequired();
}
});
}
This way you can assing to self the current scope, and use it later on any other function call in the same execution scope.
More about javascript scope
You are trying to call applySubConditionalRequired(this) and displaySubFormRequired(this) in the wrong context you should get applySubConditionalRequired and displaySubFormRequired are not defined.
Try this:
bindUISubActions: function() {
// when a radio or checkbox changes value, click or otherwise
var that = this;
$("input[type='radio'].stepThreeDiag").change(function() {
if($(this).attr("id") == "maybe_evtDiag") {
$(this).prop('checked', false);
}else{
//it should work now //
that.applySubConditionalRequired(this);
that.displaySubFormRequired(this);
}
});
},
I'm learning JS and JQuery at the moment and I am making a drawing game, now I need to be able to reset the game.
The user gets prompted at the beginning and selects grid size. Now when I reset, the user gets asked again but I cannot find a way to remove my existing cells properly.
I think maybe it is to do with how I'm organising my functions?
Any help would be amazing, I put two of my options in there at the bottom of the script.
Thanks in advance
http://codepen.io/Middi/pen/rrgqOv
$(document).ready(function() {
createGrid();
});
function createGrid() {
// if('.cell'.length > 0) {
//
// $(.cell).remove()
//
// }
var boxes = prompt("select a grid between 2 - 128?","0");
var x = parseInt(boxes);
if(x > 128) {
alert("must be between 1-128");
}
else {
}
for(elementCount = 0; elementCount < x; elementCount++) {
$('#container').append('<div class="col"></div>');
}
for(columnCount = 0; columnCount < x; columnCount++) {
$('.col').append('<div class="cell"></div>');
$(".cell").width(572/x);
$(".cell").height(572/x);
}
$('.cell').mouseenter(function () {
$(this).addClass('highlight');
});
}
function clearButton() {
$(".cell").removeClass('highlight');
}
// --------- OPTION ONE ---------- //
// function resetButton() {
// $('#container').remove('.cell');
// }
// -------- OPTION TWO ---------- //
function resetButton() {
createGrid();
}
Try remove all .cell
//like $('#container').empty()
function removeCell() {
$('#container').empty()
}
function resetButton() {
removeCell();
createGrid();
}
Your resetButton only creates new grid, meaning it redimensionates your existing grid... if you want it to clear it before resizing, you can invoke the clearButton() function before resizing.
function resetButton() {
clearButton();
createGrid();
}
I tested in your example and it did the trick!
Was that what you wanted?
I have this code:
$("#open").click(function()
{
var pos = $(window).scrollTop();
/* the next lines of code affects the value
* of 'pos'.
*/
});
$("#close").click(function()
{
var pos = /* what i want here is the $(window).scrollTop();
before the #open event handler changes it's value. */
//another code of mine.
});
Can anyone help me with this? Thanks in advance.
it's very simple, make variable global
var pos; //global variable
$("#open").click(function()
{
pos = $(window).scrollTop();
/* the next lines of code affects the value
* of 'pos'.
*/
});
$("#close").click(function()
{
// use pos here accordingly
//another code of mine.
});
You can store the original window DOM contents before you call any functions:
var pos;
$("#open").click(function(){
pos = $(window).scrollTop();
});
$("#close").click(function(){
$(window).height(pos);
});
Docs
http://api.jquery.com/scrollTop/
http://api.jquery.com/height/
You could just organize a little your code and do this:
function MyApp(){
var self = this;
this.pos = "";
this.temp = $(window).scrollTop(); //store initial value
this.wire = function(){
$("#open").click(self.open);
$("#close").click(self.close);
}
this.open = function(){
self.pos = $(window).scrollTop();
/* the next lines of code affects the value
* of 'pos'.
*/
}
this.close = function(){
self.pos = /* what i want here is the $(window).scrollTop(); before
* the #open event handler changes it's value.
*/
//another code of mine.
var original = self.temp; //here get the initial stored value
}
}
Example:
<script type="text/javascript">
$(function() {
var app = new MyApp();
app.wire(); //wire handlers
});
</script>
I'd use a variable local to an anonymous function:
(function() {
var context = {};
$('#open').click(function() {
context.pos = $(window).scrollTop();
});
$('#close').click(function() {
// Do something with context.pos
});
})();
Your code and explanation don't make this clear, but the above maintains an assumption from your code: That close cannot be clicked unless open has been clicked, and open cannot be clicked again until close has been clicked. But that really depends on your code - if that assumption isn't true I'd approach it differently (if that assumption isn't true, clicking close here risks getting an undefined).
More safe way.
$("#open").click(function() {
$("#close").attr("data-pop", $(window).scrollTop());
});
$("#close").click(function() {
var pos = $(this).attr("data-pop");
});
I'm new to javascript so i'm not exactly sure how I can do this. Basically, in my website I have a kind of tooltip, that displays when hovering over certain input boxes.
This is my javascript:
function showTip () {
firstnameTip.style.display = "inline";
}
function hideTip () {
firstnameTip.style.display = "none";
}
/* link HTML elements to corresponding event function */
function init () {
/* link the variables to the HTML elements */
firstnameTip = document.getElementById("firstnameTip");
firstname = document.getElementById("firstname");
/* assigns functions to corresponding events */
firstname.onmouseover = showTip; /* for mouse */
firstname.onmouseout = hideTip;
firstname.onfocus = showTip; /* for cursor on input field */
firstname.onblur = hideTip; /* for cursor moving out */
}
/* execute the initialisation function once the window*/
window.onload = init;
Basically the functionality i would like is to if i hover over "firstname", it displays the firstnameTip, and so on for other things like lastname (lastnameTip), etc.
Simple question but I've tried many things and can't figure it out. Anyone have any ideas? Thanks.
Here's how I'd set it up:
function showTip (tipElement) {
return function () {
tipElement.style.display = "inline";
};
}
function hideTip (element, tipElement) {
return function () {
if (document.activeElement !== element) {
tipElement.style.display = "none";
}
};
}
function init() {
initTipEvents("firstname", "firstnameTip");
initTipEvents("lastname", "lastnameTip");
}
function initTipEvents(elementId, tipId) {
var el = document.getElementById(elementId),
tip = document.getElementById(tipId),
showHandler = showTip(tip),
hideHandler = hideTip(el, tip);
el.onmouseover = showHandler;
el.onfocus = showHandler;
el.onmouseout = hideHandler;
el.onblur = hideHandler;
}
window.onload = init;
DEMO: http://jsfiddle.net/LX2Cb/
The initTipEvents binds all necessary events, based on an element's id and its tip's id, reusing the modified showTip and hideTip functions. I added an extra check to the hideTip function to make sure that the tip isn't hidden when the mouse leaves the input, yet its still focused.
And whats the problem? Works like a charm:
var firstnameTip;
var firstname;
function showTip () {
firstnameTip.style.display = "inline";
}
function hideTip () {
firstnameTip.style.display = "none";
}
/* link HTML elements to corresponding event function */
function init () {
/* link the variables to the HTML elements */
firstnameTip = document.getElementById("firstnameTip");
firstname = document.getElementById("firstname");
/* assigns functions to corresponding events */
firstname.onmouseover = showTip; /* for mouse */
firstname.onmouseout = hideTip;
firstname.onfocus = showTip; /* for cursor on input field */
firstname.onblur = hideTip; /* for cursor moving out */
}
/* execute the initialisation function once the window*/
init();
http://jsfiddle.net/6QvXT/
ok, to have that more generic, you should use the event parameter passed to the handler and the retrieve the target object out of that like:
var getTarget = function (event)
{
var ttn = null;
if (!event)
event = window.event;
else if (event.target)
ttn = event.target;
else if (event.srcElement)
ttn = event.srcElement;
var tipId = ttn.id + "Tip";
ttn = document.getElementById(tipId);
return ttn;
}
and then:
function showTip (evt) {
var ttn = getTarget(evt);
ttn.style.display = "inline";
}
function hideTip (evt) {
var ttn = getTarget(evt);
ttn.style.display = "none";
}
furthermore:
function init () {
/* for all relevant elements */
for ( .... ) // iterate through a list or the dom
{
var theElement = ....(); // get the element
/* assigns functions to corresponding events */
theElement.onmouseover = showTip; /* for mouse */
theElement.onmouseout = hideTip;
theElement.onfocus = showTip; /* for cursor on input field */
theElement.onblur = hideTip; /* for cursor moving out */
}
}
/* execute the initialisation function once the window*/
init();
hope that helps.