Thursday, 29 August 2019

Ext JS 7.0 Has Arrived

 Ext JS version 7.0 is finally over! The latest milestone update for our highly regarded JavaScript framework is now generally available, bringing major enhancements to the Modern Toolkit.

Modern Toolkit Enhancements in the Ext JS 7.0 release include:

  • Froala WYSIWYG HTML Edito​r- Froala, a light-weight WYSIWYG HTML Editor written in JavaScript, is now a part of Ext JS framework. Edit your application code using the smartest, feature-rich editing capabilities
  • Tree Drag and Drop- Easily move and reorder tree menus 
  • CheckBoxGroup Form Component- Group collection of checkbox buttons in a flexible format
  • RadioGroup Form Component- Customize option selection with radio buttons
  • Breadcrumb Toolbar- Present information in an easily navigable hierarchical format 
  • Accordion Panel- Support multiple expandable/collapsible panels
  • Accessibility improvements: Keyboard/Focus Management, Tab Indexing
  • Quality improvements throughout the Modern and Classic toolkits addressing over 70 customer reported issues.
  • And more!

Thursday, 15 August 2019

React v16.9.0 and the Roadmap Update

Renaming Unsafe Lifecycle Methods 

Over a year ago, we announced that unsafe lifecycle methods are getting renamed:
  • componentWillMount → UNSAFE_componentWillMount
  • componentWillReceiveProps → UNSAFE_componentWillReceiveProps
  • componentWillUpdate → UNSAFE_componentWillUpdate

Deprecating javascript: URLs


URLs starting with javascript: are a dangerous attack surface because it’s easy to accidentally include unsanitized output in a tag like <a href> and create a security hole

Deprecating “Factory” Components 

Before compiling JavaScript classes with Babel became popular, React had support for a “factory” component that returns an object with a render method:

New Features 


Async act() for Testing



Performance Measurements with <React.Profiler>




Reference: Reactjs Blog

Understanding the Spread Operator in JavaScript



Today we are going to discuss about the ES6 feature of Spread operator, Based on MDN docs.

Spread syntax allows an iterable such as an array expression or string to be expanded in places where zero or more arguments (for function calls) or elements (for array literals) are expected, or an object expression to be expanded in places where zero or more key-value pairs (for object literals) are expected.

Syntax for how to use:

For function calls:

myFunction(...iterableObj);

For array literals or strings:

[...iterableObj, '4', 'five', 6];

For object literals (new in ECMAScript 2018):

let objClone = { ...obj };


Example of Replace of apply:

function sum(x, y, z) {
  return x + y + z;
}

const numbers = [1, 2, 3];

console.log(sum(...numbers));
// expected output: 6

console.log(sum.apply(null, numbers));
// expected output: 6

concatenate arrays

var arr1 = [0, 1, 2];
var arr2 = [3, 4, 5];
arr1 = [...arr1, ...arr2]; // arr1 is now [0, 1, 2, 3, 4, 5]


Spread in object literals

var obj1 = { foo: 'bar', x: 42 };
var obj2 = { foo: 'baz', y: 13 };

var clonedObj = { ...obj1 };
// Object { foo: "bar", x: 42 }

var mergedObj = { ...obj1, ...obj2 };
// Object { foo: "baz", x: 42, y: 13 }

Tuesday, 2 July 2019

Ext JS TAGFIELD for modern Toolkit

Upto now Extjs 6 sencha is not providing Tagfield for modern toolkit.
This kind of component we can use many places in current mobile apps based on client requirements. So i implemented the tagfield using picker and working as expected.

Preview:



Code snippet:

Ext.define('Ext.field.TagField', {
    extend: 'Ext.field.Picker',
    xtype: 'tagfield',
    requires: [
        'Ext.picker.Picker'
    ],
    config: {
        store: null,
        displayField: 'text',
        valueField: 'id',
        picker: 'floated',
        floatedPicker: {
            xtype: 'list',
            selectable: 'multi'
        },
        selected: {}
    },

    onSelect(t, recs) {
        let i = 0,
            len = recs.length;
        if (!this._selected) {
            this._selected = {};
        }
        while (i < len) {

            this._selected[recs[i].get(this.getValueField())] = recs[i];
            this.addTag(recs[i]);
            i++;
        }
    },

    onDeselect(t, recs) {
        let i = 0,
            len = recs.length;
        while (i < len) {
            delete this._selected[recs[i].get(this.getValueField())];
            this.removeTag(recs[i]);
            i++;
        }

    },

    addTag(tag) {
        
        var dispFld = this.getDisplayField();
        var elId = this.id + '-tagId-' + tag.internalId;
        let el = document.createElement('span');
        el.id = elId;
        el.innerHTML = `${tag.get( dispFld )} <span style="margin-left: 2px; color: red;" class="x-fa fa-times-circle" aria-hidden="true">&nbsp;</span>`;
        el.style.padding = '4px';
        el.style.margin = '4px';
        el.style.cursor = 'default';
        el.style.backgroundColor = '#1E90FF';
        el.style.borderRadius = '3px';
        if (tag.tagCls) {
            el.classList.add(tag.tagCls);
        }

        el.setAttribute('tagFieldSpan', true);

        el.querySelector('span').addEventListener('click', function () {
            this.getPicker().onItemDeselect([tag]);
            this.getPicker().setItemSelection([tag], false);
        }.bind(this));

        this.beforeInputElement.append(el);
        this.beforeInputElement.setStyle({
            marginRight: '10px',
            flexWrap: 'wrap'
        });

        let storedValues = this.getValue();
        this.fireEvent('change', this, storedValues, this._selected);
        storedValues = null;
    },

    removeTag(tag) {
        
        let removed = tag.get(this.getValueField());

        let el = this.beforeInputElement.down(`#${this.id}-tagId-${tag.internalId}`);
        if (el) {
            el.destroy();
        }

        if (!this.expanded) {
            this.syncLabelPlaceholder(true);
        }

        let storedValues = this.getValue();
        this.fireEvent('change', this, storedValues, this._selected, removed);
        storedValues = null;
        removed = null;
    },
    createFloatedPicker() {
        
        const me = this;
        let result = Ext.merge({
            ownerCmp: me,
            store: me.getStore(),
            itemTpl: '{name}',
            listeners: {
                select: {
                    fn: me.onSelect,
                    scope: me
                },
                deselect: {
                    fn: me.onDeselect,
                    scope: me
                }
            }
        }, me.getFloatedPicker());
        return result;
    },

    getValue() {
        
        var keys = Object.keys(this._selected),
            i = 0,
            len = keys.length,
            values = [];

        while (i < len) {
            values.push(this._selected[keys[i]].get(this.getValueField()));
            i++;
        }

        return values;
    },

    setValue(v) {
        
        let selection = [];

        if (!(v instanceof Array)) {
            v = [v];
        }

        let i = 0,
            len = v.length,
            store = this.getPicker().getStore(),
            f, me = this;

        if (!store) {
            return false;
        }

        if (!store.isLoaded()) {
            store.addListener('load', () => {
                me.setValue(v);
            });
            return false;
        }

        while (i < len) {
            f = store.getAt(store.findExact(this.getValueField(), v[i]));
            if (f) {
                selection.push(f);
            }
            i++;
        }

        if (selection.length) {
            this.getPicker().select(selection);
        }

        if (!this.expanded) {
            this.syncLabelPlaceholder(true);
        }
    },

    privates: {
        syncLabelPlaceholder: function (val) {
            let inside;
            this._animPlaceholderLabel = val;
            if (this.rendered) {
                if (Object.keys(this._selected).length > 0) {
                    inside = false;
                } else {
                    inside = !this.hasFocus || this.getDisabled() || this.getReadOnly();
                }
                this.setLabelInPlaceholder(inside);
            }

            this._animPlaceholderLabel = false;
        },
    },

    isInputField: false,
    isSelectField: true
});

Ext.application({
    name: 'Fiddle',
    launch: function () {

        Ext.define('Fiddle.view.MyPanel', {
            extend: 'Ext.panel.Panel',
            alias: 'TestPanelDataBinding',
            viewModel: {
                data: {
                    fName: 'HariKrishna Bura'
                }
            },
            width: 400,
            height: 300,
            title: 'Form data',
            items: [{
                xtype: 'textfield',
                bind: '{fName}',
                width: 300,
                label: 'Name'
            }, {
                xtype: 'tagfield',
                multiSelect: true,
                displayField: 'name',
                valueField: 'id',
                label: 'tag Field',
                store: Ext.create('Ext.data.Store', {
                    data: [{
                        id: 1,
                        name: 'Hyderabad'
                    }, {
                        id: 2,
                        name: 'Bengaluru'
                    }, {
                        id: 3,
                        name: 'Chennai'
                    }]
                })
            }]

        });
        /*
        tag or checkbox
        */
        var pnl = Ext.create('Fiddle.view.MyPanel', {
            fullscreen: true
        });
    }

});
 

You can access my fiddler for reference:

https://fiddle.sencha.com/#view/editor&fiddle/2sdu




Tuesday, 30 April 2019

State of Sencha Address - Webinar

You’re invited to join Sencha leadership for a webinar on Thursday, May 2nd at 8:30am PDT/11:30am EDT/4:30pm BST where we will discuss the state-of-the-state of all things Sencha planned for 2019, including but not limited to: 

  • Sencha Roadmap overview, including new and upcoming product releases
  • Growth initiatives to reignite the momentum of Ext JS
  • Preview of Ext JS 7.0
  • And more!
You will also have the opportunity to meet our new General Manager of Sencha, Kegan Blumenthal and we'll host a Q&A session at the end. 

We hope you’ll join us and look forward to your participation. 

Event Details: 
Date: Thursday, May 2, 2019
Time: 8:30am PDT/11:30am EDT/4:30pm BST
Duration: 60 Minutes

Friday, 26 April 2019

React online code Editors

If you’re interested in playing around with React, you can use an online code playground. Try a Hello World template on CodePenCodeSandbox, or Glitch.
If you prefer to use your own text editor, you can also download this HTML file, edit it, and open it from the local filesystem in your browser. It does a slow runtime code transformation, so we’d only recommend using this for simple demos.
From React.


Friday, 15 March 2019

BackboneJS


BackboneJS is a light weight JavaScript library that allows to develop and structure client side applications that run in a web browser. It offers MVC framework which abstracts data into models, DOM (Document Object Model) into views and bind these two using events. This tutorial covers most of the topics required for a basic understanding of BackboneJS and to get a feel of how it works.

Backbone.js gives structure to web applications by providing models with key-value binding and custom events, collections with a rich API of enumerable functions, views with declarative event handling, and connects it all to your existing API over a RESTful JSON interface.


BackboneJS is a lightweight JavaScript library that allows to develop and structure the client side applications that run in a web browser. It offers MVC framework which abstracts data into models, DOM into views and bind these two using events.
History − BackboneJS was developed by Jeremy Ashkenas and was initially released on October 13th, 2010.
When to use Backbone
  • Consider you are creating an application with numerous lines of code using JavaScript or jQuery. In this application, if you −
    • add or replace DOM elements to the application or
    • make some requests or
    • show animation in the application or
    • add more number of lines to your code,
  • then your application might become complicated.
  • If you want a better design with less code, then it is better to use the BackboneJS library that provides good functionality, is well organized and in a structured manner for developing your application.
  • BackboneJS communicates via events; this ensures that you do not mess up the application. Your code will be cleaner, nicer and easy to maintain.
Features
The following are a list of features of BackboneJS −
  • BackboneJS allows developing of applications and the frontend in a much easier way by using JavaScript functions.
  • BackboneJS provides various building blocks such as models, views, events, routers and collections for assembling the client side web applications.
  • When a model changes, it automatically updates the HTML of your application.
  • BackboneJS is a simple library that helps in separating business and user interface logic.
  • It is free and open source library and contains over 100 available extensions.
  • It acts like a backbone for your project and helps to organize your code.
  • It manages the data model which includes the user data and displays that data at the server side with the same format written at the client side.
  • BackboneJS has a soft dependency with jQuery and a hard dependency with Underscore.js.

It allows to create client side web applications or mobile applications in a wellstructured and an organized format.

Sencha Extjs Array Utility classes

Folks,

Today we are going to discuss the basic and most important concept of Array utility methods.

Useful classes of Ext.Array

Ext.Array.erase(array, index, removeCount):


It will remove the item from an array

Removes items from an array. This is functionally equivalent to the splice method of Array, but works around bugs in IE8's splice method and does not copy the removed elements in order to return them (because very often they are ignored). 
It will returns array.

                // At index 0 erase 2 items.
     var a = Ext.Array.erase(['a', 'b', 'c', 'd', 'e'], 0, 2);  
     console.log(a); 
    // logs ["c", "d", "e"]
     

Ext.Array.unique(array)

Returns a new array with unique items.

               var a = [1, 2, 3, 4, 1, 2];
     var b = Ext.Array.unique(a);
     alert(b); // alerts [1, 2, 3, 4]


Ext.Array.merge(array1, array2, etc)

Merge multiple arrays into one with unique items.
union() is an alias for merge().

Ext.Array#union is an alias for Ext.Array#merge


               var a = [ 1, 2, 3 ];
     var b = [ 2, 3, 4 ];
     var c = [ 2, 3, 5 ];
     var d = [ 2, 3, 6 ];
     var e = Ext.Array.merge(a, b, c, d);
     alert(e); // alert [1, 2, 3, 4, 5, 6] - all items in a new array




 


Saturday, 26 January 2019

Ext JS Development Best Practices



Most of our development work in the Extjs space entails creating new apps from scratch. Having worked in this capacity as “cleaners” for quite some time now, we’ve noticed a common set of ill-advised coding practices that tend to pop up rather often in the apps we’re investigating. Based on a review of our work over the last few years, I came up with this list of development practices we recommend you avoid in your Ext JS apps.

1. Unnecessary nesting of component structures
One of the most common mistakes developers make is nesting components for no reason. Doing this hurts performance and can also cause unappealing aesthetics in the app with oddities such as double borders or unexpected layout behaviour.
Example:
1A below, we have a panel that contains a single grid. In this case, the panel is unnecessary.

items: [{
    xtype : 'panel',
    title: ‘My Cool Grid’,
    layout: ‘fit’,
    items : [{
        xtype : 'grid',
        store : 'MyStore',
        columns : [{...}]
    }]

}]


As shown in example 1B, the extra panel can be eliminated. Remember that forms, trees, tab panels, and grids all extend from Panel, so you should especially watch for unnecessary nesting conditions whenever using these components.
1B below: The grid is already a panel so just use any panel properties directly on the grid.

layout: 'fit',
items: [{
    xtype : 'grid',
    title: 'My Cool Grid',
    store : 'MyStore',
    columns : [{...}]

}]

2. Failing to follow upper/lowercase naming conventions
There are certain upper/lowercase standards that Sencha follows when naming components, properties, xtypes, etc. To avoid confusion and to keep your code clean, you should follow the same standards.
Example 2A shows several incorrect scenarios. Example 2B shows the same scenarios with the correct upper/lowercase naming conventions.
  2A: 
Ext.define('MyApp.view.customerlist',{          // should be capitalized and then camelCase
    extend : 'Ext.grid.Panel',
    alias : ‘widget.Customerlist’,                       // should be lowercase             
    MyCustomConfig : ‘xyz’,                            // should be camelCase
    initComponent : function(){
        Ext.apply(this,{
            store : ‘Customers’,
            ….
        });
        this.callParent(arguments);
    }
});

2B GOOD: Areas in bold follow all of the correct upper/lowercase rules.


Ext.define('MyApp.view.CustomerList',{      
    extend : 'Ext.grid.Panel',
    alias : 'widget.customerlist',      
    myCustomConfig : 'xyz',            
    initComponent : function(){
        Ext.apply(this,{
            store : ‘Customers’,
            ….
        });
        this.callParent(arguments);
    }

});


Additionally, if you are firing any custom events, the name of the event should be all lowercase. Of course, everything will still work if you don’t follow these conventions, but why stray outside of the standards and write less clean code?
3.Making your code more complicated than necessary

There are many times we see code that is more complicated than necessary. This is usually a result of not being entirely familiar with each component’s available methods. One of the most common cases we see is code that loads each form field from a data record individually.


 Example 3A shows an example of this.

  BAD: Loading form fields from a record individually.
//suppose the following fields exist within a form

items : [{
    fieldLabel : 'User',
    itemId : 'username'
},{
    fieldLabel : 'Email',
    itemId : 'email'
},{
    fieldLabel : 'Home Address',
    itemId : 'address'
}];

// you could load the values from a record into each form field individually
myForm.down('#username').setValue(record.get('UserName'));
myForm.down('#email').setValue(record.get('Email'));

myForm.down('#address').setValue(record.get('Address'));






Instead of loading each value individually, use the loadRecord method to load all fields from the record into the proper form fields with one line of code. The key is to make sure the “name” property of the form field matches the field name of the record as shown in example 3B.

Use loadRecord to load all form fields with one line of code.

items : [{
    fieldLabel : 'User',
    name : 'UserName'
},{
    fieldLabel : 'Email',
    name : 'Email'
},{
    fieldLabel : 'Home Address',
    name : 'Address'
}];

myForm.loadRecord(record);


This is just one example of ways code can be more complicated than necessary. The point is to review all of a component’s methods and examples to make sure you are using simple and proper techniques.


4. Unreliable referencing of components

We sometimes see code that relies on component positioning in order to get a reference. This should be avoided as the code can easily be broken if any items are added, removed or nested within a different component. 



Example 4A shows a couple common cases.

var mySaveButton = myToolbar.items.getAt(2);

var myWindow = myToolbar.ownerCt;

Example 4A. BAD: Avoid retrieving component references based on component positioning.
Instead, use ComponentQuery, or the component “up” or “down” methods, to retrieve references as shown in example 4B. With this technique the code will be less likely to break if the structure or ordering of components is subsequently changed.

var mySaveButton = myToolbar.down('#savebutton');    // searching against itemId

var myWindow = myToolbar.up(‘window');


5. Don’t Use of “id”

We don’t recommend the use of id’s on components because each id must be unique. It’s too easy to accidentally use the same id more than once, which will cause duplicate DOM id’s (name collisions). Instead, let the framework handle the generation of id’s for you. With Ext JS ComponentQuery, there is no reason to ever have to specify an id on an Ext JS component. Example 6A shows two code segments of an app where there are two different save buttons created, both of which were identified with an id of ‘savebutton’, causing a name collision. Although obvious in the code below, it can be hard to identify name collisions in a large application.

//here we define the first save button
xtype : 'toolbar',
items : [{
    text : ‘Save Picture’,
    id : 'savebutton'
}]

// somewhere else in the code we have another component with an id of ‘savebutton
xtype : 'toolbar',
items : [{
    text : ‘Save Order’,
    id : 'savebutton'
}]

BAD: Assigning a duplicate ‘id’ to a component will cause a name collision.

Instead, if you want to manually identify each component you can simply replace the ‘id’ with ‘itemId’ as shown in example 5B. This resolves the name conflict, and we can can still get a reference to the component via itemId. There are many ways to retrieve a reference to a component via itemId. A few methods are shown in example 5C.

xtype : 'toolbar',
itemId : ‘picturetoolbar’,
items : [{
    text : 'Save Picture',
    itemId : 'savebutton'
}]

// somewhere else in the code we have another component with an itemId of ‘savebutton
xtype : 'toolbar',
itemId: ‘ordertoolbar’,
items : [{
    text : ‘Save Order’,
    itemId: ‘savebutton’
}]