BackboneJS Magnific Popup URL's - backbone.js

Is there a way to display a thumbnail of a youtube video in a BackboneJS view, then after clicking the thumbnail a lightbox opens and plays the video and at the same time the URL changes, so that you actually can send the URL-link?
I have a Backbone App where I list multiple Artists and when you click on one of those you get to an artist specific page where the user among other things can watch videos. So lets say you are on Lady Gaga's page and i click on a video, the Magnific Popup-opens with the video. But what I want to achieve i that the URL changes as well. something like ladygaga/videos/titleofvideo(or youtubelink):
Right now, in my Backbone View I have:
events: {
'click .video' : 'popUp'
},
popUp: function (e) {
e.preventDefault();
$('.video').magnificPopup({
disableOn: 700,
type: 'iframe',
mainClass: 'mfp-fade',
removalDelay: 160,
preloader: false,
fixedContentPos: false
});
}
The popup works fine, I just need the URL to change... Does anyone have an idea how to add this here if it is possible?
Thanks in advance...

Related

FullCalendar's dayClick not firing when a date is tapped

What I'm trying to do. Tap a day in the calendar and have show the details of that day's events in the area below it.
How I'm doing it. With Angular and the ui-calendar directive. In FullCalendar's dayClick event, I'm creating a new set of events that are happening on that day. In the template, I'm doing a typical ng-repeat="event in daysEvents" div. This works perfectly fine when I'm testing it in ionic serve.
The problem. The dayClick event doesn't work in the iOS emulator, when I send the app to my device (with ionic run ios) or Chrome Developer Tools "Toggle device mode".
The code. Here's my controller:
angular.module('starter.controllers', ['ui.calendar'])
.controller('CalendarCtrl', function($scope) {
$scope.eventSources = [
{
title: "Spring Awards Night",
start: moment("2015-5-19 18:30"),
description: "The Spring Awards are awesome and you should come."
}
]
$scope.uiConfig = {
calendar:{
height: 'auto',
editable: false,
header:{
left: 'prev',
center: 'title',
right: 'next'
},
dayClick: function(date, jsEvent, view) {
$scope.daysEvents = $scope.eventSources.filter(function(event){
return event.start.isBetween(date, moment(date).add(1, 'days'));
});
$(".fc-day").removeClass("fc-selected");
$(this).addClass("fc-selected");
}
}
};
And part of my template:
<div ui-calendar="uiConfig.calendar" ng-model="eventSources"></div>
If you need anything else, let me know. Thanks in advance.
1st solution:
This happens only when using UI-Calendar (FullCalendar) with Ionic, because Ionic catches all tap events. That's why it works fine for you in a desktop browser, but not in a mobile browser.
To solve this issue, add data-tap-disabled="true" to UI-Calendar directive, like this:
<div data-tap-disabled="true" ui-calendar="uiConfig.calendar" ng-model="eventSources"></div>
UPD - 2nd solution:
By disabling the Ionic tap listeners, you'll face the default browser's 300ms delays after each tap is made, which leads to an extremely poor user experience.
So, another solution for your question would be to select dates programmatically.
function onViewRender( view, element ){
// 1. Add tap listeners for each day (in my case - the date number element)
var matches = document.querySelectorAll(".fc-day-number");
_.forEach(matches, function(element){
$ionicGesture.on('tap', function (event) {
// 2. On tap - parse data-date attribute from the element
var selectedDateStr = $(event.target).attr('data-date');
// 3. And select an according day with uiCalendarConfig select method
uiCalendarConfig.calendars.mobileCal.fullCalendar('select', moment(selectedDateStr), moment(selectedDateStr).add(24,'h'));
}, angular.element(element));
});
}
In FullCalendar, if you drag on the day then the dayclick event is fired.
Other devices fire the dragstart and dragend events when you tap on the day, but iOS devices don't.
I had no choice but to modify fullcalendar.js. You can see my modified version here:
angularui-calendar-fullcalendar-dayclick-not-work-expectedly-on-ios

Loading mask does not show

I create a webpage which has some elements of ext js embedded in it. I am having a problem displaying a loading mask especially when there is so much data to load. In this example, I am using color box to create a popup window. Inside the popup window, I want to display ext js data grid where a user can select items. The problem is in the speed in which the grid loads. It takes a while before it fully loads.
The page is : http://ictpunt.be, click on the 'add offer' button to see the popup.
I would like to display a loading mask while it is loading. I have tried doing it on the viewport, but it only shows when the data is about to load. So a user has to look at the blank screen for close to 10 seconds before the loadmask msg appears! Here is a piece of my code
Ext.create('Ext.Viewport', {
items: [ contentPanel ],
renderTo: 'content',
loadMask: true,
viewConfig: {
loadingText: "Loading, please wait..."
},
....
});
You want the setLoading method on the instance of the Viewport that you are creating:
myViewport = Ext.create('Ext.Viewport', {
renderTo: 'body'
});
myViewport.setLoading('Loading, please wait...');
setTimeout(function () { myViewport.setLoading(false); }, 2000);

BackboneJS - Magnific popup not firing youtube video

I want to show youtube videos in the Magnific popup http://dimsemenov.com/plugins/magnific-popup/. The URl for the youtube video I get from a JSON file which I insert in my HTML with HandlebarsJS. So far so good, when I check the <a href> with the webinspector, the correct link is available.
Somehow though, when I click on it, the Magnific popup opens, but the youtube video is not firing, instead I get an error message. It seems like as soon the popup opens, or rather, when Magnific popup gets triggered, it completely disattaches itself from my BackboneJS App. Can this be true?
In my HTML (video.html) I have:
<a class="vidPopup" href="youtubelink here">
and in the Backbone View i created event:
template: 'video', //referring to the video.html
events: {
'click .vidPopup': 'seeVid'
},
seeVid: function(e) {
e.preventDefault();
$('.vidPopup').magnificPopup({
disableOn: 700,
type: 'iframe',
mainClass: 'mfp-fade',
removalDelay: 160,
preloader: false,
fixedContentPos: false
});
}
What could be the issue here?
I solved it myself! Since the Youtube API returns the ID of the youtube video I just had to do this:
<a class="vidPopup" href="https://www.youtube.com/watch?v={{id}}">
I didnt have to change the popup settings

Backbone JS view theory

I'm new to Backbone JS, and am having some trouble wrapping my head around a concept.
I have an interface with panels, where one panel is displayed at a time on the screen. Each panel is controlled by its own view, with its own model attached. Now, each panel as an "activator" tab that can be clicked to show the next panel.
In my mind, those tabs are actually sub-views of the parent panel view. Without a panel, the tab shouldn't exist. However, all tabs must appear on the screen at once, so that the user can switch between panels (views). So essentially all panels (their templates, anyway) would be loaded, but hidden until triggered by the click of a tab, at which time its content will be populated or else updated.
My problem, architecturally, comes with binding events to the tab views. So, for example:
window.PanelTabView=Backbone.View.extend({
className: 'view panel-tab-view',
el: '#appPanelTabs',
tagName: 'li',
events: {
'click a': 'test'
},
initialize: function() {
},
render: function(panel) {
this.$el.append(this.template(panel.toJSON()));
},
test: function(x) {
console.log(this.cid);
}
});
So when the tab is clicked, every click event is fired for all tab views.
Maybe I should treat all tabs as a single view, then? But I like the idea of each tab having it's own view from the point of modularity in the template.
Or maybe I'm missing something greater about Backbone and its MVC-esque approach.
What would you do in this scenario?
Why not have a parent view that simply manages the tabs and then simply delegates the click to the tab views? It would be a pretty simple approach.
Alternatively, you could be using a router, and in the router you could create your individual tab views based on a particular route taken. This would allow your page to be linkable.
First Approach:
ParentView = Backbone.View.extend({
el : '#your-tabs',
events : {
'click #tab1' : 'tab1',
'click #tab2' : 'tab2'
},
tab1 : function() {
var t1 = new Tab1();
t1.render();
},
tab2 : function() {
var t2 = new Tab2();
t2.render();
}
});
With a Router:
MyRouter = Backbone.Router.extend({
routes : {
"tab/1" : 'tab1',
"tab/2" : 'tab2'
},
tab1 : function() {
var t1 = new Tab1();
t1.render();
},
tab2 : function() {
var t2 = new Tab2();
t2.render();
}
});
Backbone isn't particularly opinionated about how views are constructed, but these seems to fit into their line of thinking.
Treating all tabs as a single view wouldn't make much sense. It would be silly to re-render all tabs just because the data on one tab changed.
I didn't understand much of your problem but at least I got that you in fact have only 1 button. Therefore you shouldn't have several views (it makes no sense anyway).
What you could do however, is use a "selected" attribute in your models which your views would listen to. So basically, when the user clicks on your button, you'll get the next panel thanks to your collection (I guess), unselect the former panel (set the selected attribute to false), therefore its view would disappear, and select the next, and its view would appear. I'll put some code later if you need.

event.preventdefault() not working after second render

I'm using brunch to work with backbone and I'm having issues with event.preventdefault(). It works initially, but after a page change it stops working.
I have a view that passes a param to the template and according to that the page is rendered. This page has multiple forms, and loads up one according to the param. All the forms have preventdefault bound to the submit buttons, but for some reason, after I switch forms using one of the nav links, the preventdefault stops working and the form gets posted. Any idea why this is the case? Let me know if you need to see code.
An example of how this happens:
I click 'submit story' nav link and type something and hit submit. I get the js alert and nothing happens. Now I click 'submit poem' and click submit, but this time the form gets posted. If I started off with 'submit poem' it works fine. It also works if I click 'submit poem' and hit refresh before submitting. Weird....
EDIT: Added Code Sample. Template renders acording to the passed in type.
class exports.ClientsSettingsView extends UberView
id: 'settings_view'
className: 'view_container'
events:
'submit #credit_card_form' : 'addCard'
'submit #profile_pic_form' : 'processPicUpload'
'submit #edit_info_form' : 'test'
'click #delete_card' : 'deleteCard'
render: (type="info",status=0) ->
$('.spinner#submit').hide()
#ReadUserInfo()
$(#el).html clientsSettingsTemplate {type,status}
#FadeIn()
#
addCard: (e) ->
e.preventDefault()
$el = $(e.currentTarget)
attrs =
card_number: $el.find('#card_number').val()
card_code: $el.find('#card_code').val()
card_expiration_month: $el.find('#card_expiration_month').val()
card_expiration_year: $el.find('#card_expiration_year').val()
options =
success: (response) ->
alert "Added"
error: (e) ->
alert "Error"
model = new app.models.paymentprofile
model.save attrs, options
console.log attrs
How are you loading the additional forms and submit buttons later on? if you are dynamically pulling them in, your event may no longer be attached. You could try binding your event to the form submit using jquery's live method.
.live()
I had the same problem.
A workaround
is to manually call delegateEvents() after the Backbone.View is added to the DOM.
The issue
I was calling subview.remove() which removes all DOM event listeners (via jQuery.remove) and used that same subview instance later on.
A solution
If a View has to remain active but must be temporary hidden use this.$el.hide() & this.$el.show()
In other situations don't reuse Backbone.View instances, but instantiate new ones.

Resources