Calling an external js function as ejs onclick event - javascript

I have a nodejs application that renders an ejs file called main.ejs including a button.
I'd like to declare a function in an external javascript file that I can call it in the onclick event of that button(in main.ejs).
But every time I run the app, by rendering the page, that function will be called automatically, but when I click on the button it won't be called!
(I need to mention that I have already tried writing this function directly in main.ejs in a script tag, and it perfectly works. But I'm persisting in moving it to a respective js file)
functions.js (the external js file)
function optionClick() {
console.log("Yoohooo!!");
}
module.exports = {
optionClickFunc: optionClick
};
server.js
var functions = require('./public/functions');
app.get('/question', (req, res) => {
res.render('main.ejs', {
data: {
function: functions.optionClickFunc
}
});
});
main.ejs
<button id="submit-button" onclick="'<%= data.function() %>';"> START </button>
And whenever I have this url in my browser: http://localhost:3000/question, I see the log message("Yoohooo!!") printed in the console without clicking on the button!
While it doesn't print the message when I click the botton!!
Any idea? I really appreciate your time.

data.function is a function and when you call it in your server-side-code, you call it in your server side code.
When you write HTML you need to write strings and the string representing the value of the onclick attribute needs to be JavaScript source code. (data.function, as mentioned, is a function not a string of source code.) The client will compile that source code and execute it.
Your server-side and client-side code might both be written in JavaScript, but they are two different programs running in two different environments (Node.js and the browser) which will usually (less so during development) run on two different computers.
Related: What is the difference between client-side and server-side programming?

Related

Sitecore SPEAK and Javascript

I am trying to replicate what is shown in this video series by Jakob:
I am able to get everything work except the custom Javascript part.
define(["sitecore"], function (Sitecore) {
var ListPage = Sitecore.Definitions.App.extend({
initialized: function () {
alert('Test');
}
});
return ListPage;
});
I even tried to fire Sitecore.app command in sc_debug mode but that is returning "undefined"
if your in Sitecore 7.5 or 8 the app has been moved to Sitecore.Speak.app rather than Sitecore.app
I believe you have to add a js script file to your Page Code control.
On the Page Code Control there is field called PageCodeScriptFileName you can add a path to your custom js file there. Then you can add your code above in that js file.
There's more info on this blog post from Martina:
http://mhwelander.net/2014/07/01/speak-for-newbies-part-4-pagecode-and-javascript-libraries/

How to include Javascript objects in a Jade template before Jade compilation

I am working with a website built with Jade/Express for a few weeks now. I recently organized the image folder for the website so all the images were disbursed between several folders to make it easier to use and sort through.
To make it easier to make changes to the hierarchy of images (and other such files) I wrote a script that contains some globals for file paths. Now I have been trying to get the script to run so that I can call functions inside the jade template to automatically use these globals.
For example. Images are now sorted into several folders:
File Hierarchy
img/
glyphs/
interactivity/
buttons/
...
In my path manager script, I created several functions, including the following:
In: path-manager.js
images_root_path = "/img/";
glyph_path = images_root_path + "glyphs/";
function getGlyph(color, name) {
return glyph_path + color + "/" + name;
}
I tried several methods to get the script to execute before the template. Here is one of the attempts:
In page.jade
include ../../../public/js/lib/path-manager.js
=NamespacePathManager();
The above is, in theory, supposed to include the js and then I execute the namespace below to make the functions available, but that isn't working.
This is a portion of the Jade template that I want to use the function in:
In page.jade after the script include
span.challenge-time
img(src=getGlyph("black","stopwatch.png"), style="margin-right:5px;")
The above example should return: "/img/glyphs/black/stopwatch.png"
The problem is, I believe, that the scripts I am trying to make available server-side to the jade template are not being executed before the jade template is rendered. Everything I have tried doing to get this to work always results in an error saying that the server doesn't recognize the function getGlyph or when I started using the namespace function, NamespacePathManager
Summary: I want a javascript file to execute before a jade template is rendered into a webpage so that I can call functions and variables from that javascript on the server to use while rendering the jade template. My problem is that all the methods I have tried are unable to execute the javascript before the Jade is rendered.
Update
One work around I found was to put the javascript into unbuffered code directly on the page including a jade. This isn't quite the elegant solution I was looking for, but it works for now
- some code
- more code
This code is executed inline. The downside is that I have to include it on every page manually - instead of just including it once and having the functions available everywhere.
You can register helper methods in Express that will then be accessible in the views.
So in your case, the path-manager.js can be the helper file that you register, and contains:
var images_root_path = "/img/";
var glyph_path = images_root_path + "glyphs/";
exports.helpers = {
getGlyph: function (color, name) {
return glyph_path + color + "/" + name;
}
// Other helper methods here..
};
Then when setting up the express server, you register the helper
var app = express.createServer();
// app.configure here...
// app.use ...
app.helpers(require('./path-manager.js').helpers);
// Routes set up here ..
Finally, you can call the helper method from Jade view like this:
span.challenge-time
img(src='#{getGlyph("black","stopwatch.png")}', style='margin-right:5px;')
There's a good write up on this topic at DailyJS http://dailyjs.com/2011/01/03/node-tutorial-8/

Can I tell Javascript to call a method from another JS file?

In AppMenu.js,
AppMenu = function()
{
var scope = this;
}
Also noted:
Star.Bus.addEvent("AppMenu_StatSheet");
Star.Bus.on("AppMenu_StatSheet", scope.AppMenu_StatSheet, scope);
scope.registerApp("Exit Game", "AppMenu/images/exit_button.png", "AppMenu_exit", "");
Further down is a method
scope.AppMenu_StatSheet = function()
{
showStats();
}
I moved the location of the showStats() method to another js file, and I want the method to send its call there instead of where it originally was going. In Javascript, can I tell the program where to look to call showStats()?
EDIT Curiously, there is no AppMenu.html. I now believe that all of the html is dealt with by a main HTML file in the above folder.
If you include both Javascript files in your PHP/HTML page, the compiler automatically uses your showStats() function, even when it is called from file1.js and the actual function is located in file2.js.
As long as you include both files in your HTML page you'll be fine. Maybe load the file with showStats() before the other one.

How to get texts from Resx to be used in Javascript?

We are building large ASP.NET applications for the intranet use in multiple languages/cultures. We utilize the Globalization with RESX files and use GetResourceText on the server side to get the localized texts.
Lately we are doing more and more client side logic with JQuery.
How do I get the RESX texts to be used in Javascript?
e.g. texts used for validation, dynamic messages etc.
All our Javascripts are in .JS files, we do not want to mix HTML in the ASPX page and Javascript blocks.
Thanks for your help.
Unfortunately, in an external JS file the server side code is not being processed by the server. However I have seen a workaround where you can set your translated values in hidden fields on the page - this way your javascript will be able to read the values in.
For example:
<%-- This goes into your page --%>
<input type="hidden" id="translatedField" name="translatedField" value="<%=Resources.Resources.translatedText %>" />
and use this inside your javascript file:
// This is the js file
$(document).ready(function() {
alert($("#translatedField").attr("value"));
});
You will be able to separate the values and still see it in your external JS file.
There is also another workaround that creates a .aspx file that only outputs Javascript instead of HTML. Check out the link below:
Using server side method in an external JavaScript file
Always separate functionality from human readable strings.
If you're creating jQuery-plugins you should be able to pass an array of localized strings as parameter when you call your different jQuery functions. The array could be defined as inline javascript directly on the page calling the different jQuery plugins or you could load the from external resource in the format /scripts/localization/strings.js?ci=en-US and register a Generic ASP.Net Handler in web.config that would respond to scripts/localization/strings.js
The DatePicker control is a fine example of how to localize text for the jQuery datepick control - this js file is dynamically created from resource files (resx) and when included on a page it will make sure the calendar control will have danish text.
Create a HttpHandler (.ashx file), and return JSON with your text resource strings.
You may also "publish" it to global namespace, i.e.
Response.Write("window.Resources=");
Response.Write((new JavaScriptSerializer()).Serialize(strings));
set up HTML like:
<script src="Resx.ashx?lang=en-US" />
<button class="LogoutButtonResourceId OtherButtonClasses">(generic logout text)</button>
<a href="#"><span class="SomeLinkTextResourceId OtherClasses">
(generic link text)
</span></a>
and apply texts like this:
$(document).ready(function() {
for(var resId in Resources){
$("."+resId).html(Resources[resId]);
}
});
If you don't want to use ASP.NET to generate your main JavaScript, here are two other options:
Use ASP.NET to generate a script file that contains variable-to-string assignments, such as var mystring = 'my value';. Your main script would then reference the localized text with variables names rather than as embedded values. If that's still too "dirty" for you, you could encode the strings as JSON rather than as variable assignments, using an HttpHandler rather than straight .aspx.
Have your JavaScript code issue an Ajax call to retrieve an array or list of localized strings from the server. The server-side part of the call would retrieve the text from your resx files.
Have you considered using $.ajax in combination with ASP.NET WebMethods? It's hard to suggest a more concrete solution to this problem without understanding how your JavaScript/jQuery would consume/process the resources. I assume that they're organized into logical groups (or could be) where you could return several resource strings that belong on a single page.
Assuming that, you could write a very simple C# class -- or use a Dictionary<string, string> -- to return data from your ASP.NET WebMethod. The results would look something like:
[WebMethod]
public Dictionary<string, string> GetPageResources(string currentPage)
{
// ... Organizational stuff goes here.
}
I always separate out my AJAX calls into separate .js files/objects; that would look like:
function GetPageResources (page, callback)
$.ajax({ // Setup the AJAX call to your WebMethod
data: "{ 'currentPage':'" + page + "' }",
url: /Ajax/Resources.asmx/GetPageResources, // Or similar.
success: function (result) { // To be replaced with .done in jQuery 1.8
callback(result.d);
}
});
Then, in the .js executed on the page, you should be able to consume that data like:
// Whatever first executes when you load a page and its JS files
// -- I assume that you aren't using something like $(document).ready(function () {});
GetPageResources(document.location, SetPageResources);
function SetPageResources(resources) {
for (currentResource in resources) {
$("#" + currentResource.Key).html(currentResource.Value);
}
}
I know it's to late but want share my experience in this task)
I use AjaxMin. It can insert resx key values into js file on build event.
It's not common way but it keeps html without unneeded script blocks and can be done during minification process if you have it.
It works like this:
ajaxmin.exe test.js -RES:Strings resource.resx -o test.min.js
Also you need to do the same for ech locale if you have many.
Syntax to write resource keys in js (and also css) is written here:
Js localization
Css localization
How about injecting it as part of a javascript control initialization? what i do is as follows:
I have a self-contained javascript control - call it CRMControl, which has an init method called setupCRMControl, to which i pass a settings object. When i initialize it, i pass an object containing all the resources i need inside javascript as follows:
CRMControl.setupCRMControl({
numOfCRMs: 3,
maxNumOfItems: 10,
// then i pass a resources object with the strings i need inside
Resources: {
Cancel: '#Resources.Cancel',
Done: '#Resources.Done',
Title: '#Resources.Title'
}
});
Then, inside this javascript control:
var crmSettings = {};
this.setupCRMControl(settings) {
crmSettings = settings;
};
and whenever i want to show a resource, i say (for example, show an alert saying 'Done'):
alert(crmSettings.Resources.Done);
You can call it "R" to make it shorter or something, but this is my approach. Maybe this may not work if you have a whole bunch of strings, but for manageable cases, this may work.

Calling a JavaScript function outside of the js file

I have problems with calling a JavaScript function (which is inside of an object, in it's own .js file) from an other HTML page. In the code exsample I'll just use a simple Hello World function.
//.js file
window.addEvent('domready',function(){
var Site = {
//Here I have like three other functions
//This function I want to detect the browser version. I use MooTools for this
detectBrowser : function(){
if(Browser.ie){
//Then what ever content goes here
}
}
}
//I execute the other three functions here because they need to be called on every page
Site.dropdownmenu();
Site.accordion();
Site.lightbox();
});
I'm working with MooTools so I have wraped everything inside of the domready function.
Now, I want this cetect function to execute only at one page. I have tried somethink like this:
//In the HTML file between two script tags:
Site.alert();
That does'nt work. Any ideas?
If I execute it in the .js file it works fine. But I don't want it to execute at every page.
If you declare a variable with var in a function, the variable is local to that function and inaccessible from outside that function. To make it explicitly global, declare it as a property of window:
window.addEvent('domready',function(){
window.Site = ...
This isn't necessary for the code to work, it just makes it explicit for programmers that might read your code that Site is a global.
External Javascript files just execute code; the code doesn't know where it's coming from.
As long as your code runs after the external JS file, it will work fine.

Categories