$ is not defined, but only on $(function()) - javascript

In my MVC partial view, the below does not fire:
$(function() {
alert('test');
});
The console reports that '$ is not defined.', which seems like jQuery is not referenced in the page.
However, in the same script block, I have other jQuery functions that work perfectly, so this problem seems isolated to just the $(function()) or $( document ).ready() on-load functions.
Here's the complete script block in the partial view:
<script type="text/javascript">
$(function () {
debugger;
alert('hi');
});
function updatePaymentTypes() {
$("#paymentTypes").empty();
$('#paymentTypes').append($('<option></option>').val("").html("- Please Select -"));
var getVoucherPaymentTypesUrl = "#Url.Action("getVoucherPaymentTypes", "Supplier", new { id = Model.Supplier.Id, area = "Configurations" })";
$.post(getVoucherPaymentTypesUrl, { "voucherPaymentMethodId": $("#paymentMethods").val() },
function (data) {
for (i = 0; i < data.length; i++) {
var paymentType = data[i];
$('#paymentTypes').append($('<option></option>').val(paymentType.Id).html(paymentType.Name));
}
// Force event
paymentTypeSelected();
});
}
function paymentTypeSelected() {
var getCardDetailsViewUrl = "#Url.Action("getVoucherCardDetailsView", "Supplier", new { id = Model.Supplier.Id, area = "Configurations" })";
$.post(getCardDetailsViewUrl, { "voucherPaymentTypeId": $("#paymentTypes").val() },
function (data) {
$("#cardDetailsView").html(data);
}).fail(function (error) {
debugger;
});
}
</script>
The partial view is being rendered within a jQuery Accordion div, and all jQuery functions in the parent view, including the $(function()) events all fire normally.
What could be wrong?

As most people pointed out in the comments, the problem is that the partial view is loaded before the script reference to jQuery.js has been rendered.
Make sure the script reference to jQuery is added on the top of the main view.

Related

jQuery .on change event binding but not firing

var myTimelineVis = {
loadData: function(visItems, visContainer, visOptions, visTimelines) {
$.getJSON('myURL/' + $(this).val(), function(data) {
visItems.clear();
$.each(data, function(i, imp_sched_events) {
$.each(imp_sched_events.items.timeline_dataset, function(i, item) {
visItems.add(item);
if ($(visContainer).is(':empty')) {
visTimeline = new vis.Timeline(visContainer, visItems, visOptions);
} else {
visItems.update(item);
}
visTimeline.fit();
$('.vis-item-content').foundation();
});
});
});
},
setData: function(selectClass) {
var visItems = new vis.DataSet(),
visContainer = document.getElementById('visualization'),
visOptions = {},
visTimeline = '';
$(selectClass).on('change', function(visItems, visContainer, visOptions, visTimelines) {
this.loadData(visItems, visContainer, visOptions, visTimelines);
});
}
}
$(document).ready(function() {
myTimelineVis.setData('select.implementation_schedule');
});
I am trying to trying to create a vis timeline on page load and then load data onto it when my select changes (I have two selects). On page load, I can see the change event binding to both selects within Chrome console, but nothing happens, not even an error, on the actual select change. It just acts like they don't exist.
Is this is a scope issue?
For jQuery, the listener would not be added in an Ajax call, but in the $(document).ready(). It works differently than vanilla JavaScript.
If the select is dynamically changed you would need to use the following syntax with a hard-coded selector. The selector can be broad like "#myForm select". There's no need to use a variable.
$(document).on('change', '.selectClass', function(visItems, visContainer, visOptions, visTimelines) {
this.loadData(visItems, visContainer, visOptions, visTimelines);
});
});

$(document).ready(function() with Meteor JS templates

I have a template I've deeply integrated with Meteor. It uses a scripts.js file that runs a bunch of commands after $(document).ready and $(window).load.
I put scripts.js inside of client/compatibility, and it works only if I do a hard refresh of the template. Otherwise, the template doesn't render and the functions don't execute.
Specifically, this code:
// Append .background-image-holder <img>'s as CSS backgrounds
$('.background-image-holder').each(function() {
var imgSrc = $(this).children('img').attr('src');
$(this).css('background', 'url("' + imgSrc + '")');
$(this).children('img').hide();
$(this).css('background-position', 'initial');
});
Much appreciated if you know how I should take it from here.
If you want a function to fire off when the DOM is loaded and all images, use this: (be forewarned, this is in ES6)
let imgCount;
let imgTally = 0;
Template.myTemplate.onRendered(function () {
this.autorun(() => {
if (this.subscriptionsReady()) {
Tracker.afterFlush(() => {
imgCount = this.$('img').length;
});
}
});
});
Template.myTemplate.events({
'load img': function (event, template) {
if (++imgTally >= imgCount) {
(template.view.template.imagesLoaded.bind(template))();
}
}
});
Then you just need to declare imagesLoaded which will get fired off when all images are done.
Template.myTemplate.imagesLoaded = function () {
// do something
};
Place this stuff in the onRendered function of the template.
Template.<name>.onRendered(function(){
//do your jquery business here!
});
For more info check the docs

How can i add $(document).ready(function(){}) after a function in java script

What I want to do is I have a code like below :
$(document).ready(
function(){
var currentPage = window.location.pathname;
$('#main-menu-list').find('a[href^="' + currentPage + '"]').closest('li').addClass('active');
}
)
And now I want to add this code to add and get work with other code. I need to add this code after this one:
function () {
/* If there are forms, make all the submit buttons in the page appear
disabled and prevent them to be submitted again to avoid accidental
double clicking. See Issue 980. */
jQuery(function() {
/* Delegate the function to document so it's likely to be the last event
in the queue because of event bubbling. */
jQuery(document).delegate("form", "submit", function (e) {
var form = jQuery(this);
if (form.hasClass("form_disabled")) {
e.preventDefault();
return false;
}
else {
form
.addClass("form_disabled")
.find(":submit")
.addClass("disabled");
}
// Reactivate the forms and their buttons after 3 secs as a fallback.
setTimeout(function () {
form
.removeClass("form_disabled")
.find(":submit")
.removeClass("disabled");
}, 3000);
});
});
}
How can I get this done. Please help me out to solve this problem.
You can create document.ready() anywhere in script. It is not necessary all of your code should be in ready function.
You can create instance variable for function and call it where you need:
$(document).ready(
var myFunc = function(){
var currentPage = window.location.pathname;
//other code
}
...
//and invoke it where you need
myFunc();
)
First, name the long function in your code section, for example, launchFormControls(). And then define the function outside of the document ready event. A good practice would be to do so and keep the ready event body clean.
For example:
function launchFormControls() {
//function code
}
Or, in other syntax:
var launchFormControls = function() {
//function code
}
Second, call your function from within the document ready event. Your function will be defined and able to call once the document is loaded. This code can be placed at the top or bottom of your javascript section or file.
For example:
$(document).ready(function(){
var currentPage = window.location.pathname;
$('#main-menu-list').find('a[href^="' + currentPage+'"]').closest('li').addClass('active');
launchFormControls();
});

Trouble calling JavaScript function on page load

I have a javascript function that i have named refreshProjects(), what it does is filter a dropdownlist depending on what was selected in a previous dropdownlist. But i need to also filter my list direcktly after the page has finishd loading.
I have tried using the code window.onload = refreshProjects(id) with no sucsses, but onload workes when i use window.onload = alert('This page has finished loading!'), so i know that part off the script works. So how do i call a javascript function on load, i thought that it would be simple but evrything i tried have failed.
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
<script type="text/javascript">
window.onload = refreshProjects(id); <-- Problem
$("#ddCustomers").change(function () {
refreshProjects($(this).val());
});
function refreshProjects(id) {
var projects = $("#ddProjects");
$.get('#Url.Action("FilterProjects","TimeEntry")', { customerId: id },
function (result) {
// clear the dropdown
projects.empty();
//Add a deafult "null" value
$("#ddProjects").get(0).options[0] = new Option("[ - No project - ]", "-1");
// rebuild the dropdown
$.each(result, function (i, e) {
projects.append($('<option/>').text(e.Text).val(e.Value));
});
});
}</script>
}
This is for MVC 4.5.
Try changing window.onload = refreshProjects(id); to:
window.onload = function() { refreshProjects($("#ddCustomers").val()); };
Onload expects a callback function. You were directly executing refreshProjects() and setting the return value as the onload.
But since you seem to be using jQUery, you could do the following:
$(function() {
refreshProjects($("#ddCustomers").val());
});
This will execute refreshProjects when the document is ready (which actually is before window load).
You can also try to use the following:
$(document).ready(function () {
refreshProjects(id);
});
This should work aswell if you are using jQuery.

Structure javascript and delay execution when dynamically loading scripts

I'm loading my javascript files using Modernizr.load(). Now lets say each page needs to call their own init method after everything has finished loading. But I put the loading in a template master, which is unaware of the child pages. How can the pages know when the dependencies have finished loading?
script
Page1Stuff= {
init: function(){ alert('page 1 executed'); }
}
Page2Stuff= {
init: function(){ alert('page 2 executed'); }
}
site master template
//Modernizr loads the script.
Modernizr.load([{
load: 'jquery.js',
},
{
load: 'script.js'
}]);
page1
$(function() {
Page1Stuff.init();
});
page2
$(function() {
Page2Stuff.init();
});
I think I see 2 problems here. If modernizr is still loading jquery, $ may not be defined. Also, Page2Stuff or Page1Stuff may not be defined.
In your template: Use the modernizer "complete" call back to emit a custom event to signal the loading is complete, also set a global variable saying that the scripts have been loaded.
In your page scripts: first check the global variable to see if all scripts have been loaded, if not, register a handler to listen for the custom event you emit when the loading completes.
In your template code:
// A simple object that calls its listeners when modernizer script loading completes.
global_scriptLoadingMonitor = (function() {
var listeners = [];
var isComplete = false;
return {
"addListener": function (listener) {
listeners[listeners.length] = listener;
},
"complete": function () {
isComplete = true;
for (var i = listeners.length - 1; i >= 0; i--) {
listeners[i]();
}
},
"isComplete": isComplete
}
})();
Modernizr.load([{
load: 'jquery.js',
},
{
load: 'script.js'
complete: function () {
{
global_scriptLoadingMonitor.complete();
}
}]);
Now in your Page1 do this:
if (global_scriptLoadingMonitor.isComplete) {
$(function() {
Page1Stuff.init();
});
} else {
global_scriptLoadingMonitor.addListener(function() {
$(function() {
Page1Stuff.init();
});
});
}
And similarly for page2.

Categories