The select2:select event gives you data about the selected object. change event does not. Hence for initializing my selects:
async function initSelect(jobj, getDataParams, width, callback) {
try {
if (jobj.data('select2Id') || jobj.data('select2')) {
jobj.select2('destroy').empty()
}
} catch (e){}
try {
if(callback) {
jobj.on('select2:select', function (e) {
callback(e)
});
}
}
}
I have dependent selects, for example, if you select SelectA, SelectB gets initialized. I would like to be able to programmatically select an element in SelectA, and for it to trigger its select2:select event which would then destroy and repopulate SelectB.
Currently all the answers I've seen on the internet say to $('#selectA').val(301235).trigger('change') but that does not cause SelectA's select2:select event and so I can't execute the callback that knows selectA's data to use to populate SelectB.
Looks like instead of trying to grab the data from the event, like which was provided to me in select2:select, but not change, just obtain the data from the currently selected item in the callback:
if(callback) {
jobj.on('change', function (e) {
// var data = jobj.select2('data')[0]);
callback(e)
});
}
Related
How can I trigger or fire or invoke save method of kendo scheduler control from moveEnd. once I preventDefault moveEnd event?
function scheduler_moveStart(e) {
log("moveStart", e);
}
function scheduler_move(e) {
log("move", e);
}
function scheduler_moveEnd(e) {
log("moveEnd", e);
e.preventDefault();
// my logic goes here
//
// line of code
//
// fire save event from here.
}
function scheduler_save(e) {
log("save", e);
}
I think you are talking about saving the scheduler's event, so you can use saveEvent() method. But, there is another option which you can save dataSource's data, in case you have added the event in your dataSource prior to save in database, by using sync():
function scheduler_moveEnd(e) {
log("moveEnd", e);
e.preventDefault();
var scheduler = $("#scheduler").data("kendoScheduler");
// Saving by scheduler's saveEvent()
scheduler.saveEvent();
// Saving by dataSource's sync()
scheduler.dataSource.sync();
}
I resolve this using below code:
use editEvent and pass current event as argument.
e.sender.editEvent(e.event);
e.sender.saveEvent();
I'm super confused by my code. Let me show what it looks like:
$(document).ready(function ($) {
var customer_exists = false;
$.get(window.additional_parameters.customer_exists_url, "json")
.done(function () {
customer_exists = true;
})
.always(function () {
// Don't make request to buy clickable until we know if the customer exists
$('#request-to-buy').on('click', function(e) {
request_to_buy(customer_exists);
});
});
function request_to_buy(customer_exists) {
response = can_request_to_buy();
response.done(function (response) {
if (customer_exists) {
// Actually create the request on the server
$.post(window.additional_parameters.request_to_buy_url,
{'ticket_id': window.additional_parameters.ticket_id},
"json")
.done(function (response) {
request_to_buy_success(response);
})
.fail(function () {
var message = handle_ajax_response(response);
show_ajax_message(message);
});
} else {
show_pre_stripe_popup();
}
})
.fail(function (response) {
var error_message = handle_ajax_response(response);
show_ajax_message(error_message, 'danger');
});
}
$(document).ready(), we set a variable called customer_exists. This variable guides the path of the code afterwards and is pretty important. If the $.get AJAX request is successful, it's true, otherwise it remains it default value of false. After the AJAX response, we attach a click event to "#request-to-buy." My goal here is to create a closure and pass in the value of customer_exists that was just set. This doesn't happen.
A good portion of the time ( I had it work correctly once or twice ), when I inspect request_to_buy in the debugger, I can see that customer_exists is a jQuery click event. why ??? Shouldn't it take on the value of the customer_exists from the surrounding scope of where the function was created? Can anyone explain what is going on here?
Thank you
EDIT: Here's a little more information that describes how it works sometimes...
The first time that I click '#request-to-buy', the handler is
function(e) {
request_to_buy(customer_exists);
}
This is what we would expect. e contains the click event, customer_exists retains it's value, and everything works inside request_to_buy.
Every time I click '#request-to-buy' after the first, instead of the above function being called, request_to_buy is called directly, and instead of passing in customer_exists in the first parameter, the click event is passed in instead. I hope this helps someone.
You should be able to do this without the need for the cumbersome outer var customer_exists.
For example :
$(document).ready(function ($) {
$.get(window.additional_parameters.customer_exists_url, "json").then(function () {
// Don't make request to buy clickable until we know if the customer exists
$('#request-to-buy').on('click', request_to_buy);
}, function() {
$('#request-to-buy').on('click', show_pre_stripe_popup);
});
function request_to_buy(e) {
e.preventDefault();
can_request_to_buy().then(function(response) {
// Actually create the request on the server
$.post(window.additional_parameters.request_to_buy_url, {
'ticket_id': window.additional_parameters.ticket_id
}, "json").then(request_to_buy_success, function() {
show_ajax_message(handle_ajax_response(response));
});
}).fail(function(response) {
show_ajax_message(handle_ajax_response(response), 'danger');
});
}
}
show_pre_stripe_popup will also be passed an event and you may need to do e.preventDefault(); there too.
You will need to check that the correct parameters are passed to the various error handlers. I can't verify them.
If it still doesn't work, then you must suspect other code that's not included in the question, for example the function can_request_to_buy().
var customer_exists = false;
Declare this outside of ready block.
$('.btn-delete').on('click', this.confirm.bind(this));
Above, on click it runs:
p.confirm = function(e) {
if(!$(this).hasClass('danger')){
$(this).addClass('danger');
$(this).bind('mouseleave',function(){
$(this).removeClass('danger');
$(this).unbind('mouseleave');
});
}
else{
this.delete();
}
};
I'm having trouble with this. I need this to get the button but I also need this to access another method (this.delete). I've tried bind but it faisl to work.
Any ideas?
Assuming I'm understanding your question correctly, you want to be able to pass the clicked element as this to the p.confirm function. You should be able to do this by using call, or by using p.confirm as the handler:
// using call
$('.btn-delete').on('click', function (e) {
p.confirm.call(this, e);
});
// as handler
$('.btn-delete').on('click', p.confirm);
Assuming that this.delete is actually p.delete, just use call in the handler to pass the clicked element as this to the delete method:
p.confirm = function (e) {
var self = $(this); // cache lookup, "this" is the clicked element
if (!self.hasClass('danger')) {
self.addClass('danger');
self.bind('mouseleave', function () {
self.removeClass('danger');
self.unbind('mouseleave');
});
} else {
p.delete.call(this); // pass clicked element to use as "this" in p.delete
}
};
I need to fire a custom event each time when clicked on div with different data attached.
Here is a simplified variant of my code (JSFiddle):
<div onclick="selectItem(Math.random())">click me</div>
<script>
function selectItem(id) {
var event_data = {
myid: id
};
if (!arguments.callee.event)
arguments.callee.event = new CustomEvent("selectItem", {detail: event_data});
arguments.callee.event.detail = event_data; // no success here
document.dispatchEvent(arguments.callee.event);
}
document.addEventListener("selectItem", function(event) {
console.log(event.detail); // same thing all the time :(
});
</script>
But in the event listener function I receive the same data each time the event is fired. I tried to change the event before dispatchEvent but seems it is read only object.
Is there any other options to send different data each time i click on div?
The reason is that detail property of the event can be any object but they are read only, i.e they can be set only when the event is created.Iit is specifically used to provide details regarding the event, and not for attaching data for each dispatch of the event.
interface CustomEvent {
readonly attribute any detail;
};
Probably you can just set a custom property data to the event during each dispatch and access that property.
Try:
function selectItem(id) {
var event_data = {
myid: id
};
if (!arguments.callee.event) arguments.callee.event = new CustomEvent("selectItem");;
arguments.callee.event.data = event_data;
document.dispatchEvent(arguments.callee.event);
}
document.addEventListener("selectItem", function(event) {
console.log(event.data);
});
Fiddle
Or you would need to init the custom Event each time to set the details property like this:
arguments.callee.event.initCustomEvent("selectItem", true, true, event_data);
and details property will have new updated value each time the event is dispacthed.
Demo
I think what I want to do is pretty simple I just don't know how to do it. I would like to fire my own event when one of my models attributes changes for the purpose of passing some data to the event handler (whether the change was an increase or decrease in value).
Basically I want my handler to do this in the view
handler: function(increased) {
if(increased) {
alert("the value increased")
}
else {
alert("the value decreased")
}
}
// ...
this.model.on("change:attr", this.handler, this);
Here you go: You basically listen for change:myvar. When a change occurs you use your model's previous() to get the old value. Depending on whether it increased or decreased you fire the appropriate event. You can listen to these events as shown in the initialize().
(function($){
window.MyModel = Backbone.Model.extend({
initialize: function () {
this.on('change:myvar', this.onMyVarChange);
this.on('increased:myvar', function () {
console.log('Increased');
});
this.on('decreased:myvar', function () {
console.log('Decreased');
});
},
onMyVarChange: function () {
if (this.get('myvar') > this.previous('myvar')) {
this.trigger('increased:myvar');
} else {
this.trigger('decreased:myvar');
}
}
});
window.mymodel = new MyModel({myvar: 1});
mymodel.set({myvar: 2});
mymodel.set({myvar: 3});
mymodel.set({myvar: 1});
})(jQuery);
Running the above will print "Increased", "Increased", "Decreased" to your console.
Just look at previousAttributes()
You can then compare:
If(this.get(attr) > this.previousAttributes()[attr]){
console.log('bigger');
} else {
console.log('smaller');
}
If you use that in your change event handler you're all set. No need for a custom trigger or a ton of code.
EDIT
This is from my Backbone.Validators project and how I obtain the list of all attributes which have changed during the validation step:
var get_changed_attributes = function(previous, current){
var changedAttributes = [];
_(current).each(function(val, key){
if(!_(previous).has(key)){
changedAttributes.push(key);
} else if (!_.isEqual(val, previous[key])){
changedAttributes.push(key);
}
});
return changedAttributes;
};
This requires Underscore 1.3.1 because it's using _.has. If you can't upgrade that's an easy thing to replace though. In your case you'd passing this.previousAttributes() and this.attributes
What if you fire your own custom event after listening to the change event?
handler: function(increased) {
this.model.trigger('my-custom-event', stuff, you, want);
},
myHandler: function(stuff, you, want){
// Do it...
}
// ...
this.model.on("change:attr", this.handler, this);
this.model.on('my-custom-event, this.myHandler, this);