I have table with a lot of tr, when my page is load 1st tr shows and 2nd tr is hide, for example:
<table>
<tr></tr> // shows
<tr></tr> // hide
<tr></tr> // shows
<tr></tr> // hide
...
...
etc.
</table>
What I want to build: When you click on "show" tr, lower tr (which is located underneath) must shows too, and when you clicked on "NEW" shows tr it must hide (like toggle)
PROBLEM: When I clcked on "show" tr, ALL "hide" tr shows too, NOT one which is located underneath
My CODE:
<template name="postJobs">
<tr class="smallInfo">
// some code
</tr>
{{#if showFullContent}}
<tr class=" bigInfo">
// some code
</tr>
{{/if}}
</template>
Template.postJobs.helpers({
showFullContent:function(){
return Session.get('showContent');
}
});
Template.postJobs.events({
'click .smallInfo':function(){
Session.set('showContent',true);
},
'click .bigInfo':function(){
Session.set('showContent',false);
},
});
I dont want to use jQuery
The problem with your current code is that you're using Session, which is a global reactive dictionary, meaning that you only end up storing one state for all of your table rows.
Here is a solution using a template scoped ReactiveVar object :
HTML
<template name="jobsTable">
<table>
{{#each jobs}}
{{> postJobs}}
{{/each}}
</table>
</template>
<template name="postJobs">
<tr class="smallInfo">
// some code
</tr>
{{#if showFullContent}}
<tr class=" bigInfo">
// some code
</tr>
{{/if}}
</template>
JS
Template.postJobs.onCreated(function(){
this.showFullContent = new ReactiveVar(false);
});
Template.postJobs.helpers({
showFullContent: function(){
return Template.instance().showFullContent.get();
}
});
Template.postJobs.events({
"click .smallInfo": function(event, template){
template.showFullContent.set(true);
},
"click .bigInfo": function(event, template){
template.showFullContent.set(false);
}
});
Related
WHAT I WANT TO BUILD IN DOM:
<table>
<tr> Today </tr>
<tr>
//data from Mongo
</tr>
...
<tr> Yesterday </tr>
....
//data from Mongo
..etc
</table>
CODE I HAVE :
<table>
{{#each posts}}
{{> postJobs}}
{{/each}}
</table>
<template name="postJobs">
<tr>
... // data from Mongo
</tr>
</template>
I think that it is necessary to compare the date from Mongo documents and today date or something like this.
Any idea how to build this ?
I guess you are requesting how to get the documents from collections grouped by date.
So on Top to see today chat, next block Yesterday, next block Previous Chats
Just call 3 times the same template
<template name="main">
<h1>Today</h1>
{{> list_posts posts=today}}
<h1>Yesterday</h1>
{{> list_posts posts=yesterday}}
<h1>Previous</h1>
{{> list_posts posts=previous}}
</template>
<template name="list_posts">
<table>
{{#each posts}}
<tr>
<td>{{col1}}</td>
<td>{{colX}}</td>
</tr>
{{/each}}
</table>
</template>
And then you need this helpers
Template.main.helpers({
today: function() {
return Posts.find() // col.date >= today
},
yesterday: function() {
return Posts.find() // col.date < today and >= yesterday
},
previous: function() {
return Posts.find() // col.date < yesterday
}
});
Good luck
Tom
I don't get what you exactly want to achieve. Comparing to today date would look like this, in an helper (that you can use in an {{#if compareDate}} statement:
compareDate: function(){
var today= new Date(new Date().getTime());
return this.date < today// it will get you true is the date field of your mongo document is older than today
}
Extra info, if you need yesterday:
var yesterday = new Date(new Date().getTime() - (24 * 60 * 60 * 1000));
Have collection
Peoples = new Mongo.Collection('peoples');
Peoples.insert({
name: ["Mark", "John", "Kate"]
});
I want to show all names in name
<template name="pTable">
<tr class="trJob">
<td>
{{#each names}}
{{> peopleName}}
{{/each}}
</td>
</tr>
</template>
<template name="peopleName">
<div>{{name}}</div>
</template>
What in my Temlate helpers
Template.pTable.helpers({
names: function(){
return Posts.tags;
}
});
Template.peopleName.helpers({
name: function(){
return Posts.tags.find();
}
});
I know that i have sh*** code in my Template helpers, any idea how to make it good ?
It must look like (in DOM)
<td>
<div>Mark</div>
<div>John</div>
<div>Kate</div>
</td>
simple array example
Template.home.helpers({
names: function(){
return [1,2,3];
}
});
<template name="home">
{{#each names}}
{{this}}
{{/each}}
</template>
will print:
1 2 3
each item becomes "this" inside the each loop. if you call another template within the loop, then its "this" will be populated by the item
Since you have different names for your collection, I will stick with the first one Peoples
Here is how I would proceed with your helpers:
Template.pTable.helpers({
names: function(){
return People.find({_id:yourId},{fields:{name:1}}).fetch();
}
});
And your peopleName template would be like this:
<template name="peopleName">
<div>{{this}}</div>
</template>
If you need to get all the names of all your documents, I need to nest your {{#each names}} into another {{#each doc}} where doc helper is like this (updated names as well) :
Template.pTable.helpers({
doc: function(){
return People.find().fetch();
},
names: function(){
return People.find({_id:this.id},{fields:{name:1}}).fetch();
});
I have published a countries collection which I want to show in a table in the countriesList template. So I have added this to the router:
Router.route('/countries_list', {
name: 'countriesList',
waitOn: function() {
return Meteor.subscribe('countries');
},
data: function() {
return Countries.find();
}
});
And this is how the template looks like:
{{#each countries}}
<tr>
<td>{{name}}</td>
</tr>
{{/each}}
But the page stays empty. However, the collection is filled on the client, if I check the browser console and do Countries.findOne();, I get this result:
Object {_id: "WWJhMBne4CiEdbbdg", name: "England"}
So what am I doing wrong here?
You template is making the assumption that the cursor is being stored in coutries. It isn't. It would be if your data hook looked like:
return {countries: Countries.find()};
As your code is written, the cursor is the context for your template so this should work:
{{#each this}}
<tr>
<td>{{name}}</td>
</tr>
{{/each}}
I have a table with data coming from a collection. When user clicks on a row I want to replace the content of the row with a form to edit the content. What would be the meteor way to do it without jQuery, if possible?
<template name="table">
<table>
{{#each items}}
{{> showrow}}
{{else}}
</table>
</template>
<template name="showrow">
<tr>
<td>{{name}}</td>
</tr>
</template>
<template name="editrow">
<tr>
<form>
… form html …
</form>
</tr>
</template>
Essentially, it's about replacing the showrowtemplate witn the editrow for onw row, I think. Is that a reasonable approach? Any pointers?
You could use a logical helper
<template name="table">
<table>
{{#each items}}
{{#if editmode}}
{{>editrow}}
{{else}}
{{> showrow}}
{{/if}}
{{/each}}
</table>
</template>
Then in your template helper
Template.table.editrow = function() {
return (this.editmode)
}
this lets you access the data context that would be in the collection for that particular item in the loop. So if you had a editmode:true for that item it would use the edit row instead.
Ok, that was easier than expected. 1:0 for Meteor:
I used the MongoDB _id as identifier of each row, in a data attribute: data-id="{{_id}}".
Then I set up a click event handler on <tr>-elements:
Template.booking.events({
'click tr': function(event, template) {
Session.set(editBookingId, event.currentTarget.getAttribute('data-id'));
}
});
A template helper listens to incoming ids and returns true if the ids match:
Template.booking.helpers({
'isEdited': function(id) {
return Session.get(editBookingId) == id;
}
});
In the template, I decide with {{#if}} whether to display the normal row or an edit dialog:
{{#if isEdited _id}}EDIT{{/if}}
Very little code. Very nice. Thanks for the pointers.
The first column in my gridview (gvAvailable) is a currently checkbox column "chkSelect".
The way it works now is that a user can check multiple checkboxes on a gridview, but I would like a jquery function to deselect all the checkboxes on the gridview except for the checkbox that was clicked.
I was also looking for a way to access the columns of the checked row with jquery on a button click.
Thanks for any help
Here's how the generated html looks
<table class="Grid" cellspacing="0" border="0" id="gvAvailable" style="width:99%;border-collapse:collapse;">
<tr class="GridHeader">
<th scope="col"> </th><th scope="col">Guid</th><th scope="col">Id</th><th scope="col">Name</th>
<th scope="col">Facility</th><th scope="col">Room</th>
</tr>
<tr class="GridItem">
<td>
<input id="gvAvailable_ctl02_chkSelect" type="checkbox" name="gvAvailable$ctl02$chkSelect" />
</td>
<td>24</td>
<td>000101020201</td>
<td>Test</td>
<td>Test Facility</td>
<td> </td>
</tr><tr class="GridAltItem">
<td>
<input id="gvAvailable_ctl03_chkSelect" type="checkbox" name="gvAvailable$ctl03$chkSelect" />
</td>
<td>25</td>
<td>1001</td>
<td>Test 2</td>
<td>Test 3</td>
<td> </td>
</tr>
</table>
if you add the same class to each of the checkboxes in the markup, you can retrieve an array of them by saying
$('.classname')
This will give you back the array of objects. You can then call 'each' on the array and deselect them all.
function removeChecks()
{
$('.classname').each(function()
{
$(this).removeAttr('checked');
});
}
Then add the above function call in the click handler for the each checkbox:
$('.classname').each(function()
{
$(this).click(function()
{
removeChecks();
$(this).attr('checked', 'checked');
});
});
the code above should be set up to run on page load.
In this example I put one button to check, and one button to uncheck gridview checkboxes :
<asp:GridView runat="server" ID="grid"></asp:GridView>
<input type="button" onclick="uncheckCheckBoxes()" value="UnCheck" />
<input type="button" onclick="checkCheckBoxes()" value="Check" />
<script>
function uncheckCheckBoxes()
{
var gridClientID = '<%= grid.ClientID %>';
jQuery.each($("#" + gridClientID + " input[type='checkbox']"), function ()
{
this.checked = false;
});
}
function checkCheckBoxes()
{
var gridClientID = '<%= grid.ClientID %>';
jQuery.each($("#" + gridClientID + " input[type='checkbox']"), function ()
{
this.checked = true;
});
}
</script>
I am assuming you would like to make sure the user clicked checkboxes do not get toggled? If so, go on below.
First, just give a class name to all checkboxes in the gridview.
Whenever a checkbox was clicked, add another class to it to denote it was physically selected.
$('.checkbox').click(function(){
$(this).addClass('checked');
});
Now, when a user clicks on the select all checkbox (let's call it "selectAll") on top, iterate through all the checkboxes and toggle the status while checking the "checked" class
$('#selectAll').click(function(){
var status = $(this).attr('checked')
$('.checkbox').each(function(){
//only toggle if not set
if(!$(this).hasClass('checked')){
if(status){
$(this).attr('checked', 'checked');
}
else{
$(this).attr('checked', '');
}
}
});
});
This should get you along your merry way hopefully.
Now, accessing columns of the checked row?
You could add an onclick event to each table row.
$('#tablename tr').click(function(){
//do something
});
i found this articale very usefull Check/Uncheck all Items in an ASP.NET CheckBox List using jQuery