need suggestions for iterator function in javascript dom generator - javascript

am getting rid of all innerHTML and moving to strictly generated dom. reason below. have written a simple dom generator written in javascript that saves me a lot of work and keystrokes.
the big problem I'm having is how to implement an iterator. I feel like it should spit out a series of objects, sort of like a pipe, that the enclosing environment would process, but not much joy integrating the function. here is an example of my current solution
var div = E.div( '.myClass', 's.whiteSpace:nowrap',
'iterator': {
'set': { 'egg':'Scrambled Eggs', 'beer':'Chang Beer', 'yams':'Sweet Potatoes' },
'function':function(v,l) { return E.radio({'name':'myRadio', 'value':v},l); } } }
);
generates a div with three radio buttons. the iterator functionality inside E.div pulls out each value/label pair from the "set" and passes them to the "function", then processes the results of the function - in this case the function makes a radio button.
documentation on the factory plus better examples
http://code.google.com/p/chess-spider/wiki/DomFactory?ts=1302156868&updated=DomFactory
the current version of the javascript is
http://code.google.com/p/chess-spider/source/browse/http/scripts/factory.js
the reason why getting rid of innerHTML (and much raw html): would like the object responsible for the html to generate it as well as handle the triggers for it using closure functions. very big win, and impossible to do with quoted html. this gives the entire functionality contained in a nice "object".

This is more of a pointer. It seems the you can accomplish your task more easily using a JavaScript template engine. Try Handlebars.js and here's a good overview of Handlebars.js Iteration and many other features are available

Related

SugarCRM 7: Call BaseFilterLayout.applyFilter() method outside event context

I'm working on a customization for Sugar Professional 7.2.x that pushes a filter from an auxiliary script into the filter function for the list view page. By setting a breakpoint inside the applyFilter function and exporting the function itself as a member of the global object, I can then call the function from my script and execute a temporary filter accordingly. So I know I have the correct syntax for execution, e.g:
window.exportedApplyFilter(null, {name:"Mr. Rogers"});
The hangup is that I can't get that applyFilter function in any other way, e.g.
App.view.layout.someMagicObject.applyFilter(...);
Is there a way to access that function from another script?
Thanks to the Sugar team, I have an answer to my question. The solution is to pry in through the controller.layout object tree:
App.controller.layout.getComponent('sidebar').getComponent('main-pane')
This allows one to drill down to any Sidecar UI component and access the controller functions associated therewith. Perhaps not as elegant as other solutions, but it's readable.
If I wanted to take this further, I might write a short function to recurse through the subtree and look for the element with the correct CID number, then return the full path to it. CID numbers are progressive and advance depth-first, so the search would be pretty fast. But a hand search in the browser dev console only took minutes. Once that's found, accessing it again is a matter of a chain of getComponent(...) calls. The final return from the chain should be the element wanted (filter control, in my case) and should have the desired method as well.

jQuery best practice - using selectors vs function(variable)

This is a general question about best practice in jQuery syntax/code organisation.
Consider the following snippet, used in a jQuery AJAX function:
if(obj.status == "error"){
$("#alert").html(obj.message);
}
I have also seen this written as:
function alert_box(str)
{
var html_str = '';
$("#alert").html(html_str);
}
if(obj.status == "error"){
alert_box(obj.message);
}
Functionally, this is precisely the same. My question: Is there any semantic or practical reason for differentiating between the two? What about load time / performance issues?
This is seems to be a question of "why use functions in general"? The idea behind a function is that you're making a code block reusable without having to write out the same code again. If you want to do that same thing in several places throughout your script, the function makes sense. If you only do that once, it may not be as practical. Then again, functions also help you hide details where you don't care about them - so you can summarize an action while the details of that action are somewhere in that function definition.
In this specific case, that function is broken anyway. Rather than using the passed in argument str, you have an empty variable html_str that you're replacing the html contents of an element with. Also, there's no need here to use html rather than text, which is better performance.
function alert_box(str) {
$("#alert").text(str);
}
Even though this is only a one liner, this can still be practical because it would let you use alert_box in several places throughout the script and not have to change those places later if you decide to change what alert_box does. Even something like changing the id of the element would require changes in several places, for example.
It also worth noting that this function searches the DOM for "#alert" each time it runs. It would be most optimal to cache that reference like this:
$alert = $("#alert");
function alert_box(str) {
$alert.text(str);
}
A few things that are great to study:
KISS
DRY
SOLID aka OOP

When should I use data type classes in JavaScript

I come from a C# background. I've been working a lot with JavaScript lately. On a new app, I have a mysql/php back end. I'm going to be passing a lot of "types" back and forth.
So in my data base, I have several tables like
table1
id, fieldx,fieldy,fieldz
table2
id, fielda,fieldb,fielc
In c# I would definitely write classes for all those in the code. Which led me to implement things like so (in my JavaScript app):
function table1(id, x,y,z){
this.id=id;
this.x=x;
this.y=y;
this.z=z;
}
After about 6 tables worth of that, it suddenly occurred to me that maybe there was no point at all in making these classes.
So my question is, in a JavaScript app, do I use "classes" for data types? or should I just "document" which fields/types are expected and so in the code instead of
a.push(new table1(5,1,2,3));
I would just have
a.push({id:5,x:1,y:2,z:3});
This may seem like a preferences question but it's a fundamental language question that I have as I try to understand how to model my app's data in JavaScript. Is there any advantage of the classes (with only data fields) or is it just a mistake. Thanks.
It depends,
Note: Most of the programmers coming from a strong OO language will have trouble like you in regard to JavaScript's functional behavior (you are not alone).
If you want to create something closer to C# I would do the following:
function Table1(id, x, y, z) {
this.id=id;
this.x=x;
this.y=y;
this.z=z;
}
Table1.prototype.mySpecialTable1Method= function()
{
console.log(this.id);
};
Implementation:
var t = new Table1(1, 2, 3, 4);
t.mySpecialTable1Method();// outputs: 1
If you need to have methods that interact with the (soon to be) objects then I would definitely go with the code above. In addition it will make it clear when working with the objects that are related to a specific 'type' (naming the data).
But if your objects do not require any special "treatment" then I don't see any problem to use normal js object literals and pass them along (probably good for small projects).
Something along the lines:
var table1 = {};
table1.id = 1;
table1.x = 2;
table1.y = 3;
table1.z = 4;
console.log(table1.id); //outputs: 1
Extra reference:
http://www.youtube.com/watch?v=PMfcsYzj-9M
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Introduction_to_Object-Oriented_JavaScript
Update:
For the sake of readability and scalability and the point that you are coming from C# you may want to stick to the "class" implementation just because it will define the correlation between the raw data and the objects you are working with.
There is a good chance that you are going to work with some data that will probably be messy and unorganized.
MVC may be the solution for you. It tries to bring some order to the chaos that you are expecting. I recommend to check out some of them like: AngularJS or Ember.
Another solution may be reactive js - but mostly if you are going to interact with the DOM according to your data (ReactJS, and Facebook's React as some good ones).
As a note for security, I would like to add that mapping the data closely to the db isn't a best practice but its your call.
Javascript is a funny language, and there are plenty of ways to do things. An Object is an Object in Javascript with or without a name. {} is just a short-hand way to create one.
If you are going for readability, then your initial example would be the way to go.
If you just want to get the block of data into an array, then your second example is appropriate. Personally, I would use your later example if it is just data.
If you are using functions and what not as well as data storage, and plan on reusing it several times in your code, then yes, define your object and call it appropriately.
JavaScript has no classes, it is a functional language and a function is a first class citizen in js meaning that a function is an object.
From your example I can see that your intention for classes is simply to pass data and using json is perfect for this.

How can I pass a string, or list of function names to be processed as callbacks in Javascript

Done a bit of Googling, but not quite finding what I want.
In an effort to reduce the amount of JAvascript lines my applications requires, I am trying to use as many reusable functions as possible.
The problem of course is trying to make these functions and flexible as possible.
So I have a form which is dynamically expanded by a cloning function using jQuery. In order for this to work, there are a few additional functions which need to run, for example, to correctly initialise datepickers, on the dynamically created elements.
These requirements are different depending upon which form is being cloned.
So, I call my cloning function as follows:
$('.button').click(function (){
var thisID = $(this).attr('id').replace('add', '');
cloneDetails(thisID, initialiseDates);
});
The cloneDetails function looks like this:
function cloneDetails(cur_num, callBackFunctions) {
/// do loads of stuff ///
callBackFunctions();
});
In this instance, the cloning function will run and do what it needs, then it'll run a second function call initialiseDates
What I want to be able to do though is specify several function names to run after the cloning function, with a call such as
cloneDetails(thisID, 'initialiseDates, doSomethingElse, doAnotherThing');
So, stating a list of functions to run after the cloneDetails function has been run.
I don't think I am setting up the callBack method correctly, and don't know how I should be.
Help much appreciated.
EDIT: I don't want to bundle all these functions into a single function, the whole point is these functions should all be useable independently and/or together.
I can think of several approaches:
You can split the string and use eval(name+'()') in each name in the list. Note that eval() can be evil, security wise.
Instead of a string, why not pass the functions as an array? Simply iterate over arguments[1..n] (arguments is an automatic variable which contains all function arguments).
Use an anonymous function:
cloneDetails(thisID, function(){
initialiseDates();
doSomethingElse();
doAnotherThing();
});
I like the last approach because:
It's the most flexible
Readable
Only adds a few bytes of code where you need them
Most performant
Another option (if you're using jQuery > 1.7): You can use the jQuery.Callbacks function.
cloneDetails(thisID, $.Callbacks()
.add(initialiseDates, doSomethingElse, doAnotherThing));
function cloneDetails(cur_num, callBackFunctions) {
/// do loads of stuff ///
callBackFunctions.fire();
});

What is the proper way to control related objects in javascript?

I'm new to object oriented programming and am slowly learning how to apply it to javascript. So please bear with me. :)
I have two basic objects:
"record" which contains methods for editing a single record from a recordset. (create, save, load, etc.)
"recordList" which contains methods for outputting a paginated list of record titles.
I would like for these objects to be able to work together. For example, if record.save() is called, recordList.refresh() is also called, so that the paginated list reflects the updated data.
To accomplish this, I have created a third object "control" which contains instances of both "record" and "recordList". I am using "control" in the following fashion:
control = {}
control.record = object.create("record");
control.recordList = object.create("recordList");
control.save = function() {
this.record.save();
this.recordList.refresh();
};
This works. But I am wondering, is it proper? (I want to be sure I am not violating any of the rules of OO design in doing this.) Is there a better way?
Thanks in advance for your help.
Speaking from an OOP perspective, I don't think a record would save itself. A record in a database is simply data, and the database itself is what does things with that data, whether it's saving or loading or etc. That being said I'd make record be simply an object that holds data and would create a recordset object for interacting with the data. Within that recordset object you could put your recordList and update it accordingly. Something like:
var recordset = function() {
var me = this;
var currentRecord = object.create("record");
var recordList = object.create("recordList");
me.save = function() {
//Insert record.save code here
recordList.refresh();
};
};
Something to note about that code. In that setup currentRecord and recordList can't be accessed from outside the function and therefore you have encapsulation, one of the hallmarks of OOP. This is because the recordset function is a closure that "closes over" all variables within, meaning that every function within has access to the variables within the scope of recordset.
You could let the outside world get access through get or set functions:
me.getRecordList = function() {
return recordList.getArray(); //Not generally a good idea to simply return your internal object
};
Your solution is fine. Two minor suggestions for improvement
Use a more specific name than control (even 'recordControl' is ok). You may end up with lots of controls for different feature sets.
Use an object literal to create the entire object. Keeps your code tidier and more readable (and saves a few bytes)
(apologies for lack of spacing - editor not doing what I want it to do!)
recordControl = {
record : object.create("record"),
recordList : object.create("recordList"),
save : function() {
this.record.save();
this.recordList.refresh();
}
}
If it's one thing I've learned over time, it is that following any paradigm to the letter will result in more frustration and difficulty than taking the concept as far as you can go and using common sense to dictate your deviations.
That said, your solution will work fine and it's normal to create a container class for multiple objects of varying types that are coupled. If you want a different way to handle it, check out Client Event Pooling. The only thing that I can say about what you've done is to be sure you're using object.create the way it was intended.
Using this method you can create an event, which when triggered will perform a series of other commands that are associated with your event. I have used this with great success in all sorts of applications, from the intended event hooking to simplifying inline javascript injections after a postback.
Good luck.
why don't you provide your recordList into record?
var record = object.create("record");
record.recordList = object.create('recordList');
record.save = function(){
/*
do something
*/
this.recordList.refresh();
}

Categories