i'm new to Meteor and and i want to learn something about it. therefore i want to build a page were i can upload images via meteor-dropzone.
the upload is working with meteor-uploads.
now i want to get events, like 'addedfile' or 'drop' from the dropzone to fire some new functions.
HTML Page Profile2:
<template name="profile2">
<div class="ibox-content">
{{> dropzone url='http://localhost:3000/uploads' maxFilesize=5 addRemoveLinks=true acceptedFiles='image/*,jpg,jpeg,png' id='dropzoneDiv'}}
</div>
</template name="profile2">
In The JS File for Profile2 i wrote this:
Template.dropzone.events({
'addedfile #dropzoneDiv': function(e, template){
e.preventDefault();
console.log("Hello");
}
});
But i don't see something in the console.log output.
I'm sure i'm doing something wrong. But i have no i idea where the problem or the wrong understanding is.
Can somebody help me please.
Thanks.
Michael
after try and error. i found the solution. Maybe someone can explain it to me. because i don't understand it completely, why it's working now but so different to the normal Meteor event version.
Dropzone.options.dropzoneDiv = {
init: function() {
this.on("addedfile", function(file) { alert("Added file."); });
}
};
The Template like that:
<!-- Page heading -->
{{> pageHeading title='File upload' category='Forms' }}
<div class="wrapper wrapper-content animated fadeIn">
<div class="row">
<div class="col-lg-12">
<div class="ibox float-e-margins">
<div class="ibox-title">
<h5>Dropzone Area</h5>
{{>iboxTools}}
</div>
<div class="ibox-content">
<!-- For more info about dropzone plugin see this: https://github.com/devonbarrett/meteor-dropzone/ -->
{{> dropzone url='/uploads' id='dropzoneDiv'}}
</div>
</div>
</div>
</div>
</div>
</template>
Try the dropped event:
'dropped #dropzoneDiv' (e, template) => {
e.preventDefault();
console.log(e.originalEvent.dataTransfer.files); // this will contain the list of files that were dropped
}
Related
As the title says, this.render does not render a template it's provided with. This is the code in router.js:
Router.configure({
layoutTemplate: 'main'
});
Router.route('/', function(){
this.render('postsList');
});
The file containing the layout template, main.html:
<template name='main'>
<div class='container'>
<header class='navbar'>
<div class='navbar-inner'>
<a class='brand' href='/'>MyApp</a>
</div>
</header>
<div id='main' class='row-fluid'>
{{> yield}}
</div>
</div>
</template>
And the file containing the postsList template which is passed to this.render() function
<template name='postsList'>
<div class='posts'>
{{#each posts}}
{{> postItem}}
{{/each}}
</div>
</template>
So when I go to localhost:3000/ the page displays only the main template and not the postsList template. However, there is no error, unless I completely remove Router.route(...), at which point it will display the standard 'route not found' error.
Also, I tried not using the global template, but a route template, by removing Router.configure(...) and adding this.layout('main') to Router.route(...). The browser then displays nothing.
Your code is perfectly fine. I also came across this issue. The iron:router package seems to be missing the ejson dependancy.
Add the ejson to your app and it should work.
meteor add ejson
I'm sure when iron:router is updated this will be resolved.
I have created a test project with Meteor which uses Masonry. I added the package mrt:jquery-masonry(or isotope:isotope), and it works well at the beginning. However, the problem comes now.
Basically, I want to implement the feature that when user clicks the button, the page will be added one more div. Below is my code:
main.html
<body>
<div class="container">
{{> masonryContent}}
</div>
<script>
(function($){
var $container = $('.masonry-container');
$container.masonry({
columnWidth: 300,
gutterWidth: 50,
itemSelector: '.masonry-item'
})
}(jQuery));
</script>
</body>
style.css
.masonry-item {
width: 300px;
}
masonry-content.html
<template name="masonryContent">
<div class="masonry-container">
<div class="masonry-item">
<p>blabla...</p>
<p>
Button
</p>
</div>
<div class="masonry-item">
<p>test...</p>
</div>
<div class="masonry-item">
<p>another test...</p>
</div>
{{#if showItem}}
<div class="masonry-item">
<p>new added item...</p>
</div>
{{/if}}
</div>
</template>
masonry-content.js
Template.masonryContent.events({
"click #click-me": function(e) {
e.preventDefault();
Session.set('show_me', true);
}
});
Template.masonryContent.helpers({
showItem: function() {
return !!Session.get('show_me');
}
});
The problem is when I click the button, the new div was created; however, it wasn't placed by following Masonry rules. The new created item just overlapped to the first item, but I expect it performs the way to append to the last item.
I would appreciate if anyone could help me on this.
Thanks in advance!
As meteor does partial rendering the element needs to be there in the DOM for masonry to work. So there are two ways of getting over the problem
1) Hide or unhide the element when the button click happens
Or
2) re-render the DOM
You can use the chrome dev tools to see what DOM elements are touched/refreshed (Green color).
There is a typo in masonry in the template name insertion.
Check the package state, many mrt packages are not well supported anymore.
I'm having a problem to insert a template after and not before a node. For example:
//Html looks like this
<div class="questions">
<div class="question"></div>
<div class="question"></div>
<div class="question"></div>
</div>
<template name="question">
<div class="question"></div>
</div>
<template name="questionExtraInfo">
<div class="extra"></div>
</template>
I'm trying to get the following:
<div class="questions">
<div class="question"></div>
<div class="extra"></div>
<div class="question"></div>
<div class="question"></div>
</div>
Calling blaze render inside question event
Template.question.events({
'click .more-details': function () {
var instance = Template.instance();
Blaze.renderWithData(Template.questionExtraInfo, {}, document.querySelector('.questions'), instance.find('.question')));
});
I can only figure out how render it before or inside how about after?
<div class="extra"></div>
<div class="question"></div>
<div class="question"><div class="extra"></div></div>
I think a better approach would be to take advantage of reactivity:
Change your questions template to:
<template name="question">
<div class="question"></div>
{{# if shouldIncludeExtra }}
{{> questionExtraInfo }}
{{/if}}
</template>
The above template should be inside an each loop.
Then in your js something like:
Template.question.helpers({
'shouldIncludeExtra': function() {
// replace 'n' with the actual index. I think `this.index` is
// provided within #each blocks, or you can use the new `#each` helper.
var index = n;
return Session.get('shouldIncludeExtra' + index);
}
});
Then, in your click event, you set a session var based on the index to true:
Template.questions.events({
'click .question': function(e, tpl) {
var question = e.currentTarget;
// You can probably come up with something better here..
var index = $(question).parent().find('> .question').index(question);
Session.set('shouldIncludeExtra' + index, true);
}
});
Because of reactivity, you would see the inserts right away when you fire the click event.
I realize this doesn't really answer the headline of your question, but it should get you the desired outcome.
I'm struggling with fullpage.js in Meteor.
When I add a button inside a template, the Template.templatename.events function does not fire on event.
For example:
Template HTML (messages.html)
<template name="messages">
<ul>
{{#each mess}}
<li>{{ messContent}}</li>
{{/each}}
<button class="addMessage">Add Message!</button>
</ul>
</template>
Template JavaScript (messages.js)
Template.messages.helpers({
mess: function(){
return Messages.find();
}
});
Template.messages.events({
'click .addMessage' : function(event){
console.log("clicked")
}
})
Main HTML
<head>
<title>fulltest</title>
</head>
<body>
{{> full}}
</body>
<template name="full">
<div id="fullpage">
<div class="section active">
<h1>First slide</h1>
{{> messages}}
</div>
<div class="section">
<h1>Second slide</h1>
</div>
</div>
</template>
My fullpage initialisation:
Template.full.rendered = function(){
$('#fullpage').fullpage();
}
If I remove the fullpage initialisation then the click event gets logged. Still new at Meteor, I didn't manage to grasp what's going wrong here.
All help much appreciated,
Joris
Use delegation or use verticalCentered:false and scrollOverflow:false.
From the fullPage.js FAQs:
My javascript/jQuery events don't work anymore when using fullPage.js
Short answer: if you are using options such as verticalCentered:true or overflowScroll:true in fullPage.js initialization, then you will have to treat your selectors as dynamic elements and use delegation. (by using things such as on from jQuery). Another option is to add your code in the afterRender callback of fullpage.js
Explanation: if you are using options such as verticalCentered:true or overflowScroll:true of fullPage.js, your content will be wrapped inside other elements changing its position in the DOM structure of the site. This way, your content would be consider as "dynamically added content" and most plugins need the content to be originally on the site to perform their tasks. Using the afterRender callback to initialize your plugins, fullPage.js makes sure to initialize them only when fullPage.js has stopped changing the DOM structure of the site.
I'm really struggling with this one. If you want to view what I have bludgeoned together, it is all in a repo on GitHub called instructor-oracle. What I would like to do is have the landing page be the layout at ./wbs. Then I would like the search to route to ./wbs/:_wbsCode and populate the sidebar with the appropriate record. I am thinking the router needs to be structured something like...
Router.configure({
layoutTemplate: 'layout'
});
Router.map(function () {
this.route('wbs', {
path: '/wbs'
}, function () {
this.render('wbs-detail', {
path: '/wbs/:_wbsAbbrev',
to: 'wbs-detail',
data: function () {
theOne = Wbs.findOne({abbrev: this.params._wbsAbbrev});
console.log(theOne.abbrev);
return theOne;
}
});
});
...and this would be paried with templates like...
<template name="layout">
<header class="container-fluid">
<nav class="navbar navbar-default" role="navigation">
<div class="navbar-header">
<a class="navbar-brand" href="{{pathFor 'wbs'}}">Instructor Oracle</a>
</div>
<div class="collapse navbar-collapse" id="bs-navbar-collapse">
<form class="navbar-form navbar-left" role="search" id="wbsSearchForm">
<div class="form-group">
<input
class="form-control typeahead"
name="wbsSearch"
id="wbsSearch"
type="text"
placeholder="Search"
autocomplete="on"
spellcheck="off"
autofocus="true"
/>
</div>
<button type="submit" class="btn btn-default">Find</button>
</form>
</div>
</nav>
</header>
<main class="container-fluid">
{{> yield}}
</main>
</template>
<template name="wbs">
<div class="col-sm-3" id="wbsCol">
{{> yield 'wbs-detail'}}
</div>
<div class="col-sm-9" id="timesheetCol">
<iframe src="http://iframeurl.html" id="timesheetFrame"></iframe>
</div>
{{#contentFor 'wbs-detail'}}
<h1>{{abbrev}} <small>{{code}}</small></h1>
{{/contentFor}}
</template>
...and an event handler for the form like this...
Template.layout.events({
// catch submit event for wbs form
'submit': function (event, template) {
// prevent default behavior and stop bubbling
event.preventDefault();
event.stopPropagation();
// store dom element in variable
var inputElement = template.find('input#wbsSearch');
// access value in form and extract abbreviation if found
var abbrev = Wbs.findOne({abbrev: (inputElement.value).toUpperCase()}).abbrev;
// clear input
inputElement.value = "";
// go to the page
Router.go('wbs-edit', {_wbsAbbrev: abbrev});
}
});
I have been trying to sort through this on the iron:router documentation, but right now I am all kinds of lost (obviously). Still, I need this to work to avoid reloads on the main layout template so the iframe does not reload while the sidebar can change along with the matching url so links to specific sidebar content can be bookmarked and shared.
Thank you in advance for your assistance. If I eventually sort all of this out, I am more than happy to contribute to the iron:router documentation so it makes sense for the next pea-brained idiot like myself who happens to need to sort this out.