jQuery: storing data between custom events - javascript

Given the following example ...
$("#some-id").on("custom-event-1", function()
{
this.someData = "test";
}).on("custom-event-2", function()
{
var test = this.someData;
...
});
... I am able to store and pass data between custom-event-1 and custom-event-2, however, is this the correct way of doing this? It works, but I'm not sure if things should be done this way, or if the jQuery data method should be used instead. If this approach is acceptable, where exactly is the data being stored? I understand where the jQuery data method stores the data, but the example above I'm not sure about.

I'd recommend you to use .data(id,value).
DOM elements are like a regular object. Ex: A div is an instance of the prototype HTMLDivElement. Test it via document.createElement('div').constructor.
Doing this.someData = 1 is similar to a = new Date(); a.someData = 1 or a = []; a.someData = 1.
It does work but it's not "clean". There is a performance cost to change the structure of an object. And you assume that the object doesn't have the attribute someData already used for something else.
With .data() you are safe.

Related

jquery ajax data object: functions are called

Consider this object:
function Cow() {
var self = this;
self.color = "blue";
self.weight=55;
}
Cow.prototype.Speak = function(){
var self=this;
alert('moo. i\'m a ' + self.color + ' cow.');
}
var bessy = new Cow();
I'm running into an issue when I try to do $.ajax(...) and pass in 'bessy' as the data parameter. My intention is for the data properties to be serialized and passed over the wire But it will actually execute Speak() upon the ajax call. This is an overly simple example, but highlights the problem I'm having.
To solve this, I've created a function that accepts an object and conditionally deletes members (such as functions). I then pass a copy of the target object to that function, and use my new simplified copy of the object for the ajax call. This seems really cumbersome. Is this a common problem? How do others deal with this? It seems like overkill to create separate DTO JS objects for this purpose because then, when I add a new property, it would need to be added in two places.
Would appreciate any thoughts.
Thanks...
-Ben
You can do it by easily converting the object into json string.
JSON.stringify(bessy) will let you have json string of the bessy variable.
Send that to the server and convert into object again by using json_decode.

Finding all objects with a jquery plugin applied

Is there a way to get a list of all objects using a specified plugin? I know i can add a class to each element when it's applied but i was wondering if there was an existing way...
thanks,
If you want to do this without using classes, you might want to sniff the plugin calls, like this:
var elemsCalled = []; // this will contain all elements upon which the plugin has been called
var orig = $.fn.somePlugin;
$.fn.somePlugin = function() {
elementsCalled.push(this);
return orig.apply(this, Array.prototype.slice.call(arguments)); // for chaining, as Alnitak noted
}
Now, whenever you call $.somePlugin, the element you call it on would be added to elemsCalled.

Creating a constant time data structure for DOM element references

Relevant discussion.
I understand I can build an array of references to elements/nodes. I realize also that I could use the neat trick of treating an array like a heap (index 2n and 2n+1 for children) to build a (potentially wasteful) binary search tree using it.
But all that's still not enough for the premature optimizer in me. Besides, implementing a BST is going to be bug prone.
Here's my question. Can I somehow use an element reference as index into javascript's hashes (which are objects, or vice versa?). If not, can I conjure up a unique string from an element reference, which I can then use as my hash key? If not, how the hell does jQuery do it?
The easiest option is to just use your own attribute on the DOM object:
var element = document.getElementById("test");
element.myData = "whatever";
Here's the general idea behind how jQuery's .data() function works that you could use in your own plain javascript. It uses one custom attribute on the object and then stores everything else in a data structure indexed by the value of that custom attribute.
var idCntr = 0; // global cntr
var data = {};
var element = document.getElementById("test");
var id = element.uniqueID;
if (!id) {
id = idCntr++ + "";
element.uniqueID = id;
}
data[id] = "whatever";
// then some time later, you can do this
var element = document.getElementById("test");
console.log(data[element.uniqueID]); // whatever
It is a bit more involved to store multiple attributes for a given object in the data object, but this is the general idea.
And, if you can use jQuery, it's trivial:
$("#test").data("myData", "whatever"); // sets the data
console.log($("#test").data("myData")); // retrieves the data
If you want to really see how jQuery's .data() works, you can step through the first call to set data and then retrieve it when using the unminified jQuery. It's easy to see what it does.

JS: capture a static snapshot of an object at a point in time with a method

I have a JS object I use to store DOM info for easy reference in an elaborate GUI.
It starts like this:
var dom = {
m:{
old:{},
page:{x:0,y:0},
view:{x:0,y:0},
update:function(){
this.old = this;
this.page.x = $(window).width();
this.page.y = $(window).height();
this.view.x = $(document).width();
this.view.y = window.innerHeight || $(window).height();
}
I call the function on window resize:
$(window).resize(function(){dom.m.update()});
The problem is with dom.m.old. I would have thought that by calling it in the dom.m.update() method before the new values for the other properties are assigned, at any point in time dom.m.old would contain a snapshot of the dom.m object as of the last update – but instead, it's always identical to dom.m. I've just got a pointless recursion method.
Why isn't this working? How can I get a static snapshot of the object that won't update without being specifically told to?
Comments explaining how I shouldn't even want to be doing anything remotely like this in the first place are very welcome :)
this is a reference to an object. You're not storing a copy of an object. You're storing a reference to that object. If you want a copy you'll need to copy the properties by hand. The easy way is to use $.extend():
this.old = $.extend({}, this);
OK right, the terminology is 'deep' copy. I would've thought it was the other way round (just get an impression rather than the object itself). So anyway Cletus is right but the syntax is:
this.old = $.extend(true,{},this)
And apparently 'snapshot' is 'clone' in developer lingo.

JavaScript mechanism for holding onto a value from a user action

I've created a JavaScript object to hold onto a value set by a user checking a checbox in a ColorBox.
I am relatively new to jQuery and programming JavaScript "the right way" and wanted to be sure that the below mechanism for capturing the users check action was a best practice for JavaScript in general. Further, since I am employing jQuery is there a simpler method to hold onto their action that I should be utilizing?
function Check() {
this.Checked = false;
}
obj = new Check;
$(document).ready(function() {
$('.cboxelement').colorbox({ html: '<input id="inactivate" type="checkbox" name="inactivatemachine"> <label for="inactivate">Inactivate Machine</label>' });
$(document).bind('cbox_cleanup', function() {
obj.Checked = $.fn.colorbox.getContent().children('#inactivate').is(':checked');
});
$(document).bind('cbox_closed', function() {
if ($($.fn.colorbox.element()).attr('id').match('Remove') && obj.Checked) {
var row = $($.fn.colorbox.element()).parents('tr');
row.fadeOut(1000, function() {
row.remove();
});
}
});
});
Personally, I would attach the value(s) to an object directly using jQuery's built-in data() method. I'm not really entirely sure what you are trying to do but, you can, for instance, attach values to a "namespace" in the DOM for use later one.
$('body').data('colorbox.checked',true);
Then you would retrieve the value later by:
var isChecked = $('body').data('colorbox.checked');
You run the data() method on any jquery object. I would say this is best-practice as far as jQuery goes.
You could capture the reference in a closure, which avoids global data and makes it easier to have multiple Checks. However, in this case it appears to be binding to the single colorbox, so I don't know that you could usefully have multiple instances.
function Check() {
this.Checked = false;
var obj = this; // 'this' doesn't get preserved in closures
$(document).ready(function() {
... as before
)};
}
var check = new Check; // Still need to store a reference somewhere.
$($.fn.colorbox.element()) is redundant. $.fn.colorbox.element() is already a jquery element.
It's common use (in the examples i watched, at least) to prepend a $ to variables referencing jquery elements.
So, var $rows = $.fn.colorbox.element().parents('tr'); gives instantly the idea that it is referencing jquery element(s).
I am afraid fadeOut won't work on rows in IE6 (if i recall correctly). You should be able to hide all the content inside the <tr> before removing it.
Can't help on the "simplify" thing because i don't know the colorbox's best uses.

Categories