Following this tutorial about Dynamic templates with dynamic data, I am not getting the template to show dynamically when the click event is fired on task1 or task2.
I would like to know why and how to fix it. Many Thanks
Template.mainMenu.onCreated(function () {
this.selectedItem = new ReactiveVar("task1");
});
Template.mainMenu.helpers({
menuItems: [
{menuItem: "task1", login: false},
{menuItem: "task2", login: true},
{menuItem: "task3", login: true},
{menuItem: "task4", login: true},
{menuItem: "task5", login: true},
{menuItem: "task6", login: true},
{menuItem: "task7", login: false},
{menuItem: "task8", login: false},
{menuItem: "task9", login: false},
{menuItem: "LOG IN", login: false}
],
task: function () {
return Template.instance().selectedItem.get();
},
taskData: function () { <<---MY IDE SAYS UN USED PROPERTY taskData -------
return Template.instance().selectedItem.get();
}
});
Template.mainMenu.events({
'click .menuItem': function (event, template) {
var item = this.menuItem;
var date = new Date();
initializeTask(item);
Session.set('taskSelected', this.menuItem);
Session.set('showMainMenu', false);
Session.set('taskInProgress', true);
Session.set('showFooter', true);
//tasks tracking
if (Tasks.find().count() === 0) {
Tasks.insert({menuItem: item, createdAt: date});
} else {
var selected = Tasks.findOne();
Tasks.update({_id: selected._id}, {$set: {menuItem: item, createdAt: date}});
}
var currentItem = $(event.target).closest("li");
template.selectedItem.set(currentItem.data("template"));
}
});
<head>
<title>Tasks</title>
</head>
<body>
{{> header}}
{{#if (session 'showMainMenu')}}
{{> mainMenu}}
{{/if}}
{{#if (session 'showFooter')}}
{{> footer}}
{{/if}}
</body>
<template name="mainMenu">
<div class="container">
<div class="row">
<section class="col-xs-12">
<div class="list-group">
{{#each menuItems}}
<li data-template="{{menuItem}}">
<a href="#" class="list-group-item menuItem">
<img src="/abc.png">
{{menuItem}} <span class="badge">></span>
</a>
</li>
{{/each}}
</div>
</section>
{{> Template.dynamic template=task data=taskData}}
</div>
</div>
</template>
<template name="task1">
task is {{ this }}
<form>
<input type="text" name="task1Number">
<input type="submit">
</form>
</template>
<template name="task2">
task is {{ this }}
</template>
Related
I am trying to set values in a map stored in a pinia store (persisted into localstorage)
in this minimal (non) working example pushing elements into a list works fine but adding a element into a Map does not persist.
component.vue
<script setup lang="ts">
import { useStore } from "./store"
const store = useStore()
</script>
<template>
<main>
<button
#click="store.createA"
>
Create new Array item
</button>
<ul v-if="store.array.length > 0">
<li v-for="(item) in store.array">
{{ item }}
</li>
</ul><br/>
<button
#click="store.createO"
>
Create Map Object
</button>
<ul v-if="store.mapObj.size > 0">
<li v-for="(item) in store.mapObj">
{{ item[1] }}
</li>
</ul>
</main>
</template>
store.ts
import { defineStore } from "pinia"
export const useStore = defineStore({
id: "character-manager",
state: () => ({ array: [] as Array<{key: string, value: string }>,
mapObj: new Map() as Map<string,string>}),
actions: {
createA() {
this.array.push({key: "key", value: "value"})
},
createO() {
this.mapObj.set("key", "value")
},
},
persist: {
enabled: true,
strategies: [{ storage: localStorage }],
},
})
I'm creating a blog with free sewing patterns as content. I'm using route parameters to receive each blog individually. However, I'm getting a blank page when trying to retrieve its data from firebase firestore. Please help.
The blog's id appears on my address bar:
http://localhost:8080/#/admin/single-pattern/4LIS362IEWa7RKEv79g8
But it renders a blank page. I cant see my blog content.
This is my route path code. I've added a parameter of :id in my singlepattern. The SinglePattern component is where I will get the individual blog's data:
{
path: "/admin",
name: "admin",
component: Admin,
meta: {
auth: true,
},
children: [
{
path: "dashboard",
name: "dashboard",
component: Dashboard,
},
{
path: "manage-patterns",
name: "manage-patterns",
component: ManagePatterns,
},
{
path: "single-pattern/:id",
name: "single-pattern",
component: SinglePattern,
},
],
},
Here is my "ListPattern" component's code. ListPattern is where all my sewing blogs are displayed.
<template>
<div class="list-blogs">
<h1>LIST BLOG TITLES</h1>
<br />
<input type="text" v-model="search" placeholder="search blogs" />
<div
class="blog-cover"
v-for="pattern in filteredPatterns"
:key="pattern.id"
>
<div>
<router-link v-bind:to="'/admin/single-pattern/' + pattern.id">
<h3 style="cursor: pointer" v-rainbow>
{{ pattern.title | uppercase }}
</h3></router-link
>
</div>
<p
:style="'background-color: var(--lightgrey)'"
:inner-html.prop="pattern.description | snippet"
></p>
</div>
</div>
</template>
<script>
import firebase from "firebase";
import searchMixin from "../mixins/searchMixin";
// Basic Use - Covers most scenarios
import { VueEditor } from "vue2-editor";
import Quill from "quill";
const AlignStyle = Quill.import("attributors/style/align");
Quill.register(AlignStyle, true);
// import $ from "jquery";
import Swal from "sweetalert2";
window.Swal = Swal;
const Toast = Swal.mixin({
toast: true,
position: "top-end",
showConfirmButton: false,
timer: 3000,
});
window.Toast = Toast;
export default {
name: "ManagePatterns",
components: { VueEditor },
data() {
return {
patterns: [],
pattern: {
title: null,
description: null,
image: null,
},
search: "",
};
},
firestore() {
return {
patterns: firebase.firestore().collection("free-patterns"),
};
},
computed: {},
},
};
</script>
And this is my 'SinglePattern' component where the clicked blog/pattern is displayed.
<template>
<div class="single-pattern">
<div class="blog-cover">
<div>
</div>
<div v-if="pattern">
<h3 style="cursor: pointer">
{{ pattern.title }}
</h3>
<div v-if="pattern.description">
<p
:style="'background-color: var(--lightgrey)'"
:inner-html.prop="pattern.description"
></p>
</div>
</div>
</div>
</div>
</template>
<script>
import firebase from "firebase";
import searchMixin from "../../mixins/searchMixin";
export default {
data() {
return {
id: this.$route.params.id,
patterns: [],
pattern: {
title: null,
description: null,
image: null,
},
};
},
firestore() {
return {
patterns: firebase.firestore().collection("free-patterns"),
};
},
mixins: [searchMixin],
created() {
console.log(this.$route.params.id);
var pat = this;
firebase
.firestore()
.collection("free-patterns")
.doc(this.$route.params.id)
.get()
.then(function(doc) {
if (doc.exists) {
pat.pattern = doc.data().pattern;
} else {
console.log("no such doc");
}
});
},
methods: {},
};
</script>
It works. I just had to change the code in my created() hook in 'SingePattern' component.
created() {
console.log(this.$route.params.id);
var docRef = firebase
.firestore()
.collection("free-patterns")
.doc(this.$route.params.id);
docRef
.get()
.then((doc) => {
if (doc.exists) {
this.pattern = doc.data();
} else {
// doc.data() will be undefined in this case
console.log("No such document!");
}
})
.catch((error) => {
console.log("Error getting document:", error);
});
I need your help to figure out what's wrong with my code.
I have a HomeLayout devided to 3 sections;
header
side
main
I have a conversation list ; it will be rendered in the main section and it contain a subsection called One_Conversation : when I click on conversation it's rendered
well right here it's ok : my problem that when I click on another conversation , the template won't be rendered
this is my code :
/routes.js
FlowRouter.route('/conversation', {
name: 'Conversation',
action(){
BlazeLayout.render('HomeLayout', {side: 'Messages', main: 'Conversation_list'});
}
});
FlowRouter.route('/conversation/:idConversation', {
name: 'oneConversation',
action(){
BlazeLayout.render('HomeLayout', {side: 'Messages', main: 'Conversation_list', conversation: 'One_conversation'});
}
});
/HomeLayout.html
<template name="HomeLayout">
<div class="app header-fixed sidebar-fixed aside-menu-fixed aside-menu-hidden">
{{> Header}}
<div class="app-body">
<div class="sidebar">
{{> Template.dynamic template=side }}
</div>
<main class="main">
<div class="container-fluid">
{{> Template.dynamic template=main }}
</div>
</main>
</div>
{{> Footer}}
</div>
</template>
/Conversation_list.html
<template name="Conversation_list">
<div class="messages">
////code
////code
////...
</div>
<conversation class="content">
{{> Template.dynamic template=conversation }}
</conversation>
</template>
and finnaly in my Conversation_list.events when I click to conversation
FlowRouter.go('/conversation/:idConversation', {idConversation:this._id});
this is /OneConversation.html Template
<template name="One_conversation">
{{#with oneConversation}}
<div class="contact-profile">
{{#if isDefault}}
<img src="{{contact.profile_pic}}" alt="" />
<p>{{contact.first_name}} {{contact.last_name}}</p>
{{else}}
<img src="http://emilcarlsson.se/assets/harveyspecter.png" alt="" />
<p>{{contactLiveChat.first_name}} {{contactLiveChat.last_name}}</p>
{{/if}}
<div class="social-media">
<i class="fa fa-facebook" aria-hidden="true"></i>
<i class="fa fa-twitter" aria-hidden="true"></i>
<i class="fa fa-instagram" aria-hidden="true"></i>
</div>
</div>
<div class="messages">
{{#each allMessagesOfConversation}}
<ul>
{{#if isFirst}}
<li class="replies">
<img src="http://emilcarlsson.se/assets/harveyspecter.png" alt="" />
<p>{{message}} </p>
</li>
{{else}}
<li class="sent">
<img src="{{contactM.profile_pic}}" alt="" />
<p>{{message}}</p>
</li>
{{/if}}
</ul>
{{/each}}
</div>
<div class="message-input">
<div class="wrap">
<input type="text" placeholder="Write your message..." />
<i class="fa fa-paperclip attachment" aria-hidden="true"></i>
<button class="submit"><i class="fa fa-paper-plane" aria-hidden="true"></i></button>
</div>
</div>
{{/with}}
</template>
and this is /OneConversation.js
import { Template } from ‘meteor/templating’;
import ‘./One_conversation.html’;
import {Meteor} from “meteor/meteor”;
var idConversation=’’;
var typeConversation=’’;
var token=’’;
var psid=’’;
Template.One_conversation.onCreated(function One_conversationOnCreated() {
idConversation = FlowRouter.getParam(“idConversation”);
// typeConversation= Session.get(‘typeConversation’);
//
//
// token= Session.get(‘token’);
// psid= Session.get(‘psid’);
// console.log("OneConversation psid: ",psid);
// console.log("OneConversation token: ",token);
//
// psid= FlowRouter.getParam(“psid”);
// console.log("OneConversation psid liveChat: ",psid);
Meteor.subscribe('allConversations');
Meteor.subscribe('allMessages');
Meteor.subscribe('allContacts');
Meteor.subscribe('allHotels');
Meteor.subscribe('allImMessenger');
});
Template.One_conversation.rendered = function () {
};
Template.One_conversation.helpers({
allMessagesOfConversation: function() {
return Messages.find({idConversation: idConversation},{sort: {createdAt: 1}}).map(function(message) {
if (message.typeMessage ==="1") {
message.isFirst=true;
return message;
}else {
return message;
}
});
},
oneConversation: function() {
return Conversations.findOne({_id: idConversation});
},
});
Template.One_conversation.events({
‘click .submit’(event,instance) {
const message = $(".message-input input").val();
if($.trim(message) === '') {
return false;
}
if(Session.get('typeConversation') ==='facebook'){
Meteor.call("sendMessage",Session.get('token'),Session.get('psid'),message, function (er) {
if (er) {
console.log("send message problem");
console.log(er);
} else {
console.log("message sended successfully");
$(".message-input input").val('');
}
});
}else{
var newMessageInfo = {
idSender: Session.get('psid'),
message: message,
type: "liveChat",
createdAt: new Date(),
idConversation: Session.get('idConversation'),
status: "seen",
typeMessage: '1'
};
Meteor.call('insertMessages', newMessageInfo, function (er) {
if (er) {
console.log("insert problem");
console.log(er);
} else {
console.log("message added successfully", "success");
$(".message-input input").val('');
}
});
}
},
});
what am I doing wrong ?
Well it's fixed , my problem was in the idConversation ;
i set the id of the conversation in a session conversationList.events and get it in the oneConversation Helper so the code become like this
/Conversation_list.js
import { Template } from 'meteor/templating';
import './conversationList.html';
import {Meteor} from "meteor/meteor";
Template.conversationList.onCreated(function conversationListOnCreated() {
Meteor.subscribe('allConversations');
Meteor.subscribe('allMessages');
Meteor.subscribe('allContacts');
Meteor.subscribe('allHotels');
Meteor.subscribe('allImMessenger');
});
var psid="";
var token="";
Template.conversationList.rendered = function () {
};
Template.conversationList.helpers({
toUpperCase: function(str) {
return str.toUpperCase();
},
allMessagesOfConversation: function() {
return Messages.find({idConversation: Session.get('conversationId')},{sort: {createdAt: 1}}).map(function(message) {
if (message.typeMessage ==="1") {
message.isFirst=true;
return message;
}else {
return message;
}
});
},
oneConversation: function() {
return Conversations.findOne({_id: Session.get('conversationId')});
},
allConversations: function() {
return Conversations.find({idHotel: Hotels.findOne({contractId: Meteor.users.findOne({_id: Meteor.userId()}).profile.contractId})._id,archived:false},{sort: {createdAt: -1}}).map(function(conversation, index) {
if (index === 0) {
conversation.isFirst = true;
}
if(conversation.typeConversation === 'facebook'){
conversation.isDefault = true;
}
return conversation;
});
},
});
Template.conversationList.events({
'click #archive'(event){
Meteor.call('archiveConversation',Session.get('idOneConversation'),function (err) {
if(err){
console.log(err);
}else{
FlowRouter.go('/conversation');
}
})
},
'click .contact'(event,instance) {
event.preventDefault();
if($("#contact_active").hasClass("active")){
$("#contact_active").removeClass("active");
$("#contact").addClass("active");
}else{
$("#contact").removeClass("active");
$("#contact_active").addClass("active");
}
Session.set('typeConversation',this.typeConversation);
if(this.typeConversation === 'facebook'){
const pageId = this.idPage;
console.log(pageId);
token = ImMessenger.findOne({pageId: pageId}).pageAccessToken;
Session.set('token', token);
psid = this.contact().idFacebook;
Session.set('psid', psid);
Session.set('conversationId', this._id);
}else{
psid = this.contactLiveChat()._id;
Session.set('idContactLiveChat', psid);
Session.set('conversationId', this._id);
}
FlowRouter.go('/conversation/:idConversation', {idConversation:this._id});
Session.set('idOneConversation',this._id);
},
'click .profile-img'(event) {
event.preventDefault();
$("#status-options").toggleClass("active");
},
'click .expand-button'(event) {
event.preventDefault();
$("#status-options").toggleClass("active");
},
'click .status-options ul li'(event) {
event.preventDefault();
$("#profile-img").removeClass();
$("#status-online").removeClass("active");
$("#status-away").removeClass("active");
$("#status-busy").removeClass("active");
$("#status-offline").removeClass("active");
$(this).addClass("active");
if($("#status-online").hasClass("active")) {
$("#profile-img").addClass("online");
} else if ($("#status-away").hasClass("active")) {
$("#profile-img").addClass("away");
} else if ($("#status-busy").hasClass("active")) {
$("#profile-img").addClass("busy");
} else if ($("#status-offline").hasClass("active")) {
$("#profile-img").addClass("offline");
} else {
$("#profile-img").removeClass();
};
$("#status-options").removeClass("active");
},
});
and this is
/oneConversation.js
import { Template } from 'meteor/templating';
import './oneConversation.html';
import {Meteor} from "meteor/meteor";
var idOneConversation='';
var typeConversation='';
var token='';
var psid='';
Template.oneConversation.onCreated(function oneConversationOnCreated() {
idOneConversation = FlowRouter.getParam("idConversation");
Session.set('idOneConversation',idOneConversation);
Meteor.subscribe('allConversations');
Meteor.subscribe('allMessages');
Meteor.subscribe('allContacts');
Meteor.subscribe('allHotels');
Meteor.subscribe('allImMessenger');
});
Template.oneConversation.rendered = function () {
};
Template.oneConversation.helpers({
allMessagesOfConversation: function() {
return Messages.find({idConversation: Session.get('idOneConversation')},{sort: {createdAt: 1}}).map(function(message) {
if (message.typeMessage ==="1") {
message.isFirst=true;
return message;
}else {
return message;
}
});
},
oneConversation: function() {
return Conversations.findOne({_id: Session.get('idOneConversation')});
},
});
Template.oneConversation.events({
'click #archive'(event){
Meteor.call('archiveConversation',Session.get('idOneConversation'),function (err) {
})
},
'click .submit'(event,instance) {
const message = $(".message-input input").val();
if($.trim(message) === '') {
return false;
}
if(Session.get('typeConversation') ==='facebook'){
Meteor.call("sendMessage",Session.get('token'),Session.get('psid'),message, function (er) {
if (er) {
console.log("send message problem");
console.log(er);
} else {
console.log("message sended successfully");
$(".message-input input").val('');
}
});
}else{
var newMessageInfo = {
idSender: Session.get('idContactLiveChat'),
message: message,
type: "liveChat",
createdAt: new Date(),
idConversation: Session.get('idOneConversation'),
status: "seen",
typeMessage: '1'
};
Meteor.call('insertMessages', newMessageInfo, function (er) {
if (er) {
console.log("insert problem");
console.log(er);
} else {
console.log("message added successfully", "success");
$(".message-input input").val('');
}
});
}
},
});
I am not sure what I am doing wrong here, still pretty noob at vue js so that might be the problem.
The problem is that it does not display anything. I got it to work with older vue version with a bit different code, but yeah...
var App = Vue.extend({});
var postList = Vue.extend({
template:'#post-list-template',
data: function(){
return {
posts: ''
}
},
mounted: function(){
posts = this.$http.get('/wp-json/wp/v2/posts?per_page=10');
posts.get(function(posts){
this.$set('posts', posts);
})
}
});
var router = new VueRouter({
mode: 'history',
routes: [
{ path: '/', component: postList}
]
});
new Vue({
el: '#app',
router: router,
template: '<router-view></router-view>'
});
HTML is here if that makes things a bit easier to understand :
<div class="container-fluid projects" id="projects">
<h1 class="text-center project-heading">Projects</h1>
<div class="white-wrap">
<div id="app">
<router-view></router-view>
</div>
</div>
<template id="post-list-template">
<div class="container">
<div class="post-list">
<article v-for="post in posts">
<div class="post-content">
<h2>{{ post.title.rendered }}</h2>
{{ post.id }}
</div>
</article>
</div>
</div>
</template>
</div>
This resolved my problem:
var postLists = Vue.component('post-list',{
template:'#post-list-template',
data: function () {
return {
posts:'',
}
},
mounted:function () {
this.$http.get('./wp-json/wp/v2/posts').then(response => {
// get body data
this.posts = response.body;
this.posts.forEach(function (){
} );
}, response => {
console.log('Not Found');
});
}
});
//router
var router = new VueRouter({
routes: [
{ path: '', component: postLists },
]
});
new Vue({
el: '#app',
router: router,
});
I am just getting started with my project using Meteor/React.
In my "Customer.jsx"
Customer = React.createClass({
propTypes: {
//customer: React.PropTypes.object.isRequired
},
getInitialState: function () {
return { customers: [] };
},
mixins: [ReactMeteorData],
deleteThisCustomer(){
Meteor.call("removeCustomer", this.props.customer._id);
},
getMeteorData() {
let query = {};
//query = {checked: {$ne: true}};
return {
customers: Customers.find(query, {sort: {createdAt: -1}}).fetch()
};
},
handleSubmit(event) {
event.preventDefault();
// Find the text field via the React ref
var data = {};
data['first_name']= ReactDOM.findDOMNode(this.refs.customerFirstName).value.trim();
data['last_name'] = ReactDOM.findDOMNode(this.refs.customerFirstName).value.trim();
console.log(data);
Meteor.call("addCustomer", data);
// Clear form
ReactDOM.findDOMNode(this.refs.customerFirstName).value = "";
ReactDOM.findDOMNode(this.refs.customerLastName).value = "";
},
renderCustomers() {
return this.data.customers.map((customer) => {
return <Customer
key={customer._id}
customer={customer.first_name}
/>
});
},
singleCustomer(){
return(
<li className="customerClassName">
<button className="delete" onClick={this.deleteThisCustomer}>
×
</button>
<label>Here{ this.props.customer }</label>
</li>
);
},
render() {
return (
<div className="container">
<header>
<h1>Add new Customer</h1>
<form role="form" className="form-inline" onSubmit={this.handleSubmit} >
<div className="form-group">
<label>First Name</label>
<input type="text" className="form-control" ref="customerFirstName" placeholder="First Name." />
</div>
<div className="form-group">
<label>Last Name</label>
<input type="text" className="form-control" ref="customerLastName" placeholder="Last Name." />
</div>
<button type="submit" className="btn btn-default">Add Customer</button>
</form>
</header>
<ul>
{this.singleCustomer()}
</ul>
</div>
);
}
});
I keep getting an errors of all sorts every time I try to add first_name or last_name. Matter of fact I think that the whole order and structure of my render() is a nightmare.
Any ideas?
Any help would be appreciated.
Thanks in Advance :)