Cordova Plugins - javascript

Can someone explain me how does a structure of a javascript file written to execute a custom plugin work, for example I know that
exec(<success function>,<failure function>,<service>,<action>,<args>)
this function is used to call the native where service is the plugin class name and action is the method that needs to be called in that class.
What I am failing to understand is that what does this structure do for example
cordova.define("cordova/plugin/pluginName",
function(require,exports,module){
var exec = require("cordova/exec")
pluginName.prototype.methodName = function()
I am unable to understand what is happening here ?

You don't have to use cordova.define anymore, that's added automatically on plugin install
From the doc:
Do not wrap the file with cordova.define, as it is added
automatically. The module is wrapped in a closure, with module,
exports, and require in scope, as is normal for AMD modules.
var exec = require("cordova/exec") just loads the cordova.exec module into exec, if you don't do this you can call your plugin with cordova.exec(<success function>,<failure function>,<service>,<action>,<args>) instead of just doing exec(<success function>,<failure function>,<service>,<action>,<args>)
pluginName.prototype.methodName = function() just creates a methodName function for your pluginName, so it makes possible that the user can call your plugin method like pluginName.methodName()

Related

How do I add a personal script to an existing node.js library?

I have a local copy of the hls.js library and I need to include a personal script with custom functions in it.
How do I go about adding a new script to the library and how do I use the function written in the new script?
Let's say that I want to add a script called hello.js that contains a function that logs "Hello World".
When I call that function in my main.js I need it to execute.
Any ideas on how to do this?
Currently, I'm getting an error that the function is not defined.
I placed the hello.js script in the src folder of the library but this (as expected) doesn't seem to work.
It should be possible to add functions to the exported hls.js object.
Your custom-script.js:
var hls = require('hls.js')
hls.customFunc1 = function () {
}
hls.customFunc2 = function () {
}
on main.js:
require('custom-script')
// your code follows
Any other code would be able to use the custom functions by just require'ing hls.js.

Load requirejs module with data-bind (knockout.js)?

What I want to do is load js using the data-bind attribute. I am fairly new to requirejs and knockout and I'm not sure how to go out this.
Right now I have my js split into different require modules for each type of component I have. For example, I have a file that deals with the header dropdown (header.js):
define('headerDropdown',['jquery', 'bootstrap']),function(jquery, bootstrap){
var $menu = $(".menu");
var $dropdown = $menu.find("ul");
$menu.on("click", function () {
$dropdown.toggle("fast");
});
};
What I want to do is:
<div class="header" data-bind="headerDropdown">...</div>
And load the respective js.
Most of my js modules are UI changes based on clicks (show and hiding stuff on click) but I only want the js to load is the html block is on the page.
Hopefully this makes sense!
How can I do this using requirejs and knockout?
Looks like you are mixing concepts. First let's see the define() definition (suppose the file is headerDropdown.js):
define('headerDropdown',['jquery', 'bootstrap']),function(jquery, bootstrap){
var $menu = $(".menu");
var $dropdown = $menu.find("ul");
$menu.on("click", function () {
$dropdown.toggle("fast");
});
};
Require.js does not recommend to define a module expliciting their name ('headerDropdown'); you can get the name based on the filename. That's because require has a tool for optimization of the javascript in production: you can concatenate and minimize the output JS. The optimizer uses the filename to define the module name. Please, avoid defining with name.
If you look at the code, you are requiring ['jquery'] but inside the module definition you're using the global jQuery variable. That's OK because jQuery define their module as a global variable, but the convention is to receive in the function the jquery reference:
define('headerDropdown',['jquery', 'bootstrap']),function($, bootstrap)
You are defining a module that manipulates DOM directly, which goes against the DOM update procedure of knockout. In your case, you are using a data-bing="headerDropwodn" so the headerDropdown is a bindingHandler rather than a simple module. Please check: http://knockoutjs.com/documentation/custom-bindings.html
You can load on require as you pointed on the question. You just need to change your codes:
Load in your HTML an app.js script (for example). This app.js requires knockout and your headerDropdown bindingHandler. In the function declaration you define the ko.applyBindings and that's all.
Greetings!

Access $ in a required file using Alloy

I am in my controller (ControllerA) and I have an external file that I want to handle orientation changes.
//-- In ControllerA
var gestures = require('gestures');
Inside gestures.js I need access to $ so I can manipulate some elements in ControllerA
Inside gestures.js I currently get undefined for $
I have successfully managed to get this to work by creating an init() function in gestures and I can intantiate the require like:
var gestures = require('gestures').init($); but this feels like a hack.
What is the proper way of doing this in alloy?
edit
Just a side note. I tried doing this with Ti.include() as well and same thing...no access to $
CommenJS modules (included in other controller using require ) must be independent off any other controllers. from it's name "gesture.js" i think you are trying to controle some orientations changes and shake gestures ... You have to define this module to use it in all other controllers and for that this feature exist.
for example suppose i have a module called animations.js :
var animations={};
animations.moveToLeft=function(element,newLeftValue){
var animation=Ti.UI.createAnimation({
left:newLeftValue,
duration:700
... so on
});
element.animate(animation);
};
module.exports=animations;
Then i can use this module from many other controller and to animate many titanium's objects
just require it in controller.js file and use moveToLeft function ...

How do I get my helper functions to load first? (Meteor, Node framework)

In my Meteor projects I have several helper functions of the sort
helpers.js
var tagStr = function () { return this.tags.join(', '); };
articles.js
Template.articles.tags = tagStr;
listing.js
Template.listing.tags = tagStr;
Now, I can define the function in either articles.js or listing.js, and it won't work in the other one. Or i can define it in helpers.js and it will work in neither..
So, how would I go about loading my helper functions before the rest of the scripts? Preferably in "the right way".
Thanks!
i think what you are looking for is a globally available handlebars helper - i keep mine in client/lib/handlebars.js - the contents of the 'lib' folder will get loaded first
define each helper like so:
Handlebars.registerHelper("joinArray", function(array) {
if(array)
return array.join(', ');
});
you would then use this in any template html file like so:
{{joinArray tags}}
you can read more about handlebars helpers here handlebarsjs.com/block_helpers.html
this is the 'right' way IMO, but if you want to use normal javascript functions and not handlebars helpers, that works also
you'll need to place the commonly used javascript function in a file like client/lib/helpers.js and do NOT use the 'var' declaration prefix
like so:
thisIsAGloballyAvailableFunction = function(){...};
not like:
var thisFunctionIsOnlyAvailableInThisFile = function(){...};
meteor does a slightly strange thing to control scoping. anything with 'var' is local to the scope of the file it occurs in, anything declared without 'var' is globally available across the app
The answer by nate-strauser was correct and helped me find the right solution but now (Meteor 1.0) Handlebars.registerhelper() is deprecated.
Now it works this way (if anyone is still interested):
Template.registerHelper()
The rest as explained by nate-strauser.

Building a remote jQuery UI widget with requirejs dependencies

I've created a jQuery UI widget which is dependent on some other custom JavaScript modules. I fetch these modules using requirejs during the "_create" method of the widget. This actually works great if, I have my end consumers define my "data-main" property. However, in the situation where my consumers are using requirejs on their own, and defining their own "data-main" property, this doesn't work.
Since I'm using requirejs to inject scripts via my widget from a totally different server, I run into a few problems with requirejs's normal way of dealing with this.
First, I can't use a package.json file unless I assume that all of my consumers have a package.json which contains the exact same resources as I have. On top of that, I've got DEV, TEST and PROD server URLs to deal with.
Second I can't use require.config to set my baseUrl during a load on their server, cause it may break everything that they are using require for.
The current implementation I have working requires the consumer to add a script reference to require with my data-main location (external server). Then add a script ref to my widget (external server). This works because nobody else at my company has ever even heard of requirejs :). The second I start showing them how to bundle all of their code into reusable JavaScript modules my solution is broken.
I want to come up with a solution whereas the end consumer can simply reference my single JavaScript widget, which in turn loads everything it needs to function.
Any suggestions on how to do this? I've thought about hacking my own version of require with a static data-main, then just assume they can have multiple requirejs libs. I WOULD HATE TO DO THAT...but I can't really think of a better way.
Here is what I am going to do...
Couple of notes:
I'm using the jQuery UI widget factory pattern (but this isn't exactly a widget)
The widget code lives on a remote server and consumers only reference it, don't download it
I'm using requirejs to load widget dependencies
I want the greatest ease-of-use for the consuming developer
Since it's required that my jQuery UI widget be loaded ASAP so that the consumer has the context of the widget right away ( $(selector).mywidget ) I've decided to tackle my problem inside of the _create method.
This code basically installs requirejs if it doesn't exist, then uses it to install an array of requirements which the aforementioned widget needs to consume. This allows me to assume that the end user can reference my "widget" script by URL, tack on a "data-requiremodule" attribute of the same name, and get a complete list of remote dependencies.
_create: function () {
var widget = this;
widget._establish(widget, function () {
widget._install(widget);
});
},
_getBaseURL: function (scriptId, callback) {
var str = $('script[data-requiremodule="' + scriptId + '"]').attr('src');
if (callback) callback(str.substring(str.search(/scripts/i), 0));
},
_require: function (requirementAry, baseUrl, callback) {
require.config({ baseUrl: baseUrl });
require(requirementAry, function () {
if (callback) callback();
});
},
_establish: function (widget, callback) {
if (typeof require === 'undefined') {
widget._getBaseURL(widget._configurations.widgetName, function (baseUrl) {
var requireUrl = baseUrl + 'scripts/require.min.js';
baseUrl = baseUrl + 'scripts/';
$.getScript(requireUrl, function (data, textStatus) {
widget._require(widget._configurations.requiredLibs, baseUrl, function () {
callback(textStatus);
});
});
});
}
},
I'm not showing my "_configurations" object here...but you get the idea. I hope this helps someone else besides me :).

Categories