Is there a way to add drupal behaviors to a theme without invoking jquery in Drupal 8?
This is what the tutorial show:
(function ($, Drupal) {
Drupal.behaviors.myModuleBehavior = {
attach: function (context, settings) {
$('input.myCustomBehavior', context).once('myCustomBehavior').each(function () {
// Apply the myCustomBehaviour effect to the elements only once.
});
}
};
})(jQuery, Drupal);
But i want to use pure js without invoking jquery, something like this:
(function (Drupal) {
Drupal.behaviors.myModuleBehavior = {
attach: function (context, settings) {
context.querySelector('input.myCustomBehavior').classList.add('processed');
}
};
})(Drupal);
I understand that modules may invoke jquery on their own but i still would like to remove it from my scripts if possible and still have it run after ajax events.
Thanks
Have you tried it?
I also did not know this, so went investigating.
It seems that Drupal no longer relys on jQuery's document.ready to fire behaviors.
As seen in this change record.
This leads me to believe that the second code block that you posted should work (with Drupal 8.x).
Related
I've been using dropzone.js in some projects recently and configuring options without no problem, but in a new project I was using a recent version of jQuery (3.1.0) auto-installed by Zend Framework 3 and it appears to cause some kind of conflict with dropzone.js version 4.3.0.
I was not able to configure options for my dropzone, it is always using default options.
If anyone else needs to use Dropzone with jQuery 3, particularly if you need to reference jQuery methods within Dropzone's callbacks, here's what worked for me:
// Do this outside of jQuery
Dropzone.autoDiscover = false;
// Start jQuery stuff
$(function() {
// Call Dropzone manually
$("#dropzone").dropzone({
paramName: "image",
maxFilesize: 8, // MB
queuecomplete: function() {
// Some more jQuery stuff inside Dropzone's callback
$("#some_id").somejQueryMethod();
}
});
});
Afer half hour searching i found problem
it works if declare befor
$(document).ready(function () {});
or
$(function () {...});
beacuse dropzone initiate befor jquery load methodes
My solution, of course have been to come back to an older version of jQuery, which is enough for me (1.11.1).
Hope this helps, and if anyone knows the reason of the conflict, cool!
Regards
I've encountered a strange problem with my chrome app i'm developing at the moment.
I want to use the "knob" extension to use it for a alarm-clock slider (to set the time)
This wouldn't be a really difficult matter, wouldn't it be for the restrictions and strange issues found while programming a chrome app.
In my index.html file I included the jquery library and the knob extension. And that is where the problems started. Somehow, my scripts only can use the Id's of elements that are above them. So when I include the tags between the tags, nothing executes, if I put them after the first tags they only work with the things that are in this div container. thats why I put the script just before the tag. That works well for "normal" javascript usability. But because I have a that referes to a jquery function (for the knob) the jquery library should be already loaded before the function gets executed (if not, it just doesn't work). I tried to get a workaround by using these posibilities:
document.onload=test();
function test(){
$(function() {
$(".dial").knob();
});
}
document.onload=test();
$(function test() {
$(".dial").knob();
});
}
document.onload=$(function() {
$(".dial").knob();
});
}
well.... It didn't work. I also tried window.onload, with the same reuslt. does someone have a solution? It would be of great help.
Thank you,
neissen
Try like this:
$(function() { //document ready function
function test(){ //inside the ready function
$(".dial").knob();
}
test(); // and call the function here
});
Your Problems:
jQuery may not be loaded but you used some vanilla JS to handle jQuery, which will cause errors.
May be related to global and local.
For the external scripts, functions are only fired locally, which means the global object which contains the html won't be able to be accessed.
To make a global function and a jQuery library - JS:
if ("undefined" === typeof jQuery) {throw new Error("This library requires jQuery"); }
$(function() {
window.myFunction = function() {
doSomething();
}
doSomething();
})
Works calling from HTML - HTML:
<script>
$(function() {
doSomething();
})
</script>
Above is the safest way to approach a jQuery library. The $(function() {... part means exactly the same as $( document ).ready(function() {..., execute if loaded and ready, ensures the browser knows how to deal with all the functions used.
I've read about how to make a JS namespace, but my question is how can I make sure the functions inside would only happen on page load?
i.e. instead of:
$(document).ready(function () {...});
(or any other lib then jquery).
also - is there a way to control what will launch on page load and what would before?
Thank you!:)
The following example uses an immediate-function to encapsulate the Code and registers an event-handler on the event DOMContentReady which fires when the Browser has the DOM ready but bevor Images are loaded.
(function () {
'use strict';
var
init = function () {
window.console.info('init()');
};
window.addEventListener('DOMContentReady', init, false);
}());
The immediate-function gets executet as soon as the browser loads the code. From that point there are different events on which further code-execution can be scheduled.
Without using a framework like jquery, which puts some effort in this toppic, you have to handle different events in different browser by your own.
put this code out of jquery code
var MyReallyCoolLibrary = {
awesome: "stuff",
doSomething: function() {
},
doAnotherThing: function() {
}
};
MyReallyCoolLibrary.awesome;
alert(MyReallyCoolLibrary.awesome);
I try to extend UI dialog according to documentation (UI version 1.8.16):
(function($) {
$.widget('ui.mydialog', $.extend(true, $.ui.dialog.prototype, {
_create: function() {
return $.Widget.prototype._create.apply(this, arguments);
}
}));
})(jQuery);
$(function() {
$('div#dialog').mydialog();
});
Executing of this code causes JS error: "this.uiDialog is undefined".
And if try to override the _init() method there are no errors, but parent method call takes no effect.
I'm confused.. Which way is legal to extending for e.g. put some custom initialize code?
I think this post would solve your question: Inherit from jQuery UI dialog and call overridden method.
In short, if you want to build a widget inheriting jQuery UI Dialog, you can do this:
(function($) {
$.widget("ui.mydialog", $.ui.dialog, {
_create: function() {
$.ui.dialog.prototype._create.call(this);
}
});
})(jQuery);
See this in action: http://jsfiddle.net/william/RELxP/.
This tutorial will enlighten you: http://wiki.jqueryui.com/w/page/12138135/Widget%20factory. In short, $.Widget is the base widget object. Even though it has a _create function, it by default does nothing, leaving the initialisation code to the subclass. Take a look at this updated example: http://jsfiddle.net/william/RELxP/1.
From jQuery 1.9 and on, if you want to add functionality to a widget and don't want to replace the existing function, after you do your code call the parent method. To do this, instead of what William Niu suggests, you can simply do this:
_create: function()
{
// Custom code here
// Call the _create method of the widget
this._super();
}
This applies to all existing methods. (eg _setOption, _trigger etc)
I posted a simple example of extending a jQueryUI Dialog using the Widget factory.
http://jsfiddle.net/Artistan/jWUGZ/
This example extends a dialog to create a simple loading modal.
I'm writing a jQuery plugin and I would like my code to take advantage of the jQuery UI show(effect, [options], [speed], [callback]) and hide(effect, [options], [speed], [callback]) functions, which allow you to show and hide elements with a nice animation.
However, I'd also like my plugin to degrade gracefully if jQuery UI isn't available, switching back to use the basic, non-animating show() and hide() functions present in the standard jQuery API.
I'll need to test for the show and hide functions specifically, as even if jQuery UI is available it could potentially be a custom version, without the Effects components included.
At first I thought that I might be able to do something like:
if(typeof myelement.show('blind', 'slow') == 'undefined')
{
myelement.show('blind', 'slow');
}
else
{
myelement.show();
}
But of course this doesn't work, as even if UI isn't present, show() is still a function, it just has a different signature—so typeof returns object in either case.
So, what's the best way for me to check if jQuery UI is available to my plugin? Any help is much appreciated!
You can check for an effect like this:
function hasEffect(effect) {
return $.effects && $.effects[effect];
}
Then you can use that anywhere:
if(hasEffect('blind')) {
myelement.show('blind', 'slow');
} else {
myElement.show();
}
//or, you can shorten it further:
//$.fn.show.apply(myelement, hasEffect('blind') ? ['blind','slow'] : []);
You can view a demo here, check/uncheck jQuery UI on the left and click "Run" up top to see it in action. This works because effects are declared like this:
$.effects.blind = function(o) { ...effecty stuff... };
For example, you can see "blind" here. The reason I check for both $.effects and $.effects.effect in the code above is you can only download some of the effects when you download jQuery UI, so this accounts for that possibility.
Nick's function worked perfectly; for consistency, I ended up adding it as a jQuery utility function from within my plugin code:
$.extend({
hasEffect: function (effect) {
return $.effects && $.effects[effect];
}
});
So now I can call $.hasEffect(effectname) anywhere I want to check for the presence of a particular jQuery UI effect.