JS - looping through an array with JQuery UI dialog method - javascript

I have the following jQuery code using jQuery UI
EDIT:
$(document).ready(function(){
$('#the-link-2').click(function(){
var array = ["test1","test2","test3","test4"]
var i = 1;
while (i<array.length) {
var newDiv = $(document.createElement('div'));
$(newDiv).html(array[i]).dialog({
buttons: {
'Previous': function() {
$(this).dialog("close");
i--;
},
'Next': function() {
$(this).dialog("close");
i++;
}
}
}
});
});
});
I am trying to loop through the items of the array (starting with item #1). The dialog box displays the item and moves to the previous/next item depending on which button the user clicks. It does not work (nothing gets fired). If I remove the "while" loop I do get the dialog box with the #1 item. Could anyone give me the right syntax to obtain the desired result please? Thanks.

I created a fiddle for this and updated your script. Instead of looping them just create a recursive function that does exactly what you want:
Script :
var array = ["test1", "test2", "test3", "test4"];
$('#the-link-2').click(function() {
var current = 0; // current data to show
createDialog(array[current], current); // create the dialog for current data
});
function createDialog(data, current) {
var $div = $('<div>'); // create a new div element
// add the html content of new div by passing array[current]
// and create the corresponding dialog
$div.html(data).dialog({
buttons: {
'Previous': function() {
if (current == 0) {
// do nothing if no more prev data
// or you can add some extra function here
// like close the dialog if no more prev data
return;
} else {
current--;
}
$(this).dialog("close").remove(); // close the dialog and remove the div
createDialog(array[current], current); // call createDialog again passing new current data
},
'Next': function() {
if (current == (array.length - 1)) {
// do nothing if no more next data
// or you can add some extra function here
// like close the dialog if no more next data
return;
} else {
current++; // increment current to next data
}
$(this).dialog("close").remove(); // close the dialog and remove the div
createDialog(array[current], current); // call createDialog again passing new current data
}
}
});
}
FIDDLE : HERE

Related

jQuery cookie key value with case statement

Ok, so my code is this so far:
$( document ).ready(function() {
// setup the initial display on page load
var menu_state = $.cookie('atd_gridlist');
// listen for the clicks
$('.gridselect').click(function() {
$.cookie('atd_gridlist', 'grid'); // update (or set) the cookie
$(".grid").css("display", "block");
$(".list").css("display", "none");
});
$('.listselect').click(function() {
$.cookie('atd_gridlist', 'list'); // update (or set) the cookie
$(".grid").css("display", "none");
$(".list").css("display", "block");
});
});
I need to also check to see if the cookie KEY has already been set, I think a case statement would work but I am not sure how to make the case read just the cookie atd_gridlist key values...
If it is gridselect I need to show the grid div and hide the list div, if it is listselect I need it to show the list div and hide the grid div, if it is not set at all, I want grid div loaded by default and hide the list. I also would like to expire the div every 7 days.
Any help in the right direction is appreciated. Thanks!
Would something like this do the job?
$(function() {
var grid = $('.grid');
var list = $('.list');
var stateCookie = 'atd_gridlist';
var SetStateCookie = function(value) {
$.cookie(stateCookie, value, { expires: 7, path: '/' });
}
var ShowByState = function(state) {
state = state || 'grid';
SetStateCookie(state);
if ('grid' === state) {
grid.show();
list.hide();
} else if ('list' === state) {
grid.hide();
list.show();
}
}
$('.gridselect').click(function() {
ShowByState('grid');
});
$('.listselect').click(function() {
ShowByState('list');
});
ShowByState($.cookie(stateCookie));
});

Javascript clearInterval not clearing

I have the following JS code
$('body').on({
click: function()
{
var el = $(this);
lookUpTask(el);
el.bind('blur', function(){
timeOutTask = setInterval(function(){
if( timeOutTask )
{
clearInterval(timeOutTask);
el.trigger('remove_match');
}
}, 500);
$('body').on({
click: function(event)
{
var match = $(this);
var color = match.attr('color');
// Check color to change brightness
var brightness = hexToLuminance(color);
var text_color = '#000';
if( brightness < 128 ) {
text_color = '#fff';
}
// Change color according to brightness
el.css('color',text_color);
el.parent().parent().children('.remove').css('color',text_color);
el.parent().parent().children('.resize').css('color',text_color);
// Change the background and task name
el.parent().parent().css('background-color', color);
el.val(match.html());
// Update DB
// Remove the task_match
el.trigger('remove_match');
}
},'.match');
});
el.bind('remove_match', function(){
if( el.val == "" ) {
el.val('Select Task');
}
el.css('text-align','center');
el.parent().children('.match_results').remove();
clearInterval(timeOutTask);
});
},
keyup: function(event)
{
lookUpTask($(this));
}
},'.task_select');
What I am trying to do is when the user clicks on .task_select, then I bring up the matched results and display it on the screen. Now, the user can either select one of those options, or click outside. If outside, then the matched results should close. If one of the options is selected, then the whole code in the middle runs.
The problem is that the matched results overlays on top of another div that if it is clicked on, something else will happen. When I click on the matched results, then the code registers as clicking on the outside (so the matched selected disappears, and the effect is as though I clicked on the other div that I don't want to click on.
So my solution was to place a timer before the click on the outside is executed. It all works fine, except clearInterval does not clearout the timer!! So the second time I load something, it is as though the timer was not cleared!
WhY?!
You're overriding timeOutTask with a new interval. You can cache the intervals to an array, something like this:
var timeOutTasks = [];
$('body').on({
...
el.bind('blur', function(){
timeOutTasks.push(setInterval(function(){
clearInterval(timeOutTasks.pop());
...
}, 500);
...
}
...
}

need to modify this jquery pop menu script to work with ajax

I am using this script from: http://pop.seaofclouds.com/
The problem is if you call the script multiple times it causes a cascading effect of a pop-out within a pop-out for as many times as you call the script.
I'm trying to figure out how to prevent it from executing when the popout has already been set. Here's the script:
//
// pop! for jQuery
// v0.2 requires jQuery v1.2 or later
//
// Licensed under the MIT:
// http://www.opensource.org/licenses/mit-license.php
//
// Copyright 2007,2008 SEAOFCLOUDS [http://seaofclouds.com]
//
(function($) {
$.pop = function(options){
// inject html wrapper
function initpops (){
$(".pop").each(function() {
var pop_classes = $(this).attr("class");
if ( $(this).find('.pop_menu').length) {
// do nothing
} else {
$(this).addClass("pop_menu");
$(this).wrap("<div class='"+pop_classes+"'></div>");
$(".pop_menu").attr("class", "pop_menu");
$(this).before(" \
<div class='pop_toggle'></div> \
");
}
});
}
initpops();
// assign reverse z-indexes to each pop
var totalpops = $(".pop").length + 100;
$(".pop").each(function(i) {
var popzindex = totalpops - i;
$(this).css({ zIndex: popzindex });
});
// close pops if user clicks outside of pop
activePop = null;
function closeInactivePop() {
$(".pop").each(function (i) {
if ($(this).hasClass('active') && i!=activePop) {
$(this).removeClass('active');
}
});
return false;
}
$(".pop").mouseover(function() { activePop = $(".pop").index(this); });
$(".pop").mouseout(function() { activePop = null; });
$("body").on("click", ".pop", function(){
closeInactivePop();
});
// toggle that pop
$("body").on("click", ".pop_toggle", function(){
$(this).parent(".pop").toggleClass("active");
});
}
})(jQuery);
now when i load this script on an ajax call the new pop-out menus work but the old ones do not react to the onclick event.
You shouldn't mess with the plugin. It works exactly like it should.
Better show us how you call this on elements that you already have.
Also I don't like this plugin. Better use something from JqueryUI
You can do such thing in much easier way.
[edit]
I tried your first code (the plugin) and it works correctly for me.
[edit]
OK. I get it. You call $.pop(); multiple times. You shouldn't! Calling $.pop(); will pin up the drop down menu to all elements that has class="pop". This is the reason why you have such funny stack.
Just use $.pop(); once.
Plugin doesn't give ability to connect NEW elements that was dynamically created on the page.
Removed pop from ajax call and just called this on success:
$(".pop").each(function() {
var pop_classes = $(this).attr("class");
if ( $(this).find('.pop_menu').length) {
// do nothing
} else {
$(this).addClass("pop_menu");
$(this).wrap("<div class='"+pop_classes+"'></div>");
$(".pop_menu").attr("class", "pop_menu");
$(this).before(" \
<div class='pop_toggle'></div> \
");
}
});
// assign reverse z-indexes to each pop
var totalpops = $(".pop").length + 100;
$(".pop").each(function(i) {
var popzindex = totalpops - i;
$(this).css({ zIndex: popzindex });
});
// close pops if user clicks outside of pop
activePop = null;
function closeInactivePop() {
$(".pop").each(function (i) {
if ($(this).hasClass('active') && i!=activePop) {
$(this).removeClass('active');
}
});
return false;
}
$(".pop").mouseover(function() { activePop = $(".pop").index(this); });
$(".pop").mouseout(function() { activePop = null; });

Trying to get my slideshow plugin to infinitely loop (by going back to the first state)

I wrote a slideshow plugin, but for some reason maybe because I've been working on it all day, I can't figure out exactly how to get it to go back to state one, once it's reached the very last state when it's on auto mode.
I'm thinking it's an architectual issue at this point, because basically I'm attaching the amount to scroll left to (negatively) for each panel (a panel contains 4 images which is what is currently shown to the user). The first tab should get: 0, the second 680, the third, 1360, etc. This is just done by calculating the width of the 4 images plus the padding.
I have it on a setTimeout(function(){}) currently to automatically move it which works pretty well (unless you also click tabs, but that's another issue). I just want to make it so when it's at the last state (numTabs - 1), to animate and move its state back to the first one.
Code:
(function($) {
var methods = {
init: function(options) {
var settings = $.extend({
'speed': '1000',
'interval': '1000',
'auto': 'on'
}, options);
return this.each(function() {
var $wrapper = $(this);
var $sliderContainer = $wrapper.find('.js-slider-container');
$sliderContainer.hide().fadeIn();
var $tabs = $wrapper.find('.js-slider-tabs li a');
var numTabs = $tabs.size();
var innerWidth = $wrapper.find('.js-slider-container').width();
var $elements = $wrapper.find('.js-slider-container a');
var $firstElement = $elements.first();
var containerHeight = $firstElement.height();
$sliderContainer.height(containerHeight);
// Loop through each list element in `.js-slider-tabs` and add the
// distance to move for each "panel". A panel in this example is 4 images
$tabs.each(function(i) {
// Set amount to scroll for each tab
if (i === 1) {
$(this).attr('data-to-move', innerWidth + 20); // 20 is the padding between elements
} else {
$(this).attr('data-to-move', innerWidth * (i) + (i * 20));
}
});
// If they hovered on the panel, add paused to the data attribute
$('.js-slider-container').hover(function() {
$sliderContainer.attr('data-paused', true);
}, function() {
$sliderContainer.attr('data-paused', false);
});
// Start the auto slide
if (settings.auto === 'on') {
methods.auto($tabs, settings, $sliderContainer);
}
$tabs.click(function() {
var $tab = $(this);
var $panelNum = $(this).attr('data-slider-panel');
var $amountToMove = $(this).attr('data-to-move');
// Remove the active class of the `li` if it contains it
$tabs.each(function() {
var $tab = $(this);
if ($tab.parent().hasClass('active')) {
$tab.parent().removeClass('active');
}
});
// Add active state to current tab
$tab.parent().addClass('active');
// Animate to panel position
methods.animate($amountToMove, settings);
return false;
});
});
},
auto: function($tabs, settings, $sliderContainer) {
$tabs.each(function(i) {
var $amountToMove = $(this).attr('data-to-move');
setTimeout(function() {
methods.animate($amountToMove, settings, i, $sliderContainer);
}, i * settings.interval);
});
},
animate: function($amountToMove, settings, i, $sliderContainer) {
// Animate
$('.js-slider-tabs li').eq(i - 1).removeClass('active');
$('.js-slider-tabs li').eq(i).addClass('active');
$('#js-to-move').animate({
'left': -$amountToMove
}, settings.speed, 'linear', function() {});
}
};
$.fn.slider = function(method) {
if (methods[method]) {
return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
} else if (typeof method === 'object' || !method) {
return methods.init.apply(this, arguments);
} else {
return false;
}
};
})(jQuery);
$(window).ready(function() {
$('.js-slider').slider({
'speed': '10000',
'interval': '10000',
'auto': 'on'
});
});​
The auto and animate methods are where the magic happens. The parameters speed is how fast it's animated and interval is how often, currently set at 10 seconds.
Can anyone help me figure out how to get this to "infinitely loop", if you will?
Here is a JSFiddle
It would probably be better to let go of the .each() and setTimeout() combo and use just setInterval() instead. Using .each() naturally limits your loop to the length of your collection, so it's better to use a looping mechanism that's not, and that you can break at any point you choose.
Besides, you can readily identify the current visible element by just checking for .active, from what I can see.
You'd probably need something like this:
setInterval(function () {
// do this check here.
// it saves you a function call and having to pass in $sliderContainer
if ($sliderContainer.attr('data-paused') === 'true') { return; }
// you really need to just pass in the settings object.
// the current element you can identify (as mentioned),
// and $amountToMove is derivable from that.
methods.animate(settings);
}, i * settings.interval);
// ...
// cache your slider tabs outside of the function
// and just form a closure on that to speed up your manips
var slidertabs = $('.js-slider-tabs');
animate : function (settings) {
// identify the current tab
var current = slidertabs.find('li.active'),
// and then do some magic to determine the next element in the loop
next = current.next().length >= 0 ?
current.next() :
slidertabs.find('li:eq(0)')
;
current.removeClass('active');
next.addClass('active');
// do your stuff
};
The code is not optimized, but I hope you see where I'm getting at here.

Adding a third step to my Wizard-step Jquery code

I am using Wizard-Step in my MVC3 project, it is two steps right now but I want to add a third step into to it.
However, I still want to submit my form in the second step.
This is how my Wizard-step Jquery code looks like:
$(function () {
$(".wizard-step:first").fadeIn(); // show first step
// attach backStep button handler
// hide on first step
$("#back-step").hide().click(function () {
var $step = $(".wizard-step:visible"); // get current step
if ($step.prev().hasClass("wizard-step")) { // is there any previous step?
$step.hide().prev().fadeIn(4500); // show it and hide current step
// disable backstep button?
if (!$step.prev().prev().hasClass("wizard-step")) {
$("#back-step").hide();
}
}
});
// attach nextStep button handler
$("#next-step").click(function () {
var $step = $(".wizard-step:visible"); // get current step
var validator = $("form").validate(); // obtain validator
var anyError = false;
$step.find("select").each(function () {
if (!this.disabled && !validator.element(this)) { // validate every input element inside this step
anyError = true;
}
});
$step.find("input").each(function () {
if (!validator.element(this)) { // validate every input element inside this step
anyError = true;
}
});
if (anyError)
return false; // exit if any error found
if ($step.next().hasClass("confirm")) { // is it confirmation?
// show confirmation asynchronously
$.post("/wizard/confirm", $("form").serialize(), function (r) {
// inject response in confirmation step
$(".wizard-step.confirm").html(r);
});
}
if ($step.next().hasClass("wizard-step")) { // is there any next step?
$step.hide().next().fadeIn(4500); // show it and hide current step
$("#back-step").show(); // recall to show backStep button
}
else { // this is last step, submit form
$("form").submit();
}
return false;
}
});
});
Any solutions is highly appreciated.
use an indexer variable then submit your form at step 2 and post the result in third step
for example... i'm posting some of my projects code here for reference...
if (indexer < 2 && $step.next().hasClass("wizard-step")) {
$step.hide().next().fadeIn();
indexer++;
ShowStep();
}
else {
$.post(paths + "/Auction/Post", $('form').serialize(), function (data) {
alert(data);
})
.complete(function () {
});
}

Categories