Function not found in jTemplate - javascript

I'm having a weird issue with a function I'm trying to call from within a jTemplates template giving the error "XYZ.getFriendlyName is not a function". It seems like I must have overlooked something simple, but I've tried everything I can think of and the error persists. The code looks like this:
<input type="text" value="{#if $T.RowId !== null}{XYZ.getFriendlyName($T.RowId)}{#/if}"/>
I've tried removing everything in the function to rule out a syntax error, renaming the function and moving it into the global namespace, moving the function itself into the page the template is on, before the template code.. Even putting everything in a ternary operator, which so far I haven't gotten to work at all in jTemplates. I continue to get the same error. Does anyone know a way I can fix this problem?
Thanks!
Garann

Don't use apostrophes for function:
Define function first:
function getFriendlyName( param ){
}
Add function to param:
$('template-name').setParam('getFriendlyName', getFriendlyName);
Access function inside template by using $P like $P.getFriendlyName()
For ex. {$P.getFriendlyName($T.id)}

Define function first:
function getFriendlyName( param ){
}
Add function to param:
$('template-name').setParam('getFriendlyName', 'getFriendlyName');
Access function inside template by using $P like
$P.getFriendlyName()

In case anyone was curious, this was a timing and context issue. The jTemplate was getting processed before a JS file on the same page was fully read. Moving the function into the object that starts processing the top/first template fixed the problem.

Related

Django 3 by example bookmarklet_launcher.js

Following is a piece of code in the Django 3 by example book we can use to bookmark in a browser and upon clicking the bookmark, the code in it will be executed.
Can anyone please help me understand this code?
(function(){ if (window.myBookmarklet !== undefined){ myBookmarklet(); } else { document.body.appendChild(document.createElement('script')).src='https://127.0.0.1:8000/static/js/bookmarklet.js?r='+Math.floor(Math.random()*99999999999999999999); } })();
Why do we need to put the function inside parenthesis? (function.....)()
How the browser executes the code. We put a javascript tag at the start of the code.
JavaScript:(function.....)()
what is this function myBookmarklet() and when if statement will be actually executed? How will the window object have myBookmarklet property?
Any relevant resources will be appreciated. Thanks a lot
It's because it's an anonymous function, it has no name. Because it has no name and needs to be executed, it has to be surrounded with parenthesis to be able to run it by calling it with () at the end.
Exactly like that. If you want to write a function that will not be needed in any other place, you can define it without a name so it's anonymous. To call it, see 1.
Before that js code, the HTML file has probably a series of <script> tags where it defines certain dependencies, in this case javascript files. One of those js files has assigned myBookmarklet to window, like this: window.myBookmarklet = //... a function definition. The code you posted is checking if window.myBookmarklet !== undefined before calling that function.

Laravel Mix Javascript undefined function onClick

I am using Laravels Mix feature with javascript and I am having a bit of trouble. I've made a new javascript file and included it in app.js, I've then done a function in this file. I want to call it from an onClick event however its giving me an error.
In cart.js I have an array that is adding all the products, and I also have this line of coded added.
<a onClick="removeProduct(${product["id"]})" class="btn-remove1">Remove</a>
Also in cart.js I have this function, that needs to be called on the onClick event.
function removeProduct(id) {
console.log(id);
}
However, It then gives me this error when trying to call removeProduct()
Uncaught ReferenceError: removeProduct is not defined at HTMLAnchorElement.onclick
So I'm not sure how to handle this, I guess I could use jQuery and wait for the object to be clicked and then get the id but just wondering if I can do it by onClick. Thanks for any help!
Edit:
Looking into this some more, Webpack is including Cart.js and in app.jss the function removeProduct() is there. Do I need to somehow call it like Cart.removeProduct() or something? (I've never used web pack/mix before)
I've found out with webpack you need to define it in the global scope. You can simply do that by adding this line of code.
window.removeProduct = removeProduct;
Clear your cache and then check or check that js file is included into your file or not.

Disabling Javascript variables renaming in Rails

I'm trying to use tripleflap.js in my app. My view is calling the function:
<script type='text/javascript' charset='utf-8'>
TwitterBird();
</script>
So, in application.js:
function TwitterBird() {
var twitterAccount = 'ulmicru';
var showTweet = false;
var birdSprite='http://127.0.0.1/birdsprite.png';
tripleflapInit();
}
Then I'm trying to run it, and Javascript debugger says me:
Uncaught ReferenceError: birdSprite is not defined
In precompiled application.js in /public/assets/ I'm watching this:
function TwitterBird()
{var e="ulmicru",t=!1,n="http://127.0.0.1/birdsprite.png";tripleflapInit()}
It seems Rails precompiler had renamed variables, and tripleflap.js cannot find them.
Is it possible to disable variable renaming in assets?
Try to move the variable definitions outside of the function, or just remove the var from in front of them, like this:
function TwitterBird() {
twitterAccount = 'ulmicru';
showTweet = false;
birdSprite='http://127.0.0.1/birdsprite.png';
tripleflapInit();
}
I googled the tripleflapInit script and took a look at it. Basically it defines a bunch of configuration variables directly on the window and expects you to overwrite them; a pretty kludgy script all in all, but that's beside the point.
Because you're defining birdSprite inside a function with var, you're actually defining a new variable local to that function. Even if it was not renamed by the minifier, the window-defined tripleflapInit would still not use it, but rather look to the variable defined on the window.
I'm not sure why you're getting the error that birdSprite is not defined, but it's possible that the compiler became confused and removed it, thinking it was unused.

jQuery - Using javascript variable elsewhere

I fear this question may be extremely newbie level, but I am just drawing a blank.
Within the $(document).ready function I have some DatePicker code...
$('#date-view1').datePicker({
selectWeek: true,
inline: true,
startDate: '01/01/1996'
}).bind('dateSelected', function (e, selectedDate, $td) {
$('#date1').val(selectedDate.asString());
var pfb = selectedDate.asString();
});
The part I am struggling with is the var pfb = selectedDate.asString();
I want to use the variable pfb further down my page in a different function called showProjects().
How can I do this? I have tried declaring the variable inside and outside of the $(document).ready function without luck.
Thanks
Declare var pfb before your document ready block. That'll make it available elsewhere on the page. In the document ready you'll be SETTING an already DECLARED variable.
In Javascript you can use global variables to store values which are accessible from anywhere in the page. Of the many ways of doing this is
setting the value using window.pfb = selectedDate.asString();
and accessing it later anywhere with window.pfb
I'm not sure if this is a problem area, but I wouldn't have tried passing pfb as a param in that onclick event - I think that may re-initialise pfb, or create a new var.
If you're creating it globally (not ideal but should work) then you shouldn't need to pass pfb as a param anyway.
Also, it's good practice not to attach events on the elements like that. Ideally - and jQuery makes this very easy - you should have something in your $(document).ready like this:
$(document).ready(function() {
$("#myButton").click(function() {
showProjects();
});
});
Or even shorten this to
$(document).ready(function() {
$("#myButton").click(showProjects());
});
if you know that showProjects() is the only call that you want to make.
It should work if you just drop the word var
Declaring variables without var makes them global.
It would probably be better form to declare it before the ready block as Dan Ray suggested, but you said you had a hard time with this? Not sure why you would.

Can I void all JavaScript calls to $

I need some scripts inside an existing site's scripts.js.
This site has been online for ages, and I can not touch the scripts file.
I am including it standardly in another page. There are numerous jQuery calls in the scripts file. The place I include it does not have jQuery.
I want to void all $() type things. I tried this...
$ = function() { };
before I included scripts.js and it didn't seem to work. I am still getting errors like
$(document) is undefined
Is there a way to void all these jQuery calls?
Thanks
Even if you do get that working, you'll still have problems because the code was written with the assumption that jQuery was present. Yes, you can avoid $ is null or not defined errors on lines like this:
$('div.foo');
But there's no point in just writing that line: there will always be actions on the returned object:
$('div.foo').html('blah');
After the NOP jQuery function, you'll get a "html" is not a function error, and so on. The only way you could do it would be to fill out a skeleton of every possible jQuery method, making sure each one returns itself when appropriate.
...or just rewrite it properly...
try
window.$ = function(selector, context) {alert('eating the calls to $');}
in your file that you're including before the scripts.js file. This is how it's defined in jquery so should take care of the selector syntax.
You may need to define other overrides to cater for the $.method() type calls tho
Well, it's no surprise that $(document) is undefined, since you're not returning a value from your placeholder function. Thus, things like $(document).ready(function(){}); will naturally be errors.
Basically, if I understand right, you need $ to be a function that does nothing and returns another object where calling any member function does nothing. Further, calling member functions of $ itself (e.g. $.ajax()) should have the same behavior.
You can do this with __noSuchMethod__, which is unfortunately non-standard:
window.$ = function()
{
var doNothingObj = new (function()
{
this.__noSuchMethod__ = function()
{
return doNothingObj;
}
})();
return doNothingObj;
};
window.$.__noSuchMethod__ = window.$;
This will allow arbitrary chains:
$(document).ready(function(){});
$("#foo").animate().animate();
$.ajax({ url: "file.html"});
etc.
Of course, a much saner solution is to refactor the code that uses jQuery.

Categories