Determining if a jquery plugin has been initialized - javascript

I'm using two different jquery plugins. selectpicker and prettyCheckable
neither return anything when I initialize them, so how can I determin if they are initialized so I don't re initialize them?
They get called like this
$("#StartTime").selectpicker();
$("input.terms").prettyCheckable();
I guess I could set a flag like this and check it very time I want to view the page and initialize the data in that page , but I don't know if that's the best way.
if (scope.isTermsInitialized === false) {
$("input.terms").prettyCheckable();
scope.isTermsInitialized = true;
}

For the picker you can check the value of the get function. I didn't see any methods for prettycheckable that would be of any use. You could add some checks with the customClass method, but at that point you might as well set a variable.
http://picker.adam-uhlir.me/
http://arthurgouveia.com/prettyCheckable/

Related

Angular isUnchanged - why doesn't this always work

I've seen this function used in several examples for form validation but can't find any info/docs/api for it and seems not to work in all cases. Is there an alternative for checking has the object changed ?
I have seen the method in AngularJS tutorials, and its just a custom function
$scope.isUnchanged = function(user) {
return angular.equals(user, $scope.master);
};
The above check i believe is reference match not the complete content.
You can use $watch method to watch any change on object. Also go through FormController it has properties like $pristine, $isDirty etc which is specific to form editing. I believe these values are also available on form elements.

setting default root element in jquery

jQuery currently uses window as its default element so any call like $('div') will look for div tags inside window.
Is there any way to change defaults on jQuery like:
$.defaultRoot = $('.anyOtherRootElement');
$('div').text("Hello");
this will select any div inside the elements containing .anyOtherRootElement class.
Thanks in advance
Upate
just an update refining the question a bit more here:
I would like to perform the actions above based on external queries coming from external script which won't know what defaultRoot is so they can still be calling what is supposed to be the current base, so in this instance, I'm afraid adding the a second parameter wouldn't be an option, unfortunately.
And at the same time creating a function which returns defaultRoot.find(el) would prevent me of using first-level methods such $.trim, $.each, etc… so unfortunately that would not be possible as well.
Ideally (for performance reasons) you'd want to use find()
$.defaultRoot.find("div");
Otherwise you can use the 2 argument form that sets a context
$("div", $.defaultRoot);
In general you don't want to do these types of things implicitly since someone else could easily end up thoroughly confused when having to work with your code later. If you want to do it consistently and make it shorter you should create your own function to do so like:
var $s = function(selector) {
return $.defaultRoot.find(selector);
}
and then you'd just be able to use
$s("div")
or you could also do a scoped higher order function with something like
var withScope = function(scope$) {
return function(selector) {
return scope$.find(selector);
}
}
var $s = withScope($.defaultRoot);
$s("div")
If for some reason you really want to screw around with the default state for client code (begging for chaos IMO), you should look at the functional practice: currying.
$('SELECTOR', 'CONTEXT')
You can use context. As in your case $('div', '.anyOtherRootElement')
For more details, visit http://api.jquery.com/jQuery/
Given that you can pass the context as a second argument, you can easily overwrite the $() operator in Javascript with a version which internally calls JQuery using jQuery.noConflict(); and always passes your new root as the second argument.
I don't think jQuery provide such method or variable. But you can pass second parameter in jQuery method to set context.
$.defaultRoot = $('.anyOtherRootElement');
$('div', $.defaultRoot ).text("Hello"); // all div inside $('.anyOtherRootElement')
$('div' ).text("Hello"); //all div inside body tag

live function with out arguments in jQuery

I wanna select some item by jQuery which has been added after loading page,so I wanna use live() function.I used it before for clicking like following code:
$("selector").live('click')
but now when I wanna use it in another function.
but It will not work with out argument,like it live()
for e.g followin code will alert test (work)
var pos_eq=Math.abs($('.myList').css("left").replace("px","")/$('.myList').children('li').eq(0).css('width').replace("px","")) + 1;
alert("test");
but this will not.
var pos_eq=Math.abs($('.myList').live().css("left").replace("px","")/$('.myList').live().children('li').eq(0).css('width').replace("px","")) + 1;
alert("test");
how can I solve it?
You want a function, not a variable. It looks like you are trying to keep pos_eq up to date after elements have been added to the page. Having a variable auto-update when the DOM changes in the way you are trying to do is not possible with JavaScript. What you can do is use a function instead of a variable. This way whenever the value is accessed you are getting the latest value because it is computed on demand:
function pos_eq() {
var list = $('.myList');
var left = parseInt(list.css("left"));
var width = parseInt(list.children('li').eq(0).css('width'));
return Math.abs(left / width) + 1;
}
I broke your code up into multiple statements to make it more readable. You would use this function the same as you used the variable, but instead add parens to the end to invoke the function:
alert(pos_eq);
alert(pos_eq());
To get a set of objects at the time you need them, just do $("selector"). That will do a query at that time and get the set of objects. There is no need to use .live() in order to query objects on the page. It does not matter whether the objects were part of the original page or were added dynamically later. When you do $("selector"), it will search the contents of the current page and get you the objects that are currently in the page that match the selector.
There is no way to do a live selector query and save it and have it automatically update in jQuery or any other library I know of. The way you solve that issue with a dynamic page is that you just do a new query when you need current results.
The description of live() is: Attach a handler to the event for all elements which match the current selector, now and in the future. It does not give you a live node list despite its name. jQuery does not have any method that returns a live node list(such as those returned by getElementsByTagName etc.) as far as I know.

Using $.data() in jQuery to store flag on element

I am authoring a simple jQuery plugin that turns an input tag into a time-formatted element (on blur it will change 245p into 2:45 pm).
Since I do not want to apply the time format events to the same element twice, I need a way to detect that the specific element in the list provided has not already had the format applied.
This is the relevant part of the code:
var methods = {
init : function(sel) {
var $this = $(sel);
return $this.each(function(){
var data = $(this).data('time_formatted');
if (data) {
return;
} else {
$(this).data('time_formatted', true);
I have heard that using $(sel).data() in a plugin is not a good idea; instead, use $.data(). I don't know why, that's just what I've heard; honestly, I don't know what the difference is.
So my question is, is this the way to accomplish checking if a specific element has had the time formatter applied to it in a plugin?
If you care to see the plugin in it's current development state, see http://jsfiddle.net/userdude/xhXCR/.
Thanks!
Jared
Where have you heard that using .data() is not good? jQuery's plugin autoring page says:
Often times in plugin development, you may need to maintain state or check if your plugin has already been initialized on a given element. Using jQuery's data method is a great way to keep track of variables on a per element basis. However, rather than keeping track of a bunch of separate data calls with different names, it's best to use a single object literal to house all of your variables, and access that object by a single data namespace.
So it should be perfectly fine.

Rendering suggested values from an ext Combobox to an element in the DOM

I have an ext combobox which uses a store to suggest values to a user as they type.
An example of which can be found here: combobox example
Is there a way of making it so the suggested text list is rendered to an element in the DOM. Please note I do not mean the "applyTo" config option, as this would render the whole control, including the textbox to the DOM element.
You can use plugin for this, since you can call or even override private methods from within the plugin:
var suggested_text_plugin = {
init: function(o) {
o.onTypeAhead = function() {
// Original code from the sources goes here:
if(this.store.getCount() > 0){
var r = this.store.getAt(0);
var newValue = r.data[this.displayField];
var len = newValue.length;
var selStart = this.getRawValue().length;
if(selStart != len){
this.setRawValue(newValue);
this.selectText(selStart, newValue.length);
}
}
// Your code to display newValue in DOM
......myDom.getEl().update(newValue);
};
}
};
// in combobox code:
var cb = new Ext.form.ComboBox({
....
plugins: suggested_text_plugin,
....
});
I think it's even possible to create a whole chain of methods, calling original method before or after yours, but I haven't tried this yet.
Also, please don't push me hard for using non-standard plugin definition and invocation methodics (undocumented). It's just my way of seeing things.
EDIT:
I think the method chain could be implemented something like that (untested):
....
o.origTypeAhead = new Function(this.onTypeAhead.toSource());
// or just
o.origTypeAhead = this.onTypeAhead;
....
o.onTypeAhead = function() {
// Call original
this.origTypeAhead();
// Display value into your DOM element
...myDom....
};
#qui
Another thing to consider is that initList is not part of the API. That method could disappear or the behavior could change significantly in future releases of Ext. If you never plan on upgrading, then you don't need to worry.
So clarify, you want the selected text to render somewhere besides directly below the text input. Correct?
ComboBox is just a composite of Ext.DataView, a text input, and an optional trigger button. There isn't an official option for what you want and hacking it to make it do what you want would be really painful. So, the easiest course of action (other than finding and using some other library with a component that does exactly what you want) is to build your own with the components above:
Create a text box. You can use an Ext.form.TextField if you want, and observe the keyup event.
Create a DataView bound to your store, rendering to whatever DOM element you want. Depending on what you want, listen to the 'selectionchange' event and take whatever action you need to in response to the selection. e.g., setValue on an Ext.form.Hidden (or plain HTML input type="hidden" element).
In your keyup event listener, call the store's filter method (see doc), passing the field name and the value from the text field. e.g., store.filter('name',new RegEx(value+'.*'))
It's a little more work, but it's a lot shorter than writing your own component from scratch or hacking the ComboBox to behave like you want.
#Thevs
I think you were on the right track.
What I did was override the initList method of Combobox.
Ext.override(Ext.form.ComboBox, {
initList : function(){
If you look at the code you can see the bit where it renders the list of suggestions to a dataview. So just set the apply to the dom element you want:
this.view = new Ext.DataView({
//applyTo: this.innerList,
applyTo: "contentbox",
#qui
Ok. I thought you want an extra DOM field (in addition to existing combo field).
But your solution would override a method in the ComboBox class, isn't it? That would lead to all your combo-boxes would render to the same DOM. Using a plugin would override only one particular instance.

Categories

Resources