Tuesday, October 2, 2012

Java CSV file Import and parsing using opencsv library

We often need to import data from a CSV file to populate a relational database table. Most of the examples I have seen use the StringTokenizer to import a CSV file but that has its limitations such as if you come across data that has a comma in them. That's when I found this open source project called opencsv. It's a very simple csv (comma-separated values) parser library for Java. It takes care of the basic stuff such as comma inside the data itself and more. Also you can use the library to create CSV files. In addition to all that the best part is take a CSV file and map to a Java Bean. Here is the site link for more information and to download the jar file for this project - http://opencsv.sourceforge.net/

Parse a CSV file in Java using opencsv

Parse a CSV file in Java using opencsv

Sample Java program that parses a CSV file

 
package com.as400samplecode;


import java.io.BufferedReader;

import java.io.FileNotFoundException;

import java.io.FileReader;

import java.io.IOException;

import java.util.List;

import java.util.StringTokenizer;


import au.com.bytecode.opencsv.CSVReader;

import au.com.bytecode.opencsv.bean.ColumnPositionMappingStrategy;

import au.com.bytecode.opencsv.bean.CsvToBean;


public class ParseCSVFile {


    public static void main(String[] args) {


        String filename = args[0];

        ParseCSVFile parseCSVFile = new ParseCSVFile();
       

        System.out.println("Starting to parse CSV file using StringTokenizer");

        parseCSVFile.parseUsingStringTokenizer(filename);

       
        System.out.println("Starting to parse CSV file using opencsv");

        parseCSVFile.parseUsingOpenCSV(filename);
       

        System.out.println("Starting to parse CSV file and map to Java Bean");

        parseCSVFile.parseCSVtoBean(filename);       

    } 
    private void parseUsingStringTokenizer(String filename){

        try {

            //create BufferedReader to read CSV file

            BufferedReader br = new BufferedReader( new FileReader(filename));

            String record = "";

            StringTokenizer st = null;

            int rowNumber = 0;

            int cellIndex = 0;

            //read comma separated file line by line

            while( (record = br.readLine()) != null)

            {

                rowNumber++;

                //break comma separated line using ","

                st = new StringTokenizer(record, ",");

                while(st.hasMoreTokens()) {

                    //display CSV values

                    cellIndex++;

                    System.out.println("Cell column index: " + cellIndex);

                    System.out.println("Cell Value: " + st.nextToken());

                    System.out.println("---");

                }

                //reset cell Index number

                cellIndex = 0;

            }

        }

        catch(Exception e){

            System.out.println("Exception while reading csv file: " + e);               

        }

    }


    private void parseUsingOpenCSV(String filename){


        try {

    
            CSVReader reader = new CSVReader(new FileReader(filename));

            String [] nextLine;

            int rowNumber = 0;

            while ((nextLine = reader.readNext()) != null) {

                rowNumber++;

                for(int i = 0;i< nextLine.length; i++){

                    //display CSV values

                    System.out.println("Cell column index: " + i);

                    System.out.println("Cell Value: " + nextLine[i]);

                    System.out.println("---");

                }

            }

        } catch (FileNotFoundException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }

        catch (IOException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }

    }
   

    private void parseCSVtoBean(String filename){

        try {
           

            CSVReader reader = new CSVReader(new FileReader(filename), ',', '\"', 2);


            ColumnPositionMappingStrategy<OrderDetail> mappingStrategy =

                                                new ColumnPositionMappingStrategy<OrderDetail>();

            mappingStrategy.setType(OrderDetail.class);

        
            // the fields to bind do in your JavaBean

            String[] columns = new String[] {"itemNumber", "description", "price","quantity"};

            mappingStrategy.setColumnMapping(columns);

            CsvToBean<OrderDetail> csv = new CsvToBean<OrderDetail>();

            List<OrderDetail> orderList = csv.parse(mappingStrategy, reader);

            for(int i = 0;i< orderList.size(); i++){

                OrderDetail orderDetail = orderList.get(i);

                //display CSV values

                System.out.println("Item Number: " + orderDetail.getItemNumber());

                System.out.println("Description: " + orderDetail.getDescription());

                System.out.println("Price: " + orderDetail.getPrice());

                System.out.println("Quantity: " + orderDetail.getQuantity());

                System.out.println("---");

            }
        } catch (FileNotFoundException e) {

            // TODO Auto-generated catch block

            e.printStackTrace();

        }
     
    }

}

Java Bean - OrderDetail.java

   

ackage com.as400samplecode;



public class OrderDetail {

   

    String itemNumber = null;

    String description = null;

    Double price = 0.0;

    int quantity = 0;

   

    public String getItemNumber() {

        return itemNumber;

    }

    public void setItemNumber(String itemNumber) {

        this.itemNumber = itemNumber;

    }

    public String getDescription() {

        return description;

    }

    public void setDescription(String description) {

        this.description = description;

    }

    public Double getPrice() {

        return price;

    }

    public void setPrice(Double price) {

        this.price = price;

    }

    public int getQuantity() {

        return quantity;

    }

    public void setQuantity(int quantity) {

        this.quantity = quantity;

    }

}

ExtJs Grid JSON Java Servlet example with Grid Filter using TriggerField

In the previous chapter we have looked into the sample source codes for creating the grid panel using ExtJs, here we are going to work on the Java Servlet program that will get us the data from MySQL database in the form of a JSON object.


ExtJs Grid JSON Java Servlet example with Grid Filter using TriggerField

Step 7: MySQL JDBC data source context.xml

  

<?xml version="1.0" encoding="UTF-8"?>

<Context reloadable="true">

<Resource auth="Container"

name="jdbc/mysql"

type="javax.sql.DataSource"

driverClassName="com.mysql.jdbc.Driver"

url="jdbc:mysql://localhost:3306/world"

username="root"

password="mysql"

maxIdle="10"

maxActive="200"

maxWait="5"

removeAbandoned="true"

removeAbandonedTimeout="1200"

/>

</Context>

Step 8: Web Application config file web.xml

  

<?xml version="1.0" encoding="UTF-8"?>

<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">

  <display-name>ExtJs_Grid_Filter</display-name>

  <welcome-file-list>

    <welcome-file>index.html</welcome-file>

    <welcome-file>index.htm</welcome-file>

    <welcome-file>index.jsp</welcome-file>

    <welcome-file>default.html</welcome-file>

    <welcome-file>default.htm</welcome-file>

    <welcome-file>default.jsp</welcome-file>

  </welcome-file-list>

  <servlet>

    <description>Country Servlet</description>

    <display-name>CountryServlet</display-name>

    <servlet-name>CountryServlet</servlet-name>

    <servlet-class>com.as400samplecode.CountryServlet</servlet-class>

  </servlet>

  <servlet-mapping>

    <servlet-name>CountryServlet</servlet-name>

    <url-pattern>/CountryServlet</url-pattern>

  </servlet-mapping>

  <resource-ref>

    <description>MySQL Datasource</description>

    <res-ref-name>jdbc/mysql</res-ref-name>

    <res-type>javax.sql.DataSource</res-type>

    <res-auth>Container</res-auth>

    <res-sharing-scope>Shareable</res-sharing-scope>

  </resource-ref>

</web-app>

Step 9: Source for Country Java Bean Country.java
  

package com.as400samplecode.util;



public class Country {

    String code = null;

    String name = null;

    String continent = null;

    String region = null;

    Double lifeExpectancy = null;

    Double gnp = null;

    public String getCode() {

        return code;

    }

    public void setCode(String code) {

        this.code = code;

    }

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }

    public String getContinent() {

        return continent;

    }

    public void setContinent(String continent) {

        this.continent = continent;

    }

    public String getRegion() {

        return region;

    }

    public void setRegion(String region) {

        this.region = region;

    }

    public Double getLifeExpectancy() {

        return lifeExpectancy;

    }

    public void setLifeExpectancy(Double lifeExpectancy) {

        this.lifeExpectancy = lifeExpectancy;

    }

    public Double getGnp() {

        return gnp;

    }

    public void setGnp(Double gnp) {

        this.gnp = gnp;

    }



Step 10: Source for Country Utility program to get MySQL data CountryInformation.java
  

package com.as400samplecode.util;

import java.sql.Connection;      

import java.sql.ResultSet;       

import java.sql.SQLException;    

import java.sql.PreparedStatement;

import java.util.ArrayList;

import javax.naming.Context;     

import javax.naming.InitialContext;

import javax.sql.DataSource;     

public class CountryInformation {        

    Connection conn = null;         

    PreparedStatement stmt = null;  

    String sql = null;

    public ArrayList<Country> getItems(String start, String limit) {

        ArrayList<Country> countryList = new ArrayList<Country>();

        try {   

            Context ctx = (Context) new InitialContext().lookup("java:comp/env");

            conn = ((DataSource) ctx.lookup("jdbc/mysql")).getConnection();

            sql = "Select * from COUNTRY order by name,code";                   

            stmt = conn.prepareStatement(sql);

            ResultSet rs = stmt.executeQuery();

            while(rs.next()){

                Country country = new Country();

                country.setCode(rs.getString("code").trim());

                country.setName(rs.getString("name").trim());

                country.setContinent(rs.getString("continent").trim());

                country.setRegion(rs.getString("region").trim());

                country.setLifeExpectancy(rs.getString("lifeExpectancy") == null ? new Double(0) : Double.parseDouble(rs.getString("lifeExpectancy").trim()));

                country.setGnp(rs.getString("gnp") == null ? new Double(0)  : Double.parseDouble(rs.getString("gnp").trim()));

                countryList.add(country);

            }                                                                      

            rs.close();                                                            

            stmt.close();                                                          

            stmt = null;                                                           

            conn.close();                                                          

            conn = null;                                                

        }                                                            

        catch(Exception e){System.out.println(e);}                   

        finally {                                                    

            if (stmt != null) {                                         

                try {                                                      

                    stmt.close();                                             

                } catch (SQLException sqlex) {                             

                    // ignore -- as we can't do anything about it here        

                }                                                          

                stmt = null;                                         

            }    

            if (conn != null) {                                   

                try {                                                

                    conn.close();                                       

                } catch (SQLException sqlex) {                       

                    // ignore -- as we can't do anything about it here  

                }                                                    

                conn = null;                                         

            }                                                     

        } 
        return countryList;
    }

    public int getTotalCount() {
        int totalCount = 0;

        try {   

            Context ctx = (Context) new InitialContext().lookup("java:comp/env");

            conn = ((DataSource) ctx.lookup("jdbc/mysql")).getConnection();

            sql = "Select count(*) from COUNTRY";                   

            stmt = conn.prepareStatement(sql);

            ResultSet rs = stmt.executeQuery();

            while(rs.next()){

                totalCount = rs.getInt(1);

                break;

            }                                                                      

            rs.close();                                                            

            stmt.close();                                                          

            stmt = null;                                                           

            conn.close();                                                          

            conn = null;                                                

        }                                                            

        catch(Exception e){System.out.println(e);}                   

        finally {                                                    

            if (stmt != null) {                                         

                try {                                                      

                    stmt.close();                                             

                } catch (SQLException sqlex) {                             

                    // ignore -- as we can't do anything about it here        

                }                                                          

                stmt = null;                                         

            }                                                     
            if (conn != null) {                                   

                try {                                                

                    conn.close();                                       

                } catch (SQLException sqlex) {                       

                    // ignore -- as we can't do anything about it here  

                }                                                    

                conn = null;                                         

            }                                                     

        }           
        return totalCount;

    }
}

Step 11: Source for Country Servlet program to process request and pass JSON object CountryServlet.java

package com.as400samplecode;

import java.io.IOException;

import java.io.PrintWriter;

import java.util.ArrayList;

import javax.servlet.ServletException;

import javax.servlet.http.HttpServlet;

import javax.servlet.http.HttpServletRequest;

import javax.servlet.http.HttpServletResponse;

import net.sf.json.JSONArray;

import net.sf.json.JSONObject;

import com.as400samplecode.util.Country;

import com.as400samplecode.util.CountryInformation;

public class CountryServlet extends HttpServlet {

    private static final long serialVersionUID = 1L;

    public CountryServlet() {

        super();

    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        doPost(request,response);

    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        String start = request.getParameter("start");

        String limit = request.getParameter("limit");

        PrintWriter out = response.getWriter();

        response.setContentType("text/html");

        JSONArray arrayObj=new JSONArray();

        CountryInformation countryInformation = new CountryInformation();

        ArrayList<Country> countryList = countryInformation.getItems(start,limit);

        for(int i=0;i<countryList.size();i++){

            Country country = countryList.get(i);

            JSONObject itemObj = JSONObject.fromObject(country);

            arrayObj.add(itemObj);

        }

        JSONObject myObj = new JSONObject();

        myObj.put("success", true);

        myObj.put("countries", arrayObj);

        myObj.put("totalCount", countryInformation.getTotalCount());

        out.println(myObj.toString());

        out.close();

    }

}

ExtJs 4 Grid Editing Tutorial based on CellEditing plugin using Java Servlet, JSON and MySQL database

  • The Ext.grid.plugin.CellEditing plugin injects editing at a cell level for a Grid. Only a single cell will be editable at a time. The field that will be used for the editor is defined at the editor. If an editor is not specified for a particular column then that cell will not be editable and it will be skipped when activated via the mouse or the keyboard.


  • This tutorial will cover the following topics ...
  • Connection to a Customer Table in MySQL database
  • Get list of customers as JSON array from Java Servlet
  • Edit a customer information using the Grid Cells
  • Add a new customer using the Grid after all validation passes
  • CheckColumn to make the customer record active or inactive
  • Automatically Sync data as soon as the changes are made using AJAX



  • ExtJs 4 Grid Editing Tutorial using the CellEditing plugin, Java servlet and MySQL
    ExtJs 4 Grid Editing Tutorial using the CellEditing plugin, Java servlet and MySQL
    ExtJs 4 Grid Editing Tutorial using the CellEditing plugin, Java servlet and MySQL

  •  Application starting point index.html  

    <html>

    <head>

        <title>ExtJs 4 Grid Editing Example </title>

        <link rel="stylesheet" type="text/css" href="extjs/resources/css/ext-all.css">

        <link rel="stylesheet" type="text/css" href="extjs/ux/css/CheckHeader.css">

        <script type="text/javascript" src="extjs/ext-all-debug.js"></script>

        <script type="text/javascript" src="app.js"></script>

    </head>

    <body></body>

    </html>

    Application JavaScript file app.js

      

    Ext.Loader.setPath('Ext.ux', 'extjs/ux');


    Ext.Loader.setConfig({

        enabled: true

        });



    Ext.require([

                 'Ext.data.*',

                 'Ext.grid.*',

                 'Ext.ux.CheckColumn'

             ]);

    Ext.application({

        name: 'GRIDEDITING',

        appFolder: 'app',

        controllers: [

                      'Customers'

                  ],

        launch: function() {

            Ext.create('Ext.container.Viewport', {

                items: [

                    {

                        xtype: 'customerList',

                    }

                ]

            });

        }

    });

    JavaScript source file for the Model Customer.js

      

    Ext.define('GRIDEDITING.model.Customer', {

        extend: 'Ext.data.Model',

        fields: [

                 'customerId',

                 'firstName',

                 'lastName',

                 'email',

                 {name: 'active', type: 'bool'}

                ],

        validations:

                [

                      {type: 'presence',  field: 'firstName'},

                      {type: 'presence',  field: 'lastName'},

                      {type: 'presence',  field: 'email'}

                 ]

    });

    JavaScript source file for the Store Customers.js

      

    Ext.define('GRIDEDITING.store.Customers', {

        extend: 'Ext.data.Store',

        model: 'GRIDEDITING.model.Customer',

        autoLoad: true,

        pageSize: 20,

        proxy: {

            type: 'ajax',

            url: 'CustomerServlet',

            extraParams: {

                store_id: 1

            },

            reader: {

                type: 'json',

                totalProperty: 'totalCount',

                root: 'customers',

                successProperty: 'success'

            },

         },

         listeners: {

             load : function(store) {

                 //if need something to do after the store loads

             }

         }

    });

    JavaScript source file for Editable Grid view CustomerList.js

    Ext.define('GRIDEDITING.view.CustomerList' ,{

        extend: 'Ext.grid.Panel',

        alias : 'widget.customerList',

        title : 'List of Customers',

        store : 'Customers',

        loadMask: true,

        autoheight: true,

        dockedItems: [{

            xtype: 'pagingtoolbar',

            store: 'Customers',

            dock: 'bottom',

            displayInfo: true,

            items: [

                    {

                        xtype: 'tbseparator'

                    },

                    {

                        xtype : 'button',

                        text: 'Add Customer',

                        action: 'add'

                    }

            ]

        }],

        plugins: [

                  Ext.create('Ext.grid.plugin.CellEditing', {

                      clicksToEdit: 1

                 })     

        ],

        selModel: {

            selType: 'cellmodel'

        },

        initComponent: function() {

          

            this.columns = [{

                header: 'Customer Id',

                dataIndex: 'customerId',

                flex: 1,

            }, {

                header: 'Active',

                dataIndex: 'active',

                flex: 1,

                xtype: 'checkcolumn',

            }, {

                header: 'First Name',

                dataIndex: 'firstName',

                flex: 1,

                editor: {

                    allowBlank: false

                }

            }, {

                header: 'Last Name',

                dataIndex: 'lastName',

                flex: 1,

                editor: {

                    allowBlank: false

                }

            }, {

                header: 'Email Address',

                dataIndex: 'email',

                flex: 1,

                editor: {

                    allowBlank: false,

                    vtype: 'email'

                }

            }];

            this.callParent(arguments);

        }

    });

    JavaScript source file for the application controller Customers.js
      

    Ext.define('GRIDEDITING.controller.Customers', {

                extend : 'Ext.app.Controller',
                //define the stores

                stores : ['Customers'],

                //define the models

                models : ['Customer'],

                //define the views

                views : ['CustomerList'],

                init : function() {

                    this.control({

                      

                        'viewport' : {

                            render : this.onPanelRendered

                        },

                        'customerList': {

                            edit: this.editCustomer

                        },

                        'checkcolumn': {

                            checkchange: this.checkboxChanged

                        },

                        'customerList button[action=add]' : {

                            click : this.addCustomer

                        }

                    });

                },

                onPanelRendered : function() {

                    //just a console log to show when the panel is rendered

                    console.log('The panel was rendered');

                },

                editCustomer : function(editor, obj) {

                    //check if record is dirty

                    if(obj.record.dirty){

                        //check if the record is valid

                        console.log(obj.record.validate());

                        if(obj.record.validate().isValid()){

                            //Make your Ajax request to sync data

                            mode = (obj.record.get('customerId') === "") ? 'insert': 'update';

                            this.syncData(obj.rowIdx, mode);

                        }

                    }

                },

                checkboxChanged : function(column,rowIndex,checked) {

                    console.log('Checkbox changed');

                    //grid column information

                    console.log(column);

                    //grid row number

                    console.log(rowIndex);

                    //the checkbox value

                    console.log(checked);

                    console.log(this.getCustomersStore().getAt(rowIndex));

                    //Make your Ajax request to sync data

                    this.syncData(rowIndex,'update');

                },

                //Sync data with the server

                syncData : function(rowIndex, mode) {

                    Ext.Ajax.request({

                           url: 'CustomerServlet',

                        params: {

                                store_id: 1,

                                action: mode,

                                rowIndex: rowIndex,

                                recordInfo: Ext.encode(this.getCustomersStore().getAt(rowIndex).data)

                        },

                        scope:this,

                        //method to call when the request is successful

                        success: this.onSaveSuccess,

                        //method to call when the request is a failure

                        failure: this.onSaveFailure

                    });

                },

                onSaveFailure: function(err){

                    //Alert the user about communication error

                    Ext.MessageBox.alert('Status', 'Error occured during update');

                },

                onSaveSuccess: function(response,opts){

                    //Remove dirty

                    var ajaxResponse = Ext.decode(response.responseText);

                    if(ajaxResponse.success){

                        //if we are doing an insert then get the new customerId

                        //and update the store record

                        if(opts.params.action === 'insert'){

                            customerId = ajaxResponse.customerId;

                            this.getCustomersStore().getAt(opts.params.rowIndex).set('customerId',customerId);

                        }

                        this.getCustomersStore().getAt(opts.params.rowIndex).commit();

                    }

                    else {

                        Ext.MessageBox.alert('Status', 'Error occured during update');

                    }

                },

                addCustomer : function(button) {

                    var customer = new GRIDEDITING.model.Customer({

                                            'customerId': '',

                                            'firstName': '',

                                             'lastName': '',

                                             'email':'',

                                             'active':true

                                        });

                                      

                    var panel = button.up('panel');

                    editor = panel.editingPlugin;

                    editor.cancelEdit();

                    this.getCustomersStore().insert(0, customer);

                    editor.startEditByPosition({row: 0, column: 2});

                }             

        });


ExtJs Rich Text Editor Example

An online rich-text editor is an interface for editing valid HTML markup making it easy for users trying to express their formatting directly as they see it. In this example we are going to display a Product and some Information about it. When the user clicks on the Edit Button it will open the Rich Text Editor for editing the information and then clicking on the save button will close the HTML editor and display the information that was just entered. This is very useful for inline editing of site content by administrators.


ExtJs Rich Text Editor ExampleExtJs Rich Text Editor Example ExtJs Rich Text Editor Example

Application HTML file - index.html


<html>
<head>
<title>ExtJs Rich Text Editor example</title>
 
<link rel="stylesheet" type="text/css"
 href="extjs/resources/css/ext-all.css">
<style type="text/css">
</style>
<script type="text/javascript" src="extjs/ext-all-debug.js"></script>
<script type="text/javascript">
Ext.Loader.setConfig({
 enabled: true
 });
 
Ext.application({
     
 name: 'myApp',
 appFolder: 'app/richTextEditor',
     
    controllers: [
                  'MyController'
              ],
 
    launch: function() {
 Ext.create('Ext.panel.Panel', {
         renderTo: 'myExample',
         title: 'Rich Text Editing Form',
         height: 300,
            width: 550,
            margin: '5 5 5 5 ',
         layout: {
                align: 'stretch',
                type: 'vbox'
            },
         defaults: {
            labelWidth: 100,
            margin: '0 0 0 5 '
         },
         items: [{
                        xtype: 'fieldcontainer',
                        width: 400,
                        layout: {
                            type: 'column'
                        },
                        fieldLabel: '<b>Item Number</b>',
                        defaults: {
             hideLabel: true
            },
                        items: [
                            {
                                xtype: 'displayfield',
                                value: 'ABC123',
                                width: 60
                            },
                            {
                                xtype: 'button',
                                text: 'Edit'
                            }
                        ]
                    },
                    {
                        xtype: 'displayfield',
                        value: '<b>Product Description</b>'
                    },
                    {
                     flex: 1,
                        xtype: 'displayfield',
                        itemId: 'productDescription',
                        value: 'Initial Product Description...'
                         
                    },
                    {
                     flex: 1,
                     //enable other features
                        xtype: 'htmleditor',
                        itemId: 'myEditor',
                        height: 200,
                        style: 'background-color: white;',
                        value: '',
                        hidden: true
                    }
                ]
        });
    }
});
    </script>
 
</head>
<body>
 <div id="myExample"></div>
</body>
</html>

Application Controller - MyController.js


Ext.define('myApp.controller.MyController', {
  extend : 'Ext.app.Controller',
 
  init : function() {
   this.control({
 
    'panel' : {
     render : this.onPanelRendered
    },
    'panel button' : {
     click : this.onButtonClick
    }
   });
  },
 
  onPanelRendered : function() {
   //console.log('The container was rendered');
  },
 
  onButtonClick : function(button) {
   //console.log('Button Click');
   var myView = button.up('panel');
   var productDescription = myView.getComponent('productDescription');
   var myEditor = myView.getComponent('myEditor');
   if(button.getText() === "Edit"){
     button.setText("Save");
     myEditor.setValue(productDescription.getValue());
     productDescription.hide();
     myEditor.show();
   }
   else {
     button.setText("Edit");
     productDescription.setValue(myEditor.getValue());
     myEditor.hide();
     productDescription.show();
   }
 
  }
 
 });


All the features in the HTML editor are enabled by default. If you need to switch them off then you must specify some of the configs mentioned below
  • enableAlignments
    • for left, center, right alignment buttons
  • enableColors
    • for tfore/highlight color buttons
  • enableFont
    • for font selection
  • enableFontSize
    • for the increase/decrease font size buttons
  • enableFormat
    • for bold, italic and underline buttons
  • enableLinks
    • for create link button
  • enableLists
    • for bullet and numbered list buttons
  • enableSourceEdit
    • for switching to source edit button
Some of the features are not avaibale in Safari, please check Sencha Docs if you need more information.