I only have one function in my scripts page, and it is giving me this error: Uncaught TypeError: Illegal invocation. To be honest, I've never seen this error before, and none of the other cases that I found online seemed to apply to me. My jquery is below, and I don't think any other pieces are necessary, but let me know and I can post other parts.
$(document).ready(function () {
/*----UPDATE BOX REQUEST----*/
$(".boxesChange").live("click", function () {
entry = $(this).closest("tr");
delivered = $(entry).find("#delivered");
if ((delivered).is(":checked")) {
deliveredBoolean = "1";
} else {
deliveredBoolean = "0";
}
boxesDelivered = $(entry).find("#boxesDelivered").val();
bubbleWrapDelivered = $(entry).find("#bubbleWrapDelivered").val();
supplyRequestId = $(entry).find(".boxesSupplyRequestId").val();
$.post('boxesChange.php', {
'delivered': delivered,
'boxesDelivered': boxesDelivered,
'bubbleWrapDelivered': bubbleWrapDelivered,
'supplyRequestId': supplyRequestId
}, function (response) {
$(this).closest(".boxesScheduleEntry").css("background-color", "#ccffcc");
});
return false;
});
});
The problem is in your $.post call. You're trying to set 'delivered' to delivered, which is a jQuery object, I assume you meant deliveredBoolean.
Also, in the callback function this is not what you think it is, it's the jqXHR object, not the element.
var $this = $(this);
$.post(
'boxesChange.php',
{
'delivered': deliveredBoolean,
'boxesDelivered': boxesDelivered,
'bubbleWrapDelivered': bubbleWrapDelivered,
'supplyRequestId': supplyRequestId
},
function (response) {
$this.closest(".boxesScheduleEntry").css("background-color", "#ccffcc");
}
);
I assume the error is inside of this part:
function (response) {
$(this).closest(".boxesScheduleEntry").css("background-color", "#ccffcc");
}
Here I think you want this to be the same as above when you are using closest to get the "tr" element. But in here this is the context of the $.post imho.
You either need to bind or rather do var boxChange = $(this), at the top of the event handler function and use the cached reference afterwards
Related
I currently have created a piece of Javascript code which checks a http response and if its a successful 200 code the traffic light shows green and if its not a 200 code the traffic light flashes red.
My current problem at the moment is I want to be able to pass Two arguments to the initializing function like so
requestResponses.init('/status', "ATTR");
The first attribute being the URL I want to test against and the second attribute being the value of the HTML5 data-request attribute I have created.
My reason for this as I want to have multiple traffic lights on the same page targeting different URL's simultaneously without effecting each other.
So for Example I create a data request attribute and give it a value of Four I then want to be able to hook it up like so
requestResponses.init('/status', "Four");
and start targeting elements like below within the code. This makes it that bit more modular and reusable.
.cp_trafficLight[data-request="Four"]
Please find my code attached and a working JSFiddle.
var requestResponses = {
greenLight: $('.cp_trafficLight_Light--greenDimmed'),
redLight: $('.cp_trafficLight_Light--redDimmed'),
greenBright: 'cp_trafficLight_Light--greenBright',
redBright: 'cp_trafficLight_Light--redBright',
settings: {
flashError: 400,
requestTime: 10000
},
init: function (url, targAttr) {
requestResponses.url = url;
requestResponses.getResponse(requestResponses.url, targAttr);
setInterval(function () {
if (requestResponses.errorCode === true) {
requestResponses.redLight.toggleClass(requestResponses.redBright);
}
}, requestResponses.settings.flashError);
},
successResponse: function (targAttr) {
requestResponses.errorCode = false;
requestResponses.redLight.removeClass(requestResponses.redBright);
requestResponses.greenLight.addClass(requestResponses.greenBright);
console.log(targAttr);
},
errorResponse: function (targAttr) {
requestResponses.greenLight.removeClass(requestResponses.greenBright);
},
getResponse: function (serverURL, targAttr) {
$.ajax(serverURL, {
success: function () {
requestResponses.errorCode = false;
requestResponses.successResponse(targAttr);
},
error: function () {
requestResponses.errorCode = true;
requestResponses.errorResponse(targAttr);
},
complete: function () {
setTimeout(function () {
requestResponses.getResponse(requestResponses.url);
}, requestResponses.settings.requestTime);
}
});
},
errorCode: false
}
requestResponses.init('/status', "TEST");
https://jsfiddle.net/8700h582/
Appreciate any help!
Then in your function you include a second parameter separated with a comma.
function foo(param1, param2) {
//Do something.
};
foo("1st", "2nd");
EDIT
i see now in your init include the second param for the light and in the init function pass this second param to your request and then from there pass it down to your error and respons function. And then return the function. That can be held in a var.
In p5.js, How do you make a DOM element callback a function if both the DOM element and the function are inside the same object ? for example :
function Snape()
{
this.myInput = createInput("");
this.myInput.changed(this.erase);
this.erase = function()
{
}
}
when I type something in this.myInput, I would like it to call the function this.erase, but I get the error 11913: Uncaught TypeError: Cannot read property 'bind' of undefined
is it possible ?
——————————————————————————————————————————
EDIT : The main issue is solved if I declare this.erase before I call it :
function Snape()
{
this.myInput = createInput("");
this.erase = function()
{
}
this.myInput.changed(this.erase);
}
but that’s a really messy way to do it.
Moreover, I wasn’t able to implement what was suggested in the answer :
In p5.js, the way we invoke a callback is like this :
this.myInput.changed(this.erase);
if I do this
this.myInput.changed(this.erase());
I get this error : Uncaught TypeError: undefined is not a function
So, when I try to call this.erase using this (as was suggested) :
this.myInput.changed(function(){ myself.erase(); });
I get the same error Uncaught TypeError: undefined is not a function
I tried all the different possibilities :
this.myInput.changed(function(){ myself.erase() });
this.myInput.changed(function(){ myself.erase; });
this.myInput.changed(function(){ myself.erase });
neither of those are working.
I can’t use the => function because I need to call this.erase a lot of times in different instance of the object, and from multiple DOM elements.
You have to save this into a variable so you can then reference it:
function Snape() {
var myself = this;
this.myInput = createInput("");
this.myInput.changed(function(){ myself.erase(); });
this.erase = function()
{
console.log("erased");
}
}
Another (less elegant) solution would be this:
var input;
function setup () {
createCanvas(500, 300);
input = new Snape () ;
}
function Snape () {
this.myInput = createInput("");
this.myInput.changed(tunnel);
this.erase = function()
{
console.log("erased");
}
}
function tunnel () {
input.erase();
}
Lately I've been working on a project that requires me to make numerous AJAX calls to a Symfony backend. Since each AJAX call is made to a different URI, I've ended up with a script that's really long, but with numerous .on('event', function(){...}) code blocks, like this:
$(document).ready(function(){
$('.class').on('click', function(e){
e.preventDefault();
//AJAX call
This is basically duplicated over and over again, but because of slight variations in the selector and the type of data to be received, I keep writing this same block of code over and over again.
I've been thinking of using a builder pattern (is it even possible in JS?) to trim the code. I'm not very good at javascript, so any help would be much appreciated.
UPDATE:
/**
* AJAX prototype
*
* #param options
* #constructor
*/
//set TestProtObj properties in the constructor
var AjaxProt = function (options) {
this.ajaxCallType = options.ajaxCallType;
this.targetEl = options.targetEl;
this.event = options.event;
this.method = options.method;
this.htmlFactory = options.htmlFactory;
};
//add methods to the object prototype
AjaxProt.prototype = {
init: function () {
var targetEl = this.targetEl;
targetEl.on(this.event, function(e) {
e.preventDefault();
this.ajaxCall();
})
},
modalCallback: function(successData) {
var modal = this.htmlFactory.createHtml({
title: 'Bet: Detailed View',
id: '#bet-detailed-model',
htmlType: 'modal'
});
if (successData.success = true) {
$('#content').prepend(modal);
$('#bet-detailed-model').modal({show:
true
});
} else {
$('#content').prepend(modal);
$('#bet-detailed-model').modal({
show: true
});
$('.modal-body').append(alert);
}
},
ajaxCall: function() {
var url = this.targetEl.attr('href'),
method = this.method,
ajaxCallType = this.ajaxCallType;
switch (ajaxCallType) {
case 'modalGet':
var callback = this.modalCallback();
break;
}
$.ajax({
url: url,
type: method,
success: function(data) {
callback(data)
}
});
}
};
//initialize client code
$(document).ready(function () {
// initialize new AjaxPro
var AjaxBetDetailed = new AjaxProt ({
ajaxCallType: 'modalGet',
targetEl: $('.ajax-ticket-view'),
event: 'click',
method: 'GET',
htmlFactory: new HtmlFactory()
});
//initialize concrete object
AjaxBetDetailed.init();
});
Unfortunately, it appears that my event handler is not binding, such that e.preventDefault is not working - all it does is follow the link. I'm really not used to writing classes in this way, so any help would be greatly appreciated.
UPDATE 2:
I've also written a proof of concept class in jsfiddle that tries to replicate the behaviour I want to achieve. It is also failing to bind the event handler - so that must be the problem. I don't seem to be able to solve it.
JSFiddle: Click Me Please!
You could reuse the same function with your "slight variations" as parameters:
function registerClick(className, url, param) {
$('.' + className).on('click', function(e) {
// Ajax call using url and param, for instance
});
}
And then use it:
registerClick('class', '/api/foo', 'bar');
registerClick('toto', '/api/foo', 'buzz');
That's not specific to JS but any kind of programming/scripting language: put all reusable code into a function (or an object if you want it oriented object, or a prototype if you want it oriented prototype, etc, but the idea is the same).
Sorry for yet another question about callbacks. In trying to solve this problem, I've run across about a million of them. However, I'm having trouble wrapping my head around this particular scenario.
I have the code below, which obviously doesn't work as delegates apparently don't return values (I'm learning as I go, here). So, I know I need a callback at this point, but I'm not sure how to change this code to do that. Can anyone help?
function MyFunction() {
var ThisLoggedInUser = checkCurrentUser();
//do some stuff with the current user
}
function checkCurrentUser() {
var context = SP.ClientContext.get_current();
var siteColl = context.get_site();
var web = siteColl.get_rootWeb();
this._currentUser = web.get_currentUser();
context.load(this._currentUser);
context.executeQueryAsync(Function.createDelegate(this, this.CheckUserSucceeded),
Function.createDelegate(this, this.CheckUserfailed));
}
function CheckUserSucceeded() {
var ThisUser = this._currentUser.get_title();
return ThisUser;
}
function CheckUserfailed() {
alert('failed');
}
Based on your comment, you have to rething the way you want your code because you cannot use ThisUser in MyFunction().
For example you could do that:
function CheckUser() { ... }
// then call the function to find the current user
CheckUser();
// then in CheckUserSucceeded you call MyFunction()
function CheckUserSucceeded() {
MyFunction(this._currentUser.getTitle())
}
// and now you can use ThisUser in MyFunction()
function MyFunction(ThisUser) {
// do something with ThisUser
}
Your CheckUserSucceed won't return anything because it's asynchronous....
So you have to do something like that:
var ThisUser;
function CheckUserSucceeded() {
ThisUser = this._currentUser.getTitle()
// here you can call an other action and do something with ThisUser
}
You may also want to check the $SP().whoami() function from http://aymkdn.github.io/SharepointPlus/ and see the documentation.
I have a question regarding developing object-orientated javascript and parsing variables. Please see this blog by net.tutsplus - The Basics of Object-Oriented JavaScript for more info.
I have the following code which creates an event:
$(document).ready(function() {
tools.addEvent('.someButton', 'click', user.getUserDetails);
)};
var tools = {
addEvent: function(to, type, fn) {
$(to).live(type, fn);
}
}
var user = {
getUserDetails: function(userID) {
console.log(userID);
}
}
As you can see, it calls the addEvent method with three variables; the DOM element to attach the event to, the type of the event and the function to run when the event is triggered.
The issue I am having is parsing a variable to the getUserDetails method and I know of 2 options:
I could obviously have 1 line of code at the start which could check an attribute of the sender. For example, the .someButton could have an attribute userID="12345". However, this is not ideal because the function is run from several different places - meaning this check is not always available (and the code is harder to manage).
A better option could be to have another method like user.willGetUserDetails and use this method to get the attribute userID from the DOM. This could be run from anywhere on the page, and would call getUserDetails after getting the userID. Whenever the user details comes from within another function, we would simply call getUserDetails directly.
What would be ideal, is if I could amend the code above to pass a variable directly - even an undefined one. Does anyone know how this could be achieved?
Add one more argument to your addEvent code that accepts data to pass to the event.
var tools = {
addEvent: function(to, type, data, fn) {
if ($.isFunction(data)) {
fn = data;
data = {};
}
$(to).live(type, data, fn);
}
}
Also, i'd suggest using delegate instead, or .on in 1.7+
var tools = {
addEvent: function(to, type, data, fn) {
if ($.isFunction(data)) {
fn = data;
data = {};
}
$(document).delegate(to, type, data, fn);
}
}
or
var tools = {
addEvent: function(to, type, data, fn) {
if ($.isFunction(data)) {
fn = data;
data = {};
}
$(document).on(type, to, data, fn);
}
}
Now you can use it like this:
$(document).ready(function() {
tools.addEvent('.someButton', 'click', {userID: theuserid}, user.getUserDetails);
)};
var user = {
getUserDetails: function(event) {
console.log(event.data.userID);
}
}