简体   繁体   中英

How to use jquery with my Node.js EJS template?

SITUATION:

I am trying to implement the first answer (with 25 upvotes) to this question: How can I make an Upvote/Downvote button? with my Node.js ejs template.

So I wrote this code.


MY CODE:

Main.js

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

$('.UpvoteButton').click(function () {
  $(this).toggleClass('on');
});

$('.DownvoteButton').click(function () {
  $(this).toggleClass('on');
});

style.css

.UpvoteButton {
    display: inline-block;
    overflow: hidden;
    width: 80px;
    height: 50px;
    margin-top: 15px;
    margin-right: 3px;
    cursor: pointer;
    background: url('/assets/UpvoteButtonSpriteSheet.png');
    background-position: 0 0px;
}

.DownvoteButton {
    display: inline-block;
    overflow: hidden;
    width: 80px;
    height: 50px;
    margin-top: 15px;
    margin-right: 3px;
    cursor: pointer;
    background: url('/assets/DownvoteButtonSpriteSheet.png');
    background-position: 0 0px;
}

.UpvoteButton.on {
  background-position: 0 50px;
}

.DownvoteButton.on {
  background-position: 0 50px;
}

index.ejs

<% include ../partials/header %>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class ="containerMarginsIndex">

        <% for(var i=0; i < fun.length; i++) {%>
            <div class="fun">
                <h3 class="text-left"><%= fun[i].title %></h3>
                <a href="details/<%= fun[i].id %>">
                    <img class = "postImg" src="/images/uploads/<%= fun[i].image %>">
                </a>
                <span class="UpvoteButton"> </span><span class="DownvoteButton"> </span>

            </div>
        <% } %>

</div>
<% include ../partials/footer %>

PROBLEM:

Nothing happens when I click. The images stay the same.


QUESTION:

What have I done wrong ?

You'll have to include jQuery and the clientside script in your EJS template, so it's rendered in the browser.

Installing jQuery with npm in Node, and doing var $ = require('jquery') on the serverside, just lets you use some of jQuery's methods on the server, it doesn't include jQuery on the clientside.

Change the template to something like

<% include ../partials/header %>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<div class ="containerMarginsIndex">

        <% for(var i=0; i < fun.length; i++) {%>
            <div class="fun">
                <h3 class="text-left"><%= fun[i].title %></h3>
                <a href="details/<%= fun[i].id %>">
                    <img class = "postImg" src="/images/uploads/<%= fun[i].image %>">
                </a>
                <span class="UpvoteButton"> </span><span class="DownvoteButton"> </span>

            </div>
        <% } %>

</div>
<script>
    $('.UpvoteButton').click(function () {
      $(this).toggleClass('on');
      $('.DownvoteButton').removeClass('on');
    });

    $('.DownvoteButton').click(function () {
      $(this).toggleClass('on');
      $('.UpvoteButton').removeClass('on');
    });
</script>
<% include ../partials/footer %>

the browser does not support require command natively. you have to use a file bundler like webpack or browserify in order to include the "jquery.js" file in your main js file.

I have faced similar issue in NodeJS using the ejs as the 'view engine' template, and resolved it as bellow:

Server side:

  1. Install jQuery and jsdom:

     npm install jquery --save npm install jsdom --save
  2. For jQuery to work in Node, a window with a document is required. Since no such window exists natively in Node, one can be mocked by tools such as jsdom and as of v10, jsdom has a new API and you can configure jsdom in your server side code (ie app.js or index.js) as below:

     var jsdom = require("jsdom"); const { JSDOM } = jsdom; const { window } = new JSDOM(); const { document } = (new JSDOM('')).window; global.document = document; var $ = require("jquery")(window);

Client side:

  1. Include jQuery package as usual in the ejs template (eg header.ejs):

     <head> <title>Whatever App</title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> </head>
  2. Then the js scripts that you put in the ejs file will be rendered without any problem, for example, in your case, just put the js script in the index.ejs:

     <script> $('.UpvoteButton').click(function () { $(this).toggleClass('on'); $('.DownvoteButton').removeClass('on'); }); $('.DownvoteButton').click(function () { $(this).toggleClass('on'); $('.UpvoteButton').removeClass('on'); }); </script>

Excuse me for my english.
I know this post is old but I have the same issue and I finded a solution.
It's possible to use an external JQuery file.
It must be placed into "public" folder.


application.js
[views]
index.ejs
[public]
[include]
jquery.min.js
fonctions_jquery.js

:

<script src="/include/jquery.min.js"></script>
<script src="/include/fonctions_jquery.js"></script>


var express =   require('express');
var path    = require('path');

var appli = express();
appli.use(express.static(__dirname +path.sep+ 'public'));


It works for me.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM