Passing Mongo Documents in Meteor - javascript

I have a question as to how I can pass my Mongo documents around my JS and HTML. I have an example below, I'm trying to have my popover display the name of the thumbnail that's being hovered over. When someone clicks on the thumbnail a modal pops up that displays the picture as well as the description of the thumbnail. The issue is that when I try to pass the this.name element to the popover, it displays the name of the first thumbnail i hover over for all of the thumbnails, but it doesnt use the information for the first thumbnail on all the modals (its actually dynamic). I want to know what I'm doing wrong, the only work around I've found is to put the {{name}} tag inside my actual html as the data-content to the thumbnail.
HTML
<template name="gallery">
<div class="col-xs-6 col-sm-4 col-md-2">
<a href="#" class="thumbnail" data-content='{{name}}'>
<img src="{{img}}" alt="...">
<div class="caption">
<h5><center>{{name}}</center></h5>
</div>
</a>
</div>
</template>
JS
Gallerys = new Mongo.Collection("gallerys");
if (Meteor.isClient) {
// This code only runs on the client
Template.body.helpers({
gallerys: function () {
return Gallerys.find({}, {sort: {createdAt :-1}});
}
});
Template.body.events({
"mouseover a.thumbnail" :function(event, template){
$('a.thumbnail').popover({
trigger: "hover",
placement: "bottom",
})
},
"click a.thumbnail": function(event, template) {
event.preventDefault();
bootbox.dialog({
title: '<center><h2>'+ this.name.toUpperCase() +'</h2></center>',
message: '<div class="row"><div class="col-md-3"><img class="img-rounded" height="200" width="200" src="' + this.img + '"></div><div class="col-md-9"><h4>Description</h4>"'+ this.description +'"</div></div>',
size: 'large',
buttons: {
play:{
label:'PLAY SAMPLE <span class="glyphicon glyphicon-play"></span>',
className:"btn-success pull-left modalbtn"
},
download: {
label:'DOWNLOAD <span class="glyphicon glyphicon-download-alt"></span>',
className:"btn-primary modalbtn",
callback: function() {}
}
},
onEscape: function() {},
});
}
});
}

Like BraveKenny already suggested, move the helper event to the Template.gallery. It isn't an optional/cosmetic step to beautify your code. It sets the correct data context in the event helper.
Here is a boilerplate app showing the way data context work:
http://meteorpad.com/pad/hPaJ35NnWyHjkWAD3/Leaderboard

Related

Remove owl carousel item

I know that there are some associated questions about it, I tried all solutions and read all documentation, but w/o result.
I am initializing a Owl carousel :
HTML
In HTML, I have 2 items :
<div class="owl-carousel owl-theme all_diplomas">
<div class="item diploma-0">
<div class="content_diplomas">
<a data-fancybox="gallery" href="images/6.jpg"><i
class="material-icons">search</i></a>
<figure><img src="images/6.jpg" alt=""></figure>
</div>
<button class="waves-effect delete-diploma waves-blue diploma-0" type="button"><span>x</span> </button>
</div>
<div class="item">
<div class="add_diplomas">
<div class="item_add_diplomas">
<span class="plus_add">+</span>
<span class="txt_btn">Add diploma<br></span>
<input id="generateInputsForDiplomas">
</div>
</div>
</div>
</div>
JS :
$(".all_diplomas").owlCarousel({
loop: true,
margin: 15,
responsive: {
1000: {
items: 4
},
1200: {
items: 2
}
},
});
Next, after my script initialization :
$('input#generateInputsForDiplomas').on('click',function() {
var template = '<div class="item diploma-' + index + '"> <div class="content_diplomas"> <a class="diploma-' + index + '" data-fancybox="gallery" href="images/3.jpg"><i class="material-icons">search</i></a>' +
'<figure><img src="images/3.jpg" class="addedDiplomaInput diploma-' + index + '"alt=""></figure> </div> </div>'
+ '<button class="waves-effect delete-diploma waves-blue ' + classes + '" type="button"><span>x</span> </button>';
var newEl= $('.all_diplomas').trigger('add.owl.carousel', [template, 33]).trigger('refresh.owl.carousel');
});
Code above just adds a block of owl-item with one image and some id-s
and classes.
Then, it appends this template to position 33 and refreshes the
carousel
Them, each element has a delete button associated to owl-item class
$(document).on('click', 'button.delete-diploma',function() {
$(".all_diplomas").trigger('remove.owl.carousel', 33).trigger('refresh.owl.carousel');
});
That's the thing. When adding an element, from documentation, I am setting the position for this element explicitly - like 33. But when I am calling the button that is responsable to remove item with position 33, it deletes entire slider, or sometimes unexpected behavior.
The reason why I'm calling position explicitly, because I need to know each item's index, because when calling delete button, to know item with which position to delete. Documentation offers callbacks that has this information, but not for "add" event.
How can I lifehack that problem? I want to add n-items to carousel, and each this block with image to has it's own delete button. So, when calling this button, it will delete that element and refresh the Owl. I tried with pure jQuery to delete parents and so on... but Owl generates some other classes, and because of it, item is deleted, but empty spaces in slider remains.

WebUI Popover cannot set title using html element

I gave up on Bootstrap popover, and went looking. I found WebUI Popover which has all the functionality i am looking for.
But I am having trouble setting the title of the popover using the html content of an element on the page. I get undefined in console.log() and the title loads empty. The html I am trying to access is dynamically created.
Where I think there is a bug in the plugin is that the content loads perfectly from another element on the page.
I have a FIDDLE here.
My WebUI Popover code is:
// Popover Menu initialize
$('.icon-popover-menu').webuiPopover({
placement: 'left',
trigger: 'click',
closeable: true,
multi: false,
animation: 'pop',
cache: 'false',
type: 'html',
width: '220',
title: function() {
return $(this).closest('td.row-icon').find('.btn-row-popover-menu-head').html();
},
content: function() {
return $(this).closest('td.row-icon').find('.btn-row-popover-menu-body').html();
}
});
// Hide popover when screen changes size
$(window).on('resize', function() {
WebuiPopovers.hideAll();
});
$(window).on('scroll', function() {
WebuiPopovers.hideAll();
});
A sample of my HTML is:
<table class="fiddle">
<tr>
<td class="row-icon">
<button class="icon-popover-menu ion-fw btn-row-popover-menu">BTN</button>
<div style="display:none;">
<div class="btn-row-popover-menu-head">
<span>THIS IS THE TITLE</span>
</div>
<div class="btn-row-popover-menu-body">
<div class="input-group" role="group">
<a class="btn btn-app btn-icon-menu btn-popover-first" href="#">
EDIT
</a>
<a class="btn btn-app btn-icon-menu-danger" href="#">
DELETE
<br>
<span class="transaction-menu-legend">DELETE</span>
</a>
</div>
</div>
</div>
</td>
</table>
Any help is appreciated.
title: function() {
return $(event.target).closest('td.row-icon').find('.btn-row-popover-menu-head').html();
},
This works fine. By doing $(this) you are trying to access the title element of the popover which obviously has no closest td.row-icon. Hence it is undefined.

jQuery modal not show name after close and open

I create my custom modal window where i show image and that image contain comments and owner name. When i click on some image modal is opened and show big image, author name, comments etc... Problem is when i close current modal and opent it again name does not exist. But first time when i open modal name is there but only when i close that window and opent it again name does not exist. Check screenshots.
I try to debug it with firebook console and GET response return real name but that name is not rendered after closing and opening.
To prview image i use this code:
preview: function() {
$('body').on('click', '#open-picture-modal', function (e) {
e.preventDefault();
$("#photo_preview").show();
var $this = $(this);
var guid = $this.data('guid');
var photo_id = $this.data('id');
$.ajax({
method: 'post',
dataType: 'json',
url: baseurl + '/photo/preview',
data: {'photo_id': photo_id},
success: function(data) {
Photo.photo_author_meta(photo_id);
$(".pleft").html('<img class="fileUnitSpacer" src="'+ $this.data('href')+data['photo_name']+'">');
}
});
//window.history.pushState(null, null, pic_url);
// $(".image-source").attr("src", $this.data('href'));
});
},
// Close image preview modal
close: function() {
$("body").on("click", ".close", function(e) {
e.preventDefault();
$('#photo_preview').hide();
$('#photo_preview .pleft').html('empty');
$('#photo_preview .pright').html('empty');
});
},
// Show photo author meta(name, date created, etc..)
photo_author_meta: function(pid){
$.ajax({
method: "post",
dataType: 'json',
url: baseurl + '/photo/photo_details',
data: {'post_id': pid},
success: function(data) {
$("h4.photo-author-full-name").html(data['account_firstname'] +' '+ data['account_lastname']);
}
});
},
And here is modal where i append and set html
<div id="photo_preview" style="display:none">
<div class="photo_wrp">
<span class="pull-right close fa fa-times"> </span>
<div style="clear:both"></div>
<div class="pleft"></div>
<div class="pright">
<div class="photo-author-meta">
<div class="media">
<a href="#" class="media-left">
<img alt="64x64" data-src="holder.js/64x64" class="media-object" style="width: 64px; height: 64px;" src="test.png" data-holder-rendered="true">
</a>
<div class="media-body photo-author-name-box">
<div class="photo-author-name">
<h4 class="media-heading photo-author-full-name"></h4>
</div>
<div class="photo-datetime-box">
<div class="photo-date-posted"> Objavljeno: </div>
</div>
</div>
</div>
</div> </div>
<div style="clear:both"></div>
</div>
</div>
Like u can see on first image i have firstname and lastname in modal.
On second image i open again the some modal but name and surname does not exist. But check firebug console, data exist but not rendered.
Your close method is removing the HTML that renders the meta data.
$('#photo_preview .pright').html('empty');
That line is emptying all the HTML within . So, when photo_author_meta() is called a subsequent time after closing, h4.photo-author-full-name no longer exists.
You have various things:
1 - You are messing with .html() and .empty():
$('#photo_preview .pleft').html(); // or .empty()
2 - As you delete all the content from #photo_preview .pright, when you do:
$("h4.photo-author-full-name").html(data['account_firstname'] +' '+ data['account_lastname']);
This element don't exist. You could create it, or not empty all the div content.
You could change this:
$('#photo_preview .pright').html(); // or .empty()
to
$('h4.photo-author-full-name').html(); // or .empty()
In order to no delete the element, only the content on it.

Uploading a file from a web app with dropzone.js

I am building a web app. I have to let a user upload a picture or drag-and-drop one into the browser. To help with this, I'm using dropzone.js. My challenge is, I need to customize the appearance a bit.
My customization requires features that seem pretty forward in dropzone.js. Basically, I need: only one file can be uploaded at once. While the file is being uploaded, I need to show a progress bar. Once uploaded, I need to let the user either a) remove the existing picture or b) replace the picture with another one. In an attempt to this, I currently have the following HTML:
<div id="myDropZone" style="cursor:pointer;">
<div class="files" id="previews">
<div id="template" class="file-row">
<ul class="list-inline">
<li>
<span class="preview" style="width:300px;"><img data-dz-thumbnail /></span>
<p class="size" data-dz-size></p>
</li>
<li style="vertical-align:top;">
<ul id="pictureActions" class="list-unstyled">
<li>
<button class="btn btn-default dz-clickable file-input-button">
<i class="glyphicon glyphicon-picture"></i>
<span>Pick...</span>
</button>
</li>
<li>
<button data-dz-remove class="btn btn-danger btn-block" style="margin-top:8px;">
<i class="glyphicon glyphicon-trash pull-left"></i>
<span>Delete</span>
</button>
</li>
</ul>
</li>
</ul>
<div id="uploadProgress" class="progress" role="progressbar" aria-valuemin="0" aria-valuemax="100" aria-valuenow="0">
<div class="progress-bar progress-bar-warning" style="width:0%;" data-dz-uploadprogress>
<span>Please wait...</span>
</div>
</div>
</div>
</div>
<div id="uploadPrompt">Drag-and-drop a picture here</div>
</div>
I am initializing this code as a dropzone using the following JavaScript:
$(function () {
var previewNode = document.querySelector("#template");
previewNode.id = "";
var previewTemplate = previewNode.parentNode.innerHTML;
previewNode.parentNode.removeChild(previewNode);
var pictureDropZone = new Dropzone("div#myDropZone", {
url: "/pictures/upload",
clickable: true,
uploadMultiple: false,
autoProcessQueue: true,
previewTemplate: previewTemplate,
previewsContainer: "#previews",
init: function () {
this.on("complete", function (data) {
$('#pictureActions').show();
$('#uploadProgress').hide();
$('#uploadPrompt').hide();
});
},
uploadprogress: function (e, progress) {
$('#uploadProgress').css('width', progress);
},
removedfile: function () {
$('#previews').hide();
$('#uploadPrompt').show();
}
});
});
There are several problems though. If I click the text Drag-and-drop a picture here, the file picker does not open. If I click outside of the text, the file picker opens. Also, this code works for the initial process of choosing a file. However, if I click the "Pick..." button, the page does a post back. In reality, I was expecting the file picker to appear again. If I click the "Delete" button, and then choose a file again from the file picker, the picture, upload progress and action buttons never appear.
I feel like I'm screwing up the initialization of the dropzone somehow. What am I doing wrong? Why can't I choose another picture or delete a picture and choose another one or open the file picker if I click the prompt text?
I have changed your code
this.on("complete", function (data) {
$("#previews").show(); //This line added ... and it's worked...
$('#pictureActions').show();
$('#uploadProgress').hide();
$('#uploadPrompt').hide();
});
i think then line: $('#previews').hide(); you have hidden preview element, and this not change status when you append new image. :).
And this word but, You can see old picture you added, I think it's a new bug... I trying solute it... Have you idea for it.
http://jsfiddle.net/qek0xw1x/15/

Combining sequential jQuery selectors into a single function

BIG EDIT: Updated the code sections, but the question remains the same.
I've got perhaps a unique jQuery issue that I could use some help on.
I've got a function (that works perfectly) that looks like this...
var openslide1 = function() {
$("#slide1").animate({
left: "+=250px",
}, 400, function() {
// Animation complete.
});
$(this).unbind('click', openslide1); \\ to prevent from pushing slide over too many times
};
$("#openslide1").click(openslide1);
My issue is there could be a potentially unlimited number of slides, and therefore "openslides". Each "openslide" selector corresponds with its own unique slide. (e.g. #openslide2 would open #slide2 and unbind #openslide2...so on and so forth).
So how do I combine these into a single variable and function?
And as a side note...I'm also going to want to "re-bind" the #openslide on the click of another event. Currently, I'm able to do them one at a time through this....
$("#closeslide1").click(function() {
$("#slide1").animate({
left: "-=250px",
}, 500, function() {
// Animation complete.
});
$('#openslide1').click(openslide1); \\ rebinds openslide1
});
But once this becomes a combined function, I'm assuming "openslide1" will no longer be the variable for the function. So how would I rebind that click event when #closeslide is clicked. (And obviously I'm going to use the first part of this question to apply to the closeslide variables as well.)
<div class="section">
<a class="edit-btn" id="openslide1" href="#null">edit</a>
<a class="edit-btn" id="openslide2" href="#null">edit</a>
<a class="edit-btn" id="openslide3" href="#null">edit</a>
<a class="edit-btn" id="openslide4" href="#null">edit</a>
</div>
<div class="slide" id="slide1">
<h1>Edit Row</h1>
<p>Prototyping data below, may not reflect link clicked.</p>
Submit <a id="closeslide1" class="btn btn-danger" style="color:#fff" href="#null">Cancel</a>
</div>
<div class="slide" id="slide2">
<h1>Edit Row</h1>
<p>Prototyping data below, may not reflect link clicked.</p>
Submit <a id="closeslide2" class="btn btn-danger" style="color:#fff" href="#null">Cancel</a>
</div>
<div class="slide" id="slide3">
<h1>Edit Row</h1>
<p>Prototyping data below, may not reflect link clicked.</p>
Submit <a id="closeslide3" class="btn btn-danger" style="color:#fff" href="#null">Cancel</a>
</div>
<div class="slide" id="slide4">
<h1>Edit Row</h1>
<p>Prototyping data below, may not reflect link clicked.</p>
Submit <a id="closeslide4" class="btn btn-danger" style="color:#fff" href="#null">Cancel</a>
</div>
PLEASE HELP!
Thanks!
I'll give it a shot, does this help you with portability?
$(".openslide1").click(function() {
openSlide(".slide1", "body", 400, ".openslide1");
});
function openSlide(target, bodyObj, speed, original) {
$(target).animate({
left: "+=250px",
}, speed, function() {
// Animation complete.
});
$(bodyObj).animate({
marginLeft: "+=250px",
}, speed, function() {
// Animation complete.
});
$(original).unbind('click');
}
Change you function to pass a reference to the element (or elements) that you want to manipulate:
var openslide = function(elem) {
var id = elem.attr("id");
$("#" + id.substring(5)).animate({
left: "+=250px",
}, 400, function() {
// Animation complete.
});
$('body').animate({
marginLeft: "+=250px",
}, 400, function() {
// Animation complete.
});
elem.unbind('click', openslide);
};
$(".edit-btn").click(function() {openslide($(this))});
Then you can use a single function for all your elements and you can bind them all at the same time if they have a common class (in this case, I called them .openslide).
Edit: looking at your original question again, I noticed that the element being animated at the start isn't the same element. But if there is an easily defined relationship between it and the element you clicked on (for example, it's a child of the original element, or the next sibling, or something) you can easily come up with the appropriate selector to select it. In the example above, I assumed a sibling relationship with the target element having a class of .targetclass, but change it as suits.
Edit 2: changed it to use the id's on the assumption that id openslide1 will correspond to the element with id slide1.
Construct the links as follows :
<div class="section">
<a class="edit-btn openslide" data-slide="#slide1" href="#null">edit</a>
<a class="edit-btn openslide" data-slide="#slide2" href="#null">edit</a>
<a class="edit-btn openslide" data-slide="#slide3" href="#null">edit</a>
<a class="edit-btn openslide" data-slide="#slide4" href="#null">edit</a>
</div>
And the slides as follows :
<div class="slide" id="slide1">
<h1>Edit Row</h1>
<p>Prototyping data below, may not reflect link clicked.</p>
Submit <a class="closeslide1 btn btn-danger" style="color:#fff" href="#null">Cancel</a>
</div>
It's hard to see exactly what effect is required but the general shape of the handler will be something like this :
$(".openslide, .closeslide").click(function() {
if($("body").filter(":animated").length) { return; } //animation in progress, abort.
var $slide = $($(this).data('slide'));
var state = $slide.data('state') || 'closed';
var sign = (state == 'closed') ? '+' : '-';
$slide.animate({
left: sign + "=250px"
}, 400, function(){
$slide.data('state', (sign == '+') ? 'open' : 'closed');
});
$('body').animate({
marginLeft: sign + "=250px"
}, 400);
return false;
});
untested
As you will see, one function (when it works) will handle both slideopen and slideclose actions.
You will have to adapt the script to achieve precisely what you want.

Categories

Resources