I have a wait list type application I am creating. I currently have it where my table will populate with the collection. I want to be able to press a button and that row in the table be moved to the bottom of the table. Here is where the table is populated.
<tbody>
{{#each student}}
<tr class="accordion-toggle mainRow"> <!--mainRow if want whole row to change green-->
<td>{{> expandButton}}</td>
<td>{{Name}}</td>
<td>{{PhoneNumber}}</td>
<td>{{VipID}}</td>
<td class="selectionChange">{{> buttonSelections}}</td>
</tr>
<tr>
<td colspan="12" class="hiddenRow">
<div class="accordian-body collapse" id="{{this._id}}">
<table class="table table-striped">
<thead id="innter-table">
<tr class="info">
<th id="inner-heading">Reason for Visit</th>
<th id="inner-heading">Current Major</th>
<th id="inner-heading">Intended Major</th>
<th id="inner-heading">Comments</th>
</tr>
</thead>
<tbody>
<tr>
<td>{{ReasonForVisit}}</td>
<td>{{CurrentMajor}}</td>
<td>{{IntendedMajor}}</td>
<td>{{Comments}}</td>
</tr>
</tbody>
</table>
</div>
</td>
</tr>
{{> autoformModals}}
{{/each}}
</tbody>
Here is the template for the button:
<template name="buttonSelections">
...//other code for different buttons
<button class="btn btn-default btn-sm">
<span class="glyphicon glyphicon-arrow-down"></span>
</button>
... //other code for different buttons
</template>
I know I'll need some type of event for the button. but I'm not sure how to go about getting the item in the collection to move in the collection so that when it populates the table again, it will move to the bottom.
How do I get the collection to reorder itself so that the selected item will move to the end of the collection?
you won't "move" the item in your collection, what you'll do is sort the collection on the client so it shows how you want. i don't see the relevant helper, but it would all look something like this:
<template name="Students">
{{#each student in students}}
{{student.name}}
{{/each}}
</template>
in the JS, it's pretty standard stuff: subscribe to the collection in the onCreated(), then the helper sorts the collection how you want. here, i'm making up a field, "waitListedTime", by which the collection sorts. your button press could timestamp it for the selected student, and the helper would run reactively and your student list would update on screen.
Template.Students.onCreated(function() {
this.subscribe('students');
});
Template.Students.helpers({
students() {
return Students.find({}, {sort: {waitListedTime: 1}});
}
});
Related
I am new to Angularjs and I am trying to figure out how it's different modules work. So, I am working on a project on which I wanna achieve an accordion-like style for a page, in which a table is shown when I click a panel button. The HTML code that creates(dynamically from a database) the div elements I modify is posted below.The problem is that in this panel, any number of tables can be shown,while I need to only have one opened at a time,so when one opens,the one opened before it should close.Any ideas how I can achieve this functionality?(I assume the error is because the showDB variable is local to each table scope, but I don't know how to work around it.) Thanks!' `
<div ng-repeat="(key, value) in data.services">
<div ng-show="showSection(key)" class="top_panel-section">
<button class="btn top_btn btn-header" type="button" name="showDB"
ng-click="showDB=!showDB">{{key}}</button>
<table ng-show="showDB"
class="n-table toptable table-responsive n-table-standard n-table-striped n-table-hover">
<thead class="n-table-thead">
<tr>
<th width="70%">VM Name</th>
<th width="30%">Status</th>
</tr>
</thead>
<tbody class="n-table-body">
<tr ng-repeat="vm in value.vms">
<td width="76%">{{vm.vm}}</td>
<td width="24%" ng-style="getStatusStyle(vm.status)">
{{vm.status}}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
Yes, you should remove that local showDB variable to achieve what you need.
You can easily replace it with a $scope.activeKey and evaluating it by the
<button ... name="showDB" ng-click="activateKey(key)">{{key}}</button>
And in your controller:
$scope.activeKey = null;
$scope.activateKey = function (keyToBeActivated) {
$scope.activeKey = keyToBeActivated;
}
Now you can reach that exclusivity by checking:
<table ng-show="activeKey === key" ... >
Using table $index as unique field: (available from ng-repeat)
<button ... name="showDB" ng-click="activateKey($index)">{{key}}</button>
And
<table ng-show="activeKey === $index" ... >
I am trying to figure out how to render some data in a table using Handlebars.
I already have the part for the header.
I did it like this:
<thead>
<tr>
{{#each chart.table-header}}
<th>
{{#if th-image.length}}
<p><img src="/assets/images/{{th-image}}" alt=""></p>
{{/if}}
<strong>{{{th-title}}}</strong>
<p>{{{th-description}}}</p>
</th>
{{/each }}
</tr>
</thead>
And here my chart.json:
{
"table-header" : [
{
"th-title": "",
"th-description": "",
"th-image": "",
"special-case": ""
},
{
"th-title": "Online Investing",
"th-description": "Make more informed...",
"th-image": "MESDicon.png",
"special-case": ""
},
{
"th-title": "Merrill Edge Guided Investing",
"th-description": "Go online to...",
"th-image": "MEGIicon.png",
"special-case": ""
},
{
"th-title": "Invest with an advisor",
"th-description": "Get professional...",
"th-image": "MEACicon.png",
"special-case": ""
}
],
"table-body" : [
{
// HERE GOES THE INFO FOR THE TBODY ELEMENT.
}
]
}
But for the rest of tbody part I don't know how can I render the rest of the info.
It should look like this:
But the idea is to render that data coming from the chart.json file.
<tbody>
<tr>
<td>Investing method</td>
<td>Online</td>
<td>Online with professional portfolio management</td>
<td>With an advisor</td>
</tr>
<tr>
<td>Simple, straight-forward pricing</td>
<td><strong>$6.95 online equity & ETF trades<sup>3</sup></strong><br>(Qualify for $0 trades with Preferred Rewards)<sup>2</sup> Other fees may apply<sup>3</sup> </td>
<td><strong>0.45% annual fee</strong><br>Other fees may apply</td>
<td><strong>0.85% annual program fee</strong><br>Other fees may apply</td>
</tr>
<tr>
<td>Minimum investment</td>
<td><strong>None</strong></td>
<td><strong>$5,000</strong></td>
<td><strong>$20,000</strong></td>
</tr>
<tr>
<td>Investment choices</td>
<td><strong>Full range of investments</strong></td>
<td><strong>A set of ETF strategies</strong></td>
<td><strong>A set of mutual fund/ETF strategies</strong></td>
</tr>
<tr>
<td>Bank & invest with one login</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
</tr>
</tbody>
Any suggestions?
since your table-body is array of objects. you can loop through that and using keys you can access data.
<thead>
<tr>
{{#each chart.table-header}}
<th>
{{#if th-image.length}}
<p><img src="/assets/images/{{th-image}}" alt=""></p>
{{/if}}
<strong>{{{th-title}}}</strong>
<p>{{{th-description}}}</p>
</th>
{{/each }}
</tr>
</thead>
<tbody>
{{#each chart.table-body}}
<tr>
<td>{{this.your_key}}</td>
<td>{{this.your_key}}</td>
<td>{{this.your_key}}</td>
<td>{{this.your_key}}</td>
</<tr>
{{/each}}
</tbody>
Use below code snippet to resolve the issue:
<thead>
<tr>
{{#each table-header}}
<th>
{{#if th-image.length}}
<p><img src="/assets/images/{{th-image}}" alt=""></p>
{{/if}}
<strong>{{th-title}}</strong>
<p>{{th-description}}</p>
</th>
{{/each }}
</tr>
</thead>
<tbody>
{{#each table-body}}
<tr>
<td>{{key1}}</td>
<td>{{key2}}</td>
<td>{{key3}}</td>
<td>{{key4}}</td>
</<tr>
{{/each}}
</tbody>
The problem is that you are not enclosing your handlebars in a <script> tag. Handlebars will compile the template incorrectly without throwing any errors. For div it works always it seems.
Thus simply wrap the template section in a script tag like so:
<script type="text/x-handlebars-template" id="carBladeTemplate">
{{#each cars}}
<tr class="carItem" data-car-id="{{Id}}">
<td>{{Id}}</td>
<td>{{Make}}</td>
<td>{{Model}}</td>
</tr>
{{/each}}
</script>
I am new to meteor and my background is JDEdwards consultant with 15 years of experience. Recently interested in web application and building small application with meteor. Here is my issue.
I have five rows of data in HTML table with checkbox and it has amount field. I have one input text just before table (Invoice Total:). I would like to select checkbox from table and it will display total value in Invoice Total. I have class in both places. For example, If I select three records with amount 55,10 and 5, Invoice total should be 70. How do I achieve this using meteor client JS. Can I get some help on this?
HTML
<template name="dashboard">
<div class="col-sm-9">
<div class="well">
<h4>Dashboard</h4>
<label class="totalamt">Invoice Total:
<input type="text" value={{invtotal}}>
</label>
<table class="table">
<thead>
<tr>
<th></th>
<th>Company Id</th>
<th>Invoice Id</th>
<th>Amount</th>
<th>Currency</th>
<th>Description</th>
</tr>
</thead>
<tbody>
{{#each invoiceList}}
{{>invoiceRow}}
{{/each}}
</tbody>
</table>
</div>
</div>
</template>
<template name="invoiceRow">
<tr class="success">
<td><input type="checkbox" checked="{{calcamt}}" class="toggle-checked"/></td>
<td>{{division_id}}</td>
<td>{{invoice_id}}</td>
<td>{{amount}}</td>
<td>{{currency}}</td>
<td>{{description}}</td>
</tr>
</template>
**
client JS
**
Router.route('/dashboard',function(){
this.render('dashboard');
Template.dashboard.invoiceList = function(){
return Invoice.find();
}
Template.invoiceRow.events({
'click.toggle-checked':function(evt,tmpl){
}
});
Template.invoiceRow.select_invoice = function(){
return Session.get('select_invoice')
}
})
Thanks,
Kaushik Roy
I have created a table/grid using jsViews. Each row has an edit button which when clicked selects the row and shows input controls instead of text values.
If I show/hide the inputs using data-link="visible{:#parent.parent.data.selectedIndex!==#index}" then it works fine.
However, I was trying a different approach using {^{if #parent.parent.data.selectedIndex===#index}}...{{else}}...{{/if}} to show/hide the inputs and this doesn't work when selectedIndex changes on my data object.
I also tried with {^{if ~root.selectedIndex===#index}} but that didn't work either. Is it possible to do this with {{if}}? The reason I am trying this over the first method that worked was to avoid rendering lots of select boxes which will just be hidden anyway.
My data object looks like this:
app = {
data: [...],
selectedIndex: null,
select: function select(index) {
if (this.selectedIndex !== index) {
$.observable(this).setProperty("selectedIndex", index);
}
}
};
I link the template like this:
$.templates("#myTemplate").link("#divHolder", app)
.on("click", ".data .editButton", function() {
app.select($.view(this).index);
})
.on("click", ".data .saveButton", function() {
// save details
})
.on("click", ".transmittals .cancelButton", function() {
// reset values
app.select(null);
});
My template is like this:
<script id="myTemplate" type="text/x-jsrender">
<table id="tblData" class="data">
<thead>
<tr>
<th></th>
<th>A</th>
<th>B</th>
<th>C</th>
</tr>
</thead>
<tbody>
{^{for data}}
<tr class="item">
<td>
{{if #parent.parent.data.selectedIndex===#index}}
<span class="editItem">
<button class="cancelButton">Cancel</button></span>
{{else}}
<span class="viewItem">
<button class="editButton">Edit</button></span>
{{/if}}
</td>
<td>
{^{if #parent.parent.data.selectedIndex===#index}}
<span class="editItem"><input type="text" data-link="B" /></span>
{{else}}
<span class="viewItem" data-link="B"></span>
{{/if}}
</td>
<td>
{^{if #parent.parent.data.selectedIndex===#index}}
<span class="editItem"><input type="text" data-link="C" /></span>
{{else}}
<span class="viewItem" data-link="C"></span>
{{/if}}
</td>
</tr>
{{/for}}
</tbody>
</table>
</script>
When you add an {{if}} block, it is a nested view, so the button click is not getting you the item view with the index. You need to use $.view(this).parent.index - or, simpler, $.view(this).getIndex() - which automatically steps up through nested views (if any) to the item view and gets its index.
app.select($.view(this).getIndex());
(See discussion here: https://github.com/BorisMoore/jsrender/issues/173#issuecomment-11058106)
BTW here is a modified form of your sample, just to give you some ideas. It uses <button data-link="{on ~root.select #getIndex()}">Edit</button> to hook up the click handler on the button and call the select method directly, passing it the index:
<script id="myTemplate" type="text/x-jsrender">
<table id="tblData" class="data">
<thead>
...
</thead>
<tbody>
{^{for data}}
<tr class="item">
{^{if ~root.selectedIndex===#index}}
<td><button class="cancelButton" data-link="{on ~root.select null}">Cancel</button></td>
<td><input data-link="A" /></td>
<td><input data-link="B" /></td>
{{else}}
<td><button class="editButton" data-link="{on ~root.select #getIndex()}">Edit</button></td>
<td data-link="A"></td>
<td data-link="B"></td>
{{/if}}
</tr>
{{/for}}
</tbody>
</table>
</script>
<div id="divHolder"></div>
<script>
var app = {
data: [{A:"aa", B: "bb"},{A:"aa2", B: "bb2"}],
selectedIndex: null,
select: function(index) {
if (this.selectedIndex !== index) {
$.observable(this).setProperty("selectedIndex", index);
}
}
};
$.templates("#myTemplate").link("#divHolder", app);
</script>
I am using Meteor, and trying to have one mongo collection that will contain products, and one that contains users.
Products have prices, but I also gave one product(as a test for now) a "dealerPrices" subcollection that contains an object like this:
"partprice" : "98",
"dealerPrices" : {
"YH" : "120",
"AB" : "125"
},
My hope is to have a table on my site with a column that displays the 'partprice' and next to it another column that shows the price for the current logged in dealer.
I could do a completely seperate collection for dealerPrices, but I am not sure which way is more efficient since I am new to Mongo.
My issue is targeting that number in the field with the "YH" or "AB" depending on the logged in user, the Users collection has a subcollection called "profile" that has a field called "code" that will match that "YH" or "AB" which is a unique code for each dealer.
I am using handlebars to display the data in Meteor, here is a bit of the html for displaying the table rows.
Larger code section:
<template name="products">
<h2> All Products <span class="productCount"></span></h2>
<table class="table table-condensed table-striped table-hover table-bordered">
<thead>
<tr>
<th class="toHide">Unique ID</th>
<th>Print</th>
<th>Product</th>
<th>FF Code</th>
<th>Base Price</th>
<th>My Price</th>
</tr>
</thead>
{{> AllProducts}}
</template>
<template name='AllProducts'>
{{#each row}}
<tr class='productRow'>
<td class="product-id toHide">{{_id}}</td>
<td class="print"><input type="checkbox" class="chkPrint"/></td>
<td class="product-name">{{partname}}</td>
<td class="product-code">{{code}}</td>
<td class="product-az-price">${{partprice}}</td>
<td class="product-dealer-price">${{dealerPrices.YH}}</td>
</tr>
{{/each}}
</template>
I hope I am explaining this correctly, basically I am trying to find some alternative to joins and having a table for products, a table for the dealer-product-dealerPrice relationship and a user accounts table in a relational database.
You probably want to do this in a Template helper. First, create a template for each loop-through, instead of just using {{#each}}:
<template name="fooRow">
... table rows
<td class="product-dealer-price">{{userBasedThing}}</td>
</template>
Then, add a Template helper for this new fooRow template:
Template.fooRow.userBasedThing = function () {
var result = "";
if (Meteor.userId() && this.dealerPrices)
result = this.dealerPrices[Meteor.user().profile[0].code];
return result;
}
Then just get rid of the stuff in the each loop, and replace it with:
{{#each row}}
{{> fooRow}}
{{/each}}
That should do it!