Issue in caching using coffeescript - javascript

I've this script
class Raffler.Views.EntriesIndex extends Backbone.View
div: $('#input')
initialize: ->
console.log #div.val()
As you can see this is a backbone's view.
I would like to cache $('#div') into a variable and call it. See the console.log #div.val().
But this seems not working..
Using normal javascript I'd write something like this:
var ToDoView = Backbone.View.extend({
div : $('#input'),
initialize: function(){
console.log(this.div.val());
}
})
And this is working fine. Where I'm going wrong with coffeescript?

There are some differences in how Coffeescript classes work and Backbone's extend mechanism work, which could be the issue you are running into. But I'm guessing that is not the issue here. There could be differences in exactly when and where you are running this code as well. If you put the javascript code in the same place where you are executing your coffeescript code, does it then work ok? And on a related note, what exacly is the problem, i.e. what error messages are you getting? Is #div initialized at all?

It's likely the $("#input") element hasn't been loaded at the moment your code runs.
The problem with caching the value in the class is that the class is most likely being defined outside the jQuery.ready callback (before the DOM has finished loading) so at the moment your class sets $("#input") as #div jQuery doesn't actually find that element.
You could set #div in the initialize function since that will most likely be called after the DOM has loaded.

Related

Running jQuery code in MEAN.JS stack

I'm starting to work with NodeJS, and more expecifically with MEAN.JS. I'm trying to run some custom JS code, using JQuery, but no matter where i put the code, it nevers runs as expected. This is my script:
$(document).ready(function(){
var tooltips = $('[data-toggle="tooltip"]');
tooltips.tooltip();
});
I tried putting it in the body of the page, in a separate script, but nothing. When I debug in Chrome, the variable tooltips does not contain any elements, but if I execute the same code in Chrome's console, then it works. It seems to me that despite the $(document).ready() thing, the DOM is not ready when the code executes. Maybe AngularJS is doing its magic at the same time and that interferes.
Is there somethign i need to do so that the code will get executed? Do I have to load it after/before something?
Thanks for any help.
I would suggest creating a directive instead of applying it in a dom ready:
angular.module("myModule")
.directive('tooltip', function () {
return {
restrict: 'A',
link: function (scope, elem) {
$(elem).tooltip();
}
}
});
Now, any time you use the tooltip or data-tooltip attribute on an element in one of your templates, the tooltip plugin will be applied to it.
Disclaimer: i have not tested this code, and in the end would suggest not using jquery for this. Instead, use angular-bootstrap-tooltip or a similar angular solution
Tooltips will not contains any elements as it is limited to the scope of the anonymous function you specified for $(document).ready(). Second, "tooltips" is misspelled in the variable declaration. Try this code to help you debug:
$(document).ready(function(){
window.$tooltips = $('[data-toggle="tooltip"]');
$tooltips.tooltip();
});
Now you can go into the console and evaluate the variable $tooltips to see if it is there. Note: I prefixed the variable with a $ to help identify it as a jQuery object. Don't confuse it with the built-in Angular services.
Also, Angular will not execute JavaScript within templates it generates pages from. Be sure to specify external JavaScript in the main page output or place this code to be executed when Angular loads the view.

Make RequireJS place class on script tags it creates?

I've noticed that RequireJS creates script tags in the tag as it loads modules.
Is there anyway to configure RequireJS to "tag" those elements w/ a class or an attribute of some kind that I could later target w/ jQuery later on?
e.g.:
var $requireJsScripts = $('script.require-script');
--UPDATE--
Ok.. I think I can get by on this little workaround for now. Thanks to this answer for the breadcrumb on require.s.contexts._.defined. I'd still like to hear if anyone knows of a way to configure RequireJS to do something similar to what was laid out in the original question...
var loadedRjsModules = Object.keys(require.s.contexts._.defined);
var $scripts = $('script');
$scripts.each(function () {
if ($(this).data('requiremodule') && $.inArray($(this).data('requiremodule'), loadedRjsModules)) {
console.log(this);
}
});
Looking at the source code, I don't see how RequireJS would allow adding anything custom to the script nodes at creation. The routine that creates them has no provision for it. The code that fleshes them out upon creation does not support it either.
There's an onResourceLoad hook considered part of the internal API. It could be used with the code you've put in your question instead of relying on require.s.contexts._.defined, which as far as I know is fully private and subject to change without notice.

dojo dijit.Dialog destroy underlay error

I have a class that extends dijit.Dialog but only to set default functionality and buttons for my site. When clicking the dialog's cancel button the following code is run:
this.actionDialog.destroyRecursive();
this.actionDialog.destroy();
nb this.actionDialog = dijit.Dialog
Sometimes (not always) the following error gets thrown:
Uncaught TypeError: Cannot call method 'destroy' of undefined
DialogUnderlay.xd.js:8
Which causes following dialogs to incorrectly display. I am using 1.5 from Google API's. Am I missing something with the underlay code?
Error thrown after Ken's answer:
exception in animation handler for: onEnd
TypeError: Cannot read property 'style' of null
Both from dojo.xd.js:14. But the code still works properly.
I'm still not entirely sure what the problem is, other than for some reason dijit.DialogUnderlay code is getting confused. FWIW, this doesn't happen in Dojo 1.6.
While I was poking at some potential solutions, I seemed to accidentally find out that avoiding this problem is perhaps as easy as calling hide() on the dialog immediately before destroying it, e.g.:
this.actionDialog.hide();
this.actionDialog.destroyRecursive();
Alternatively, you might be interested in hiding the dialog, then destroying it once the hide animation finishes.
Here's how you can do it on Dojo 1.5 and earlier (tested 1.3+):
dlg.connect(dlg._fadeOut, 'onEnd', function() {
this.destroyRecursive();
});
dlg.hide();
In 1.6, the fadeOut animation is no longer exposed on the instance (granted, it was technically private earlier anyway), but onHide now triggers once the animation ends (whereas before it triggered as soon as it began). Unfortunately a setTimeout is needed to get around an error that occurs due to other code in the branch calling onHide, which assumes that something still exists on the instance which won't after we've destroyed it (see #12436).
dlg.connect(dlg, 'onHide', function() {
setTimeout(function() { dlg.destroyRecursive(); }, 0);
});
dlg.hide();
See it in action on JSFiddle: http://jsfiddle.net/3MNRu/1/ (See the initial version for the original error in the question)
The dialog.hide() method returns a Deferred, your code can be something more readable like this:
var dialog = this.actionDialog;
dialog.hide().then(function(){ dialog.destroyRecursive(); });
Be careful not to do this:
this.actionDialog.hide().then(function(){ this.actionDialog.destroyRecursive(); });
At the context of then this has another meaning!
You only need to call destroyRecursive()
The second destroy command is what is probably causing the error, and the error probably is causing the issues with other dialogs.
http://dojotoolkit.org/api/1.3/dijit/_Widget/destroyRecursive
destroyRecursive
Destroy this widget and it's descendants. This is the generic "destructor" function that all widget users should call to cleanly discard with a widget. Once a widget is destroyed, it's removed from the manager object.
I was getting the IE8 error : 'this.focusNode.form' is null or not an object. I found this was the result of the dialog.hide() returning a deferred. I wrote my own _closeDialog which eliminated the IE error.
_closeDialog : function(cntxt){
cntxt.popup.hide().then(
function(){
cntxt.popup.destroyRecursive(false);
cntxt.popup.destroy(false);
cntxt.destroyRecursive(false);
cntxt.destroy(false);
});
},

Javascript executing when jQuery not ready

The following scenario is a problem I am having. I came to the conclusion that jQuery must not be ready when Javascript is executing by observing this scenario.
Scenario:
I have a Java application which injects Javascript script tags into the currently loaded DOM page. The following Java code runs inline Javascript which inserts jquery.js and myCode.js. myCode.js holds my Javascript codes.
browser.executeJavaScript("var head= document.getElementsByTagName('head')[0];" +
"var script= document.createElement('script');script.type= 'text/javascript';script.src= 'jquery.js';head.appendChild(script);" +
"var script4= document.createElement('script');script4.type= 'text/javascript';script4.src= 'http://myCode.js';head.appendChild(script4);");
In this Java application, I also have a buttonListener that fires a function in myCode.js in ActionPerformed();
executedJS = browser.executeJavaScript("replaceAllLinks()");
The problem that is encountered is nullPointerException at the above line when button is clicked. Accomodating for null case results in endless loop without any changes.
while(executedJS == null) browser.executeJavaScript("replaceAllLinks()");
The cause of the problem was pinpointed down to when jQuery functions, methods are present inside replaceAllLinks(); javascript function. when jQuery, methods were absent, no problems could be observed. There was not one instance of nullPointerException raised.
The only possible underlying issue would be that somehow jQuery library is not fully loaded while replaceAllLinks(); is being executed. If jQuery methods and functions were not in use, it doesn't matter and everything runs okay.
My question is then, how can I make sure that jQuery is fully loaded and available for use?
Every script relying on jQuery should be contained inside a DOM ready function. Such a function normally takes this form:
$(document).ready(function() {
/* code here */
});
and a shortcut to achieve the same thing would be:
$(function() {
/* code here */
});
Here's the documentation for further information on the ready method:
http://api.jquery.com/ready/
Declare some global variable at the end jquery.js, e.g.
window.jQueryIsLoaded=true;
and check this variable before using jQuery.
<edit>Forget this, see Salman A's comment below, should be the right answer.</edit>

Dojo Calendar Not Destroying On My Connect

Hey all, this is weird. This widget will not destroy onHide. I know the event is firing because I have placed debug code within the function that is ran. I have no idea why this won't work... it is clearly documented in the API. My code is below:
var formitem=new dijit.Calendar({
name:this.formitems.calendaritems[i].id,
id: this.formitems.calendaritems[i].id
},
dojo.create('dd',null,
this.lineitems));
dojo.connect(myself.dialog, 'onHide', function() {
formitem.destroy();
});
I keep getting the error the widget is already registered, however if the destroy function is supposed to work correctly then it is supposed to destroy the instance of it. Please help.
"the widget is already registered" error results from using a ID that's already been used. If you have to set the id, ensure that you never use the same one twice. But I would just remove that line where you set the id. Somewhere along the line you are recreating the Calendar. It's possible that you are deleting it as expected but its trying to recreate.
Note this is a bit of guess, since the example seems to be missing code that is relevant to your problem.

Categories