Re-run javascript code when the value changes - javascript

I have two files: a html file (with the code below) and a javascript file (it creates a value for the <span id="quantity">) The code works fine, but the word only changes if I refresh the whole page.
I want the word to change from 'articles' to 'article' or vice versa as soon as the 'quantity' changes. Is this possible? And if so, how?
<span id="quantity" class="simpleCart_quantity"></span>
<span id="quantityText"></span>
<script type="text/javascript">
$(window).load(function()
{
var quantity = document.getElementById("quantity"),
quantityText = document.getElementById("quantityText");
if (parseInt(quantity.innerHTML, 10) === 1) {
quantityText.innerHTML = "article";
} else {
quantityText.innerHTML = "articles";
}
});
</script>

You might want to look into MVVC framework like Knockout JS. For example, you would set the contents of the #quantity <span></span> element to be an observable.
However, try reading this SO thread to find a solution similar to what you probably are hoping for. In summary, change events only occur from the browser on the blurring of form fields, so you'll need to implement a $("#quantity").trigger('change')
Once you have a trigger set-up after the DOM element has been loaded, you can do the following:
$('#myParentNode').on('change','#mynum', function() {
// Add your logic in here
$('#quantityText').text('articles') .... .. .. .....
});

Normally, the span element doesn't fire a change event, so you cannot subscribe to it, like you would normally do in an input element.
However, you can trigger such an event using jQuery in the same code, which changes the value of the span (I assume there is such code, because normally spans don't change value).
Here is an example which simulates this change every 10 seconds, and triggers the change event. It also includes a handler for that change event, which duplicates the value in the other span.
<span id="quantity" class="simpleCart_quantity">1</span>
<span id="quantityText"></span>
<script src="http://code.jquery.com/jquery-1.10.1.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
var quantity = $("#quantity"),
quantityText = $("#quantityText");
setInterval(function() {
var currentVal = parseInt(quantity.html());
if (currentVal >= 10) {
quantity.html(1);
}
else {
quantity.html(currentVal + 1);
}
quantity.trigger('change');
}, 10000);
quantity.on('change', function(sender, args) {
quantityText.html($(this).html());
});
});
</script>

Related

How to set on change as a default on page load jquery?

I have created a on change method for a select box of my project. On selecting particular option it is basically showing and hiding a div which is perfectly working fine. Now, my problem is when first time page is loading this show and hide not working for first default section of form. Can I make this onchange function also working when page load first time.
$('.contact-form').on('change', (e) => {
var selectedId = $(e.currentTarget).val();
var listofforms = $("#discount").data("display-for").split(",");
if (listofforms.indexOf(selectedId) !== -1) {
$("#discount").collapse('show');
}
else {
$("#discount").collapse('hide');
}
});
Here you go with a solution
function changeMethod(selectedId) {
var listofforms = $("#discount").data("display-for").split(",");
if (listofforms.indexOf(selectedId) !== -1) {
$("#discount").collapse('show');
}
else {
$("#discount").collapse('hide');
}
}
changeMethod($('.contact-form').val())
$('.contact-form').on('change', (e) => {
changeMethod($(e.currentTarget).val());
});
You need to move your code outside the change event, so I have kept your existing code within a method changeMethod.
Then call the method from to places
From you change event method
OnLoad of the JS file
Is it possible can I make my on change trigger on page load
Yes, you will just need to change your on change event from e.currentTarget to this as on page load e.currentTarget will be null, but this always points to the current element like:
$('.contact-form').on('change', function() {
var selectedId = $(this).val();
// Your other logic here
});
and to trigger this change event on page load, simply add .change() at last like:
$('.contact-form').on('change', function() {
var selectedId = $(this).val();
// Your other logic here
}).change(); //<---- here

How can I observe changes to my DOM and react to them with jQuery?

I have this function where I toggle a class on click, but also append HTML to an element, still based on that click.
The problem is that now, I'm not listening to any DOM changes at all, so, once I do my first click, yup, my content will be added, but if I click once again - the content gets added again, because as far as this instance of jQuery is aware, the element is not there.
Here's my code:
(function($) {
"use strict";
var closePluginsList = $('#go-back-to-setup-all');
var wrapper = $('.dynamic-container');
$('#install-selected-plugins, #go-back-to-setup-all').on('click', function(event) {
$('.setup-theme-container').toggleClass('plugins-list-enabled');
if ( !wrapper.has('.plugins-container') ){
var markup = generate_plugins_list_markup();
wrapper.append(markup);
} else {
$('.plugins-container').hide();
}
});
//Below here, there's a lot of code that gets put into the markup variable. It's just generating the HTML I'm adding.
})(jQuery);
Someone suggested using data attributes, but I've no idea how to make them work in this situation.
Any ideas?
You could just do something like adding a flag and check for it before adding your markup.
var flag = 0;
$('#install-selected-plugins, #go-back-to-setup-all').on('click', function(event) {
$('.setup-theme-container').toggleClass('plugins-list-enabled');
if ( !wrapper.has('.plugins-container') ){
var markup = generate_plugins_list_markup();
if(flag == 0){
wrapper.append(markup);
flag = 1;
}
} else {
$('.plugins-container').hide();
}
});
If you want to add element once only on click then you should make use of .one() and put logic you want to execute once only in that handler.
Example :
$(document).ready(function(){
$("p").one("click", function(){
//this will get execute once only
$(this).animate({fontSize: "+=6px"});
});
$("p").on("click", function(){
//this get execute multiple times
alert('test');
});
});
html
<p>Click any p element to increase its text size. The event will only trigger once for each p element.</p>

How do I detect when a div has lost focus?

Given the following markup, I want to detect when an editor has lost focus:
<div class="editor">
<input type="text"/>
<input type="text"/>
</div>
<div class="editor">
<input type="text"/>
<input type="text"/>
</div>
<button>GO</button>
EDIT: As the user tabs through the input elements and as each editor div loses focus (meaning they tabbed outside the div) add the loading class to the div that lost focus.
This bit of jquery is what I expected to work, but it does nothing:
$(".editor")
.blur(function(){
$(this).addClass("loading");
});
This seems to work, until you add the console log and realize it is triggering on every focusout of the inputs.
$('div.editor input').focus( function() {
$(this).parent()
.addClass("focused")
.focusout(function() {
console.log('focusout');
$(this).removeClass("focused")
.addClass("loading");
});
});
Here is a jsfiddle of my test case that I have been working on. I know I am missing something fundamental here. Can some one enlighten me?
EDIT: After some of the comments below, I have this almost working the way I want it. The problem now is detecting when focus changes to somewhere outside an editor div. Here is my current implementation:
function loadData() {
console.log('loading data for editor ' + $(this).attr('id'));
var $editor = $(this).removeClass('loaded')
.addClass('loading');
$.post('/echo/json/', {
delay: 2
})
.done(function () {
$editor.removeClass('loading')
.addClass('loaded');
});
}
$('div.editor input').on('focusin', function () {
console.log('focus changed');
$editor = $(this).closest('.editor');
console.log('current editor is ' + $editor.attr('id'));
if (!$editor.hasClass('focused')) {
console.log('switched editors');
$('.editor.focused')
.removeClass('focused')
.each(loadData);
$editor.addClass('focused');
}
})
A bit more complicated, and using classes for state. I have also added in the next bit of complexity which is to make an async call out when an editor loses focus. Here a my jsfiddle of my current work.
If you wish to treat entry and exit of the pairs of inputs as if they were combined into a single control, you need to see if the element gaining focus is in the same editor. You can do this be delaying the check by one cycle using a setTimeout of 0 (which waits until all current tasks have completed).
$('div.editor input').focusout(function () {
var $editor = $(this).closest('.editor');
// wait for the new element to be focused
setTimeout(function () {
// See if the new focused element is in the editor
if ($.contains($editor[0], document.activeElement)) {
$editor.addClass("focused").removeClass("loading");
}
else
{
$editor.removeClass("focused").addClass("loading");
}
}, 1);
});
JSFiddle: http://jsfiddle.net/TrueBlueAussie/8s8ayv52/18/
To complete the puzzle (get your initial green state) you will also need to also catch the focusin event and see if it is coming from the same editor or not (save the previous focused element in a global etc).
Side note: I recently had to write a jQuery plugin that did all this for groups of elements. It generates custom groupfocus and groupblur events to make the rest of the code easier to work with.
Update 1: http://jsfiddle.net/TrueBlueAussie/0y2dvxpf/4/
Based on your new example, you can catch the focusin repeatedly without damage, so tracking the previous focus is not necessary after all. Using my previous setTimeout example resolves the problem you have with clicking outside the divs.
$('div.editor input').focusin(function(){
var $editor = $(this).closest('.editor');
$editor.addClass("focused").removeClass("loading");
}).focusout(function () {
var $editor = $(this).closest('.editor');
// wait for the new element to be focused
setTimeout(function () {
// See if the new focused element is in the editor
if (!$.contains($editor[0], document.activeElement)) {
$editor.removeClass("focused").each(loadData);
}
}, 0);
});
Here's what worked for me:
$(".editor").on("focusout", function() {
var $this = $(this);
setTimeout(function() {
$this.toggleClass("loading", !($this.find(":focus").length));
}, 0);
});
Example:
http://jsfiddle.net/Meligy/Lxm6720k/
I think you can do this. this is an exemple I did. Check it out:
http://jsfiddle.net/igoralves1/j9soL21x/
$( "#divTest" ).focusout(function() {
alert("focusout");
});

Jquery change variable on click

Right, what I'd like to happen is when a button (or in this case, some text) is pressed, Jquery shows a div tag that contains an image, fades out the image after 2 seconds then displays some text.
This all works nicely, however I only want it to work once.
I decided to do this by using a variable and an if statement, so the variable changes from 0 to 1 and then the button cannot be clicked again due to the variable being changed.
Or at least, that's the badly worded version.
Anyhow, this is what I have so far, but for some reason the variable won't change from 0 to 1 after the button has been clicked, other than that, it works well.
The JS:
$(document).ready(function(){
$("#text2").css("display","none");
$("#ltt").css("display","none");
var clicked = '0';
if(clicked == 0) {
$(".clicker").click(function() {
$("#ltt").fadeIn("slow");
$('#ltt').delay(2000).fadeOut('slow');
$("#text2").delay(3000).fadeIn(1000);
$clicked = '1';
});
}
});
The HTML:
<div class="clicker">
click to see text
</div>
<div id="ltt">
<img src="Images/LoadingCircle.gif" width="24" height="24">
</div>
<div id="text2">
SOME TEXT
</div>
Try to use .one() in this context,
$(".clicker").one('click', function() {
$("#ltt").fadeIn("slow");
$('#ltt').delay(2000).fadeOut('slow');
$("#text2").delay(3000).fadeIn(1000);
});
You should use .one() instead:
Attach a handler to an event for the elements. The handler is executed at most once per element per event type.
$(".clicker").one('click',function() {
$("#ltt").fadeIn("slow");
$('#ltt').delay(2000).fadeOut('slow');
$("#text2").delay(3000).fadeIn(1000);
$clicked = '1';
});
You declared the variable to
var clicked = '0';
but calling
$clicked = '1';
later on, so your variable will not be found.
Other than in PHP you don't need the Dollar $ to declare a variable, it's just a simple typo :)
well this should work :)
$(document).ready(function(){
$("#text2").css("display","none");
$("#ltt").css("display","none");
window.clicked = false;
$(".clicker").click(function() {
if(!window.clicked){
$("#ltt").fadeIn("slow");
$('#ltt').delay(2000).fadeOut('slow');
$("#text2").delay(3000).fadeIn(1000);
window.clicked = true;
}
});
});

how to hide submenu after click

I'm creating a dropdown menu for mobile site
http://gthost.dyndns.org/kudu/en/
when I click on My Account and click on Who we are, submenu still show,,
I Want to hide it after I click on the link.
this is JavaScript code
var $j = jQuery.noConflict();
$j(document).ready(function () {
$j(".account").click(function () {
var X = $j(this).attr('id');
if (X == 1) {
$j(".submenu").hide();
$j(this).attr('id', '0');
} else {
$j(".submenu").show();
$j(this).attr('id', '1');
}
});
//Mouseup textarea false
$j(".submenu").mouseup(function () {
return false
});
$j(".account").mouseup(function () {
return false
});
//Textarea without editing.
$j(document).mouseup(function () {
$j(".submenu").hide();
$j(".account").attr('id', '');
});
});
i would try using:
$('.submenu').css({display:"none"});
instead of .hide();
Two things strike me as odd here.
Why are your ID's integers - valid names start with [a-z_] etc.
Why are you changing the ID? An ID is meant to be a unique identifier and should persist as long as the element does. If you wish to store information about the state of an element within the element itself, then perhaps look into data attributes.
Without seeing your HTML structure everyone is going to be guessing but rather than whatever you are trying to do with the ID's it looks like you could logically use jQuery.toggle:
$j(".account").click(function(){
$j(".submenu").toggle();
});

Categories