Masonry is not a function - vue-component

I am trying to use masonry in my application. Following is my component template.
<template>
<div>
<section class="section">
<div class="container">
<div class="row team">
<div class="col-md-4 col-sm-6 member" v-for="team in teamMembers">
<div class="team__item">
<div class="team__info">
<h4>{{team.name}}</h4>
<small>{{team.title}}</small>
</div>
</div>
</div>
</div>
</div>
</section>
</div>
</template>
<script src="https://unpkg.com/masonry-layout#4.1.1/dist/masonry.pkgd.min.js"></script>
<script>
export default {
data() {
return {
teamMembers: []
}
},
mounted() {
this.getTeamMembers();
},
methods : {
getTeamMembers : function() {
this.$http.get('teamMembers').then(response =>{
// console.log(response);
if(response.data.status=200) {
this.teamMembers = response.data.teamMembers;
this.$nextTick(function() {
var $container = $('.team');
$container.masonry({
columnWidth: '.member',
itemSelector: '.member'
});
})
}
})
}
}
}
</script>
I get the following error whenever the view is getting rendered.
TypeError: $container.masonry is not a function
Can you please let me know what I am doing wrong here ?

You can get vue component DOM element by this.$el. So you can do the following:
$(this.$el.querySelector('.team')).masonry({
columnWidth: '.member',
itemSelector: '.member'
});
But remember this is valid as long as your component is not a Fragment Instance i.e. it has a single root HTML tag.
You many need to put following script line in index.html, so that it loads properly.
<script src="https://unpkg.com/masonry-layout#4.1.1/dist/masonry.pkgd.min.js"></script>

Related

Fullcalendar custom view click on event

I am using fullcalendar 5 and have created a custom view according to the documentaion
In may calendar configuration I have added this eventClick: (info) => this.displayDetail(info) it work great with the default views but can't figure out how to trigger the eventClick from my customview
How could I trigger it.
Customview configuration:
import { sliceEvents, createPlugin } from '#fullcalendar/core'
const CustomViewConfig = {
classNames: ['list-view'],
duration: {
month: 1.5
},
buttonText: 'Planning',
content (props, element) {
let html = '<div class="row">'
const events = sliceEvents(props, false)
for (const event of events) {
html += `
<div class="col-12 col-md-6 event color-${event.def.sourceId}">
<div class="row mb-4">
<div class="col-4">
<div class="col-date">
<span>${event.range.start.getDate()} ${event.range.start.toLocaleString('default', { month: 'long' })}</span>
<span>${event.range.end.getDate()} ${event.range.end.toLocaleString('default', { month: 'long' })}</span>
</div>
</div>
<div class="col-8">
<div class="col-content">
${event.def.title}
</div>
</div>
</div>
</div>
`
}
html += '</div>'
return { html: html }
}
}
export default createPlugin({
views: {
custom: CustomViewConfig
}
});

Meteor Dynamic Template not working

The line {{> Template.dynamic template=content }} makes my page not load. It actually crashes my browser sometimes. I had it working for a while but something happened and now it does not work anymore.
{{> Template.dynamic template='navBar' }} works so my packages should be ok.
Meteor: 1.4
Packages: kadira:flow-router, kadira:blaze-layout
imports/ui/layouts/mainLayout.html:
<template name="mainLayout">
<header>
<div class="container">
{{> navBar }}
</div>
</header>
<body>
<div class="container">
{{> Template.dynamic template=content }} <!-- not working -->
</div>
</body>
<footer>
<div class="container">
<h3>Footer</h3>
</div>
</footer>
</template>
imports/ui/layouts/mainLayout.js:
import { Template } from 'meteor/templating';
import './mainLayout.html';
import '../components/navBar.html';
import '../pages/settings.html';
imports/startup/client/routes.js:
import { FlowRouter } from 'meteor/kadira:flow-router';
import { BlazeLayout } from 'meteor/kadira:blaze-layout';
import '../../ui/layouts/mainLayout.js';
import '../../ui/pages/settings.js';
FlowRouter.route('/', {
action() {
BlazeLayout.render('mainLayout', { content: 'mainLayout' });
},
});
FlowRouter.route('/settings', {
action() {
BlazeLayout.render('mainLayout', { content: 'settings' });
},
});
imports/ui/pages/settings.html:
<template name="settings">
<div class="container">
<h1>This is the settings page</h1>
</div>
</template>
This route:
FlowRouter.route('/', {
action() {
BlazeLayout.render('mainLayout', { content: 'mainLayout' });
},
});
is not going to work because you are inserting the mainLayout component into itself - the nested content helper is the issue. Instead, you should be rendering a different component into content:
BlazeLayout.render('mainLayout', { content: 'home' }); // or whatever component should be at "/"

Flick from a textarea to a ui-codemirror frame

I want to make an editor of files. By the following code (JSBin), we list all the file names on the left hand, and their body on the right hand. I use ui-codemirror to style the body of the files.
However, when we click on the file names and switch from one to another, from time to time, we could see the quick flick from a textarea to a codemirror frame, which is not a good experience for an editor.
Does anyone have a solution to avoid the flick? Addtionally, is it a good direction to make an editor by angularJS and ui-codemirror?
<html ng-app="flapperNews">
<head>
<link rel="stylesheet" href="https://codemirror.net/lib/codemirror.css">
<script src="https://code.jquery.com/jquery.min.js"></script>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" rel="stylesheet" type="text/css" />
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.7/angular.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-router/0.3.2/angular-ui-router.js"></script>
<script src="https://codemirror.net/lib/codemirror.js"></script>
<script src="https://codemirror.net/mode/xml/xml.js"></script>
<script src="https://codemirror.net/mode/htmlmixed/htmlmixed.js"></script>
<script src="https://codemirror.net/mode/javascript/javascript.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui/0.4.0/angular-ui.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.11.0/ui-bootstrap-tpls.js"></script>
<script>
var app = angular.module('flapperNews', ['ui', 'ui.router']);
app.config(['$stateProvider', function ($stateProvider) {
$stateProvider
.state('file', {
template: '<textarea ui-codemirror="editorOptionsHTML" ng-model="file.body"></textarea>',
controller: 'FileCtrl',
params: { name: null }
})
}]);
app.controller('MainCtrl', ['$scope', '$state', function ($scope, $state) {
$scope.files = [
{ name: "index.html", body: "<html><body>index.html</body></html>" },
{ name: "index.js", body: "the body of index.js" },
{ name: "test.html", body: "the body of test.html" }];
}]);
app.controller('FileCtrl', ['$scope', '$stateParams', function ($scope, $stateParams) {
$scope.file = $scope.files.find(function (file) { return file.name === $stateParams.name });
$scope.editorOptionsHTML = { mode: 'text/html', lineNumbers: true, matchBrackets: true };
}]);
</script>
</head>
<body ng-controller="MainCtrl">
<div class="row">
<div class="col-sm-3 col-md-3 col-xl-3 col-lg-3">
<div ng-repeat="file in files track by $index">
<a ui-sref="file({name: file.name})">{{file.name}}</a>
</div>
</div>
<div class="col-sm-9 col-md-9 col-xl-9 col-lg-9">
<ui-view></ui-view>
</div>
</div>
</body>
</html>
Every time you click on the link, it is creating new editor, which is an expense operation.
The best approach is to create one editor and load the content on every click.
so I removed the ui-router linking (ui-sref) and related controllers
<script>
var app = angular.module('flapperNews', ['ui', 'ui.router']);
app.controller('MainCtrl', ['$scope', '$state', function ($scope, $state) {
$scope.files = [
{ name: "index.html", body: "<html><body>index.html</body></html>" },
{ name: "index.js", body: "the body of index.js" },
{ name: "test.html", body: "the body of test.html" }];
$scope.editorOptionsHTML = { mode: 'text/html', lineNumbers: true, matchBrackets: true };
// for every click event it will load the content
$scope.go=function(file){
$scope.file=file;
}
}]);
and the body
<body ng-controller="MainCtrl">
<div class="row">
<div class="col-sm-3 col-md-3 col-xl-3 col-lg-3">
<div ng-repeat="file in files track by $index">
<a ng-click="go(file)">{{file.name}}</a>
</div>
</div>
<div class="col-sm-9 col-md-9 col-xl-9 col-lg-9">
<textarea ui-codemirror="editorOptionsHTML" ng-model="file.body"></textarea>
</div>
</div>
</body>
Example : JSBin
you could avoid the flick by adding hide class to textarea like the following code ( jsbin )
template: '<textarea class="hide" ui-codemirror="editorOptionsHTML" ng-model="file.body"></textarea>',

change element style in method callback

This code is trying to add a class to an element. the class definition is located in meteor_app_root/stylesheets/style.css .wrongInput { color: red; }
This method returns fine but the text inside the input element is not changing to red as I am expecting.
edited
I get browser console print "server returned" but the addClass line is not doing its work.
edited
changing the style from color: Red; to border-color: Red; makes the boarder colour red.
What am I doing wrong? Thanks
Template.footer.events({
'click button': function () {
var doc = {};
$('input').each(function () {
this.value && (doc[this.name]=this.value)
});
Meteor.call('processInputs', doc, function (err, res) {
if (res) {
console.log("res " + res);
$('[name="plate"]').addClass("wrongInput");
}
});
}
});
//server.js
Meteor.methods({
processInputs: function (doc) {
return "server acted";
}
});
<template name="content">
<div class="container">
<div class="row">
<section class="col-xs-12">
<form>
<ul class="list-group">
{{#each this.items}}
<li>
<input class="list-group-item basic-vertical-spacing col-xs-12" type="text"
name={{name}} placeholder={{placeholder}}>
</li>
{{/each}}
</ul>
</form>
</section>
</div>
</div>
</template>
I see what it is, you didn't have the if(err):
Meteor.call('myFunction', function(err, data) {
if (err)
{
$('[name="plate"]').addClass("wrongInput");
}
});

Unable to access data from Meteor in React

When trying to access the root page I get a blank screen with no layout. I check developer tools and get an error in App.jsx
Uncaught TypeError: Cannot read property 'loggedIn' of undefined
This is my App component:
App = React.createClass({
mixin: [ReactMeteorData],
getMeteorData() {
return {
loggedIn: !!Meteor.user()
};
},
showLayout() {
return (
<div className="container-fluid main-container">
<div className="col-xs-3">
{this.props.nav}
</div>
<div className="col-xs-9">
{this.props.content}
</div>
</div>
)
},
showLogin() {
return (
<div className="row">
<div className="col-xs-12 text-center">
<p>You must be logged in to do that.</p>
</div>
<Login />
</div>
)
},
render() {
return(
<div className="container-fluid main-container">
<div className="row">
{ this.data.loggedIn ? this.showLayout() : this.showLogin() }
</div>
</div>
)
}
});
I'm not sure what the issue can be, I'm following along a tutorial.
You should have this:
mixins: [ReactMeteorData],
instead of this:
mixin: [ReactMeteorData],
(Note the 's')

Resources