Structure application by using jQuery - javascript

I am going to build an application as it is not too much rich otherwise I can use angularjs for that purpose. I wanted to organize my JS code into proper modular programming approach.
E.g
var SignUpModule = {
elem: $('#id'), // unable to access jquery object here
init: function (jQuery) {
alert(jQuery('.row').html());
}
};
var application = {
modules: [],
addModule: function (module) {
this.modules.push(module);
},
run: function (jQuery) {
_.each(this.modules, function (module) {
//Iterate each module and run init function
module.init(jQuery);
});
}
}
jQuery(document).ready(function () {
application.addModule(SignUpModule);//add module to execute in application
application.run(jQuery);//Bootstrap application
});
Please now look at it I have updated my question with actual code

The biggest mistake you've done is using anonymous first parameter of an anonymous function taken by $.each method. The first argument is just index, and the second argument is an element you were looking for. Below you can find working code.
And no, you don't need to pass jQuery object everywhere. It's global. It already is everywhere. You can see it in the code below.
var SignUpModule = {
elem: $('.row'), //jQuery works fine here
init: function () {
alert(this.elem.html());
}
};
var application = {
modules: [],
addModule: function (module) {
this.modules.push(module);
},
run: function () {
$.each(this.modules, function (index, module) { //this function takes 2 parameters
//Iterate each module and run init function
module.init();
});
}
}
//document.ready
$(function () {
application.addModule(SignUpModule);//add module to execute in application
application.run();//Bootstrap application
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="row">alert <b>me!</b></div>

Related

Using elements within API functions in Nightwatch JS

I have a page object and am creating a command for use in my test file. When I use a WebDriver API command like .elements(), the elements that I created are not passed through and cannot be used in the callback function.
Example code:
var commands = {
command1: function () {
var element1 = "div.some-class"; //I end up doing this
this.api
.elements("css selector", "#element1", function (result) {
return this
.click("#element2");
})
}
}
module.exports = {
url: function() {
return this.launchUrl;
},
elements: {
element1: "div.some-class",
element2: "h2[id=some-id]"
},
commands: [commands]
}
I have noticed that calling .api makes it so you cannot use elements, but is there any way around this? I have been making variables for each of my commands, but I feel like that defeats the purpose of having elements.
to make it more generic inside a custom function u can use:
var objectSelector = this.page.pageobject.elements[elementName]
it should return element1 css: div.some-class
if i gona think about better solution will post it here in a comment

jQuery extension, can I make this code more elegant?

I was writing some custom jQuery plugins and I have the following code
that extends the jQuery:
(function ($) {
$.fn.extend({
pluginOne: function () { return this.each(pluginOneFN) },
pluginTwo: function () { return this.each(pluginTwoFN) },
pluginThree: function (p1, p2) {
return this.each(function() {
pluginThreeFN.call(this, p1, p2);
});
}
});
})(jQuery);
Now the pluginOne and pluginTwo are OK but pluginThree looks messy.
The pluginThree requires some parameters, and I was wondering
is there shorter or more elegant way to write this piece of extension code for plugin 3?
Only thing I can think of is a little reusability improvement. You could introduce a function to initialize plugins in general, supporting arguments.
(function ($) {
$.fn.initializePlugin = function(pluginFn, args) {
return this.each(function() {
pluginFn.apply(this, args);
});
};
$.fn.extend({
pluginOne: function () { return this.each(pluginOneFN) },
pluginTwo: function () { return this.each(pluginTwoFN) },
pluginThree: function () { return this.initializePlugin(pluginThreeFN, arguments) }
});
})(jQuery);
Note that I haven't tested this code, it's only for demonstrating the idea.
Also, if I were creating plugins, I would follow the existing convention of using only one argument, which is some kind of options object at initializtion, or a string for calling methods. Your method cannot support this, neither can this in my answer. You can check bootstrap's source code for a good skeleton implementation of such a plugin system.

Writing multiple functions in AMD javascript module

I am quite new to writing javascript code using AMD. I am stuck at figuring out how to write multiple functions in a file:
define(function(){
return {
and: function(a,b){
return (a&&b);
}
};
}
);
I tried writing another function plus in the following way:
define(function(){
return {
plus: function(a,b){
return (a+b);
}
};
}
);
But when I use grunt for testing, it is not able to detect the function plus
You should place each module in it's own file. At least requireJS (are you using that?) determines the module name by it's file name (without the .js).
So a file sitting in /modules/A.js will have the module name "modules/A".
If you really want to define multiple modules in one file, you can do it in a more explicit way like this:
define("A", [], function () { return ...whatever... });
define("B", [], function () { return ...whatever... });
Edit:
for defining one module with two functions you can use different patterns. For a singleton (i.e. no "Class") I usually do something like this:
define(function () {
var myModule = {
fn1: function () { .... },
fn2: function () { .... }
};
return myModule;
});

Making use of browserified NodeJS file into browser

I have a NodeJS file which I browserfied using browserify module. I used following command
browserify testFile.js -o bundle.js
To make use of this file in browser, I am making use of window object.
Assume below code is generated after browserifying the file.
var Main = function () {
this.foo = function () {
},
this.temp= function () {
},
this.bar= function () {
}
}
to make use I changed it to
window.Main = function () {
this.foo = function () {
},
this.temp= function () {
},
this.bar= function () {
}
}
and then to use of these functions, I used following code:
var obj= new Main ();
and then I can say obj.foo(); or obj.bar();
All this is working fine but I wonder if this is the right way to call function from a browserfied file.
Please suggest correct way to make use of browserfied file.
Browserify is a great tool when you use it for the entire project. It makes almost no sense to use it for single files only. The whole point of it is avoiding globals, instead of setting window.Main you could do this:
module.exports = function () {
this.foo = function () {
},
this.temp= function () {
},
this.bar= function () {
}
}
And then in all files that need access to the above, do:
var Main = require('./path/to/main.js');
Browserify resolves and inlines all require calls automatically so you only need to run Browserify on the single file that fires up the app.

How can I call a function that's created inside a chain of other functions?

I have created the following:
module Admin.Grid {
export function addGridControls() {
$('#createLink')
.click(function () {
var $link = $(this);
$link.prop('disabled', true);
adminDialog($link);
return false;
});
}
}
This is converted to:
var Admin;
(function (Admin) {
(function (Grid) {
function addGridControls() {
$('#createLink').click(function () {
var $link = $(this);
$link.prop('disabled', true);
adminDialog($link);
return false;
});
Previously when it was not inside a module I called the function like this:
$(document).ready(function () {
"use strict";
addGridControls()
});
Now it's inside of a module what's the best way for me to call this
function so it gets executed every time the document is ready?
One way of doing this is, is to add the function to some object.
var Admin = {};
(function (Admin) {
(function (Grid) {
Admin.addGridControls = function () {
....
And call it like
$(document).ready(function () {
"use strict";
Admin.addGridControls()
});
As #Mike Lin has commented, you need to import the module.
Working in TypeScript (and assuming AMD module format, with your module in another file), you can do it like this:
import g = module('path-to-admin-grid-module');
$(document).ready(() => {
"use strict";
g.Admin.Grid.addGridControls();
});
Otherwise, if you're just using internal modules within the same file, it's as simple as:
$(document).ready(() => {
"use strict";
Admin.Grid.addGridControls();
});
The latter case is nicely previewed in the Walkthrough: Modules example here: http://www.typescriptlang.org/Playground/
There's a pretty good example of the former here: TypeScript compile AMD modules with required defines and AMD is covered in more detail here: http://requirejs.org/docs/whyamd.html

Categories

Resources