vue-router v-link in v-for use data - javascript

I use vue make single page , I want each grid item`s v-link path diffrent.
Now it's like this:
<div v-link="'/detail/' + 'work'" class="itemImg">
I want like this:
<div v-link="'/detail/' + data.title " class="itemImg">
the v-link`s data.title can not find, but data.title in v-for other pace work fine.
her is my code
var png = ".png"
var jpg = ".jpg"
var HtmlFormat = ".html"
// WORK
var db = new loki('workDB.json');
var workCol = db.addCollection('workCol');
var workNames = ["x50", "glmg", "ring", "iwatch", "moto", "edge", "i8", "nike", "shave", "house"];
var workWebglFolder = "assets/webgl/";
var workHtmlFolder = "pages/work/";
var workImgFolder = "img/workImg/";
var workImgkUrls = [];
var workHtmlUrls = [];
var workTitles = [];
var workSummary = [];
$.each(workNames, function(index, title) {
var workWebglUrl = workWebglFolder + title;
var workHtmlUrl = workHtmlFolder + title + HtmlFormat;
var workimgkUrl = workImgFolder + title + png;
var workOBJ = {};
workOBJ.id = index;
workOBJ.useClass = title;
workOBJ.title = title;
workOBJ.link3d = workWebglUrl;
workOBJ.link = workHtmlUrl;
workOBJ.image = workimgkUrl;
workCol.insert(workOBJ);
var useClass = "." + title;
workHtmlUrls.push(workHtmlUrl);
workImgkUrls.push(workimgkUrl);
$.ajax({
url: workHtmlUrl,
async: false,
success: function(data) {
title = $(data).filter('title').text();
summary = $(data).filter(useClass).text();
workOBJ.title = title;
workOBJ.summary = summary;
}
});
})
// BLOG
var db = new loki('blogDB.json');
var blogCol = db.addCollection('blogCol');
var blogNames = ["waveLoader", "playcanvas-introduce", "lokiJS", ];
var blogHtmlFolder = "pages/blog/";
var blogImgFolder = "img/blogImg/";
var blogImgkUrls = [];
var blogHtmlUrls = [];
var blogTitles = [];
var blogSummary = [];
$.each(blogNames, function(index, title) {
var blogHtmlUrl = blogHtmlFolder + title + HtmlFormat;
var blogimgkUrl = blogImgFolder + title + jpg;
BJ.useClass = title;
blogOBJ.title = title;
blogOBJ.link = blogHtmlUrl;
blogOBJ.image = blogimgkUrl;
blogCol.insert(blogOBJ);
var useClass = "." + title;
blogHtmlUrls.push(blogHtmlUrl);
blogImgkUrls.push(blogimgkUrl);
$.ajax({
url: blogHtmlUrl,
async: false,
success: function(data) {
title = $(data).filter('title').text();
summary = $(data).find('.summary').text().substring(0,200) + "...";
blogOBJ.title = title;
blogOBJ.summary = summary;
}
});
})
// db.saveDatabase(function () {
// console.log("save db")
// });
var workdv = workCol.addDynamicView('workCol_view');
workdv.applyWhere(function customFilter(obj){
return obj.id > -1;
});
workdv.applySimpleSort('id')
var blogdv = blogCol.addDynamicView('blogCol_view');
blogdv.applyWhere(function customFilter(obj){
return obj.id > -1;
});
blogdv.applySimpleSort('id')
//USE VUE GET LOKIJS DATA
var lookVue = new Vue({
el: '.pages',
data: {
work: workdv.data(),
blog: blogdv.data()
},
});
console.log(lookVue.work[0].title)
var notFound = Vue.extend({
template: '<h1>Not Found</h1>' +
'<router-view></router-view>'
})
var workComponent = Vue.extend({
template:
'<h1>Work</h1>' +
'<router-view></router-view>'
})
var blogComponent = Vue.extend({
template:
'<h1>Blog</h1>' +
'<router-view></router-view>'
})
var aboutComponent = Vue.extend({
template:
'<h1> aboutComponent </h1>' +
'<a v-link="{ path: \'/subroute\' }" class="btn btn-lg btn-primary" role="button">View SubRoute</a>' +
'<router-view></router-view>'
})
var contactComponent = Vue.extend({
template:
'<h1> 联系 </h1>' +
'<router-view></router-view>'
})
var detail = Vue.extend({
template:
'<h1>Navbar example</h1>' +
'<p>This example is a quick exercise to illustrate how the default, static and fixed to top navbar work. It includes the responsive CSS and HTML, so it also adapts to your viewport and device.</p>' +
'<p>To see the difference between static and fixed top navbars, just scroll.</p>'
})
Vue.config.debug = true;
Vue.use(VueRouter)
var router = new VueRouter({
history: false,
hashbang:true,
// saveScrollPosition:true,
root: '/'
})
Vue.component('newtemp', {
template: '#workVUE',
route: {
data: function(transition) {
transition.next({
// saving the id which is passed in url to $data
itemName: transition.to.params.itemName
});
}
},
data: function() {
return {
itemName:itemName,
}
},
})
router.map({
// '*': {
// component: notFound
// },
'/': {
component: workComponent,
subRoutes: {
'/detail': {
component: detail
}
}
},
'/work': {
component: workComponent,
subRoutes: {
'/detail': {
component: detail
}
}
},
'/blog': {
component: blogComponent,
subRoutes: {
'/detail': {
component: detail
}
}
},
'/about': {
component: aboutComponent,
subRoutes: {
'/detail': {
component: detail
}
}
},
'/contact': {
component: contactComponent
},
'/detail/:itemName': {
name: 'detail', // 给这条路径加上一个名字
component: Vue.component('newtemp')
},
});
var App = Vue.extend()
router.start(App, 'body')
<template v-for="data in work" id="workVUE">
<div class="item scrollItem">
<div v-link="'/detail/' + 'work'" class="itemImg">
<div class="gridImg workImg">
<img v-bind:src="data.image" />
</div>
</div>
<div class="itemTitle">
<h3>{{data.title}}</h3>
</div>
<div class="itemTag">
<div class="tagTitle">
<ul class="tagName">
<li class="tagTip"><h3> 标签: </h3> </li>
<li><h3 class="pageName"> {{data.useClass}} </h3> </li>
<li><h3> {{data.tag}} </h3> </li>
</ul>
<div class="titlePos"> <h3>titlePos</h3> </div>
</div>
</div>
<ul class="info">
<li class="infoItem infoTitle">
<h3>{{data.title}}</h3>
</li>
<li class="infoItem infoCont">
<h3>{{data.date}}</h3>
<h3>作者:laishi</h3>
</li>
</ul>
<ul class="bar">
<li class="barItem barMark">
<div> <i class="fa fa-bookmark" aria-hidden="true"></i> </div>
</li>
<li class="barItem">
<dir> <a class="moreLink" v-bind:href="data.link3d"> <h3> 3D </h3> </a> </dir>
</li>
<li class="barItem barInfo">
<div>
<i class="fa fa-info"></i>
</div>
</li>
</ul>
</div>{{ }}
</template>
Due to the lack of knowledge of the route, the results are often not the same as I think, so please help.
plz fix my code ,thanks+++

With Vue2 you can use in combination with attribute binding (:to)
<li v-for="project in projects">
<router-link :to="'/project/' + project.id">{{project.name}}</router-link>
</li>

Related

How to get methods inside vue, the methods is googlemap api?

I have some google maps api that i've already craeted in javascript, but, for some time my collagues decided to use vue framework on the apps.
I tried to put my initMap of my googlemaps javascript inside vue methods and trye to call it on windows.initmap outside vue app, but it doesn't work,
here are my javascript code bellow
let base_url = '{{ envx('APP_BASE_URL') }}';
let cdn = '{{ envx('CDN_ENDPOINT') }}';
let endpoint = '{{ envx('API_ENDPOINT') }}';
addEventListener('load', () => {
const {
createApp
} = Vue;
const initialState = () => {
return {
containerClass: 'container-grid',
loading: false,
properties: <?= json_encode($list_properti) ?>,
filter: {
page: 1,
limit: 12,
keyword: '',
harga: '',
status_unit: '',
jenis: '',
id_propinsi: '',
}
}
}
const app = createApp({
data() {
return initialState()
},
methods: {
checkData() {
console.log(this.properties.DATA);
},
getPropertiImage(imageUrl) {
const urlOnly = `{{ file_exists('${imageUrl}') }}`
if (urlOnly) return base_url + 'assets/img/no-data.png'
if (imageUrl === null) return base_url + 'assets/img/no-data.png'
const checkImage = imageUrl.split("")
const getFlag = [checkImage[0], checkImage[1]].join("")
if (getFlag !== '1|') return base_url + 'assets/img/no-data.png'
return imageUrl.replace('1|', cdn + '?key=')
},
setToBillions(item) {
let price = item;
let idrPrices = `{{ rupiah((float) '${price}') }}`;
let prices = idrPrices.split('.');
if (prices.length > 3) {
return [prices[0], prices[1]].join('.') + " Juta";
}
return idrPrices;
},
cicilan(val) {
let cicilan = (val / 1000000).toFixed(1);
if (cicilan < 1) {
return 'Rp.' + (cicilan * 1000).toLocaleString('id-ID') + 'rb/bln';
}
return 'Rp.' + cicilan.toLocaleString('id-ID') + 'jt/bln';
},
getAvatar(url) {
if (url) {
let explodeAva = url.split('|member');
if (explodeAva.length == 2) {
return cdn + '?key=member' + explodeAva[1];
}
return url;
}
return base_url + 'assets/img/avatar/1552FBA78C75D6FBA33F.png';
},
changePage(id) {
if (this.loading) {
return false;
}
document.getElementById('container-loading').scrollIntoView({
behavior: 'auto',
block: 'start',
inline: 'nearest'
});
this.filter.page = id;
this.updateContent()
this.initMap()
},
async initMap() {
const centerPosition = {
lat: -1.6160679698214473,
lng: 117.38277669882174
}
let map = new google.maps.Map(document.getElementById("container-map"), {
center: centerPosition,
zoom: 5,
});
const areaProperties = []
for (const properti of this.properties.DATA) {
const exampleUrl = `{{ envx('CDN_ENDPOINT') }}?key=`;
let imageUrl = properti.GBR1;
imageUrl = imageUrl.replace('1|', exampleUrl);
const urlAvatar = ``
let imageMember = properti.AVATAR_MEMBER;
const imageAvatar = imageMember.replace('1|', imageMember);
const propertiAreas = {
position: new google.maps.LatLng(properti.LATITUDE, properti.LONGITUDE),
content: ` <template v-if="!loading" v-for="(properti, index) in properties.DATA">
<div class="card card-container card-shadow card--radius mb-2">
<div class="img-container">
<div class="img-top">
<div class="badge-report bg-colors-blue" v-html="properti.JENIS_PROPERTI"></div>
</div>
<img class="card-img-top img-card" v-bind:src="'' + getPropertiImage(properti.GBR1)"
alt="''+ properti.NAMA">
</div>
<div class="card--body m-4">
<small class="d-flex gap-2 align-items-center text-dim">
<img src="assets/img/shape/location.png" class="icon-location" height="12">
<div style="width: 100%; text-overflow: ellipsis;
overflow: hidden;
white-space: nowrap; "
v-html="properti.ALAMAT"></div>
</small>
<h4 v-html="properti.NAMA"></h4>
<small class="text-dim">Mulai dari</small>
<h3 v-html="'Rp. '+ setToBillions(properti.HARGA)"></h3>
<small class="text-dim d-block">Cicilan dari <b class="text-black"
style="font-family: 'Futura'" v-html="cicilan(properti.CICILAN)"></b></small>
<small class="text-dim d-block">Suku Bunga <b class="text-black"
style="font-family: 'Futura'" v-html="'Dari '+ properti.BUNGA + '%'"></b></small>
<small class="d-flex gap-2 align-items-center mt-2"
style="font-size: 12px; color: var(--c-blue); font-family: 'FuturaMD';">
<img src="'' + getAvatar(properti.AVATAR_MEMBER)" height="25" class="rounded-circle">
<div v-html="properti.NAMA_AGEN"></div>
</small>
</div>
<div class="card-label--foot bandingkan-button" role="button" #onclick="handleCompare()">
Bandingkan
</div>
</div>
</template>
`
}
areaProperties.push(propertiAreas)
}
var infowindow = new google.maps.InfoWindow();
const icon = {
url: 'data:image/svg+xml;charset=UTF-8,' + encodeURIComponent(
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 512"><!--! Font Awesome Pro 6.2.1 by #fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path d="M36.8 192H603.2c20.3 0 36.8-16.5 36.8-36.8c0-7.3-2.2-14.4-6.2-20.4L558.2 21.4C549.3 8 534.4 0 518.3 0H121.7c-16 0-31 8-39.9 21.4L6.2 134.7c-4 6.1-6.2 13.2-6.2 20.4C0 175.5 16.5 192 36.8 192zM64 224V384v80c0 26.5 21.5 48 48 48H336c26.5 0 48-21.5 48-48V384 224H320V384H128V224H64zm448 0V480c0 17.7 14.3 32 32 32s32-14.3 32-32V224H512z"/></svg>'
),
scaledSize: new google.maps.Size(20, 20)
}
let marker, i;
for (i = 0; i < areaProperties.length; i++) {
marker = new google.maps.Marker({
position: areaProperties[i].position,
icon: icon,
map: map,
});
google.maps.event.addListener(marker, 'click', (function(marker, i) {
return function() {
infowindow.setContent(areaProperties[i].content);
infowindow.open(map, marker);
}
})(marker, i));
}
},
// async updateContent() {
async updateContent() {
this.loading = true;
this.containerClass = 'w-full'
const filterData = this.filter;
const filterStrings = []
const lastKey = Object.keys(filterData).pop();
for (const key in filterData) {
if (filterData[key] !== "" || filterData[key] !== null) {
filterStrings.push(key)
filterStrings.push('=')
filterStrings.push(filterData[key])
if (key !== lastKey) {
filterStrings.push('&')
}
}
}
//FIXME string zero values
const params = filterStrings.join('')
await $.ajax({
type: 'get',
dataType: 'json',
url: base_url + 'api/properti/list-properti?' + params,
success: res => {
this.properties = res;
}
})
this.loading = false;
this.containerClass = 'container-grid'
}
}
}).mount('#app')
window.initMap = app.initMap();
})
And here is the error that i got
How could i solve this?
You shouldn't call window.initMap = app.initMap(); after creating the Vue instance but rather in the mounted lifecycle hook:
mounted() {
window.initMap = app.initMap();
}

Cannot use v-for on stateful component root element because it renders multiple elements

postman.response.txt
https://gist.github.com/stanislavgr79/e82999e5ae69876f0316280687388a25
var app = new Vue({
el: "#app3",
data: {
path: "",
sortEvent: "",
eventsValue: [],
},
methods: {
getResponse(){
this.requestByParam(this.sortEvent);
},
requestByParam: function (byParam) {
this.$http
.get(this.path, {
params: { sortEvent: this.sortEvent },
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
})
.then((response) =>
response.json().then((data) => {
let listResultQuery = [];
if (data.length == 0) {
return;
}
// data.forEach((element) => {
// listResultQuery.push(element);
// dont work
});
this.eventsValue = data;
this.emptyMessage = "";
})
);
},
},
});
<div id="app3">
<events_nav path=${resource.path}></events_nav>
<all_events id="all-events" :eventsValue="eventsValue"></all_events>
</div>
i try reformat:
$.ajax({
type: method_event,
url: path_event + '.sort.json',
data: params,
contentType: 'application/json',
success: function (response, status, request) {
if (status == 'success') {
var output = "";
$.each(response, function (key, value) {
output += "<div class='span3'>";
output += "<h3>" + key + "<i class='events__" + key + "'></i></h3>";
$(value).each(function (index, el) {
output += "<ul class='icons icons_type'><i class='icon-" + el.topic + "'></i>";
output += "<li class='events_type'>";
output += "<span class='date' type='date'>" + formatDate(el.eventStartDate) + "</span>";
output += "<h4><a href='"+el.titleLink+"' rel='"+el.typeOfOpen+"'>" + el.title + "</a></h4>";
output += el.description;
output += "</li></ul>";
});
output += "</div>";
$('#all-events').html(output);
});
}
}
})
}
now i have error :
Vue.component("all_events", {
props: {
eventsValue: Array,
},
template:
'<div class="span3" v-for="(value, name) in eventList">' +
'<h3>{{ name }}<i class="events__{{ name }}"></i></h3>' +
'</div>',
});
eventsValue - its Object ????? its Array ???????
what i need to write tempalate to see key
$.each(response, function (key, value) {
output += "<div class='span3'>";
output += "<h3>" + key + "<i class='events__" + key + "'></i></h3>";
this method dont work:
<ul id="example-1">
<li v-for="item in items" :key="item.message">
{{ item.message }}
</li>
</ul>
and this dont work:
<ul id="example-2">
<li v-for="(item, index) in items">
{{ parentMessage }} - {{ index }} - {{ item.message }}
</li>
</ul>
and this dont work:
<ul id="v-for-object" class="demo">
<li v-for="value in object">
{{ value }}
</li>
</ul>
and this dont work:
<div v-for="(value, name) in object">
{{ name }}: {{ value }}
</div>
and this dont work:
<div v-for="(value, name, index) in object">
{{ index }}. {{ name }}: {{ value }}
</div>
For the error "Cannot use v-for on stateful component root element because it renders multiple elements"
You just need to wrap the template in another dom element
example:
Vue.component("all_events", {
props: {
eventsValue: Array,
},
template:`
<div>
<div class="span3" v-for="(value, name) in eventList">
<h3>{{ name }}<i class="events__{{ name }}"></i></h3>
</div>
</div>
`});
try that with the code before you reformatted.
this code works. thanks community and Daniel
Vue.component("events_nav", {
props: {
dataPath: String,
},
data() {
return {
sortEvent: "topic",
topic: true,
type: false
};
},
methods: {
requestTopic: function () {
this.sortEvent = "topic";
this.$root.sortEvent = this.sortEvent;
this.topic = true;
this.type = false;
this.$root.getResponse();
},
requestType: function () {
this.sortEvent = "type";
this.$root.sortEvent = this.sortEvent;
this.topic = false;
this.type = true;
this.$root.getResponse();
},
},
created: function () {
let servletSelector = ".sort";
let servletExtension = ".json";
this.$root.dataPath = this.dataPath.concat(
servletSelector,
servletExtension
);
this.$root.sortEvent = this.sortEvent;
this.$root.getResponse();
},
template:
'<div class="navbar events_nav">' +
'<div class="navbar-inner">' +
'<span class="brand">View By:</span>' +
'<ul class="nav" id="event_sort" data-sort="topic" data-method="GET" :data-path="dataPath">' +
'<li :class="{active: topic}" id="events__view-topic"><span #click="requestTopic">Topic</span></li>' +
'<li :class="{active: type}" id="events__view-type"><span #click="requestType">Type</span></li>' +
'</ul>' +
'</div>' +
'</div>',
});
Vue.component("all-events", {
props: {
eventsValue: "",
},
template:
'<div class="row event-listing">' +
'<div class="span3" v-for="(value, name) in eventsValue">' +
'<h3>{{ name }}<event-icon :icon="name"></event-icon></h3>' +
'<event-column :value="value"></event-column>' +
'</div>' +
'</div>',
});
Vue.component("event-icon", {
props: {
icon: String,
},
computed: {
classIcon: function () {
let icon = '';
if (this.$props.icon == 'Database') {
icon = 'icon-hdd'
}
if (this.$props.icon == 'Cloud') {
icon = 'icon-cloud'
}
if (this.$props.icon == 'Mobile') {
icon = 'icon-mobile-phone'
}
if (this.$props.icon == 'Other Topics') {
icon = 'icon-calendar'
}
return icon;
}
},
template:
'<i :class="classIcon"></i>',
});
Vue.component("event-column", {
props: {
value: Array,
},
template:
'<ul class="unstyled" >' +
'<li class="event-list" v-for="item in this.$props.value">' +
'<element-event :element="item"></element-event>' +
'</li>' +
'</ul>',
});
Vue.component("element-event", {
props: {
element: Object,
},
data() {
return {
description: "",
eventdate: ""
};
},
computed: {
classIcon: function () {
let icon = '';
if (this.$props.element.topic == 'Database') {
icon = 'icon-hdd'
}
if (this.$props.element.topic == 'Cloud') {
icon = 'icon-cloud'
}
if (this.$props.element.topic == 'Mobile') {
icon = 'icon-mobile-phone'
}
if (this.$props.element.topic == 'Other Topics') {
icon = 'icon-calendar'
}
return icon;
},
selectTopic: function () {
let result = false;
if (this.$root.sortEvent == "type") {
result = true;
}
return result;
}
},
methods: {
formatDate() {
return new Date(this.$props.element.eventStartDate).toLocaleString('en-US', {
day: '2-digit',
month: 'long'
});
},
},
template:
'<div>' +
'<i v-if="selectTopic" class="icon" v-bind:class="classIcon"></i>' +
'<span class="date" type="date" v-html="formatDate()"></span>' +
'<h4><a :href="element.titleLink" :rel="element.typeOfOpen" v-html="element.title"></a></h4>' +
'<p class="event-description" v-html="element.description"></p>' +
'</div>',
})
var app = new Vue({
el: "#eventviewer-v2",
data: {
dataPath: "",
sortEvent: "",
events: "",
},
methods: {
getResponse() {
this.requestByParam(this.sortEvent);
},
requestByParam: function (byParam) {
this.$http
.get(this.dataPath, {
params: { sortEvent: this.sortEvent },
headers: {
"Content-Type": "application/json",
Accept: "application/json",
},
})
.then((response) =>
response.json().then((data) => {
this.events = data;
this.emptyMessage = "";
})
);
},
},
});
To remove wrap element...
mounted () {
this.$el.replaceWith(...this.$el.childNodes)
}

Link div and textbox value on div selection

I am trying to sync div with textbox.
For example, I created 2 nodes i.e Node 1 and Node 2 and when I select node1 and I enter title and location then title and location should sync with Node1 so when I enter title while I have selected node1 then title value should get reflected for node1 and after entering title and location next time when I select node1 then title and location value should be reflected in my textbox.
I created this below Fiddle to demonstrate the problem : http://jsfiddle.net/quk6wtLx/2/
$scope.add = function (data) {
var post = data.nodes.length + 1;
var newName = data.name + '-' + post;
data.nodes.push({ name: newName, nodes: [],selected : false });
};
$scope.tree = [{ name: "Node", nodes: [], selected: false }];
$scope.setActive = function (data) {
clearDivSelection($scope.tree);
console.log(data);
data.selected = true;
};
I am not getting how to do this.
You need to bind the form elements with the data you are appending to the tree.
Check this snippet
var app = angular.module("myApp", []);
app.controller("TreeController", function ($scope) {
$scope.delete = function (data) {
data.nodes = [];
};
$scope.add = function (data) {
var post = data.nodes.length + 1;
var newName = data.name + '-' + post;
data.nodes.push({ name: newName, nodes: [],selected : false, myObj: { name: newName} });
};
$scope.tree = [{ name: "Node", nodes: [], selected: false }];
$scope.setActive = function ($event, data) {
$event.stopPropagation();
$scope.selectedData = data;
clearDivSelection($scope.tree);
data.selected = true;
};
function clearDivSelection(items) {
items.forEach(function (item) {
item.selected = false;
if (item.nodes) {
clearDivSelection(item.nodes);
}
});
}
});
ul {
list-style: circle;
}
li {
margin-left: 20px;
}
.active { background-color: #ccffcc;}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<ul ng-app="myApp" ng-controller="TreeController">
<li ng-repeat="data in tree" ng-include="'tree_item_renderer.html'"></li>
<script type="text/ng-template" id="tree_item_renderer.html">
<div ng-class="{'active': data.selected}" > {{data.myObj.name}}</div>
<button ng-click="add(data)">Add node</button>
<button ng-click="delete(data)" ng-show="data.nodes.length > 0">Delete nodes</button>
<ul>
<li ng-repeat="data in data.nodes" ng-include="'tree_item_renderer.html'" ng-click="setActive($event, data)"></li>
</ul>
</script>
<div style="margin-left:100px;">
Title : <input type="text" ng-model="selectedData.myObj.name" />
Location : <input type="text" ng-model="selectedData.myObj.location" />
</div>
</ul>
You can check the binding documentation for AngularJs and all the possibilities https://docs.angularjs.org/guide/databinding

How dynamically enable data- tag using JS, Telerik and Kendo UI?

I am using App Builder from Telerik with Kendo UI trying to build a SPA application. I am very new to using Telerik and Kendo UI, please forgive the code.
There are two things I am trying to accomplish.
Enable swipe to open and hide the login head image until the user is logged in.
When a user is logged out return to the login screen and disable swipe to open and hide the login header image.
I have tried adding: data-swipe-to-open="false" in the layout, using the .hide on the header in the layout. When I use data-swipe-to-open="false" the #appDrawer does not open (which is what I want) but I cannot set the data-swipe-to-open = true. I cannot find any documentation from Telerik.
Any and all feedback is appreciated.
Login screen as of now
Swipe on login
HTML
<!--Login View-->
<div id="tabstrip-login"
data-role="view"
data-title="Login"
data-model="app.loginService.viewModel"
data-before-show="app.loginService.beforeShow"
data-after-show="app.loginService.afterShow">
<div style="background-image:url(/xxxx.png); background-position:top; background-repeat:no-repeat; background-size:contain; background-color:white;">
<div style="min-width:325px; min-height:144px;"></div>
</div>
<div data-bind="visible: isLoggedIn">
<div data-bind="visible : isExpired">
Expired Card info
</div>
<div id="dvCardInfoContainer" class="panel panel-default " style="background-color:white;" data-bind="invisible : isExpired">
<div class="panel panel-body" style="background-image:url(img/xyx.png); background-size:cover; background-position:center; background-color:white; ">
<div style="display:flex; flex-flow: row nowrap; align-content:center; justify-content:center; align-items:center;">
<div class="dvVerticalTextContainerLeftSide"><div id="memberStatusTop" data-bind="text :memberStatus" class="dvVerticalTextLeftSide capText bold"></div></div>
<div class="dvCenterVerticalContainer">
<ul>
<li data-bind="text :attCompanyName"></li>
<li data-bind="text :attAircraftTypes"></li>
<li data-bind="text :attAircraftRegNum"></li>
<li class="bold" data-bind="text :attExpirationDate"></li>
<li data-bind="text :calcDateTillExp"></li>
</ul>
</div>
<div class="dvVerticalContainerRightSide"><div class="dvVerticalTextRightSide capText bold" data-bind="text :memberStatus" id="memberStatusBottom"></div></div>
</div>
<div id="goodStanding" class="text-center capText bold"> TEXT </div>
</div>
</div>
</div>
<form data-bind="events: { keyup: checkEnter }">
<ul data-role="listview" data-style="inset" data-bind="invisible: isLoggedIn">
<li>
<label>
<div>Username</div>
<input type="text" data-bind="value: username" />
</label>
</li>
<li>
<label>
<div>Password</div>
<input type="password" data-bind="value: password" />
</label>
</li>
</ul>
<input id="login" type="submit" data-role="button" data-bind="click: onLogin, invisible: isLoggedIn" value="Login" class="login-button" />
</form>
</div>
Layout
<div data-role="layout" data-id="tabstrip-layout">
<header id="hdr" data-role="header">
<div data-role="navbar" >
<span data-role="view-title"></span>
<a data-role="button" href="#appDrawer" data-rel="drawer" data-align="left" data-icon="details"></a>
</div>
</header>
<!-- application views will be rendered here -->
</div>
<div id="appDrawer" data-role="drawer" data-title="Navigation">
<header data-role="header">
<div data-role="navbar">
<span data-role="view-title"></span>
</div>
</header>
<ul id="navigation-container" data-role="listview">
<li>Membership Card</li>
<li>Card Info</li>
<li><a onclick="app.clearLocalStorage();">Log Out</a> </li>
</ul>
</div>
app.js
(function (global) {
var app = global.app = global.app || {};
app.clearLocalStorage = function () {
localStorage.clear();
app.loginService.viewModel.set("isLoggedIn", false);
}
app.makeUrlAbsolute = function (url) {
var anchorEl = document.createElement("a");
anchorEl.href = url;
return anchorEl.href;
};
document.addEventListener("deviceready", function () {
navigator.splashscreen.hide();
app.changeSkin = function (e) {
var mobileSkin = "";
if (e.sender.element.text() === "Flat") {
e.sender.element.text("Native");
mobileSkin = "flat";
} else {
e.sender.element.text("Flat");
mobileSkin = "";
}
app.application.skin(mobileSkin);
};
var element = document.getElementById('appDrawer');
if (typeof (element) != 'undefined' && element !== null) {
if (window.navigator.msPointerEnabled) {
$('#navigation-container').on('MSPointerDown', 'a', function (event) {
app.keepActiveState($(this));
});
} else {
$('#navigation-container').on('touchstart', 'a', function (event) {
app.keepActiveState($(this));
});
}
}
app.application = new kendo.mobile.Application(document.body, { layout: "tabstrip-layout", skin: 'nova'});
//$("#hdr").hide();
// app.loginService.viewModel.set("isLoggedIn", true);
}, false);
app.removeActiveStatus = function _removeActiveState(item) {
var currentItem = item;
$('#navigation-container li a.active').removeClass('active');
currentItem.addClass('notActive');
}
app.keepActiveState = function _keepActiveState(item) {
var currentItem = item;
$('#navigation-container li a.active').removeClass('active');
currentItem.addClass('active');
};
app.isOnline = function () {
if (!navigator || !navigator.connection) {
return true;
} else {
return navigator.connection.type !== 'none';
}
};
})(window);
Login.js
function loadState() {
var cardData = localStorage.getItem("userAttributeList");
if (cardData) {
var obj = JSON.parse(localStorage.getItem("userAttributeList"));
var companyName = obj[0].attData;
var airCraftTypes = obj[23].attData;
var airCraftRegNum = obj[24].attData;
var memberType = obj[1].attData;
var x = obj[17].attData;//experation date
var daysTillExpire = app.loginService.viewModel.calcDate(x);
var expirationDate = app.loginService.viewModel.formatDate(x);
app.loginService.viewModel.set("attCompanyName", companyName);
app.loginService.viewModel.set("attAircraftTypes", airCraftTypes);
app.loginService.viewModel.set("attAircraftRegNum", airCraftRegNum);
app.loginService.viewModel.set("attExpirationDate", "Expires: " + expirationDate);
app.loginService.viewModel.set("calcDateTillExp", "Days to expiration: " + daysTillExpire);
var strMembershipDecision = "Paid Members";
if (strMembershipDecision == memberType) {
app.loginService.viewModel.set("memberStatus", "Prefered Member");
}
else { app.loginService.viewModel.set("memberStatus", "Trial Member"); }
if (daysTillExpire <= 0) {
app.loginService.viewModel.wipeout();
}
//app.loginService.viewModel.set("data-swipe-to-open", true);
$("#appDrawer").data("kendoMobileDrawer");
}
else { }
}
(function (global) {
var LoginViewModel,
app = global.app = global.app || {};
// default empty credentials
// configure the local-storage adapter
LoginViewModel = kendo.data.ObservableObject.extend({
userDataSoruce: null,
isLoggedIn: false,
isExpired: false,
showExpired: false,
username: "",
password: "",
authUrl: '',
userUrl: '',
groupUrl: '',
token: null,
groupId: "",
orgId: "",
userId: "",
cardData: null,
airCraftTypes: null,
expirationDate: null,
memberGroupStatus: null,
memberType: null,
airCraftRegNum: null,
companyName: null,
daysTillExpire: null,
onLogin: function () {
var that = this,
username = that.get("username").trim(),
password = that.get("password").trim();
if (username === "" || password === "") {
navigator.notification.alert("Both fields are required!",
function () { }, "Login failed", 'OK');
return;
}
this.getAuthToken();
},
onLogout: function () {
var that = this;
that.clearForm();
that.set("isLoggedIn", false);
},
clearForm: function () {
var that = this;
that.set("username", "");
that.set("password", "");
},
checkEnter: function (e) {
var that = this;
if (e.keyCode == 13) {
$(e.target).blur();
that.onLogin();
}
},
checkAuth: function (response) {
var that = this;
if (response) {
that.getCardInfo();
}
else { alert('Not success'); }
},
getAuthToken: function () {
var that = this, dataSource;
var response = false;
dataSource = new jQuery.ajax({
type: "POST",
url: that.authUrl,
contentType: "application/json; charset=utf-8",
dataType: "json",
data: 'apiKey=' + '&username=' + that.username + '&password=' + that.password,
username: that.username,
password: that.password,
success: function (data, status) {
that.token = data.token;
that.groupId = data.groupId;
that.orgId = data.orgId;
that.userId = data.userId;
response = true;
that.checkAuth(response);
localStorage.setItem("usertoken", data.token);
localStorage.setItem("username", that.username);
localStorage.setItem("password", that.password);
localStorage.setItem("groupId", data.groupId);
localStorage.setItem("orgId", data.orgId);
localStorage.setItem("userId", data.userId);
},
error: function (error) {
alert('Error in validing username and password.');
response = false;
that.checkAuth(response);
return false
}
});
},
getCardInfo: function () {
var that = this, datasoruce;
datasoruce = new jQuery.ajax({
type: "GET",
url: '' + that.userId + '/attribute',
contentType: "application/json",
dataType: "json",
headers: { 'Authorization': that.token },
success: function (data, status) {
localStorage.setItem("userAttributeList", JSON.stringify(data.attribute));
that.cardData = JSON.stringify(data.attribute);
that.loadData();
},
error: function (error) {
console.log(JSON.stringify(error));
}
})
},
loadData: function () {
var that = this;
var obj = JSON.parse(that.cardData);
that.companyName = obj[0].attData;
that.airCraftTypes = obj[23].attData;
that.airCraftRegNum = obj[24].attData;
var memberType = obj[1].attData;
var x = obj[17].attData;//experation date
that.daysTillExpire = this.calcDate(x);
that.expirationDate = this.formatDate(x);
that.set("attCompanyName", that.companyName);
that.set("attAircraftTypes", that.airCraftTypes);
that.set("attAircraftRegNum", that.airCraftRegNum);
that.set("attExpirationDate", "Expires: " + that.expirationDate);
that.set("calcDateTillExp", "Days to expiration: " + that.daysTillExpire);
that.set("isLoggedIn", true);
//checking for membership status
var strMembershipDecision = "Paid Members";
if (strMembershipDecision == memberType) {
that.set("memberStatus", "Prefered Member");
}
else { that.set("memberStatus", "Trial Member"); }
if (that.daysTillExpire <= 0) {
this.wipeout();
}
},
checkMembershipStatus: function (memberStatus, numDaysToExp) {
},
wipeout: function () {
var that = this;
that.set("isExpired", true);
that.set("showExpired", true);
},
formatDate: function (expirationDate) {
var date = new Date(); //date of experation
date.setYear(parseInt(expirationDate.substr(0, 4), 10));
date.setMonth(parseInt(expirationDate.substr(4, 2), 10) - 1);
date.setDate(parseInt(expirationDate.substr(6, 2), 10));
date.setHours(parseInt(expirationDate.substr(8, 2), 12)); // 201609290000
date.setMinutes(parseInt(expirationDate.substr(10, 2), 12));
return (date.toLocaleDateString());
},
calcDate: function (expirationDate) {
var date = new Date(); //date of experation
date.setYear(parseInt(expirationDate.substr(0, 4), 10));
date.setMonth(parseInt(expirationDate.substr(4, 2), 10) - 1);
date.setDate(parseInt(expirationDate.substr(6, 2), 10));
date.setHours(parseInt(expirationDate.substr(8, 2), 12)); // 201609290000
date.setMinutes(parseInt(expirationDate.substr(10, 2), 12));
var today = new Date(); //Setting todays date
today.setYear(today.getFullYear());
today.setMonth(today.getMonth());
today.setDate(today.getDate());
var millisecondsPerDay = (1000 * 60 * 60 * 24);
var millsBetween = (date.getTime() - today.getTime());
var numExpDays = Math.floor(millsBetween / millisecondsPerDay);
return (numExpDays);
}
});
app.loginService = {
viewModel: new LoginViewModel(),
afterShow: function () {
},
beforeShow: function () {
loadState();
},
//
// //loadState();
//var x = app.loginService.viewModel.get("companyName")
//alert(x);
// app.loginService.viewModel.isLoggedIn = true;
//logic to determine if user is logged in or not.
onShow: function () {
}
};
})(window);
I created a worked around using this
<a data-role="button" href="#appDrawer" data-rel="drawer" data-align="left" data-icon="details" data-bind="visible: isLoggedIn"></a>

MeteorJS the good way to build & access my documents

I'm trying to build an MeteorJS App. This is a kind of playlist manager.
It looks like spotify, There is 3 colums so I made 3 templates,
from left to right :
- The playlists list
- The medias of the selected playlist
- The selected media's details
so here's my code :
server.js
Playlists = new Meteor.Collection("playlists");
if (Meteor.isServer) {
Meteor.startup(function() {
if (Playlists.find().count() === 0) {
var names = ["test1",
"222",
"test3",
"444",
"test5",
"666"];
for (var i = 0; i < names.length; i++)
Playlists.insert({'name': names[i]});
}
return (
Meteor.methods({
addPlaylist: function(playlistName) {
Playlists.insert({'name': playlistName, 'medias': []});
},
delPlaylist: function(playlistId) {
Playlists.remove({'_id': playlistId});
},
renPlaylist: function(playlistId, newName) {
Playlists.update({'_id': playlistId}, {'$set': {'name': newName}});
},
addMedia: function(playlistId, newMedia) {
var current_playlist = Playlists.findOne({'_id': playlistId});
Playlists.update(current_playlist, {$push: {'medias': newMedia}});
}
})
);
});
Playlists.allow({
insert: function(userId, doc) {
return (false);
},
update: function(userId, doc, fields, modifier) {
return (false);
},
remove: function(userId, doc) {
return (false);
}
});
}
my templates :
<template name="t_playlistsCol">
<button id="newPlaylist" class="btn btn-primary" type="button">
New Playlist
</button>
<div id="listPlaylist">
{{#each playlists}}
<button class="playlist {{Pselected}} btn btn-default" type="button">
{{name}}
</button>
{{/each}}
</div>
</template>
<template name="t_mediasCol">
{{#if current_playlist}}
<div class="menuPlaylist">
<img id="playPlaylist" class="btn" src="icon_play1.png">
<h4>{{current_playlist}}</h4>
<div id="optionsPlaylist">
<button id="insertMedia" class="btn btn-primary">Insert</button>
<button id="renamePlaylist" class="btn btn-info">Rename</button>
<button id="deletePlaylist" class="btn btn-danger">Delete</button>
</div>
</div>
<table id="listMedias">
<thead>
<tr>
<th class="mediaName">Titre</th>
<th class="mediaType">Type</th>
<th class="mediaTime">Durée</th>
</tr>
</thead>
<tbody>
{{#each medias}}
<tr class="media {{Mselected}}">
<td class="mediaName">{{name}}</td>
<td class="mediaType">{{type}}</td>
<td class="mediaTime">{{time}}</td>
</tr>
{{/each}}
</tbody>
</table>
{{else}}
<div class="menuPlaylist">
<h3 id="noPlaylist">Select a playlist</h3>
</div>
{{/if}}
</template>
<template name="t_previewCol">
{{#if current_media}}
<div class="menuPreview">
<p>{{current_media}}</p>
</div>
{{else}}
<div class="menuPreview">
<h3 id="noPreview">Select a media</h3>
</div>
{{/if}}
</template>
client.js :
(
Playlists = new Meteor.Collection("playlists");
if (Meteor.isClient) {
Template.t_playlistsCol.playlists = function() {
return (Playlists.find({}, {sort: {"name": 1}}));
};
Template.t_playlistsCol.events = {
'click #newPlaylist': function() {
var playlistName = prompt("Nom de la playlist : ");
if (playlistName) {
Meteor.call('addPlaylist', playlistName);
}
},
'click .playlist': function() {
Session.set("selected_playlist", this._id);
}
};
Template.t_playlistsCol.Pselected = function() {
return ( Session.equals("selected_playlist", this._id) ? "Pselected" : '' );
};
Template.t_mediasCol.current_playlist = function() {
var playlist = Playlists.findOne(Session.get("selected_playlist"));
return (playlist && playlist.name);
};
Template.t_mediasCol.medias = function() {
var current_playlist = Playlists.findOne(Session.get("selected_playlist"));
return ( current_playlist.medias );
};
Template.t_mediasCol.events = {
'click #insertMedia': function() {
var playlistId = Session.get("selected_playlist");
var newMedia = {
name: "mediaTest",
type: "img",
time: "00:15"
};
newMedia._id = new Meteor.Collection.ObjectID();
Meteor.call('addMedia', playlistId, newMedia);
},
'click #deletePlaylist': function() {
var playlistId = Session.get("selected_playlist");
Meteor.call('delPlaylist', playlistId);
},
'click #renamePlaylist': function() {
var playlist = Playlists.findOne(Session.get("selected_playlist"));
var newName = prompt("Renommer " + playlist.name + " en :");
if (newName) {
Meteor.call('renPlaylist', playlist._id, newName);
}
},
'click .media': function() {
Session.set("selected_media", this._id);
}
};
Template.t_mediasCol.Mselected = function() {
return ( Session.equals("selected_media", this._id) ? "Mselected" : "" );
};
Template.t_previewCol.current_media = function() {
var playlistId = Session.get("selected_playlist");
var mediaId = Session.get("selected_media");
var playlist = Playlists.find({'_id': playlistId});
return(playlist.medias[0] && playlist.medias[0].name);
};
Accounts.ui.config({
passwordSignupFields: 'USERNAME_ONLY'
});
}
I'm a newbie, I'm learning Meteor for 3 weeks.
SO, MY PROBLEM is that, I want the user to be able to select a media and see its details with the template "t_previewCol" .
It works for the playlists, but I don't have what I want with the helper "Template.t_previewCol.current_media", it prints this error when I do a console.log to debug :
Exception in template helper:
Template.t_previewCol.current_media#http://localhost:3000/client
/client.js?7212665c7dc29cf721272fa4cabeb499f2e18bf5:69:5
bindToCurrentDataIfIsFunction/<#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:2448:7
Blaze.wrapCatchingExceptions/<#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1552:7
Spacebars.call#http://localhost:3000/packages
/spacebars.js?8717c3bee1160f47e7a46ea4e1bd0796f944cad8:169:5
#http://localhost:3000/client
/template.client.js?d2b9a924f64621cd0bcfc1292538f5b63523959a:117:5
Blaze.If/</<#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:2275:11
viewAutorun/<#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1805:7
Blaze.withCurrentView#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:2038:5
viewAutorun#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1804:5
Deps.Computation.prototype._compute#http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:214:5
Deps.Computation#http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:148:5
Deps.autorun#http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:362:7
Blaze.View.prototype.autorun#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1803:7
Blaze.If/<#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:2277:1
fireCallbacks#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1818:9
Deps.nonreactive#http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:382:5
Blaze._fireCallbacks/<#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1815:5
Blaze.withCurrentView#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:2038:5
Blaze._fireCallbacks#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1814:3
Blaze.materializeView#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1830:3
.visitObject#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1458:7
.visit#http://localhost:3000/packages
/htmljs.js?fcf2660be84fbc0c33b97ee8932dbd46612f3566:116:7
doMaterialize#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1862:13
Deps.nonreactive#http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:382:5
doRender#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1860:7
viewAutorun/<#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1805:7
Blaze.withCurrentView#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:2038:5
viewAutorun#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1804:5
Deps.Computation.prototype._compute#http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:214:5
Deps.Computation#http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:148:5
Deps.autorun#http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:362:7
Blaze.View.prototype.autorun#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1803:7
Blaze.materializeView/<#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1851:5
Deps.nonreactive#http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:382:5
Blaze.materializeView#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1850:3
.visitObject#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1458:7
.visit#http://localhost:3000/packages
/htmljs.js?fcf2660be84fbc0c33b97ee8932dbd46612f3566:116:7
.visitArray#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1363:7
.visit#http://localhost:3000/packages
/htmljs.js?fcf2660be84fbc0c33b97ee8932dbd46612f3566:114:9
.visitTag#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1441:9
.visit#http://localhost:3000/packages
/htmljs.js?fcf2660be84fbc0c33b97ee8932dbd46612f3566:101:11
.visitArray#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1363:7
.visit#http://localhost:3000/packages
/htmljs.js?fcf2660be84fbc0c33b97ee8932dbd46612f3566:114:9
.visitTag#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1441:9
.visit#http://localhost:3000/packages
/htmljs.js?fcf2660be84fbc0c33b97ee8932dbd46612f3566:101:11
.visitArray#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1363:7
.visit#http://localhost:3000/packages
/htmljs.js?fcf2660be84fbc0c33b97ee8932dbd46612f3566:114:9
doMaterialize#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1862:13
Deps.nonreactive#http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:382:5
doRender#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1860:7
viewAutorun/<#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1805:7
Blaze.withCurrentView#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:2038:5
viewAutorun#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1804:5
Deps.Computation.prototype._compute#http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:214:5
Deps.Computation#http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:148:5
Deps.autorun#http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:362:7
Blaze.View.prototype.autorun#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1803:7
Blaze.materializeView/<#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1851:5
Deps.nonreactive#http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:382:5
Blaze.materializeView#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1850:3
.visitObject#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1458:7
.visit#http://localhost:3000/packages
/htmljs.js?fcf2660be84fbc0c33b97ee8932dbd46612f3566:116:7
.visitArray#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1363:7
.visit#http://localhost:3000/packages
/htmljs.js?fcf2660be84fbc0c33b97ee8932dbd46612f3566:114:9
doMaterialize#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1862:13
Deps.nonreactive#http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:382:5
doRender#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1860:7
viewAutorun/<#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1805:7
Blaze.withCurrentView#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:2038:5
viewAutorun#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1804:5
Deps.Computation.prototype._compute#http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:214:5
Deps.Computation#http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:148:5
Deps.autorun#http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:362:7
Blaze.View.prototype.autorun#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1803:7
Blaze.materializeView/<#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1851:5
Deps.nonreactive#http://localhost:3000/packages
/deps.js?d9b2b2601bdab0f57291b38e7974a7190b8aac01:382:5
Blaze.materializeView#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:1850:3
Blaze.render#http://localhost:3000/packages
/blaze.js?309c2a3b573dca998c07c493ba4953d451b2c963:2068:3
instantiateBody#http://localhost:3000/packages
/templating.js?e2c0d3bbe4292a0b20c3083eaf4fcd0f5f91bb52:245:7
ready#http://localhost:3000/packages
/meteor.js?7a66be7a03504cd2c18dd47b699e6233b60675ed:641:6
Perhaps its because of way I built my documents, they look like that :
{
_id: "idP",
name: "nameP",
medias: [
{
_id: "idM1",
name: "nameM1"
},
{
_id: "idM2",
name: "nameM2"
},
...
]
}
I tried to give you a maximum of details about my problem, I hope someone could help me.
thanks.
EDIT :
I have fixed the behavior of my "preview column" when the user click on a media
Template.t_previewCol.current_media = function() {
var playlistId = Session.get("selected_playlist");
var mediaId = Session.get("selected_media");
var playlist = Playlists.findOne({'_id': playlistId});
for (var i = 0 ; i < playlist.medias.length ; ++i)
if (playlist.medias[i]._id._str === mediaId._str)
return(playlist.medias[i] && playlist.medias[i].name);
return (null);
};
I was trying to do
if (playlist.medias[i]._id === mediaId)
but since I've assigned the medias._id using Meteor.Collection.ObjectId() it was not working.
Now I just want to understand what is the error I pasted above.
Playlists.find returns a cursor. I think that you want Playlists.findOne.
Template.t_previewCol.current_media = function() {
var playlistId = Session.get("selected_playlist");
var mediaId = Session.get("selected_media");
var playlist = Playlists.findOne({'_id': playlistId});
return(playlist.medias[0] && playlist.medias[0].name);
};

Categories

Resources