Here are the templates in question:
<template name="tables">
<div class="table-area">
{{#each tableList}}
{{> tableBox}}
{{/each}}
</div>
</template>
<template name="tableBox">
<table id="{{name}}" class="table table-condensed table-striped">
<tr>
<td>{{name}}</td>
<td> Min:</td>
<td>{{minBet}}</td>
<td>{{cPlayers}}</td>
</tr>
<tr>
<td>Dice1</td>
<td>Dice2</td>
<td>Dice3</td>
<td>Total</td>
</tr>
{{#each table [{{name}}]}}
{{> tableRow}}
{{/each}}
</table>
</template>
<template name="tableRow">
<tr>
<td>{{Roll.dice1}}</td>
<td>{{Roll.dice2}}</td>
<td>{{Roll.dice3}}</td>
<td>{{Roll.total}}</td>
</tr>
</template>
And here are the Meteor Handlebars functions:
Template.tables.tableList = function(){
return Tables.find();
}
Template.tableBox.table = function(tableID){
return Rolls.find({tableName: tableID});
}
The problem is each table that is rendered on screen has all the 'Rolls' listed (All 100 lines). Instead of being filtered for the parameter I am trying to pass through to the Roll template function which is the table name {{name}}.
In the "table id" tag of TableBox, the {{name}} gets converted correctly. i.e. "T1", "T2", "T3" etc. But it's that same TableID that i need to pass to the function to filter from the db query properly. Is there a way to do this more simply? I would like to stick to the handlebars templating way of doing things here if possible.
For reference below is the JSON initialisation code for the test data:
//initiate tables
for (i = 1; i < 11; i++) {
Tables.insert({
name: 'T' + i,
minBet: '300',
cPlayers: '(8)'
});
}
//initiate rolls within tables
for (i = 1; i < 11; i++) {
for(j=1; j<11; j++){
var die1 = ((Math.floor(Math.random() * 5) +1).toString());
var die2 = ((Math.floor(Math.random() * 5) +1).toString());
var die3 = ((Math.floor(Math.random() * 5) +1).toString());
var t = (parseInt(die1) + parseInt(die2) + parseInt(die3)).toString();
Rolls.insert({
Roll: {
tableName: 'T' + i,
rollNumber: j;
dice1: die1,
dice2: die2,
dice3: die3,
total: t
},
});
}
}
Ok - After trial and error - figured it out:
In the helper function:
Template.tableBox.table = function(tableID){
return Rolls.find({"Roll.tableName": tableID});
}
I needed to add the nested Roll.tableName property name but within brackets as the query.
And back in the tableBox template:
<template name="tableBox">
<table id="{{name}}" class="table table-condensed table-striped">
<tr>
<td>{{name}}</td>
<td> Min:</td>
<td>{{minBet}}</td>
<td>{{cPlayers}}</td>
</tr>
<tr>
<td>Dice1</td>
<td>Dice2</td>
<td>Dice3</td>
<td>Total</td>
</tr>
{{#each table name}}
{{> tableRow}}
{{/each}}
</table>
</template>
No need for the curly braces for the 'Name' argument for the function. Somehow handlebars and Meteor recognise the context you are referring to without the curly braces and applies it like it is within {{name}} for the tableBox. I.e. "T1", "T2", "T3" are passed correctly to the function and now my unique tables only contain the list of rolls specific to individual tables.
Related
I have a nested aura:iteration like this:
<aura:iteration items="{!v.results}" var="res">
<tr class="slds-hint-parent">
<aura:iteration items="{!v.ColumnsNameArr}" var="colName">
<td>
<div class="slds-truncate" >
{!res[colName]}}
</div>
</td>
</aura:iteration>
</tr>
</aura:iteration>
How can I write correct {!res[colName]}? It is possible to do something like this in lightning?
It looks like you want to iterate the res property, what looks like to me of type Map. In Lightning Aura it's not possible to iterate over a Map (Apex) / Object (Javascript).
What you can do as solution would be to transform the res Map to a type of Array (Javascript) or in Apex to type of a List.
In Lightning Aura it is possible to iterate Array's.
So how would that look like:
{
process: function() {
var res = { a: 1, b: 2};
var resArray = [];
for (var key in res) {
resArray.push({
key: key,
value: res[key]
});
}
// now, from here on you can use the 'resArray' to iterate in your Aura component
}
}
It is possible. Use the iteration variable at the next level down.
I think this will work...
<aura:iteration items="{!v.results}" var="res">
<tr class="slds-hint-parent">
<aura:iteration items="{!res.ColumnsNameArr}" var="colName">
<td>
<div class="slds-truncate" >
{!colName}}
</div>
</td>
</aura:iteration>
</tr>
PROBLEM: I have table with tr that have data from table, When I insert element in Mongo and post it on my page, element added on the bottom of the table
Posts = new Mongo.Collection('posts');
Meteor.publish('allPosts', function(){
return Posts.find({}, { sort: { date: -1 }} );
});
Meteor.subscribe("allPosts");
Posts.insert({
date: 1
})
Posts.insert({
date: 2
})
Posts.insert({
date: 3
})
<table class=" table">
{{#each posts}}
{{> postJobs}}
{{/each}}
</table>
<template name="postJobs">
<tr class="smallInfo">
<td>{{date}}</td>
</tr>
</template>
In DOM I have:
<table>
<tr>
<td>1</td> // must be 3
</tr>
<tr>
<td>2</td> // must be 2
</tr>
<tr>
<td>3</td> // must be 1
</tr>
</table>
All my last inserts must add to the top of my page (table)
EDIT :
My problem with dynamic insert in collection (and i know about -1 gramatik mistake)
EXAMPLE :
Meteor.startup(function(){
Meteor.setTimeout(function(){Test("10");}, 1000);
function Test(x)
{
Posts.insert( {
submitDate: moment().format()
});
}
Meteor.setTimeout(function(){Test("10");}, 10000);
If i sort by submitDate it will show like :
<tr><td>10-10-10</td></tr> // must be 10-10-20
<tr><td>10-10-20</td></tr> // must be 10-10-10
BUT when i refresh my page(F5) all ok
<tr><td>10-10-20</td></tr>
<tr><td>10-10-10</td></tr>
Why do you not sort descending?
{sort: { date: -1 } }
Cheers,
Tom
UPDATE:
You can find a live example at a MeteorPad I prepared:
http://meteorpad.com/pad/Ba5DTe94NjFi3ZTPA/Playground_Flow-Router_Chat
You have to do the sort on the client side not within the publish method.
This is why you get first time sorted but then just as inserted returns.
If you do the sort on client side find() the minimongo will do it on each new document.
Hope this helps for you.
Tom
I am rendering table dynamically.
Templates are defined as below:
<template name="home">
<div class="row">
<div class="tblCSV">
<table class="table table-bordered table-hover table-striped">
<thead>
// Dynamic Header Row - Working
<tr>
{{#each columns}}
<th>
{{columnName}}
</th>
{{/each}}
</tr>
</thead>
// Dynamic Rows - Working
<tbody>
{{#each entries}}
{{> entry}}
{{/each}}
</tbody>
</table>
</div>
</div>
</template>
// if i try to iterate columns to print values per row, it prints field/column name instead it's value
<template name="entry">
<tr>
{{#each columns}}
// columnName is a mongodb field name, Not Working
<td>{{columnName}}</td> // This prints text of Column name itself instead its value
{{/each}}
</tr>
</template>
// If i use static column names, it prints all the column values perfectly
<template name="entry">
<tr>
<td>{{MyColumnName1}}</td> //This prints value of column name i.e. MyColumnValue
<td>{{MyColumnName2}}</td>
<td>{{MyColumnName3}}</td>
<td>{{MyColumnName4}}</td>
</tr>
</template>
Template Script
Template.home.helpers({
entries: function () {
return Entry.find();
},
columns: function () {
return Column.find();
}
});
Template.entry.helpers({
columns: function () {
return Column.find();
}
});
This is what the problem is
This is what i want
Feel free to ask for any information you need.
I'm trying to create my first Meteor App and I'm stuck on what should be a simple process. Here are the inserts that I used to first set up the DB;
income.insert({income_acct_name: "Account 1", income_acct_budget: 0, income_acct_total: 0});
income.insert({income_acct_name: "Account 2", income_acct_budget: 0, income_acct_total: 0});
income.insert({income_acct_name: "Account 3", income_acct_budget: 0, income_acct_total: 0});
here is template;
<template name="income">
{{#each accounts}}
<tr>
<td class="row1"><input type="text" value="{{income_acct_name}}"></td>
<td class="row2"><input type="text" value="{{income_acct_budget}}"></td>
<td class="row3">0%</td>
<td class="row4"><input type="text" value="0" id="income_amt_entered"></td>
<td class="row5">$ </td>
<td class="row6"> - </td>
<td class="row7"></td>
</tr>
{{/each}}
</template>
and this is the helper that throws the error;
Template.income.events ({
'change td.row4': function(theEvent, theTemplate) {
var rowId = this._id;
Session.set('changedRow', rowId);
var changedRow = Session.get('changedRow');
var amount = theTemplate.find('#income_amt_entered').value;
income.update (
{"_id": changedRow},
{$inc: {"income_acct_total": amount}}
)
//console.log(amount);
}
});
So in my form I enter an amount like 45.50 in row4 to update "income_acct_total" and I get that error. I'm using pretty much the same code from the Leader Board app that is working. The amount entered appears correctly in the console log.
Try to get number from '#income_amt_entered' input :
var amount = parseFloat(theTemplate.find('#income_amt_entered').value);
So I have I have a simple structure where one purchase have a collection of expenses, and each expense have an account(plastic, cash, plastic#2...).
So the json my api gets is similar to this:
[
{"$id":"1","Id":1,"Name":"apple","Value":100.0,"AccountId":1,"Account":
{"$id":"2","Id":1,"Name":"Cash"}},
{"$id":"3","Id":2,"Name":"pear","Value":50.0,"AccountId":1,"Account":
{"$ref":"2"}},
{"$id":"4","Id":3,"Name":"raspberry","Value":10.0,"AccountId":1,"Account":
{"$ref":"2"}}
]
I see my json is not writing my cash account each time it needs it, it is refering it with
{"$ref":"2"}
where
{"$id":"2","Id":1,"Name":"Cash"}
so when I render my table with this html:
<table>
<tbody data-bind="foreach: gastos">
<tr>
<td data-bind="text: $data.id"></td>
<td data-bind="text: $data.name"></td>
<td data-bind="text: $data.value"></td>
<td data-bind="text: $data.account.Name"></td>
<td>
<button type="button" class="btn btn-xs">
<i class="glyphicon glyphicon-trash"></i>
</button>
</td>
</tr>
</tbody>
</table>
I get this, because the account for pear, and raspberry are nulls:
So how do you handle $ref in knockout?
I am mapping to 'gastos' this way:
$.getJSON('#ViewBag.GastosUrl', function (data) {
data.forEach(function(o) {
gastos.push(new gastoVM(o.Id, o.Name, o.Value, o.Account));
});
});
var gastoVM = function(Id, Name, Value, Account) {
var self = this;
self.id = Id;
self.name = Name;
self.value = Value;
self.account = Account;
};
thanks.
I'm not familiar with entity-framework but with the data as provided, a couple options available (JSFiddle):
Build up the account information alongside the gastos. And only provide the $id or $ref for later referencing.
var vm = {
gastos: [],
accounts: {},
accountLookup: function(accountId){
return this.accounts[accountId];
}
}
//... inside AJAX call
var accountId = o.Account["$id"]
if(accountId)
{
vm.accounts[accountId] = o.Account;
}
Use a ko utility method to lookup the account from within your array.
accountLookupByUtil: function(accountId) {
var gasto = ko.utils.arrayFirst(this.gastos, function(item) {
if(item.account['$id'] == accountId)
{
return item
}
});
return gasto.account;
}
From the html:
<td data-bind="text: $root.accountLookup($data.accountId).Name"></td>
<td data-bind="text: $root.accountLookupByUtil($data.accountId).Name"></td>
Note: Both methods are available in the fiddle, thus some properties are provided that would not be necessary depending upon the method used.