Perform Jquery function on multiple divs without user event - javascript

I've got a variable called "widthz" that determines the css width for .progress
Each instance of "widthz" is unique since it's determined from the contents other "brother" divs to .progress. Right now, my function works perfectly but only if you click on .item. I want this action to take place for every instance of .progress without a user event such as a click.
Current code:
$(document).ready(function() {
$( ".budgets .item" ).click(function() {
var limitz = $(this).children('.limit').html();
var spentz = $(this).children('.spent').html();
var widthz = spentz / limitz * 100 ;
$(this).find('.progress').css('width', widthz + '%');
});
});

Replace the event handler with each to iterate over all of them and keep the this reference
$(document).ready(function() {
$( ".budgets .item" ).each(function() {
var limitz = $(this).children('.limit').html();
var spentz = $(this).children('.spent').html();
var widthz = spentz / limitz * 100 ;
$(this).find('.progress').css('width', widthz + '%');
});
});

Related

Multiple Functions with one Code

so I'm using this code, to slideToggle a box on my webpage.
// OPEN CERTAIN BOX
$(function() {
var sliding = false;
var mq = window.matchMedia( "(min-width: 700px)" );
if (mq.matches) {
var time = 500;
} else {
var time = 0;
}
var id = ('1');
var div = ('#toggle-content-' + id);
var img = ('#toggle-img-' + id);
var toggler = ('toggler-' + id);
$(div).hide()
$(toggler).click(function() {
if (sliding == false) {
sliding = true;
// Open / Close
$( div ).slideToggle(time,"swing");
// ...
As you can see, I'm using the var id, to use the toggle function for a certain box, which has its own css and html code.
I have 7 more boxes. Until now, i copied the code 7 times and changed the id at each copy from 2 - 8. Is there a way to make it with one code?
I tried a for loop, that goes from 1 - 8 but this obviously didnt work.
Has someone an idea? Or do I have to make that 8 copies and changed the id.
Edit:
My approach with the for-loop:
$(function() {
var sliding = false;
var mq = window.matchMedia( "(min-width: 700px)" );
if (mq.matches) {
var time = 500;
} else {
var time = 0;
}
for(i = 1; i <= 8; i++){
var id = (i.toString());
var div = ('#toggle-content-'+id);
var img = ('#toggle-img-'+id);
var toggler = ('toggler-'+id);
$( div ).hide()
$( toggler ).click(function(){
if (sliding == false){
sliding = true;
// Open / Close
$( div ).slideToggle(time,"swing");
...
And this is my html code for one box:
<tr><td cellspacing="0" cellpadding="0" height="50px" class="upper">
<toggler-1><area-head-text><img id="toggle-img-1" src="images/box_opener.png"/>Starterpaket</area-head-text></toggler-1>
</td></tr>
<tr><td>
<div id="toggle-content-1">
<area-head-text>
<img class="text-image" src="images/arrow.png"/>3 individuelle Entwürfe<br>
<img class="text-image" src="images/arrow.png"/>3 Korrekturzeichnungen<br>
<img class="text-image" src="images/arrow.png"/>Internationale Nutzungsrechte<br>
<img class="text-image" src="images/arrow.png"/>400€<br><br>
</area-head-text>
</div>
</td></tr>
I'm not sure why you put "Obviously" a loop doesn't work, because that's pretty much exactly what you should do. Something like this:
for(var i = 1; i <= 8; i++)
{
var div = $('#toggle-content-' + i);
var img = $('#toggle-img-' + i);
var toggler = $('toggler-' + i);
$(div).hide()
$(toggler).click(function() {
if (sliding == false) {
sliding = true;
// Open / Close
$( div ).slideToggle(time,"swing");
// ...
}
This is 2 options.
(and my preference) -
Instead of using an ID to add the click event onto each individual toggle button, use the same class on each, and add the click event on that class. When the user clicks a toggle button traverse the DOM from the clicked toggle button to perform your toggle on the relevant <div>.
This would look something like:
$(function() {
$('.toggleBtn').click(function() {
var sliding = $(this).data('sliding'); //use data attr to store sliding status
if (sliding == false) {
$(this).data('sliding') = true;
}else {
return; //don't toggle we're sliding
}
// navigate to element and toggle
$(this).parent('.someParentElement').children('.theDiv').slideToggle(time,"swing");
//clear sliding status
$(this).data('sliding', false);
}
}
The reason this is my preference, is because although it's faster to target an ID for a click event than a class for a single event, using 7 click events on 7 different IDS in my opinion (I don't know for sure) is less efficient than using a single click event on 1 class. That's my perceived purpose of using events on classes rather than IDS.
Also this way, when you want to add another box in, or remove a box, you don't need to modify any Javascript, the only thing you would need to maintain this code for is if you decide to change the structure of the HTML, and therefore the navigation of the DOM to perform your toggle.
using your method:
var ids = ["id1","id2","id3"];
for(var id in ids) {
var $div = $('#toggle-content-' + id);
var $img = $('#toggle-img-' + id);
var $toggler = $('toggler-' + id);
$div.hide()
$toggler.click(function() {
if (sliding == false) {
sliding = true;
// Open / Close
$div.slideToggle(time,"swing");
// ...
}

how to progress bar based on count entered in field using jQuery

I have a simple form has two field with ids = "q9" , "q10" and one button named post , i put total number in "#q9", I am trying to code a progress bar that will be updated based on the count entered in "#q10" when user click post button. https://jsfiddle.net/v756hkd2/10/
//jquery Code
$(document).ready(function(){
$(".postbtn").click(function(){
var curStatus = $('#q9 input').val();;
var startCount = $('#q10 input').val();
$("#q9 input").change(function(){
var progress = (curStatus / startCount) * 100;
$("#myBar").width(progress);
});
});
});
I think the problem is that you use change event listener in the click event listener.
Code is waiting for the #q9 input to change, but I guess you have already set it and you just need to use it.
Maybe something like this would work?
$(document).ready(function(){
$(".postbtn").on('click', function() {
var progress = ($('#q9').val() / $('#q10').val()) * 100;
$("#myBar").width(progress);
});
});
EDIT:
I am not sure if I understood correctly. But it seemed like you fill change the #q9 input value automatically after post.
So I made a solution based on that this input value will change automatically and the change event will occur.
$(document).ready(function(){
$(".postbtn").on('click', function() {
// this is because after click the first label would appear
var currentCount = $('#q9').val();
var progress = (currentCount / $('#q10').val()) * 100;
$("#myBar").width(progress + '%');
$("#label").text(progress + '%');
// then you start to listen the change of the current count input
$('#q9').on('change', function(e) {
currentCount = $(e.target).val();
progress = (currentCount / $('#q10').val()) * 100;
// and change it accordingly
$("#myBar").width(progress + '%');
$("#label").text(progress + '%');
});
});
});
A few notes:
1) $('#q9 input') won't work because it thinks that element with id #q9 has a child input, so I used $('#q9'), or you can use, like someone noted $('input#q9')
2) You can also use methods .change or .click. I just prefer using .on. :)
EDIT: I changed a bit the solution again. And added jsfiddle. It should work now - https://jsfiddle.net/v756hkd2/11/
And more beautiful code would be
$(document).ready(function(){
$(".postbtn").on('click', function() {
// this is because after click the first label would appear
changePercentage($('#q9').val());
// then you start to listen the change of the current count input
$('#q9').on('change', function(e) {
changePercentage($(e.target).val());
});
});
// then there won't be repeated code ;)
function changePercentage(currentCount) {
var progress = (currentCount / $('#q10').val()) * 100;
$("#myBar").width(progress + '%');
$("#label").text(progress + '%');
}
});
You don't need to listen to input's change event, if you want to update progress when pressing Post button. It's easier to listen to Post button click. Also values inside inputs are strings, so you have to convert them to numbers before calculation.
function getInputValue(selector) {
var str = $(selector).val();
return parseInt(str, 10);
}
function updateProgress() {
var total = getInputValue('#q10');
var current = getInputValue('#q9');
var progress = (current / total) * 100;
//if you want to limit number of digits after decimal point
//progress = progress.toFixed(2);
$("#myBar").css("width", progress + "%");
$("#label").text(progress + "%");
}
$(function() {
$(".postbtn").click(updateProgress);
updateProgress();//if you want to render outside of click handler, for example after page load.
});
https://jsfiddle.net/yevt/ne1k7w03/2/

How to clone and place two different items in jquery in the respective positions

I have a div and a button to close that div. I am cloning them both separately and assigning a unique incrementing id to both. Everything is working in that the cloning happens and the button closes the Div.
I have a problem though regarding the placement of the button. I want the button to always be in the same position with reference to its cloned div. Any ideas how to do this?
HTML
X
<div id="id"></div>
Add
Javascript
function duplicateDiv(){
$('#btn').clone().attr('id', 'btn'+ cloneCount2++).insertBefore($('[id^=id]:first'));
$('#id').clone().attr('id', 'id'+ cloneCount++).insertAfter($('[id^=id]:first'));
//clearing the input items in the new cloned div
$("#id").find("input").val("");
}
function hideDiv(obj){
var currentId = $(obj).attr('id');
var divId = currentId.replace("btn", "id");
$("#"+divId).hide();
$("#"+currentId).hide();
}
If interpret Question correctly , try using .appendTo() , .insertAfter($("#btn" + cloneCount))
var cloneCount = 0, cloneCount2 = 0;
function duplicateDiv() {
//the close button
$("#btn")
.clone().attr("id", function(_, id) {
return id + (++cloneCount2)
})
.appendTo("body")
$("#id")
.clone().attr("id", function(_, id) {
return id + (++cloneCount)
})
.insertAfter($("#btn" + cloneCount))
//clearing the input items in the new cloned div
$("#id").find("input").val("");
}
function hideDiv(obj) {
var currentId = $(obj).attr('id');
var divId = currentId.replace("btn", "id");
$("#" + divId).hide();
$("#" + currentId).hide();
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
</script>
X
<div id="id">div</div>
Add
One of the way is Jquery Offset
var destination = $('.original-content').offset(); // get position of original
$('.original-content').hide(); // hide original
$('.cloned-content').css({top: destination.top, left: destination.left}); // set position of cloned

Giving specific css with jquery for each instance of div depending on text height

I have a grid with several boxes (280px by 280px)and I need to vertical align text enclosed on hover overlays.
My code is working for first element but txt lenght/height varies on each box and I need a function that assigns top padding depending on specific p height.
I believe I can use .each , but I wasn't able to implement it successfully.
Here is my working code that I need to modify to target each box individually:
var txtHeight = $( ".login-item .lgn-overlay p" ).height();
var topPadding = ((284 - txtHeight) / 2);
$('.login-item .lgn-overlay').css('padding-top', topPadding);
$('.login-item .lgn-overlay').each(function(){
var $this = $(this);
$this.css('padding-top', function(){
return ((284 - $this.find("p").height()) / 2);
});
});
Try if this works. I made this on plan page so correct if any error in the code
Try something like this
//determine this programmatically
var necessaryHeight = 200;
$('.login-item .lgn-overlay').each(function () {
//this = each individual element
//$this = a jQuery wrapper for the given element.
var $this = $(this);
//The rest I think you understand
var thisHeight = $this.outerHeight();
var missingHeight = necessaryHeight - thisHeight;
var addedPadding = missingHeight / 2;
$this.css('padding-top', addedPadding);
});

Warning: Unresponsive Script error?

Hey, my script seems to be getting this warning message whenever I run it.
This happens when I call a jquery function in the script. I have included the script below and put - Warning: Unresponsive Script - comment where I called the function. I don't really know why I'm getting the warning message.
Here is the project Im working on, if you want to see it Click Here
I am trying to update the pagination numbers when filter options are selected. So when you select the color 'yellow' you get one result, which is 'giant' and there should only be 1 page number displayed as opposed to the 4.
If anyone has any ideas to get this working properly that would be amazing. Thanks.
JQuery Script:
<script>
$(document).ready(function(){
function paginateIt(){
//how much items per page to show
var show_per_page = 3;
//getting the amount of elements inside content div
var number_of_items = $('#content ul').filter(":not(.hidden)").children().size();
//calculate the number of pages we are going to have
var number_of_pages = Math.ceil(number_of_items/show_per_page);
//set the value of our hidden input fields
$('#current_page').val(0);
$('#show_per_page').val(show_per_page);
//now when we got all we need for the navigation let's make it '
/*
what are we going to have in the navigation?
- link to previous page
- links to specific pages
- link to next page
*/
var navigation_html = '<a class="previous_link" href="javascript:previous();">Prev</a>';
var current_link = 0;
while(number_of_pages > current_link){
navigation_html += '<a class="page_link" href="javascript:go_to_page(' + current_link +')" longdesc="' + current_link +'">'+ (current_link + 1) +'</a>';
current_link++;
}
navigation_html += '<a class="next_link" href="javascript:next();">Next</a>';
$('#page_navigation').html(navigation_html);
//add active_page class to the first page link
$('#page_navigation .page_link:first').addClass('active_page');
//hide all the elements inside content div
$('#content ul').filter(":not(.hidden)").children().css('display', 'none');
//and show the first n (show_per_page) elements
$('#content ul').filter(":not(.hidden)").children().slice(0, show_per_page).css('display', 'block');
// Start filter script
(function($) {
$.fn.randomize = function(){
return $(this).sort(function() {return 0.5 - Math.random()});
}
$.fn.filterprojects = function(settings) {
settings = $.extend({
animationSpeed: 900,
animationPulse: 100,
animationEase: "linear",
activeClass: "active",
allTag: "all",
randomize: true,
show: { width: "show", opacity: "show" },
hide: { width: "hide", opacity: "hide" },
filterTagSelector: [] // specify at least one
}, settings);
$(this).each(function(i, o){
var _elements = $(this).children();
/* Binding the filter */
$(this).bind("filter", function(){
var _groups = [];
var _filtered_elements = _elements;
$.each(settings.filterTagSelector, function(k, j){
_groups[k] = [];
$(this + "." + settings.activeClass).each(function(){
if(!$(this).hasClass(settings.allTag) && this.hash != undefined) { _groups[k].push(this.hash.substring(1)); }
});
if(_groups[k].length > 0){
_filtered_elements = _filtered_elements.filter("." + _groups[k].join(",."));
}
});
/* Randomize */
if(settings.randomize){
_filtered_elements = _filtered_elements.randomize();
_elements = _elements.randomize();
}
/* Show */
_filtered_elements.each(function(i,o){
$(this).queue(function(){
$(this).animate({left: "+0"}, (settings.animationPulse*i)); // dirty trick :)
$(this).animate(settings.show, settings.animationSpeed);
$(this).dequeue()
});
});
/* Hide */
_elements.not(_filtered_elements).each(function(i,o){
$(this).queue(function(){
$(this).animate({left: "+0"}, (settings.animationPulse*i)); // dirty trick :)
$(this).animate(settings.hide, settings.animationSpeed);
$(this).dequeue()
});
});
});
/* Setup filter selectors */
$.each(settings.filterTagSelector, function(k, j){
$(""+this).click(function(e){
e.preventDefault();
if($(this).hasClass(settings.allTag)){
$(j).removeClass(settings.activeClass);
$(this).addClass(settings.activeClass);
} else {
$(this).hasClass(settings.activeClass) ? $(this).removeClass(settings.activeClass) : $(this).addClass(settings.activeClass);
$(j+"."+settings.activeClass).length > 0 ? $(j+"."+settings.allTag).removeClass(settings.activeClass) : $(j+"."+settings.allTag).addClass(settings.activeClass);
}
/* Triggering the filter */
$(o).trigger("filter");
})
});
});
return this
};
// Warning: Unresponsive Script
paginateIt();
})(jQuery); // End filter script
} // End PaginateIt script
paginateIt();
}); // End of JS script.
function previous(){
new_page = parseInt($('#current_page').val()) - 1;
//if there is an item before the current active link run the function
if($('.active_page').prev('.page_link').length==true){
go_to_page(new_page);
}
}
function next(){
new_page = parseInt($('#current_page').val()) + 1;
//if there is an item after the current active link run the function
if($('.active_page').next('.page_link').length==true){
go_to_page(new_page);
}
}
function go_to_page(page_num){
//get the number of items shown per page
var show_per_page = parseInt($('#show_per_page').val());
//get the element number where to start the slice from
start_from = page_num * show_per_page;
//get the element number where to end the slice
end_on = start_from + show_per_page;
//hide all children elements of content div, get specific items and show them
$('#content ul').filter(":not(.hidden)").children().css('display', 'none').slice(start_from, end_on).css('display', 'block');
/*get the page link that has longdesc attribute of the current page and add active_page class to it
and remove that class from previously active page link*/
$('.page_link[longdesc=' + page_num +']').addClass('active_page').siblings('.active_page').removeClass('active_page');
//update the current page input field
$('#current_page').val(page_num);
}
</script>
Unresponsive Script Fix
It looks like you're just calling paginateIt recursively. The paginateIt function does a bunch of work and then calls itself again, infinitely.
To fix this, remove the call to paginateIt() just below your comment "Warning: Unresponsive Script" comment.
Here's the simplified structure of your code so that you can see the problem more clearly:
function paginateIt(){
// Start filter script
(function($) {
$.fn.filterprojects = function(settings) {
$(this).each(function(i, o){
/* Binding the filter */
/* Setup filter selectors */
});
};
// Warning: Unresponsive Script
paginateIt();
})(jQuery); // End filter script
} // End PaginateIt script
paginateIt();
Re-pagination Fix
I would have written this line of code:
//getting the amount of elements inside content div
var number_of_items = $('#content ul').filter(":not(.hidden)").children().size();
as this:
var number_of_items = $('#content ul').children().filter(":visible").length;
Also, you'll want to call paginateIt after the animation completes for that to work correctly. You'll probably want to do this in an animation callback, but here's a temporary workaround:
/* Triggering the filter */
$(o).trigger("filter");
setTimeout(paginateIt, 1500);

Categories

Resources