Template tag inside react jsx - meteor

Im playing with meteor and reactjs and I would like to define a Template, inside a component, something like this:
render() {
return (
<div className="container">
<template name="postsList">
<ul>
{this.renderPosts()}
</ul>
</template>
</div>
); }
Meteor can't find it, and nothing gets rendered, can't we use the template tag inside jsx?

Related

see the menu in all views with vue and css

Hello I am trying to implement my menu that I have created with css in all views, for example in my home view I want to invoke it as I saw an example on the web like this:
<template>
<Fragment>
<menu></menu>
<div class="portada">
<menu></menu>
<div id="desarrollofrontend">
Test Menu
</div>
<div class="text">
<h1>Test Menu Home</h1>
<h3>Description home</h3>
</div>
</div>
</Fragment>
</template>
<script>
import menu from '../components/Head/menu.vue'
export default {
components: { menu }
}
</script>
But so far nothing works for me, I'm really new to this
This is my view of my home page, I have my menu created with scss, in the <menu> </menu> tags it is how I saw some examples on the web but it does not work for me
Any recommendations to make it work?

Vue 2.0 Laravel 5.3 array and object passsing via forEach

I have the following child methods
methods:{
selectedPC(selectedProductChoice){
this.$parent.$children.forEach(choice=>{
choice.isActive = (choice.id == selectedProductChoice.id)
})
}
}
and my child template is the following
<template>
<transition name="fade">
<li
class="product-choice"
:class="{'selected': productChoice.isActive}"
#click.prevent="selectedPC(productChoice)"
>
......
......
......
</li>
</transition>
</template>
and here is where the child product-choices is called by the the parent template
<ul class="product-choices" v-show="thumbnailHover">
<product-choices v-for="(productChoice, index) in productChoices" :key="productChoice.id" :product="product" :product-choice="productChoice" :index="index"></product-choices>
</ul>
Not sure why but the choice in the forEach in child template is an object which does not allow me to read choice.id (undefined as I tried to alert it). Is it array object problem? I kind of follow the tabs tutorial from Vue 2 Laracast for you reference.
You have to try child.$data to access the data associated with the child, like following:
methods:{
selectedPC(selectedProductChoice){
this.$parent.$children.forEach(choice=>{
choice.$data.isActive = (choice.$data.id == selectedProductChoice.id)
})
}
}

VueJS component won't render on front end (possibly Drupal issue)

The site I'm currently working on is built in Drupal 7. I have one form that requires user input so I'm attempting to build it with VueJS. The form is contained all within one template file (.tpl.php) and all the content is provided in this template file or via the VueJS Javascript (nothing is coming from the CMS).
The issue I have is that the Vue components are not rendering on the front-end, but when I copy the code into a JSFiddle they do, so I'm guessing it is an issue with the interaction between VueJS and Drupal. Here is a screenshot of my markup when inspecting...
Here is the code from the .tpl.php file...
<div id="app">
<form>
<div>
<label for="year">Per Year</label>
<input type="radio" name="frequency" id="year" value="year" v-model="frequency" checked>
<label for="month">Per Month</label>
<input type="radio" name="frequency" id="month" value="month" v-model="frequency">
</div>
</form>
<ul class="plans">
<template id="plan-component">
<h2 class="plan-name">{{ name }}</h2>
<h2 class="plan-cost">{{ price }}</h2>
<h2 class="plan-tagline">{{ tagline }}</h2>
Choose this plan
</template>
<li>
<plan-component :frequency="frequency"
name="Basic"
tagline="Basic tagline"
price-yearly="Free"
price-monthly="Free"
></plan-component>
</li>
<li>
<plan-component :frequency="frequency"
name="Rec"
tagline="Rec tagline"
price-yearly="3"
price-monthly="4"
></plan-component>
</li>
<li>
<plan-component :frequency="frequency"
name="Team"
tagline="Team tagline"
price-yearly="4"
price-monthly="5"
></plan-component>
</li>
<li>
<plan-component :frequency="frequency"
name="Club"
tagline="Club tagline"
price-yearly="5"
price-monthly="6"
></plan-component>
</li>
</ul>
</div>
..and the code from my JS file...
Vue.component('plan-component', {
template: '#plan-component',
props: ['frequency', 'name', 'tagline', 'priceYearly', 'priceMonthly'],
computed: {
'price': function() {
if (this.frequency === 'year') {
return this.priceYearly;
} else {
return this.priceMonthly;
}
}
},
methods: {
makeActivePlan() {
// We dispatch an event setting this to become the active plan
this.$dispatch('set-active-plan', this);
}
}
});
new Vue({
el: '#app',
data: {
frequency: 'year',
activePlan: {name: 'no', price: 'You must select a plan!' }
},
events: {
'set-active-plan': function(plan) {
this.activePlan = plan;
}
},
});
And here is the JSFiddle which outputs the components correctly - https://jsfiddle.net/2xgrpLm6/
What browser are you using? <template> tags are not supported in IE.
Another idea is to make sure you are never using fragment components (meaning wrap everything inside your template with a div like so:
<template id="foobar">
<div>
CONTENT HERE
</div>
</template>
Lastly, have you turned on Vue debug mode? Before you instantiate your Vue instance, set Vue.config.debug = true and see if you get console errors then.
Try moving the <template id="plan-component">...</template> code outside of the Vue instance. I.e., such that it is not contained within <div id="app">...</div>.
This has solved a similar problem for me in the past, though I'm not sure if it applies here.
For anyone having a similar issue, the solution was simple. After Jeff suggested turning on Vue debug mode (and downloading the Dev version of Vue JS instead of minified - https://vuejs.org/guide/installation.html) the console gave the error [Vue warn]: Cannot find element: #app.
The issue was that Drupal was loading my scripts in the <head>, before <div id="app"> was loaded in the DOM. As such #app couldn't be found. After outputting the scripts before the closing <body> tag all was sorted. See here for more information [Vue warn]: Cannot find element

Meteor, Flow Router, and React: How to get FlowRouter.subsReady() function to be reactive in render

I am trying to create a pattern so that all the subscriptions are ready before I load the main page. Similar to Iron Router waitOn.
Take a look at this react component:
export const PageContainer = React.createClass({
render() {
return (
<div id="content-box">
<div className="banner banner-primary">
<div className="page_title pull-left">
{this.props.pageName}
</div>
</div>
<div>
{ FlowRouter.subsReady() ? this.props.page : (
<div> Loading .... </div>
)
}
</div>
</div>
);
}
});
as you can see I am using the FlowRouter.subsReady() helper to render the page or the loading text.
The problem is that this is not reactive. It just renders once but does not update and show the page once the subscription is ready.
How can I get this to be reactive?
What is the best way to use Flow Router's subscription management with React. I have a base layout and want to show loading sign before loading the page main. If I could get this function to be reactive it should work just fine.
UPDATE:
It seems like I have to attach the helper, FlowRouter.subsReady() to the get Meteor data function
export const PageContainer = React.createClass({
mixins: [ ReactMeteorData ],
getMeteorData() {
return {
isLoading: FlowRouter.subsReady()
}
},
render() {
return (
<div id="content-box">
<div className="banner banner-primary">
<div className="page_title pull-left">
{this.props.pageName}
</div>
<i className="fa fa-question-circle help-icon pull-right"></i>
</div>
<div>
{ this.data.isLoading ? this.props.page : (
<div> Loading ... </div>
)
}
</div>
</div>
);
}
});
It seems to be working now. Is this the way to do it?
You accessed the problem in the wrong direction. You don't really need to check the subsReady of FlowRouter when using meteor with react. Just install the mixin ReactMeteorData and set the this.data properly, it will reactively render the Dom. More details here
React render is not reactive. The Dom is only re-rendered when the props or state of the component is changed

FullpageJs and Meteor : Capture event from template

I'm struggling with fullpage.js in Meteor.
When I add a button inside a template, the Template.templatename.events function does not fire on event.
For example:
Template HTML (messages.html)
<template name="messages">
<ul>
{{#each mess}}
<li>{{ messContent}}</li>
{{/each}}
<button class="addMessage">Add Message!</button>
</ul>
</template>
Template JavaScript (messages.js)
Template.messages.helpers({
mess: function(){
return Messages.find();
}
});
Template.messages.events({
'click .addMessage' : function(event){
console.log("clicked")
}
})
Main HTML
<head>
<title>fulltest</title>
</head>
<body>
{{> full}}
</body>
<template name="full">
<div id="fullpage">
<div class="section active">
<h1>First slide</h1>
{{> messages}}
</div>
<div class="section">
<h1>Second slide</h1>
</div>
</div>
</template>
My fullpage initialisation:
Template.full.rendered = function(){
$('#fullpage').fullpage();
}
If I remove the fullpage initialisation then the click event gets logged. Still new at Meteor, I didn't manage to grasp what's going wrong here.
All help much appreciated,
Joris
Use delegation or use verticalCentered:false and scrollOverflow:false.
From the fullPage.js FAQs:
My javascript/jQuery events don't work anymore when using fullPage.js
Short answer: if you are using options such as verticalCentered:true or overflowScroll:true in fullPage.js initialization, then you will have to treat your selectors as dynamic elements and use delegation. (by using things such as on from jQuery). Another option is to add your code in the afterRender callback of fullpage.js
Explanation: if you are using options such as verticalCentered:true or overflowScroll:true of fullPage.js, your content will be wrapped inside other elements changing its position in the DOM structure of the site. This way, your content would be consider as "dynamically added content" and most plugins need the content to be originally on the site to perform their tasks. Using the afterRender callback to initialize your plugins, fullPage.js makes sure to initialize them only when fullPage.js has stopped changing the DOM structure of the site.

Resources