How to add Search with Meteor and Bootstrap? - meteor

I am trying to implement searching in my Meteor app. I don't exactly understand how it ties together. At this point, I have this following code:
html:
<form class="navbar-search pull-left">
<input type="text" class="search-query" placeholder="Search">
</form>
js:
Template.menubar.events({
'keyup input.search-query': function (evt) {
console.log("Keyup value: " + evt.which);
if (evt.which === 13) {
console.log("Got an Enter keyup");
Session.set("searchQuery", "justATestVar");
}
}
});
I can see the values of keyup as I press different keys into the search box, so I know the event is being hit. Capturing the "enter" keyup also works, but pressing enter causes the enter site to reload and when I do:
Session.get("searchQuery")
it returns undefined.
I don't know if I'm handling this properly. Essentially, I just want to get the value from the search box and then use that value for making a search on my collection. Any help would be appreciated! Thank you.

You should really use a submit button for your search form to avoid ruining accessibility.
Using a submit button will also enable by default the behavior you're looking for : form submission on enter key pressed.
If you really want to get rid of the submit button, keep it in the DOM but use CSS to hide it.
It's very important to call preventDefault on the event you'll receive from "submit form" handler, if you forget to do so, the page will refresh ruining the meteor "Single Page App" experience (and by the way, page refresh will clear your Session variables, which is why you get an undefined value in the first place).
"submit form":function(event,template){
event.preventDefault();
Session.set("searchQuery",template.find(".search-query").value);
}

What is probably happening is your form is being submitted when you hit enter. Try an preventDefault(). Probably something like this would work:
Template.menubar.events({
'keyup input.search-query': function (evt) {
console.log("Keyup value: " + evt.which);
if (evt.which === 13) {
console.log("Got an Enter keyup");
Session.set("searchQuery", "justATestVar");
}
},
'submit form': function (evt) {
evt.preventDefault();
}
...
You could also try adding evt.preventDefault(); in your keyup but I think it's the form submission that's doing it.

In case anyone got here trying to implement the search function as well, I recommend the following:
meteor add matteodem:easy-search
On client and server:
Players = new Meteor.Collection('players');
// name is the field of the documents to search over
Players.initEasySearch('name');
On the client, make a template.html:
<template name="searchBox">
{{> esInput index="players" placeholder="Search..." }}
<ul>
{{#esEach index="players"}}
<li>Name of the player: {{name}}</li>
{{/esEach}}
</ul>
</template>
Reference

Related

In Meteor can I capture or pass the link/anchor text in the event when user clicks a link?

I am trying to set a Session variable to the text that a user clicks on when they click a link. For example if the link is The Link.
I would like to Session.set('clickedLink', <<The Link>>); but with "The Link" obviously replaced with the text string that the user has clicked on.
Is this possible? Am I going about this all wrong?
I figured I might be able to use something like:
Template.SingleQuote.events({
"click .link": function (event) {
Session.set("currentPageName", event.a.text);
}
});
Use event.target.text.
Template.SingleQuote.events({
'click .link'(event) {
Session.set('currentPageName', event.target.text);
}
});
Edit:
Instead of what has been posted, it has been suggested by reviewers that I update this answer to make use of the following syntax:
'click .link': function(event) { /* ... */ }
Both of these are perfectly valid syntax for a Meteor Template Event, use whichever you feel most comfortable with.

Save the current view in variable to be able to render it later

I am reproducing a simplified version of my problem, to ask a fundamental question.
I have a template called 'form',
<template name="form">
<input id="name" type="text">
<button id="submitform type="submit">Submit</button>
</template>
I am handling the submit event as follows,
Template.form.events({
'click #submitform': function() {
event.preventDefault();
if(Meteor.user())
alert('submitted');
else{
//save the filled form along with view (basically the template or view)
Router.go('login');
}
}
});
My question is, how do i save the filled template with data filled in a variable/any how, so that i can render it after sign in.
This is how I am rendering to form template,
Router.route('/form', function () {
this.render('form');
});
What I want is to be able to render the user filled template/view back for him when he signs in. Please tell if there is a meteor way of doing it, and not easy JavaScript hack. Please ask if you need additional data/code.
Thanks in advance.
You can use a session variable for this if I'm understanding your question.
<template name="form">
<input id="name" type="text" value="{{name}}">
<button id="submitform type="submit">Submit</button>
</template>
Template.form.helpers({
name() {
return Session.get('name');
}
});
Template.form.events({
'click #submitform': function(event, template) {
event.preventDefault();
if(Meteor.user())
alert('submitted');
else{
Session.set('name', template.find('#name').value);
Router.go('login');
}
}
});
Then on your Meteor.loginWithPassword callback redirect back to the form route.
If you want to save the form with the user data in it, you could you make it invisible and then visible again later when you want to show it?
Otherwise you could repopulate the form from a save formData object. See Use jquery to re-populate form with JSON data

How to implement form area box in meteors JS?

I am new for MeteorJs. Some one could you please provide info for form area text tag.I tried to add text area and tried to implement using with event.
I got answer from refer few docs.. below is the correct one
html:
JS:
Template.body.events({
"submit .new-task": function (event) {
// Prevent default browser form submit
event.preventDefault();
var message=event.target.newMessage.value;

Session variable resetting between pages

I'm learning Meteor and I'm trying to use the counter example with Iron Router.
Everything is working in the counter page and the routes too, except that when I'm navigating between pages and come back to the counter page, the counter resets to 0 (after I've clicked and incremented the counter).
The HTML is:
<template name='counter'>
<button>Click Me</button>
<p>You've pressed the button {{counter}} times.</p>
</template>
and the javascript is:
Session.setDefault("counter", 0);
Template.counter.helpers({
counter: function () {
return Session.get("counter");
}
});
Template.counter.events({
'click button': function () {
Session.set("counter", Session.get("counter") + 10);
}
});
I tried to put
Session.setDefault("counter", 0);
inside a template.counter.rendered/template.counter.created but it's the same.
Does anyone knows how to guarantee that session values can be preserved?
It seems that everything is working as expected and it was my problem: as I was trying to test dynamic routes, sometimes I changed the URL manually on the browser instead of using the "go back" button or navigate using my own page links.
And, as it is supposed, by doing that I'm refreshing the page, and everytime I refresh a page I loose session values...
Hope this could be useful to someone else.

Reactive updates not received in other browsertabs

Meteor promises reactive updates, so that views are auto-updated when data changes. The included leaderboard example demonstrates this. It runs fine when I test it: data is updated across several browsertabs in different browsers, as expected.
All set and go, I started coding with meteor and progress was being made, but when I tested for reactive updates across browertabs, I noticed that only after a short while the updates across tabs stopped.
I boiled down the problem to the following code, based on a new empty meteor project:
updatebug.html
<head>
<title>updatebug</title>
</head>
<body>
{{> form}}
</body>
<template name="form">
<form onsubmit="return false;">
{{#each items}}
{{> form_item }}
{{/each}}
</form>
</template>
<template name="form_item">
<div>
<label>{{name}}
<input type="text" name="{{name}}" value="{{value}}">
</label>
</div>
</template>
updatebug.js:
Items = new Meteor.Collection("items");
if (Meteor.is_client) {
Template.form.items = function () {
return Items.find();
};
Template.form_item.events = {
'blur input': function(e) {
var newValue = $(e.target).val();
console.log('update', this.name, this.value, newValue);
Items.update({_id: this._id}, {$set: {value: newValue}});
},
};
}
if (Meteor.is_server) {
Meteor.startup(function () {
if (Items.find().count() === 0) {
Items.insert({name: 'item1', value: 'something'});
}
});
}
Run in multiple browsertabs, start changing the value of the input in one tab. The other tabs will reflect the change. Goto the next tab and change the value. Repeat a couple of times.
After a while, no more updates are received by any other tabs. It seems that once a tab has changed the value, it does not receive/show any more updates.
Differences compared to the leaderboard example (since it's very similar):
The leaderboard uses no form controls
The leaderboard example does an increment operation on update, not a set
I am about to file a bug report, but want to be sure I am not doing anything stupid here, or missing an essential part of the Meteor Collection mechanics (yes, autopublish package is installed).
The issue here is input element preservation. Meteor will preserve the input state of any form field with an id or name attribute across a template redraw. The redraw is preserving the old text in your form element, because you wouldn't want to interrupt another user typing in the same field. If you remove the name attribute from the text box, each tab will update on blur.
In fact, I'm not sure why the first update works in your example. That may actually be the bug!
You can see it's not a data problem by opening the console in each browser. On each blur event you will get an updated document in every open tab. (Type Items.find().fetch())

Resources