I need to know about the below shown Issue :
JS Code:
Template.main.helpers({
ItemName: function() {
var self = this;
console.log("helpers : " +self.fieldoptions);
return _.map(self.fieldoptions,function(p)
{
p.parent = self;
return p;
});
}
});
HTML Code :
{{#each ItemName}}
{{this.parent.fname}}
{{/each}}
The above Js return code doesn't show the html.So how to show the above return code in HTML.I didn't get any idea about this.So please help me?
Its not clear to me so I'll write what I think is happening. You should have at least 2 files on your meteor directory (the one created with meteor create)
template.main.html that if you are not using any router to make the template append to the body should look like
<head>
<title>My title</title>
</head>
<body>
{{> templateMain}}
</body>
<template name="templateMain">
{{#each ItemName}}
{{fname}}
{{/each}}
</template>
template.main.js with something around these lines
FieldNames = new Meteor.Collection('fieldname');
if( Meteor.isServer && FieldNames.find().count() === 0)
_.each(['one','two','three','four'], function(value, index){
FieldNames.insert({ fname : value, index : index });
});
if(Meteor.isClient){
Template.main.helpers({
ItemName: function() {
return FieldNames.find();
}
});
}
So what I think was happening was that you didn't include the template on the body.
Let me know if something is not clear.
Related
Update Edited my original code due to errors.
This is my first question posted here so please be gentle. :)
I am using node.js with Express and EJS forms.
What I am trying to achieve is to have an EJS template re-rendered after a jQuery POST request with new data. This is a simplified example of what I am trying to do (my original code includes a lot of fuss, SQL queries and is not properly refactored).
My goal would be to render the same template with different data when pressing a button on the page. What happening currently is when I press the button, the data is there (checking it in console), but the page does not render again with the new data. I am completely out of ideas and been stuck with this for almost a day now.
I know I could do something like
res.send(JSON.stringify(myData));
and build the HTML with a JS script, but it would be nice to be able to use EJS for better readability - my original code includes a lot of HTML elements.
Is it doable at all? Or is this an intended behaviour for rendering with Express? Sorry if I am being clueless, as I am fairly new to web development.
Anyway, here is my code, all ideas are greatly appreciated. Thanks!
test_dynamic.ejs:
<html>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form method="post" action="/test">
<wrapper>
<h1>
<button id="toggleButton" onclick="toggle()" type="button">Toggle</button>
</h1>
<div>
<% console.log('Should show ' + name + ' with id: ' + id) %>
<li><%=name %></li>
<li><%=id %></li>
</div>
</wrapper>
</form>
</html>
<script>
var shouldShowJohn = false;
function toggle () {
var postData = {};
shouldShowJohn = !shouldShowJohn;
if (shouldShowJohn)
postData.mode = 1;
else
postData.mode = 2;
$.post('http://localhost:3000/test', postData, function (data) {
$('#toggleButton').html('').append('Showing ' + postData.mode);
});
}
</script>
routes.js:
router.get('/test', (req, res) =>{
var obj = {
name: 'DefaultName',
id: 1
}
res.render('test_dynamic', obj);
})
router.post('/test', (req, res) => {
var obj = {};
console.log('req.body.mode: ' + req.body.mode);
if (req.body.mode == 1)
obj = {
name: 'John',
id: 2
}
else
obj = {
name: 'Karl',
id: 3
}
res.render('test_dynamic', obj)
})
Please take a look at the example I've included via link below. There is a lot wrong with your HTML above, but I will focus on your question. There are several ways you can solve this problem so this is the simplest.
As stated in my comment, the workflow is:
Send POST
Respond with success/failure
If success, redirect/re-request same page from server.
Note I am not addressing EJS because when you request the page from the server that will happen naturally as you have laid out above.
Step 1: So in the sample, index.js is the server, I have basic routing to two files, index.html and page2.html. I did this so you can see the change happening. Next, in the index.html file I have a button that generates the POST request via jQuery. This takes care of step 1.
Step 2: index.js accepts the post request to /test and responds with a simple string "success" (you could respond with anything)
Step3: In index.html the $.post() handler tests for the string 'success' and the redirects to page2.html. In your scenario this would redirect back to the same page. I made it different so you could realize the change easily.
Solution
https://repl.it/#randycasburn/SimplePostResponseRedirect
Here is my solution, partially based on Randy's answer.
test_dynamic.ejs:
<html>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<body id="myBody">
<form method="post" action="/test">
<wrapper>
<h1>
<button id="toggleButton" onclick="toggle()" type="button">Toggle</button>
</h1>
<div>
<% console.log('Should show ' + name + ' with id: ' + id) %>
<li><%=name %></li>
<li><%=id %></li>
</div>
</wrapper>
</form>
</body>
</html>
<script>
var shouldShowJohn = false;
var postData = {};
postData.mode = 'toggle';
function toggle () {
$.post('http://localhost:3000/test', postData, function (data) {
$('#toggleButton').html('').append('Showing ' + postData.mode);
$('#myBody').html(data);
});
}
</script>
routes.js:
router.get('/test', (req, res) =>{
var obj = {
name: 'DefaultName',
id: 1
}
res.render('test_dynamic', obj);
})
var currentMode = 1;
router.post('/test', (req, res) => {
var obj = {};
console.log('req.body.mode: ' + req.body.mode);
if (req.body.mode == 'toggle')
if (currentMode < 3)
currentMode++;
else
currentMode = 1;
if (req.body.mode == 1)
obj = {
name: 'John',
id: 2
}
else
obj = {
name: 'Karl',
id: 3
}
res.render('test_dyanmic', obj)
})
Stuck with javascipt's knockout library.
So, I want to implement simple forum. I have javascript file with two ajax requests, for topics and for posts. And I have html template.
function dealModel() {
var self = this;
self.board = ko.observableArray([]);
var res = [];
$.getJSON("http://someaddress/threads", function(data) {
$.each(data, function(i, thread) {
var js = jQuery.parseJSON(thread);
js.posts = ko.observableArray([]);
var postres = []
$.getJSON("http://someadress/posts/" + js.id, function(postdata) {
$.each(postdata, function(idx, post){
var jspost = jQuery.parseJSON(post);
postres.push(jspost);
})
})
js.posts(postres);
res.push(js);
})
self.board(res);
})
}
$(document).ready(function(){
ko.applyBindings(new dealModel());
});
var testdata = [{text : "text 1"} , {text : "text2"}]
This is my js code. It perfectly works with topics, but when I put my posts, my observable array "posts" already empty.
For test I created test array "testdata" (below), and pass in my observable array. And, javascript work perfectly.
Here is my template
<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/knockout/knockout-3.3.0.js"></script>
<script type="text/javascript" src="ajaxknockout.js"></script>
</head>
<body>
<div class='board'>
<div class='threads' data-bind="foreach: board">
<p data-bind="text: title"></p>
<div class= "posts" data-bind="foreach: $data.posts">
<p data-bind="text: text"> </p>
</div>
</div>
</div>
</body>>
</html>
So, I think something bad with my posts JSON.
Here it is.
["{\"createTime\": \"Monday, 04. January 2016 05:53PM\",\"thread_id\": \"2\",\"text\": \"post 1\",\"id\": \"4\"}", "{\"createTime\": \"Monday, 04. January 2016 05:53PM\",\"thread_id\": \"2\",\"text\": \"post 2\",\"id\": \"5\"}", "{\"createTime\": \"Monday, 04. January 2016 05:53PM\",\"thread_id\": \"2\",\"text\": \"post 3\",\"id\": \"6\"}"]
SO, I have a question. Whats wrong with my code? Why knockout understand my testdata, but completly reject production data?
That's because this part of your first json request:
js.posts(postres);
executes ahead of callback from your second json request where you are pulling posts. You have to change that so the posts array is populated before doing js.posts(postres);, e.g like so:
$.getJSON("http://someadress/posts/" + js.id, function(postdata) {
$.each(postdata, function(idx, post){
var jspost = jQuery.parseJSON(post);
postres.push(jspost);
})
js.posts(postres);
})
I need to display data to all clients using Meteor.publish/subscribe.I did one sample example in that example what i am did is 10 records are inserted at that time of server startup and these 10 records are trying to display to all clients.The Problem is The data doesn't shows the clients.I didn't have any idea because i am new to meteor JS.So Please see the below code and suggest me how to do?
HTML Code :
<head>
<title>DataApp</title>
</head>
<body>
{{> main}}
</body>
<template name="main">
{{#each messages}}
{{messages}}
{{/each}}
</template>
ANd JS Code is :
Messages = new Meteor.Collection("messages");
if (Meteor.isClient)
{
Meteor.subscribe('messages');
}
if (Meteor.isServer)
{
Meteor.startup(function ()
{
// code to run on server at startup
for(var i = 0 ; i <= 10 ; i++ )
{
console.log("EXE"+i);
Messages.insert({ name: "EXE"+i });
}
});
Meteor.publish('messages', function() {
return Messages.find();
});
}
Firstly, you are missing a template helper on your template main, so make your Meteor.isClient look like this:
if (Meteor.isClient) {
Meteor.subscribe('messages');
// this is the template helper that is referenced by {{messages}}
// in your template 'main'
Template.main.messages = function () {
return Messages.find();
};
}
Secondly, the handlebars in your html don't make sense, try this instead:
<template name="main">
<!-- inserts value of property 'name' of each object in 'messages' -->
{{#each messages}}
{{name}}
{{/each}}
</template>
I've got a setup like this in Ember:
App.ListObject = Ember.Object.create({
knownThings: function() {
var ot = this.openThings.get('content');
var ct = this.closedThings.get('content');
var kt = ot.concat(ct);
var known = Ember.ArrayController.create({content: kt});
return known;
}.property(),
openThings: Ember.ArrayController.create({
content: []
}),
closedThings: Ember.ArrayController.create({
content: []
}),
})
Basically, known things is the combined arrays of openThings and closedThings. I can't seem to figure out how to iterate over knownThings in the template. Just doing
{{#each App.ListObject.knownThings }}
Does not work as the property needs to be accessed like App.ListObject.get('knownThings') but that doesn't work in the template unless I'm doing something terribly wrong. Iterating over the other attributes in the template does work (open and closed things)
So, how would you iterate over knownThings in the template?
Slight Modifications needed...
Firstly,
knownThings: function() {
//use get to retrieve properties in ember, Always !
var ot = this.get('openThings').get('content');
//var ot = this.get('openThings.content') if you are using latest ember
var ct = this.get('closedThings').get('content');
//var ot = this.get('closedThings.content') if you are using latest ember
var kt = ot.concat(ct);
var known = Ember.ArrayController.create({content: kt});
return known;
//Add dependencies to keep your knownThings in sync with openThings & closedThings if at all they change in future
}.property('openThings', 'closedThings')
Coming to Handlebars iterate using
//you forgot content property, and in handlebars you don;t need to use get, dot operator is enough
{{#each App.List.knownThings}}
Let me know if this works...
Update
Working Fiddle...
Unless I didn't understand what you're saying, I think you should have ListObject extending Em.ArrayController instead of Em.Object. Also, if your property depends on content, it should be .property('content.#each'). If you're using the router, your template should look like {{#each thing in controller.knownThings}} and you use {{thin.something}}, if not using router, then {{#each item in App.listObject.knownThings}}. Also, openThings and closedThings don't seem to be correct and the way you're accessing them is wrong too.
I didn't write a fiddle for this specific case cause I don't really know what you're trying to do, but take a look at this fiddle, specifically at App.ResourcesController and the template 'resources-view':
Controller:
// ...
App.ResourcesController = Em.ArrayController.extend({
content: [],
categories: ['All', 'Handlebars', 'Ember', 'Ember Data', 'Bootstrap', 'Other'],
categorySelected: 'All',
filtered: function() {
if(this.get('categorySelected') == "All") {
return this.get('content');
} else {
return this.get("content")
.filterProperty(
"category",
this.get('categorySelected')
);
}
}.property('content.#each', 'categorySelected'),
filteredCount: function() {
return this.get('filtered').length;
}.property('content.#each', 'categorySelected'),
hasItems: function() {
return this.get('filtered').length > 0;
}.property('filteredCount')
);
// ...
Template:
<script type="text/x-handlebars" data-template-name="resources-view">
<h1>Ember Resources</h1>
{{#view Bootstrap.Well}}
The following is a list of links to Articles, Blogs, Examples and other types of resources about Ember.js and its eco-system.
{{/view }}
{{view Bootstrap.Pills contentBinding="controller.controllers.resourcesController.categories" selectionBinding="controller.controllers.resourcesController.categorySelected"}}
<i>{{controller.filteredCount}} Item(s) Found</i>
{{#if controller.hasItems}}
<ul>
{{#each resource in controller.filtered}}
<li>
<a {{bindAttr href="resource.url"
target="resource.target"
title="resource.description"}}>
{{resource.htmlText}}
</a>
</li>
{{/each}}
</ul>
{{else}}
{{#view Bootstrap.AlertMessage type="warning"}}
Couldn't find items for {{controller.categorySelected}}
{{/view}}
{{/if}}
</script>
I am new to scala as well as Java Play. I was looking at a code which looks like this but I am getting the above error. I am unable to fix this despite adding the curly braces etc. Any help is much appreciated.
Sorry I forgot to mention that the error shows up in #main. Even as I replace Some(username) with #main(username) there is no respite. routes this is how the relevant code looks
conf/routes
GET /Login controllers.Application.Login(username:String)
app/view/Login.scala.html looks like this
#(username: String)(implicit request: RequestHeader)
#main(Some(username)) {
<div class="page-header">
<h1>Login <small>You are Logging in as #username</small></h1>
</div>
<div id="onError" class="alert-message error">
<p>
<strong>Oops!</strong> <span></span>
</p>
</div>
<script type="text/javascript" charset="utf-8">
$(function() {
var WS = window['MozWebSocket'] ? MozWebSocket : WebSocket
var loginSocket = new WS("#routes.Application.UserLogin(username).webSocketURL()")
var receiveEvent = function(event) {
var data = JSON.parse(event.data)
// Handle errors
if(data.error) {
loginSocket.close()
$("#onError span").text(data.error)
$("#onError").show()
return
} else {
$("#onChat").show()
}
}
})
</script>
}
According to the error message, you have provided Some[String] where play.api.templates.Html is expected. The most likely candidate based on the code you've provided is:
#main(Some(username)) {
Based on that I would replace it with:
#main(Html(username)) {
That assumes that the first parameter of the main view is of type Html.