How can my Meteor Chat app recognize the users message? - javascript

Im having a really hard time with a project. Im pretty new to Meteor and JavaScript for that matter. Any help would be great. I have created a messenger app. When the users sign in, they can select who to chat with. However, when they start chatting. It only recognizes the user who is signed in and not the other chatter. Here is a screenshot of what I mean. I am signed in as a user from firefox and another from chrome.Here is the image, showing the chat.
Here is my HTML
<template name="chat_page">
<h2>Type in the box below to send a message!</h2>
<div class="row">
<div class="col-md-12">
<div class="well well-lg">
{{#each messages}}
{{> chat_message}}
{{/each}}
</div>
</div>
</div>
<div class="row">
<div class="col-md-12">
<form class="js-send-chat">
<input class="input" type="text" name="chat" placeholder="type a message here...">
<button class="btn btn-default">send</button>
</form>
</div>
</div>
</template>
<template name="chat_message">
<div class = "container">
<div class = "row">
<div class = "col-md-6">
{{> profile}} said: {{text}}
</div>
</div>
</div>
</template>
<template name="profile">
<small>
<img src = "/{{avatar}}" class="img-rounded" width="65" height="50">
{{username}}
</small>
</template>
Here is my JavaScript.
Template.chat_page.helpers({
messages:function(){
var chat = Chats.findOne({_id:Session.get("chatId")});
return chat.messages;
},
other_user:function(){
return ""
},
})
Template.profile.helpers({
username: function() {
return Meteor.user().profile.username;
},
avatar: function() {
return Meteor.user().profile.avatar;
},
})

Related

Creating a search box with vue.js

I'm wanting to add functionality for the search box to search the current cards on the page for the movie inputted, but all the other examples and solutions I've found online their solutions don't seem to work for me.
This is the body of the HTML:
<body>
<div id="app">
<div class="row pt-3">
<div class="col">
<input type="text" class="form-control" v-model="search" placeholder="Search Movies">
</div>
<div class="col-md-auto">
<button type="button" class="btn btn-primary" id="search"> Go! </button>
</div>
</div>
<div class="row text-center pt-3">
<div v-for="movie in movies" class="card" style="width: 18rem;">
<img :src="movie.Poster" class="card-img-top" alt="img">
<div class="card-body">
<h5 class="card-title">{{ movie.Title }}</h5>
<p class="card-text">{{ movie.Year }}</p>
View Movie
</div>
</div>
</div>
</div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.4.2/vue.js"></script>
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
<script src="main.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap#5.0.0-beta1/dist/js/bootstrap.bundle.min.js" integrity="sha384-ygbV9kiqUc6oa4msXn9868pTtWMgiQaeYH7/t7LECLbyPA2x65Kgf80OJFdroafW" crossorigin="anonymous"></script>
</body>
And this the JS file:
new Vue({
el: '#app',
data: {
movies: [],
search: '',
},
created() {
var vm = this
axios.get('https://www.omdbapi.com/?s=Harry+Potter&apikey=a9018efb')
.then(function(response) {
vm.movies = response.data.Search
})
}
})
Instead of looping over movies, create a computed set of filtered data to loop over. For example, if you were searching the titles:
computed: {
searchedMovies() {
return this.movies.filter(movie => {
return movie.Title.toLowerCase().includes(this.search.toLowerCase());
})
}
}
Loop over this:
<div v-for="movie in searchedMovies" :key="movie.Title">
...
</div>
When you haven't searched for anything, this will return all movies.

Vue js: Change value using if else

I am new to Vue and I have two button. One is to show the login section and one is to show the register section. What I am tryin to achieve is, if I click on the login button, I want the login section to show and if I click on the register button, I want to hide login section and the register section to show. And by default, I want the login section to be showing. And also, if I click on the login button or Join button and that section was already showing, I want to keep that section showing. Is there a way to achieve this using if else statement or is there a better way to do this. Below is my code
var app = new Vue({
el: '#app',
data: {
displayLoginPage: true,
displayJoinPage: false
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div class="container-fluid p-0" id="app">
<div class="col-md-12">
<div class="col-md-12 sub-title">
<div class="col horizontal-line">
<h5>PERSONAL DETAILS</h5>
</div>
<div class="col-md-12 text-color-per">
<p>Make Sure All Enter Information Are Correct</p>
</div>
</div>
</div>
<div class="d-flex justify-content-center entry-section col-sm-12">
<div class="col-md-6 entry-option-button-login" id="show-login-section">
<button #click="displayLoginPage = !displayLoginPage" type="button" name="btn button">
Login</button>
</div>
<div class="col-md-6 entry-option-button-join" id="show-join-section">
<button #click="displayJoinPage = !displayJoinPage" type="button" name="btn button">
Join</button>
</div>
</div>
<div v-show="displayLoginPage">
<h5>Hello Login Page</h5>
</div>
<div v-show="displayJoinPage">
<h5>Hello Register Page</div>
</div>
</div>
You could use a single boolean, since there are only two views. Set the variable to true to show the login view and hide the other, and vice versa for false. Additionally, replace v-show with v-if and v-else:
<template>
<div>
<button #click="displayLoginPage = true">Login</button>
<button #click="displayLoginPage = false">Join</button>
<div v-if="displayLoginPage">
<h5>Hello Login Page</h5>
</div>
<div v-else>
<h5>Hello Register Page</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
displayLoginPage: true
}
}
}
</script>
var app = new Vue({
el: '#app',
data: {
displayLoginPage: true
}
})
<script src="https://unpkg.com/vue#2.6.11/dist/vue.min.js"></script>
<div class="container-fluid p-0" id="app">
<div class="col-md-12">
<div class="col-md-12 sub-title">
<div class="col horizontal-line">
<h5>PERSONAL DETAILS</h5>
</div>
<div class="col-md-12 text-color-per">
<p>Make Sure All Enter Information Are Correct</p>
</div>
</div>
</div>
<div class="d-flex justify-content-center entry-section col-sm-12">
<div class="col-md-6 entry-option-button-login" id="show-login-section">
<button #click="displayLoginPage = true" type="button" name="btn button">
Login</button>
</div>
<div class="col-md-6 entry-option-button-join" id="show-join-section">
<button #click="displayLoginPage = false" type="button" name="btn button">
Join</button>
</div>
</div>
<div v-if="displayLoginPage">
<h5>Hello Login Page</h5>
</div>
<div v-else>
<h5>Hello Register Page</div>
</div>
</div>
If you plan to have more than two views, you could set the variable to a string specific to each view. For example, set displayPage to "login" to show the login-view; or "join" to show the join-view. Change your v-show condition to compare displayPage against the corresponding value:
<template>
<div>
<button #click="displayPage = 'login'">Login</button>
<button #click="displayPage = 'join'">Join</button>
<div v-show="displayPage == 'login'">
<h5>Hello Login Page</h5>
</div>
<div v-show="displayPage == 'join'">
<h5>Hello Register Page</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
displayPage: 'login'
}
}
}
</script>
var app = new Vue({
el: '#app',
data: {
displayPage: 'login'
}
})
<script src="https://unpkg.com/vue#2.6.11/dist/vue.min.js"></script>
<div class="container-fluid p-0" id="app">
<div class="col-md-12">
<div class="col-md-12 sub-title">
<div class="col horizontal-line">
<h5>PERSONAL DETAILS</h5>
</div>
<div class="col-md-12 text-color-per">
<p>Make Sure All Enter Information Are Correct</p>
</div>
</div>
</div>
<div class="d-flex justify-content-center entry-section col-sm-12">
<div class="col-md-6 entry-option-button-login" id="show-login-section">
<button #click="displayPage = 'login'" type="button" name="btn button">
Login</button>
</div>
<div class="col-md-6 entry-option-button-join" id="show-join-section">
<button #click="displayPage = 'join'" type="button" name="btn button">
Join</button>
</div>
</div>
<div v-show="displayPage == 'login'">
<h5>Hello Login Page</h5>
</div>
<div v-show="displayPage == 'join'">
<h5>Hello Register Page</div>
</div>
</div>
You just need to explicitly set the values for displayLoginPage and displayJoinPage when either button is clicked. See the following example:
var app = new Vue({
el: '#app',
data: {
displayLoginPage: true,
displayJoinPage: false
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div class="container-fluid p-0" id="app">
<div class="col-md-12">
<div class="col-md-12 sub-title">
<div class="col horizontal-line">
<h5>PERSONAL DETAILS</h5>
</div>
<div class="col-md-12 text-color-per">
<p>Make Sure All Enter Information Are Correct</p>
</div>
</div>
</div>
<div class="d-flex justify-content-center entry-section col-sm-12">
<div class="col-md-6 entry-option-button-login" id="show-login-section">
<button #click="(displayLoginPage = true) && (displayJoinPage = false)" type="button" name="btn button">
Login</button>
</div>
<div class="col-md-6 entry-option-button-join" id="show-join-section">
<button #click="(displayJoinPage = true) && (displayLoginPage = false)" type="button" name="btn button">
Join</button>
</div>
</div>
<div v-show="displayLoginPage">
<h5>Hello Login Page</h5>
</div>
<div v-show="displayJoinPage">
<h5>Hello Register Page</div>
</div>
</div>

Vue, edit the content of components with another component

I have a simple Vue js spa app that contain some bulma.io component.
And I need to edit the content of components with another component.
Like this image:
And somehow we need it to dynamically show form component when the panel or message component is clicked.
Thanks
Updated:
index.html
<div id="app">
<div class="columns">
<div class="column is-6">
<message title="Message test title 1" body="Message test body 1" #titleUpdate="title = $event" #bodyUpdate="body = $event"></message>
<message title="Message test title 2" body="Message test body 2" #titleUpdate="title = $event" #bodyUpdate="body = $event"></message>
<card title="Card test title 1" body="Card test body 2" #titleUpdate="title = $event" #bodyUpdate="body = $event"></card>
<card title="Card test title 1" body="Card test body 2" #titleUpdate="title = $event" #bodyUpdate="body = $event"></card>
</div>
<div class="column is-6">
<messageform></messageform>
<cardform></cardform>
</div>
</div>
</div>
main.js
import Vue from 'vue'
import message from './components/message'
import card from './components/card'
import messageform from './components/messageform'
import cardform from './components/cardform'
/* eslint-disable */
new Vue({
el: '#app',
components: { message, card, messageform, cardform }
});
card.vue
<template>
<div class="card">
<div class="card-image">
<figure class="image is-4by3">
<img src="https://bulma.io/images/placeholders/1280x960.png" alt="Placeholder image">
</figure>
</div>
<div class="card-content">
<div class="media">
<div class="media-left">
<figure class="image is-48x48">
<img src="https://bulma.io/images/placeholders/96x96.png" alt="Placeholder image">
</figure>
</div>
<div class="media-content">
<p class="title is-4">{{ title }}</p>
<p class="subtitle is-6">#{{ title }}</p>
</div>
</div>
<div class="content">
{{ body }}
<br>
<time datetime="2016-1-1">11:09 PM - 1 Jan 2016</time>
</div>
</div>
</div>
</template>
<script>
export default {
props: ['title', 'body'],
name: 'card',
methods: {
}
}
</script>
<style scoped>
.card {
margin-top: 20px
}
</style>
message.vue
<template>
<article class="message" v-show="isShow">
<div class="message-header">
<p>{{ title }}</p>
<button class="delete" aria-label="delete" #click="close"></button>
</div>
<div class="message-body">
{{ body }}
</div>
</article>
</template>
<script>
export default {
props: ['title', 'body'],
name: 'message',
data () {
return {
isShow: true
}
},
methods: {
close () {
this.isShow = false
}
}
}
</script>
<style>
</style>
cardform.vue
<template>
<article>
<h1>Card form</h1>
<div class="field">
<label class="label">Card title</label>
<div class="control">
<input class="input" type="text" placeholder="Text input" :value="title">
</div>
</div>
<div class="field">
<label class="label">Card body</label>
<div class="control">
<textarea class="textarea" placeholder="Textarea" :value="body"></textarea>
</div>
</div>
</article>
</template>
<script>
export default {
props: ['title', 'body'],
name: 'cardform'
}
</script>
<style>
</style>
messgeform.vue
<template>
<article>
<h1>Message form</h1>
<div class="field">
<label class="label">Message title</label>
<div class="control">
<input class="input" type="text" placeholder="Text input" :value="title" #input="titleUpdate">
</div>
</div>
<div class="field">
<label class="label">Message body</label>
<div class="control">
<textarea class="textarea" placeholder="Textarea" :value="body" #input="bodyUpdate"></textarea>
</div>
</div>
</article>
</template>
<script>
export default {
props: ['title', 'body'],
name: 'messageform',
methods: {
titleUpdate (event) {
this.$emit('titleUpdate', event.target.value)
},
bodyUpdate (event) {
this.$emit('bodyUpdate', event.target.value)
}
}
}
</script>
<style>
</style>
Not really sure I understood your question, but this may help you if you want to transfer data/use fonction from one component to another.
You should take a look at the usage of Passing Data to Child Components with props and Sending Messages to Parents with Events as it will cover everything you need to know to implement that functionality.
When you want to pass data to child you'll need to use props and get the data back by using the event emitter.
You can use eventbus or even vuex. I suggest you to take a look at props and events first.

Updating ng-repeat angularJS with mysqli connection

I am quite new with AngularJS so excuse me if I'm asking a stupid thing. I'm trying to create a task manager for events with AngularJS + Mysql + PHP.
The layout is separated in two columns. In the left column there's an overview of staff, loaded by function getUsers() in app.js. By clicking the + button after each staffname the user_id is being posted in a mysql database table. The results of this table is shown in the right column, function getEventUsers() in app.js. I'm trying to find out how to reload or update the right table after clicking the + button. The functions itself are working correctly (they get json_encoded results from the .php pages), but the right column is not updating itself only after pressing F5 after each click it is showing the correct result. So the right column, so function getEventUsers() in app.js, has to refresh/reload after clicking on the + button.
Template
ng-app="myApp" is in the html tag
ng-controller="usersController" is in the body tag
<div class="row">
<div class="container">
<blockquote><h1>Task Manager</h1></blockquote>
<div class="col-md-6">
<div class="widget-box" id="recent-box" ng-controller="usersController">
<div class="widget-header header-color-blue">
<div class="row">
<div class="col-sm-6">
<h4 class="bigger lighter">
<i class="glyphicon glyphicon-align-justify"></i>USERS
</h4>
</div>
<div class="col-sm-6">
<input type="text" ng-model="filterTask" class="form-control search header-elements-margin" placeholder="Filter Tasks">
</div>
</div></div>
<div class="widget-body ">
<div class="task">
<label class="checkbox" ng-repeat="user in users | filter : filterTask">
<input
type="checkbox"
value="{{user.active}}"
ng-checked="user.active==1"
ng-click="toggleStatus(user.id,user.active)"/>
<span ng-class="{strike:user.active==0}">{{user.firstname}} {{user.lastname}} [{{user.id}}]</span>
<a ng-click="addEventUser(user.id)" class="pull-right"><i class="glyphicon glyphicon-plus"></i></a>
</label>
</div>
</div>
</div>
</div>
<div class="col-md-6">
<div class="widget-box" id="recent-box" ng-controller="usersController">
<div class="widget-header header-color-blue">
<div class="row">
<div class="col-sm-6">
<h4 class="bigger lighter">
<i class="glyphicon glyphicon-align-justify"></i>EVENT MANAGER
</h4>
</div>
<div class="col-sm-6">
<input type="text" ng-model="filterTask" class="form-control search header-elements-margin" placeholder="Filter Tasks">
</div>
</div></div>
<div class="widget-body ">
<div class="task">
<label class="checkbox" ng-repeat="eventuser in eventusers | filter : filterTask">
<span ng-class="{strike:task.STATUS==2}">{{eventuser.firstname}} [{{eventuser.lastname}}]</span>
<a ng-click="deleteTask(eventuser.id)" class="pull-right"><i class="glyphicon glyphicon-trash"></i></a>
</label>
</div>
</div>
</div>
</div>
</div>
</div>
<script type="text/javascript" src="js/angular.min.js"></script>
<script type="text/javascript" src="app/app.js"></script>
App.js
//Define an angular module for our app
var app = angular.module('myApp', []);
app.controller('usersController', function($scope, $http) {
getUsers(); // Load all available users
function getUsers(){
$http.post("ajax/getUsers.php").success(function(data){
$scope.users = data;
//alert(data);
});
};
getEventUsers(); // Load all available users for event
function getEventUsers(){
$http.post("ajax/getEventUsers.php").success(function(data){
$scope.eventusers = data;
//alert(data);
});
};
$scope.addEventUser = function (user_id) {
$http.post("ajax/addEventUser.php?userid="+user_id).success(function(data){
alert(getEventUsers());
});
};
$scope.toggleStatus = function(item, status) {
if(status=='1'){
active='0';
}else{
active='1';
}
$http.post("ajax/updateUsers.php?id="+item+"&active="+active).success(function(data){
getUsers();
});
};
});

How can I choose a sub document to insert and update with a click function from the client side

I have two collections, one is a Posts collection which has posts, with an id.
And the other is a Sets collection which has an array called ArticleId that can be updated by the user by inserting a post id from the Posts collection into it via a click function with the button toggle-addToSet.
The user Creates the Array called ArticleId, gives it a name and saves articles in it periodically. Think Pinterest Boards or G+ collections.
I have a button on the post item that when a user clicks the icon, all the Sets he has created come up in a dialogue and the user chooses which Set he want to save the post id into.
<template name="summeryArticle">
<li>
<div class="row col s12 m7">
<div class="card" id="cardId">
<div class="card-image waves-effect waves-block waves-light">
<img src="{{better_featured_image.source_url}}">
</div>
<div class="card-content">
<h5 class=" truncate grey-text text-darken-4">{{title.rendered}}</h5>
MORE <i class="waves-effect waves-teal small material-icons right">playlist_add</i>{{>
likePartial}}{{> reblogPartial}}
<!-- The modal below is what brings up all the sets the user has created so that the user can pick with set they wat to save the article in -->
<div id="modal2" class="modal bottom-sheet">
<div class="modal-content">
<div class="row">
{{#each set}}
<div class="col s6 m6 addSet teal">
<div class="card ">
<div class="card-image">
<span class="card-title cardSet">{{name}}</span>
</div>
<div class="card-footer">
<button type="button" class="btn toggle-addToSet" name="button">add Article Id to this Set!</button>
</div>
</div>
</div>
{{/each}}
</div>
</div>
</div>
</div>
</div>
</div>
</li>
</template>
Graphically it looks like this
And when the user clicks the icon modal-trigger to bring up the Sets he created, it looks like this
As you can see, the user has three Sets, Lifestyle, Love, Business, they can choose to save the posts id into any one of those three.
## GOAL ##
I want to be able to choose a Set, click the add button of my chosen Set, and somehow capture the post Id of the current post in my foreach loop, and insert it into that via the click function, at the moment all I have is this
Template.summeryArticle.events({
'click .toggle-addToSet': function(e, template) {
var ob = this.id
console.log(ob);
}
});
and when I console log that, I just get the Set id instead of the post id.
Question
How can I capture the post id of the current post,
Choose a Set of my liking, then insert the post id into my chosen set?
And if there is a better way to achieve this, please let me know.
EDIT AFTER FEEDBACK
I did the second option like this
<template name="summeryArticle">
{{#let article=this}}
<li>
<div class="row col s12 m7">
<div class="card" id="cardId">
<div class="card-image waves-effect waves-block waves-light">
<img src="{{better_featured_image.source_url}}">
</div>
<div class="card-content">
<h5 class=" truncate grey-text text-darken-4">{{title.rendered}}</h5>
MORE <i class="waves-effect waves-teal small material-icons right">playlist_add</i>{{>
likePartial}}{{> reblogPartial}}
<!-- The modal below is what brings up all the sets the user has created so that the user can pick with set they wat to save the article in -->
<div id="modal2" class="modal bottom-sheet">
<div class="modal-content">
<div class="row">
{{#each set}}
<div class="col s6 m6 addSet teal">
<div class="card ">
<div class="card-image">
<span class="card-title cardSet">{{name}}</span>
</div>
<div class="card-footer">
{{#each s in set}}
<button type="button" class="btn toggle-addToSet" name="button" data-setid="{{s._id}}" articleid="{{article._id}}">add Article Id to this Set!</button> {{/each}}
</div>
</div>
</div>
{{/each}}
</div>
</div>
</div>
</div>
</div>
</div>
</li>
{{/let}}
</template>
my helper is like this
Template.summeryArticle.events({
'click .toggle-addToSet': function(e, template) {
var ob = this
console.log(ob);
var sid = $(e.currentTarget).data('setid');
var aid = $(e.currentTarget).data('articleid');
console.log(sid);
console.log(aid);
}
});
However, this is what I'm getting.
and the log looks like this
where 7MgLCEnTWjXFRhLg6 is the Sets_id depending on which of the three buttons I clicked
SECOND EDIT. CONTEXT
when i do this
<template name="summeryArticle">
{{#let article=_id}}
<li>
<div class="row col s12 m7">
<div class="card" id="cardId">
<div class="card-image waves-effect waves-block waves-light">
<img src="{{better_featured_image.source_url}}">
</div>
<div class="card-content">
<h5 class=" truncate grey-text text-darken-4">{{title.rendered}}</h5>
MORE <i class="waves-effect waves-teal small material-icons right">playlist_add</i>{{> likePartial}}{{> reblogPartial}}
<!-- The modal below is what brings up all the sets the user has created so that the user can pick with set they wat to save the article in -->
<div id="modal2" class="modal bottom-sheet">
<div class="modal-content">
<div class="row">
{{#each s in set}}
<div class="col s6 m6 addSet teal">
<div class="card ">
<div class="card-image">
<span class="card-title cardSet">{{name}}</span>
</div>
<div class="card-footer">
<button type="button" class="btn toggle-addToSet" name="button" data-setid="{{s._id}}" articleid="{{article._id}}">add Article Id to this Set!</button>
</div>
</div>
</div>
{{/each}}
</div>
</div>
</div>
</div>
</div>
</div>
</li>
{{/let}}
</template>
I get this
What's going on here is that I have the articles organised in categories, so what's going on now is that the article=_idbeing captured is the last article in the category, no matter what articles I try to add, it's just one article being caught, and its always the one at the bottom. I have no idea why
There are several ways. One would be something like this:
I would but article id and set id to toggle-addToSet button's data-attributes:
<button type="button" class="btn toggle-addToSet" name="button" data-setid="SETID" data-articleid="ARTID">add Article Id to this Set!</button>
If you call your summeryArticle like this:
{{#each article in articles}}
{{>summeryArticle article=article}}
{{/each}}
(another opotion is use let-helper:
<template name="summeryArticle">
{{#let article=this}}
...
{{/let}}
</template>
Then in your summeryArticle-template you can get article id in sets-loop:
{{#each s in set}}
<button type="button" class="btn toggle-addToSet" name="button" data-setid="{{s._id}}" articleid="{{article._id}}>add Article Id to this Set!</button>
{{/each}}
Then in template events:
Template.summeryArticle.events({
'click .toggle-addToSet': function(e, template) {
var ob = this.id
console.log(ob);
var sid = $(e.currentTarget).data('setid');
var aid = $(e.currentTarget).data('articleid');
Sets.update({_id: sid}, {$addToSet: {ArticlesId: aid}});
}
});
Note!
This assumes you can update your collection directly from client side! Depending on your situation, but usually it is not recommended. Normally you should deny client side updates and use methods for updating collections:
Method.call('mymethd', sid, aid, function(e, r) {
if (!e) {
console.log(r);
} else {
console.error(e);
}
});

Categories

Resources