PDA

View Full Version : [DHTML] Flexible AJAX table - DBGrid



BYK
08-04-2008, 06:39 AM
1) CODE TITLE: DBGrid

2) AUTHOR NAME/NOTES:
BYK (byk@amplio-vita.net) (JavaScript & CSS)
snlzkn (snlzkn@amplio-vita.net) (PHP, Demo & Wiki)

3) DESCRIPTION:
This is a very easy to implement, very easy to use Javascript based table. It uses XML files as source, and also capable of sending POST queries to gather dynamically generated data.

It supports client side sorting, filtering and grouping. It also supports exporting to Excel file format(this is server based with the PHP file we provide).

Here is a simple demo: http://amplio-vita.net/JSLib/demos/DBGrid
Here is a wiki which tells the basics: http://code.google.com/p/av-jslib/wiki/aVDBGrid

4) URL TO CODE:
http://code.google.com/p/av-jslib

BYK
08-11-2008, 06:53 PM
No comments yet? Look what I say, if something is perfect, then nothing need to be said since you would just say "oh yes, great work" etc. OR if something is too bad, again you might not say anything since everything you'll say would be negative or there would be a lot to say :)

So, since I know this work is neither perfect nor too bad(err. OK assuming this part ;)) I and my friend would love to hear your ideas to improve it. So come on, say something :)

Nile
08-11-2008, 07:03 PM
I love this script, I think its great.

TheJoshMan
08-11-2008, 11:31 PM
I looks well done, however I don't think I could find any reason to ever use it personally.

BYK
08-12-2008, 07:06 AM
First of all thank you for your kind responses :)

@Nyne Lyvez
We are using this module for a commercial site which is heavily based on database entries, searching and organising them so it might look a bit serious but its appearance is fully customizable with its css base so may be you may find it useful if you ever intend to show dynamically generated, tabulated data on your personal page(yeah, I know it is unlikely :)).

dailytool
08-21-2008, 06:03 AM
Do you think this would work for this:?

http://www.dynamicdrive.com/forums/showthread.php?p=158230

Thanks for any input...

BYK
08-21-2008, 06:25 AM
To display and manage(filter, sort, group etc.) server-side filtered data(by searching on server side I mean) yes it would be extremely useful and a good fit. But if you want to supply a 18.000 rowed table data to DBGrid it will most probably freeze the browser for a long period. If the browser is IE then it will definetly not work with that amount of data, with browsers which has a fast JS engine, like Fx3, it might work but I strongly depreciate it. You should filter first. There should be at most a few thousand records in the client-side.

You can try SQLite which does not require a huge install(and might be work portable) and Apache again which might work portably. Or you can check PHP2EXE ;)

BYK
09-13-2008, 12:20 PM
Added client side paging support. JSON support is on its way. You can check the demo to see the paging support.

dailytool, it might work with your project now since it does not try to print all the records at once. ;)

Twey
09-13-2008, 01:09 PM
Good idea, but poorly implemented. There are a series of memory leaks, and all the methods of DBGrid objects are needlessly recreated for each new instance.

BYK
09-13-2008, 01:47 PM
I switched to prototype based implementation. :)

And can you give some examples of memory leaks and some ways to avoid them. For example I have to assign a "creator" property to the HTML table objects in order to access the original object from the event handlers. Is there any other way? EDIT: Yes there is and I'm working on it.

BTW, looking at a few things and then saying "poorly implemented" is really easy, the hard thing is to see the good points and give suggestions to improve the bad things. ;)

BYK
09-13-2008, 02:56 PM
Ok. Now, as stated in the above message, switched to prototype based definitions AND removed all cyclic references under the name of creator.

There a few minor issues about paging when the filtering or grouping is active, will fix them soon.

Do you see any more memory leaks Twey?

Twey
09-13-2008, 08:15 PM
I did point them out, but the explanation is long and involved, and judicious use of Google (http://www.google.com/search?q=javascript+memory+leaks) will get you far. :)

I don't see any further obvious memory leaks, although it's getting late and my head hurts, so my soundness of judgment is currently questionable. There are some other poor programming practices in there, though, like looping over that huge object in unite() to no apparent purpose, and extending Object in the first place. See http://blog.metawrap.com/blog/June6thIsJavaScriptArrayAndObjectprototypeAwarenessDay.aspx.

Here's another solution if you like extending stuff:
var using = (function() {
var extensions = {}, global = this;

function isApplied(extn) {
var e = extn.split('.');
return extensions[e[0]][e[1]] && global[e[0]].prototype[e[1]];
}

function apply(extn) {
var e = extn.split('.');
return global[e[0]].prototype[e[1]] = extensions[e[0]][e[1]];
}

function unapply(extn) {
var e = extn.split('.');
delete global[e[0]].prototype[e[1]];
}

function using() {
var extns = Array.prototype.slice.call(arguments);
return function(fn) {
return function() {
for (var i = extns.length; --i >= 0; )
if (!isApplied(extns[i]))
apply(extns[i]);
else
extns.splice(i, 1);

var r = fn.apply(this, Array.prototype.slice.call(arguments));

for (var i = extns.length; --i >= 0; )
unapply(extns[i]);

return r;
};
};
}

function add(c, o) {
for (var x in o)
if (o.hasOwnProperty(x))
(extensions[c] || (extensions[c] = {}))[x] = o[x];
return o;
}

using.add = add;

return using;
})();This permits you to write code like:
using.add("Array", {
map: function(f, a) {
for (var i = a.length, r = []; --i >= 0; )
r[i] = f(a[i]);
return r;
},

reduce: function(f, t, a) {
for (var i = 0, n = a.length; i < n; ++i)
t = f(t, a[i]);
return t;
}
});

// ... then use it:

var sumDoubles =
using("Array.map", "Array.reduce")
(function(a) {
return a.map(function(n) { return n * 2; }).reduce(function(a, b) { return a + b; });
});

// And call the function normally:

sumDoubles([1, 2, 3]); // 12 (2 + 4 + 6)

BYK
09-13-2008, 10:25 PM
Thank you very much for the resources I'll look into them.

I'm using unite to allow users to use an external configuration file so that they do not have to change the original JS file everytime it is updated. Unite assures that everything is covered up even if the user does not fill out every config area and does not override them. But extending Object class, well I thought about it, the only difficulty was that I had to use "hasOwnProperty" check in every "for in" loop but I do not know any disadvantages so I'll look into the article that you have given.

Thanks again ;)

EDIT: I have read the article and again, if you use hasOwnProperty verification there is not much danger except that if you use any preserved name for a hash object as Dean Edwards stated. Will look into this and try to find an easy and compatible way for both of them ;)

Twey
09-14-2008, 11:56 AM
Also that you're adding a property to the lookup chain of every object in the environment, which I suspect would cause some fairly considerable performance issues. The using() function I outlined above should be quite sufficient.

Certainly you can use hasOwnProperty() to check, but you shouldn't have to — and more importantly, your users shouldn't have to. You are developing a library for reuse by yourself and other users: it's up to you to make it play nicely. I personally don't bother extending built-ins any more without careful use of using(): it's messy. Simple code like:
if ('foo' in bar)becomes
if ('foo' in bar && bar.hasOwnProperty('foo'))while a simple for..in loop
for (var x in bar)becomes
for (var x in bar)
if (bar.hasOwnProperty(x))Nasty, verbose, easy to forget, and irritating in the cases where there really are properties one would like to add to the prototype that one would prefer to be able to iterate over. If you want to deal with this in your own code, go ahead, but limit it with using() so other people don't have to.

Oh, minor hint:
foo = foo ? foo : bar;
// can become: foo = foo || bar;

if (!foo)
foo = bar;
// can become: foo = foo || bar;

if (!foo)
foo = {};
foo = foo.unite(bar);
// can become: foo = (foo || {}).unite(bar);

BYK
09-14-2008, 02:57 PM
Actually, moving a few functions outside the Object prototype won't hurt anyone so I think I'll simply make them functions which are taking the objects as their first parameters. Simple and effiicient enough I think? :)

Twey
09-14-2008, 04:52 PM
Indeed. Greatly preferable.