I'm creating a gallery application, and I have a categories bar such that when I click one of the categories, I want the gallery to only show images that are in the selected category.
This is gallery.html
<template name="gallery">
<div class="container col-sm-10">
{{>gallerypost}}
<div class="grid master">
{{#each images}}
<div class="grid-item">
<div class="galleryimage" style="">
{{#if isPortrait this.orientation}}
<img src="{{c.url (nameHelper this.name) width=473 height=646 crop="scale"}}" class="img img-responsive" />
{{else}}
<img src="{{c.url (nameHelper this.name) width=646 height=473 crop="scale"}}" class="img img-responsive" />
{{/if}}
</div>
</div>
{{/each}}
</div>
</div>
client.js
Meteor.subscribe('allimages');
Session.setDefault('category', null);
Tracker.autorun(function(){
Meteor.subscribe('categoryimages', Session.get('category'));
console.log('this is working');
});
publications.js
Meteor.publish('allimages', function(){
return ImageInfo.find();
});
Meteor.publish('categoryimages', function(category){
return ImageInfo.find({category: category});
});
So I know the my Session variable works, as I have tested it out in the console. But for some reason the database is not updating. Is it because of the grid framework (Masonsry) that I'm using? What's causing the database to not subscribe to the specific one?
Maybe reloadItems inside your autorun would help http://masonry.desandro.com/methods.html#reloaditems
$('.container').masonry('reloadItems');
Related
I implemented pagination for the gallery on my website following this tutorial. Problem is that unlike the pagination on the website linked above, my webpage refreshes after a new page number is clicked. That is not what I want to happen.
I want the webpage to stay in the same position, the same way it is on the tutorial. Here is a fiddleJS of how my gallery looks. Unfortunately, since the new pages lead to new URLs and the page refreshes, it leads to а 404 error on fiddleJS but I think it is sufficient to get the idea of what I have done so far.
Code from the fiddleJS:
<div class="container text-center" id="app">
<h1 class = "mb-3">Gallery</h1>
<div class="img-gallery">
<div v-show="currentPage == 1" class="row">
<img src="https://www.gstatic.com/webp/gallery/1.jpg" class="w-25">
</div>
<div v-show="currentPage == 2" class="row">
<img src="https://www.gstatic.com/webp/gallery/1.jpg" class="w-25">
<img src="https://www.gstatic.com/webp/gallery/1.jpg" class="w-25">
</div>
<div v-show="currentPage == 3" class="row">
<img src="https://www.gstatic.com/webp/gallery/1.jpg" class="w-25">
<img src="https://www.gstatic.com/webp/gallery/1.jpg" class="w-25">
<img src="https://www.gstatic.com/webp/gallery/1.jpg" class="w-25">
</div>
</div>
<div class="mt-2 mt-sm-3 d-flex justify-content-center">
<b-pagination-nav
v-model="currentPage"
:link-gen="linkGen"
:number-of-pages=3
limit=7
use-router>
</b-pagination-nav>
</div>
</div><!-- container -->
<script>
new Vue({
el: '#app',
data: {
currentPage: ''
},
methods: {
linkGen(pageNum) {
return `${pageNum}`
}
}
})
</script>
Reading the tutorial, what I thought I should do is add use-router to the tag, however, the addition of it did not change anything.
Try this :::
methods: {
linkGen(pageNum) {
return pageNum;
}
}
https://jsfiddle.net/np62xjrq/
Make sure your linkGen function returns the full URL path, or return a vue-router location object (assuming you want to use a query string in the URL to change page):
linkGen(page) {
return {
query {
page: page
}
}
}
I'm very new to meteor/semantic/javascript in general so I apologize if this question seems a little to rushed, but I seriously cannot figure this out.
An example of a click event I am trying to initialize, I have a semantic-ui dropdown menu. With what I have now, I get this error:
=> Meteor server restarted
Errors prevented startup:
While processing files with ecmascript (for target web.browser):
client/main.js:18:4: Unexpected token (18:4)
Your application has errors. Waiting for file change.
Here's what I have, I know it's pretty messy. I'll work on that later.
import { Template } from 'meteor/templating';
import { ReactiveVar } from 'meteor/reactive-var';
import '/main.html';
import '/templates/cards.html';
import '../lib/collections.js';
Template.cards.helpers({
cards: function() {
return Cards.find();
}
});
Template.card.events({
$('.ui.dropdown')
.dropdown()
;
});
<template name="card">
<div class="three wide column">
<div class="ui cards">
<div class="card">
<div class="content">
<div class="header">
{{header}}
<div class="ui dropdown right floated">
<i class=" small grey ellipsis vertical icon"></i>
<div class="menu">
<div class="item">Edit</div>
</div>
</div>
</div>
<div class="description">
{{desc}}
</div>
</div>
<div class="extra content">
<button class="ui fluid blue icon button"><i class="map icon"></i></button>
</div>
</div>
</div>
</div>
</template>
You've messed up with Template.card.events, you don't need it at all here.
It should be like this instead:
Template.card.onCreated(function() {
$('.ui.dropdown').dropdown();
});
I have hide and show functionality on dynamically generated cards after form submission.
{{#each newaction}}
<div class="workflowcard">
<div class="module-card-small">
<div class="res-border"></div>
<div class="card-img">{{team}}</div>
<div class="res-content">
<div class=" newaction-name">{{action_title}}</div><hr>
<div class="newaction-des">{{description}}</div>
<!-- <div class=" due-on">Due on:{{d_date}}</div><hr>-->
</div>
<div class="due">
Due on:
<div>
<div class="day-stamp">{{weekday d_date}}</div>
<div class="date-stamp">{{date d_date}}</div>
<div class="month-stamp">{{month d_date}}</div>
</div>
</div>
{{> actioncardsubcontent}}
</div>
<div class="btn-box">
<button type="button" class="cancelsub">Hide Option</button>
<button type="submit" class="createbtnsub">Show Options</button>
</div>
</div>
</div>
{{/each}}
</div>
</div>
<template name="actioncardsubcontent">
<div class="subcontent" >
<div class="modulepath"><div>{{module_list}}</div></div>
<div class="linkto"><div>Linked To: <div class="linkto-color">{{link}}</div></div></div>
<div class="description"><div>Notes:<br>{{description}}</div></div>
</div>
</template>
When I click on show options button the action card subcontent is displaying and when I click on hide option it is hiding.
The problem is, the hide and show functionality is applying for all the cards which are creating dynamically at a time when I click on single card. I understand the reason is I have given the class name for the buttons. So how to stop that and make it work to current target.
Here is my JS:
Template.actioncardsubcontent.rendered = function(){
this.$(".subcontent").hide();
};
Template.workflow.events({
"click .createbtnsub":function(){
$('.subcontent').show();
},
"click .cancelsub":function(){
$('.subcontent').hide();
}
What you need to do is give a unique ID for each iteration to your cards div class attribute.
in JSTL usually has indexId attribute. You can use that and set your class.
Sample:
{{#each newaction indexId="i"}}
{{/each}}
<div class="btn-box">
<button type="button" class="cancelsub<%=i%>">Hide Option</button>
<button type="submit" class="createbtnsub<%=i%>">Show Options</button>
</div>
In your javascript:
use i to hide.
You have a couple of options here. The one I prefer is to put everything in the {{#each}} into its own template. If you do that, you can put the button click events inside of the child template's event which makes it much simpler to manipulate your data. An example:
Templates:
<template name='workflow'>
{{#each newaction}}
{{> card}}
{{/each}}
</template>
<template name='card'>
<div class="workflowcard">
<div class="module-card-small">
<div class="res-border"></div>
<div class="card-img">{{team}}</div>
<div class="res-content">
<div class=" newaction-name">{{action_title}}</div><hr>
<div class="newaction-des">{{description}}</div>
</div>
<div class="due">
Due on:
<div>
<div class="day-stamp">{{weekday d_date}}</div>
<div class="date-stamp">{{date d_date}}</div>
<div class="month-stamp">{{month d_date}}</div>
</div>
</div>
{{> actioncardsubcontent}}
</div>
<div class="btn-box">
<button type="button" class="cancelsub">Hide Option</button>
<button type="submit" class="createbtnsub">Show Options</button>
</div>
</div>
</div>
</template>
Javascript (template.$ docs):
Template.cards.events({
"click .createbtnsub":function(event, template){
template.$('.subcontent').show();
},
"click .cancelsub":function(event, template){
template.$('.subcontent').hide();
}
});
-- OR --
You can do a better DOM query.
Without more info on what is actually in the actioncardsubcontent template or proper testing, this is a best guess on what you're trying to find. You should be able to tweak this query to meet your specific needs easily enough through trial and error. Please read the jQuery Traversing docs as it should clear this up a bit for you.
Template. workflow.events({
"click .createbtnsub":function(event, template){
$(event.target).siblings('.due').find('.subcontent').show();
},
"click .cancelsub":function(event, template){
$(event.target).siblings('.due').find('.subcontent').hide();
}
});
I am trying to Set a default DP for the users who do not have/not uploded an image.
Tried using helpers to display content but getting error "Uncaught Error: {{#each}} currently only accepts arrays, cursors or falsey values."
Code Below(Client JS)
JS :
Template.mcomments.helpers({
'mcommentsdata':function(){
return comdata.find({},{sort:{"at":-1}}).fetch();
},
images2: function () {
var fetchimg=Meteor.users.findOne({
"_id":this.__id
});
if((fetchimg.profileimage==undefined)||(fetchimg.profileimage=="")){
var hello="/images/prof.jpg"
return hello;
}else{
return Images.find({"_id":fetchimg.profileimage})
}
}
});
HTML
<template name="mcomments">
<div id="mcomments" class="col-lg-3">
<div><h5 class="mcommentsheader">Followup Stream </h5>
</div>
<div class="col-lg-12 scrolling comscrolllist" id="mcomments1">
<div id="mcomments2">
{{#each mcommentsdata}}
<div class="col-lg-12 comcontainer">
<div class="row">
<div class="col-lg-3 indcomments" >
{{#each images2}}
<img src="{{this.url
}}" width="45px" height="50px" alt="">
{{/each}}
</div>
<div class="col-lg-9" style="">
<div class="row combody" >
<div class="pull-left mcommfont" >{{user}}</div>
<div class="pull-right mcommcust">{{product}} Case#{{productcaseno}}</div>
</div>
<div class="maincomment">{{comment}}</div>
<div class="comtemp"> <span data-livestamp="{{at}}"></span></div>
</div>
</div>
</div>
<div class="col-lg-12 comblankspace">
</div>
{{/each}}
</div>
</div>
</div>
</template>
Now i have given up on this approach and thinking of uploading an image and attaching the url to all profiles by default(onCreateuser) until they change it.I believe to do this i might have to upload and image automatically on server startup. Please lead me to the right direction as i am still noob in meteor.
Storage Adapter: GridFS.
Regards,
Azaruddin
Change the 'hello' variable to the following code:
var hello = [
{ url: "/images/prof.jpg" }
];
You're running into problems because hello is currently a string - #each expects an array/cursor/etc. as your error suggests.
Alternatively, you could use {{#else}} on your each block and get rid of returning your 'hello' case entirely:
{{#each images}}
...
{{else}}
<!-- Default profile image code -->
{{/each}}
I have a page where I do multiple binding to the same object (item, item2, message, messageType)
Though I placed the binding in several part of the page it works only the first time i placed. The objects are filled with ajax calls that return correctly the value (I logged them in the console)
What sounds even strange to me is that the <infomessage> directive has been used in several other places in the app (twice in the same page) and worked perfectly.
Do you have any idea on why these bindings don't work?
I even tried to $watch the objects and they are properly changes but seems that the view use the updated value only the first time
<div class="container" ng-app="MyApp" >
<div class="row" ng-controller="MyCtrl" >
<div class="col-lg-10">
<h3>...</h3>
</div>
<div class="col-lg-10">
<infomessage type="{{messageType}}" message="{{message}}"></infomessage>
</div>
<div class="col-lg-10">
Item: {{item.idbene_ext}} / {{item.id}} / {{item.img}}<br>
Ubicazione: {{item2.id}} {{item2.code}}
</div>
</div>
<div class="row" style="margin-top:20px">
<div class="col-xs-1"></div>
<div class="col-xs-4" ng-class="{'ubiBox':true,'ausilio-enabled':(item!=null),'ausilio-disabled':(item==null), 'boxfocus':(item==null)}">
<div ng-show="item==null">
<div class="number">1</div>
<img src="assets/images/disabled-128.png" width="100" class="img_none"/>
<h4> {{item.idbene_ext}} Select an item</h4>
</div>
<div ng-show="ausilio!=null">
<h4>Item:{{item.idbene_ext}}</h4>
</div>
</div>
<div class="col-xs-2"></div>
<div class="col-xs-4" ng-class="{'ubiBox':true,'ubi-enabled':(item!=null),'ubi-disabled':(item==null),'boxfocus':(item!=null) }">
<div ng-show="item==null">
<div class="number">2</div>
<img src="assets/images/Office-disabled-128.png" width="100" class="img_none"/>
<h4> Select the second item</h4>
</div>
<div ng-show="item!=null">
<h4>Item2 {{item2.code}}</h4>
</div>
</div>
<div class="col-xs-1"></div>
</div>
<div class="row">
<div class="col-lg-10">
<infomessage type="{{messageType}}" message="{{message}}"></infomessage>
</div>
<div class="col-lg-10">
Item: {{item.idbene_ext}} / {{item.id}} / {{item.img}}<br>
Ubicazione: {{item2.id}} {{item2.code}}
</div>
</div>
Here's the angularJS code
MyApp.controller("MyCtrl",function($scope,$http,Config,BarcodeService){
$scope.iditem2=-1
$scope.iditem=-1
$scope.item2=null
$scope.item=null
$scope.message=""
$scope.messageType=""
$scope.$on(BarcodeService.handleitem2,function(){
$scope.message=""
$scope.messageType=""
if($scope.item==null){
$scope.message="select an item before"
$scope.messageType="error"
}
$scope.iditem2=BarcodeService.id
$http
.post(Config.aj,{call:"item2.getitem2",id:$scope.iditem2})
.success(function(data){
$scope.item2=data.payload
})
})
$scope.$watch("item",function(){
console.log("---->",$scope.item)
},true)
$scope.$on(BarcodeService.handleitem,function(){
$scope.message="loading item"
$scope.messageType="info"
$scope.iditem=BarcodeService.id
$http
.post(Config.aj,{call:"item.getArticoloByIdMin",id:BarcodeService.id})
.success(function(data){
$scope.message="item loaded!!"
$scope.item=data.payload
})
})
})
Ok guys, got it!
The problem was lying in the fact that I have two in my application but i placed the ng-controller only on the first one.
This caused all the binding in the second div to fail because they were outside the controller.
I moved the ng-controller in the parent div that contains both and now everything works like a charm.
Thanks anyway to #wachme and #ivarni for taking care of my question.
Happy coding to *