Module pattern, jquery callback issue; - javascript

Sorry for the pseudo code, but I can't post the original code here(company policy).
I have two "classes" in javascript, the class CLS2 I use to populate a DIV with HTML which come from the server (Actually it's a table). I am using the method LOAD in jquery for this.
The class CLS1 calls the CLS2 to load the HTML table and after trying to get some infos from the table with jquery method FIND.
I know what is happening. When I try to get these infos inside the table I am not able to do this, because the HTML table is not ready yet.
But if I am using the jquery method WHEN, I guessed, I should be able to do this. But it is not working so far.
If I use the callback on the jquery LOAD method everything works fine, but when I am using WHEN it is not waiting the HTML table to get ready.
Am I forgetting any thing?
I have a return from the jquery LOAD method. Is it possible to check in this return if the content is ready? console.log(retParam);
CLS2:
var cls2 = (function ($) {
return {
load: function() {
return this.populateDiv();
},
populateDiv: function() {
var ret = $('#content').load('url', function(){
// IF I USE THE JQUERY METHOD FIND HERE WORKS FINE
});
return ret;
}
};
}(jQuery));
CLS1:
var cls1 = (function ($) {
return {
init: function(){
this.config();
},
config: function() {
$.when(cls2.load()).then(this.doPagination());
},
doPagination: function(retParam) {
console.log(retParam);
var val = $('#datatable').find('.tdActive').val();
}
};
}(jQuery));
JQUERY Ready
$(document).ready(){
cls1.init();
}

load returns jQuery, not a promise. if you replace .load() with .get() instead, since .get() returns a promise (actually a jqXhr) that you can do .when on.
something like
var ret = $.get( "url", function( data ) {
$( '#content' ).html( data );
});
return ret;

Related

Getting value from this JQuery plugin

I've been experimenting with writing JQuery plugins lately, and I'm sure this is a very simple question. But, I seem to not be able to get a value inside of my plugin.
For example, I have the following code:
plugin.js
$(function($) {
$.fn.myPlugin = function() {
// alert the id from main.js
}
});
main.js
$(document).ready(function() {
$('#someDIV').attr('id').myPlugin();
});
You cannot define plugin on string. Use selector to call the plugin.
Have a look at this.
Use it like this:
(function ($) {
$.fn.myPlugin = function () {
this.each(function () {
// Allow multiple element selectors
alert(this.attr('id'));
});
return this; // Allow Chaining
}
} (jQuery));
$('.myClass').myPlugin();
DEMO
Tutorial
Try this:
(function($) {
$.fn.myPlugin = function() {
alert($(this).attr('id'));
}
}(jQuery));
See here: http://jsfiddle.net/1cgub37y/1/
You should pass only the object into your jQuery-extension function (not the object's ID), as below or in this fiddle (will alert "someDIV" onload):
// jQuery extension
// The object passed into jQuery extension will occupy keyword "this"
$(function($) {
$.fn.myPlugin = function() {
// Get the ID (or some other attr) of the object.
var id = $(this).attr("id");
// Now do something with it :)
alert(id);
}
});
$(document).ready(function() {
$('#someDIV').myPlugin();
});

how to pass parameter in jquery using .on?

Good Day, this maybe a silly question :) how can I pass a parameter to an external javascript function using .on ?
view:
<script>
var attachedPo = 0;
$this.ready(function(){
$('.chckboxPo').on('ifChecked', addPoToBill(attachedPo));
$('.chckboxPo').on('ifUnchecked', removePoToBill(attachedPo ));
});
</script>
external script:
function addPoToBill(attachedPo){
attachedPo++;
}
function removePoToBill(attachedPo){
attachedPo--;
}
but Im getting an error! thanks for guiding :)
You need to wrap your handlers in anonymous functions:
$('.chckboxPo')
.on('ifChecked', function() {
addPoToBill(attachedPo);
})
.on('ifUnchecked', function() {
removePoToBill(attachedPo);
});
You can also chain the calls to on as they are being attached to the same element.
If your intention is to count how many boxes are checked, via passing variable indirectly to functions try using an object instead like this:
JSFiddle: http://jsfiddle.net/TrueBlueAussie/pBkhX/
var attachedPo = {
count: 0
};
$(function () {
$('.chckboxPo')
.on('change', function () {
if ($(this).is(':checked')) {
addPoToBill(attachedPo);
} else {
removePoToBill(attachedPo);
}
$("#output").prepend("" + attachedPo.count + "<br/>");
});
});
function addPoToBill(attachedPo) {
attachedPo.count++;
}
function removePoToBill(attachedPo) {
attachedPo.count--;
}
If it is not doing anything else you can simplify the whole thing to count checked checkboxes:
$(function () {
var attachedPo = 0;
$('.chckboxPo')
.on('change', function () {
attachedPo = $(".chckboxPo:checked").length;
});
});
"DOM Ready" events:
you also needed to wrap it in a ready handler like this instead of what you have now:
$(function(){
...
});
*Note: $(function(){YOUR CODE HERE}); is just a shortcut for $(document).ready(function(){YOUR CODE HERE});
You can also do the "safer version" (that ensures a locally scoped $) like this:
jQuery(function($){
...
});
This works because jQuery passes a reference to itself through as the first parameter when your "on load" anonymous function is called.
There are other variations to avoid conflicts with other libraries (not very common as most modern libs know to leave $ to jQuery nowadays). Just look up jQuery.noConflict to find out more.

automatic clicks on links and doing something with every page's DOM

i have some links in a web page ,what i want to do :
Trigger click event on every link
When the page of every link is loaded , do something with page's DOM(fillProducts here)
What i have tried :
function start(){
$('.category a').each(function(i){
$.when($(this).trigger('click')).done(function() {
fillProducts() ;
});
})
}
Thanks
What you want to do is much more complicated than you seem to be giving it credit for. If you could scrape webpages, including AJAX content, in 7 lines of js in the console of a web browser you'd put Google out of business.
I'm guessing at what you want a bit, but I think you want to look at using a headless browser, e.g. PhantomJs. You'll then be able to scrape the target pages and write the results to a JSON file (other formats exist) and use that to fillProducts - whatever that does.
Also, are you stealing data from someone else's website? Cause that isn't cool.
Here's a solution that may work for you if they are sending their ajax requests using jQuery. If they aren't you're going to need to get devilishly hacky to accomplish what you're asking (eg overriding the XMLHttpRequest object and creating a global observer queue for ajax requests). As you haven't specified how they're sending the ajax request I hope this approach works for you.
$.ajaxSetup({
complete: function(jQXHR) {
if(interested)
//do your work
}
});
The code below will click a link, wait for the ajax request to be sent and be completed, run you fillProducts function and then click the next link. Adapting it to run all the clicks wouldn't be difficult
function start(){
var links = $('.category a');
var i = 0;
var done = function() {
$.ajaxSetup({
complete: $.noop//remove your handler
});
}
var clickNext = function() {
$(links.get(i++)).click();//click current link then increment i
}
$.ajaxSetup({
complete: function(jQXHR) {
if(i < links.length) {
fillProducts();
clickNext();
} else {
done();
}
}
});
clickNext();
}
If this doesn't work for you try hooking into the other jqXHR events before hacking up the site too much.
Edit here's a more reliable method in case they override the complete setting
(function() {
var $ajax = $.ajax;
var $observer = $({});
//observer pattern from addyosmani.com/resources/essentialjsdesignpatterns/book/#observerpatternjquery
var obs = window.ajaxObserver = {
subscribe: function() {
$observer.on.apply($observer, arguments);
},
unsubscribe: function() {
$observer.off.apply($observer, arguments);
},
once: function() {
$observer.one.apply($observer, arguments);
},
publish: function() {
$observer.trigger.apply($observer, arguments);
}
};
$.ajax = function() {
var $promise = $ajax.apply(null, arguments);
obs.publish("start", $promise);
return $promise;
};
})();
Now you can hook into $.ajax calls via
ajaxObserver.on("start", function($xhr) {//whenever a $.ajax call is started
$xhr.done(function(data) {
//do stuff
})
});
So you can adapt the other snippet like
function start(){
var links = $('.category a');
var i = 0;
var clickNextLink = function() {
ajaxObserver.one("start", function($xhr) {
$xhr.done(function(data) {
if(i < links.length) {
fillProducts();
clickNextLink();
} else {
done();
}
});
})
$(links.get(i++)).click();//click current link then increment i
}
clickNextLink();
}
try this:
function start(){
$('.category a').each(function(i){
$(this).click();
fillProducts() ;
})
}
I get ya now. This is like say:
when facebook loads, I want to remove the adverts by targeting specific class, and then alter the view that i actually see.
https://addons.mozilla.org/en-US/firefox/addon/greasemonkey/
Is a plugin for firefox, this will allow you to create a javascript file, will then allow you to target a specific element or elements within the html rendered content.
IN order to catch the ajax request traffic, you just need to catcher that within your console.
I can not give you a tutorial on greasemonkey, but you can get the greasemonkey script for facebook, and use that as a guide.
http://mashable.com/2008/12/25/facebook-greasemonkey-scripts/
hope this is it

Calling jQuery plugin public function within plugin

I know, there are quite a few examples on the Web, but finding real one out of them all is tough for beginner. So I want to create jQuery plugin with public methods. Example code:
(function($) {
$.fn.peel = function(options) {
var defaults = {
};
var settings = $.extend({},defaults, options);
this.public = function() {
alert("public");
};
var private = function() {
alert("private");
}
return this.each(function() {
//this.public();
private();
});
};
})(jQuery);
As I found, this is the way to make public function, which could be called like this :
var peel = $('img').peel();
peel.public();
So far it works as expected - public() can be called. But what if i want to call that function within my plugin? I commented out in this.each() because it does not work. How can i achieve that?
One way to create publicly accessible methods within your plugins is to use the jQuery UI widget factory. This is the framework that jQuery UI uses for all of it's supported UI widgets. A quick example would look like this:
(function( $ ) {
$.widget( "something.mywidget", {
// Set up the widget
_create: function() {
},
publicFunction: function(){
//...
}
});
}( jQuery ) );
var $w = $('#someelement').mywidget();
$w.mywidget('publicFunction');

Question about cache in javascript/jquery

I wonder if selector "$cacheA" will be cached on page load in the example below?
// MY JQUERY FUNCTION/PLUGIN
(function( $ ){
$.fn.myFunction = function() {
var $cacheA = this,
$cacheB = $cacheA.children(),
$cacheC = $cacheB.eq(0);
$cacheD = $cacheA.parent();
$cacheD.click(function(){
$cacheA.toggle();
$cacheB.fadeIn();
$cacheC.slideUp();
});
};
})( jQuery );
// END JQUERY FUNCTION/PLUGIN
$(window).load(function(){
$('#mySelector').myFunction();
});
Would it be any reason to do this:
$(window).load(function(){
var $mySelector = $('#mySelector');
$mySelector.myFunction();
});
If, inside your "load" handler, you were to do many jQuery operations with "$mySelector", then saving that in a variable would be a good idea. However, in your example, you only use the value once, so it really makes no difference at all.
Firstable, $cacheA and others inside click function will be undefined.
$cacheD.click(function(){
$cacheA.toggle();
$cacheB.fadeIn();
$cacheC.slideUp();
});
Second,
$.fn.myFunction = function() {
var $cacheA = this,
$cacheB = $cacheA.children(),
$cacheC = $cacheB.eq(0);
$cacheD = $cacheA.parent();
}
So, after $('selector').myFunction() how can I use $cacheB, $cacheC and $cacheD? Where they are will store?

Categories

Resources