Go Back   CodingForums.com > :: Client side development > JavaScript programming

Before you post, read our: Rules & Posting Guidelines

Reply
 
Thread Tools Rate Thread
Enjoy an ad free experience by logging in. Not a member yet? Register.
Old 01-12-2013, 11:54 AM   PM User | #1
Kyle123
New Coder

 
Join Date: Jan 2013
Posts: 10
Thanks: 3
Thanked 1 Time in 1 Post
Kyle123 is an unknown quantity at this point
Loading Javascript Modules through Ajax

Disclaimer, I posted this here, but was told it wasn't the place since it was more of a question of approach than non-working code. In hindsight I agree, SO isn't really the place for discussing things.

Apologies for the long post, I've tried to only include the relevant bits and the code works, I'm just looking for a better/more accepted method.

I'm really just beginning in Javascript, and despite much googling I can't find the preferred method of doing what I'm attempting to do.

I'm creating a desktop style web page which will have a lot of small self contained applications that I want to load in as required through Ajax. Some of these may take a while to load, so I don't want to load them all at once and many of them will not be required for all users. I'm also trying to limit the scope of the variables since a lot of the "widgets" will use the same libraries so I'm trying to create self contained javascript modules (keeping them separate to make them easier to work on in isolation) that "plug in" to the desktop module. I'm currently using a model like the below (simplified) and to be honest, I'm not really sure whether I'm committing some fundamental errors since I've never used js in this way before.

I've used this as the base of what I'm doing: http://sonspring.com/journal/jquery-desktop

I've got a main page that lays out the desktop environment, each widget will be called by clicking on a link like this:
PHP Code:
    <class="abs icon ui-draggable active" style="left:20px;top:100px;" href="#icon_dock_admin" rel="targets">
          <
img src="/images/desktop/icons/icon_32_drive.png">
          
Targets
    
</a
Which chains to (in the taskbar):
PHP Code:
      <li id="icon_dock_targets">
        <
a href="#window_targets">
              <
img src="/images/desktop/icons/icon_22_admin.png">
              
Admin
       
</a>
      </
li
The base js looks something like:
PHP Code:
    var DSK = (function($, windowundefined) {
      return {
        
go: function() {
          for (var 
i in DSK.init) {
            
DSK.init[i]();
          }
        },
        
init: {
            
desktop: {
             var 
= $(document);
             
d.on('dblclick''a.icon', function() {
              
// Get the target.
              
var winsrc = $(this).attr('rel');
              
//check rel exists
              
if(typeof winsrc !== 'undefined' && winsrc !== false) {
              
                  var 
= $(this).attr('href');
                  var 
= $(x).find('a').attr('href');
    
                  
// Load the window if it doesn't exist in the page.
                  
if($(y).length==0) {
                     $.
get('/'+winsrc, function(data) {
                       $(
"#desktop").append(data);
                       
DSK.apps[winsrc].go();
                     });
                  } else { 
                    
//show window
                  
}
            } else {
                
alert('application not found');
            }});
            }
        },
        
apps: {}    
      }
    })(
jQuerythisthis.document); 
The page (widget) that it calls is structured like this:
PHP Code:
    <div id="window_targets" class="abs window">
      
//some stuff
    
</div>
    <
script src="/js/desktopApps/targets.js"></script> 
The js for each widget is structured like this:

PHP Code:
    DSK.apps.targets = (function($, undefined) {
      return {
        
go: function() {
          var 
tgts DSK.apps.targets;
          for (var 
i in tgts.init) {
            
tgts.init[i]();
          }
        },
        
init: {
            
//Loading code
            
logIt: function() {
                
//some code
            
}
        }
      }
    })(
jQuerythis); 
All the code works and works for multiple widgets, but I'm thinking there's probably a better way of doing all this. So are there any major issues with my approach? and are there any frameworks/guidelines out there on how to load self contained js widgets into and existing page? The widgets will have a lot of html in them, so it's useful to be able to edit this directly rather than import the whole lot as javascript, it's also generated by PHP - I'm using codeigniter.

Any advice/pointers would be very much appreciated, thanks in advance.
Kyle123 is offline   Reply With Quote
Old 01-13-2013, 01:46 AM   PM User | #2
rnd me
Senior Coder

 
rnd me's Avatar
 
Join Date: Jun 2007
Location: Urbana
Posts: 3,455
Thanks: 9
Thanked 466 Times in 450 Posts
rnd me is a jewel in the roughrnd me is a jewel in the roughrnd me is a jewel in the rough
it's a neat idea, but it seems a bit complicated to me.
i have some bones about the markup:
i prefer data-attribs to trying to re-jigger existing attribs.
inline styles are harder to maintain and adjust than CSS.
the init routines look a little too boilerplate-heavy to me.

But, don't think that i am typical at all.
If it works for you and you can build and expand it, go for it.


a widgets is typically a combo of html, css, and js, not just JS.
you CAN use pure JS to build the widgets ui, but it would be a lot more code and harder to maintain than adding behavior to pre-styled HTML chunks.

if you don't need firefox compat, you can store raw html and css in a function's comment block. this lets you keep all three formats in one place and without escaping. Still, most people need firefox, so it gets complicated, and there's no "right" way".

one the one hand, you want all code unescaped for long-term maintenance, greater readability, and text editor suggestions. These assets are usually store together by type, in folders such as /css/ and /js/... On the other hand, you don't want to have to create several files, especially in several different places, each time you add a widget.

Lastly, you don't want to repeat yourself and make each widget a lot heavier than it needs to be. For example, Tabs and Accordions are 90% the same thing, just some behavior adjustments and some different css. It would be nice to be able to add capabilities like "between visit selection persistence" to both widgets from one place. If you had ten widgets in 38 different files, that simple upgrade can be a real chore...

i don't have a perfect solution for you. i would try to build two or three master scripts that provide a framework for making the widgets i need. I think this is how YUI works.

you may want to look into newer copies of dojo: they have a lot of self-contained interaction widgets, and they are now famous for self-loading self-contained widget architecture. I must warn you that AMD modules are probably going to make your head spin at this point; they still give me headaches.
__________________
my site (updated 5/13)
STATS (2013/5) HTML5:90.2% MOB:14% IE7:0.5% IE8:8.6% IE9:9.8% IE10:10%
rnd me is offline   Reply With Quote
Users who have thanked rnd me for this post:
Kyle123 (01-13-2013)
Old 01-13-2013, 05:31 PM   PM User | #3
Kyle123
New Coder

 
Join Date: Jan 2013
Posts: 10
Thanks: 3
Thanked 1 Time in 1 Post
Kyle123 is an unknown quantity at this point
Thanks, that's really useful input.

I hadn't considered data-attribs, makes sense to convert those and stop abusing the rel tag

I'm not sure entirely what you mean by boilerplate heavy, do you mean that it adds spurious code that isn't really needed/too formulaic?

I get your point on inline styles, but I'm not too concerned about them since they're only to initially lay out the "icons" on the desktop, then they're all draggable.

Thanks for the pointers on Dojo and YUI, I'll check them out. I'm intrigued with the approach of putting css and html in the comment block, what would this look like? I don't need FireFox compat since it'll be used in an intranet environment.

As for repeating code, I was getting round this by including common libraries in the desktop page at load, so they'll always be there, Jquery, Jquery UI and datatables to now.

Thanks again for your help
Kyle123 is offline   Reply With Quote
Old 01-14-2013, 09:57 AM   PM User | #4
rnd me
Senior Coder

 
rnd me's Avatar
 
Join Date: Jun 2007
Location: Urbana
Posts: 3,455
Thanks: 9
Thanked 466 Times in 450 Posts
rnd me is a jewel in the roughrnd me is a jewel in the roughrnd me is a jewel in the rough
Quote:
Originally Posted by Kyle123 View Post
I'm not sure entirely what you mean by boilerplate heavy, do you mean that it adds spurious code that isn't really needed/too formulaic?
the js for each widget. you should be able to move the loop to some base file, and you don't need the anon function wrapping it all. also, imho, a widget file should include a bit of meta about itself, like name, filename, lastupdate, copyright, short description, etc. trust me, when you look at a file in 18 months, you'll be glad it's there. That meta can replace the loop and anon for a non-weight-adding swap that leaves a better module behind.




Quote:
Originally Posted by Kyle123 View Post
Thanks for the pointers on Dojo and YUI, I'll check them out. I'm intrigued with the approach of putting css and html in the comment block, what would this look like? I don't need FireFox compat since it'll be used in an intranet environment.
functions can be viewed as thier source code using their toString() method. except for firefox, this source view includes code comments.
as long as your css or html does not contain "*/", you can store it safely in a comment. all you need to do is grab the function's string, split it at the comments, and bingo: multi-line unquoted or escaped text.


i've been doing this sort of thing for at least five years, and it's even better on mobile than it was for desktops, thanks to webkit being king. the code in that linked post is ancient, don't use it (E4X is dead in FF now/next ver). it was from a time when there were really only two browsers: blue and orange...

anyway, here is a copy/demo of the ripper i use for single-block markup functions:

Code:
function rating1(){/*

<fieldset class="fieldset">
	<legend>Rate Thread</legend>
	<div style="padding:3px">
		<div>If you like, you can add a score for this thread.</div>
		<div>
			<select name="rating" tabindex="1">
				<option value="0">Choose a rating</option>
				<optgroup label="&nbsp;">
					<option value="5">5 : Excellent</option>
					<option value="4">4 : Good</option>
					<option value="3">3 : Average</option>
					<option value="2">2 : Bad</option>
					<option value="1">1 : Terrible</option>
				</optgroup>
			</select>
		</div>
	</div>
</fieldset>

*/}



//unpacks a single commented block in a template function:
Function.prototype.rip=function(){
  return String(this).split("*/")[0].split("/*")[1];
}



//example of using ripper:
alert(  rating1.rip()  ) //shows HTML above without JS wrappings...
__________________
my site (updated 5/13)
STATS (2013/5) HTML5:90.2% MOB:14% IE7:0.5% IE8:8.6% IE9:9.8% IE10:10%

Last edited by rnd me; 01-14-2013 at 09:59 AM..
rnd me is offline   Reply With Quote
Users who have thanked rnd me for this post:
Kyle123 (01-15-2013)
Old 01-15-2013, 01:44 PM   PM User | #5
Kyle123
New Coder

 
Join Date: Jan 2013
Posts: 10
Thanks: 3
Thanked 1 Time in 1 Post
Kyle123 is an unknown quantity at this point
Sorry for my delayed response, I can see how that's useful.

Yes, I can move the loop for the widget into a base file and I hear you on the meta - It's something I'm a big advocate of in other coding projects.

Thanks again for your help
Kyle123 is offline   Reply With Quote
Old 01-21-2013, 04:34 PM   PM User | #6
Kyle123
New Coder

 
Join Date: Jan 2013
Posts: 10
Thanks: 3
Thanked 1 Time in 1 Post
Kyle123 is an unknown quantity at this point
IF anyone's interested in a similar project, I found that the most efficient/neatest way of doing this is through a module loading library. I've used requirejs, the basic method is:

A main loading module that handles all the desktop set up and handles the loading of additional modules. Standalone js modules are then called as required and added to the desktop, these are pure js/jquery modules containing no html. Each of them contain a url to the html for the "widget" which is called by the main desktop js.

This approach has allowed a lot of flexibility, where the widget html content needs to be rendered by the server the page is called via ajax, otherwise the js in the widget builds the html.

requireJS has also reduced initial loading times since there's no requirement to load js libraries that aren't linked to widgets just in-case the user wants to use them
Kyle123 is offline   Reply With Quote
Reply

Bookmarks

Jump To Top of Thread


Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +1. The time now is 01:09 AM.


Advertisement
Log in to turn off these ads.