Actively searching for a username in meteor ionic with angular - search

I'm trying to get meteor to search for a username as the user types. For example typing in "a" would give users "admin", "adam" and "apple". "ad" would give "admin", "adam" etc..
In the controller I have:
this.helpers({
users() {
return Meteor.users.find({username:this.searchText});
}
});
and in the template I have
<ion-content>
<div class="new-chat.search">
<label class="item item-input">
<input ng-model="searchText" type="search" placeholder="Enter a username">
</label>
</div>
<div class="list">
<a ng-repeat="user in chat.users" ng-click="chat.newChat(user._id)" class="item">
<h2>{{ user.username }}</h2>
<h3>{{ user.profile.name }}</h3>
</a>
</div>
</ion-content>
If "this.searchText" is chaneged to 'admin' it will return admin.
Anyone know what I need to do to get this working?

You want to search for a partial match I guess. You could use a regular expression for that.
https://docs.mongodb.com/manual/reference/operator/query/regex/
For example:
return Meteor.users.find({username: $regex: {this.searchText, $options: 'i'}});

Related

How do you implement a HTML form which accepts text input meant for tag/hashtag values?

Update 1
I managed to locate a solution called Tagify but I have problems implementing it.
As a start, I am trying to implement only the simplest version of Tagify.
Below is the content of my show.ejs file.
As you might expect, I also have a routes folder containing the CRUD routes and logic but I do not think that should be touched for this purpose?
I also ran the command to install the Tagify module in my node_modules folder but I am not exactly clear where I should import the contents of that folder, and whether I should be doing this
import tagify from ....
or
var Tagify = require("...")
Though I believe it is the latter.
<% include ../partials/header %>
<div class="container">
<div class="row">
<h1 style="text-align: center">Create a New Entry</h1>
<div style="width: 30%; margin: 25px auto;">
<form action="/events" , method="POST">
<div class="form-group">
<input class="form-control" type="text" name="name" placeholder="Name">
</div>
<div class="form-group">
<input class="form-control" type="number" name="price" placeholder="Price" min="0.01" step="0.01">
</div>
<div class="form-group">
<input class="form-control" type="text" name="image" placeholder="image url">
</div>
<div class="form-group">
<input class="form-control" type="text" name="description" placeholder="Describe the place">
</div>
<div class="form-group">
<textarea name='tags2' placeholder='Movie names'>The Matrix, Pulp Fiction, Mad Max</textarea>
</div>
<div class="form-group">
<button class="btn btn-lg btn-primary btn-block">Submit!</button>
</div>
</form>
View all events
</div>
</div>
</div>
<script type="text/javascript">
var input = document.querySelector('textarea[name=tags2]'),
tagify = new Tagify(input, {
enforceWhitelist: true,
whitelist: ["The Shawshank Redemption", "The Godfather", "The Godfather: Part II", "The Dark Knight", "12 Angry Men", "Schindler's List", "Pulp Fiction", "The Lord of the Rings: The Return of the King", "The Good, the Bad and the Ugly", "Fight Club", "The Lord of the Rings: The Fellowship of the Ring", "Star Wars: Episode V - The Empire Strikes Back", "Forrest Gump", "Inception", "The Lord of the Rings: The Two Towers", "One Flew Over the Cuckoo's Nest", "Goodfellas"],
callbacks: {
add: console.log, // callback when adding a tag
remove: console.log // callback when removing a tag
}
});
</script>
<% include ../partials/footer %>
Original question
For example, if I create a restaurant reviews website and am creating the page with a form so I can add new restaurants to the site, I would like to include fields like:
Restaurant name
Address
Average price per pax
Further to this, let's say I want to add a field where every semi-colon separated string can become something like a tag. Examples: "italian" "western" "family-friendly". How are possible ways I can implement this? It seems the standard HTML forms do not allow this and I need to import something - Am I wrong?
Currently learning & experimenting on a MEN stack (MEAN less Angular)
Much thanks in advance.

EJS just outputs the first found user in some cases

I'm Using mongoDB and ejs to display all my users in a table. The table also has some action buttons to delete the user and to change the users role. The buttons open a popup to change the role or to confirm the deletion. But EJS doesn't pass the users info into the popup. It works totally fine in the table, but not in the popup.
My EJS User Table with the Role change Popup:
<tbody>
<%users.forEach(function(users){%>
<tr>
<td><%=users.name%></td>
<td><%=users.username%></td>
<td><%=users.createdAt%></td>
<td><span class="badge label-table badge-<%=users.role%>"><%=users.role%></span></td>
<td><span class="badge label-table badge-<%=users.verifyEmailToken%>"><%=users.verifyEmailToken%></span></td>
<td>
<button type="submit" class="btn btn-xs btn-success" data-toggle="modal" data-target="#con-close-modal" name="changeRoleButton"><i class="remixicon-user-settings-line"></i></button>
</td>
</tr>
<div id="con-close-modal" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" style="display: none;">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title">Change <%=users.name%> Role</h4>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
</div>
<form class="" action="/changeuserrole" method="post">
<div class="modal-body p-4">
<div class="row">
<div class="col-md-12">
<div class="form-group">
<label for="field-1" class="control-label">User Role</label>
<select class="form-control" name="role">
<option>Partner</option>
<option>Admin</option>
<option>User</option>
</select>
</div>
<button type="submit" value="<%=users._id%>" name="userroleid" class="btn btn-primary">Submit</button>
</div>
</div>
</div>
</form>
</div>
</div>
</div>
<%});%>
</tbody>
Here is my app.js where I search for the users and pass them to EJS:
app.get("/users", function(req, res) {
if (req.isAuthenticated() && req.user.role === "Admin") {
User.find({}, function(err, foundUsers) {
if (err) {
console.log(err);
} else {
res.render("users", {
users: foundUsers,
name: req.user.name.replace(/ .*/, ''),
email: req.user.username,
});
}
});
} else {
res.redirect("/login");
}
});
All the <%=users...%> tags work inside the table, but not inside the popup divs. Inside the Popup it just displays the information from the first user in the Database, which is super strange.
I would be very thankful for any kind of help. Thanks!
Your ejs code is good. I think that the problem is the id of each modal.
For each user you generate a modal with id="con-close-modal", So all your modals have the same id. As a result, every submit button (all of them have the same data-target="#con-close-modal"), triggers the same modal, probably the first one.
I recommend you, give each modal a unique id like
<div id="<%= users._id %>" class="modal fade" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true" style="display: none;">
and give each submit button the right data-target attribute
<button type="submit" ... data-target="#<%= users._id %>"...></button>
I may be wrong, but since the popup is displaying only the info from the first user, you may need the specific user id to be apart of the link. I had a similar issue with a project, except it was a link to a new view instead of a pop up.
I hope this documentation may be of some help
https://mongodb.github.io/node-mongodb-native/api-bson-generated/objectid.html

How to prevent registration if Password and Confirm Password are not the same

I have a simple registration form as follows:
<div class ="container form">
<div class="jumbotron form"><h2><i class="fa fa-user-plus" aria-hidden="true"></i> Signup</h2></div>
<form action = "/register" method="POST">
<div class="form-group">
<i class="fa fa-user" aria-hidden="true"></i>
<label for="username">Username</label>
<input type = "text" class = "form-control" placeholder = "Enter username" name="username">
</div>
<div class="form-group">
<i class="fa fa-key" aria-hidden="true"></i>
<label for="password1">Password</label>
<input id="password1" type = "password" class ="form-control" placeholder = "Enter password" name="password1">
</div>
<div class="form-group">
<i class="fa fa-key" aria-hidden="true"></i>
<label for="password2">Confirm password</label>
<input id="password2" type = "password" class ="form-control" placeholder = "Enter password" name = "password">
</div>
<div class="form-group">
<i class="fa fa-picture-o" aria-hidden="true"></i>
<label for="img">Image</label>
<input type = "text" class ="form-control" placeholder = "Enter image URL" name = "image">
</div>
<button id="submit-login" type ="submit" class="btn btn-primary btn-lg">Signup</button>
</form>
</div>
My register route looks like this:
router.post("/register", function(req, res){
var newUser = new User({username: req.body.username, image: req.body.image});
User.register(newUser, req.body.password, function(err, user){
if(err){
res.redirect("/blogs");
console.log(err);
}
passport.authenticate("local")(req, res, function(){
res.redirect("/blogs");
});
});
})
I need to throw an error if the password fields don't match to prevent user registration. I figured it might be best to write some middleware and insert it in the register route, but I've been playing around with code and cannot quite work out how to write this middleware. Can anybody help?
My thoughts are that this requires some kind of if statement along the lines of if(document.getElementById("password1").value != document.getElementById("password2").value then hijack the POST route, but not sure how to write it or where to insert it in the code?
Update: I still don't have a solution for this.
I've now tried the following in my JS file but it doesn't work either:
$('#submit-login').on('submit', function(e){
e.preventDefault();
if($('#password1').val() !== $('#password2').val());
alert("Passwords don't match!")
}
)
Anyone able to advise?

NodeJS Uncaught reference error for EJS variable that isn't required in page render

I am getting an uncaught reference error for a variable 'profile_image' that isn't used in the page render when attempting to check GET variable 'message' for 'error'. The 'profile_image' is used in the 'partials/header' however this particular render is using 'partials/header-shadow'. I am using a similar <% if //condition {} %> on another page with the same partials and it works okay, and if I remove the <% if //condition {} %> statement from this page it works okay too. I can't figure out why this particular page doesn't work, any ideas?
here is the EJS:
<% include partials/index-header-shadow %>
<div class="container">
<div class="col col-1-1">
<div class="wrapper no-scroll">
<div class="signup-form">
<div class="signup-form-inner">
<h3>Sign Up</h3>
<% if ( message == "error") { %>
<span class="error">This email is already being used, you can login to your account by clicking the link below</span>
<% } %>
<form action="/sign_up" method="post">
<input type="text" name="name" placeholder="Username" required/>
<span class="error">Please enter a username</span>
<input type="email" name="email" placeholder="Email Address" required/>
<span class="error">Please enter a valid email address</span>
<input type="password" name="password" pattern=".{6,}" placeholder="Password (minimum 6 characters)" required/>
<span class="error">Please enter a password</span>
<input type="hidden" name="profile_image" value="images/profile_images/user_icon.png"/>
<input type="submit" name="submit" class="submit-btn" value="Sign Up" />
</form>
<div class="login-link">
Already have an account? Log in here
</div>
</div>
</div>
</div>
</div>
</div>
<% include partials/footer %>
And here is the Server Render:
/* GET Sign_Up page. */
app.get('/sign_up',
function(req, res){
res.render('sign_up',
{
title: 'Utasko | Sign Up',
});
});
/* GET Sign_Up POST data. */
app.post('/sign_up', passport.authenticate('signup', {
successRedirect: '/login?message=success',
failureRedirect: '/sign_up?message=error'
}));
You need to pass the message parameter. in your case
app.get('/sign_up',
function(req, res){
res.render('sign_up',
{
title: 'Utasko | Sign Up',
message:req.query.message
});
});

Parsing nested data from select form with Angularjs

I'm trying to parse a model from a form which contain a select(ngOptions) and save it to db but the selected value is never parsed. i'm stuck here can someone help please.
here is my code:
View
<section class="container" data-ng-controller="TagsController" >
<h2><i class="fa fa-pencil-square-o"></i>Add a new Tag</h2>
<form class="form-horizontal col-md-5" data-ng-submit="create()">
<div class="form-group ">
<div class="controls">
<input type="text" class="form-control input-lg" data-ng-model="label" id="label" placeholder="Label" required>
</div>
</div>
<div class="form-group" data-ng-controller="CategoriesController" data-ng-init="find()">
<select class="form-control input-lg" ng-model="category._id" ng-options="category._id as category.label for category in categories">
<option value="">Choose a Category</option>
</select>
</div>
<div class="control-group">
<div class="controls">
<input type="submit" class="btn">
</div>
</div>
</form>
</section>
controller
angular.module('mean.tags').controller('TagsController', ['$scope', '$routeParams', '$location', 'Global', 'Tags', function ($scope, $routeParams, $location, Global, Tags) {
$scope.global = Global;
$scope.create = function() {
var tag = new Tags({
label: this.label,
category: this.category
});
tag.$save(function(response) {
$location.path("tags/");
});
this.label = "";
this.category = "";
};
...
I found the problem so i will answer my question. The problem was due to architecture restrictions, Angularjs don't allow to nest a ng-controller inside an other one...

Resources