Skip to content

Instantly share code, notes, and snippets.

@idmontie
Last active January 6, 2016 17:24
Show Gist options
  • Save idmontie/638b03ef871fa4c4de4d to your computer and use it in GitHub Desktop.
Save idmontie/638b03ef871fa4c4de4d to your computer and use it in GitHub Desktop.
Meteor Demonstration

Demonstration files for Meteor.

Clicks = new Mongo.Collection('clicks');
if (Meteor.isClient) {
Template.hello.helpers({
counter: function () {
return Clicks.findOne({}).clicks;
}
});
Template.hello.events({
'click button': function () {
// increment the counter when button is clicked
var clickTracker = Clicks.findOne({});
clickTracker.clicks++;
Clicks.update(clickTracker._id, {
$set: {
clicks: clickTracker.clicks
}
});
}
});
}
if (Meteor.isServer) {
Meteor.startup(function () {
var clickTracker = Clicks.findOne({});
if (clickTracker == null) {
Clicks.insert({
clicks: 0
});
}
});
}
// App component - represents the whole app
App = React.createClass({
getTasks() {
return [
{ _id: 1, text: "This is task 1" },
{ _id: 2, text: "This is task 2" },
{ _id: 3, text: "This is task 3" }
];
},
renderTasks() {
return this.getTasks().map((task) => {
return <Task key={task._id} task={task} />;
});
},
render() {
return (
<div className="container">
<header>
<h1>Todo List</h1>
</header>
<ul>
{this.renderTasks()}
</ul>
</div>
);
}
});
// Task component - represents a single todo item
Task = React.createClass({
propTypes: {
// This component gets the task to display through a React prop.
// We can use propTypes to indicate it is required
task: React.PropTypes.object.isRequired
},
render() {
return (
<li>{this.props.task.text}</li>
);
}
});
/* CSS declarations go here */
body {
font-family: sans-serif;
background-color: #315481;
background-image: linear-gradient(to bottom, #315481, #918e82 100%);
background-attachment: fixed;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
padding: 0;
margin: 0;
font-size: 14px;
}
.container {
max-width: 600px;
margin: 0 auto;
min-height: 100%;
background: white;
}
header {
background: #d2edf4;
background-image: linear-gradient(to bottom, #d0edf5, #e1e5f0 100%);
padding: 20px 15px 15px 15px;
position: relative;
}
#login-buttons {
display: block;
}
h1 {
font-size: 1.5em;
margin: 0;
margin-bottom: 10px;
display: inline-block;
margin-right: 1em;
}
form {
margin-top: 10px;
margin-bottom: -10px;
position: relative;
}
.new-task input {
box-sizing: border-box;
padding: 10px 0;
background: transparent;
border: none;
width: 100%;
padding-right: 80px;
font-size: 1em;
}
.new-task input:focus{
outline: 0;
}
ul {
margin: 0;
padding: 0;
background: white;
}
.delete {
float: right;
font-weight: bold;
background: none;
font-size: 1em;
border: none;
position: relative;
}
li {
position: relative;
list-style: none;
padding: 15px;
border-bottom: #eee solid 1px;
}
li .text {
margin-left: 10px;
}
li.checked {
color: #888;
}
li.checked .text {
text-decoration: line-through;
}
li.private {
background: #eee;
border-color: #ddd;
}
header .hide-completed {
float: right;
}
.toggle-private {
margin-left: 5px;
}
@media (max-width: 600px) {
li {
padding: 12px 15px;
}
.search {
width: 150px;
clear: both;
}
.new-task input {
padding-bottom: 5px;
}
}
<head>
<title>Todo List</title>
</head>
<body>
<div id="render-target"></div>
</body>
if (Meteor.isClient) {
// This code is executed on the client only
Meteor.startup(function () {
// Use Meteor.startup to render the component after the page is ready
React.render(<App />, document.getElementById("render-target"));
});
}
// App component - represents the whole app
App = React.createClass({
// This mixin makes the getMeteorData method work
mixins: [ReactMeteorData],
// Loads items from the Tasks collection and puts them on this.data.tasks
getMeteorData() {
return {
tasks: Tasks.find({}).fetch()
}
},
renderTasks() {
// Get tasks from this.data.tasks
return this.data.tasks.map((task) => {
return <Task key={task._id} task={task} />;
});
},
render() {
return (
<div className="container">
<header>
<h1>Todo List</h1>
</header>
<ul>
{this.renderTasks()}
</ul>
</div>
);
}
});
// Define a collection to hold our tasks
Tasks = new Mongo.Collection("tasks");
if (Meteor.isClient) {
// This code is executed on the client only
Meteor.startup(function () {
// Use Meteor.startup to render the component after the page is ready
React.render(<App />, document.getElementById("render-target"));
});
}
// App component - represents the whole app
App = React.createClass({
// This mixin makes the getMeteorData method work
mixins: [ReactMeteorData],
// Loads items from the Tasks collection and puts them on this.data.tasks
getMeteorData() {
return {
tasks: Tasks.find({}, {sort: {createdAt: -1}}).fetch()
}
},
renderTasks() {
// Get tasks from this.data.tasks
return this.data.tasks.map((task) => {
return <Task key={task._id} task={task} />;
});
},
handleSubmit(event) {
event.preventDefault();
// Find the text field via the React ref
var text = this.refs.textInput.value.trim();
Tasks.insert({
text: text,
createdAt: new Date() // current time
});
// Clear form
this.refs.textInput.value = "";
},
render() {
return (
<div className="container">
<header>
<h1>Todo List</h1>
<form className="new-task" onSubmit={this.handleSubmit} >
<input
type="text"
ref="textInput"
placeholder="Type to add new tasks" />
</form>
</header>
<ul>
{this.renderTasks()}
</ul>
</div>
);
}
});
// Task component - represents a single todo item
Task = React.createClass({
propTypes: {
task: React.PropTypes.object.isRequired
},
toggleChecked() {
// Set the checked property to the opposite of its current value
Tasks.update(this.props.task._id, {
$set: {checked: ! this.props.task.checked}
});
},
deleteThisTask() {
Tasks.remove(this.props.task._id);
},
render() {
// Give tasks a different className when they are checked off,
// so that we can style them nicely in CSS
const taskClassName = this.props.task.checked ? "checked" : "";
return (
<li className={taskClassName}>
<button className="delete" onClick={this.deleteThisTask}>
&times;
</button>
<input
type="checkbox"
readOnly={true}
checked={this.props.task.checked}
onClick={this.toggleChecked} />
<span className="text">{this.props.task.text}</span>
</li>
);
}
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment