i'm using backbone.js to build my frontend.
So what i want to do is, to render a view in a "lightbox" (the same way like pinterest).
I tried it that way:
var itemDetailsBoxView = CloseableView.extend({
el: '#itemwrapperItemBox #itemwrapperItem2',
initialize: function(options) {
var self = this;
self.render(options);
},
render: function(options) {
$('#itemwrapperItemBox').fadeIn(300);
var self = this;
app._itemDetailsView = new itemDetailsView({id: options.id, el: '#itemwrapperItemBox #itemwrapperItem2'});
self.rendered(app._itemDetailsView);
},
events: {
'keydown': 'keydownHandler'
},
keydownHandler: function(e) {
switch (e.which) {
// esc
case 27 :
$('#itemwrapperItemBox').hide();
break;
}
}
This view just opens another view (itemDetailsView) in a lightbox. This itemDetailsBoxView is opened when i click on an item:
itemDetails: function(events) {
var self = this;
var that = $(events.currentTarget).parents('.item');
var id = that.find('.covercontainer').find('img').data('id');
if (app._itemDetailsBox) {
app._itemDetailsBox.close();
}
app._itemDetailsBox = new itemDetailsBoxView({id: id});
self.rendered(app._itemDetailsBox);
app.navigate("/collage/" + id, false);
},
However, there are several problems with this approach:
When the itemWrapperItem2 appears (like a pin on Pinterest when you zoom in), there are two scrollbars. One for the itemStream in the background and one for the lightbox.
The itemDetailsView generates also an itemStream. When i click there on an item, it loads again in the itemDetailsBoxView and also pushes the url (Same functionality, when u have a pin open and click again on a pin). This means, that when i want to go back to the original itemStream, i have a problem because i don't know the URL.
There are more - but this is enough to see, that this approach doesn't work to good. So do you know a solution for backbone.js to copy the whole pinterest "zoom in on a pin" functionality (including, that you land on another page when you reload the pin).
This is my first post here - please be gentle if this post has to less description :)
Related
We have a WordPress theme serving as an online directory. This theme uses a JSON file to display our listings on our map. For each of our modifications on a listing we must click on a button named "JSON Generator" to update the data of the map.
The problem is that we are currently adding/modifying a lot of content on our map so it requires a lot of manual regenerations.
Screenshot of the button and the HTML declaration
Is there a way to replace the click launch of the JavaScript function regenerating the JSON by an automatic launch every 24 hours for example?
Here is the start of my actual .js file :
;(function($) {
// Json Generator
var directoryManagerAdmin = function() {
this.param = lava_dir_admin_param;
this.init();
}
directoryManagerAdmin.prototype.constructor = directoryManagerAdmin;
directoryManagerAdmin.prototype.init = function() {
var self = this;
$(document)
.on('click', '.lava-data-refresh-trigger', this.onGenerator())
.on('click', '.fileupload', this.image_upload())
.on('click', '.fileuploadcancel', this.image_remove())
$('button[data-listing-type-generator]').each(function() {
var listingType = $(this).data('listing-type-generator') || false;
var Instance = self.onGenerator(listingType);
$(this).on('click', Instance);
});
self.bindJsonEditor();
}
directoryManagerAdmin.prototype.onGenerator = function(type) {
// THEN YOU HAVE THE VERY LONG FUNCTION...
I think that I have to replace the launcher: .on( 'click', '.lava-data-refresh-trigger', this.onGenerator() ) with an automatic launcher every 24 hours or so.
I found out how to get the current date: var date = new Date().toLocaleDateString();, I also know that I may have to use the setInterval action but I don't know how to use it.
Thanks by advance if you have any clue to help me !
I have tried various snippets of code that I've found online, but I can't get any of them to work with the current version of VideoJS, which is version 7. I'm very new to javascript programming, and the documentation does not give example code on how to implement this. There is a codepen here that can be used to experiment with customizing the player: https://codepen.io/heff/pen/EarCt This is the link to the VideoJS player documentation on adding a button to the player: https://docs.videojs.com/button
I've tried inserting code from various web page and 5-6 different discussions I found on StackExchange, but none of them make a button appear next to the video progress bar.
I'm simply trying to create a button with the text "Exit Course" that will appear to the right of the video progress bar, and that will execute a javascript function when pressed.
Could someone familiar with VideoJS please take a look at the codepen link above to see if they can add such a button to the player? Thank you!
I'm required to add some code to this question, so here is one piece of code that I tried on codepen:
var setup = {
'techOrder' : ['html5', 'flash'],
'controls' : true,
'preload' : 'auto',
'children':{
'controlBar': {
'children': {
'playbackSpeedPopoverMenu': {},
'selectBitrateControlButton': {src:videosrc},
'verticalVolumeMenuButton': {},
'volumeControl': false,
'muteToggle':false,
'liveDisplay':false,
}
}
};
var player = new vjs.Player(vjs.el("id_of_my_video_element_note_that_theres_no_poundsign"),
setup,
function() {
//this is your ready function
}));
I've tested this snippet with video.js 7.4.1 and it works fine. I used video.js's cancel icon instead of text to save space on the control bar. Give it a try:
<script>
var player = videojs('my-player');
var button = videojs.getComponent('Button');
var closeButton = videojs.extend(button, {
constructor: function() {
button.apply(this, arguments);
this.controlText("Exit Course");
this.addClass('vjs-icon-cancel');
},
handleClick: function() {
this.player().dispose();
}
});
videojs.registerComponent('closeButton', closeButton);
player.getChild('controlBar').addChild('closeButton', {});
</script>
var player = videojs('video');
var skipBehindButton = player.controlBar.addChild("button");
var skipBehindButtonDom = skipBehindButton.el();
skipBehindButtonDom.innerHTML = "30<<";
skipBehindButton.addClass("buttonClass");
skipBehindButtonDom.onclick = function(){
skipS3MV(-30);
}
var skipAheadButton = player.controlBar.addChild("button");
var skipAheadButtonDom = skipAheadButton.el();
skipAheadButtonDom.innerHTML = ">>30";
skipAheadButton.addClass("buttonClass");
skipAheadButtonDom.onclick = function(){
skipS3MV(30);
}
function skipS3MV(skipBy) {
player.currentTime(player.currentTime() + skipBy);
}
The reason I've used text ("30<<" and ">>30") is because in my player, the colors are all customizable. So if I used an icon image for skip-back and skip-forward, then I wouldn't be able to change the color of the icon every time someone customizes the player colors (which includes the all the text in the control bar).
I’m pretty new to backbonejs and i’m trying to create a basic application.
The application is something like this:
I have 5 sections: A, B, C, D and E
Each section has 2 radio buttons.
Section A - Radio1, Radio2
Section B - Radio3, Radio4
Section C - Radio5, Radio6
Section D - Radio7, Radio8
Section E - Radio9, Radio10
Depending on what radio button is selected, I need to display a section (previous sections must also display)
I have had a look at maybe using a model to determine which radio was selected and also what section is displayed. Is this the correct approach?
var State = Backbone.Model.extend({
defaults: {
id: null,
name: "",
isOn: false
}
});
var Section = Backbone.View.extend({
model: State,
events: {
'change [type="checkbox"]': function (event) {
var $checkbox = $(event.target);
this.model.set("isOn", $checkbox.is(":checked"));
this.model.get("dispatcher").trigger("toggle", this.model.get("id"));
}
},
initialize: function (options) {
this.listenTo(this.model, "change:isOn", function (model, isOn) {
if ( isOn ) {
this.$el.find(".section").show();
this.$el.find("input").prop("checked", true);
}
else {
this.$el.find(".section").hide();
this.$el.find("input").prop("checked", false);
}
});
this.listenTo(dispatcher, "toggle", function (id) {
if ( this.model.get("id") < id ) {
this.model.set("isOn", true);
}
if ( this.model.get("id") > id ) {
this.model.set("isOn", false);
}
});
},
render: function () {
this.$el.html('<div>' + this.model.get("name") + '</div><input type="checkbox"><div class="section" style="min-height:100px; background-color:grey; display:none;"></div>');
this.$el.appendTo("body");
}
});
var dispatcher = _.extend({}, Backbone.Events);
_.each([
{id: 1, name: "A", isOn: false, dispatcher: dispatcher},
{id: 2, name: "B", isOn: false, dispatcher: dispatcher},
{id: 3, name: "C", isOn: false, dispatcher: dispatcher},
{id: 4, name: "D", isOn: false, dispatcher: dispatcher},
{id: 5, name: "E", isOn: false, dispatcher: dispatcher}
], function (item) {
var view = new Section({model: new State(item)});
view.render();
});
I didn't understand the meaning of two radio.. so I used checkbox per section.. Hope this will uncover some basics of backbone.
Yes this approach will work. I recommend if you need to communicate between views to use models via events - this will generally result in better architecture (your views will be more decoupled).
You can react to the change event in the view (using the events hash) and update an attribute on a model for each group, e.g. this.model.set('termsAccepted', true/false) then as long as the other view(s) have access to this model you can react to the change event of that attribute, e.g. this.listenTo(this.model, 'change:termsAccepted', this.onTermsAcceptedChange).
There may be a very simple solution to your objective. If you monitor the radio-button state via a javascript function, then you can use that function to change a class statement for the parent div. In CSS, you can then define actions to hide or display a div based on it's class. This would only take a few lines of javascript and a few lines of CSS.
For example, this example in codepen shows a way to accomplish the hide/show for a variably sized div. The number of divs in this approach is arbitrary - you can have as many or few as you like, and the only action required of the user is to click on the header to expand or collapse the associated div. In this example, clicking on the header acts as a toggle to expand or collapse the associated div. The example is set up so that only one div is expanded at a time and clicking on a different header automatically collapses any open div so that only one div is open at a time. If you do not want that behavior, just remove the for loop in the accOff() function.
It's kinda like a choose-your-own-adventure, ya sipher_z?
I advise using the Backbone Router with route parameters storing the current state, that is, which section is currently showing.
Each component of the view should be a Backbone.View.extend({...}). Components might be Section and Radio.
On each Radio button, in HTML, put a data-go-to attribute, with a value of the section to go to next. Then, in your RadioView code, put a click event. When clicked, extract this data-go-to, and do something like location.hash = '/section/' + section to trigger your router.
Then, all your router does is hide all the Sections except the selected one whenever triggered. If there's no selection, it just shows the first one!
I'm not 100% sure of this strategy, but this is definitely "the Backbone way". Let me know if I can clear anything up.
I need functionality for book library and for that I have used:
Turn.js, which is used for flipbook effect (only 3rd release working, 4th release not working with it, if someone have similar functionality with 4th release of turn.js, then please share your code).
pdf.js, which converts PDF to HTML on client side
This is a reference link, that I have followed.
I have modified one function for using that script dynamically, which adds PDF's path into that function and according to that link, books open in popup.
Here is the JavaScript function for that:
function display_book(path){
var url = path;
PDFJS.disableWorker = false;
PDFJS.getDocument(url).then(function(pdfDoc) {
numberOfPages = pdfDoc.numPages;
pdf = pdfDoc;
$('#book').turn.pages = numberOfPages;
$('#book').turn({acceleration: false,
pages: numberOfPages,
elevation: 50,
gradients: !$.isTouch,
// display: 'single',
when: {
turning: function(e, page, view) {
// Gets the range of pages that the book needs right now
var range = $(this).turn('range', page);
// Check if each page is within the book
for (page = range[0]; page<=range[1]; page++) {
addPage(page, $(this));
//renderPage(page);
};
},
turned: function(e, page) {
$('#page-number').val(page);
if (firstPagesRendered) {
var range = $(this).turn('range', page);
for (page = range[0]; page<=range[1]; page++) {
if (!rendered[page]) {
renderPage(page);
rendered[page] = true;
}
};
}
}
}
});
$("button.close").click(function(){
//code for destroy pdfjs object
$(".modal").css({"display":"none"});
});
});
}
on that popup close event, I want to destroy object of PDFJS (to release memory). In this code turn.js 3rd released version is used, and if I replace that version with 4th release then code doesn't work.
You just need to call destroyon the pdfDoc instance.
In your code sample, it looks like pdfDoc is assign to the global variable pdf. So, this should do what you want:
pdf.destroy();
I am using JQuery 1.3.2-min in a project to handle JavaScript animations, ajax, etc. I have stored the file on the same server as the site instead of using Google. When I run the site locally on my development machine, everything works fine in FF, IE, Opera, and Safari (all the latest versions - I work from home and I only have 1 machine for personal use and development use) except for some CSS differences between them and when I go to the live site on my machine it works fine also. I have cleared my caches and hard refreshed the page, and it still works.
This is where it gets interesting however. When I send the site to my boss to test in various OS/Browser configurations, one page doesn't work correctly, some of it works, some doesn't. Also, the client (who uses IE 8) has also confirmed that it is not completely working - in fact he has told me that the page will work fine for a hour, and then just "turn off" for a while. I have never heard of this sort of thing before, and google isn't turning too much up. I have a hunch it may partly be with JQuery's .data(), but I'm not sure.
The page is basically nested unordered lists, and three basic actions happen on the list.
The top most unordered list is set to visible (all list via css are set to display: none to keep them hidden on a fresh page request); all list items divs are given a hover action of full opacity on mouseon, and faded back to 50% opacity on mouseoff; and then whenver a paragraph is clicked, the top most unordered list in that list item is displayed.
Here is my Javascript file for the page:
$(function() {
// Set first level ul visible
$('div#pageListing ul:first').css('display', 'block');
// Disable all the hyperlinks in the list
$('div#pageListing li a').click(function() {
var obj;
obj = $(this).parent(0).parent('div:first');
highlight(obj);
return false;
});
// List Item mouse hovering
$('#pageListing li').hover(
// Mouse On
function() {
if ($(this).children('div').attr('id') !== 'activePage') {
$(this).children('div').css('opacity', 1).css('filter',
'alpha(opacity=100)');
}
}, // Mouse off
function() {
if ($(this).children('div').attr('id') !== 'activePage') {
$(this).children('div').css('opacity', 0.4).css('filter',
'alpha(opacity=40)');
}
});
// Active list item highlighting
$('#pageListing li div').click(function() {
highlight($(this));
});
// Sub-list expanding/collapsing
$('#pageListing p.subpageslink').click(function() {
// Get next list
var subTree = $(this).parent('div').next('ul');
// If list is currently active, close it, else open it.
if (subTree.data('active') != true) {
subTree.data('active', true);
subTree.show(400);
} else {
subTree.data('active', false);
subTree.hide(400);
}
});
// Double clicking of list item - edit a page
$('#pageListing li div').dblclick(function() {
var classes = $(this).attr('class');
var classArray = classes.split(' ');
var pageID = classArray[1];
editPage(pageID);
});
// Handle button clicking
$('button#addPage').click(function() {
addPage();
});
$('button#editPage').click(function() {
var div = $('div#activePage');
var classes = div.attr('class');
var classArray = classes.split(' ');
var pageID = classArray[1];
editPage(pageID);
});
$('button#delPage').click(function() {
var div = $('div#activePage')
var classes = div.attr('class');
var classArray = classes.split(' ');
var pageID = classArray[1];
delPage(pageID);
});
});
// Highlighting of page when clicked
function highlight(obj) {
// Get previous hightlighted element
// and un-highlight
var oldElement = $('div#activePage');
oldElement.css('background', 'white');
oldElement.css('opacity', 0.4).css('filter', 'alpha(opacity=40)');
oldElement.removeAttr('id');
// highlight current selection
obj.attr('id', 'activePage');
obj.css('opacity', 1).css('filter', 'alpha(opacity=100)');
obj.css('background', '#9dc0f4');
// add appropiate action buttons
$('button.pageButton').css('display', 'inline');
}
function addPage() {
window.location = "index.php?rt=cms/editPage";
}
function delPage(page) {
var confirm = window.confirm("Are you sure? Any sub-pages WILL BE deleted also.");
if (confirm) {
var url = './components/cms/controller/forms/deletePage.php';
$.ajax( {
url : url,
type : 'GET',
data : 'id=' + page,
success : function(result) {
if (!result) {
document.location = "index.php?rt=cms";
} else {
window.alert('There was a problem deleting the page');
}
}
});
}
}
function editPage(page) {
var url = "index.php?rt=cms/editPage/" + page;
window.location = url;
}
Is it possible that you are linking to (some of) the script files using a src that points to a file on your local disk/HDD? If so, that would explain why it works only on your machine, as then only your machine has access to the script file.
Thank you one and all for your suggestions. The end problem was miscommunication. I work from home, and upload my projects to a SVN server, which the boss then uses to update the live server. Somehow, the correct files were not getting updated - a communication error on my part. Another possible reason was that the page, while being declared XHTML 1.0 Strict, had something like 50 validation errors (mosting incorrectly nested UL), and I cleaned that up to 5 errors. So thank you all, but again a sad example of the importance of team work communication.