How to rewrite this JQuery plugin into AngularJS - angularjs

I have a code here and i want to make it usable for AngularJS. this's the original plugin PAPER COLLAPSE i want to use it in a AngularJS project so i'll be able to Do ng-repeat
here's the jQuery Plugin's code
(function() {
(function($) {
'use strict';
$.fn.paperCollapse = function(options) {
var settings;
settings = $.extend({}, $.fn.paperCollapse.defaults, options);
$(this).find('.collapse-card__heading').add(settings.closeHandler).click(function() {
if ($(this).closest('.collapse-card').hasClass('active')) {
settings.onHide.call(this);
$(this).closest('.collapse-card').removeClass('active');
$(this).closest('.collapse-card').find('.collapse-card__body').slideUp(settings.animationDuration, settings.onHideComplete);
} else {
settings.onShow.call(this);
$(this).closest('.collapse-card').addClass('active');
$(this).closest('.collapse-card').find('.collapse-card__body').slideDown(settings.animationDuration, settings.onShowComplete);
}
});
return this;
};
$.fn.paperCollapse.defaults = {
animationDuration: 400,
easing: 'swing',
closeHandler: '.collapse-card__close_handler',
onShow: function() {},
onHide: function() {},
onShowComplete: function() {},
onHideComplete: function() {}
};
})(jQuery);
}).call(this);
Thank you

It's quite easy, see this plunk. You'll probably want to tune the css abit.
There's no solid way to do a css only slideUp/slideDown, but if you don't mind including jquery you can always add a watch on card.$active and do the slide via jquery.

Related

How to use VRView in Angular 1

VRview is not working and doesn't show me the 360 image. I am coding in Angular 1 app and trying to show 360 image. I tried photosphere viewer and now vrviewer but unable to understand regarding how to write the code in angular. Kindly assist
angular.module("MyControllers", [])
.controller("VR", function ($window) {
var onVrViewLoad = function() {
var vrView = new VRView.Player('#vrview', {
img: 'img/virtualTour.jpg',
is_stereo: false
});
}
$window.addEventListener('load', onVrViewLoad)
})
According to Google VR docs
To use VR View, include the Google-provided vrview.min.js script
within your HTML:
<script src="https://storage.googleapis.com/vrview/2.0/build/vrview.min.js"></script>
Video View
Your controller should be as follows. Instantiate the VR View as soon as the page loads which should be listening to the load event.
angular.module('VRApp', [])
.controller('VRController', function($window) {
var onVrViewLoad = function() {
var vrView = new VRView.Player('#vrview', {
video: 'https://storage.googleapis.com/vrview/examples/video/congo_2048.mp4',
is_stereo: true,
});
};
$window.addEventListener('load', onVrViewLoad);
});
Check out my Plunker for live demonstration.
Image View
I've tested it in IE 11 and it worked fine. Tried the below code
angular.module('myApp', [])
.controller('VRController', function($scope, $window) {
var onVrViewLoad = function() {
var vrView = new VRView.Player('#vrview', {
width: '60%',
height: '60%',
img: 'http://storage.googleapis.com/vrview/index.html?image=//storage.googleapis.com/vrview/examples/coral.jpg&is_stereo=true',
is_stereo: true,
});
};
$window.addEventListener('load', onVrViewLoad);
});
Output in IE 11

Why is angular-toastr not accepting the overriden postionClass.?

Plugin used: https://github.com/Foxandxss/angular-toastr
My intention is to create a toastr that spans the full with of the page on top and according to the documentation, positionClass: 'toast-top-full-width' will do the trick.
toastr.success('Hello world!', 'Toastr fun!', {
positionClass: 'toast-top-full-width'
});
A peek into the plugins css also validate the claim.
.toast-top-full-width {
top: 0;
right: 0;
width: 100%;
}
But somehow, the code doesn't work. Whats wrong with my code?
Plunkr: http://plnkr.co/edit/2O6hjk5vnMUWWULNK9hs?p=preview
You need to configure the toast in the angular config.
var app = angular.module('app', ['ngAnimate', 'toastr']);
app.config(function(toastrConfig) {
angular.extend(toastrConfig, {
positionClass: 'toast-top-full-width'
});
});
app.controller('toastr-demo', function($scope, toastr) {
toastr.success('Hello world!', 'Toastr fun!');
});
Plunker: http://plnkr.co/edit/pdstz2WkJqdi1Qw0R1pX?p=preview
Your problem is the toastContainer is not big enough, you should add a config like :
app.config(function(toastrConfig) {
angular.extend(toastrConfig, {
positionClass: 'toast-top-full-width'
});
});
This way, the container of all your toast will be full width, and then when you call a toast you can set his size to full-width.

How to check internet connection in AngularJs

This is how I would check internet connection in vanilla javascript:
setInterval(function(){
if(navigator.onLine){
$("body").html("Connected.");
}else{
$("body").html("Not connected.");
}
},1000);
I have angular controllers and modules in my project. Where should I put the code above? It should be executed in global context and not be assigned to a certain controller. Are there some kind of global controllers maybe?
First of all, I advise you to listen to online/offline events.
You can do it this way in AnguarJS:
var app = module('yourApp', []);
app.run(function($window, $rootScope) {
$rootScope.online = navigator.onLine;
$window.addEventListener("offline", function() {
$rootScope.$apply(function() {
$rootScope.online = false;
});
}, false);
$window.addEventListener("online", function() {
$rootScope.$apply(function() {
$rootScope.online = true;
});
}, false);
});
NOTE: I am wrapping changing of root scope's variable in $apply method to notify Angular that something was changed.
After that you can:
In controlller:
$scope.$watch('online', function(newStatus) { ... });
In HTML markup:
<div ng-show="online">You're online</div>
<div ng-hide="online">You're offline</div>
Here is a working Plunker: http://plnkr.co/edit/Q3LkiI7Cj4RWBNRLEJUA?p=preview
Other solution could be to broadcast online/offline event. But in this case you need to initialize current status upon loading and then subscribe to event.
It's definitely not as nice, but you could just try an AJAX request to your web server; it'll either succeed or time out.
Also, the HubSpot/offline project looks really good.
Your options:
addEventListener on the window, document, or document.body.
setting the .ononline or .onoffline properties on document or
document.body to a JavaScript Function object.
specifying ononline="..." or onoffline="..." attributes on the tag in
the HTML markup
I will demonstrate the easiest.
In you controller
document.body.onoffline = function() {
alert('You are offline now');
$scope.connection = 'offline'
}
document.body.ononline = function() {
alert('You are online again');
$scope.connection = 'online'
}
Check $scope.connection variable before you try to send requests around.
For Angular 2+ you can use ng-speed-test:
Just install:
npm install ng-speed-test --save
Inject into your module:
import { SpeedTestModule } from 'ng-speed-test';
#NgModule({
...
imports: [
SpeedTestModule,
...
],
...
})
export class AppModule {}
Use service to get speed:
import {SpeedTestService} from 'ng-speed-test';
#Injectable()
export class TechCheckService {
constructor(
private speedTestService:SpeedTestService
) {
this.speedTestService.getMbps().subscribe(
(speed) => {
console.log('Your speed is ' + speed);
}
);
}
}

Backbone boilerplate: "this.model is undefined"

I'm a backbone newbie, so I'm sort of fumbling on getting an app set up. I'm using the backbone-boilerplate (https://github.com/tbranyen/backbone-boilerplate) and github-viewer (https://github.com/tbranyen/github-viewer) as a reference, though when running I seem to be getting a "this.model is undefined".
Here is my current router.js:
define([
// Application.
"app",
//Modules
"modules/homepage"
],
function (app, Homepage) {
"use strict";
// Defining the application router, you can attach sub routers here.
var Router = Backbone.Router.extend({
initialize: function(){
var collections = {
homepage: new Homepage.Collection()
};
_.extend(this, collections);
app.useLayout("main-frame").setViews({
".homepage": new Homepage.Views.Index(collections)
}).render();
},
routes:{
"":"index"
},
index: function () {
this.reset();
this.homepage.fetch();
},
// Shortcut for building a url.
go: function() {
return this.navigate(_.toArray(arguments).join("/"), true);
},
reset: function() {
// Reset collections to initial state.
if (this.homepage.length) {
this.homepage.reset();
}
// Reset active model.
app.active = false;
}
});
return Router;
}
);
And my homepage.js module:
define([
"app"
],
function(app){
"use strict";
var Homepage = app.module();
Homepage.Model = Backbone.Model.extend({
defaults: function(){
return {
homepage: {}
};
}
});
Homepage.Collection = Backbone.Collection.extend({
model: Homepage.Model,
cache: true,
url: '/app/json/test.json',
initialize: function(models, options){
if (options) {
this.homepage = options.homepage;
}
}
});
Homepage.Views.Index = Backbone.View.extend({
template: "homepage",
el: '#mainContent',
render: function(){
var tmpl = _.template(this.template);
$(this.el).html(tmpl(this.model.toJSON()));
return this;
},
initialize: function(){
this.listenTo(this.options.homepage, {
"reset": function(){
this.render();
},
"fetch": function() {
$(this.el).html("Loading...");
}
});
}
});
return Homepage;
});
Thanks in advance for the help!
Update: After much googling (you should see how many tabs I have open), I think I made a little bit of headway, but still no luck. I updated my router to have the following:
app.useLayout("main-frame").setViews({
".homepage": new Homepage.Views.Index()
}).render();
I made a number of modifications to my homepage.js module to now look like this:
define([
"app",
["localStorage"]
],
function(app){
"use strict";
var Homepage = app.module();
Homepage.Model = Backbone.Model.extend({
defaults: function(){
return {
homepage: {}
};
}
});
Homepage.Collection = Backbone.Collection.extend({
//localStorage: new Backbone.LocalStorage("Homepage.Collection"),
refreshFromServer: function() {
return Backbone.ajaxSync('read', this).done( function(data){
console.log(data);
//save the data somehow?
});
},
model: Homepage.Model,
cache: true,
url: '/app/json/test.json',
initialize: function(options){
if (options) {
this.homepage = options.homepage;
}else{
//this.refreshFromServer();
}
}
});
Homepage.Views.Index = Backbone.View.extend({
template: "homepage",
el: '#mainContent',
initialize: function(){
var self = this;
this.collection = new Homepage.Collection();
this.collection.fetch().done( function(){
self.render();
});
},
render: function(){
var data = this.collection;
if (typeof(data) === "undefined") {
$(this.el).html("Loading...");
} else {
$(this.el).html(_.template(this.template, data.toJSON()));
}
return this;
}
});
return Homepage;
});
As you can see, I have localStorage code but commented out for now because I just want to get everything working first. The ultimate goal is to have an initial call that loads data from a JSON file, then continues afterwards using localStorage. The app will later submit data after the user does a number of interactions with my app.
I am getting the main view to load, though the homepage module isn't populating the #mainContent container in the main view.
I did all of the googling that I could but frustrated that it's just not sinking in for me. Thanks again for looking at this and any feedback is appreciated!
I think your class hierarchy is a bit wonky here. Your instance of Homepage.Collection is actually assigning a homepage property out of options, for instance. Then you pass an instance of Homepage.Collection into Homepage.Views.Index as the homepage option... It's a bit hard to follow.
That said, it seems to me your problem is simply that you aren't supply a model option when you construct your Homepage.Views.Index:
new Homepage.Views.Index(collections)
collections doesn't have a model property, and thus I don't see how this.model.toJSON() later on in the view can have a model to access. Basically, you seem to want Homepage.Views.Index to handle a collection of models, not just one. So you probably need a loop in your render function that goes over this.collection (and you should change your construction of the view to have a collection option instead of homepage option).
If I'm missing something here or I'm unclear it's because of this data model oddness I mentioned earlier. Feel free to clarify how you've got it reasoned out and we can try again :)
This example code you have is a little bit confusing to me, but I think the problem lies in the following two lines of code:
".homepage": new Homepage.Views.Index(collections)
$(this.el).html(tmpl(this.model.toJSON()));
It looks like you pass a collection to the view, but in the view you use this.model, hence the error "this.model is undefined", since it is indeed undefined.
If you aren't in any rush, may I suggest that you start over. It seems you are trying too much too quickly. I see that you have backbone, requirejs (or some other module loader), and the boilerplate, which is a lot to take in for someone new to backbone. Trust me, I know, because I am relatively new, too. Maybe start with some hello world stuff and slowly work your way up. Otherwise, hacking your way through bits of code from various projects can get confusing.

Backbone, Require, Jasmine view not rendering

For the life of me I can't seem to get my view to render HTML within a Jasmine test. I have been following all the tutorials I can find but nothing is working.
require(['../js/app', '../js/views/demand/match'], function(App, Match) {
App.initialize();
beforeEach(function() {
this.view = new Match();
});
describe("Instantiation", function() {
it("returns the view object", function() {
expect(this.view.render()).toEqual(this.view);
});
it("produces the correct HTML", function() {
this.view.render();
var expectedHtml = '<h2>MatchLinkTitle</h2>';
expect(this.view.el.innerHTML).toEqual(expectedHtml);
});
});
});
The above code always has a blank innerHTML property. The HTML associated to the match.js (match.html) file isn't showing up at all. Anyone have any ideas?

Resources