Solved

Debut theme / Jquery / Not a function?

SHPMP
Tourist
8 1 1

I've been struggling to identify why I'm having issue executing scripts with shopify / debut theme.  Other devs did work on this site before me so their maybe something custom they did.

Trying to load nanogallery2 gallery page using the javascript sample code provided here.  https://nanogallery2.nanostudio.org/

I'm consistently getting error - "nanogallery2 not a function" ?

SHPMP_0-1613247811128.png

 

Here are the additions /  modifications to debut theme that I've done to theme.liquid file in past.

(Other devs may have modified elsewhere)

Appreciate any suggestions as to what maybe cause this error

 

Click to expand...
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
</head>

<body>

<script>
jQuery(function() {
jQuery('body').on('click', '[name="checkout"], [name="goto_pp"], [name="goto_gc"]', function() {
var formIsValid = true;
var message = "Please inform us ........";
jQuery('[name^="attributes"], [name="note"]').filter('.required, [required="required"]').each(function() {
jQuery(this).removeClass('error');
if (formIsValid && jQuery(this).val() == '') {
formIsValid = false;
message = jQuery(this).attr('data-error') || message;
jQuery(this).addClass('error');
}
});
if (formIsValid){
jQuery(this).submit();
}
else {
alert(message);
return false;
}
});
});
</script>

<script>
$(window).on("beforeunload", function() {
var cartForm = jQuery('form[action="/cart"]');
if (cartForm.size()) {
var params = {
type: 'POST',
url: '/cart/update.js',
data: cartForm.serialize(),
dataType: 'json',
async: false
};
jQuery.ajax(params);
}
});
</script>

<script>
function createPopupWin(pageURL, pageTitle,
popupWinWidth, popupWinHeight) {
var left = (screen.width - popupWinWidth) / 2;
var top = (screen.height - popupWinHeight) / 4;
var myWindow = window.open(pageURL, pageTitle,
'resizable=yes, width=' + popupWinWidth
+ ', height=' + popupWinHeight + ', top='
+ top + ', left=' + left);
}
</script>

</body>

 

Accepted Solution (1)
SHPMP
Tourist
8 1 1

This is an accepted solution.

Thanks Diego for your help on our site. 

For any onlookers.

A viable solution for my "not a function" error in which thread started was

var waitForJQuery = setInterval(function () {
    if (typeof $ != 'undefined') {

        // place your code here.

        clearInterval(waitForJQuery);
    }
}, 10);

As mentioned here.  https://stackoverflow.com/questions/7486309/how-to-make-script-execution-wait-until-jquery-is-loaded

Also - For any in need of assistance with their site.  I'd recommend Diego_ezfy - Good support.  Affordable rate.

 

View solution in original post

Replies 8 (8)

diego_ezfy
Shopify Partner
2935 562 883

@SHPMP 

You're trying to load a library that is dependent on jQuery before jQuery itself loads. You need to:

1. Import your library after importing jQuery;
2. Wait for jQuery to load before using your library. 

Something like this would work:

 

async function loadSomething(){
while(!window.hasOwnProperty("jQuery")){
await new Promise(resolve => setTimeout(resolve, 100));
}

jQuery(function() {
jQuery('body').on('click', '[name="checkout"], [name="goto_pp"], [name="goto_gc"]', function() {
var formIsValid = true;
var message = "Please inform us ........";
jQuery('[name^="attributes"], [name="note"]').filter('.required, [required="required"]').each(function() {
jQuery(this).removeClass('error');
if (formIsValid && jQuery(this).val() == '') {
formIsValid = false;
message = jQuery(this).attr('data-error') || message;
jQuery(this).addClass('error');
}
});
if (formIsValid){
jQuery(this).submit();
}
else {
alert(message);
return false;
}
});
});
</script>

<script>
$(window).on("beforeunload", function() {
var cartForm = jQuery('form[action="/cart"]');
if (cartForm.size()) {
var params = {
type: 'POST',
url: '/cart/update.js',
data: cartForm.serialize(),
dataType: 'json',
async: false
};
jQuery.ajax(params);
}
});

}

loadSomething();

 


You may need to adjust the code to better suit your needs.

Kind regards,
Diego

◦ Follow my blog & youtube for coding tutorials. Most questions in here are already answered there!
◦ Top #4 Shopify Expert, 24h reply. Click here to hire me.
Download copy/paste code snippets that can replace most apps.

SHPMP
Tourist
8 1 1

Thank you.  I felt it was an order of execution.  Though I still don't understand.  Jquery is referenced above the header on theme.liquid - Why isn't jquery ready (loaded) for every page on site in which I would call a library?

Reviewing the code you shared.  I don't understand how to use it.  Where the scripts begin and end?  Is it that it shouldn't close after loadSomething();    to then run scripts on my other pages.

Clearly I'm outta my element here with JS.  The other scripts I sourced from https://github.com/carolineschnapp to meet our needs for order info attributes + mandatory field select.

SHPMP
Tourist
8 1 1

Got it to execute.

With your guidance on #1,2 - searching around landed me here - https://stackoverflow.com/questions/7486309/how-to-make-script-execution-wait-until-jquery-is-loaded

Leaving scripts alone in theme.liquid

I modified the sample code of nanogallery2 page code.  ((The defer tag being required in source script)

So many ways to do a task in JS - I'm open for suggestions if I should be taking another approach. 

But for now its working so I'm going to attempt duplicate our old jquery gallery from our old website using this defer method.

Thanks for help.

 

<head>
<script  type="text/javascript" src="https://cdn.jsdelivr.net/npm/nanogallery2@3/dist/jquery.nanogallery2.min.js" defer='defer'></script>
</head>

<body>
<script>
var waitForJQuery = setInterval(function () {
if (typeof $ != 'undefined') {
jQuery(document).ready(function () {

jQuery("#nanogallery2").nanogallery2( {
// ### gallery settings ### 
thumbnailHeight:  150,
thumbnailWidth:   150,
itemsBaseURL:     'https://nanogallery2.nanostudio.org/samples/',
                       
// ### gallery content ### 
items: [
{ src: 'berlin1.jpg', srct: 'berlin1_t.jpg', title: 'Berlin 1' },
{ src: 'berlin2.jpg', srct: 'berlin2_t.jpg', title: 'Berlin 2' },
{ src: 'berlin3.jpg', srct: 'berlin3_t.jpg', title: 'Berlin 3' }
]
});
});
clearInterval(waitForJQuery);
}
}, 10);
</script>
</body>

 

diego_ezfy
Shopify Partner
2935 562 883

@SHPMP 

Very likely because it's being loaded twice, though I'd need to debug it to be sure. Usually jQuery is imported in a vendors.js file on Shopify free themes (which I assume is what you're using), so importing it again will make it be ignored or cause conflict.

Replace the code you shared:

<script>
jQuery(function() {
jQuery('body').on('click', '[name="checkout"], [name="goto_pp"], [name="goto_gc"]', function() {
var formIsValid = true;
var message = "Please inform us ........";
jQuery('[name^="attributes"], [name="note"]').filter('.required, [required="required"]').each(function() {
jQuery(this).removeClass('error');
if (formIsValid && jQuery(this).val() == '') {
formIsValid = false;
message = jQuery(this).attr('data-error') || message;
jQuery(this).addClass('error');
}
});
if (formIsValid){
jQuery(this).submit();
}
else {
alert(message);
return false;
}
});
});
</script>

<script>
$(window).on("beforeunload", function() {
var cartForm = jQuery('form[action="/cart"]');
if (cartForm.size()) {
var params = {
type: 'POST',
url: '/cart/update.js',
data: cartForm.serialize(),
dataType: 'json',
async: false
};
jQuery.ajax(params);
}
});
</script>


With the code I gave you:

<script>
async function loadSomething(){
while(!window.hasOwnProperty("jQuery")){
await new Promise(resolve => setTimeout(resolve, 100));
}

jQuery(function() {
jQuery('body').on('click', '[name="checkout"], [name="goto_pp"], [name="goto_gc"]', function() {
var formIsValid = true;
var message = "Please inform us ........";
jQuery('[name^="attributes"], [name="note"]').filter('.required, [required="required"]').each(function() {
jQuery(this).removeClass('error');
if (formIsValid && jQuery(this).val() == '') {
formIsValid = false;
message = jQuery(this).attr('data-error') || message;
jQuery(this).addClass('error');
}
});
if (formIsValid){
jQuery(this).submit();
}
else {
alert(message);
return false;
}
});
});
</script>

<script>
$(window).on("beforeunload", function() {
var cartForm = jQuery('form[action="/cart"]');
if (cartForm.size()) {
var params = {
type: 'POST',
url: '/cart/update.js',
data: cartForm.serialize(),
dataType: 'json',
async: false
};
jQuery.ajax(params);
}
});

}

loadSomething();
</script>
◦ Follow my blog & youtube for coding tutorials. Most questions in here are already answered there!
◦ Top #4 Shopify Expert, 24h reply. Click here to hire me.
Download copy/paste code snippets that can replace most apps.

SHPMP
Tourist
8 1 1

I believe you are right that jquery might being loaded twice.  Yes using the free Debut theme.  I did review vendor.js - but not sure what I'm looking for specifically.

I don't see any code referencing - <script type="text/javascript" src="...../jquery.min.js"></script>   

When I originally setup cart scripts I read to add the jquery source in theme.liquid - above the header.   And neither of scripts functioned until added.

 

I tried the code you shared.  Has same syntax errors that I encountered earlier when I guessed implied start / close tags.  See screenshots.  (Cart scripts also non functional)

If I have theme.liquid loading jquery above header the sample nanogallery2:

SHPMP_0-1613355136325.pngSHPMP_1-1613355186271.png

 

Then trying without jquery load above theme.liquid header

SHPMP_2-1613355294784.png

I was able to clone our old gallery and develop on it today using the other method.  So I should be able to easily modify my gallery page to load using this method.

Thanks for help.

diego_ezfy
Shopify Partner
2935 562 883

@SHPMP 

The standard Shopify theme structure is often times different than a default HTML website: whilst you may import external libraries using a script tag in your website, Shopify themes tend to load it all together within one single file, typically named vendors.js. 

Therefore it makes sense that you wouldn't find any <script type="text/javascript" src="...../jquery.min.js"></script> in your theme.

You can use this Google Chrome extension to search the files in your theme and see where jQuery shows up.

https://chrome.google.com/webstore/detail/shopify-theme-file-search/mhchmhfecfdpaifljcfebnlaiaphfkmb

Kind regards,
Diego

 

◦ Follow my blog & youtube for coding tutorials. Most questions in here are already answered there!
◦ Top #4 Shopify Expert, 24h reply. Click here to hire me.
Download copy/paste code snippets that can replace most apps.

SHPMP
Tourist
8 1 1

This is an accepted solution.

Thanks Diego for your help on our site. 

For any onlookers.

A viable solution for my "not a function" error in which thread started was

var waitForJQuery = setInterval(function () {
    if (typeof $ != 'undefined') {

        // place your code here.

        clearInterval(waitForJQuery);
    }
}, 10);

As mentioned here.  https://stackoverflow.com/questions/7486309/how-to-make-script-execution-wait-until-jquery-is-loaded

Also - For any in need of assistance with their site.  I'd recommend Diego_ezfy - Good support.  Affordable rate.

 

monomyth_io
Tourist
5 0 0

Just to follow up here, I was able to resolve this issue by moving my custom js to the bottom of the <body>.