Undefined not a function - Drupal 7 - JQuery Dialog - No UI CSS - drupal-7

I have followed tutorials such as this one and this one. At first glance they are quite simple as in how to add JQuery UI to Drupal 7. Nonetheless, when I apply them, all I get is that the function dialog is undefined. Here is what I have done:
template.php
function mytheme_preprocess_image(&$variables) {
drupal_add_library('system','ui.dialog');
}
chat_overlay.js
jQuery(document).ready(function(){
console.log("*********************Setting up click");
jQuery('#small_chat_wrapper #chat_message').click(function(){
console.log("*********************CLICKED CLICKED");
if (typeof jQuery.ui !== 'undefined')
console.log("loaded");
else
console.log("undefined");
jQuery('#chat_overlay').dialog('open');
});
})
The console logs print out wonderfully, and the if check prints out loaded. Nonetheless, when it gets to the line of .dialog(..) the Undefined error occurs. I don't know what else to try. Such a simple thing and it's becoming painful.
Help is very much appreciated.
Edit:
The site's Status Report has the following:
jQuery Update jQuery 1.7.1 and jQuery UI 1.8.7
My MISTAKE:
Change function mytheme_preprocess_image(&$variables) to function mytheme_preprocess_page(&$variables) . Goodness.
Now the UNDEFINED ERROR NO LONGER happens, BUT, even though the ui classes and divs are getting added, the UI CSS is not coming through (the dialog does not pop up).
Really would appreciate some help.

You should load the jquery library that you need either in the preprocess_html function of your template.php or in yourmodule_init hook like that:
<?php
function yourmodule_init(){
drupal_add_library('system', 'ui.dialog');
drupal_add_library('system', 'ui.draggable');
drupal_add_library('system', 'ui.sortable');
}
?>
The source: https://www.drupal.org/node/1172846

Related

Using Angular2 from a script inside an iframe of the main document

Note: I am new to Angular, any version.
I am trying to add some Angular2 parts to the web UI that is otherwise implemented using other frameworks. In the scenario I have (and cannot get away from) the main document does not have (much) JavaScript running in it at all - all scripts are inside iframe element(s) inside that document, as managed by the main framework.
I didn't even try to load Angular2 in that iframe, assuming that would not work. When it is needed (rarely), I "eval" all required Angular scripts on the main/root window to introduce Angular to it (once), but I have to have the JavaScript code configuring it inside the iframe, at least a bit of it and, because of that, it would be simpler for me to put all of it there. Inside that iframe I declared "ng" to be the "ng" from the main window. That enabled me to run the Angular2 5 minute quick start and worked fine. However, when I started adding more content via directives (I followed http://www.gurustop.net/blog/2015/12/16/angular2-beta-javascript-component) this didn't work. Specifically, it threw exceptions from this Angular2 function:
TypeScript:
function isValidType(value: Type): boolean {
return isPresent(value) && (value instanceof Type);
}
Actual JavaScript:
function isValidType(value) {
return lang_1.isPresent(value) && (value instanceof lang_1.Type);
}
Essentially it is was missing lang_1. The exception message has complaining of about "class0" and "class1".
If I move the exact same code from the iframe to the main window, it works. Also, If I hack the Angular2's isValidType() function to simply return true as follows it also works:
function isValidType(value) {
return true;
}
I tried bringing lang_1 in from the main window to the iframe as well, but that did not help.
Can someone, at least, tell me what is going on here, if not how to solve this? Thanks!

Non-angular page opened with click - angular not defined using ignoreSynchronization or waiting for Angular without

After a lot of research, and tinkering, I can't seem to actually get my Protractor test to do anything else other than have an Angular related error, even though I am using browser to avoid Angular being detected at all.
The test involves an Angular app, opening a dropdown in it, and clicking on the link for the console; the console opens a non-Angular admin page in a separate window.
So based on the many informative SO posts I found, I first used this...
browser.driver.getAllWindowHandles().then(function(handles) {
browser.driver.switchTo().window(handles[1]).then(function() {
//expect for new window here
});
});
Which appeared to work, as I could get to the window through repl pretty easily.
The issue is when either of the following were added...
browser.driver.getAllWindowHandles().then(function(handles) {
browser.driver.switchTo().window(handles[1]).then(function() {
expect(browser.getLocationAbsUrl()).toContain('/console/login.jsp');
expect(browser.driver.findElement(By.css('th.login')).getText()).toEqual('Login');
});
});
One expect check the URL and the other checks for the header element on the page, which is a table header. When I run this, I get the following:
Error while waiting for Protractor to sync with the page: "angular could not be found on the window"
When I decide to use browser.ignoreSynchronization = true, both in the function, or in a beforeEach, with or without a following afterEach setting it to false, I get the following:
JavascriptError: angular is not defined
I can't seem to get any "useful" errors to help me debug it, and trying it in repl does not help, as I get the same issue.
To be comprehensive, trying my URL expect without getting the second window will give me the root, and the other will fail.
Just doing one or the other will cause the same problem.
Changing to regular syntax (element(by.css...)) does not change things.
So much for my first question...
It appears that my use of browser.getLocationAbsUrl() is meant to be used for an Angular page, and was causing my issue...
Essentially, even though I believed I was using pure Webdriver calls, that call still required Angular on the page to work...
As stated in another post, the use of browser.driver.getCurrentUrl() is a non-Angular call using Webdriver, and fixed the problem. Thus, the final code is the following...
browser.sleep(1000); //to wait for the page to load
browser.driver.getAllWindowHandles().then(function(handles) {
browser.driver.switchTo().window(handles[1]).then(function() {
expect(browser.driver.getCurrentUrl()).toContain('/console/login.jsp');
expect(browser.driver.findElement(By.css('th.login')).getText()).toEqual('Login');
});
});
This works without setting ignoreSynchronization, BTW.
I realized it would probably be something relatively simple to fix it, just didn't expect I'd get it that quickly (I intended on submitting the question last night, but posted it this morning instead).
In any case, I hope this will at least be a good reference for anyone else facing the same issue.
Seems like getLocationAbsUrl is angular abs url.
Try using the native driver getCurrentUrl instead.
-- expect(browser.getLocationAbsUrl()).toContain('/console/login.jsp');
++ expect(browser.driver.getCurrentUrl() ...

Why does finally and done of $animateCSS behave differently in UI Bootstrap Angular JS

I am using UI Bootstrap for collapsing/expanding a div section based on user clicking a button similar to the example shown in the official site - UI Bootstrap-Collapse
I included the latest version of ui-bootstrap(0.14.2) but it was not showing the expected behavior. In particular the collapseDone() and expandDone() callbacks are never called after the $animateCSS is done the animations. (The animations are working properly, presumably because of the css transition property of the class 'collapsing' in twitter bootstrap.)
But when I inspected the UI Bootstrap site, I found that it's working properly as expected. (That's the class 'collapsing' is added during the animation and then removed after animation and then the class 'collapse' is added). So I checked the source code link for collapse collapse source code -github and found that finally is used for $animateCSS promise resolution rather than done in the ui.bootstrap.js code I included.
So could someone please explain the difference between finally and done methods of the $animateCSS function? The documentation [Angular Docs-$animateCSS][3] says that
there is also an additional method available on the runner called .done(callbackFn). The done method works the same as .finally(callbackFn), however, it does not trigger a digest to occur. Therefore, for performance reasons, it's always best to use runner.done(callback) instead of runner.then(), runner.catch() or runner.finally() unless you really need a digest to kick off afterwards.
So it looks like both should behave similarly. Could someone shed light on this, as there seems to be very little resources to learn about $animateCSS. (google search for $animateCss returns results for animate.css which seems to be part of the earler angular js verion (v1.2) - so that doesn't help)
I had forgotten to inject "ngAnimate" to my module. That way the animation by $animateCss was not successful, so the done() was never called. But finally will be called even if the animation is not successful.

Some of your tests did a full page reload - error when running Jasmine tests

I'm running into an issue where when I run my tests on Jasmine, I get this error below. The problem is, it seems to happen when I try to execute a certain amount of tests. It doesn't seem to be tied to a particular test, as if I comment out some, the tests pass. If I uncomment some tests, the error appears. If I comment out ones that were uncommented before, they all pass again. (ie if I have red, green, blue and orange test and it fails, I comment out orange and blue it passes, then I uncomment blue and orange it fails again, but if I comment out red and green it passes again).
Chrome 41.0.2272 (Mac OS X 10.10.1) ERROR Some of your tests did a
full page reload! Chrome 41.0.2272 (Mac OS X 10.10.1): Executed 16 of
29 (1 FAILED) ERROR (0.108 secs / 0.092 secs)
I'm stumped as to what is going on. The more tests I add, that's when this becomes an issue. Has anyone encountered this before? I have no idea what could be causing it, as nothing in any of my tests do any kind of redirection, and they all pass universally on another persons machine.
In my case the problem was that in my source code I had code directly setting the href on the location object, like window.location.href = 'somewhere';
In my specs I set up a onbeforeunload listener that just returns a string instead of allowing the redirect to take place:
beforeAll(() => {
window.onbeforeunload = () => 'Oh no!';
});
I suppose you are using window.location somewhere in your targeted code. In order to pass it just create a spy for the window.onbeforeunload
Example:
window.onbeforeunload = jasmine.createSpy();
Or even better use $window instead, and this will not happen.
Make sure that your tests are properly isolating all modules under test with mocks/spies. The behavior you are seeing says to me that your tests are not truly running in isolation - they are changing some state somewhere that will trigger a reload.
I recently encountered this error with Karma 0.13.12. I upgraded to Karma 0.13.14 and my tests work again. The problem for me (and probably also for #mqklin) was related to https://github.com/karma-runner/karma/issues/1656 and https://github.com/jasmine/jasmine/issues/945.
There are many ways this error can happen.
If your component has a form element, this might be the cause.
Whenever a button on the form is clicked, this error can happen, even tho your component contains no navigation logic.
What worked for me was upgrading Karma from 1.4.0 to 1.4.1 and changing the maximumSpecCallbackDepth in my jasmine.js file from 20 to 100.
creating a spy on the function which has the window.location / reload fixed the issue for me
Hope you have used window.location = "some url" in your code;
Faced similar problem, and solved by using the below changes.
Replaced window.location in the code with,
window.location.assign("some url");
Do the below in unit test:
spyOn(window.location, "assign").and.callFake(() => {
// Dummy assign call - so that your actual call will be faked and the reload will not happen.
});
You also need to make sure that modules are not being loaded twice. In my case, I had an AngularJS module file -e.g., auth.controller.js which contents were already bundled in a core.js file. Once I excluded the bundled files on karma, the error disappeared.
Try to reduce amount of describe sections or completely remove them. I don't know why, but it works for me.
I was using setTimeout(() => window.location.replace('/'), 10);
I used below code in my unit test and it worked for me.
spyOn(global, 'setTimeout');
In case it was ng-submit callback, which doesn't call "event.preventDefault()" and the browser reloads page. Mocking $location doesn't help in that situation.
According to angularjs documentation you should inject the $window module to be able to solve the testability issue you get. If you really want to do a full page refresh while routing, which will reload the whole application. But anyway...
So for example in component
.controller('ExampleController', ['$scope', '$window', function($scope, $window**)
{
$scope.doRerouteWithPageReload = function() {
return this.$window.location.href = "/myUrl";
};
And then in your test-file you import $window to the test-controller your way, then where you assign spies you can do something like this:
$window = { location: {href: jasmine.createSpy() };
And then the actual test is something like this:
expect($window.location.href).toBe("/myUrl");
Angularjs documentation for reading more about $window.
It will solve this Karma redirect error!
var html = '<script type="text/javascript">';
html += 'window.location = "' + urlToRedirect +'"';
html += '</script>';
$( '.wrapper' ).append( html );

Backbone.js model not defined in view?

I've decided that I am going to try and learn backbone.js by making a web app. This is the first time I have done anything extensive in javascript, so the answer to my problem may be right in front of my face.
I have the web app on github, along with a running version that doesn't work. The javascript console just says that something is undefined when I don't think it should be. Here's the error that chrome gives for line 30 of app.js:
Uncaught TypeError: Cannot read property 'el' of undefined
I've sort of been referencing the backbone-fundamentals example modular to-do app, and it doesn't seem to have any issues with a similar thing.
If anyone could point out what I am doing wrong, I would be most appreciative!
Thanks in advance!
Your Machine view render method was missing return this and by default all methods return undefined - that's why chaining didn't work
Edit: and a small tip:
jQuery, Underscore and Backbone register globally - and thanks to that you don't have to define them as dependencies every time - it's enough if you require them in your main script once and after that you can access them from the global scope as you normally would
In my case i was returning this without the return keyword. As i was using javascript and not coffeescript it failed on me. So, if you are using javascript use return this; instead of just this in the last line of the render() function.
I also had a problem when using this.collection.on('reset', this.render(), this). I instead had to use this.collection.on('reset', this.render.bind(this));

Resources