Latest Ext JS 7.8 is now available. Learn more

Create A Currency Converter Application Quickly With Sencha Ext JS And Exchange Rates API

April 21, 2021 126 Views

With the world turning into a global village for free trade, it has become vital for individuals to have avenues for converting currencies. Currencies like the United States Dollar, the Euro, and the British Pound are widely used around the world for international transactions. So, individuals and businesses keep a close eye on the exchange rates.

As a developer, you can help people access exchange rates by creating a currency converter application with Sencha Ext JS (arguably the best javascript framework in our opinion) and Exchange Rates API. In this post, you will find all the details.

What is Exchange Rates API?

Exchange Rates API is a JSON-based REST API that provides current and historical exchange rates. It supports 170 global currencies and over 14,000 exchange rate conversion pairs. It is one of the fastest and most scalable exchange rate APIs that you can find online.

Why should you use Exchange Rates API?

  • Delivers unmatched performance
  • Offers quick data refresh rate (60 seconds)
  • User-friendly interface
  • Easy to integrate with web applications
  • Offers dedicated support team for helping you implementing the API

How to Create a Currency Converter Application Quickly with Sencha Ext JS and Exchange Rates API

Sencha Ext JS is a powerful framework for building cross-platform web applications. By integrating Exchanges Rates API, you can develop a currency converter application easily. Take a look at the app:

Currency Converter

To build the currency converter web application shown above, you have to follow these steps:

1. First, you have to create the model for exchange rates. Go to the App folder. Then head to the model directory, create the new RateModel.js file and add these codes:

Ext.define('HeaderLeftRight.model.RateModel', {

                extend: 'Ext.data.Model',

           

 

                requires: [

                    'Ext.data.field.String',

                    'Ext.data.field.Number'

                ],

           

 

                fields: [

                    {

                        type: 'string',

                        name: 'symbol'

                    },

                    {

                        type: 'float',

                        name: 'rate'

                    }

                ]

            });

Here, you are adding two fields, called ‘symbol’ and ‘rate.’ Also, you are defining their types.

2. You have to create models for the currency symbols. Create a new file, called SymbolModel.js, inside the model folder. Then add these codes:

Ext.define('HeaderLeftRight.model.SymbolModel', {

                extend: 'Ext.data.Model',

           

 

                requires: [

                    'Ext.data.field.String'

                ],

           

 

                fields: [

                    {

                        type: 'string',

                        name: 'symbol'

                    },

                    {

                        type: 'string',

                        name: 'value'

                    }

                ]

            });

Here, you are defining two fields: symbol and value.

3. Next, you have to add the Views. Go to the view folder, create the MyPanelViewModel.js file and add these codes:

Ext.define('HeaderLeftRight.view.MyPanelViewModel', {

                extend: 'Ext.app.ViewModel',

                alias: 'viewmodel.mypanel'

           

 

            });

4. Create the MyPanelViewController.js file and insert these codes:

Ext.define('HeaderLeftRight.view.MyPanelViewController', {

                extend: 'Ext.app.ViewController',

                alias: 'controller.mypanel',

           

 

                setRatesComapareValue: function(baseSymbol, rate, exchangeSymbol) {

                    this.resultLbl.setText(`1 ${baseSymbol} = ${rate} ${exchangeSymbol}`);

                },

           

 

                toggleSymbolGrid: function() {

                    if(this.isSymbolGridShowed) {

                         this.symbolGrid.hide();

                         this.isSymbolGridShowed = false;

                    } else {

                         this.symbolGrid.show();

                         this.isSymbolGridShowed = true;

                    }

                },

           

 

                loadRates: function() {

           

 

                    var store = this.rateGrid.getStore();

           

 

                    store.proxy.extraParams.base = this.currentSymbol;

           

 

                    store.load({

                         scope:this,

                         callback: function(records, operation, success) {

                                     store.setData(records);

                         }

                    });

           

 

                },

           

 

                setCurrentSymbolText: function(text) {

                    this.currentSymbolText.setValue(text);

                },

           

 

                onMenuBtnClick: function(button, e, eOpts) {

                    this.toggleSymbolGrid();

                },

           

 

                onRefreshBtnClick: function(button, e, eOpts) {

                    this.loadRates();

                },

           

 

                onSymbolGridRowClick: function(tableview, record, element, rowIndex, e, eOpts) {

                    var base = record.data.symbol;

                    this.currentSymbol = base;

                    this.loadRates();

                    this.setCurrentSymbolText(base);

                    this.setRatesComapareValue(base, "?", "");

                },

           

 

                onRateGridAfterRender: function(component, eOpts) {

                    this.rateGrid = Ext.ComponentQuery.query('#rateGrid')[0];

                    this.symbolGrid = Ext.ComponentQuery.query('#symbolGrid')[0];

                    this.currentSymbolText = Ext.ComponentQuery.query('#currentSymbolText')[0];

                    this.resultLbl = Ext.ComponentQuery.query('#resultLbl')[0];

                    this.isSymbolGridShowed = true;

                    this.currentSymbol = "USD";

           

 

                    var symbolStore = this.symbolGrid.getStore();

           

 

                    symbolStore.load({

                        scope:this,

                        callback: function(records, operation, success) {

                            symbolStore.setData(records);

                        }

                    });

                    this.loadRates();

                    this.setCurrentSymbolText(this.currentSymbol);

                },

           

 

                onRateGridRowClick: function(tableview, record, element, rowIndex, e, eOpts) {

                    this.setRatesComapareValue(this.currentSymbol, record.data.rate, record.data.symbol);

                }

           

 

            });

Here, you are adding codes for various functionalities, like toggling symbols grids and loading currency rates. Also, you are defining the sections of the web page where all the necessary information, like currency rate and symbols, will be rendered.

4. Create the MyPanel.js file. Then add these codes:

Ext.define('HeaderLeftRight.view.MyPanel', {

                extend: 'Ext.panel.Panel',

                alias: 'widget.mypanel',

           

 

                requires: [

                    'HeaderLeftRight.view.MyPanelViewModel',

                    'HeaderLeftRight.view.MyPanelViewController',

                    'Ext.toolbar.Toolbar',

                    'Ext.button.Button',

                    'Ext.form.field.Text',

                    'Ext.grid.Panel',

                    'Ext.view.Table',

                    'Ext.grid.filters.filter.List',

                    'Ext.grid.column.Number',

                    'Ext.grid.filters.Filters',

                    'Ext.toolbar.Fill',

                    'Ext.form.Label'

                ],

           

 

                controller: 'mypanel',

                viewModel: {

                    type: 'mypanel'

                },

                border: false,

                height: 600,

                style: {

                    margin: 'auto'

                },

                width: '800px',

                bodyBorder: false,

                title: '',

           

 

                dockedItems: [

                    {

                        xtype: 'toolbar',

                        dock: 'top',

                        height: 66,

                        style: {

                            'background-color': '#e4e4e4'

                        },

                        items: [

                            {

                                xtype: 'button',

                                height: 40,

                                id: 'menuBtn',

                                minWidth: 40,

                                iconCls: 'fas fa-bars',

                                text: '',

                                listeners: {

                                    click: 'onMenuBtnClick'

                                }

                            },

                            {

                                xtype: 'textfield',

                                height: 54,

                                id: 'currentSymbolText',

                                style: {

                                    'font-size': '18px !important'

                                },

                                width: 685,

                                fieldLabel: '',

                                value: 'text',

                                readOnly: true,

                                editable: false

                            },

                            {

                                xtype: 'button',

                                height: 40,

                                id: 'refreshBtn',

                                minWidth: 40,

                                iconCls: 'fas fa-redo-alt',

                                text: '',

                                listeners: {

                                    click: 'onRefreshBtnClick'

                                }

                            }

                        ]

                    }

                ],

                items: [

                    {

                        xtype: 'panel',

                        defaultAlign: 'w-w',

                        flex: 2,

                        title: '',

                        dockedItems: [

                            {

                                xtype: 'gridpanel',

                                dock: 'left',

                                id: 'symbolGrid',

                                resizable: false,

                                scrollable: 'vertical',

                                width: 234,

                                title: '',

                                store: 'SymbolsStore',

                                columns: [

                                    {

                                        xtype: 'gridcolumn',

                                        width: '100%',

                                        dataIndex: 'value',

                                        text: ''

                                    }

                                ],

                                listeners: {

                                    rowclick: 'onSymbolGridRowClick'

                                }

                            }

                        ],

                        items: [

                            {

                                xtype: 'gridpanel',

                                height: 450,

                                id: 'rateGrid',

                                resizable: false,

                                resizeHandles: 'e',

                                scrollable: 'vertical',

                                title: '',

                                enableColumnResize: false,

                                store: 'RatesStore',

                                columns: [

                                    {

                                        xtype: 'gridcolumn',

                                        width: '50%',

                                        dataIndex: 'symbol',

                                        text: 'Symbol',

                                        filter: {

                                            type: 'list'

                                        }

                                    },

                                    {

                                        xtype: 'numbercolumn',

                                        width: '50%',

                                        align: 'end',

                                        dataIndex: 'rate',

                                        text: 'Currecy Value'

                                    }

                                ],

                                listeners: {

                                    afterrender: 'onRateGridAfterRender',

                                    rowclick: 'onRateGridRowClick'

                                },

                                plugins: [

                                    {

                                        ptype: 'gridfilters'

                                    }

                                ]

                            }

                        ]

                    },

                    {

                        xtype: 'container',

                        height: 86,

                        items: [

                            {

                                xtype: 'toolbar',

                                border: '1px solid #000000',

                                height: 86,

                                items: [

                                    {

                                        xtype: 'tbfill'

                                    },

                                    {

                                        xtype: 'label',

                                        id: 'resultLbl',

                                        style: {

                                            'font-size': '40px',

                                            'font-weight': 'bold'

                                        },

                                        text: '1 USD = ?'

                                    },

                                    {

                                        xtype: 'tbfill'

                                    }

                                ]

                            }

                        ]

                    }

                ]

           

 

            });

Here, you are customizing various elements of the currency converter app, including toolbar, buttons, and text fields.

6. Now, you have to create the view model for the main view of the application. Create a new folder, called main, inside the view folder. Go to the main folder. Now, create the MainModel.js file and insert these codes:

Ext.define('HeaderLeftRight.view.main.MainModel', {

                extend: 'Ext.app.ViewModel',

           

 

                alias: 'viewmodel.main',

           

 

                data: {

                    name: 'HeaderLeftRight',

           

 

                    loremIpsum: 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'

                }

           

 

                //TODO - add data, formulas and/or methods to support your view

            });

7. Next, you have to add the controller for the main view for the currency converter app. Create MainController.js file and add these codes:

Ext.define('HeaderLeftRight.view.main.MainController', {

                extend: 'Ext.app.ViewController',

           

 

                alias: 'controller.main',

           

 

                onItemSelected: function (sender, record) {

                    Ext.Msg.confirm('Confirm', 'Are you sure?', 'onConfirm', this);

                },

           

 

                onConfirm: function (choice) {

                    if (choice === 'yes') {

                        //

                    }

                }

            });

8. Next, you have to create the main view for the application. Create the Main.js file. Then insert these codes:

Ext.define('HeaderLeftRight.view.main.Main', {

                extend: 'Ext.tab.Panel',

                xtype: 'app-main',

           

 

                requires: [

                    'Ext.plugin.Viewport',

                    'Ext.window.MessageBox',

           

 

                    'HeaderLeftRight.view.main.MainController',

                    'HeaderLeftRight.view.main.MainModel',

                    'HeaderLeftRight.view.main.List'

                ],

           

 

                controller: 'main',

                viewModel: 'main',

           

 

                ui: 'navigation',

           

 

                tabBarHeaderPosition: 1,

                titleRotation: 0,

                tabRotation: 0,

           

 

                header: {

                    layout: {

                        align: 'stretchmax'

                    },

                    title: {

                        bind: {

                            text: '{name}'

                        },

                        flex: 0

                    },

                    iconCls: 'fa-th-list'

                },

           

 

                tabBar: {

                    flex: 1,

                    layout: {

                        align: 'stretch',

                        overflowHandler: 'none'

                    }

                },

           

 

                responsiveConfig: {

                    tall: {

                        headerPosition: 'top'

                    },

                    wide: {

                        headerPosition: 'left'

                    }

                },

           

 

                defaults: {

                    bodyPadding: 20,

                    tabConfig: {

                        plugins: 'responsive',

                        responsiveConfig: {

                            wide: {

                                iconAlign: 'left',

                                textAlign: 'left'

                            },

                            tall: {

                                iconAlign: 'top',

                                textAlign: 'center',

                                width: 120

                            }

                        }

                    }

                },

           

 

                items: [{

                    title: 'Home',

                    iconCls: 'fa-home',

                    // The following grid shares a store with the classic version's grid as well!

                    items: [{

                        xtype: 'mainlist'

                    }]

                }, {

                    title: 'Users',

                    iconCls: 'fa-user',

                    bind: {

                        html: '{loremIpsum}'

                    }

                }, {

                    title: 'Groups',

                    iconCls: 'fa-users',

                    bind: {

                        html: '{loremIpsum}'

                    }

                }, {

                    title: 'Settings',

                    iconCls: 'fa-cog',

                    bind: {

                        html: '{loremIpsum}'

                    }

                }]

            });

Here, you are customizing different elements, including the header and tab bar. Also, you are adding the font awesome icons.

8. You have to create the view for the list of people. Create the List.js file and add these codes:

Ext.define('HeaderLeftRight.view.main.List', {

                extend: 'Ext.grid.Panel',

                xtype: 'mainlist',

           

 

                requires: [

                    'HeaderLeftRight.store.Personnel'

                ],

           

 

                title: 'Personnel',

           

 

                store: {

                    type: 'personnel'

                },

           

 

                columns: [

                    { text: 'Name',  dataIndex: 'name' },

                    { text: 'Email', dataIndex: 'email', flex: 1 },

                    { text: 'Phone', dataIndex: 'phone', flex: 1 }

                ],

           

 

                listeners: {

                    select: 'onItemSelected'

                }

            });

9. Now, you will need the Exchange Rates API access key. You can get it for free by simply signing up on this website.

10. Create a new folder, called store, inside the app folder. Create the Personnel.js file and insert these codes:

Ext.define('HeaderLeftRight.store.Personnel', {

                extend: 'Ext.data.Store',

           

 

                alias: 'store.personnel',

           

 

                fields: [

                    'name', 'email', 'phone'

                ],

           

 

                data: { items: [

                    { name: 'Jean Luc', email: "[email protected]", phone: "555-111-1111" },

                    { name: 'Worf',     email: "[email protected]",  phone: "555-222-2222" },

                    { name: 'Deanna',   email: "[email protected]",    phone: "555-333-3333" },

                    { name: 'Data',     email: "[email protected]",        phone: "555-444-4444" }

                ]},

           

 

                proxy: {

                    type: 'memory',

                    reader: {

                        type: 'json',

                        rootProperty: 'items'

                    }

                }

            });

Here, you are adding different data, including the name, email, and phone number of the personnel.

11. Create the RatesStore.js file. Insert these codes:

Ext.define('HeaderLeftRight.store.RatesStore', {

    extend: 'Ext.data.Store',

 

    requires: [

        'HeaderLeftRight.model.RateModel',

        'Ext.data.proxy.JsonP',

        'Ext.data.reader.Json'

    ],

 

    constructor: function(cfg) {

        var me = this;

        cfg = cfg || {};

        me.callParent([Ext.apply({

            storeId: 'RatesStore',

            model: 'HeaderLeftRight.model.RateModel',

            proxy: {

                type: 'jsonp',

                extraParams: {

                    access_key: 'fb6e8c73be27e96f7392a4db33fa5fc5',

                    base: 'USD'

                },

                url: 'https://api.exchangeratesapi.io/v1/latest',

                reader: {

                    type: 'json',

                    transform: function(data) {

                        var rates = data.rates;

                        data = Object.keys(rates).map((symbol) => {

                            return {

                                symbol: symbol,

                                rate: rates[symbol]

                            };

                        });

                        return data;

                    }

                }

            }

        }, cfg)]);

    }

});

Integrating the Exchange Rates API with the ExtJS App

Keep in mind that you are adding the access key of Exchange Rates API, which you got in Step 9, by using these codes:

               extraParams: {

                    access_key: 'fb6e8c73be27e96f7392a4db33fa5fc5',

                    base: 'USD'

                },

                url: 'https://api.exchangeratesapi.io/v1/latest',

12. Create SymbolsStore.js file inside store folder. Add these codes:

Ext.define('HeaderLeftRight.store.SymbolsStore', {

                extend: 'Ext.data.Store',

           

 

                requires: [

                    'HeaderLeftRight.model.SymbolModel',

                    'Ext.data.proxy.JsonP',

                    'Ext.data.reader.Json'

                ],

           

 

                constructor: function(cfg) {

                    var me = this;

                    cfg = cfg || {};

                    me.callParent([Ext.apply({

                        storeId: 'SymbolsStore',

                        model: 'HeaderLeftRight.model.SymbolModel',

                        proxy: {

                            type: 'jsonp',

                            extraParams: {

                                access_key: 'fb6e8c73be27e96f7392a4db33fa5fc5'

                            },

                            url: 'https://api.exchangeratesapi.io/v1/symbols',

                            reader: {

                                type: 'json',

                                transform: function(data) {

                                    var symbols = data.symbols;

           

 

                                    data = Object.keys(symbols).map((symbol) => {

                                        return {

                                            symbol: symbol,

                                            value: symbols[symbol]

                                        };

                                    });

           

 

                                    return data;

                                }

                            }

                        }

                    }, cfg)]);

                }

            });

Keep in mind that you are integrating currency symbols from Exchange Rates API using these lines:

extraParams: {

                    access_key: 'fb6e8c73be27e96f7392a4db33fa5fc5'

                },

                url: 'https://api.exchangeratesapi.io/v1/symbols',

That’s it! You have successfully built a currency converter app, which looks like this:

You Have Successfully Built A Currency Converter App, Which Looks Like This

Source Code:

You can find the project files here.

How to run the source code on your PC?

You will need to install Sencha Architect to run the project files on your computer. You can download it for free from here.

After the installation, launch Sencha Architect on your PC and open the project folder. Simply build and preview the project. The currency converter app will show up on your favorite web browser.

Ready to get started with this powerful framework?

That’s how you build a currency converter app that pulls in data from Exchange Rates API. You can use the same codes to add the currency converter feature in your cross-platform application using Sencha Ext JS.

Sencha Ext JS is a powerful JavaScript framework for developing business-grade web applications. Try it now for free.

 

Recommended Articles

8 Must-Know Tips for Choosing the Right Web Application Framework for Your Project

Starting web application development on a project can feel like a very difficult task. The abundance of frameworks adds to the confusion. It leaves developers…

Web Application Development | Top 10 Frameworks in 2024

If you are a developer, you must know the role of frameworks in creating amazing applications. Web application development frameworks come with pre-built tools to…

Understanding the Difference: When to Use Ext JS Classic vs. Modern Toolkit

Ext JS is a JavaScript framework for building powerful web and mobile applications. The framework features over 140+ high-performance, fully tested, and customizable UI widgets/components.…

Ext JS 7.8 Has Arrived!

The Sencha team is pleased to announce the latest Ext JS version 7.8 release. Following the 7.7 release, which included numerous quality enhancements in Ext…

How to Work with Ext JS Models and Stores: Tutorial on Managing Data and State

Ext JS is a popular JavaScript framework for creating robust enterprise-grade web and mobile applications. The framework offers a rich set of high-performance and fully-tested…

Discover the Top 07 Architecture Patterns used in Modern Enterprise Software Development

Developing software without an architecture pattern may have been an option back then. However, that’s not the case anymore. Modern software development requires apps to…

View More