Auto hide and show div after 2 seconds - timeout

I am very new to these kinds of scripts and would be very thankful for any help.
I have 3 rotating divs and want div1 to show for 2 seconds, then div2 to show for 2 seconds, then div3 to show for 2 seconds and then the whole cycle to start from the beginning. One div at a time while the other 2 are hidden. I'd also like to get rid of the click to start the function but as soon as I visit the page the cycle to begin.
I am basically taking the code from the following post. I got all that to work
auto hide div after 2 seconds

use jquery .fadein() and .fadeout() or .css('display','none') and use window.setInterval(FunctionName, 2000);
Every two seconds the function you enter in the first parameter will run. Create a variable that keeps track of which div you're about to show. When the variable goes to 3 you reset it to 1 so the process can continue infinitely.
Edit:
style:
div{
width:500px;
height:500px;
margin-left:50px;
border:1 px solid black;
float:left;
opacity:0;
}
#div3
{
opacity:1;
}
div:nth-child(odd){
background:#dad;
}
div:nth-child(even){
background:#a55;
}
jquery/js:
var Index = 1;
window.setInterval(ChangeVisibleDiv, 2000);
function ChangeVisibleDiv()
{
var nextIndex = Index + 1;
var prevIndex = Index - 1;
//reset on 4, not 3 because then the 3rd div would never be faded out.
if(Index == 4)
nextIndex = 1;
// opposite story here as above
if(Index == 1)
prevIndex = 3;
$(("#div" + prevIndex)).css('opacity',0);
$(("#div" + nextIndex)).css('opacity',0);
$(("#div" + Index)).css('opacity',1);
Index++;
//reset on 4, not 3 because then the 3rd div would never be faded out.
if(Index == 4)
Index = 1;
}
html
<div id="div1">
</div>
<div id="div2">
</div>
<div id="div3">
</div>
It starts at the third div, I hope you don't mind because I'm too lazy to fix =)
I really recommend you learn some jquery and javascript, though. It's not clever to use something if you dont know how it works. At least learn the fundamentals.
Also, people on this forum want questions that are fun and challenging, not assignments from school =)

Related

How to display progress percentage in UI in Ruby on Rails?

I have a button in my Rails application. When it is clicked, around 5 stored procedures run (sequentially) in the background. It takes around 60 seconds for all of them to complete.
Until then, I would like to display some kind of a progress bar (or a spinner that shows percentage of progress) in the UI so that the user does not get a feeling that the application just hangs.
So, if 1 out of 5 stored procedures are complete, then we could should show the progress as 20%; if 2 stored procedures are complete, then show the progress as 40% and so on.
What is the best way to do this?
(Ajax spinners don't seem to have a provision to display % progress)
you can use bootstrap progress bar and update the values from js or jquery. Here are the examples.
Js :
HTML :
var i = 0;
fill_bar();
function fill_bar(){
setInterval(function() {
var art = i;
doSomethingWith(art)
if(i >= 5) {return false;}
}, 5000);
}
valuer = 0;
function doSomethingWith(art){
valuer = valuer + 20;
$('.progress-bar').css('width', valuer+'%').attr('aria-valuenow', valuer);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<div class="progress progress-striped active">
<div class="progress-bar" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100">
</div>
</div>
You can call the method
fill_bar()
from controller or after clicking the button.

jQuery UI sortable drag initiation is slow when container has hidden items

I have an unordered 'source' list that can contain up to around 1,000 list items. I want to be able to drag the items from the source list into a connected 'destination' list. I have everything working great until my source list gets filtered. I'm using the jquery quicksearch plugin to filter (search) my source list. The filter is accomplished by setting 'display:none;' on items that don't match the search.
When 1..n items in my source list are hidden, the drag operation is not fluid when initiated. Meaning, I click on the item I want to drag, move my mouse around the screen, but the item I'm dragging does not appear under my cursor until about a full second after I've initiated the drag.
For diagnosis, I've slimmed down my use case to just one list that I want to sort. I've completely eliminated the use of quicksearch by just hard coding half of my list items as hidden. I'm still able to reproduce the 'non-fluid' behavior. My example is here:
http://pastebin.com/g0mVE6sc
If I remove the overflow style from the list in my example, the performance is a little better, but still slower than I'd hope to see.
Does anyone have any suggestions for me before I start considering other options?
Thanks in advance.
As you can see on this jsferf example, calculating outerWidth()/outerHeight() (this is what the plugin does - see below) for hidden elements (with display none) is terribly slower than for visible elements, wether it is achieved by a style attribute or a class.
The only way I have found to bypass this and still achieve the same result is to set the height for the elements to hide to zero, instead of working with the display property, whether using the style atttibute or a class:
<li style="height: 0;">b</li>
<li class="hidden">b</li>
.hidden { height: 0 }
DEMO (with class) - DEMO (with style attr)
What's happenning with sortable when dragging an element ?
When starting dragging, the plugin refreshes the list of all items and recalculates positions of all elements. The plugin actually gets outerWidth and outerHeight:
_mouseStart: function(event, overrideHandle, noActivation) {
...
//We only need to call refreshPositions, because the refreshItems call has been moved to mouseCapture
this.refreshPositions();
...
}
refreshPositions: function(fast) {
...
for (var i = this.items.length - 1; i >= 0; i--) {
var item = this.items[i];
...
if (!fast) {
item.width = t.outerWidth();
item.height = t.outerHeight();
}
var p = t.offset();
item.left = p.left;
item.top = p.top;
};
...
return this;
},​
If you still want to use display:none, this is a simple fix to the jQuery UI source specified in Didier's answer:
if (!fast) {
if(item.item.css('display') === 'none') {
item.width = 0;
item.height = 0;
}
else {
item.width = t.outerWidth();
item.height = t.outerHeight();
}
}
This is my very first post on stackoverflow, so do let me know if I messed something up.
I was also having a similar problem, but with hidden drop containers instead of sortable items. Here is my solution applying Jordan's answer to both sortable items and their containers and simply replacing the relvent method.
$.ui.sortable.prototype.refreshPositions = function(fast) {
//This has to be redone because due to the item being moved out/into the offsetParent, the offsetParent's position will change
if(this.offsetParent && this.helper) {
this.offset.parent = this._getParentOffset();
}
for (var i = this.items.length - 1; i >= 0; i--){
var item = this.items[i];
//We ignore calculating positions of all connected containers when we're not over them
if(item.instance != this.currentContainer && this.currentContainer && item.item[0] != this.currentItem[0])
continue;
var t = this.options.toleranceElement ? $(this.options.toleranceElement, item.item) : item.item;
if (!fast) {
/********** MODIFICATION ***********/
if(item.item.css('display') === 'none') {
item.width = 0;
item.height = 0;
} else {
item.width = t.outerWidth();
item.height = t.outerHeight();
}
/********** END MODIFICATION ***********/
}
var p = t.offset();
item.left = p.left;
item.top = p.top;
};
if(this.options.custom && this.options.custom.refreshContainers) {
this.options.custom.refreshContainers.call(this);
} else {
for (var i = this.containers.length - 1; i >= 0; i--){
/********** MODIFICATION ***********/
if (this.containers[i].element.css('display') == 'none') {
this.containers[i].containerCache.left = 0;
this.containers[i].containerCache.top = 0;
this.containers[i].containerCache.width = 0;
this.containers[i].containerCache.height = 0;
} else {
var p = this.containers[i].element.offset();
this.containers[i].containerCache.left = p.left;
this.containers[i].containerCache.top = p.top;
this.containers[i].containerCache.width = this.containers[i].element.outerWidth();
this.containers[i].containerCache.height = this.containers[i].element.outerHeight();
}
/********** END MODIFICATION ***********/
};
}
return this;
};
I came across with the same problem...
I've searched for a solution, but it seems there is no solution to the jquery problem, only some workaround...
I didn't found either a solution, just another workaround.
In my case I just created a general method to to a search in a sortable list, where on keyup, the code goes and do a find on every element in the list and was hiding it by fadeout if didn't match the value.
This was working very well, but when you have hundreds of items in a list, the of hidden gets big enough to trigger the slow effect on the drag&drop.
My solution was to reorder the list, bringing to the top the matched items..
Just remove and appendTo again...
This way I don't have problems with the hidden elements :)
Sorry this was no solution, but just another workaround..
Regards
More recently I came accross with this issue again... and found that my workaround was not the best solution anymore. Since the issue is the height... I've just create a CSS class with
.hidden {display: block; line-height:0; height: 0; overflow: hidden; padding: 0; margin: 0; }
and instead of setting the element hidden with just add this class and remove it to show/hide the element..
Regards,
AP
I got the same issue today with sortable + draggable table rows.
The solution was simple : use visibility:collapse instead of display:none and removing the jQuery hide/show function for the hidden lines did the trick. It's a lot faster now.
Hope I will help.

Get scroll position of panel using SplitView (JQuery Mobile)

I have implemented a WebApp using SplitView - http://asyraf9.github.com/jquery-mobile/ - (and that seems to use the ScrollView component) together with jQuery Mobile. Everything works fine ...
Within the panel I have got a list of elements that should dynamically add elements when scrolling reaches the end of the list. On the iPhone I do not use SplitView but iScroll - http://cubiq.org/iscroll - and the following code to achieve this (and it is working).
HTML:
<div data-role="panel" data-id="menu" data-hash="crumbs" style="z-index: 10000;" id="Panel">
<div data-role="page" id="Root" class="Login" onscroll="console.log('onscroll');">
<div data-role="content" data-theme="d" onscroll="console.log('onscroll');">
<div class="sub">
<ul data-role="listview" data-theme="d" data-dividertheme="a" class="picListview" id="PortfolioList">
<!-- Content added dynamically -->
</ul>
</div>
</div>
</div>
</div>
Javascript:
var defaultIScrollOptions = {
useTransition: true,
onScrollStart: function() {
this.refresh();
},
onScrollEnd: function() {
if (this.elem && this.id) {
possiblyDisplayNextDocuments(this.y, this.elem, this.id);
}
}
};
iScrolls.push(new iScroll(document.getElementById("searchResults").parentNode, defaultIScrollOptions));
But when using SplitView I do not really know which event and which element to bind the listener on or how to get the scroll position. I already tried several combinations, but did not achieve good results. The best one was the following:
$("#PortfolioList").scrollstop(function(event) {
console.log("scrollstop: "+$("#PortfolioList").scrollTop());
});
My question is: Am I using the right event listener (since it already fires althgough the scrolling animation is still in use) and how do I get the scroll position?
dont use the scrollview plugin. its buggy. Use iscroll for both iOS phonegap apps as well as android. It works fine on both.
For detecting the scroll and loading new elements into the list, listen to the the 'onScrollMove' event of iscroll.
In the iscroll-wrapper.js add this-
options.onScrollMove = function(){
that.triggerHandler('onScrollMove', [this]);
};
then in your code attach a event handler to the onScrollMove event and handle adding new rows in that. onScrollMove will fire whenever you scroll.
In the handler you can find how many rows are there in your list and that which row is on the top of your view port using something like
iscrollScrollEventHandler:function(event){
var contentDiv= $('div:jqmData(id="main") .ui-page-active div[data-role*="content"] ul li' );
var totalItemsonList = contentDiv.length;
var cont =$('div:jqmData(id="main") .ui-page-active div:jqmData(role="content")');
var itemToScrollOn = totalItemsonList - x; // x is the item no. from the top u want to scroll on. u need to keep updating i guess
var docViewBottom = $(cont).scrollTop() + $(cont).height();
var itemOffset = $(contentDiv[itemToScrollOn]).offset();
if(itemOffset){
var elemTop = itemOffset.top;
if (elemTop <= docViewBottom){
event.data.callback();
}
}
}
and in the callback add the code to add new rows. hope that helps.

Rails & prototype - insert a div and position it

For my rails site, when somebody attempts to delete an item, I wish to pop up a custom div (as opposed to a javascript alert box) asking for confirmation before doing so.
At the moment, the way that I am doing this, is that clicking on the delete link will call a function (in application_helper.rb) as below:
def show_delete_box(object, name)
update_page do |page|
page.insert_html :before, "content", render(:partial => "shared/generic_delete_box", :locals => { :object => object, :name => name })
page << "$('delete_box').Center"
end
end
The rendered partial is intended to appear in the middle of the screen, and the locals are what will be used to create the appropriate delete link in the div.
However, my problem here is attempting to make it appear in the middle of the screen. I've always massively suffered with javascript and this is driving me insane as well. (Ya, I've tried to use firebug as well, but those long lines of javascript mean nothing to me. >.< )
The 2nd line in my update_page block is meant to call a javascript function that center's the inserted div.
The function that I've written and stuck into my application.js file is as follows:
Element.Center = function(element) {
var vH, vW, eH, eW;
var d = Element.getDimensions(element);
eH = d.height;
eW = d.width;
vH = document.viewport.getHeight();
vW = document.viewport.getWidth();
var y = (vH/2) - (eH/2) + "px";
var x = (vW/2) - (eW/2) + "px";
var style = { position: 'absolute'; top: y + 'px'; left: x + 'px'};
element.setStyle(style);
}
What happens when I click, is that the partial div is created, and inserted into the page at the appropriate spot. However it is not being positioned in anyway that I can tell.
So, I'm looking for help! What am I doing wrong in the javascript function, or in attempting to call the function?
Thanks in advance!
--edit--
I'm not sure if this will help... This is the relevant CSS code for delete_box.
#delete_box {
background-color: green;
border: 5px solid #999;
padding: 15px;
width: 600px;
}
So the CSS doesn't touch the positioning in any way.
There are several prebaked libraries out there that do just what you're saying, might be easier than writing it yourself. Redbox is a rails plugin that works in Prototype, for one example.

getting jQuery UI's datepicker to always open in a certain direction?

I'm using jQuery UI's datepicker control in a position: fixed toolbar at the bottom of my page. Occasionally, on random computers, the datepicker appears below the toolbar, which means it's off the page and impossible to view or interact with.
Is there a way to force the positioning of the datepicker control to always be above and to the right of its <input>?
The only way to be certain (for the jQueryUI version of datepicker) is to disable the functionality of the datepicker that tries to render inside the viewport. Here's a way to do it without modifying the source code files:
$.extend(window.DP_jQuery.datepicker,{_checkOffset:function(inst,offset,isFixed){return offset}});
on later versions of JQuery UI try:
$.extend($.datepicker,{_checkOffset:function(inst,offset,isFixed){return offset}});
That just nukes the _checkOffset function inside datepicker that makes it squirrelly. Then you can use the .ui-datepicker css to make sure it stays fixed if that's what you're after. More info at how-to-control-positioning-of-jqueryui-datepicker.
Problem is that element in position: fixed show top position 0px (check with: alert$('#datepicker2').position()).
Solution:
$('#datepicker').datepicker( {beforeShow: function(input) {
var x = 100; //add offset
var y = 20;
field = $(input);
left = field.position().left + x;
bottom = y;
setTimeout(function(){
$('#ui-datepicker-div').css({'top':'', 'bottom':bottom + 'px', 'left': left + 'px'});
},1);
}}
Test HTML:
<form style="position:fixed; bottom:0; width:100%" name="form1" method="post" action="">
<label>
<input style="left:300px; position:absolute; bottom:0" type="text" name="textfield" id="datepicker">
</label>
</form>
You could change the lines:
offset.left -= (offset.left + dpWidth > viewWidth && viewWidth > dpWidth) ? Math.abs(offset.left + dpWidth - viewWidth) : 0;
offset.top -= (offset.top + dpHeight > viewHeight && viewHeight > dpHeight) ? Math.abs(offset.top + dpHeight + inputHeight*2 - viewHeight) : 0;
...to read:
offset.left = $(inst.input).position().left + dpWidth;
offset.top = $(inst.input).position().top - dpHeight;
This loses flexibility, though. If your input happens to be at the top of the page, you'll have the opposite problem from before.
http://www.mindfiresolutions.com/Make-jQuery-datepicker-to-popup-in-different-positions-995.php
check this. I used this and was able to position the datepicker control in all browsers.
I had a similar problem. I have a page with date pickers potentially used at various placed on the page but also on a fixed header where the user can scroll the page both horizonally and vertically with the fixed header staying in place. The header also has a datepicker. So I can't do a global change of datepicker.
This is what I did. It is admittedly a kluge but it works so I thought it might help someone else. Hopefully in the future the jquery datepicker will add a position option.
beforeShow: function(input, inst) {
$("#ui-datepicker-div").css({ "visibility": "hidden", "display": "none" );
window.setTimeout(function() {
var leftPosition = parseInt($(window).width() / 2);
$("#ui-datepicker-div").css({ "position": "fixed", "top": 0, "left": leftPosition });
$("#ui-datepicker-div").css({ "visibility": "visible", "display": "inherit" );
}, 500);
}
From the documentation, it looks like you might be able to use the 'dialog' method of the datepicker plugin to achieve your desired outcome. However, using this most likely means that you will have to implement some of the glue that you would otherwise get out-of-the-box with datepicker, such as a callback handler to extract the date, etc.
I tried to mock up some code to see it in action and short of getting the datepicker to display, I couldn't quite get it working, though. Anyway, I wanted to point you to it in case you have better luck than I did.

Resources