This weekend I had one of those “oh DUH” moments which I have been struggling with for quite some time. How can I better structure my jQuery selectors and make the code more maintainable? I came across this excellent article – Decoupling your HTML CSS and JavaScript and it all came into focus.
The problem
Using JavaScript selectors (dojo or jQuery) in XPages can be a problem because of the id naming scheme used by the JSP generator “id=”view:_id1:_id2:link5” and how this falls over in a selector. So an alternate to not having to mess with is attributes is to use class selectors $(‘.class’) which is actually much simpler and less troubling to get your head around.
When you are using class selectors for a DOM element which already has a class then awesome I don’t have to add any more classes. Using this bootstrap example there are multiple classes I can get a hold of to manipulate the dialog contents.
<div class="modal fade myModal" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close modal-maxmin" aria-hidden="true"> <i class="icon-external-link"> </i> </button> <button type="button" data-dismiss="modal" class="close" aria-hidden="true"> <i class="icon-remove"> </i> </button> <h4 class="modal-title">modal-title</h4> </div> <div class="modal-body"> modal-body : HERE GOES THE MESSAGE </div> <div class="modal-footer"> <div class="btn-group"> <button type="button" class="btn btn-default modal-cancel" data-dismiss="modal">CANCEL</button> <button type="button" class="btn btn-primary modal-ok">OK</button> </div> </div> </div><!-- /.modal-content --> </div><!-- /.modal-dialog --> </div><!-- /.modal -->
To add something to the body of the dialog I would do something like this
$(".modal-body").html('Hi Marky')
The other problem
This example is very “coupled” code whereby my JavaScript selector is coupled to the real class file used by the HTML code. In reality what it means is that if I have to change the classname for some reason (hmm an example – oh I don’t know – going from Bootstrap2 to Bootstrap3 for example) then my JavaScript breaks down. While tightly coupled code is easy to follow, easy to create initially, it can be an absolute nightmare in the long run.
The epiphany moment
As I am reading Philip Walton’s article I am struck by the “oh well no duh” moment when he talks about using js-* as a naming convention for classes which only exist for JavaScript selection.
- My personal recommendation is to use a prefix for all JavaScript hooks. I use
js-*
. That way, when a developer sees such a class in the HTML source, she’ll know exactly where to look to discover its purpose.
Well no duh – brilliant idea!
In all senses this makes perfect sense:
- The developer does not have to search through CSS files looking to see if you used the class as a selector as a real CSS marker
- (well ok they changed something and the CSS broke, then they started to look for it)
- It is immediately apparent from looking at the HTML that there is some dojo or jQuery selection/manipulation going to go on in this area because of the js-* class naming scheme
- Within eclipse you can do a quick search and find out what is trying to manipulate this area before you go and ruin it
The new code
A very simple change to the modal-body but this then decouples my code form the bootstrap code – allowing me to make changes to the bootstrap classes int he future without breaking my JavaScript
<div class="modal fade myModal" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <button type="button" class="close modal-maxmin" aria-hidden="true"> <i class="icon-external-link"> </i> </button> <button type="button" data-dismiss="modal" class="close" aria-hidden="true"> <i class="icon-remove"> </i> </button> <h4 class="modal-title">modal-title</h4> </div> <div class="modal-body js-modal-body"> <!-- js-modal-body change here --> modal-body : HERE GOES THE MESSAGE </div> <div class="modal-footer"> <div class="btn-group"> <button type="button" class="btn btn-default modal-cancel" data-dismiss="modal">CANCEL</button> <button type="button" class="btn btn-primary modal-ok">OK</button> </div> </div> </div><!-- /.modal-content --> </div><!-- /.modal-dialog --> </div><!-- /.modal -->
To add something to the body of the dialog I would now select the js-* class not the modal-body itself
$(".js-modal-body").html('Hi Marky')
Comment
One of the things I love about my career is that it is an “always learning” experience for me. There are times like this where you think to yourself that is an awesome idea and you are very happy to learn it – and at the same time feel so stupid that you didn’t think of it yourself before 🙂