Foundation 6 reveal modal events not firing for me - zurb-foundation-6

I want videos playing in the reveal modal window to stop playing when the modal window closes (who doesn't?). This is easily done with jQuery by setting the iframe source to empty.
But I can't figure out how to make it work in a callback. The modal window itself functions as expected. And this works:
$('.close-button', '#video-reveal').on('click', function() {
$('#video-player').attr("src", "");
console.log("button event fired");
});
However, neither of the following has any effect:
// from documentation
$(document).on('close.fndtn.reveal', '[data-reveal]', function() {
var modal = $(this);
console.log("closing reveal event fired");
});
// my attempt to do it programmatically
$('[data-reveal]').on ('opened.fndtn.reveal', function() {
var modal = jQuery(this);
console.log("opened reveal");
});
So it feels like the event is not firing. I'm sure it is, but how to capture it?

The magic of Foundation 6 is not all obvious without some digging. Working with version 6.2.3
$(document).on(
'open.zf.reveal', '[data-reveal]', function () {
console.log("'open.zf.Reveal' fired.");
}
);

It appears as though you are using Foundation 5's callbacks, rather than Foundation 6...
For your callbacks, I'd suggest using 'closed.zf.reveal', 'open.zf.reveal' or 'closeme.zf.reveal' as mentioned here:
http://foundation.zurb.com/sites/docs/reveal.html

In HTML
<!--the button -->
<a class="button" data-open="videoModal" href="#">Example Video Modal</a>
<!--Modal Video -->
<div class="row" id="theVideo">
<div id="videoModal" class="reveal" data-reveal data-close-on-click="true">
<h2>This modal has video</h2>
<div class="flex-video">
<iframe id="youtubePlayer" width="854" height="480" src="https://www.youtube.com/embed/4z6aSO05YHg" frameborder="0" allowfullscreen allowscriptaccess="always"></iframe>
</div>
<button class="close-button" data-close aria-label="Close reveal" type="button" onClick="destroyVideo()">
<span aria-hidden="true">×</span>
</button>
</div>
</div>
<!--in apps.js-->
function destroyVideo(){
var url = $('#youtubePlayer').attr('src');
$('#youtubePlayer').attr('src', '');
$('#youtubePlayer').attr('src', url);
}

Related

Cannot use $(this) in $.getJSON in .each

Im building a custom Minecraft Server Status and hit a problem. The first version of this was successful but the code was rather long and I decided to make it better and shorter. The script is supposed to fill the elements of each .server but it doesn't work.
<div class="server_status">
<div class="container servers_info">
<h1>My Network</h1>
<div id="of the server" class="server" title="of the server" server-ip="0.0.0.0">
<div class="name"></div>
<div class="count"><i class="fa fa-spinner fa-spin"></i></div>
<div class="players">Loading player data <i class="fa fa-spinner fa-spin"></i></div>
<div class="status"></div>
</div>
<div id="of the server" class="server" title="of the server" server-ip="0.0.0.0">
<div class="name"></div>
<div class="count"><i class="fa fa-spinner fa-spin"></i></div>
<div class="players">Loading player data <i class="fa fa-spinner fa-spin"></i></div>
<div class="status"></div>
</div>
<!-- ..... more servers -->
<span class="total"><i class="fa fa-spinner fa-spin"></i></span>
</div>
$(document).ready(function ping() {
$( ".servers_info .server" ).each( function() {
var name = $(this).attr( "title" );
var ip = $(this).attr( "server-ip" );
var id = $(this).attr( "id" );
var total = 0;
var call = "Get Avatar List adress";
//Set the name:
$(".name",this).html(name);
//Gets the data:
$.getJSON("http://mcapi.ca/v2/query/info/?ip=" + ip, function (json) {
//Checks The status and applies visual effects:
if (json.status !== "false") {
$(".status",this).html("<span class=\"l-online\">" + json.ping + " ms</span>");
$(this).removeClass('blur');
} else {
$(".status",this).html("<span class=\"l-offline\">0 ms</span>");
$(this).addClass('blur');
};
});
});
//Sets Refresh rate of 10s
setTimeout(ping, 10000);
});
I narrowed down the problem to the $.getJSON part. The data is retrieved correctly but cannot be placed in its respective DIVs. The only difference with the first version of the script is that I used 4 getJSON separately for each of the servers I wanted to display. Now using .each to combine it for all 4 of them and also $(this) to use relative objects.
I suspect the problem is in th usage of $(this) in .get but I'm nnot sure and don't know how to fix it.
As you suspect, the issue is the $(this). part. Inside the $.getJSON callback this no longer refers to the DOM object that triggered the event.
To fix this you can either:
Add a .bind(this) to the callback function. No changes required inside the function itself.
$.getJSON(url, function(json) {
/* all your code here */
}.bind(this)
);
Or save the reference to this before $.getJSON and use it inside the callback.
var _this = this;
$.getJSON(url, function(json) {
/* replace all references of this to _this for example*/
$(_this).removeClass('blur');
});
Hope that helps

textbox can't get focus in Node.js

I have a textbox in my site that can't seem to get focus. I tried adding focus on click with jQuery but that seems to have no effect. Can anyone help me out?
App link: http://test-app-andrew.herokuapp.com/
Jade:
div(id="templates",class="sideBarContent")
div(id="addPageBox")
input(type="text",id="addPage")
HTML(output from above):
<div id="templates" class="sideBarContent">
<div id="addPageBox">
<input type="text" id="addPage">
</div>
</div>
Coffeescript:
$ ->
$('input#addPage').click ->
$('input#addPage').focus()
Javascript (output from above):
// Generated by CoffeeScript 1.8.0
(function() {
$(function() {
return $('input#addPage').click(function() {
return $('input#addPage').focus();
});
});
}).call(this);
Any help would be great, thanks!

Rendering new div created dynamically with Meteor

I have a the classic "Thread->Posts" model.
In the application, I have a left sidebar with the "Thread" collections. When the user click in a Thread, I want to create another div with the Thread->Posts elements.
Is there any way to do this, conservating the reactivity?
For now, I've got this:
// In the client
Template.threadlist.events({
'click tr': function(event){
Session.set("selectedThread",this);
$("#posts").html( Meteor.render(Template["datathread"]) );
}
})
[...]
Template.datathread.events({
'click input.add-post' : function(event){
var t = Session.get("selectedThread");
Meteor.call("addPost", {"thread":t,"text":"foo","user":"var"},callback})
}
})
[...]
// In the server
addPost: function(param){
var id = Threads.update(param.thread,{ $addToSet: {"posts": {"text":param.text, "user": param.user}}});
return id;
}
The template with the posts is something like this:
<template name="datathread">
{{#each thread.posts}}
{{user}} says: {{text}}
<br />
{{/each}}
</template>
(The "user" and "text" propertis are from the "thread.posts" elements)
With this code, I only get the new values refreshing (F5) the webpage (or executing the 'click tr'event). What I'm doing wrong?
Thank you!
== Edit ==
Ok... Now, with the recomendation of Chistian Fritz, my code its something like this:
// In the client
Template.datathread.thread = function(){
return Session.get("selectedThread");
}
[...]
Template.threadlist.events({
'click tr': function(event){
Session.set("selectedThread",this);
}
});
//In the html
<div class="span5" id="threads">
{{> datathread}}
</div>
<template name="datathread">
{{#if thread}}
<hr />
{{#each thread.posts}}
{{user}} says: {{text}}
<br />
{{/each}}
{{/if}}
</template>
The changes are great (it's so simple!), but the reactivity still doesn't work :(....
The problem is that you are using jQuery to fill your DOM:
$("#posts").html( Meteor.render(Template["datathread"]) );
This breaks the reactivity chain.
You are only showing part of your code, so I can't give you the full solution, but it seems that the datathread template is already using the selectedThread session variable -- which is good. Hence, it might be as easy as using {{> datathread}} in place of the #posts element in your HTML.
EDIT:
One thing that you need to change is the scope you are assuming datathread: it's already the thread itself, if I understand correctly:
<template name="datathread">
<hr />
{{#each posts}}
{{user}} says: {{text}}
<br />
{{/each}}
</template>
Also, the this in the threadlist event handler most certainly won't be the thread. I don't know the data of the tr in the threadlist (can you show that code?), but you will most probably do something like the following:
Session.set("selectedThread", this.id);
And for datathread:
Template.datathread.thread = function(){
return Threads.find({_id: Session.get("selectedThread")});
}
or similar.

AngularJS socket.IO Bootstrap Modals only once

I have a problem with bootstrap modal window when using AngularJS together with NodeJS and socket.io. I have been googling and it seems like it is issue that has a solution, but for some reason it doesn't work when I am trying to implement it together with Socket.io. I used modals on two different places - when I click on a static div (works perfectly), when I receive a message from webSockets (opens only once and then nothing). I guess I might have a problem in my JS code since the modal when I click on a static div works fine, but I don't know.
I have an address and I am sending some data via WebSockets to the client when this link is visited. The client event looks like this:
socket.on('patient', function(data){
modalInstance = $modal.open({
templateUrl: 'templates/patient.js',
controller: 'patientModalCtrl',
resolve: {
details: function(){return data;}
}
});
});
and:
socket.on('alergy',function(data){
modalInstance = $modal.open({
templateUrl: "templates/alergy.js",
controller: 'alergyModalCtrl'
});
});
Both of these work only once and then the modal window stops to appear. Interesting is, that when I emit "alergy", then again and then "patient" I get an "alergy" window and then patient window the second "alergy" window under it.
emiting looks like this:
app.get('/api/socket/hash/:hash', function(req, res){
var hash = req.params.hash;
//allergy
if(hash === "3fDecCD"){
connected_sockets[0].emit('alergy', {alergy: true});
res.json({status: true});
}
//patient detail
else if(hash === "Vc43Sf"){
connected_sockets[0].emit('patient', {name: 'Jan', surname: 'Bjornstad'});
res.json({status: true});
}
else{
res.json({status: false});
}
});
My template looks like this:
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header"></div>
<div class="modal-body" style="background-color: #FFD1D1;">
<h1 style="text-align: center; color: red;">Allergy!</h1>
<h2 style="text-align: center; color: red;">The patient is allergic to opium!</h2>
</div>
<div class="modal-footer">
<button class="btn btn-warning" ng-click="cancel()">Close</button>
</div>
</div>
</div>
I am using AngularJS 1.0.7, Bootstrap CSS 2.3.1
I would say that your socket-event listeners are firing "outside of AngularJS world" and as such AngularJS machinery is not kicking-in to do its 2-way data binding "magic". In precise terms, you are not entering AngularJS $digest loop so bindings are not updated, promises not resolved etc.
The easy fix is to wrap calls to AngularJS-specific code (here - call to the $modal service) into Scope.$apply method, ex.:
socket.on('alergy',function(data){
$scope.$apply(function(){
modalInstance = $modal.open({
templateUrl: "templates/alergy.js",
controller: 'alergyModalCtrl'
});
});
});

Dijit.MenuItem and <a href=></a> link

My question is similar to that one:
Dijit Menu (bar) with link
I'm using Dijit Menu as in following listing:
<div data-dojo-type="dijit/Menu">
<div id="menuItem" data-dojo-type="dijit/MenuItem">
urlLink
</div>
</div>
But link is not working as it blocked by dojo.stopEvent in _onClick().
The question is:
How to remove dojo.stopEvent and make link inside <div id="menuItem" data-dojo-type="dijit/MenuItem"> work properly?
The issue:
I need to put inside <div id=menuItem"> some code, which has to receive onClick event.
P.S. Originally this is XPages code.
Well I fell in same problem, saw this post and the related other, but wasn't satisfied with the "onclick" solution :
it didn't work (for me) with keyboard navigation
it imposes to a add script element (onclick=...) in the declarative zone which is not what I expect for unobtrusive JavaScript
Finaly I digged further in dojo and decided to directly use the href attribute of first sub-node in the handler. My script section (derived from dijit menus tutorial) is then :
<script>
require([
"dojo/dom",
"dojo/parser",
"dojo/dom-attr",
"dojo/query",
"dijit/registry",
"dijit/WidgetSet", // for registry.byClass
"dijit/Menu",
"dijit/MenuItem",
"dijit/MenuBar",
"dijit/MenuBarItem",
"dijit/PopupMenuBarItem",
"dojo/domReady!"
], function(dom, parser, domattr, query, registry){
// a menu item selection handler
var onItemSelect = function(event){
dom.byId("lastSelected").innerHTML = this.get("label");
var achild = query("a", this.domNode)[0];
if (achild != null) {
var href = domattr.get(achild, "href");
if ((href != null) && (href != '') && (href != '#')) {
window.location.href = href;
}
}
};
parser.parse();
var setClickHandler = function(item){
item.on("click", onItemSelect);
};
registry.byClass("dijit.MenuItem").forEach(setClickHandler);
registry.byClass("dijit.MenuBarItem").forEach(setClickHandler);
});
</script>
That way I don't have to change anything in a menu of type
<ul><li>...</li></ul>
that works with JavaScript disabled, and links work fine with mouse and keyboard navigation when JavaScript is enabled. Simply don't forget the "class='claro'" in body element ....
What about this:
<div data-dojo-type="dijit/Menu">
<div id="menuItem" data-dojo-type="dijit/MenuItem"
onclick="window.location('http://url.com')">
urlLink
</div>
</div>
Working jsfiddle:
http://jsfiddle.net/KuyYX/

Resources