How to use JS functions from an EJS file - javascript

I was wondering how I would do it; use a function written in a external javascript file and then use it in ejs.
Here's the code;
<head>
<script src="https://code.jquery.com/jquery-3.3.1.js" integrity="sha256-2Kok7MbOyxpgUVvAk/HJ2jigOSYS2auK4Pfzbm7uH60=" crossorigin="anonymous"></script>
<script src="//gitcdn.link/repo/wintercounter/Protip/master/protip.min.js"></script>
<script src='/javascripts/index.js'></script>
<link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.3.1/css/all.css" integrity="sha384-mzrmE5qonljUremFsqc01SB46JvROS7bZs3IO2EmfFsd15uHvIt+Y8vEf7N7fWAU" crossorigin="anonymous">
<link rel="stylesheet" href="//gitcdn.link/repo/wintercounter/Protip/master/protip.min.css">
<link rel='stylesheet' href='/stylesheets/style.css'/>
<link href="https://fonts.googleapis.com/css?family=Work+Sans" rel="stylesheet">
</head>
<body>
<% include header %>
<section class='header-placeholder'></section>
<section class='game'>
<% items.forEach(function(item){ %>
<% hi(); %>
<% }); %>
</section>
<% include footer %>
</body>
I'm trying to call the function hi() which is written in index.js like so;
function hi(){
console.log('hello');
}
is there any way I can access this function, or could I somehow have the function in ejs and access it from js?

Related

Could not find matching close tag for "<%"

I am trying to access variables passed from the server to the client with ejs
My server file:
router.get('/', function (req, res, next) {
res.render('chat', {user: req.user, message: null});
});
My client file:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" const="text/html;charset=UTF-8"/>
<link href="http://fonts.googleapis.com/css?family=Comfortaa" rel="stylesheet" type="text/css">
<link rel="stylesheet" type="text/css" href="style.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.4/socket.io.js"></script>
<title>Simple Chat App</title>
</head>
<body>
<header>
<h1>Super Chat</h1>
</header>
<section>
<div id="change_username">
<input id="username" type="text"/>
<button id="send_username" type="button">Change username</button>
</div>
</section>
<section id="chatroom">
<section id="feedback"></section>
</section>
<section id="input_zone">
<input id="message" class="vertical-align" type="text"/>
<button id="send_message" class="vertical-align" type="button">Send</button>
</section>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript">
<% var user = <% user %> %>
console.log(user);
</script>
<script src="chat.js"></script>
</body>
</html>
I get an error:
Could not find matching close tag for "<%".
How do I fix this?
<% var user = <% user %> %>
You can't nest <% %> blocks. You are either inside EJS mode or outside it. You can't go into Extra Deep EJS Mode.
Aside, you also can't just output a variable into client-side JS. You need to generate JavaScript source code from the variable. JSON.stringify is a good way to generate object, array and string literals from objects, arrays and strings.
<script>
const user = <%- JSON.stringify(user); %>
console.log(user);
</script>
Note that use of <%- to output without escaping for HTML.
The problem is here, you just have to replace the value of the user in the template.
var user = "<%=user%>" // Please change this line
Updated Code
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" const="text/html;charset=UTF-8"/>
<link href="http://fonts.googleapis.com/css?family=Comfortaa" rel="stylesheet" type="text/css">
<link rel="stylesheet" type="text/css" href="style.css">
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.4/socket.io.js"></script>
<title>Simple Chat App</title>
</head>
<body>
<header>
<h1>Super Chat</h1>
</header>
<section>
<div id="change_username">
<input id="username" type="text"/>
<button id="send_username" type="button">Change username</button>
</div>
</section>
<section id="chatroom">
<section id="feedback"></section>
</section>
<section id="input_zone">
<input id="message" class="vertical-align" type="text"/>
<button id="send_message" class="vertical-align" type="button">Send</button>
</section>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script type="text/javascript">
var user = "<%= user %>" // problem is here
console.log(user);
</script>
<script src="chat.js"></script>
</body>
</html>
I Hope this helps you.
it says that it cannot find closing tag for your ejs template.
you don't need the surrounding ejs template notation in script.
<script type="text/javascript">
var user = '<%= user %>'
console.log(user);
</script>
Try this.
GOOD LUCK. :)

JavaScript will not run at all

I have this template as my sinatra layout.erb
<!DOCTYPE html>
<html>
<head>
<title>Invoicer</title>
<link rel="stylesheet" href="/static/css/bootstrap.min.css">
<link rel="stylesheet" href="//code.jquery.com/ui/1.12.1/themes/base/jquery-ui.css">
<link rel="stylesheet" href="/static/css/font-awesome.min.css">
</head>
<body>
<nav class="navbar navbar-default">
...
</nav>
<div class="container">
<%= yield %>
</div>
<%#<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>%>
<script src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script src="http://code.jquery.com/ui/1.10.2/jquery-ui.js"></script>
<script src="/static/js/bootstrap.min.js"/>
<script src="/static/js/jobs/new.js" />
</body>
</html>
and this small javascript call
console.log("running")
$('#datepicker').datepicker()
the server gets a 200 call to the js file but nothing will print to the console or execute.
Always use <script></script>.
<script src="..." /> is not a valid tag. When the HTML is parsed, it thinks that <script src="/static/js/jobs/new.js" /> is in the body of the <script src="/static/js/bootstrap.min.js"/> tag like this:
...
<script src="/static/js/bootstrap.min.js">
<script src="/static/js/jobs/new.js">
...
From MDN <script> documentation:
Tag omission
None, both the starting and ending tag are mandatory.

Mustache templating - Basic example not displaying and not throwing errors

I have been looking for a simple basic example of using a Mustache template where the Mustache markup and templating stays in the HTML document (separation of concerns).
Here is where I am at:
<html>
<head>
<meta charset="utf-8">
<title></title>
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mustache.js/2.3.0/mustache.js"></script>
</head>
<body>
<div class="container">
<h2>Here is a person</h2>
<template id="theTemplate">
{{name}}
</template>
</div>
<script>
$(function() {
template = $('#theTemplate').html();
data = {
name: 'billy'
};
Mustache.render(template, data);
});
</script>
</body>
</html>
No errors are being thrown but it is not working!
Mustache.render returns a string which is the amalgamation of the template and the data from the provided object. It does not do anything else with that string, so if you want to update the DOM you will still need to do that manually. As you're using jQuery you can use append() to do that:
$('h2').append(Mustache.render(template, data));
However, it would make more sense to include the whole h2 text value in the template to at least make its use worthwhile:
$(function() {
template = $('#theTemplate').html();
data = { name: 'billy' };
$('h2').text(Mustache.render(template, data));
});
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/mustache.js/2.3.0/mustache.js"></script>
<div class="container">
<h2></h2>
<template id="theTemplate">
Here is a person named {{name}}
</template>
</div>

difference between putting scripts in body or outside body

I have this structure now:
<!DOCTYPE html>
<html>
<head>
<!-- stylesheets-->
<link rel='stylesheet' href='/static/stylesheets/style.css'/>
<link href='http://fonts.googleapis.com/css?family=Open+Sans:400,700,600,300' rel='stylesheet' type='text/css'>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css">
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap-theme.min.css">
<link href="/static/css/bootstrap/bootstrap-notify.css" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="/static/css/portal/simple-sidebar.css" media="screen" />
<link rel="stylesheet" type="text/css" href="/static/css/userProfileView/user-profile.css" media="screen" />
</head>
<body>
<main>
<div name="main-div" id="main-div-id"></div>
</main>
</body>
<% if(env == 'development') {%>
<script data-main="/static/app/js/main" src="/static/vendor/require.js"></script>
<% } else { %>
<script src="/static/app/optimized/optimized.js"></script>
<% } %>
</html>
as you can see, my javascripts are "at the bottom" but they are outside the body tags, not inside.
I am sure it makes a difference, but I am not sure what difference it makes to put the scripts outside the <head> and outside the <body> tags.
At first I thought I remembered that <head> and <body> was optional and that therefore it's okay to place <script> in <html>, but it's only partially true.
<script> isn't allowed inside of <html> because <html> may only contain <head> and <body>.
However if you don't declare <body> or <head> the browser will implicitly create them for you (under the right conditions). I.e. this is invalid:
<html>
<head></head>
<body><body>
<script>console.log('test')</script>
</html>
This is implicitly creates a body element which the script tag is part of:
<html>
<head></head>
<script>console.log('test')</script>
</html>
This implicitly creates a head element which the script tag is part of:
<html>
<script>console.log('test')</script>
</html>
So no, you should never place a <script> after </body>

Using a jQuery plugin in a Rails application

I'm currently trying to set up a very basic lightbox effect for a login in a Rails application. I'm using a the plugin Lightbox Evolution. Usage is as follows per the directions:
Make sure it is a valid DOCTYPE.
Include the jQuery library lightbox CSS and the lightbox js file in the head of the pages where you want to use the lightbox
Initialize the plugin:
<script type="text/javascript"
jQuery(document).ready(function($){
$('.lightbox').lightbox();
});
</script>
The jquery.lightbox.min.js and jquery.lightbox.css are located in the vendor/assets/javascripts and vendor/assets/stylesheets directories respectively.
I've included the lightbox script in the application.html.erb file since I plan on using the lightbox effect on other places on the site.
My application.html.erb file looks like:
<!DOCTYPE html>
<html>
<head>
<title>Test App</title>
<%= stylesheet_link_tag "application", :media => "all" %>
<%= stylesheet_link_tag "jquery.lightbox.css", :media => "all" %>
<%= javascript_include_tag "application" %>
<%= javascript_include_tag "jquery.lightbox.min" %>
<%= csrf_meta_tags %>
</head>
<body>
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>
<%= yield %>
<script type="text/javascript">
jQuery(document).ready(function($){
$('.lightbox').lightbox();
});
</script>
</body>
</html>
My landing page is app/views/welcome/index.html.erb:
<h1>Landing Page</h1>
Login
and I use the class "lightbox" per the instructions.
When I go to localhost:3000, the html is built as follows in development environment:
<!DOCTYPE html>
<html>
<head>
<title>MetaLinx Material Management</title>
<link href="/assets/application.css?body=1" media="all" rel="stylesheet" type="text/css" />
<link href="/assets/bootstrap_and_overrides.css?body=1" media="all" rel="stylesheet" type="text/css" />
<link href="/assets/containers.css?body=1" media="all" rel="stylesheet" type="text/css" />
<link href="/assets/scaffolds.css?body=1" media="all" rel="stylesheet" type="text/css" />
<link href="/assets/scales.css?body=1" media="all" rel="stylesheet" type="text/css" />
<link href="/assets/welcome.css?body=1" media="all" rel="stylesheet" type="text/css" />
<link href="/assets/jquery.lightbox.css?body=1" media="all" rel="stylesheet" type="text/css" />
<script src="/assets/jquery.js?body=1" type="text/javascript"></script>
<script src="/assets/jquery_ujs.js?body=1" type="text/javascript"></script>
<script src="/assets/twitter/bootstrap/bootstrap-transition.js?body=1" type="text/javascript"></script>
<script src="/assets/twitter/bootstrap/bootstrap-alert.js?body=1" type="text/javascript"></script>
<script src="/assets/twitter/bootstrap/bootstrap-modal.js?body=1" type="text/javascript"></script>
<script src="/assets/twitter/bootstrap/bootstrap-dropdown.js?body=1" type="text/javascript"></script>
<script src="/assets/twitter/bootstrap/bootstrap-scrollspy.js?body=1" type="text/javascript"></script>
<script src="/assets/twitter/bootstrap/bootstrap-tab.js?body=1" type="text/javascript"></script>
<script src="/assets/twitter/bootstrap/bootstrap-tooltip.js?body=1" type="text/javascript"></script>
<script src="/assets/twitter/bootstrap/bootstrap-popover.js?body=1" type="text/javascript"></script>
<script src="/assets/twitter/bootstrap/bootstrap-button.js?body=1" type="text/javascript"></script>
<script src="/assets/twitter/bootstrap/bootstrap-collapse.js?body=1" type="text/javascript"></script>
<script src="/assets/twitter/bootstrap/bootstrap-carousel.js?body=1" type="text/javascript"></script>
<script src="/assets/twitter/bootstrap/bootstrap-typeahead.js?body=1" type="text/javascript"></script>
<script src="/assets/twitter/bootstrap/bootstrap-affix.js?body=1" type="text/javascript"></script>
<script src="/assets/twitter/bootstrap.js?body=1" type="text/javascript"></script>
<script src="/assets/bootstrap.js?body=1" type="text/javascript"></script>
<script src="/assets/containers.js?body=1" type="text/javascript"></script>
<script src="/assets/jquery.ui.effect.js?body=1" type="text/javascript"></script>
<script src="/assets/jquery.ui.core.js?body=1" type="text/javascript"></script>
<script src="/assets/jquery.ui.widget.js?body=1" type="text/javascript"></script>
<script src="/assets/jquery.ui.mouse.js?body=1" type="text/javascript"></script>
<script src="/assets/jquery.ui.sortable.js?body=1" type="text/javascript"></script>
<script src="/assets/jquery.ui.position.js?body=1" type="text/javascript"></script>
<script src="/assets/jquery.ui.menu.js?body=1" type="text/javascript"></script>
<script src="/assets/jquery.ui.autocomplete.js?body=1" type="text/javascript"></script>
<script src="/assets/jquery.ui.datepicker.js?body=1" type="text/javascript"></script>
<script src="/assets/rails_admin/jquery.ui.timepicker.js?body=1" type="text/javascript"></script>
<script src="/assets/rails_admin/ra.datetimepicker.js?body=1" type="text/javascript"></script>
<script src="/assets/rails_admin/jquery.colorpicker.js?body=1" type="text/javascript"></script>
<script src="/assets/rails_admin/ra.filter-box.js?body=1" type="text/javascript"></script>
<script src="/assets/rails_admin/ra.filtering-multiselect.js?body=1" type="text/javascript"></script>
<script src="/assets/rails_admin/ra.filtering-select.js?body=1" type="text/javascript"></script>
<script src="/assets/rails_admin/ra.remote-form.js?body=1" type="text/javascript"></script>
<script src="/assets/rails_admin/jquery.pjax.js?body=1" type="text/javascript"></script>
<script src="/assets/jquery_nested_form.js?body=1" type="text/javascript"></script>
<script src="/assets/rails_admin/ra.nested-form-hooks.js?body=1" type="text/javascript"></script>
<script src="/assets/rails_admin/ra.widgets.js?body=1" type="text/javascript"></script>
<script src="/assets/rails_admin/ui.js?body=1" type="text/javascript"></script>
<script src="/assets/rails_admin/custom/ui.js?body=1" type="text/javascript"></script>
<script src="/assets/rails_admin/rails_admin.js?body=1" type="text/javascript"></script>
<script src="/assets/scales.js?body=1" type="text/javascript"></script>
<script src="/assets/welcome.js?body=1" type="text/javascript"></script>
<script src="/assets/application.js?body=1" type="text/javascript"></script>
<script src="/assets/jquery.lightbox.min.js?body=1" type="text/javascript"></script>
<meta content="authenticity_token" name="csrf-param" />
<meta content="NGWSCp8qKAwi52ViQNfSP+2WG4teWxwOzCDCFfqQaLc=" name="csrf-token" />
</head>
<body>
<p class="notice"></p>
<p class="alert"></p>
<h1>Landing Page</h1>
<p>Find me in app/views/welcome/index.html.erb</p>
Login
<script type="text/javascript">
jQuery(document).ready(function($){
$('.lightbox').lightbox();
});
</script>
</body>
I'm using devise for authentication, so it sets up the routes for users/sign_in. When I click the link above, it takes me to the page users/new, but it does not pop-up in the lightbox. the generated html looks like:
app/views/sessions/new.html.erb:
<h2>Sign in</h2>
<%= form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f| %>
<div><%= f.label :email %><br />
<%= f.email_field :email, :autofocus => true %></div>
<div><%= f.label :password %><br />
<%= f.password_field :password %></div>
<% if devise_mapping.rememberable? -%>
<div><%= f.check_box :remember_me %> <%= f.label :remember_me %></div>
<% end -%>
<div><%= f.submit "Sign in" %></div>
<% end %>
<%= render "devise/shared/links" %>
So the question is what am I doing wrong so that when I click the "Login" link in app/views/welcome/new.html.erb it take me to the login page rather than popping it up using the lightbox jQuery?
Try change href="users/sign_in" to href="#". Since the link really doesn't matter if you just wanna click on it and let lightbox pops out the login form.

Categories