'this' not being set correct using jQuery and CoffeeScript - javascript

I am trying to write a rather simple "select all" feature, but I am getting errors with my javascript. The code is rather straight forward, so I'll just post it:
(function() {
$(function() {
var all_check_box;
all_check_box = '#tournament_league_127';
return $(all_check_box).change(function() {
return $('.leagueCheckBox').each(function() {
return this.prop("checked", true);
});
});
});
}).call(this);
This code was generated by the following CoffeeScript:
$ ->
all_check_box = '#tournament_league_127'
$(all_check_box).change ->
$('.leagueCheckBox').each ->
this.prop("checked", true)
However, when I click #tournament_league_127, I get the following error: this.prop is not a function. I'm not really sure what I'm doing wrong. Any help would be appreciated.

this refers to the element not the jQuery object so you need,
return $(this).prop("checked", true);

It should be $(this).prop ...(assuming jQuery 1.6+, before that .prop did not exist).

Related

Javascript functions in associative array "is not a function"

Recently I learned Javascript ES6 has classes so I tried them but my functions were always giving me errors saying they don't exist. So I made pseudo-classes using javascript associative arrays. It was working absolutely fine until I added some new methods.
Here is the error message I'm receiving:
EventListener.js:132 Uncaught TypeError: this.listen_for_tab_swap is not a function
at HTMLDivElement.<anonymous> (EventListener.js:132)
at Object.alert_eventlistener_of_tabs (EventListener.js:41)
at Object.new_tab (EventListener.js:59)
alert_eventlistener_of_tabs # EventListener.js:41
new_tab # EventListener.js:59
xhr.onreadystatechange # EventListener.js:94
XMLHttpRequest.send (async)
(anonymous) # EventListener.js:101
Here is the relevant code body:
const eventListener = {
listen_for_tab_swap: function() {
$(".footer button").on("click", function (event) {
file_tabs.show_tab(event.target.innerText);
});
},
listen_for_tabs_activation: function() {
$("#AZ_content").on("tabs_loaded", function () {
this.listen_for_tab_swap();
});
},
listen: function() {
$(function () {
console.log("Yeah, I'm listening...");
$(".menu").on("click", function (event) {
AZ_page_is_opened(event);
showTab(event, event.target.id.replace("Button", ""));
});
});
}
};
Please let me know if there is any additional information required to troubleshoot. Thanks in advance for any help.
In js this is dynamic. It depends on how a function is called. I'm assuming you're using jQuery because it looks like jQuery syntax at a glance so for your specific case all you need to know is that in jQuery (and also in regular javascript) the value of this in an onclick event is the element that triggered the event:
{
// ...
listen_for_tabs_activation: function() {
$("#AZ_content").on("tabs_loaded", function () {
this.listen_for_tab_swap(); // this is AZ_content
});
}
In the code above what you are doing is trying to call $("#AZ_content")[0].listen_for_tab_swap() and it is complaining that that HTML element does not have a method called listen_for_tab_swap
There are several ways to fix this. The simplest is probably do:
eventListener.listen_for_tab_swap();
You can also use arrow functions to bind this:
{
// ...
listen_for_tabs_activation: function() {
$("#AZ_content").on("tabs_loaded",() => { // this fixes `this`
this.listen_for_tab_swap();
});
}
There are several more ways to solve this. Check out this answer to another related question for how this actually behaves: How does the "this" keyword in Javascript act within an object literal?

Cannot set property 'classRules' of undefined

am just don't know what happened it was work correctly .... What's most reasons that led us to this error ????
I was trying to run my website locally then this error comes to me from I don't know so what is this error mean and how can I solve it
the error occurs in this code .... actually , its complete website and I'm a beginner with JS and SO so please help me
// disable class and attribute rules defined by jquery.validate
$.validator.classRules = function() {
return {};
};
$.validator.attributeRules = function() {
return {};
};
Your Code tries to access an non existing JQuery namespace. You are either missing some sort of JQuery plugin, or you need to create on your self.
If you would like to create the validator namespace you can use such sample code as described here
(function ($) {
// do not overwrite the namespace, if it already exists
$.validator= $.validator|| {};
$.validator.classRules = function () { return {};}
$.validator.attributeRules = function () { return {};}
})($);

How do I use a function as a variable in JavaScript?

I want to be able to put the code in one place and call it from several different events.
Currently I have a selector and an event:
$("input[type='checkbox']").on('click', function () {
// code works here //
});
I use the same code elsewhere in the file, however using a different selector.
$(".product_table").on('change', '.edit_quantity', function () {
// code works here //
});
I have tried following the advice given elsewhere on StackOverflow, to simply give my function a name and then call the named function but that is not working for me. The code simply does not run.
$(".product_table").on('change', '.edit_quantity', function () {
calculateTotals() {
// code does not work //
}
});
So, I tried putting the code into it's own function separate from the event and call it inside the event, and that is not working for me as well.
calculateTotals() {
// code does not work //
}
So what am I doing wrong ?
You could pass your function as a variable.
You want to add listeners for events after the DOM has loaded, JQuery helps with $(document).ready(fn); (ref).
To fix your code:
$(document).ready(function() {
$("input[type='checkbox']").on('click', calculateTotalsEvent)
$(".product_table").on('change', '.edit_quantity', calculateTotalsEvent)
});
function calculateTotalsEvent(evt) {
//do something
alert('fired');
}
Update:
Vince asked:
This worked for me - thank you, however one question: you say, "pass your function as a variable" ... I don't see where you are doing this. Can you explain ? tks. – Vince
Response:
In JavaScript you can assign functions to variables.
You probably do this all the time when doing:
function hello() {
//
}
You define window.hello.
You are adding to Global Namespace.
JavaScript window object
This generally leads to ambiguous JavaScript architecture/spaghetti code.
I organise with a Namespace Structure.
A small example of this would be:
app.js
var app = {
controllers: {}
};
You are defining window.app (just a json object) with a key of controllers with a value of an object.
something-ctlr.js
app.controllers.somethingCtlr.eventName = function(evt) {
//evt.preventDefault?
//check origin of evt? switch? throw if no evt? test using instanceof?
alert('hi');
}
You are defining a new key on the previously defined app.controllers.somethingCtlrcalled eventName.
You can invoke the function with ();.
app.controllers.somethingCtlr.eventName();
This will go to the key in the object, and then invoke it.
You can pass the function as a variable like so.
anotherFunction(app.controllers.somethingCtlr.eventName);
You can then invoke it in the function like so
function anotherFunction(someFn) { someFn();}
The javascript files would be structured like so:
+-html
+-stylesheets
+-javascript-+
+-app-+
+-app.js
+-controllers-+
+-something-ctlr.js
Invoke via chrome developer tools with:
app.controllers.somethingCtlr.eventName();
You can pass it as a variable like so:
$(document).ready(function() {
$('button').click(app.controllers.somethingCtlr.eventName);
});
JQuery (ref).
I hope this helps,
Rhys
It looks like you were on the right track but had some incorrect syntax. No need for { } when calling a function. This code should behave properly once you add code inside of the calculateTotals function.
$(".product_table").on('change', '.edit_quantity', function () {
calculateTotals();
});
$("input[type='checkbox']").on('click',function() {
calculateTotals();
});
function calculateTotals() {
//your code...
}
You could just condense it all into a single function. The onchange event works for both the check box and the text input (no need for a click handler). And jQuery allows you to add multiple selectors.
$('input[type=checkbox], .product_table .edit_quantity').on('change', function() {
console.log('do some calculation...');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="product_table">
<input type="checkbox">
<input class="edit_quantity">
</div>

jQuery Plugin public methods not working when applied to multiple elements

I posted a similar issue earlier, but it was flagged as a duplicate. However, this referenced article did not answer my question, so I'll try this again, this time using the solution of said article in my example.
The solution provided in this article creates the same issue I had before: when there is more than one element, I cannot call any of the public methods of the plugin.
Since no working example was provided, let's start with the code the article gave:
(function($){
$.fn.myPlugin = function(options) {
// support multiple elements
if (this.length > 1){
this.each(function() { $(this).myPlugin(options) });
return this;
}
// private variables
var pOne = '';
var pTwo = '';
// ...
// private methods
var foo = function() {
// do something ...
}
// ...
// public methods
this.initialize = function() {
// do something ...
return this;
};
this.bar = function() {
// do something ...
};
return this.initialize();
}
})(jQuery);
I LOVE the internal loop so that it's applied to each instance of the element, but I feel the repeated "return this" is redundant. I think if we removed every single one of them, this plugin would work exactly the same. But, for the sake of argument, I'm going to leave them in my working example.
As you can see in this jsfiddle example, it works fine when there is only one element. The public method runs fine.
However, if I were to comment the other 4 elements back in like here, it throws an error in the console: "undefined is not a function". This, of course, makes sense since I'm attempting to run the public method on a reference to all elements on not an individual element.
Well, then I use .eq(0) to run the method only on the first instance of the element here, but I get the exact same error in the console.
So, why isn't calling the public method on the individual element working? Is this a scoping issue?
Please advise. Thanks!
Ok, so I think I've answered my own question. The issue is that I'm not applying a jQuery plugin to a DOM element. I'm applying it to a jQuery element. So, if I were to apply the jQuery plugin to a jQuery element, referenced like $element or $('.element'), I can then run any public methods because the scope is the same. But, if I were to reference it in a different way, like say $parentelement.eq(0), I'm using a difference reference, one that did not get the plugin applied to it, so naturally, it would not have the defined method. I think I'm getting the concept right. Still a little shaky on this. Maybe someone else can explain it better.
Nevertheless, while the above code does technically work, public methods are not practical on a jQuery plugin. I suggest instead using a Custom Event to make the jQuery plugin do something. Like this:
(function($) {
$.fn.extend({
myTestPlugin: function() {
if (this.length > 1) {
this.each(function() { $(this).myTestPlugin(); });
}
this.done = function() {
$(this).html('Done!');
};
var alsoDone = function() {
$(this).html('Also done!');
};
this.html('Replace me!');
this.on('alsoDone', alsoDone);
}
});
})(jQuery);
Here is an example where I am using trigger to make the plugin do something on an individual element, which works, but the method still fails as expected.
I hope this helps other people with similar issues.

Correct jQuery markup

How would I write the following code to jQuery?
$("select").change(function(){
if($("#selectedid").is(":selected")){
$("#showblock").slideDown("slow");
} else { $("#showblock").slideUp("slow"); }
});
I also tried the following:
jQuery("select").change(function($){
if($("#selectedid").is(":selected")){
$("#showblock").slideDown("slow");
} else { $("#showblock").slideUp("slow"); }
});
It's for wordpress.
Thanks!
In wordpress you'll probably get errors because wordpress includes a version of jquery that is editted to not use the '$' operator
you have to replace every instance of the '$' with jQuery
so your code should look like this;
jQuery("select").change(function(){
if(jQuery("#selectedid").is(":selected")){
jQuery("#showblock").slideDown("slow");
} else {
jQuery("#showblock").slideUp("slow");
}
});
try that and tell me how it works for you.
an easier way would be just to include a standard (downloaded) version of jquery and include it in your header.php
I think it happening because You have to resolve the conflict for "$"
From Word Press Codex
jQuery(document).ready(function($) {
// Inside of this function, $() will work as an alias for jQuery()
// and other libraries also using $ will not be accessible under this shortcut
});
You need to just wrap your code into immediately invoking function and pass Jquery to it.
(function($) {
$("select").change(function(){
if($("#selectedid").is(":selected")){
$("#showblock").slideDown("slow");
} else {
$("#showblock").slideUp("slow");
}
});
})(jQuery);

Categories