using revealling moduler pattern for complex in javascript - javascript

I have a very complex class so i decided to break into sub modules and trying to use revealing modules pattern.
I have main class and decided to divide into smaller container function. but in current scenario
But i am not able to access any internal function from outside i.e callSearchResultWithCallBack using searchFinder.Search.callSearchResultWithCallBack(). which pattern should i use to keep this code clean as well have control to call internal function in sub module.
Thanks
var searchFinder;
function SearchFinder() {
me = this;
this.searchResult = null;
this.init = function() {
declareControls();
createAccordian();
addEvents();
fillControls();
var declareControls = function() {
this.SearchButtons = jQuery('.doSearch');
this.InputLocation = jQuery('#inputLocation');
this.InputDistanceWithIn = jQuery('#inputDistanceWithIn');
this.InputName = jQuery('#inputName');
}
var addEvents = function() {
me.SearchButtons.click(function() {
me.Search();
});
}
var fillControls = function() {
var getGetCategory = function() {
}
}
}
this.Search = function() {
var url = '';
var searchCriteria = {};
validateAndCreateCriteria();
callSearchResultWithCallBack();
function validateAndCreateCriteria() {
function validateAandGetCategory() {
if (SearchValidation.ValidateZipCode(me.InputLocation.val().trim())) {
searchCriteria.location = me.InputLocation.val().trim();
} else if (SearchValidation.ValidateCityState(me.InputLocation.val().trim())) {
searchCriteria.location = me.InputLocation.val().trim();
}
}
}
// need to access it outsite
function callSearchResultWithCallBack() {
me.searchResult(searchCriteria, SearchResultCallBack);
function SearchResultCallBack() {
}
}
}
}
jQuery(function() {
searchFinder = new SearchFinder();
searchFinder.init();
searchFinder.Search.callSearchResultWithCallBack();
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>

This code has multiple issues, first I will address the fact that for example declareControls is not executing. First declare the function than execute!
this.init = function() {
var declareControls = function() {
this.SearchButtons = jQuery('.doSearch');
this.InputLocation = jQuery('#inputLocation');
this.InputDistanceWithIn = jQuery('#inputDistanceWithIn');
this.InputName = jQuery('#inputName');
}
var addEvents = function() {
this.SearchButtons.click(function() {
me.Search();
});
}
var fillControls = function() {
var getGetCategory = function() {
}
}
declareControls();
//createAccordian(); //not defined
addEvents();
fillControls();
}
Now let's look at others problems that will arise.
the me object referring to this is in the scope of searchFinder and does not refer to the same this in the instance of searchFinder.
function jQuery can be replaced by the commonly used $.
searchFinder.Search.callSearchResultWithCallBack() this is never going to work. Since the Search function is an object and callSearchResultWithCallBack isn't a property of this function.
Solution; make it part of the prototype of Search.
Steps:
Move callSearchResultWithCallBack outside the search function.
Add prototype to Search function
Call function via prototype.
function callSearchResultWithCallBack() {
me.searchResult(searchCriteria, SearchResultCallBack);
function SearchResultCallBack() {
}
}
this.Search.prototype.callSearchResultWithCallBack = callSearchResultWithCallBack;
If you want to fire this function outside of search use this:
searchFinder.Search.prototype.callSearchResultWithCallBack();
Please remember that callSearchResultWithCallBack will throw an error because searchCriteria is undefined.
This fixes your problems for now, but this code has to be revised thoroughly. But this should get you started. http://ejohn.org/blog/simple-javascript-inheritance/

Related

javascript class with event methods

My goal is to make a class with some chained functions, but I'm stuck and hoping for some help. This is what I got:
robin = new batman("myiv");
var batman = (function() {
var me = this;
function batman(id){
me._id=id;
document.getElementById(id).addEventListener('mousemove', me.mouseMoving.bind(me),true);
}
this.mouseMoving = function(){
document.getElementById(me._id).style.background="orange";
}
return batman;
}
And this pseudo code is what I am aiming to get. Basically, pass in the ID of an element in my HTML and chain functions to it such as onclick etc, and whatever code inside there, runs. as in example, changing background colors.
Is it possible?
superman("mydiv"){
.onmouseover(){
document.getElementById(the_id).style.background="#ffffff";
},
.onmouseout(){
document.getElementById(the_id).style.background="#000000";
},
etc...
}
edit: updated with missing code: "return batman;"
You can do method chaining by returning the current object using this keyword
var YourClass = function () {
this.items = [];
this.push = function (item) {
if (arguments) {
this.items.push(item);
}
return this;
}
this.count = function () {
return this.items.length;
}
}
var obj = new YourClass();
obj.push(1).push(1);
console.log(obj.count())
Working sample
https://stackblitz.com/edit/method-chaining-example?file=index.js

I wanted to make a javascript library function is not working

I wanted to call the run function that should call the other and action will be done on the base of element_id
NGL = {}
NGL.SceneBuilder = function() {
var yamlFile = 'http://example.com/main.yaml'
var parseYaml = function() {
}
var buildScene = function() {
// other code
simulationStarted(element_id);
}
return {
run: function(element_id) {
parseYaml();
buildScene(element_id);
}
}
}
NGL.SceneBuilder.run('#someid');
You're not executing your factory so NGL.SceneBuilder is a function, not an object having the run property. Call the function :
NGL.SceneBuilder = (function() {
...
})(); // <<===
Note also that you forget to declare the element_id parameter in buildScene but maybe is it just for the question.

How do I call a nested JavaScript function properly

I'm trying to set up function a nested function that I can call throughout my script, but I keep getting "error undefined is not a function". Perhaps someone can help me with how to do this correctly.
First I set global my variables:
var trigger = document.getElementById('trigger');
var subject = document.getElementById('subject');
Then I create a show/hide function:
var toggleVis = function() {
function showSomething() {
trigger.classList.add("active");
subject.classList.add("active");
}
function hideSomething() {
trigger.classList.remove("active");;
subject.classList.remove("active");
}
}
Then I set my event listener:
trigger.addEventListener('click', function() {
if ( subject.classList.contains("active") ) {
toggleVis.hideSomething();
}
else {
togglePicker.showPicker();
}
});
The reason I'm trying to do it this way is that there will be other triggers for subject on the page that will need access to the show/hide functions.
You can't access the functions inside the function, they are out of scope, you could attach them as properties to the wrapping function, but it looks like you just need an object
var toggleVis = {
showSomething: function() {
trigger.classList.add("active");
subject.classList.add("active");
},
hideSomething: function() {
trigger.classList.remove("active");;
subject.classList.remove("active");
}
}
Your togleVis variable is a function and not an object so you can't do toggleVis.hideSomething(). Try updating your code to :
var toggleVis = (function() {
return {
showSomething : function () {
trigger.classList.add("active");
subject.classList.add("active");
},
hideSomething : function () {
trigger.classList.remove("active");;
subject.classList.remove("active");
}
};
}());
With this toggleVis is now an object with two properties showSomething and hideSomething functions.

How to call public method from a event handler

I have the function below.
Everything works fine except for the Push, Pop and Remove method. These method should be called by the event-handler. This event is fired by the Google Maps API.
The problem is that when the event is fired, these method are not found. I have a "Push is not defined" error message.
I tried with this but that's not working.
How do I call the public method from the event handler?
function Track(mapContainer) {
var map = mapContainer;
var points = new Array();
var isEditMode = false;
var clickListener;
this.Push = function(point) { ... }
this.Pop = function() { ... }
this.Remove = function(point) { ... }
//Enable / disable the marker placements
this.PlaceWaypoint = function(isPlacing) {
if (isPlacing != true) {
if (clickListener != null) {
google.maps.event.removeListener(clickListener);
clickListener = null;
}
} else {
clickListener = map.AddEvent("click", function(event) {
if (!IsDoubleClick()) {
var point = map.PlaceMarker(new WayPoint(event.latLng))
point.RemoveListener(function() { Remove(point); });
Push(point);
} else {
Pop();
}
});
}
}
}
You've got a closure/binding problem. One convention that is frequently used it to assign a variable called self of that, which can later be used in place of this, thanks to the closure properties of JS.
function Track(mapContainer) {
var map = mapContainer,
points = new Array(),
isEditMode = false,
clickListener,
// Make a variable self that points to this, that can be used inside closures
// where the original context is lost
self = this;
this.Push = function(point) { ... }
this.Pop = function() { ... }
this.Remove = function(point) { ... }
//Enable / disable the marker placements
this.PlaceWaypoint =
function(isPlacing) {
if (isPlacing != true) {
if (clickListener != null) {
google.maps.event.removeListener(clickListener);
clickListener = null;
}
} else {
clickListener = map.AddEvent("click", function(event) {
if (!IsDoubleClick()) {
var point = map.PlaceMarker(new WayPoint(event.latLng))
point.RemoveListener(function() { Remove(point); });
// Use the closure reference self instead of this
self.Push(point);
} else {
// Use the closure reference self instead of this
self.Pop();
}
});
};
}
this always refers to the context of the current function, so if you use this in your event handler it refers to that function calls this, not the this in your Track function.
To create a closure that accesses the this of an outer scope, you need to assign that this to a new variable which can be accessed from the inner function:
var self = this;
this.PlaceWaypoint = function(isPlacing) {
// ...
self.Pop();
// ...
}
First of all Pop and Push is not global, second this in the inner scope has another meaning. So you can use closure and rename the "this" to variable of more global scope.
function Track(mapContainer) {
//....
var $this = this;
//Enable / disable the marker placements
this.PlaceWaypoint = function(isPlacing) {
if (isPlacing != true) {
if (clickListener != null) {
google.maps.event.removeListener(clickListener);
clickListener = null;
}
} else {
clickListener = map.AddEvent("click", function(event) {
if (!IsDoubleClick()) {
var point = map.PlaceMarker(new WayPoint(event.latLng))
point.RemoveListener(function() { $this.Remove(point); });
$this.Push(point);
} else {
$this.Pop();
}
});
}
}
}

Javascript Object Confusion

I've confused myself nicely here. My scenario is as follows:
function DesignPad() {
function EditBar() {
...
this.removeHandler = function() {
**// how do I call Dragger.removeAsset**
}
}
function Dragger(){
...
this.removeAsset = function() {}
}
this.init = function() {
this.editBar = new EditBar();
this.dragger = new Dragger();
}
}
var dp = new DesignPad();
...
I can't seem to call Dragger.RemoveAsset. I understand the why, my question is how do I call it?
I'm trying to keep like-things separated (e.g. Dragger / EditBar) but I seem to get all sorts of mixed up in my event handlers. Any suggestions, good reading materials, etc. on this stuff?
I found Douglas Crockford's Javascript to be the best introduction to JavaScript. Especialy videos for Yahoo, like: The JavaScript Programming Language where you can learn how exactly are objects created and inherited in JS.
Solution to you problem is:
function DesignPad() {
var that = this;
function EditBar() {
this.removeHandler = function() {
print("RemoveHandler");
that.dragger.removeAsset();
}
}
function Dragger() {
this.removeAsset = function() {
print("RemoveAsset");
}
}
this.init = function() {
this.editBar = new EditBar();
this.dragger = new Dragger();
}
}
var dp = new DesignPad();
dp.init();
dp.editBar.removeHandler();
But as others noticed you could refactor some things :).
To me it just looks like you should refactor that code to make it simpler.
I think that your issue comes from the fact that a nested function is private, so you can't access it from outside.
Is an instance of Dragger a 'property' of your DesignPad object? If so, you could pass a reference to that object into your removeHandler() method.
Try this:
function DesignPad() {
function EditBar(s) {
super = s;
this.removeHandler = function() {
alert('call 1');
super.dragger.removeAsset();
}
}
function Dragger(s){
super = s;
this.removeAsset = function() {
alert('call 2');
}
}
this.init = function() {
this.editBar = new EditBar(this);
this.dragger = new Dragger(this);
}
}
var dp = new DesignPad();
dp.init()
dp.editBar.removeHandler();
alert('end');

Categories

Resources