How can I modify jQuery to allow $('dialog').showModal() to work? - javascript

I am trying to show a modal dialog using a jQuery script. Using the $ approach to get the element and call the function results in an error, but using vanilla JS to get the element and call the function works as expected. How can I make the call work using the $ approach to get the element?
Vanilla JavaScript
Works as expected. No errors on Chrome v67.0.3396.87.
document.getElementById("error").showModal()
<dialog id="error">Error message</dialog>
jQuery (v3.3.1)
Does not work as expected. Returns an error on the same browser.
Uncaught TypeError: $(...).showModal is not a function
$('#error').showModal();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<dialog id="error">Error message</dialog>
I realize what's probably happening is dialog.showModal() functionality is still experimental, so jQuery may not have formal support for it yet. However, I expected that any functions or properties not overridden by jQuery would cascade to the vanilla JavaScript functions and properties. That is evidently not the case, so I could use some help to make $('#dialog').showModal() behave functionally like document.getElementById("dialog").showModal().
Edit: I'm trying to use this like any other typical jQuery call within my scripts. For more context, here's how I'm trying to use the calls.
err = $('#error');
err.html('New error message'); //err = $('#error')[0] results in an error here
err.showModal(); //err = $('#error') results in an error here
//err.show() does not create the supporting elements that showModal() does
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<dialog id="error">error</dialog>

Extend jQuery
jQuery.fn.extend({showModal: function() {
return this.each(function() {
if(this.tagName=== "DIALOG"){
this.showModal();
}
});
}});
Use as
$('#error').showModal();

Modifying the showModal() call meets my requirements:
$.fn.showModal = function() {
el = $(this);
if (el.is('dialog')) {
el[0].showModal();
}
return el;
};
err = $('#error');
err.html('New error message');
err.showModal();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<dialog id="error">error</dialog>
At some point I'll need to add in browser compatibility checks to cascade to some degraded mode alternative. Also need to add a jQuery version number check in case formal support for the call is added in a future version.

Related

jQuery is not a function when using .has()

I have this simple jQuery code
function removePreloader() {
jQuery('ul.woocommerce-error').has('li').jQuery("#preloader").css("display", "hidden");
}
and it's being called by
jQuery('form[name="checkout"]').submit(function(e) {
... // lots of line
setTimeout(removePreloader(), 2000);
}
both block of codes is inside jQuery(document).ready(function() { ... });
the other jQuery() is working fine, only this one is causing a problem and showing
Uncaught TypeError: jQuery(...).has(...).jQuery is not a function
is it not possible to use .has? or is there any alternate? because this wordpress theme using a lot of old plugin, so they can't accept newer version of jQuery.
Thank you
here is the screenshot from jquery.com
I just trying to follow this javascript and modified it a little bit, please let me know how to do this the right way, because I don't never code with javascript before
You're using an invalid jQuery statement .jQuery..., I would suggest the use of the if statement when checking if there are any li children inside the list like :
function removePreloader() {
if( jQuery('ul.woocommerce-error li').length ){
jQuery("#preloader").css("display", "none");
}
}
NOTE 1: display property has no hidden value, so you're searching for none instead.
NOTE 2: Remove the () in the function call like :
setTimeout(removePreloader, 2000);
Uncaught TypeError: jQuery(...).has(...).jQuery is not a function
means .jQuery is not a function on the returned object of .has(). That also means .has() works just fine here. Try to use .find() instead.

$.on is not a function

I am getting following error when trying to run my website,
Uncaught TypeError: $(...).on is not a function
I am not well aware of javascript, hence i dont know what all this code does :
$(window).on('hashchange', function(){
var url = window.location.hash.replace("#/", "");
if(url != ""){
setHashChange(true);
} else {
iniMenuSlide("home");
}
});
Please guide me on how to resolve this error.
Paste below line in your page's head tag, preferably before any javascript linking or code.
<script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
The error is coming because you are not linking jQuery file or linking to older version, which is not supporting on function.
The on method was introduced in jQuery 1.7 (which is pretty ancient these days). Since you don't seem to have it, you need to upgrade to a more recent version of jQuery.
The code calls one of two different functions depending on if the URL has changed to one with fragment identifier at the end or not.

jQuery-UI draggable error 'cannot call methods prior to init', in updating to version 1.10.1

I was working the draggable plugin fine while using jQuery-UI 1.8.2, then I changed to 1.10.1. The major difference I found was that in enabling and disabling the plugin, I no longer needed to use:
$this.draggable('option', 'disabled', true);
but could simply use
$this.draggable('disable');
But then I realized there's another problem. I get this error, which messes up my entire program, and I don't know how to fix it:
Error: cannot call methods on draggable prior to initialization;
attempted to call method 'enable'
To fix it, I ensured that I always call $this.draggable('enable'); before any further options, but it didn't make a difference. What's the problem?
The meaning of your error is : $this.draggable('enable'); is called before $this.draggable();.
Check the execution flow of your progam : make sure that you have indeed initialized the plugin (e.g : called $this.draggable();) before trying to do anything with it.
Expanding on what LeGEC said...
$this.draggable(); is being called before $this.draggable('enable');
For me the solution would be to chain the event like this...
$this.draggable().draggable('disable');
First declaring that $this is a draggable, then declaring that it is dissabled
I had a similar issue when upgrading from jquery 1.6.1 to 1.9.1
var tr$ = $('<tr>', { draggable: 'true' });
threw "cannot call methods on draggable prior to initialization"
modified to:
var tr$ = $('<tr>');
if(!('draggable' in document.createElement('span'))) {
//handle old browsers
} else {
tr$.attr('draggable', 'true');
}
Posting in case it helps someone else to see it this way.

How can I use jQuery 1.5.2+ on a Firefox addon?

At first I made a function that received a parameter and returned jQuery such as:
function getjQuery(window)
{
/*jquery code*/(window);
return window.jQuery;
}
But then I got an email form the review and they told me I have to use jQuery file with the original file name and completely unmodified.
I started to search for an alternative and found this solution, but there is no way it work.
jQuery object is created, but I can't find any elements. $("#id").length is always 0. With the previous method it was always found.
My current code (which doesn't work)
AddonNameSpace.jQueryAux = jQuery;
AddonNameSpace.$ = function(selector,context) {
return // correct window
new AddonNameSpace.jQueryAux.fn.init(selector,context||contentWindow);
};
AddonNameSpace.$.fn =
AddonNameSpace.$.prototype = AddonNameSpace.jQueryAux.fn;
AddonNameSpace.jQuery = AddonNameSpace.$;
The jQuery file is loading on my browser.xul overlay:
<script type="text/javascript" src="chrome://addon/content/bin/jquery-1.5.2.min.js" />
Am I loading in the right place?
How can I use jQuery to modify the content on a page (HTML) with the original jQuery file, is it even possible?
You need pass the e.originalTarget.defaultView on the second parameter on jquery..
If you don't jquery will use window.document, which is the window.document from the xul.
Use
gBrowser.addEventListener("DOMContentLoaded", function (e) {
$("#id", e.originalTarget.defaultView).length
}, true);
instead of
$("#id").length;
And, for avoid conflicts with other extensions don't use script in the xul page, use MozIJSSubScriptLoader.
Components.classes["#mozilla.org/moz/jssubscript-loader;1"]
.getService(Components.interfaces.mozIJSSubScriptLoader)
.loadSubScript("chrome://youraddon/content/jquery-1.5.2.min.js");
If you use this method, you load jquery only when you need, avoiding memory leak.
The preferred way to load it is with mozIJSSubScriptLoader so you don't collide with other's extensions. I'm not sure why you're having problems, I can use jQuery in my addon like $("#id").hide() with no additional code (although from the sidebar, now browser.xul).
Either way, this blog post provides a pretty good guide and even has an example xpi to download.

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