Ext JS and Sencha Architect Customer Spotlight: Williams

WilliamsWilliams is a publicly traded (NYSE: WMB) Fortune 500 company focused on energy infrastructure. We operate interstate natural gas pipelines, midstream gathering and processing, and natural gas liquid and olefins production and transportation. Our operations span from deep water Gulf of Mexico to the Canadian oil sands.

Our product, Amigo, is used to provide near real-time monitoring and alarming of assets in the field including meters, compressor stations, dehydrators, etc. We use push technology to allow users and customers to define what data they want to watch, or complex formula calculations to better understand the relationship between assets in the field.

Main screenMain screen with real-time monitors on the application desktop. Large widget has two states, the front is numeric and then flips to the back display which is a small trend chart.

Why We Chose Ext JS and Sencha Architect

Architect Helps Enforce Coding Continuity

We chose Ext JS 4 along with Architect 3 to enable our team to have a standard methodology of development and training for developers new to Sencha frameworks. With the recent release of Ext JS 5, we can realize our vision of making our trending features even more useful and feature full.

One of the downfalls of the JavaScript world is the lack of patterns and what I like to call “Wild West Coding” — anything goes as long as it works. Writing JavaScript is not like other more consistent languages. Being a dynamic language has some great benefits and disadvantages. One of the biggest disadvantages is the fact that you can pretty much put any property or method or closure anywhere in your JavaScript codebase, and it has a good chance of working. However, when you return to that code six months later or are the poor soul who has to figure out what the author was trying to do after they’re no longer working on the code, and it’s not so great. What usually happens is that code gets rewritten into a new form of insanity, and the next person gets to have the same fun; it’s a nasty and costly form of paying it forward. Instead, Architect enforces the MVC pattern — you only get to put code where it really should live and it’s easier to find, maintain and update. Follow that with predictable naming conventions, and the code base becomes more understandable, your release cycles increase, the separation of concerns is cleaner and ultimately your product is more stable. You can, of course, still write bad code, but at least it’s organized in a predictable manner.

Architect greatly helps to reduce poor coding habits and produces standards-compliant JavaScript. Ext JS is a very large and feature-full framework that can be overwhelming for new or junior developers. Architect helps reduce the time to productive coding. Each component in the framework has many options and properties and that can contribute to a steep learning curve. Architect helps developers learning the framework to more effectively create solid applications. It also helps more experienced developers see new functionality when the underlying frameworks, Ext JS or Touch, are upgraded.

We made a commitment to use Architect at version 2 and have since upgraded to version 3.1 — we’re very pleased with the new features. We’ve found Architect helps developers and designers work in a more cohesive manner. Yes, designers still need to have a good understanding of CSS, but they don’t need to understand the logic underneath to assign style classes or create UIs. Once the UIs are created, it also makes styling new components much more straightforward for designers and developers alike.

We upgraded to Architect version 3 for numerous reasons. Styling our Ext JS applications is very important for creating the UX users expect. We now have created two custom themes that users can switch back and forth between, depending on their preference or their environment. We’re not only making use of UIs and changing the theme-specific sprites, we’re also using our own CSS classes to achieve a precise look and feel. While this was achievable in the past, it was more difficult and time consuming. We were able to restyle the app from the base gray theme to 80% of what you see in the screenshots below within two weeks. We would not have been able to achieve that fast a turnaround without the style tools in Architect.

Main screen with second custom themeMain screen with second custom theme.

Reusable Components

Another great feature of Ext JS is the ability to not only customize the available tools, but also to create reusable components capable of being shared across projects/products. This kind of reuse helps with consistency in branding and UX. The result is that, as our visual language of UI elements spreads across products, users will automatically understand how to use an application because of similar controls.

Vertical NavigationVertical navigation with type-ahead filter at the top. This filters on a buffered grid with a full round trip to the server in an average of 130 milliseconds.

For example: in the screenshot above, there is a bar (highlighted in the orange box) with controls for deleting, saving, creating, duplicating, a custom button, and a naming control. This bar, a stylized simple container, is componentized and is not only used throughout our application, but in other projects as well. The vertical navigation with type-ahead filtering is also reusable and appears in multiple areas of the application.

This screenshot shows how we are using multiple styles for grids: Point/Analog Browser, Working Points and the Flyout. Just because it’s a grid, doesn’t mean it has to look like a grid. We’re using an Ext.toolbar.Toolbar to display formula parts and styling it to NOT look like a toolbar.

Formula EditorThe formula editor uses a flyout, so the user can choose values to place in the Sencha toolbar widget.

Business Value of Using Ext JS and Sencha Architect

Using Ext JS and Architect lowers our Total Cost of Ownership (TCO) because developers can focus on each project and fulfilling business requirements — while not having to recreate components for every project. The flexibility of the Sencha frameworks has allowed us to extend and seriously customize existing components to fulfill our needs. We don’t have to “create from scratch,” we can completely customize components to help us fulfill our business requirements.

Executing a cost benefit analysis is another clear indicator of the benefits of a strong framework and component reuse. Once you have stable, reusable components, it’s possible to more accurately predict the cost of developing a project. You always have to consider risk analysis and variability in this process, but the more items you can accurately predict, the better your analysis will be. It doesn’t matter if you’re a contractor or an employee, we all make a living on projects and those projects have to be funded.

Not only have we decreased our development time for new products, the time it takes to update or maintain the app after it has been deployed is much less. Using Architect, we can allow junior developers to make changes or maintain the code base while senior developers continue creating new features, custom components or new applications. We keep our development teams small, under 10, encouraging open communication to ensure we stay nimble and more effectively help each other learn and cross train.

Our Advice to New Developers

Learn the frameworks first! Don’t try to override everything because the framework probably has more features than you realize.

This isn’t jQuery. Use the patterns the framework provides and stop “Wild West Coding.” It will save you time and tears when you return to update or maintain the application.

Pay attention to performance. The framework is powerful, but large enterprise applications can still choke if you try to do too much simultaneously. Learn to use Ext.suspendLayouts() Ext.resumeLayouts() if you are doing anything DOM heavy.

Just because it works on a mobile device doesn’t mean that it’s right for a mobile device. This is probably more for managers than developers, but there are design considerations that make a difference between platforms/frameworks: Ext JS or Sencha Touch. These design considerations include mouse vs. finger, data volume, memory usage, screen size and orientation, etc.

Architect is your friend. As with any tool, learning Architect can take time but that time is easily gained in speed of development once you commit to its use. Architect helps you in many, many ways, and it has made our team more productive. All of the screenshots are examples of our application, solely developed in Architect.

Final Thoughts

Ext JS and Architect are fantastic tools for creating web or mobile applications. Sencha has great frameworks and toolsets that are robust with very flexible and extensible components. Ext JS is well suited for creating enterprise-level applications with large amounts of data, while other frameworks like AngularJS or jQuery really aren’t created for that purpose. When building large data intensive applications, I’ve found it best to use a tool that has been designed from that perspective. Sure you can get just about anything to work, but you will probably sacrifice stability and maintainability in the process. If you have an application that is data intensive, needs to be fast, and requires a complete customized UI, you should use Ext JS and Sencha Architect.

williams-customer-spotlight.jpg No Comments   Read more

Sencha Architect – Team Development in the Real World (Part 3 of 3)

Guest Blog Post

Sencha Architect Team Development in the Real World Part 3 of 3In part 1 and part 2 of this blog series, I provided details about the tools that CNX uses to manage team development with Sencha Architect, and I explained the basic process and presented some simple example scenarios. In this last installment, I will show you what happens when two or more developers make changes to the same files within an app at the same time.

As discussed in part 2, CNX assigns tasks to developers in such a way as to minimize the chances of two or more developers making changes to the same files at the same time, but of course it can and does happen.

Example 3: Multiple Developers Making Changes to the Same Area of an App at the Same Time

In this example, I will add some code to a controller and Sean (another developer at CNX) will do the same, completely unaware of what I have done. In the real world, the fact that a merge conflict arises would normally prompt me to discuss it with Sean before deciding how to resolve the merge. We will then have three choices to consider:

  1. Accept my changes and dump Sean’s changes.
  2. Accept Sean’s changes and dump my changes.
  3. Try to gracefully merge the changes and then have one developer review and resolve any logic problems.

Let’s say Sean and I discussed enhancing the controller from part 2 to display a better temporary message window. Further, let’s say we had a misunderstanding of who was going to code that logic, so we both completed the work separately in our local copies of the app. First, here’s Sean’s version:

Sean’s Sencha Architect - Better temporary message window
Sean’s Sencha Architect – Better temporary message window.

Now, here’s my version that I coded independently. Note that Sean’s and my versions are similar but not exactly the same:

Richard’s Sencha Architect - Better temporary message window
Richard’s Sencha Architect – Better temporary message window.

Sean will commit and push his changes first. I won’t show screenshots of this because there won’t be any conflicts on the first push. Next, I will commit and push my changes and get a merge conflict similar to the last example:

Richard’s WebStorm - Rejection when Richard’s new message window pushed
Richard’s WebStorm – Rejection when Richard’s new message window pushed.

After clicking the Merge button, the list of files with conflicts will show:

Richard’s WebStorm - Files with merge conflicts
Richard’s WebStorm – Files with merge conflicts.

The first file with a conflict is Main.js. WebStorm will nicely show my change on the left with Sean’s change on the right, and I can merge whatever side I want into the target Merge Result in the center:

Richard’s WebStorm - Merge Revisions window for Main.js
Richard’s WebStorm – Merge Revisions window for Main.js.

I’ve discussed it with Sean, and we’ve agreed that his change is better, so I’ll use the arrow next to his change to merge that into the center and dump my change:

Richard’s WebStorm - Merge Revisions window for Main.js
Richard’s WebStorm – Deciding on changes to accept in Merge Revisions window.

Richard’s WebStorm - Merge Revisions window for Main.js
Richard’s WebStorm – Sean’s merge revision accepted in Main.js.

If there were other change blocks, I would simply go to each one of them and review it in a similar fashion. In other types of changes, I could easily incorporate pieces of one side and/or the other into the center to get the desired result.

The next file to merge is the Sencha Architect metadata file for the Main controller:

Richard’s WebStorm - Sean’s merge revision accepted in Main metadata file
Richard’s WebStorm – Sean’s merge revision accepted in Main metadata file.

Conclusion

In this blog series, I have outlined the development tools and methodology that CNX uses to develop effectively with Sencha Architect in a team environment. The key takeaway from this series should be: it’s time to introduce Sencha Architect to your team. If you like Sencha Architect but weren’t sure how to make it work in a team environment, you should now be equipped with enough information to get started. Now that CNX has been using this development methodology for many months, we really can’t understand why we didn’t do it sooner.

Further Reading

architect-dev-3.jpg 4 Comments   Read more

Sencha Architect – Team Development in the Real World (Part 2 of 3)

Guest Blog Post

Sencha Architect Team Development in the Real World Part 2 of 3In part 1 of this blog post series, I detailed the tools that CNX uses to manage team development with Sencha Architect and presented one example to explain the basic process. In this installment, I will look at a more common scenario—two or more developers working on the same app in different areas. This turns out to be quite easy to manage because Sencha Architect metadata and JavaScript files will only change for those models, stores, controllers, views, etc. that you have actually changed. For example, if one developer changes a controller and another changes a view, these changes will be merged automatically and gracefully by Git and pushed to the Gitlab server without any trouble.

Example 2: Typical Case – Multiple Developers Making Changes to Different Areas of an App

Ok, let’s get to the example. Here, I will change the SimpleForm view again by adding a Help button at the bottom while Sean (another developer at CNX) adds the controller logic at the same time to handle what happens when that button is pressed.

Here I’ve added the Help button on the bottom toolbar:

Richard’s Sencha Architect - Added Help Button
Richard’s Sencha Architect – Added Help Button.

This is a screenshot of Sean’s Sencha Architect where he has added a Controller Action to handle when my Help button is pressed:

Sean’s Sencha Architect - Added onHelpButtonClick Controller Action
Sean’s Sencha Architect – Added onHelpButtonClick Controller Action.

You can see in this screenshot of Sean’s WebStorm that it’s showing only the Main controller has been changed (Note: Sean’s WebStorm is using a dark theme whereas mine is using a light gray theme. Also, ignore the .architect file in the following screenshots—I should have added it to the .gitignore file so that it was not tracked for changes.):

Sean’s WebStorm - Only the Main controller has changed
Sean’s WebStorm – Only the Main controller has changed.

On my WebStorm, it shows only the Viewport view class has been changed:

Richard’s WebStorm - Only the Viewport class has been changed
Richard’s WebStorm – Only the Viewport class has been changed.

Now, let’s see what happens when Sean and I both commit and push into Gitlab. First, Sean will commit and push:

Sean’s WebStorm - Commit and push his changes to the Main controller
Sean’s WebStorm – Commit and push his changes to the Main controller.

Now, I will commit and push the changes I made to the view:

Richard’s WebStorm - Commit and push changes to Viewport class
Richard’s WebStorm – Commit and push changes to Viewport class.

In this case, since Sean has committed a change to Gitlab that I don’t have on my local copy, WebStorm is giving a push rejection message. However, on this error message, there’s an option to Merge:

Richard’s WebStorm - Push rejected with option to Merge
Richard’s WebStorm – Push rejected with option to Merge.

Now, I will click the Merge button. As long as Sean and I have not changed any of the same files (we haven’t), I’ll go immediately to the Push window and push the changes:

Richard’s WebStorm - Push changes after a merge
Richard’s WebStorm – Push changes after a merge.

If we now look at the files on Gitlab, we can see the last person that has changed a controller is Sean and the last person that has changed a view is me:

Gitlab Server - Files after changes pushed by both Sean and RichardGitlab Server – Files after changes pushed by both Sean and Richard.

Obviously, this was a really simple scenario, but as long as multiple developers are working within different classes (i.e. files) all the changes should merge gracefully with no conflicts. At CNX, we try to assign programming tasks specifically to minimize merge conflicts.

Conclusion

In this blog post, I presented an example of how two or more developers can make changes to different areas of the same Sencha Architect app and bring those changes together gracefully. In the third and final installment of this series, I will tackle the most tricky case—multiple developers making a change to the same area of an app and resolving merge conflicts.

Further Reading

architect-dev-2.jpg 4 Comments   Read more

Sencha Architect — Team Development in the Real World (Part 1 of 3)

Guest Blog Post

Sencha Architect Team Development in the Real World Part 1 of 3At CNX, we write many apps using Ext JS and Sencha Touch. As CTO of CNX, I’ve been drawn to Sencha Architect from its inception as a way to decrease the developer’s learning curve and to produce prototypes and applications faster. However, we had avoided using Sencha Architect in real world development until recently for one big reason—we couldn’t wrap our heads around how to use it in a team environment. We had big questions (fears really):

  • How do you control JavaScript source that is automatically generated by Sencha Architect?
  • How do you control the Sencha Architect project files (the metadata)?
  • How can you merge Sencha Architect metadata work from multiple developers?
  • Will our apps fall apart when we try to merge work from multiple developers?

Getting Over the Fear

Now that we have a team methodology within CNX for developing apps in Sencha Architect, I’m slightly embarrassed that we had so much fear and concern. The reality is, if you’re familiar with source control like Git, you should have no problem managing multiple developers using Sencha Architect. Thankfully Sencha developers have made the Sencha Architect metadata code and resultant JavaScript very source-control friendly.

Of course, the devil is in the details, so I will explain CNX’s development tools and methodology and how multiple developers effectively work on a single Sencha Architect app. The tools you use and your needs may be different than ours, but at a minimum you should be able to adapt CNX’s development methodology to your own based upon my examples. And don’t be afraid. So far, we have not had one single problem or merge conflict that we couldn’t easily resolve.

Our Development Tools

At CNX, we primarily use the following tools and technologies when developing apps:

Sencha Architect – We still have many apps that are done strictly in code because they were originally developed that way. However, since establishing our team methodology months ago, we are now developing many new apps with Sencha Architect.

WebStorm from JetBrains – We like WebStorm for various reasons. It has excellent JavaScript editing along with awesome Git integration without any need to use Git from the command line. I know developers are very passionate about their editors, so I want to be clear that you don’t have to use WebStorm. I’m only listing it here because that’s what CNX uses and what you’ll see in my examples. As long as you have some decent JavaScript editor and a way of running Git commands, that’s all you really need.

You might be wondering why we need a separate JavaScript editor at all if development is done within Sencha Architect. The answer is you probably don’t need it in all cases, but we find it convenient that WebStorm visually shows us files that have been changed, visually manages the Git branches, and has an excellent way of reviewing and resolving merge conflicts. Plus, even though we use Sencha Architect, there are still many apps where we have external JavaScript and other resources to edit that we simply reference within Sencha Architect, but actually edit and manage within WebStorm.

GitLab

If you’re not familiar with GitLab, you can think of it as kind of a self-hosted GitHub. If you already use Git in some capacity, then you should be in good shape for understanding my upcoming examples. If you’ve never used Git, GitHub or GitLab, then you should familiarize yourself with them first.

GitLab - Example help page
GitLab – Example help page

In case you’re interested in specifics, this is CNX’s typical setup for its GitLab servers:

  • Hardware: Rackmounted Dell PowerEdge R310
  • Virtualization: VMware ESXi
  • OS: Ubuntu Server 14.04

For most readers, this GitLab setup will be serious overkill. I’m only including it for full disclosure, so you understand the way CNX works and can potentially learn from it. If you’re interested in more information about how to set up GitLab, see the Further Reading section at the end. Otherwise, I suggest you just use GitHub at github.com. Everything you see in my examples that I do with my internally-hosted GitLab, you can do with GitHub.

Example 1: Simple Case – Single Developer Making a Change

I’m going to start with a super simple case, so you can get an understanding of the most basic workflow. I will make a change to a simple Sencha Architect app and show you how I see what has been changed and how I check that into GitLab.

Let’s start with my app called SimpleForm. It’s a very basic app that shows a customer record in a form. It has only a single form and a single controller. Here’s what it looks like in Sencha Architect:

Sencha Architect - SimpleForm Example before any changes
Sencha Architect – SimpleForm Example before any changes

I have checked out the SimpleForm project from GitLab. Here’s what it looks like in WebStorm:

WebStorm - SimpleForm Example app before any changes
WebStorm – SimpleForm Example app before any changes

Lastly, here’s what the unchanged SimpleForm app looks like on the GitLab server:

GitLab - SimpleForm Example before any changes
GitLab – SimpleForm Example before any changes

Now let’s make a simple change. I need to add a country field at the bottom of the form. In this screenshot, I have highlighted the change in yellow:

Sencha Architect - SimpleForm Example with Country field added
Sencha Architect – SimpleForm Example with Country field added

Now, the really fun part is that if we go back into WebStorm, you will see that it has recognized the files that were changed by Sencha Architect, even though WebStorm didn’t even open them:

WebStorm - SimpleForm Example after changes by Sencha Architect
WebStorm – SimpleForm Example after changes by Sencha Architect

We can now use WebStorm’s built-in Git management to commit and push the changes to the GitLab server (important bits are highlighted in yellow):

SimpleForm Example - Commit and push changes to GitLab
SimpleForm Example – Commit and push changes to GitLab

Now, going back to the GitLab server, we can see the committed changes:

GitLab - SimpleForm example commit
GitLab – SimpleForm example commit

Drilling into the commit, you can see the changes to both the JavaScript and Sencha Architect metadata. The metadata should be easily understood by any experienced Sencha developer. It’s quite easy to see how Sencha Architect translates that metadata to JavaScript:

GitLab - SimpleForm example showing commit details
GitLab – SimpleForm example showing commit details

Parts of a Sencha Architect App to Put Under Source Control

Strictly speaking, you don’t really need to put the /app/ folder under source control. All the js files can be recreated by Sencha Architect simply by opening the project and saving again. However, we also put the /app/ folder and all Sencha Architect-generated js files under source control. It creates a bit more work for us when resolving merge conflicts since we need to address the metadata and js files. But for us, this is outweighed by the ability to easily perform source comparisons on the js files, and to have the app immediately runnable in the browser when a developer clones the app from the repository (i.e., without first needing to re-save it in Sencha Architect).

If you’re familiar with building apps with Sencha Architect build tools or through Sencha Cmd, you might be wondering what we do with the build folder. When we do build apps, we don’t track the build folder because our apps are built automatically by a special script that triggers Sencha Cmd to run on the server when apps are checked in. This, of course, is beyond the scope of this article.

Also, for experienced Git users, here’s an example of the .gitignore file entries that CNX typically uses with its Sencha Architect projects:

  • *.apdisk
  • *.DS_Store
  • *.TemporaryItems
  • *.idea
  • build/

Git Branches

To keep the examples in this blog post simple and easy to explain, I am making all changes on the master branch. In reality, this is something we wouldn’t normally do. In CNX’s real methodology, we use a development branch and other feature or bug branches off that, constantly merging changes into the development branch. When we are ready to do a new release, we then merge development into master. This process of managing branches is highly individualized, and developers have different opinions and preferences. For more information on managing branches, see the Further Reading section at the end of this article.

Conclusion

In this introductory blog post, I have detailed the tools that CNX uses to manage team development with Sencha Architect and performed one example to explain the basic process. In my next post, I will present a more typical example of how two developers can make changes to different areas of the same app and bring those changes together gracefully.

Further Reading

General info on the Git branching strategy that CNX uses:

http://nvie.com/posts/a-successful-git-branching-model/

More info regarding GitLab:

https://about.gitlab.com/

Installing GitLab on Debian/Ubuntu Linux:

https://gitlab.com/gitlab-org/gitlab-ce/blob/6-9-stable/doc/install/installation.md

About CNX

CNX Corporation is a Sencha Certified Select Partner. The Sencha Partner Network is a valuable extension of the Sencha Professional Services team.

CNX has been a leader in the development of custom business apps since 1996. CNX standardized its browser-based user interface development on Ext JS in 2008, adding Sencha Touch as a standard for mobile development in 2010. We have created world-class web apps for customers around the world in many industries including Education, Finance, Food, Law, Logistics, Manufacturing, Publishing and Retail. Our development teams are based at our corporate office in downtown Chicago and can handle projects of any scale. CNX can work independently or with your team to achieve project goals in a fast and cost-effective manner. Check us out at http://www.cnxcorp.com.

3 Comments   Read more

Announcing Sencha Architect 3.1

Sencha Architect 3.1On behalf of Sencha and the entire Architect team, I’m proud to announce the release of Sencha Architect 3.1. It comes with many new features, most notably Ext JS 5 support. Within the short period since the Ext JS 5 release, we have added support to bring Sencha Architect to parity with all the new features offered by Ext JS 5. We want to thank all the participants of the Sencha Architect 3.1 Early Access Program (EAP) for their invaluable input.


Ext JS 5 Support in Sencha Architect

The biggest update in Sencha Architect 3.1 is the addition of Ext JS 5 support. Ext JS 5 offers many new and exciting features: Touch support, architectural improvements (MVVM), responsive configs, and component upgrades, to name a few. All of these features are now supported by Sencha Architect.

MVVM Architecture Support

Ext JS 5 introduced support for MVVM architecture, with ViewControllers tied directly to the Views. To support this new approach, Sencha Architect 3.1 automatically generates a ViewController for every view that you create. Also with the new MVVM approach, a ViewModel coordinates changes between Model’s data and the View it represents, using a technique called “two-way data binding.” Sencha Architect 3.1 automatically generates a ViewModel as well for every view that you create. We encourage you to use ViewModels and ViewControllers. Note that if you are upgrading an existing Ext JS 4.2.x app, Sencha Architect 3.1 will continue to use the MVC structure you are accustomed to, but it will also allow you to leverage the MVVM functionality.

View Controllers

Routing Support

We have added support for the newly introduced routing feature in Ext JS 5, which allows you to implement “deep linking” within your applications by translating your application’s URL into controller actions and methods. Sencha Architect 3.1 offers a very simple interface to designate URLs on which to fire functions.

Routing Support

Touch-Optimized Charts Support

Ext JS 5 added a new high-performance and touch-optimized charting package (built on top of Sencha Touch charts) that offers support for interactions (pan, zoom, etc.) as well as some new chart types and enhancements to existing chart types.

Touch Charts Support

There are significant differences between this new charting package and the older Ext JS 4 legacy charts. Due to the differences, Sencha Architect 3.1 can’t auto-update your charts, instead it asks you to replace them using the new charts package. Note that Sencha Architect 3.1 does not support the use of the legacy charts, even though its available as a standalone package with the Ext JS 5 framework. That said, we have made every effort to provide helpful migration information for updating to the new charts package.


Migrating Ext JS 4.2.x Applications to Ext JS 5.0.x

One of our main goals with Sencha Architect 3.1 was to make the migration of Ext JS 4.2.x applications (built using the previous versions of Sencha Architect) as simple as possible. MigrationTo upgrade your application, simply open your Ext JS 4.2.x project in Sencha Architect 3.1, right-click on the Library node under Resources, and click Upgrade to Ext JS 5.0.x. Remember, Ext JS supports both the new MVVM and the previous MVC architectures, and it is not mandatory to switch to MVVM from MVC for your existing applications. Sencha Architect 3.1 will not automatically convert your MVC code to MVVM, but it will enable you to get started with the new MVVM architecture along with your existing MVC structure.


Sencha Cmd 5 in Sencha Architect 3.1

The latest Sencha Cmd 5.0.x integration with Sencha Architect 3.1 also offers a number of optimizations to make Sencha Architect and Cmd work faster and better, together.

Sencha Architect 3.1 leverages the Sencha Cmd ‘sencha app watch’ functionality to automatically digest and recompile the changes to your application by continuously monitoring for changes. With Sencha Cmd 5.0.x, Sencha Architect 3.1 can now deploy its own lightweight web server. This is especially helpful for users that are doing proof-of-concept projects or are just getting started and do not have a server environment set up. You can find the configurations for the web server under Preferences -> Web Server, where you can enable or disable it, and designate a port number.

Cmd Support


Other Improvements in Sencha Architect 3.1

Improved Project Inspector

We’ve greatly enhanced the project inspector in Sencha Architect 3.1 to make it easier to navigate, and to load large projects faster. The new project inspector even shows the namespaces as folders (a highly requested feature by our users), which is incredibly helpful when trying to organize your classes. The inspector now has two tree panels that sit side by side. The left pane shows every top level class and the right pane shows all details of the selected class.

Project Inspector

Visualization for Linked Instances

Sencha Architect has always allowed you to re-use existing views as building blocks to compose other views. We call this feature linked instances. When hand-coding this would be the same as writing a subclass and then re-using that class. Simple and DRY (http://en.wikipedia.org/wiki/Don’t_repeat_yourself).

When we expanded the single pane inspector to two panes it was obvious that we would need to change the way we visualized the relationships between classes. We are drawing bezier curves with SVG from each instance of the class in the detail inspector to where the class is defined.

Class Relationships

The reverse connection can also be shown by clicking the linked instance icon in the main panel. It will list every instance of where this class is being used.

Class Relationships

Helper Tool

We have added a “Helper” tool to provide common use cases that will support your development. The initial implementation of the ‘Helper” contains a data UI builder. We plan to enhance this feature in future releases of Sencha Architect.

Helper Tool

Theming Enhancements

Sencha Architect 3.1 provides a new feature for theming called “Quick Themes.” Quick Themes, which work just like custom themes, allow quick modifications to Neptune and Neptune Touch (default Ext JS themes) by simply modifying a few variables. Users save time by not having to customize every single component. A Quick Theme can always be converted to a regular custom theme, if you need more detailed customization. Other areas where Theming got some enhancements are: speed, autocomplete for SCSS variables, gradient selectors, and font selectors.

Theming

Editor Enhancements

The editor experience in Sencha Architect 3.1 has been enhanced to allow inline editing within classes. Users can now see the full context of their classes as they edit properties, create functions, and/or add comments.


Thank You

Adding Ext JS 5 support to Sencha Architect was a huge task, and we sincerely appreciate the comments and feedback from our Early Access Program (EAP) participants. We are very excited about this release and would like to hear about your experiences. Please give us your feedback in the Sencha Architect 3.x forum, so we can improve it further.

20140804-architect-3-1.jpg 19 Comments   Read more

Training Tip: Using Custom Fonts with Sencha Architect

Back in the days when websites were restricted to typical fonts such as Arial, Georgia, Times and so on, fonts were delivered from the user’s machine. Fortunately today, because of HTML5 and CSS3, browsers support embedded web fonts.

In this month’s training tip, I will explain how to use custom fonts with Sencha Architect. For this tutorial, I will use one of the Sencha Touch starter apps, with the default theme. However, you can also use these tips for other Sencha Touch or Ext JS apps.

Incorporating a custom font from a font service

If you haven’t done so, drag the Default theme into your project (I used one of the Sencha Touch starter apps). Apply the Default theme, to create a custom theme extension.

  1. Select the MyDefaultTheme, and click on the scss + button, to add a new Sass snippet.
  2. Click on the right arrow button of the Scss Resource to enter the Sass code snippet properties.
  3. Set the compile order to beforeVariables
  4. Note: One thing you should know about working with custom fonts is that font imports must always be at the very top of your stylesheet. If you don’t change the compile order of the Scss resource, this snippet will be inserted after all the Sencha theme styles are inserted. That would cause your custom fonts to not be visible.

  5. A font service (or online font provider) is a directory of free hosted web fonts. This is nice, because with a font service, you don’t need to host the fonts locally, and therefore you don’t have to deal with font copyrights. There are a couple of popular font services, such as Google Web Font or Typekit.
  6. Let’s use Google Web Font and you can choose a font you like.

    Once, you have found the font you want, click the Add to Collection button.

    Next, click the “Use” tab. Scroll down to paragraph #3, and click the @import tab. Then, copy the code it displays.

  7. Open Architect, in the Code editor paste the font code, for example:
  8. @import
    url(http://fonts.googleapis.com/css?family=Exo&subset=latin,latin-ext);
  9. Select the MyDefaultTheme and click on the Theme tab in the config inspector.
  10. Here, filter for font. In Ext.Class, you can set the font family. Set it to the following value (depending on the font you choose):
  11. 'Exo', sans-serif;

Now go back to the Design view, (if you don’t see anything, hit the “Refresh” button) and preview your new font.

Incorporating a custom @font-face (local) font

But what if you want to use your own font? Or, maybe your company has its own font you want to use. Before we get into that, let me explain a little more about local fonts.

@font-face is a CSS technique used to integrate custom web fonts. With system fonts, it picks the font if available in your OS, @font-face downloads the font from the Internet. Unfortunately, the major browsers have not standardized on one web font solution. Therefore, you have to embed multiple webfont extensions into your stylesheet.

You can get these packages of fonts online. For example, http://www.fontsquirrel.com is a website where you can download fonts, 100% free for commercial use.

  1. Select the MyDefaultTheme, and click on the scss + button, to add a new Sass snippet.
  2. Click on the right arrow button of the Scss Resource to enter the Sass code snippet properties.
  3. Set the compile order to beforeVariables
  4. Now let’s download a nice font-face kit from font-squirel.com to your hard drive, for example:
    http://www.fontsquirrel.com/fonts/exo-2
  5. Click on the Webfont kit tab, make sure the following extensions are included in the package: ttf, eot, woff, svg, and hit the blue Download @Font-face Kit button.

  6. Extract the zip file, and open one of the regular font folders. Check out the .css stylesheet that’s included, and copy the import lines of code.
  7. Go back to Sencha Architect, in the Code editor of the MyDefaultTheme, and paste the import. For example:
  8. @font-face {
            font-family: 'exo_2.0regular';
            src: url('Exo2.0-Regular-webfont.eot');
            src: url('Exo2.0-Regular-webfont.eot?#iefix') format('embedded-opentype'),
                     url('Exo2.0-Regular-webfont.woff') format('woff'),
                     url('Exo2.0-Regular-webfont.ttf') format('truetype'),
                     url('Exo2.0-Regular-webfont.svg#exo_2.0regular') format('svg');
            font-weight: normal;
            font-style: normal;
    }
  9. Now save your Architect project, and copy the 4 font extensions over to your project resources folder in your file system; if you want, you may create a subfolder fonts here.
  10. Since my fonts are located in resources/fonts/, I need to fix the path in my Architect snippet. Sencha Architect expects the fonts to be located in the /theme/ folder. I also renamed the font-family name:
  11. @import url(http://fonts.googleapis.com/css?family=Exo&subset=latin,latin-ext);
     
    @font-face {
            font-family: 'Exo2';
            src: url('../../resources/fonts/Exo2.0-Regular-webfont.eot');
            src: url('../../resources/fonts/Exo2.0-Regular-webfont.eot?#iefix') format('embedded-opentype'),
                     url('../../resources/fonts/Exo2.0-Regular-webfont.woff') format('woff'),
                     url('../../resources/fonts/Exo2.0-Regular-webfont.ttf') format('truetype'),
                     url('../../resources/fonts/Exo2.0-Regular-webfont.svg#exo_2.0regular') format('svg');
            font-weight: normal;
            font-style: normal;
    }
  12. Select the MyDefaultTheme, and click on the Theme tab.
  13. Here, filter for font. In Ext.Class, you can set the font family. Set it to the following value: (depending on the font you choose):
  14. 'Exo2';
  15. Compile your project, and test the result in your browser. You will see the new font.

Looking for more help with theming for Sencha Touch? Sign up for a training class. In July, we will offer an advanced Sencha Touch online theming course.

20140519-training-tip-custom-fonts.png 2 Comments   Read more

SenchaCon 2013: Top 10 Sessions You May Have Missed

Update: We’re working on exciting new products at Sencha to help you design, build, deploy, & manage your apps. Join us and learn more at our next SenchaCon, now in April 2015.

Earlier this year, we announced that SenchaCon 2014 is coming to the San Francisco Bay Area, November 10-13. Stay tuned for news on early bird discounts. Sign up now to be notified when registration opens in early summer.

In planning this year’s conference, we are constantly reminded of how much fun we had in Orlando last year. But beyond the parties, the contests and the swag, SenchaCon is best known for delivering amazing technical content covering all aspects of the HTML5 and Sencha ecosystems.

Here are our ten favorite sessions from SenchaCon 2013:


#1: The Magic Touch: What’s Next for Ext JS

In this session, Don Griffin covers the new technologies and features that will be coming (and are now available!) in Ext JS 5.

Don goes into great detail describing how touch events, changes to the core package, and other new features will affect Ext JS applications. If you are currently using Ext JS 4 and considering the upgrade to 5.0, you can’t miss this video.


#2: Making Great Looking Touch Charts

In this session, Jamie Avins teaches us how to use the Sencha Touch plugin-free charting library to create amazing visualizations for your next app. Jamie dives into some great code examples, featuring everything from fully customized colors, size, and positioning to HTML overlays and even synchronized components!

This session is particularly relevant today as Ext JS 5 now shares the same charting library as Sencha Touch.


#3: Don’t Get Bit by the Bug: Advanced Tips and Tricks for Debugging

Steven Roussey offers some tips, tricks, and advanced techniques for working with Chrome DevTools, Safari Web Inspector, Mozilla DevTools, and Firebug. Learn new ways to navigate your source code when debugging, measure the performance impact of your code and your theme choice, and get up to speed on a new project quickly.


#4: The Building of Fastbook

Sencha built Fastbook in late 2012 in response to comments made by Mark Zuckerberg that HTML5 &quotwasn’t ready&quot, and we received a ton of press surrounding the app.

Listen to Jacky Nguyen, one of our Sencha Touch engineers, explain how we made Fastbook so fast and what it means for JavaScript and web developers. Learn more about how browsers composite, how to recycle DOM elements, and the various other tricks that were used to make Fastbook into the app that it is.


#5: Sencha Touch Best Practices and Component Architecture

Tommy Maintz takes an in-depth look at custom components and how to build them, illustrating many best practices surrounding components and general application architecture.

Although this session is specifically targeted at Sencha Touch, most Ext JS developers should also take time to watch Tommy’s presentation because the best practices and architectural advice apply to both frameworks.


#6: Sencha Touch Debugging and Performance

Ever get an error but then are unsure how to find out the issue causing it? Think there is a better way to do something to improve performance? In this session, Jamie Avins covers common debugging techniques and offers expert tips on how to get the very best performance in your application.

Although this session is specifically targeted at Sencha Touch, Jamie dives into some advanced features of Chrome DevTools which will also help you debug Ext JS applications.


#7: Sencha Space

Sencha Space is an advanced platform for securely deploying mobile apps and delivering a consistent, elegant, mobile user experience to end users. In this session, Jason Cline introduces Sencha Space and describes how organizations can now easily build, deploy and manage applications across the enterprise.


#8: Sencha Architect 3

Get all the details on the newest version of Sencha Architect and see how the latest features and technologies will help you build powerful Sencha applications faster and more easily than ever. Aaron Conran and Gil Gordon also give you a sneak peek at what we are working on next.


#9: Turbocharge Your Grids

Almost every business app is built around a grid, and Ext JS has the best grid on the web. In this session, Nige White explains how to make your data display in a flash &#8212 no matter how many records you may have. Learn the best methods for making large data grids highly performant and scale to whatever your business needs are.


#10: Deep Dive into Ext JS Layouts

Ext JS lets you harness the browser to build amazing applications on web standards. Having these applications work across browsers, from standards to quirks modes, from panels to grids, and across all the complexity is no simple matter, and the Ext JS layout system takes those problems out of your hands, so you can focus on your app.

Don Griffin gives you a deeper understanding of what you can do with the Ext JS Layout system and how to avoid unnecessary overhead in the process.


Bonus Video: SenchaCon 2013 Wrap Up

SenchaCon 2013 brought together more than 800 application developers from the Sencha and HTML5 communities to learn, share, code, and collaborate. We had a great time in 2013, and we can’t wait to announce the lineup for SenchaCon 2014 in November! Sign up now to be notified when registration opens for this year’s conference.

Which session was your favorite?

Did you have a favorite session from SenchaCon 2013? We would love to hear which sessions were most interesting to you &#8212 and don’t forget to tell us what you want to see at SenchaCon 2014!

Last by not least, if you are interested in speaking at this year’s conference, we will be holding our Call for Speakers in early June. Start planning your abstracts today!


teaser.jpg No Comments   Read more

Sencha @ Developer Week With Architect Bootcamp

We will be at the Developer Week conference next week in San Francisco where we will be running a boot camp on Wednesday, February 19th from 9:00am–10:40am. At the boot camp you’ll use Sencha Architect to quickly build a Touch Asset Tracking application. You can still sign up for the bootcamp, so add Sencha to your agenda today.

Here’s a roundup of our recent blog posts about Architect to bring you up to speed:

Architect is a great value as part of Sencha Complete or Touch Bundles, which you can try free for 30 days or buy today.

We are looking forward to seeing you there!

20140214-developer-week.png 1 Comment   Read more

Building a User Extension and Integrating It Into Sencha Architect 3 – Part 2

Sencha Architect 3 allows users to create User Extensions that package useful third party libraries as reusable tools in all of their projects.

In Part 1 of this blog post series, Aaron Conran outlined a Car Query API and showed you how to build a useful component using Ext JS. The LinkedComboContainer he created will likely be valuable in many of your projects — a series of combo boxes that affect each other’s values is not a unique scenario.

In this post, we’ll walk you through the process of creating a reusable AUX (Architect User Extension) package. The components of an AUX are relatively simple. An AUX package is modeled after a Sencha Cmd package, and is compatible with Sencha Cmd. An AUX package has two extra pieces of information beyond a standard Sencha Cmd package. We’ll explain both of those in detail.

  1. The “architect” section of the package.json tells Architect how your class(es) should be loaded, and what CSS files may need to be loaded along with them.
  2. The “definitions” are bits of data that tell Sencha Architect how your class(es) should be presented in the toolbox.

Getting Started

Let’s get started by creating an empty package with Sencha Cmd. From your command shell, navigate to a Cmd workspace, and run “sencha generate package [packageName]” like so:

sencha generate package LinkedComboContainer

This will generate some output indicating the generation of the package. It will be placed in a “packages” directory under your workspace folder. The package name you used will define the folder name for that package.

For example: if you’re in a directory called /cmd-workspace/, the package will be placed under /cmd-workspace/packages/LinkedComboContainer

Let’s take a look now at the contents of a package, specifically as it pertains to Architect. The most interesting parts (those that are Architect specific, and that we’ll need to modify in this example) are highlighted in bold. For simpler readability, we’ve left out two folders that are generated (overrides, sass) since we will not need them in this particular AUX.

architect/            # JSON definition files for each of the AUX classes
        Xx.Definition.js  # Definition file for the XX.Definition class
build.xml             # Generated file that controls how the AUX is built
docs/
        package.png       # Graphic used on Sencha Market for this AUX
        screenshots/
                pict.png      # Graphic used for Sencha Market
licenses/             # License agreement for this AUX
                Readme.md
package.json          # 
Readme.md             # Description of this AUX used on Sencha Market
resources/            # Static resources used in this AUX
                css/          # CSS resources for this AUX
                images/       # Files for images used in this AUX
src/                  # Javascript source files for each extension class
        xxxx.js
        yyyy.js

You can see looking at this structure that there are three tasks ahead:

  1. Add our code to the src/ folder.
  2. Edit the package.json to let Architect know about that code.
  3. Create a Definition file and place it in the architect/ folder.

Step 1 — Adding your external source code to the package:

The first step is simple. We’ll download the code from the example in Part 1.

Now, just place it in the src/ folder of our generated package. It will be located here: src/LinkedComboContainer.js

That’s it. If you have more files, you can place them in the src folder as well. If you’ve got a lot of files you prefer to keep organized, subfolders are fine. You’ll just need to specify them in the package.json, which we’ll cover next.

Step 2 — Editing the package.json:

The package.json file is used by both Sencha Architect and Sencha Cmd to understand the contents of this package. Here’s what an unedited package.json looks like:

{
        "name": "LinkedComboContainer",
        "type": "code",
        "creator": "anonymous",
        "summary": "Short summary",
        "detailedDescription": "Long description of package",
        "version": "1.0.0",
        "compatVersion": "1.0.0",
        "format": "1",
        "local": true,
        "requires": []
}

You’ll want to put your name in the “creator” field, as well as add a summary and a detailed description for your package in their respective fields.

The “version” field can be left at 1.0.0 for now. If you release a new version of this package, you’ll want to update that value.

The “compatVersion” is not used by Architect at this time, though Sencha Cmd does use it to ensure that if you install an upgraded package, your project won’t need to be adjusted due to API changes. You can read more under the “Package Versioning” section of the Sencha Cmd Packages guide here.

Next, you’ll need to add an “architect”: {} object to your package.json. It’ll look like this:

"architect": {
        "compatFrameworks": [
                "ext42"
        ],
        "classes": [{
                "definition": "LinkedComboContainer.Definition.js",
                "className": "Ext.ux.LinkedComboContainer",
                "js": [
                        "LinkedComboContainer.js"
                ],
                "css": [
                ]
        }]
},

Let’s look at this piece by piece:

“compatFrameworks” is simply an array of strings indicating what framework(s) this code will work in. In our case, it was only built and tested for Ext JS 4.2, so we’ll list “ext42”. If you built an extension for Sencha Touch 2.2 and 2.3, for example, you’d list [ “touch22”, “touch23” ].

“classes” is an array of objects, where each object defines one of your classes. Let’s examine the components of each of those objects:

{
        "definition": "LinkedComboContainer.Definition.js",
        "className": "Ext.ux.LinkedComboContainer",
        "js": [
                "LinkedComboContainer.js"
        ],
        "css": [
        ]
}

Details of the class object:

“definition”: There will always be a 1:1 correlation between definitions and classes/components you want the user to be able to drag out of the toolbox. The value here is simply the filename of the definition file, placed in the architect/ folder. In this case, “LinkedComboContainer.Definition.js” — which we’ll author shortly.

“className”: This should match the className that we’re loading. You’ll recall that the class created in Part 1 is defined using: Ext.define(‘Ext.ux.LinkedComboContainer’, { … }); — we simply place that className here. Note that Architect will always start looking in the “src” folder, so that doesn’t need to be specified. However, had we put the file in a subfolder, e.g. “src/lib”, the entry would read “lib/LinkedComboContainer.js”

“js”: This is an array of JavaScript files which creates the class that will reside in the src/ folder of our package. For this case, we’ll just need one file — “LinkedComboContainer.js”. However, if LinkedComboContainer.js required another bit of code we created, e.g. “SpecialComboContainer.js”, to be loaded first, we’d list both files in order of dependency, like so: [“SpecialComboContainer.js”,”LinkedComboContainer.js”]

“css”: In this particular instance, we don’t have any special CSS. However, you may create a component that has special styles associated with it. Listing one or more files here will cause them to be loaded if/when you drag out this component.

If our example had additional classes, we’d simply have an object for each one, separated by commas, just as you’d expect in JSON.

Writing a definition:

Definitions are the magic that brings your code into Architect. There’s not much to writing the simplest of definitions, but developers can perform some pretty involved tasks with definitions if they choose to. Here’s an example definition for our LinkedComboContainer, which I’ll break down piece by piece:

{
        "classAlias": "widget.linkedcombocontainer",
        "className": "Ext.ux.LinkedComboContainer",
        "inherits": "Ext.container.Container",
        "autoName": "MyLinkedComboContainer",
        "helpText": "A linked combo container",
 
        "toolbox": {
                "name": "Linked Combo Container",
                "category": "Form Fields",
                "groups": ["Forms"]
        },
 
        "configs": [{
                "name":"disclosureMode",
                "type":"string",
                "initialValue":"enable"
        },{
                "name":"loadMode",
                "type":"string",
                "initialValue":"ondemand"
        },{
                "name":"listeners",
                "type":"object",
                "initialValue":null
        }]
 
}

The required fields here are:

className: this should match the className

classAlias: this should match the alias of the class you created in your custom code
autoName: this is the base name given to instances of your class — the name given to a component that the user drags out of Architect.

toolbox: {} — this object tells Architect what the name of the component should be when displayed in the toolbox, and what categories/groups to place it in. The “group” is the pane at the left of the toolbox, in this case the component is placed under “forms”. The “category” indicates which section on the right pane the component is placed in (as shown below).

Building Architect Extension

Some optional items we’re using in this definition:

inherits: if your component extends or inherits from another, it’s useful to specify this here. Configs that Architect already exposes for that component will be automatically pulled in. This will save you a considerable amount of work, making your component easily configurable. In our case, we’re extending “Ext.Container”, so we’re going to specify inherits: “Ext.Container”. This is different from actual class inheritance — Architect merely uses it to inherit behavior such as exposing configs.

helpText: this text will show up when the mouse is hovered over the (?) icon in the toolbox. Use it to give the user some details on what this component is. This is especially useful in extensions that contain many different components that might require a bit of explanation.

configs: all components in Ext JS and Sencha Touch have “configs” — values that the component uses as configuration options ranging from simple strings to complex objects. In this case, our component needs a few special configs beyond those that a ComboBox already provides. You can expose configs in an AUX by specifying their name, type and initial value in the definition as we did above.

While we haven’t covered everything you can do within a definition, this is enough to get our project going. For further details, please see Creating App Templates and User Extensions in our documentation.

Putting it all together

Now that we’ve created our package.json and our definition and put the files in the right place, and barring any typing mistakes, we’ve got a working package.

The next step is to make sure the package loads, so we’ll need to copy it where Architect can find and load it. As mentioned earlier, AUX files are ZIP archives for the purposes of easy distribution. However, Architect stores installed extensions in the directory specified in your Sencha Architect preferences (Sencha Architect -> Preferences).

Each package is placed in a directory like so:

%ExtensionDir%/{extensionName}/{version}

So, if we create a folder called LinkedComboComponent, and a subfolder called 1.0.0, we can copy our files in and Architect will load it right up for testing.

Note: Be sure that the “.sencha” folder gets copied over. On Linux / OSX systems, the “cp” command may not bring over hidden folders, but this is required for Architect and Cmd to load them.

If you’re looking to get started quickly, here’s the relevant folder in our github repository for the LinkedComboContainer extension.

A few pointers for editing and debugging your extension:

First and foremost: when saving a project that uses any components of a user extension, the package is copied into the project since it’s needed for deployment. This means that subsequent edits from the %ExtensionDir% folder won’t automatically make it into the project. Instead, it may be easiest to edit directly from the packages folder inside the saved project while debugging and tweaking the extension until it’s ready for release.

If definitions aren’t being loaded into the toolbox, check the Log pane at the bottom for error messages. More than likely, it’s a typo in the definition (e.g. a missing comma), or a missing field that is required.

Finally, if you’re struggling and need a bit of help, please check out our brand new forum for Sencha Architect User Extensions and Templates.

Packaging your extension:

Once an extension is working and ready for public distribution, packaging it is a breeze. Simply right click the item in the toolbox under “Extensions”, and choose “Package Extension.” Choose a location to save the file, click “save” and that’s all there is to it.

Building Architect Extension

Installing a packaged extension:

It’s extremely easy to install an AUX file. Simply click the “Install User Extensions” icon in the toolbox, or click File -> Install User Extension and navigate to the file.

To try it out, download the extension created in this post.

We hope you’ve found this to be a useful introduction to developing User Extensions for Sencha Architect, and we’re looking forward to all of the great things the Sencha developer community comes up with. Keep an eye on the User Extensions section of the Sencha Marketplace for more useful extensions that will help speed up your development process.

20140127-architect-aux-p2.jpg 2 Comments   Read more

Building a User Extension and Integrating It Into Sencha Architect 3 (Part 1)

Building an Extension in Sencha Architect 3Regardless of the type of application you’re building, there is almost always room to create a custom component or user extension that can be used across projects or teams. There is a rich ecosystem of user extensions surrounded by the vibrant Sencha community. We love to see developers share their work with the community and empower other developers to accomplish tasks more quickly. We’d like to show you some of the considerations that we take into account when building the API for a user extension.

This is the first article in a two-part series on building a user extension and integrating it into Architect. We will walk through some of the challenges in creating a robust user extension, and in the next article, we will put it all together and package it for reuse in Architect.

When building an application, sometimes you’re able to recognize which components should be user extensions right away. Others may take an implementation or two before you recognize that you are repeating yourself and need to refactor it into a user extension. The common use case that we have selected is Linked or Chained ComboBoxes. Here’s an example of what we consider a chained combo: consider the case where a person has to select the Make, Model and then Trim level of their car to purchase parts. Each time the person selects an option, it further limits the choices available in the next combobox. This is a perfect example of an interaction that developers implement over and over in different ways. It’s also a great example of a use case that can be wrapped up into a user extension for use inside and outside of Architect.

Linked Combo Container

When developing a custom component, you need to consider several use cases to make it useful to the majority of people while not making the API too complex. Oftentimes, configurations may be mutually exclusive (or certain configurations may only be valid when another configuration is set to a certain value). The trick is to make the component configurable enough to fit most situations while not making it overly complicated to configure to the developer’s specific use case. This is a common struggle that all API designers face. Some languages coerce you to be more rigid in structure than others, but this is JavaScript and like Voltaire said, “With great power comes great responsibility.”

Here are some of the things that we wanted to generalize while developing the new component, which we decided to call LinkedComboContainer:

  • Data Retrieval — The options displayed in each ComboBox should be able to come in any format via a Reader (JSON, XML, Arrays, etc) and from any source via a Proxy (Ajax, JSON-P, Direct, etc). It should also be capable of loading all of the data up-front or loading the data on demand.
  • Number of Linked ComboBoxes — A developer should be able to configure any number of linked combos together. There should be no fixed number like 3 or 4.
  • Developers should be able to use their own subclass of ComboBox — We wanted to allow developers to use their own ComboBoxes. Our user extension should not require that a user subclasses yet another class just to use their own ComboBox.
  • Display of the LinkedCombos — Should the next active combo be progressively disclosed by showing the combo from a hidden state or should it be disclosed by enabling it from a disabled state? The user should be able to configure the way ComboBoxes are disclosed.
  • Support various box layout options — The LinkedComboContainer should be able to use any configuration of vbox or hbox layout.
  • Configurations of ComboBox — We wanted to try to make all of the configurations of ComboBox available for use. For example, we should be able to set the displayField, valueField, tpl, etc.

We’re going to explore in further detail how we supported multiple approaches to load the ComboBoxes, so we could fit most environments. This article assumes that you are familiar with Ext.define and the Basics of Creating Custom Components.

Independent Stores per ComboBox

The first approach to load data covers the case where developers need to go to several different endpoints. Data in each store can be of a different proxy, reader and model. Developers can define their own stores on each ComboBox they want to use, and the LinkedComboContainer handles loading the next store each time a selection is made.

Here is a small code snippet that works off of a live JSON-P API called CarQueryAPI to retrieve Makes, Models and Trims of cars from the year 2000.

var carQueryApiUrl = 'http://www.carqueryapi.com/api/0.3/?year=2000&sold_in_us=1&';
var makeStore = new Ext.data.Store({
        proxy: {
                type: 'jsonp',
                url: carQueryApiUrl + 'cmd=getMakes',
                reader: {
                        root: 'Makes',
                        type: 'json'
                }
        },
        fields: ['make_id','make_display']
});
 
var modelStore = new Ext.data.Store({
        proxy: {
                type: 'jsonp',
                url: carQueryApiUrl + 'cmd=getModels',
                reader: {
                        root: 'Models',
                        type: 'json'
                }
        },
        fields: ['model_name']
});
var trimStore = new Ext.data.Store({
        proxy: {
                type: 'jsonp',
                url: carQueryApiUrl + 'cmd=getTrims',
                reader: {
                        root: 'Trims',
                        type: 'json'
                }
        },
        fields: [{
                name: 'model_trim',
                convert: function(v, record) {
                        // Some vehicles only come in one trim and the API returns "".
                        // Lets provide a meaningful trim option.
                        return v || 'Standard';
                }
        }]
});
 
var carComboCt = Ext.create('Ext.ux.LinkedComboContainer', {
        // configs to be passed to all combos created.
        defaultComboConfig: {
                width: 350
        },
        comboConfigs: [{
                name: 'make',
                valueField: 'make_id',
                displayField: 'make_display',
                fieldLabel: 'Choose a Car',
                store: makeStore
        },{
                name: 'model',
                valueField: 'model_name',
                displayField: 'model_name',
                store: modelStore
        },{
                name: 'trim',
                displayField: 'model_trim',
                valueField: 'model_trim',
                store: trimStore
        }]
});

Each API call to CarQueryAPI returns a different set of data and a different model. This is a good example of where we need to use different stores for each ComboBox. Here is a live example of the data that will be retrieved when choosing Lotus and then Exige.

First we grab all makes that were in year 2000.

Then we get all models for year 2000 and make of Lotus.

Then we get all trims available for 2000 Lotus Exige.

A Single Master Store

The next approach allows the developer to load all of the data for the ComboBox on demand from the same endpoint. When a selection is made, the current field will be sent as well as the previous selections made in the chain. For example, if we always want to retrieve data from the same ajax endpoint: getOptions.php.

This code snippet shows how we would do it:

var masterMockStore = new Ext.data.Store({
        proxy: {
                type: 'ajax',
                url: 'getOptions.php',
                reader: {
                        type: 'array'
                }
        },
        fields: ['name','value']
});
var mockLinkedCombo = Ext.create('Ext.ux.LinkedComboContainer', {
        // master store to load all combos from
        store: masterMockStore,
        // configs to be passed to all combos created.
        defaultComboConfig: {
                displayField: 'name',
                valueField: 'value'
        },
        comboConfigs: [{
                name: 'parentOption',
                fieldLabel: 'Parent Option'
        },{
                name: 'childOption',
                fieldLabel: 'Child Option'
        }],
        listeners: {
                subselect: function(comboCt, value, combo) {
                        // console.log('Chose ' + combo.getValue() + ' from ' + combo.name);
                },
                select: function(comboCt, value, combo) {
                        Ext.Msg.alert("A Fine Selection!", Ext.encode(value));
                }
        }
});

Requests for this configuration would be:

getOptions.php?field=parentOption

This code would return all the parentOptions.

After making a selection, the request would be:

getOptions.php?field=childOption&parentOption=optB

This code would return all the childOptions that have a parentOption of optB. With each additional subselect (selecting one option in the chain of combos), a new request will be sent including all of the previously selected fields (until all have been completed).

Loading All the Data as a List — Up-front

For small sets of data, it is nice to load all data up-front and then have the LinkedComboContainer do all the filtering on the client-side. Loading the data as a list allows you to define one store and load the data once.

Data defined as a list looks like:

[{
        state: 'CA',
        county: 'San Mateo',
        city: 'San Mateo'
},{
        state: 'CA',
        county: 'San Mateo',
        city: 'Burlingame'
},{
        state: 'CA',
        county: 'Santa Clara',
        city: 'Palo Alto'
},{
        state: 'CA',
        county: 'Santa Clara',
        city: 'Sunnyvale'
},{
        state: 'MD',
        county: 'Frederick',
        city: 'Frederick'
},{
        state: 'MD',
        county: 'Frederick',
        city: 'Middletown'
},{
        state: 'MD',
        county: 'Carroll',
        city: 'Westminster'
},{
        state: 'MD',
        county: 'Carroll',
        city: 'Eldersburg'
}]

And here is an example using that flat-list:

var stateCountyStore = new Ext.data.Store({
        proxy: {
                type: 'ajax',
                url: 'aslist.json',
                reader: {
                        type: 'json'
                }
        },
        fields: ['state','county','city']
});
var stateCountyCombo = Ext.create('Ext.ux.LinkedComboContainer', {
        // master store to load all combos from
        store: stateCountyStore,
        loadMode: 'aslist',
        comboConfigs: [{
                name: 'state',
                displayField: 'state',
                valueField: 'state',
                fieldLabel: 'State'
        },{
                name: 'county',
                displayField: 'county',
                valueField: 'county',
                fieldLabel: 'County'
        },{
                name: 'city',
                displayField: 'city',
                valueField: 'city',
                fieldLabel: 'City'
        }]
});

This is probably the easiest way to get your data in a chain of ComboBoxes but it certainly hits the client-side the hardest. There are additional optimizations that could be made by caching resultsets when filtering. Take a look at getSubListRecords of LinkedComboContainer.js.

Loading Data as a Tree — Up-front

There is one last method of retrieving the data that we wanted to tackle with our user extension — loading data in a tree format. There are some pending enhancements to Ext JS that will make this drastically easier, so we’ll put that discussion off until then.

Implementing Flexible Data

Building a widget that can be so flexible with its data is a testament to the strength of the data package in our frameworks. There were really only a few tricky bits to get all of the functionality we wanted.

When using the single store configuration. the LinkedComboContainer will create a store per ComboBox by using the same model.

The LinkedComboContainer tracks whether or not the user has provided a store when creating the ComboBox by a internal flag `userProvidedStore`; this way it knows if it should load the data from the master store or directly load the store.

userProvidedStore: !!userComboConfig.store,

When creating new instances of stores, we use the same model from the master store. By using the modelName we are able to copy in explicit models defined by a class or even implicit models that are defined just by fields.

var store = new Ext.data.Store({
        proxy: {
                type: 'memory'
        },
        // we are re-using the model from the master store
        model: this.store.model.modelName
});

Achieving Our Original Goals

Take a look at the LinkedComboContainer.js code and you will notice that we did not create any additional store classes or custom ComboBox subclasses. We also did not use any overrides. This makes it very easy for developers to use their own custom ComboBoxes, Stores, Reader & Proxies as well as integrate the component into their code base. We did run into one small problem along the way: The LinkedComboContainer needed to know when a ComboBox trigger was clicked. By design, no events are exposed when the trigger is clicked. Individual subclasses of TriggerField typically implement onTriggerClick. Because of this, we had to hijack onTriggerClick of every ComboBox that was added to the LinkedComboContainer. This way regardless of the users implementation of onTriggerClick, the LinkedComboContainer code will still be run.

// no events are exposed onTriggerClick and we'd like developers to be able to use any subclass
// of combobox without subclassing a custom one, therefore we hijack triggerClick
combo.onTriggerClick = Ext.Function.createInterceptor(combo.onTriggerClick, this.onBeforeComboTriggerClick, this);

You’ll also see that onBeforeComboTriggerClick will now run in the context of the LinkedComboContainer (meaning this. will point to the LinkedComboContainer). In order to find out what combo generated the request, we need to check the .target property which is tagged on by createInterceptor.

onBeforeComboTriggerClick: function() {
        // grab the combo that generated the triggerClick via .target (tagged on by Ext.Function.createInterceptor)
        var combo = arguments.callee.target,
                comboIndex = this.combos.indexOf(combo);
 
        // the first combo is the only one that load is triggered by clicking on the combo trigger
        // all of the others are loaded once a selection has been made.
        if (comboIndex === 0 && combo.store.getCount() === 0) {
                this.doLoad(combo);
        }
},

Please note that arguments.callee is not available in strict mode of ES5. We chose to use it in this case rather than using something like named functions in order to maintain Internet Explorer support.

What’s Next

We hope that this article has helped provide insight into custom component development and some of the issues faced when designing an API. In the next article, we will take the LinkedComboContainer and wrap it up into an Architect User Extension for drag and drop configuration. Can you think of any new features that would be useful to add to the LinkedComboContainer? Have you coded something similar? Did you do it as a one-off implementation, or did you write a custom component? Let us know.

20131209-arch-3-extension.jpg 8 Comments   Read more