I would like to set context data in an event handler that inserts new uploaded photos to the image FScollection. What I want to set is the newly generate id of the photo file. I need to pass this id to a child template to do further processing. Below is the code I am working with:
How should I define data I want to use later in an event handler?
images.js
Template.Profile.events({
'change #uploadBtn': function(event, template) {
var name = $("#uploadBtn").val();
$("#uploadFile").val(name);
FS.Utility.eachFile(event, function(file) {
Images.insert(file, function (err, fileObj) {
if (err){
// handle error
}
else {
//here I want to set fileObj._id as data for further usage.
}
});
});
}
});
Template.imageView.helpers({
images: function () {
return Images.findOne({_id: this.imageId});
}
});
Template.imageView.events({
'click #deleteBtn': function (event) {
this.remove();
}
});
template file
images.html
<template name="Profile">
<input id="uploadFile" placeholder="Choose File" disabled="disabled" style="cursor: auto; background-color: rgb(235, 235, 228); "/>
<div class="fileUpload btn btn-primary">
<span>Upload</span>
<input id="uploadBtn" type="file" name="…" class="upload">
</div>
{{> imageView}}
</template>
<template name="imageView">
<div class="imageView">
{{#if images}}
<div style="width: 120px;height: 120px;margin-bottom: 30px;">
<div style="float: middle;">
{{#with images}}
<button id="deleteBtn" type="button" class="btn btn-primary" >Delete</button>
{{/with}}
</div>
<a href="{{images.url}}" target="_blank" >
<img src="{{images.url}}" alt="" class="thumbnail" style="width: 96px; height: 96px;"/>
</a>
</div>
{{/if}}
</div>
</template>
You have a couple choices.
Include the _id of the image in the object that is referring to it
Include the _id of the object in the image itself as parentId or similar
For the first case, in the callback from Image.insert use the _id of the image and then do a .update() on the parent object (is this a user perhaps?) to include a reference to the image. If you're allowing multiple images then you might want to update an array with those _ids.
In the second case you can update the object you just inserted in the callback from the insertion with the parentId that you need.
Then you just need to include the appropriate clause in your query for the dependent images and thanks to reactivity it will update automatically.
Related
How do I retrieve information stored in a js file? I assume I am labelling my node elements in HTML incorrectly
I'm hoping to gain a better understanding of how to retrieve a function node from localStorage
Below are the key factors I am trying to get using getElementById into local storage from post HTML.
This is not everything in my listing.html document, I have excluded everything but what I think are essential elements
<div class="listing">
<div class="container-form">
<div class="mySlides fade">
<div class="numbertext">1 / 3</div>
<img class="img" value(src)="1" id="img" src="images/4.JPG" alt="img1">
</div>
<div class="infoBox">
<h5 post="weight" id="weight" value="7.00">7.00 : Under - 16 oz</h5>
</div>
<div class="column-bottom">
<div class="add-button">
<div class="add-button" method="post">
<p><input type="submit" onclick="addListing()" class="btn"></input></p>
<div class="buy-button">
<span class="price" post="price" id="price" value="60">$60</span>
<button type="button" class="btn" onclick="window.location.href='cart.html'" onclick="addListing()"
;>BuyMe</button>
</div>
</div>
</div>
</div>
</div>
</div>
I am trying to use the function below to store each element from the post HTML
function addlisting() {
let listing = ['listings'];
if (localStorage.getItem('listings')) {
listing = JSON.stringify(localStorage.getItem('listings'));
alert("added!");
}
listing.push({ 'listingId': listingId + 1, image: '<imageLink>' });
listingsId = listingsId + 1;
var listingsName = document.getElementById('name').innerHTML;
var listingsPrice = document.getElementById('price').getAttribute('data- value');
var listingsImage = document.getElementById("img").src;
var listingsWeight = document.getElementById('weight').getAttribute('data- value');
value = parseFloat(listingsPrice, listingsWeight).toFixed(2);
localStorage.getItem('name', 'price', 'img', 'weight', JSON.stringify(listingsName, listingPrice, listingsImage, listingsWeight));
}
here is the $(document).ready(function(){ function I'm hoping to implement into my code, I got this from another Stack Overflow page as it was the most fitting however I am yet to understand each component.
$(document).ready(function () {
$('#Btn').load(function () {
let listings = [];
if (localStorage.getItem('listings')) {
listings = JSON.parse(localStorage.setItem('listings'));
}
listings.push({ 'listingId': 1, image: '<imageLink>' });
});
});
my question again is how do I then execute this function using onload Onto a separate HTML, called cart.html. I did not display my cart.html file because there is nothing pertaining to this question on it. And furthermore how to go about styling Onload events that retrieve information from localStorage.
P.S.
There is an alert function within my first .js excerpt addListing(), that does not fire when clicked. probably a sign of bad programming. I've just never found a straightforward answer
I need a graph inside a card, with records from the database.
Each card contains a button element, which onclick, updates the value for the particular ID of the card. . The value will be triggered through the event.
Controller:
class SampleController extends Controller
{
public function index()
{
$users=User::all();
return view('progress', ['users'=> $users]);
}
#foreach($users as $user)
<div class="card">
<div class="card-title">
<div class="caption">
{{ $user['name'] }}
</div>
<div class="actions">
<div class="btn">
<button id="ref">Refresh</button>
</div>
</div>
</div>
<div class="card-body" id="{{ $user['id'] }}">
<center>
<div style=" display:inline; width: 200px; height: 200px;">
<input
class="graph"
data-max="{{ $user['goal'] }}"
value= ""
/>
</div>
</center>
</div>
</div>
#endforeach
</div>
Script::
var pusher = new Pusher('xxxxxxx', {
cluster: 'ap3',
encrypted: true
});
// Subscribe to the channel we specified in our Laravel Event
var channel = pusher.subscribe('my-channel');
channel.bind('App\\Events\\myEvent', function(data){
target = data.id;
value = data.value;
//Refresh button
$('#ref').click(function(){
$.ajax({url: '/api/getId/' + target,
success: function(){
alert('THe UI is updated' + value);
$(target).block({
message: 'processing',
timeout: 20000,
});
$(target).unblock();
}
});
});
When I pass the value through tinker like the below,
event(new App\Events\myEvent('3',40));
I could see the particular Id(3) is updated with the value 40.
The purpose of refresh is ,the card should be blocked for 20seconds, Meanwhile If I pass the value through Event for the particularId, It unblocks the card and updates the card with the new value.
The problem is ,If I have 10 cards, only the refresh button in the first card works, the refresh button in the remaining cards doesn't work.
How can I make the refresh button work in all the cards?
Could anyone please help?
Many thanks.
I'm in the process of building a web scraper for a homework assignment involving Express, Mongoose, Cheerio/axios, and Handlebars. My "/" route grabs the Mongoose objects and handlebars loads them to the page in individual cards. A save button is generated with an attribute data-id={{_id}}' in these cards. I'm trying to access the attribute with jQuery when it's pressed to save it to another collection but $(this) is returning undefined.
js
$(document).ready(function () {
$("#artDiv").on("click", ".save", (event) => {
event.preventDefault();
let id = $(this).attr("data-id");
console.log($(this).data("id"));
console.log(id);
})
});
html
<div id="artDiv" class="container">
{{#obj}}
{{#each .}}
{{#if headline}}
<div id="articleCard" class="card">
<h5 class="card-header">{{altHead}}</h5>
<div class="card-body">
<h5 class="card-title">{{headline}}</h5>
<p class="card-text">{{desc}}</p>
Visit
<button data-id="{{_id}}" data-control="saveBtn" type="button" class="btn btn-success save">Save</button>
</div>
</div>
{{/if}}
{{/each}}
{{/obj}}
</div>
If you want to have your clicked element in $(this), you cannot use arrow functions. You have to use $("#artDiv").on("click", ".save", function (event) { ... });.
This is my Razor Page containing multiple divs with each div containing either follow or unfollow button with NeighbourhoodName and other stuff.
<p class="lead" style="display: none" data-bind="visible: profiles().length == 0">No neighbourhood found...</p>
<ul data-bind="visible: profiles().length > 0, foreach: profiles">
<li class="media" style="border-top: solid 1px lightgrey; padding-top: 15px;">
<div class="media-body">
<h4 class="media-heading">
<a class="btn pull-right" data-bind="visible: !IsFollowed, attr: { href: followAction }">Follow</a>
<a class="btn btn-danger pull-right" data-bind="visible: IsFollowed, attr: { href: unfollowAction }">Unfollow</a>
</h4>
<em data-bind="text: NeighbourhoodName"></em>
<em data-bind="text: NeighbourhoodId"></em>
//stuck at this line
</div>
</li>
I want to Generate a new page with click on any of the div. So,I want to send id of the neighbourhood to action method with click on respective div. Right now, i am able to get NeighbourhoodId with data-bind attribute but dont know how to send this id to action method with click on any area of div means how to mix this anchor tag. something like that.
This is my follow action url in a knockout code which send neighbourhoodId on follow button click:
self.followAction = location.protocol + "//" + location.host + '/Neighbourhood/Follow?uid=' + data.NeighbourhoodId;
But, i dont want any button. simple click on div should send id to action method.
how to achieve this. please suggest me something.
You simply have to use the click binding on the div, and bind it to a function in your viewmodel.
The function in your viewmodel receives as parameter the knockout context available in the bound element. So, you can directly access the desired data from that function.
<div class="media-body" data-bind="click: yourViewModelFunction">
In your viewmodel, your function should be implemented like this:
yourViewModelFunction = function(data) {
// here you can use data.NeighbourhoodId
}
I want to use different Sessions for a specific click event within a {{#each}} block. The problem is that HTML elements will be displayed for all {{#each}} block members, but I only want it for the one, a user performs the click event on.
Here is my code:
...
{{#each articles}}
<tr id="{{_id}}" class="article-row">
<td class="articles">
{{> article}}
</td>
</tr>
{{/each}}
...
<template name="article">
{{#if editArticle}}
<div class="input-group">
<span class="input-group-addon">Edit article</span>
<input type="text" name="edit-article-input" class="form-control" placeholder="Name your article." value="{{title}}">
<span class="input-group-btn">
<button class="btn btn-success glyphicon glyphicon-ok edit-article-submit" data-type="last"></button>
</span>
</div>
{{else}}
<div class="panel panel-default article">
<div class="panel-heading">
<h3 class="panel-title">{{title}}</h3>
</div>
<div class="panel-body">
<button class="glyphicon glyphicon-pencil btn btn-default btn-xs edit-article"></button>
</div>
</div>
{{/if}}
</template>
Helper methods and events:
Template.article.helpers({
editArticle: function() {
return Session.equals('editArticle', true);
}
});
In the template with the {{#each}} block I use this helper method:
'click .edit-article': function(e, t) {
e.preventDefault();
Session.set('editArticle', true);
}
Now the problem is, that if I click on the button .edit-article the {{#if editArticle}} block appears on every article. I just want it for the one I clicked on.
Any help would be greatly appreciated.
This is a perfect example of how Session isn't always the right tool for the job when it comes to template reactivity. Unless you actually need to know which article is being edited outside of the template, I'd strongly recommend using a ReactiveVar or ReactiveDict rather than a global variable like Session. It's a little more to write but, in my opinion, a much more encapsulated and elegant solution. Here's the outline of the code you'd need:
Template.article.created = function() {
this.isEditing = new ReactiveVar(false);
};
Template.article.events({
'click .edit-article': function(e, template) {
e.preventDefault();
template.isEditing.set(true);
},
submit: function(e, template) {
e.preventDefault();
template.isEditing.set(false);
}
});
Template.article.helpers({
editArticle: function() {
return Template.instance().isEditing.get();
}
});
Note that you'd need to do meteor add reactive-var for this to work. For more details, see my post on scoped reactivity.