Overriding the default addressLayout.jsp

This week I had to override the existing addressLayout.jsp. At first I was very confused in how to do it so I discussed it with Daniel, Brian and I sent an mail to the dev list. Finally Ben gave me an wonderful example and using that I successfully overriden the default addressLayout.jsp. Actually I tried that before Ben sent me the example but by mistake I extended SimpleFormController for portlet instead of the servlet one. Finally Daniel noticed it and corrected it and I have successfully overridden it. I had to create my own controller since the controller which the portlets usually extends doesnt support formView.  But I think I am wrong in the moduleApplicationContext.xml part which is given below. Must show that to Daniel and cross check it. Or if you find something wrong in that please let me so that I can correct it.

Here’s a screenshot:

So this is how it overrides.

This is how i modified my moduleApplicationContext.xml

<bean id=”addresshierarchyUrlMapping” class=”org.springframework.web.servlet.handler.SimpleUrlHandlerMapping”>
<property name=”mappings”>
<props>
<prop key=”**/addressLayout.portlet”>addressLayoutPortletController</prop>
</props>
</property>
</bean>

<bean id=”addressLayoutPortletController” class=”org.openmrs.module.addresshierarchy.web.controller.AddressLayoutPortletController” >
<property name=”commandName”><value>addressLayout</value></property>
<property name=”commandClass”><value>org.openmrs.module.addresshierarchy.web.controller.AddressLayoutPortletController</value></property>
<property name=”formView”><value>/module/@MODULE_ID@/portlets/addressLayout</value></property>
<property name=”successView”><value>/module/@MODULE_ID@/portlets/addressLayout</value></property>
</bean>

Still I am not done with the backend. I have few doubts hope I will finish it within this week.

But I do face a problem with this. Whenever newPatient form reloads with some validation errors my addressLayout.jsp is missing there.

If someone has solution or suggestion please feel free to drop it here.

Advertisements

Codes for review

Tree builder JS

var TreeBuilder = {
buildTreeNodes:function (dataObjs, treeParentNode){
var arr=new Array("Start","Country","State","Sub Location1","Sub Location2","Sub Location3","Sub Location4","Sub Location5","Sub Location6","Postal Code","Longitude","Latitude");

for(var i=0; i<dataObjs.length;i++){
var typ = dataObjs[i].typeId;
var dumm = parseInt(typ);
var titl = dataObjs[i].title+”( “+arr[dumm]+” )”;
var node = dojo.widget.createWidget(“TreeNode”,{
title:titl ,locationName:dataObjs[i].title, locationId:dataObjs[i].locationId , typeId:dataObjs[i].typeId , parentId:dataObjs[i].parentId
});
treeParentNode.addChild(node);
treeParentNode.registerChild(node,i);
if(dataObjs[i].children){
this.buildTreeNodes(dataObjs[i].children, node);
}
}
},
buildTree:function (treeDat){
myTreeWidget = dojo.widget.createWidget(“Tree”,{
widgetId:”myNewTreeWidget”
});

this.buildTreeNodes(treeDat.treeNodes,myTreeWidget);
var treeContainer = document.getElementById(“myWidgetContainer”);
var placeHolder = document.getElementById(“treePlaceHolder”);
treeContainer.replaceChild(myTreeWidget.domNode,placeHolder);
DemoTreeManager.init();

}

};

Context menus and its actions

var DemoTreeManager = {
djWdgt: null,
myTreeWidget: null,
addTreeContextMenu: function(){

var ctxMenu = this.djWdgt.createWidget(“TreeContextMenu”,{});
ctxMenu.addChild(this.djWdgt.createWidget(
“TreeMenuItem”,{caption:”Add Location Component”,
widgetId:”ctxAdd”}));
ctxMenu.addChild(this.djWdgt.createWidget(
“TreeMenuItem”,{caption:”Edit Location Component”,
widgetId:”ctxEdit”}));
ctxMenu.addChild(this.djWdgt.createWidget(
“TreeMenuItem”,{caption:”Delete Location Component”,
widgetId:”ctxDelete”}));
document.body.appendChild(ctxMenu.domNode);
/* Bind the context menu to the tree */
ctxMenu.listenTree(this.myTreeWidget);
},

addController: function(){
this.djWdgt.createWidget(
“TreeBasicController”,
{widgetId:”myTreeController”,DNDController:”create”}
);
},
bindEvents: function(){
/* Bind the functions in the TreeActions object to the
context menu entries */
dojo.event.topic.subscribe(“ctxAdd/engage”,
function (menuItem) {
TreeActions.addNewNode(menuItem.getTreeNode(), “myTreeController”); }
);
dojo.event.topic.subscribe(“ctxDelete/engage”,
function (menuItem) { TreeActions.removeNode(menuItem.getTreeNode(),
“myTreeController”); }
);
dojo.event.topic.subscribe(“ctxEdit/engage”,
function (menuItem) { TreeActions.editNode(menuItem.getTreeNode(),
“myTreeController”); }
);
},
init: function(){
/* Initialize this object */
this.djWdgt = dojo.widget;
this.myTreeWidget = this.djWdgt.manager.
getWidgetById(“myNewTreeWidget”);
this.addTreeContextMenu();
this.addController();
this.bindEvents();
}
};

Its actions

var TreeActions = {
addNewNode: function(parent,controllerId){
this.controller = dojo.widget.manager.getWidgetById(controllerId);
if (!parent.isFolder) {
parent.setFolder();
}
var arr=new Array("Country - 1","State - 2","Sub Location1 - 3","Sub Location2 - 4","Sub Location3 - 5","Sub Location4 - 6","Sub Location5 - 7","Sub Location6 - 8","Postal Code - 9","Longitude - 10","Latitude - 11");
var typeid = parent.typeId;
var str="Enter corresponding code for the location type \n";
for(var i=typeid;itypeid){
if(dummy<12){
var titl = prompt("Enter the location name","");
if(titl==""){
alert("Enter valid name");
}
else{
var rad = this.controller;
AddressHierarchy.createLocation(titl,parseInt(dummy)-1,parent.locationId,function(data){
var arr=new Array("Start","Country","State","Sub Location1","Sub Location2","Sub Location3","Sub Location4","Sub Location5","Sub Location6","Postal Code","Longitude","Latitude");
var dumm = parseInt(data[2]);
var titl = data[0]+"( "+arr[dumm]+" )";
var res = rad.createChild(parent, 0, { title: titl,locationName:data[0], locationId : data[1],typeId : data[2], parentId : data[3] });
})

}}
else{
alert(“Invalid location type”);
}
}
else{
alert(“Invalid location type”);
}

},
removeNode: function(node,controllerId){
if(node.title!=”Start”){
if (!node) {
alert(“Nothing selected to delete”);
return false;
}
else{
var name = node.locationName;
var parid = node.parentId;
this.controller = dojo.widget.manager.getWidgetById(controllerId);
var rad = this.controller;
if(!confirm(“Are you sure you want to delete “+name)){
return false;
}
AddressHierarchy.deleteLocation(parid,name,function() {
var res = rad.removeNode(node, dojo.lang.hitch(this));
})

}
}
else{
alert(“Cannot remove”);
}
},
editNode: function(node,controllerId){
if(node.title!=”Start”){
if (!node) {
alert(“Nothing selected to edit”);
return false;
}
else{
var oldname = node.locationName;
var parid = node.parentId;
this.controller = dojo.widget.manager.getWidgetById(controllerId);
var rad = this.controller;
var newname = prompt(“Enter the location name”,oldname);

if(newname!=null){
AddressHierarchy.editLocation(parid,oldname,newname, function(){
var arr=new Array(“Start”,”Country”,”State”,”Sub Location1″,”Sub Location2″,”Sub Location3″,”Sub Location4″,”Sub Location5″,”Sub Location6″,”Postal Code”,”Longitude”,”Latitude”);
var dumm = parseInt(node.typeId);
var titl = newname+”( “+arr[dumm]+” )”;
node.edit({title:titl , locationName:newname});
})}
}
}
else{
alert(“Cannot Edit”);
}
}};

JSON input from servlet

function loadData(){
$.getJSON("${pageContext.request.contextPath}/moduleServlet/addresshierarchy/addressTree",
function(data){
TreeBuilder.buildTree(data);
});
}

HTML code before the tree loads

<div  id=”myWidgetContainer”>
<span id=”treePlaceHolder”
style=”background-color:#F00; color:#FFF;”>
Loading…
</span>
</div>

Screenshots for review

This is how it looks in the admin page now.

This is how the tree looks when there is no location components.

On right click on the tree these options are given out. Brian has asked me to do something like even the options are given out according to the user previleges.

When user selects “Add Location Component” a pop up with list of components and its code is given. Its enough to enter the code by user.

The location component is created and it displayed with the location type in the braces.

Prompt box user gets when he selects “Edit Location Component”.

Confirmation box user gets when he selects “Delete Location Component”.

Sixth week of coding

This week I had to work bit harder because i had to take off for four days from the project since I had to attend my cousin’s marriage.  At the start of the week Brian suggested a new concept for easy user interface. A javascript tree to maintain the address hierarchy even Daniel thought that would be good and pretty useful.

As they wished I designed the javascript tree with a small css bug (an extra line could be easily removed on a small research). Here are the screen shots

This is default view. You cannot delete or edit that “Start” link.

This is the tree view.

Three options you get when you right click on a link.

Popup you get when select “Add Location”.

Popup you get when you select “Edit Location”.

Confirmation dialog you get when you select “Delete Location”.

I use a Java string parsed into Json array to build this array. But I feel loading the tree the with a large number of locations will take pretty long time but once it is loaded this is the best way for an user to create a location rather than the old way plus maintaining the locations is also very easy.

I hope my mentor and backup mentor like this tree. I am doing a small research for the second part of my project. It will take 2 or 3 days and on 10th I have my project review. After that I will start coding for the second part.

P.S : I welcome any alternative suggestion for the Json array. I am not sure how to build a js tree without an array.

Fifth Week of Coding

I have almost completed my first half project to be submitted for mid term evaluation.

I have put few screenshots here and explanation for it.

This is the create hierarchy page. It has auto completion text boxes which helps admin to create locations easily. There’s also a location counter in this page showing the number of locations in the table.

This is the manage hierarchy page. When it loads it looks like this. You can start editing or deleting by selecting a country.

The hierarchy is changed as you choose a location. If a hierarchy skips a location type then that particular drop down menu will be disabled.

As you can see in screenshots the hierarchies are changed as the locations are changed.

Even manage hierarchy page has a location counter.

On choosing edit the submit button is renamed to “Edit”. And the user will be provided radio buttons and corresponding disabled textboxes. On selecting a radio button the corresponding textbox will be loaded with the selected value in the drop down menu. If the drop down menu is disabled then the textbox will not be enabled on selecting the radiobox. User can edit the location in the text box and click Edit button.

Delete also similar to Edit but this will not give out textboxes. User can click the radio button and click the Delete button.

Yesterday when Brian tried to work with my module he faced problems in manage hierarchy page. Still I could not figure out the reason. I tried the module in few other systems it worked fine there. Even in Internet Explorer 6 it worked fine. I have done this autocomplete thing today havent updated my code yet in the repository since there’s some problem in the repository.

Fourth Week of Coding

Huh… Atlast I am gonna complete my first half. Only few things left in the enhancements and backend. Hopefully I will finish the backend works tomorrow. Finally got access to svn repository gonna upload my src code tomorrow 🙂 . I am working on the form for managing the created hierarchies such as editing and deleting. Since I have merged both ideas in the same form I am working on something like fliping. I am gonna provide the user with radio buttons. If he selects edit then he will get options for edit and if he selects delete he will get options for delete. The drop down works fine here but still things are there have to be done. I used drop down here because it would be helpful for users and I could gain some idea on how to do the second half. If everything works fine then I am gonna use the same Javascript file for my second half. Ah I forgot to mention. At the beginning I misunderstood few things in the DWR documentation and thats the reason for this delay. I misunderstood the “CALL BACK FUNCTION” part in the DWR. Thats really crazy na. Thats all for now folks. I will give my update once I finish the rest of works.

The Third Week of Coding

I am extremely sorry for the delay in the updates. Me and my mentor Daniel worked together and solved many issues. This is the first time in my lifetime to correct such many errors. But finally I see a small hope that I can finish the major part of the first deliverable by tomorrow. Actually I thought I could do that by last weekend but I could not. And that was the reason for the delay in the updates. Hope I will put my codes in repository in this week for further reviews, suggestions and enhancements. Right now I am little bit held up in the hql part. I am in the verge of completing. I will update this post once I get done with this issue. Thanks for the patience.