Wednesday, 2 July 2014

ExtJS4 : Copying data from one grid to another.

Copying content into clipboard is a security hole. As a result no simple javascript method is available to write content into clipboard. Except IE, no other browser supports this without any plugins/flash. But if you just want to copy one row of grid and paste it into another grid you can use following hack.(Two grid stores should use same model). 

  • Select a row and provice ExtJS context menu, in action get selected record. It will be in the form of model. Convert this model object into JSON object using getData(true) method on the model. It converts model object into json including association data. 
  • Now your task is to persist this data in user's environment. For this you can use HTML5 web storage. It is simple, faster and secure. But it doesn't work on IE7 and earlier versions.
                   localStorage.setItem("json-object", model.getData(true));
  • Above code stores model object into client's browser in the form of string. 
  • When you wan to handle paste, fetch the stored data string and decode into JSON object. 
                  var jsonObject =  Ext.Deode(localStorage.getItem("json-object"));
  • After retrieving jsonObject convert this back in to model and push it into grid's store. 
            Check this to convert jsonObject into model.


Extjs4 : Converting JSON Object into model

ExtJS provides getData(true) method on model to convert model object into JSON Object including associations. But other way is not a straight forward thing in ExtJS4. If you have JSON and want to convert into model, one dirty way could be create a store with memory proxy, input JSON object as data object and access first record in the store. But this method is not always fruitful. If your JSON has associated data, this method will not work properly. Especially in case of hasOne association case, it never creates *HasOneInstance objects using this method.

I found similar API in Sencha touch 2.2.1 and modified a bit to make it work in ExtJS 4.2.1

Thursday, 12 June 2014

MxGraph Indicator Diagram

Recently I have used mxGraph to draw an indicator diagram to indicate active panel in a wizard. Event though mxGraph has a documentation, I found it difficult while working with this framework.

By default mxCell allows one lable per cell. If you need more than that we can insert labels using insertCell or insertVertex. In this example I needed two lables(One for state and other is for name of the state), so I have used vertex and inserted one more vertex to the parent vertex. 




Source can also be found @ https://github.com/Balagangadhar/ExtJS4-Misc/blob/master/Indicator.js

Tuesday, 18 March 2014

Extjs 4 : Converting treestore into store using associations.

Extjs doesn't support updating tree by keeping nodes in its own hierarchy. treestore.sync90 function only sends updated nodes to the server as individual models. But sometimes we may need to send tree structure in the form of tree to the server(Ofcourse only updated nodes).

For example consider following tree,
Parent1
  • Child1
  • Child2
  • Child3
Parent2
  • Chld4
  • Child5
 If  child2 and child5 are dirty records and if we fire treestore.sync(), it only sends child2 and child5 models as data. We loose the context of parent. We may not know for which parent this child belongs to. In such a case you can use following model and code snippet to convert your tree into model with associated models.

Each node will have subtree models as associated model and using following function, you can convert modified tree nodes into associated-model store. This store is a plain store with associated models. Now you can send this model to the server
(For more info on sending updated model associations to the server viz following blog post
http://balu-learnings.blogspot.in/2014/03/extjs-4-sending-updated-models-to.html ).

model :

Ext.define('App.model.treegridsample', {
    extend : 'Ext.data.Model',
    fields : [ {
        name : 'id',
        useNull : true,
        defaultValue : ''
    }{
        name : 'text'
    }{
        name : 'leaf',
        persist : false
    }],

    associations : [ {
        type : 'hasMany',
        model : 'App.model.treegridsample',
        name : 'children'
    }
});


CustomTree.js
  
Ext.define('App.view.common.CustomTree', {
 extend : 'Ext.tree.Panel',
 convertToStore : function(model) {
  if (this.getStore() === null) {
   return null;
  }
  var rootNode = this.getStore().getRootNode();
  model = model || Ext.getClassName(this.getStore().getRootNode());
  dataStore = this.convertNodeToStore(rootNode, model);
  return dataStore.childrenStore;
 },
convertNodeToStore : function(rootNode, model) {
 var record = Ext.create(model);
 record.data = rootNode.data;
 if (record.childrenStore === null || typeof record.childrenStore === 'undefined') {
  record.childrenStore = Ext.create('Ext.data.Store', {
   model : model
  });
 }
 for (var i = 0; i < rootNode.childNodes.length; i++) {
  var cNode = rootNode.childNodes[i];
  var child = this.convertNodeToStore(cNode, model);
  if (cNode.dirty || cNode.phantom) {
   record.childrenStore.add(child);
   rootNode.setDirty();
  }
 }
 return record;
}


Source can be found@ https://github.com/Balagangadhar/ExtJS4-Misc/blob/master/CustomTree.js

Extjs 4 : Sending updated models to server along with associations (has many)

Model- Association is one of the beautiful features of extjs4. Sencha documentation has plenty of examples on 'how to read association' but it doesn't have official documentation on 'how to update model along with its association' which is also a required feature most of the times.


Copy following code snippet in a javascript file and include it in your JSP/html page after extjs framework file inclusion.

<script type="text/javascript" src="extjs4/ext-all-dev.js"></script>
<script type="text/javascript" src="ext-model-assoc-override.js"></script>


Source : sencha forum topic.
Detailed example : http://stackoverflow.com/questions/9871440/extjs-store-hasmany-belongsto-and-update-process-howto


Note: Following code only works for has many associations. We need to extend this for has one, in case if we want it for has one associations.

An internal error occurred during: “Requesting JavaScript AST from selection”

Sometime eclipse suddenly stops working by throwing following error
'Requesting Javascript AST from Selection' has encountered a problem. An internal error occured during "Requesting Javascript AST from selection"
and throws following error in the console, if you run eclipse through console.

java.lang.OutOfMemoryError: PermGen space 

Eclipse is not suitable for javascript validations. Sometimes it messes up with javascript and throws this error. You can disable javascript validation to get rid-off this error.

  • Go to window-preferences, search for mark
  • Select Javascript - editor - Mark Occurrences
  • Uncheck Mark selected occurrences as shown below
 

Friday, 7 March 2014

Spring xml validation failures in eclipse

While working with spring framework in eclipse, sometimes suddenly xmls fail to validate by throwing following marker error in eclipse.

Multiple markers at this line
    - cvc-complex-type.2.4.c: The matching wildcard is strict, but no declaration can be found for element
     'context:component-scan'.
    - schema_reference.4: Failed to read schema document 'http://www.springframework.org/schema/context/spring-
     context.xsd', because 1) could not find the document; 2) the document could not be read; 3) the root element of the
     document is not <xsd:schema>.

   
It could be a problem that spring jars are not accessible in the class path or different version of spring xsd files are cached in eclipse.

More frequently if you go offline, then eclipse starts showing this error(Eventhough if you connect to internet again). You can get rid off this error by clearing cached xsd templates and re-validating them.

Go to eclipse preferences, search for 'cache'(Generally it is under Network Connections), select all xsd files and remove them. After removing xsd files revalidate xmls files.

Sunday, 27 October 2013

ExtJS-JSplumb Integration - Flowchart Demo

ExtJS 4 is a very popular javascript framework to design Rich Internet Applications. It has its own drawing mechanism to draw charts but it doesn't support flowchart mechanism out-of the box. There are some plugins available to draw flowcharts to some extent.
JSPlumb is one of the famous drawing framework to draw shapes/components and connect them. It is build on top of jquery, so we can make use of all the advantages of jquery as well.

While I was trying to draw flowcharts in ExtJS, I found JSplumb is one of the suitable frameworks for my requirements, but I couldn't get a complete post/material to integrate these two. Finally I had to buy some time to integrate them and here comes the post.

There are wide-variety of javascript libraries available on net(Raphael, Processing.js...) but none of them support diamond(Decision) box as as component. Since JSplumb is built on jquery, we can play with html+CSS and get components as per our wish. 

In the following fiddle, go to the Result tab, right click on the pane and play-around with it. I have added some jquery events to prove some of the jquery actions.



Here is the sample fiddle  and following is the sample snap-shot of it.

Here is the source code : Extjs-Jsplumb-html

Saturday, 30 March 2013

Configure Mail Server In Liferay : Simplest Way

Intended users for this post are developers. As we have to work on restricted environment, where we cannot configure complete mail server and test mails,we need a simplest way to test mailing applications.

Recently I need to test forgot functionality in liferay 6.1.1 for which we need a mail server. Google's smtp free server (smtp.gmail.com: 465) is not allowed in our environment. So I have configured my own smtp server on local machine and tested the functionality. It is really simplest way to test your application.

Step 1: First configure your own mail server on your machine.
Step 2: Login to liferay as admin user, go to control panel\Server Administration\Mail and enter following details(There are default details, any way).
  • Incoming POP Server: localhost
  • Incoming Port: 110
  • User Name: root
  • Password: root
  • Outgoing SMTP Server: localhost
  • Outgoing Port: 25
  • User Name: root
  • Password: root 
and save them. 
Step 3: Click on forgot password, enter captcha, password hint and send-email-link. 
Step 4: Verify your mail here where you can see password update link.
JAMES_HOME\apps\james\var\mail\outgoing\XXXXXXXXXXXXXXXXXX.Repository.FileStreamStore 


Note: If you are using liferay 6.1.1 GA2 and default configuration of apache-james-2-3-2 then link pattern will be some thing like this,
http://localhost:8080/c/portal/update_password?p_l_id=10591&amp;ticketKey=b594ea37-718a-44d0-b46d-f6f9cefe3c09
Remove amp;from the above link, other wise forgot password link will redirect user to home page. It will not ask user for new password.

How To Setup Own Mail Server For Your Application

There are plenty of mail servers available in the market for free, hmailserver, apache-james.. are some of them. In the following post, I am going to write about configuring mail server(apache-james 2.3.2) on your own machine. This might be useful for developers to test their application in the restricted environment.
(For simplicity, I am ignoring configuration settings, and going to write about main steps, for more info you can read in apache-james site).
  1. Download apache-james 2.3.2 and unpack on your machine(Here after james-2.3.2 folder will be referred as JAMES_HOME.
  2. Go to JAMES_HOME\bin and click on run.bat, if the mail server runs successfully, following screen can be seen
    .
  3.  You are almost there. To test whether you have configured your mail server properly, open command prompt and try this command. telnet localhost 25, then you can see a scree like this.
  4. Now use out going smtp server as localhost or 127.0.0.1 and port as 25. (You can modify these details in conf.xml and host file). 
  5. Send a mail from your application and check your out box/inbox here.
    JAMES_HOME\apps\james\var\mail\inboxes
    JAMES_HOME\apps\james\var\mail\outgoing
Done.