I made this fiddle
http://jsfiddle.net/nAb6N/10/
As you can see I have 2 animators , a element and body class,
I am adding class to body after the first click on a element but once I click on body is not closing it. If I define animators as
var animators = $$('#opendiv,body');
it works ok except that I do not want the div to open on body click. I need it to close on body click.
Any help is appreciated.
Thank you!
Right. Seems as if you really require an outerClick pattern to close. Here's the one that is most notably used within mootools devs, allowing you to create a custom event, based on click:
Element.Events.outerClick = {
base : 'click',
condition : function(event){
event.stopPropagation();
return false;
},
onAdd : function(fn){
this.getDocument().addEvent('click', fn);
},
onRemove : function(fn){
this.getDocument().removeEvent('click', fn);
}
};
The way it works is: it is based on a normal click. upon adding, it adds the callback as a click event on the document. when a click happens within the element itself,it stops bubbling via event.stopPropagation();, else, it will bubble and the callback will run.
here's how it ties together after the above:
http://jsfiddle.net/dimitar/nAb6N/13/
(function() {
var opener = $('opendiv');
var boxtoopen = $('box');
boxtoopen.set('morph', {
duration: 700,
transition: 'bounce:out'
});
boxtoopen.addEvent('outerClick', function(event) {
boxtoopen.morph(".openOff");
opener.removeClass("hide");
});
opener.addEvent('click', function(e) {
e.stop();
boxtoopen.morph(".openOn");
this.addClass("hide");
});
})();
I have also 'outsourced' the morph properties to the CSS as it makes more sense, semantically.
P.S. note that you need mootools 1.4.3 or 1.4.5, but not 1.4.4 as there's a morph bug to do with units in that release. the jsfiddle above uses 1.4.6 (mootools edge).
Related
hi sorry completely new to mootools used to jquery, have a container (saved to variable itemContent) which reveals,
after this a function galleryScroll is call which scrolls the element to the container saved to var itemScroll,
want to make sure itemContent is revealed before scroll function is called whats the best way to do this?
thanks
itemContent.reveal({
'height' : '100%',
duration: 1600,
}).addClass('open-content');
// should this fire this in a callback function so it fires once the container is revealed
galleryScroll.toElement(itemScroll);
Fx.Reveal extends Fx and as such, inherits all of it's events.
try via the element setter:
itemCount.set('reveal', {
onComplete: function(){
galleryScroll.toElement(this.element);
}
}.reveal({... });
you can also get the reveal instance:
var fxReveal = itemCount.get('reveal');
this will return the instance and you can set whatever you like to it like usual.
You can enable chaining with the link option.
itemContent.reveal({
'height': '100%',
duration: 1600,
link: 'chain'
}).addClass('open-content');
This example will hide, reveal and then alert. Please note that I need to get the reveal instance as the standard Element in mootools does not implement the Chain class.
document.id('first').set('reveal', {
duration: 'long',
transition: 'bounce:out',
link: 'chain'
}).dissolve().reveal().get('reveal').chain(function(){alert('message');});
To see it in action: http://jsfiddle.net/LKSN8/1/
How to trigger an event in Mootools for a specific tag/element with a specific element ID?
I have this:
Video
This rel="rokbox" means that the element will be used by the Mootools RokBox modal box, but I've hidden the link.
Now, I've added this code:
window.onload = function() {
if(document.readyState == 'complete') {
// point of execution
// here I want to trigger the "a" element I've wrote up before
}
}
The code reaches until the "point of execution", when I set a basic alert, or whatsoever.
window.addEvent('domready', function() {
$('video_popup').fireEvent('click');
});
Note the use addEvent/domready, which is the proper method to add a function which must execute once the page is ready.
I have a jQuery datepicker function bound to the "birthday" input html element, written in the page header:
<script type="text/javascript">
$(function() {
$( "#birthday" ).datepicker();
});
</script>
Next, I have some AJAX functionality - it adds new input html element to the page. That element is:
<input type="text" id="birthday" value="" class="detail-textbox1" />
Clicking on that birthday element does not pop up the date picker below the text field. I expected this, as the element is added after the page is loaded, thus it isn't in relation with the function provided in the header.
How can I make it work? I tried moving the script from the header to the body, but nothing seems to work. Thanks.
P.S. If I create an input html element with id="birthday" in the page body, everythig works as expected. It appears that only the elements added through AJAX are dysfunctional.
I'm a bit late to the party, but for thoroughness - and with the .live() function being deprecated from jQuery 1.7 onwards - I thought I'd provide an updated solution based on my experiences, and from all the help I got from other answers on StackOverflow!
I had a situation where I needed to add the datepicker functionality to input fields that were being added to the DOM through AJAX calls at random, and I couldn't modify the script making the AJAX calls to attach the datepicker functionality, so I opted for the new shiny .on() function with its delegation features:
// do this once the DOM's available...
$(function(){
// this line will add an event handler to the selected inputs, both
// current and future, whenever they are clicked...
// this is delegation at work, and you can use any containing element
// you like - I just used the "body" tag for convenience...
$("body").on("click", ".my_input_element", function(){
// as an added bonus, if you are afraid of attaching the "datepicker"
// multiple times, you can check for the "hasDatepicker" class...
if (!$(this).hasClass("hasDatepicker"))
{
$(this).datepicker();
$(this).datepicker("show");
}
});
});
I hope this helps someone, and thanks for all the answers so far that led me to this solution that worked for me! :)
You need to use .live() so that any newly added elements have the event handler attached: http://api.jquery.com/live/
$('#birthday').bind('load', function() {
$(this).datepicker();
});
EDIT
.live() documentation states, that it is a bit out of date. With new versions of jquery (1.7+) use .on().
Boris, JK: This was super helpful for me. I have also found that you can use the following for AJAX html if you want to use Datepicker's date range selection:
$('#groundtransporation').live('focus', function() {
var gt = $( "#rentalPickUp, #rentalDropOff" ).datepicker({
defaultDate: "+1w",
changeMonth: true,
numberOfMonths: 2,
onSelect: function( selectedDate ) {
var option = this.id == "rentalPickUp" ? "minDate" : "maxDate",
instance = $( this ).data( "datepicker" ),
date = $.datepicker.parseDate(
instance.settings.dateFormat ||
$.datepicker._defaults.dateFormat,
selectedDate, instance.settings );
gt.not( this ).datepicker( "option", option, date );
}
});
});
I got another case.
My script is copying last table elements including datepicker.
The jquery will not working because the copied element has mark that it "hasDatepicker".
To activate datepicker in new element, remove that class name and the initiate it, like this.
$("#yournewelementid").attr("class","your-class-name");
$("#yournewelementid").datepicker();
your issue is always happens when elements don't exist when you try to initialize it.
When you use $(function(){/** some code **/}); elements must exsit on the document, it means that has to be on the html so you could can create a function to initialize the component or initialize it on the success event after been add it to the document.
Is important to first add the external html load in the ajax request to the document before you try to initialize it or it won't be initialize at all.
Example:
$.ajax({
url:"ajax_html.html",
dataType:"html"
}).done(function(html){
$("#selector").html(html)
init();
});
function init(){
$(".birthday").datepicker({});
}
You could initialize the date picker for the newly added element within your ajax success callback:
$.ajax({
...
success: function(response) {
if(response.success) {
$(body).append(response.html);
$("#birthday").datepicker();
}
}
});
Is there a way of preventing a Google Maps (JS, v3) map being displayed from the get-go? I'm doing some pre-processing and would like to show my 'Loading' spinner until everything is good to go (more eloquently put, hide the map -- e.g. the container div – until all pre-processing is complete – at which point, show the map).
Hooking up the map's idle event doesn't help that much, since the map is already displayed when this event hits.
I know that the container div gets inline-styled by GMaps after loading, my first idea was to clear out the style attribute (whilst listening to the idle event), but it would be interesting to see if there is a way of creating the map and not displaying it until all pre-processing is done.
Maybe by using an argument to the new google.maps.Map constructor, or a MapOption ?
Any thoughts on this?
Thank you in advance!
Also remember to call:
google.maps.event.trigger(map, 'resize');
if you have changed the size of the <div>. A display:none <div> has no size.
Or you could just hide it like with css visablility or css opacity.
$("#GoogleMap").css({ opacity: 0, zoom: 0 });
initialize();
google.maps.event.addListener(map,"idle", function(){
$('#Loader').hide();
$("#GoogleMap").css({ opacity: 1, zoom: 1 });
});
This works for me. I'm using the JQuery library.
$(document).ready(function(){
$('#Checkbox').click(function(){
$('#googleMapDiv').toggle();
initialize(); // initialize the map
});
});
another way to show the hidden map when map is first time rendering the <div> is to set style: visibility.
When firstly hidden, use visibility = hidden; to show use visibility = visible
the reason is: visibility:hidden means that the contents of the element will be invisible, but the element stays in its original position and size.
this works fine for me, I use jquery tabs
setTimeout(function() {
google.maps.event.trigger(map, "resize");
map.setCenter(new google.maps.LatLng(default_lat, default_lng));
map.setZoom(default_map_zoom);
}, 2000);
om this link https://code.google.com/p/gmaps-api-issues/issues/detail?id=1448
This will work
google.maps.event.addListener(map, "idle", function ()
{
google.maps.event.trigger(map, 'resize');
});
better way:
gmap.redraw = function() {
gmOnLoad = true;
if(gmOnLoad) {
google.maps.event.trigger(gmap, "resize");
gmap.setCenter(gmlatlng);
gmOnLoad = false;
}
}
and in show click event:
$("#goo").click(function() {
if ($("#map_canvas").css("display") == "none") {
$("#YMapsID").toggle();
$("#map_canvas").toggle();
if (gmap != undefined) {
gmap.redraw();
}
}
});
depending on what you are doing another posibility could be to have multiple bools you set to true when each process is done.
For example:
if you have a geocode service running which you want to wait for, you could have a var called
GeoState
and in the result part of the geocoder set GeoState to true,
then have a timed function check if all the services have returned true, when they have, make the map visible.
I have a Prototype snippet here that I really want to see converted into Mootools.
document.observe('click', function(e, el) {
if ( ! e.target.descendantOf('calendar')) {
Effect.toggle('calendar', 'appear', {duration: 0.4});
}
});
The snippet catches clicks and if it clicks outside the container $('calendar') should toggle.
Are you trying to catch clicks anywhere in the document? Maybe you could try...
var calendar = $('calendar');
$$('body')[0].addEvent('click', function(e) {
if (!$(e.target).getParent('#calendar')) {
var myFx = new Fx.Tween(calendar, {duration: 400});
myFx.set('display', 'block');
}
}
I'm not sure how you are toggling visibility but the way Fx.Tween.set works allows you to change any CSS property. You may want to look at http://mootools.net/docs/core/Fx/Fx.Tween for other possibilities.
Also, notice that I wrapped e.target using a $. This is specifically for IE. I wrote a post about this here under the sub-heading "Mootools Events Targets".
Lastly, I factored out $('calendar') so that you are not searching the DOM every time.