I just started using Node.js and learning web development but I'm a bit unclear on the meaning/function of some symbols/signs.
For example, in the following code:
$(function() {
$.getJSON('/data', function(data) {
var $dataContainer = $('#data-container');
if (data.error) {
$dataContainer.html('Error! ' + data.error);
return;
}
// Clear the loading message.
$dataContainer.html('');
data.records.forEach(function(record) {
var $galleryCard = $('<div class="gallery-card" />');
if (record.picture[0]) {
// Just show the first picture, if it has one.
$('<img />').attr('src', record.picture[0].url).appendTo($galleryCard);
}
var $label = $('<strong />').text(record.name);
$galleryCard.append($label);
$dataContainer.append($galleryCard);
});
});
});
Why is there a "$" before the function()? What about when the $ is in front of ".getJSON", in front of the variable DataContainer, and infront of ('#data-container')? Also, what does the # infront of data-container mean?
Thank you!
It looks like the code you're referring to is using jQuery: a JavaScript library that makes things like HTML document traversal and manipulation, event handling, animation, and Ajax much simpler.
The $ is, simply put, the shortcut to access the jQuery library. Syntax would be $(selector).action().
The # symbol you're referring to is a selector, particularly referring to id. Selectors allow you to select and manipulate different elements, in this case an element (possibly a div) with an id="data-container".
If you would like to read more about jQuery their website is: https://jquery.com/
To learn more about selectors, go here: https://api.jquery.com/category/selectors/
what $ in your code means is alias of jQuery (which is a javascript library) object. (see this).
In simpler words basically, your code has nothing to do with nodejs(server side javascript) but it is related to browser supported version of javascript.
Related
I am learning about writing custom JavaScript for my Odoo 10 addons.
I've written the following piece of code:
odoo.define('ioio.io', function(require) {
'use strict'
const e = $('div.o_sub_menu_footer')
console.log('--testing--'.repeat(7))
console.log(e)
// the "Powered by Odoo" down the secondary menu
e.remove()
})
The code is well loaded and I can see my testing string in the console.
However when this code is being loaded before the target div, so e empty/not yet filled and thus its content is not removed.
Doing it manually from the console works.
My question is what is the right way to do that? And how to know exactly when the code gets executed?
You can
put your html code before the script tag in your file
use jQuery $(document).ready(...);
Place your script at the bottom of the <body> tag to make sure the DOM renders before trying to manipulate it.
This is an Odoo specific question, so you should use the Odoo standard way, which is via its base JS class. That class contains a ready() method which does exactly what you need.
In your case, to use that function, you need to require the class first. Then you can use ready().
Updating your code, it should look like this:
odoo.define('ioio.io', function(require) {
'use strict'
// require base class
var base = require('web_editor.base');
//use its ready method
base.ready().done(function () {
// put all the code you want to get loaded
// once the DOM is loaded within this block
const e = $('div.o_sub_menu_footer')
console.log('--testing--'.repeat(7))
console.log(e)
// the "Powered by Odoo" down the secondary menu
e.remove()
});
})
While your accepted answer leads to the same outcome, you might want to update it to this one since this is the Odoo way. It's generally advised to work within the Odoo framework as much as possible and customise only if really needed. (Though it can be tough to learn what features Odoo already provides because of its poor documentation.)
I found a function (via this person's github) that I might use in my script that mimics the functionality of an API object.
Here's the relevant code from the link:
unsafeWindow = (function() {
var e1 = document.createElement('p')
e1.setAttribute('onclick', 'return window;');
return e1.onclick();
})();
Where the poster says you can use the function in the format unsafeWindow.jQuery
Now, I want to be able to use $ instead of the jQuery keyword elsewhere in my code. I tried learning from this stack overflow question to simplify it and re-wrote the code like so:
(function($){
var e1 = document.createElement('p')
e1.setAttribute('onclick', 'return window;');
return e1.onclick();
})(jQuery);
But it didn't work. I guess I could just try something like $ = unsafeWindow.jQuery in order to map to the $, but I wanted to try to do it in the format seen above.
You would map $ to unsafeWindow.jQuery like so:
unsafeWindow = ( function () {
var dummyElem = document.createElement('p');
dummyElem.setAttribute ('onclick', 'return window;');
return dummyElem.onclick ();
} ) ();
var $ = unsafeWindow.jQuery;
// Now you can use the page's jQuery. EG:
$("body").append ('<p>Content added by unsafeWindow.jQuery</p>');
But keep in mind:
This is a Hack, and it will probably stop working around Chrome version 28.
It may still fail due to a race condition about when userscripts fire. To fix that, add // #run-at document-end to the userscript's metadata block.
Don't do things this way! It will only cause grief, side effects and maintenance headaches.
For userscripts: use this technique (best cross-browser) or this technique (relies on page's jQuery, but the example shows how to use GM_ functions too).
For full extensions or content scripts:, use this technique (use the manifest.json and keep everything properly sandboxed).
Is it possible to add a function to a plugin without modifying the actual plugin? Can I do something like this in my site's js file?
$.fn.Watermark.Refresh = function() {
$.Watermark.HideAll();
$.Watermark.ShowAll();
}
or
(function($){
$.fn.Watermark.Refresh = function() {
$.Watermark.HideAll();
$.Watermark.ShowAll();
};
})(jQuery);
neither worked, the first says $ is undefined, the second that jQuery is undefined...
ideas?
Solution: Either method works, just include the jquery file before the site js file.
You can add those functions if you want to, but you'll have to make sure that you're also loading jQuery itself and the plugin to be modified. If you're getting those errors (that jQuery or "$" are not defined), then you have not correctly done that.
Now, though it's true that you can add those functions, I have to wonder what the point would be. If I were to do this, for example:
$.fn.css.myFunction = function() { return "hello world"; };
then it would be possible to call it:
var str = $.fn.css.myFunction();
but so what? What good does that do me? I don't think it's very useful.
Make sure you are including the plugin after jQuery.
I am working on a website globalization project, which involves (us the vendor) asking our clients to insert a script tag on their home/origin site. The script tag is necessary for helping our clients go global, and part of the solution embodies a UI that gets triggered based on certain end user criteria.
The UI is built through the help of jQuery, which we really can't expect our clients to insert on their pages, not to mention version mismatches will be hard to resolve. Therefore, our third party library downloads its own jQuery version, albeit namespaced differently to avoid any conflicts.
However, such a mechanism requires us to rename all instances of jQuery to something that will help us avoid name clashes with another jQuery instance (if present), and makes the our mangled jQuery (MY_Query in examples below) very hard to manage, let alone upgrade.
For example
jQuery = window.jQuery = window.$ = function( selector, context ) {
// The jQuery object is actually just the init constructor 'enhanced'
return new jQuery.fn.init( selector, context );
},
.
.
.
jQuery.fn = jQuery.prototype = ...
becomes
MY_JQuery = window.MY_JQuery = window.MY_Q = function( selector, context ) {
// The MY_JQuery object is actually just the init constructor 'enhanced'
return new MY_JQuery.fn.init( selector, context );
},
.
.
.
MP_JQuery.fn = MP_JQuery.prototype = ...
In an ideal world, both us and the client would have a single version of jQuery on the site, and we both would use it to our advantage. But that would mean an upgrade of jQuery would require heavy testing on both sides (while the mangled jQuery version is contained) and that any plugin wanted would require the client to add appropriate script tags to their site, spurring a political debate between the two parties on what versions win.
So, can I manage our jQuery version (with plugins) on a client site without having to rename all instances of jQuery with something like MY_Query with the constraints mentioned above?
Why not check to see if they have jQuery already included on the page and if not dynamically load it? If you know the base level jQuery needed you can check for that like this:
if( !jQuery || !jQuery.fn.jquery === "1.4.4"){
var url = "http://code.jquery.com/jquery-1.4.4.js";
var script = document.createElement( 'script' );
script.type = 'text/javascript';
script.src = url;
document.body.appendChild(script);
}
You'd probably want to improve the version detection to make sure that it doesn't have a version after 1.4.4, but I'm sure you could write the code for that yourself ;-)
==== Edit based on feedback
So you need to maintain multiple versions of jquery on the page. Have you tried something like this:
var original_jquery = $().noConflict();
original_jquery.getScript("http://code.jquery.com/jquery-1.4.4.js");
var new_jquery = $().noConflict();
window.$ = original_jquery;
Then use the new_jquery as your version of jquery? I haven't tested this to see if it would work, but you might have some luck with it.
==== Final edit
As you mentioned, my javascript above wasn't exactly correct, so I tried out a few things in the console. And yes, you don't need to save the old version of jQuery because jQuery does that in the noConflict method. So just call getScript, then noConflict but saving to a new variable:
>> $.fn.jquery
"1.4.2"
>> $.getScript("http://code.jquery.com/jquery-1.4.4.js");
undefined
>> $.fn.jquery
"1.4.4"
>> var new_jquery = $.noConflict();
undefined
>> new_jquery.fn.jquery
"1.4.4"
>> $.fn.jquery
"1.4.2"
Have you tried to use JQuery.noConflict(). This sounds like it could help you.
I am experimenting with Jetpack and I would like to parse all the years in a given html page and then wrap the year with a link to the Wiki page. I tried the code in jquery and there it works but now I am using it in Jetpack and it gives an error $(doc).replace is not a function. I am definitely new to Jquery / Jetpack so maybe I am missing something really easy but your help is much appreciated.
EDIT: I have tried the suggestions but I am still stuck. The weird thing is that this
JQuery function works:
(function($) {
$.fn.clickUrl = function() {
var regexp = /([1-2][0-9][0-9][0-9])/gi;
this.each(function() {
$(this).html(
$(this).html().replace(regexp,'<ahref=\"http://nl.wikipedia.org/wiki/$1\">$1<\/a>')
);
});
return $(this);
}
})(jQuery);
and basically, I would like to 'port' this function to Jetpack.
This is the 'old' non-working port of my JQuery function to Jetpack:
jetpack.statusBar.append({
html: "Hyperlink Years",
width: 80,
onReady: function(widget){
$(widget).click(function(){
var regexp = /([1-2][0-9][0-9][0-9])/gi;
var doc = jetpack.tabs.focused.contentDocument;
$(doc).each(function() {
$(this).html(
$(doc).replace(regexp,'<a href=\"http://nl.wikipedia.org/wiki/$1\">$1<\/a>'));
});
return $(doc);
});
}
});
I'm not familiar with jetpack, but your jquery seems to be quite messed up.
If "doc" is an HTML document, then doing $(doc).each() doesn't really make sense. It would only loop once, and "this" would be the same as doc.
Then later you are doing $(doc).replace(regexp, ...), but replace() is not a jquery function. You might have wanted to do .html().replace(regexp, ...); HOWEVER, I do not recommend doing this because it will not work - you will just end up replacing any numbers in the document, even if they are part of another URL or the HTML of the page.
For more information, refer to this question or google for jquery text nodes:
Find text string using jQuery?