Add javascript code into the rails app - ruby-on-rails-4.2

Actually, I'm having trouble adding javascript code into my rails application.
I tried putting the import.js in "app/assets/javascripts" as well and it didn't work either.
I also added, //= require import at the end of application.js file but still not working.As a result the whole application got stucked.
index.html.erb
TEST
<div id = "test">
<h2>Import Statements</h2>
<%= form_tag import_samples_path, multipart: true do %>
<%= file_field_tag :file %>
<%= submit_tag "Import" %>
<% end %>
</div>
sample.coffee
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/
$( document ).ready(function() {
$("div#test").hide();
$("a").click(function(event) {
event.preventDefault();
$("div#test").toggle();
});
});
application.js
// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file.
//
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require bootstrap-sprockets
//= require nicetitle
Thanks in advance.

A couple of things here:
First off - you need to have a //= require_tree . inside of your application.js file. What this does is automatically requires all of the files inside of your javascripts directory.
Next, (and I'm not entirely sure that this is best practice) the way that I call javascript inside of a html.erb file is inside of a <script> tag. I'll put an example of my code below. I only very recently figured out how to call JS from inside of html in rails, so like I said this is probably not best practice, but this is how I did it.
<script language="javascript" type="text/javascript">
var counts = ['Count']
var dates = ['x']
<% #chart.datasource.datapoints.each do |c| %>
dates.push( "<%= c.date %>" )
counts.push( <%= c.count %> )
<% end %>
chart(counts, dates);
</script>
So I actually put it inside of a script tag like you saw. Hopefully this helps.

Related

Optional include in ejs

Can I optionally include a partial if only it exists?
For example,
<%- include('some-template'); %>
should be complied to:
if some-template.ejs exists:
// content of some-template.ejs
if some-template.ejs does not exist:
// nothing
Currently, it throws an error if the partial not exists, like:
ENOENT: no such file or directory, open 'some-template'
Just enclose it with a if that checks the existence of the file:
<% if (fs.existsSync('views/some-template.ejs')) { %>
<%- include('some-template'); %>
<% } %>
Make sure your 'views' folder match the path inside the condition.
Also, you must send the fs object to the engine, so that it can be used in the scriptlet of the parent template:
res.render("main-template", {
fs: fs
});

Use console.log in EJS

Is it possible to use console.log in a node / ejs template? It doesn't seem to do anything when I try, even something as simple as:
<% console.log('test') %>
I've also tried:
<%= console.log('test') %>
Nothing shows up in the console.
I think you are expecting it to show in the developer console. It will not show up there.
console.log() in EJS file will show the log in the terminal where the server is running.
This worked perfectly
<% console.log('heheeh', JSON.stringify(doc, null, '\t')) %>
console.log() is working fine, but its log does not display in dev tools.
So, check your terminal first:
<% console.log("test") %>
It's perfect.
console.log(test) in ejs file will show the log in the terminal
And if you want to see test object or value in browser than try
<%= test %>
This will show objects as string
I know this is a really old thread, but I just had this issue and this is what I ended up doing:
<% var data = JSON.stringify(htmlWebpackPlugin) %>
<script>
console.log(<%= data %>)
</script>
It doesn't look pretty, but it works
Code
Output
<% console.log(posts) %>
NB: Make sure you define your variable in any other file you have eg app.js file...
let posts = [];
app.get("/", (req, res) => {
res.render("home", {
posts: posts
});
});
OUTPUT
Click me
first, Your home route inside your index.js/server.js/app.js, render a variable you want console log in another ejs file; in the code below, nposts is a variable or an array;
app.get("/",function(req,res){
res.render("home", {posts: nposts});
then in your ejs file, in this example in the home.ejs console.log in the <% %> tags
<% console.log(posts); %>
send from serve-side
let item = [arr1, arr2, arr3]
res.send("index", { item })
in client-side
example
use in script
console.log('<%- item %'>
arr1,arr2,arr3
console.log('<%- JSON.stringify( item ) '%>
["arr1","arr2","arr3"] //text
var newArray = JSON.parse('<%- JSON.stringify( item )%>')
console.log(newArray )
<% { %>
<script>console.log('hello')</script>
<% } %>
this code is work well.
create { } by <% %> from ejs.
We can add javascript code inside { }.
The simple answer would be:
If you are in your home route and you want to test any condition you would have to use ejs tags. inside the tags drop your normal console.log.
<% console.log(test) %>

How to write a lodash template loader for requirejs

I'm using a requirejs plugin to define "tmpl!" loader (not a jquery template, but a lodash template. The problem is that the text! loader is adding a ";" at the end of the template. This is being rendered and is breaking everything.
(function(global){
"use strict";
define({
load : function(name, require, load, config) {
var deps = [];
deps.push('text!' + name);
deps.push('underscore');
require(deps, function(source, _) {
var template = _.template(source);
load(template);
});
}
});
})(this);
How can I stop text! from adding a semi-colon? Or: is there a better way to do this?
Taking the questions in reverse order:
is there a better way to do this?
It seems there is an existing implementation of this, and you might want to consider using it rather than writing your own. Although the simple case is a small amount of code, there are a bunch of r.js optimizer-related things you might eventually need.
But regarding your implementation logic, I noticed that this similar project for Handlebars does not use the text! plugin but instead does its own XHR in the load() method. This is not explained, but he gives some guidance for adapting it to other templating languages. Note: the link came from this question where there is some other good discussion of the approach.
How can I stop text! from adding a semi-colon?
I tried your plug-in and did not get any added semicolons. Perhaps you could post more of the sample project and templates? Below is mine, with everything in one flat folder for simplicity:
require.js: latest from RequireJS site
domReady.js: latest from RequireJS site
text.js: latest from RequireJS site
lodash.js: latest from lodash site
tmpl.js: your example loader from the question
index.html:
<!DOCTYPE html>
<html>
<head>
<script src='require.js'></script>
<script>
requirejs.config({
map: {
'*': { 'underscore': 'lodash' }
}
});
require( [ 'underscore', 'tmpl!friend-template.htm', 'domReady!' ]
, function( _, friendTemplate ){
var friendsData = [{ name: 'Bob', age: 35 }, { name: 'Fred', age: 38 }];
document.body.innerHTML = friendTemplate( {friends: friendsData});
});
</script>
</head>
<body>
<!-- To be populated dynamically. -->
</body>
</html>
friend-template.htm:
<ul>
<% _.forEach(friends, function(friend) { %>
<li>
<span><%- friend.name %></span>
<span>( Age: <span class="value"><%- friend.age %></span> )</span>
</li>
<% }); %>
</ul>
I've created a loader specifically for Lo-Dash which you can see here:
https://gist.github.com/tbranyen/6821045
Note: I have no unit tests or assurances this free of bugs, but from my initial testing it appears to work fantastic.
This is better in a number of ways than requirejs-tpl which bakes in it's own implementation which is not exposed. It also requires a file extension and hardcoded path. Both of these are configurable in my code.
Edit: I've since released a project called lodash-template-loader which has tests. https://github.com/tbranyen/lodash-template-loader

Inside Express/EJS templates, what is cleanest way to loop through an array?

I have an Express.js app set up using EJS templates. I successfully looped through an array with classic JS syntax:
<% for (var i = 0; i < myArray.length; i++) {
this = myArray[i];
// display properties of this
} %>
But I'm wondering, is there a cleaner way to do this?
Specifically, can I use Underscore or Lodash to loop through with .each ? thank you
You can use forEach method
myArray.forEach(function(el, index) {
// el - current element, i - index
});
#wachme's answer is correct, but to stick with the original question, here is the version using Underscore's _.each (and integrated in template syntax):
<% _.each(myArray, function(el, index) { %>
Value is <%= el %>, index is <%= index %>.
<% }) %>
The advantage of Array.prototype.forEach is that you don't need to depend on Underscore in your templates. The advantage of _.each is that it has some additional tricks up its sleeves (for example, it also works on objects) and that it works in older JS environments without any need for polyfills.
As an aside, Underscore's _.template can be used instead of EJS, although it has fewer features. Also, the meaning of <%= and <%− is swapped between the two libraries. Naturally, you can always use _.each in Underscore templates.

Using interpolation within Node.js EJS includes

My Express app is using EJS, and my views directory looks like this:
./views
./contents
home.ejs
./includes
header.ejs
footer.ejs
layout.ejs
I'm trying to load home.ejs in my layout.ejs view conditionally based on a local variable named contents in my routes/index.js. That file looks like this:
/*
* GET home page.
*/
exports.index = function(req, res){
res.render('index', { title: 'Home', contents: 'home.ejs' });
};
Ideally I could simply write (in layout.ejs):
<% include '/contents' + contents %>
where the trailing "contents" is the local variable which contains the relative path to the body text to load.
But alas, it appears EJS always interprets the text following an include directive literally, and there is no chance for any interpolation magic to happen.
I've also tried to no avail:
<% function yieldContent(contents){ %>
<% var contentPath = 'contents/' + contents; %>
<% include contentPath %>
<% }; %>
<% loadContent(); %>
Does anyone have a creative solution for conditionally including a view based on a variable passed in routes?
I think there is no way to do this kind of dynamic includes in EJS. It might break the separation of business logic and view.
The solution can be to rendering the subtemplate in the controller, and passing its content to the layout.
For rendering subtemplate in the controller use something like this:
var ejs = require('ejs'),
, fs = require('fs')
, home = ejs.render(fs.readFileSync("contents/home.ejs", "utf-8"))
In the version 2 of EJS, the include function does it well. With it, includes are inserted at runtime so variables can be used as pathnames.
In this case, the solution may be :
<%- include('contents/' + contents) %>
The function can also have another argument if necessary :
<%- include('mypathname', {foo:"bar"}) %>
The pathname has to be relative to the template which calls the function.
Currently this hasn't been implemented into ejs but, there is this discussion and pull request that offers the functionality.
https://github.com/visionmedia/ejs/issues/93
in your render function you can include fs.readFileSync and __dirname.
Render your page with options like this
res.render('pages/'+req.file,{file_get_contents:fs.readFileSync,__dirname:__dirname});
Then you can use it in your .ejs page like this. This remains in server side.
<% var products=JSON.parse(file_get_contents(__dirname+'/web/data/products.json','utf8')) %>
You can print the data on client HTML like this.
<%- JSON.stringify(products)%>
Note : Using this method means you have fs included somewhere at the top of your script.
var fs = require('fs')

Resources