Quantcast
Channel: Telerik Blogs
Viewing all 5210 articles
Browse latest View live

KendoReact: Getting Started Blog Series

$
0
0

These companion articles by Eric Bishard bring our highly informative video series by Tara Manicsic up to the present day with new details, including working with React Hooks. We get you up and running with our native UI component library for React JS.

KendoReact is the latest offering from Progress in the JavaScript framework space. It is one of two offerings that we have built from the ground up using native components that that are composable and configurable to your needs. These are components that range from everyday use to robust interactive components like Grids and Data Visualizations. For forms we have inputsdropdown listsbuttons, and more!

This blog post is a TOC for a set of companion articles making the informative video series for KendoReact available as an updated HTML version of each video from the series. Some changes have been made to account for updates and new features in the React core library. Each blog post below is a step by step guide through the basics of working with KendoReact. If you have any questions about a particular video, please post any comments or feedback on the respective video. 

The links in this post will be updated as the series is published over the coming days - bookmark this post to keep track of the entire series. Look out for the first post tomorrow.

Blog Series Table of Contents

 


Continue to the First Post (not yet live) of the series. 


A Quick Intro to the Telerik ASP.NET DataGrids – AJAX, MVC and Core

$
0
0

With more than 100 built-in functionalities available in each of the Telerik ASP.NET DataGrids, you get a powerful component which provides a variety of options for how to present and perform operations over the underlying data.

As you know, ASP.NET comes in three distinct flavors. One is not better than another, however which one you use will depend primarily on your ultimate application goals. If you plan on building a cloud-based application that could run on Windows, macOS, or Linux, you would go with ASP.NET Core. If you are interested in something lightweight and highly testable, you may go with ASP.NET MVC. Or, if you come from a desktop background and prefer a declarative and control-based programming method, ASP.NET Web Forms would likely be your framework of choice.

And with any web app, you may find yourself in need of components or controls to provide a modern UI. Because we build components, we have some insight into which ones developers are using the most in their applications. Without a doubt, across all frameworks the most popular is the DataGrid.

It makes sense. DataGrids are a ubiquitous way to represent and manipulate data.

Essential DataGrid Elements

Any developer who has tried to build one will tell you that a grid is not static. A functional grid is interactive; it has structure and often requires more than you might think at first glance.

The datagrid depicted below is a fairly common one. It includes some of the most requested features such as paging, filtering, grouping, editing, nesting tables, and more.

ASP.NET DataGrid Essential Elements

The grid is part of the Telerik UI for ASP.NET AJAX, Telerik UI for ASP.NET MVC, and Telerik UI for ASP.NET Core toolsets. Telerik UI for ASP.NET AJAX can be purchased as a standalone product or part of the Telerik DevCraft bundle. The others can be purchased as server-side add-ons to Kendo UI or in Telerik DevCraft.

With more than 100 built-in functionalities available in each of the Telerik ASP.NET DataGrids, you get a powerful component which provides a variety of options for how to present and perform operations over the underlying data. In addition to basic and expected features such as sorting, filtering, grouping, editing, and exporting, more advanced functionalities are supported as well – detail rows, reordering of rows, scroll modes, multi row or cell selection, responsive design and more. In terms of data binding, the data source you choose and how you implement may vary from framework to framework, but if you use Telerik ASP.NET DataGrid controls, you often have multiple data binding options.   

Because each framework is somewhat different, let’s explore the ASP.NET AJAX, MVC and Core DataGrids built by the Telerik team at Progress.

ASP.NET Web Forms (aka AJAX) DataGrid

The ASP.NET AJAX DataGrid is one of the most mature and advanced controls in the Telerik ASP.NET AJAX suite, featuring a rich arsenal of functionalities like data binding to various data sources, editing, filtering, sorting, CRUD operations, mobile supportgrouping and more. And each of these features is richer than a single word might suggest.

For example, with the Telerik UI for ASP.NET AJAX DataGrid you can use any declarative data source control (AccessDataSource, SqlDataSource, LinqDataSource, EntityDataSource, ObjectDataSource, XmlDataSource, OpenAccessDataSource) or bind the grid to your custom objects. We also support server events, which are executed only when the grid needs to get fresh data from the server. Declarative and programmatic client-side binding to ASP.NET Web Services, WCF, ADO.NET, OData services and Page Methods are also supported.

Telerik ASP.NET AJAX GridView - Data Binding

When bound to a DataSource control, the editing feature of the ASP.NET AJAX Grid allows you to enable automatic data editing. You can also use the extensive API to handle the CRUD operations in a custom manner. You can display the edit form inline, as a regular form or in a popup and choose between the built-in edit forms, your own template or a user control. You can also enable batch editing to allow users to edit multiple items and save them all by hitting the Save button just once.

Telerik ASP.NET AJAX GridView - Editing

Filtering is another functionality providing you with plenty of options for displaying data. With the Telerik ASP.NET DataGrids you can filter any type of data - string, decimal, Boolean, date and time. Depending on the column filtered your users can select any filtering function from the contextual menu, including “Equal,” “Contains,” “Greater than” and “Less than.” You can use the different grid columns to provide suitable filter inputs like date pickers, numeric textboxes, and drop down lists. The client and server-side APIs allow you to define your own filter template while still utilizing the built-in filtering mechanism.

Telerik ASP.NET AJAX GridView - Filtering

And those examples are just the beginning. To find out more about the functionalities of the Telerik ASP.NET AJAX DataGrid make sure you explore our resources about grid hierarchy with templates, grid virtualization, excel-like filtering, mobile-friendly grids, as well as getting started with Telerik UI for ASP.NET AJAX tips.

As you start to see the depth of the DataGrid and the richness of each feature, you will realize how much you can do with your DataGrid with the right control. You also won’t be surprised to find out that major organizations and institutions such as American Express, Bank of America and the University of North Carolina all have used the Telerik UI for ASP.NET AJAX controls.

Trial | Web Mail Sample App | Demos | Documentation

ASP.NET MVC DataGrid

The Telerik UI for ASP.NET MVC Grid enables highly sophisticated interactions with your data.

As an example, SanDisk, one of the world’s largest manufacturers of flash memory products, used the Telerik UI for ASP.NET MVC controls in an application designed to help their employees plan and forecast production and sales numbers for all the different markets they serve without maintaining spreadsheets. Analysts can maintain various versions of their forecasts and merge them into the final published version developed by the planning managers or VPs. The reports are published at the end of every quarter using BI tools such as Tableau, and released to a larger audience, including the CEO and other decision makers in the company. 

The end application featured the Grid, and was built using HTML5 and jQuery-based Kendo UI controls, Telerik UI for ASP.NET MVC, a web API and a service layer that uses a custom Data Access Layer specifically developed for SAP HANA. You can learn more about the application and project from our case study.

Much like the ASP.NET Web Forms/AJAX Grid, the Telerik UI for ASP.NET MVC DataGrid offers the essential Grid features like paging, sorting, filtering and grouping your data using a very intuitive interface. You have the ability to re-size and reorder your columns and even easily hide or display them individually. You can freeze columns with the change of a single property, or allow the user to lock and unlock columns interactively, or even easily create a hierarchy for your parent and child records. With the template feature of the Grid component you have full control over complex formatting. You can choose between a Toolbar template, Column header template, Row template, Detail template and others.

Telerik ASP.NET MVC DataGrid - Essential Features

And, as we mentioned in the section about Web Forms, each of the features has a depth and richness that enables you to create an outstanding user experience.

Take editing as an example. Editing can easily be wired to a RESTful API, or work with local data. Edit forms can be presented in-line, or in a pop-up. You can even do batch updates to allow many changes to be done before preserving them in the data. This allows your users to create, update or even delete data from your underlying data source.

Telerik ASP.NET MVC DataGrid - Editing

And since we’ve mentioned data source, with the MVC DataGrid, you can easily configure remote data binding with the Kendo UI DataSource utility which works with any RESTful API. You can connect to any local data source or remotely communicate through JSON/JSONP, OData, or XML formats.

Telerik ASP.NET MVC Grid - Data Sources

Again – we’ve just explored the tip of the iceberg with these examples, so make sure you check out our demos as well as the .NET DevChat: Responsive Web Apps with ASP.NET MVC and Bootstrap 4 and Refactoring Data Grids with C# Extension Methods articles.

Trial | Kendo UI® ♥ Bootstrap Sample App | Demos | Documentation

ASP.NET Core DataGrid

ASP.NET Core is an open-source, cross-platform framework that was first released by Microsoft in June 2016. That fall, Progress announced its Telerik UI for ASP.NET Core toolset.

In the two short years the product has been available, the ASP.NET Core DataGrid has quickly become a favorite component in the toolset. As with the other ASP.NET DataGrids, it is a responsive and adaptive HTML5 Grid that provides more than 100 features from filtering to sorting data, to more advanced features like pagination and hierarchical data grouping.

In addition to the traditional HTMLHelpers, one of which is the Grid HtmlHelper, Telerik UI for ASP.NET Core comes with the industry’s first compete packaged-set of Tag Helpers as well. The Grid Tag Helper helps you configure the Kendo UI grid component within your ASP.NET Core applications.

With the exception of the Tag Helpers, which are unique to ASP.NET Core, the ASP.NET Core and ASP.NET MVC DataGrids share the same features and functionalities. We’ve talked a little about editing and data sources, but did you know that the Telerik UI for ASP.NET Core Grid offers virtualization and endless scrolling functionalities, allowing users to scroll smoothly through records? This affords you the opportunity to achieve exceptional performance regardless of the size of your database or the grid configuration.

Telerik ASP.NET Core DataGrid Performance

From a usability perspective, our DataGrid meets accessibility requirements as well as multiple interaction opportunities. The Telerik UI for ASP.NET Core DataGrid component is Section 508, WAI-ARIA and WCAG 2.1 compliant, ensuring individuals with disabilities can interact with it. And it provides keyboard navigation that enables you to create an application that allows users to use mouse clicks, keyboard strokes or both.

Telerik ASP.NET Core DataGrid - Keyboard Navigation

With more than 100 features of the Grid alone, it’s definitely worth checking out some of our articles, particularly Working with ASP.NET Core and Data Grids, Prototyping ASP.NET Core Data Grids and Getting Started with Telerik UI for ASP.NET Core and Bootstrap 4.

As you might expect, we have an arsenal of demo pages including an Insert, Update and Delete from Data Source demo, Export to PDF & Excel demo, Freeze Grid Columns demo, Hierarchical Grid demo and Column Interaction demo.

TrialKendo UI® ♥ Bootstrap Sample App | Demos |  HTML Helpers Documentation | Tag Helpers Documentation

Additional Resources for ASP.NET AJAX, MVC, and Core DataGrids 

The DataGrids for our ASP.NET tools are feature-rich, highly performant, and beautifully designed. But don’t just take our word for it. Definitely download a free 30-day trial and take them for a spin.

And check out a few of the other Grid resources and information we have available that span across our toolsets.

  • Article:Top 17 Tips for Effective Grids in Web Apps
  • Themes: All grids have three Sass-based themes – Default, Bootstrap and Material. Have we mentioned there are Less-based themes as well? The Theme Builder application, which enables you to create new or customize the existing themes of each framework, is also available.
  • Unlimited Product Support: We’re proud to provide a support service that our customers love. Progress offers unlimited support delivered by the engineers of the product with a 24-hour guaranteed response time, Monday through Friday.
  • StackOverflow: We’re big fans of StackOverflow at Progress. If you want to learn from the larger Telerik user community, we encourage you to visit stackoverflow.com and use the tag “telerik-grid.”

Happy coding!

KendoReact: What Can It Do for You?

$
0
0

In this first post in the Getting Started with KendoReact series, you'll learn what KendoReact can do for you, the React developer.

The Kendo UI team has been building component libraries for over 15 years and they have gained a lot of experience with user interface components in particular. They've built them for jQueryAngularVue, and now they're out with a true native component library built specifically for React.

A license holder of the React libraries also has access to the jQuery, Vue and Angular libraries as well. Not that anybody would ever stray from React or have different projects where they use different libraries . But, just in case, you have all of our JavaScript libraries at your disposal.

Why React?

We decided to build a library specifically for React, because React is cool . Okay, but more importantly, a lot of developers use it, including myself and probably you. The Kendo UI team wanted to build a library that would make React applications more efficient, faster, and easier to build. This is why we have a library that's specifically made with native React components. No funny business behind the scenes with wrappers and such, although we do have jQuery wrappers for React if that's what you prefer. But we advise those starting fresh to use our native component library for React instead.

What all does that mean for your React application? These React components are composable and precisely configurable to give you the ability to work with them just as you would any other React component. They support controlled and uncontrolled state - in both cases, we got you covered!

What Other Components are There?

To check out a list of all of the components (to date), just head over to the KendoReact page and explore. It's a long list, so feel free to take a minute before getting back to the article. I should also mention that we have a roadmap to see what's coming in the future.

To use these components, all you need to do is install them using npm, import them into your existing React project, add them to your JSX template, and that's it!

If you have a basic Create React App started we can try it with the following npm install command:

npm install @progress/kendo-react-ripple @progress/kendo-react-buttons @progress/kendo-theme-default

Then, in the App.js file, we would import the following:

import { Ripple } from '@progress/kendo-react-ripple';
import { Button } from '@progress/kendo-react-buttons';
import '@progress/kendo-theme-default/dist/all.css';

With the following component definition:

class App extends React.Component {
  render() {
    return (
      <div className="example-wrapper">
        <Ripple>
          <p>Ripple on Buttons</p>
          <Button>Primary Button</Button>
        </Ripple>
      </div>
    );
  }
}

Here is the output we will get:

Ripple on Buttons example 

It's pretty easy, and one of my favorite things about using KendoReact is that styling is done for you when using our Sass themes. We know CSS isn't easy for everyone, and even if it is easy for you, it's still nice to have a theme to work with. For this reason we have created several of them, including our Kendo Default theme, Material theme, and a Bootstrap theme. With these, all you need to do is install the theme with npm and then import it into your project. As we did in the example above, the theme is one npm install and an import:

npm install @progress/kendo-theme-default
import '@progress/kendo-theme-default/dist/all.css';

With minimal effort, the themes give you lovely styled components that are consistent across your application, across components, and across projects. You don't have to touch the CSS files unless you want to provide overrides or additional customization. You also get different interactions and animations with these style libraries.

Accessibility

Support for accessibility is very important to us, we want everyone using your applications to feel comfortable. It can take time and effort to meet standard accessibility guidelines, but for our components, again, we got you covered. When you use the Kendo UI components we give you a lot of accessibility right out of the box. This includes Section 508 compliance, W3C web content accessibility guidelines, WCAG 2.1, WAI-ARIA and keyword navigation. This relieves you from having to put major development hours into custom-built components of your own. Instead, just use KendoReact because accessibility comes with the components.

Internationalization

We also provide standard internationalization support if using dates (or numbers like date input) as well as grids, numeric text boxes, etc.

Support When You Need it

At some point, everybody needs a little help! In those cases where you may hit some bumps in the road or you may not understand something, for our license holders, we offer different sources of help and support. This includes three support options for rapid help from the developers who make the product, as well as an option for 24-7 human support for tailor-made projects. You can also visit community forums where other people who are using the Kendo UI library and actual Kendo UI team members are there to help you answer questions, have discussions, and talk about different strategies they using our components.

Demos, Tutorials and Examples

There are more resources like interactive demos that you can explore. We also have example projectswebinarsblog posts, and tutorials that will give you more resources to help you. A little extra to help guide you beyond the documentation that we already have for each component.


Stay tuned for the upcoming Second Post of the series (not yet live, look out for this soon!)

Razor Components for a JavaScript-Free FrontEnd in 2019

$
0
0

Could a server application architecture that promises to provide an alternative to JavaScript be the next big thing for .NET developers in 2019? In this article we'll discuss Razor Components, a new framework that promises JavaScript free web development backed by .NET technologies like C#, .NET Standard, and SignalR.

Could a server application architecture that promises to provide an alternative to JavaScript be the next big thing for .NET developers in 2019? In this article we'll discuss Razor Components, a new framework that promises JavaScript free web development backed by .NET technologies like C#, .NET Standard, and SignalR. This new technology is on the road-map for .NET Core 3.0 and it's showing a lot of potential.

Razor Components, is what originally started as Blazor Server-Side in early 2018. Blazor is a .NET single page web application framework that is generally associated with .NET running on Web Assembly. However, Blazor is capable of running under multiple scenarios including server-side as a .NET Standard application, a.k.a. Razor Components. Blazor and Razor Components are essentially the same, except for where they execute. Blazor runs on the browser using web assembly, while Razor Components runs on the server. Razor Components treats the browser as a “thin-client” where the web browser handles just the user interface (UI) and the server receives events and responds with UI updates remotely. To the user, the application is indistinguishable from any other web application.

Author's note: In my opinion, the current name choice of “Razor Components” leads to confusion. To clarify what we're discussing:

  • Razor is a template markup syntax for .NET
  • Blazor is a .NET based web framework which can run on the client using WebAssembly or as:
    • Razor Components - Blazor framework running on the server

On the surface the concept of Razor Components brings up more questions that it answers, so let's dig deeper into the architecture.

Server - Client Architecture

Razor Components has a unique architecture that allows a .NET application to run server-side while the user interface runs out of process in a remote browser. The combination of .NET Core and SignalR allows us to write web applications without JavaScript.

At the “Core”

Razor Components is the combination of several .NET Core technologies. First and foremost a Razor Components application utilizes .NET Standard 2.0. Building with .NET Standard means Razor Components has a large .NET API surface to work with as it is compatible with other .NET Standard libraries. In addition, Razor Components is a .NET Core application, so it can be built and deployed using any operating system. A quick look inside a Razor Components .csproj shows we're in familiar .NET territory. The application type is even an EXE, which tells us this is an executable. > In .NET Core the actual output is an executable .dll, not a literal .exe.

<PropertyGroup>
  <TargetFramework>netstandard2.0</TargetFramework>
  <OutputType>Exe</OutputType>
  <LangVersion>7.3</LangVersion>
  <!-- ... -->
</PropertyGroup>

So what do we do with this executable and how does it translate into a magical thin-client enabled web application? To understand this we'll need to take a look at the server & client relationship.

Now Serving Razor Components

On the server the application is hosted by ASP.NET Core. This is again a typical ASP.NET Core application, the base on which other ASP.NET Core apps are hosted including: MVC, WebAPI, and Razor Pages. In a Razor Components application the host uses services and middleware to register the application in the HTTP pipeline. Looking into the Startup.cs of the server application we can see the services and middleware configurations.

At the time of writing, Razor Components is still called ServerSideBlazor in the related APIs.

public void ConfigureServices(IServiceCollection services)
{
  // ...

  // adds the Server-Side Blazor services, and those registered
  // by the app project's startup
  services.AddServerSideBlazor<App.Startup>();

  // ...
}

// This method gets called by the runtime. Use this method to
// configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app,
                      IHostingEnvironment env)
{
  // ...

  // Use component registrations and static files from the
  // app project.
  app.UseServerSideBlazor<App.Startup>();

  // ...
}

Once the server application is ready we can make an initial web request request, this leads us to setting up the browser as a “thin-client”.

SignalR the Thin-Client

Upon making a request to the server, we receive back static files for the application. As with most typical web applications we receive HTML. With Razor Components the first file received by the client is the Index.html file which kicks off the client-side application. The client application is a single JavaScript file included with the framework, blazor.server.js. This application is a special SignalR client with a responsibility to receive/process DOM changes from the server, send events to the server, and most importantly establish a WebSocket connection with the server.

The communication between the client and server is done through SignalR as binary data. The packets of data contain just the necessary DOM changes and not the entire rendered DOM. There's NO Viewstate a la ASP.NET WebForms to worry about with Razor Components.

With the client - server relationship understood, now we can focus on the UI portion of the framework.

Writing Web UIs Razor and C#

Since Razor Components runs server side as a .NET Standard app, logic is written using .NET technologies. This is possible due to the Blazor framework which employs the RenderTree, a DOM abstraction similar to virtual DOMs used in popular JavaScript frameworks like Angular and React. Let's look at UI side of the framework to understand how components are written.

Component Basics

Razor is the popular template markup syntax that was introduced in ASP.NET MVC 3.0. Razor gained popularity through its simplicity in that it requires an @ symbol to begin a code-block without an explicit closing tag. Unlike the MVC framework, where Razor is used to explicitly write HTML, Razor Components emits a RenderTree. In Razor Components every .cshtml file is as a component which can be used as an element, ex: Widget.cs becomes <Widget>. Carrying on the tradition of simplicity can be seen in the following image as much of the concept of a component can be understood from some basic annotations.

The header of a component defines special characteristics or features of a component such as: routing, layout, and dependency injection. In the image, we can see that this component has a route specified by @page "/counter". The component acts as a page when visiting the route /component, additionally the component can be used in other components as the element <Counter>.

All markup inside the component becomes part of the RenderTree. This shares some similarity to the way .jsx is used in React. Given the example <h1>Counter</h1> the framework will create the following code behind the scenes when building the RenderTree builder.AddMarkupContent(0, "<h1>Counter</h1>\n\n");. With the RenderTree abstracted away, developers can focus on writing components with Razor and HTML.

Component logic is written as C# within a @funcitons block. Fields, properties, and events are bound using Razor syntax. Referencing an event or value from the code block within the component's markup is as simple as using @propertyName.

Component Parameters

The concept of components goes beyond encapsulating markup. In order to create reusable components we need to be able to communicate with components. Components support the use parameters to bind data and events. Using the [Parameter] attribute in a component exposes properties for consumption. In the following Counter component, the [Parameter] attribute is added to allow consumers to specify the amount to increment the count by.

<p>Current count: @currentCount</p>
<button class="btn btn-primary" onclick="@IncrementCount">
  Click me
</button>

@functions {
  int currentCount = 0;

  [Parameter] protected int CountBy { get; set; } = 1;

  void IncrementCount()
  {
    currentCount += CountBy;
  }
}

In another file we can now set the CountBy value on the component element.

<Counter CountBy="5"></Counter>

The parameter CountBy can also be bound to other components on the page allowing the value to be set dynamically by the user. For example, we can place an input on the page and bind its value to the CountBy property. Now the counter's behavior can change at run-time by changing the value of the input.

<Counter CountBy="@countBy"></Counter>
<input bind="@countBy" type="number" />

@functions {
  int countBy = 5;
}

The component model is easy to learn but provides a robust base to build complex UIs. Additional libraries can also be used to support the application logic and UI experience.

A Broad Range of Options: Including JavaScript

Because Razor Components leverages .NET and the browser, the architecture allows for some interesting integration points.

.NET Standard and Beyond

Since Razor Components is a .NET Core application, it works with .NET Standard libraries, this means existing NuGet packages and SDKs may be compatible. This includes most .NET Standard libraries provided they do not interact with or depend on technologies that are tightly coupled to a platform. For example, a library like MarkDig which is used to parse Markdown into HTML is compatiable because it has no dependencies beyond .NET Standard 2.0. At the time of writing, even the advanced .NET based Machine Learning SDK - ML.NET is compatible when used as a service within a Razor Components application.

JavaScript Interoperability

Additionally a Razor Components app can use dependencies the JavaScript ecosystems and through an interoperability layer the app can communicate bidirectionally with both .NET and JavaScript dependencies. This is helpful for situations where the Razor Components does not support a necessary browser/DOM API or an existing JavaScript library is useful.

While the component model in Razor Components an solve most UI needs, some DOM APIs are still needed. For example, getting the users geo location information is not supported directly through Razor Components. To access this feature as a DOM API, Razor Components can call upon the JavaScript implementation in the browser through the JavaScript interop layer.

The following example shows an example of how a C# abstraction can be written to interface with the browser's geo location APIs, specifically the getCurrentPosition method. From .NET, the JSRuntime.Current.InvokeAsync method is used to invoke a JavaScript moduleinteropGeolocation.js.

// GeoLocation.cs (.NET)
public class Geolocation
{
  // ...

  public async Task GetCurrentPosition(
    Action<Position> onSuccess,
    Action<PositionError> onError,
    PositionOptions options = null)
  {
    OnGetPosition = onSuccess;
    OnGetPositionError = onError;
    await JSRuntime.Current.InvokeAsync<bool>(
      "interopGeolocation.getCurrentPosition",
      new DotNetObjectRef(this),
      options);
  }

  // ...
}

Through invokeMethodAsync the JavaScript module is able to call back into .NET returning the results.

// interopGeolocation.js (Browser)

window.interopGeolocation = {
  getCurrentPosition: function (geolocationRef, options) {
    const success = (result) => {
      geolocationRef.invokeMethodAsync(
        'RaiseOnGetPosition',
        interopGeolocation.toSerializeable(result));
    };
    const error = (er) =>
    geolocationRef.invokeMethodAsync(
      'RaiseOnGetPositionError',
      er.code);
    navigator.geolocation.getCurrentPosition(
      success,
      error,
      options);
},

// ...

The abstraction is then used within the application as normal C# code. This interop can written as a .NET library that can be shared among many projects.

// Index.cshtml (Application usage)

// Component initialized
protected override async Task OnInitAsync()
{
  var g = new Geolocation();
  await g.WatchPosition(Handler, HandleError);
}

void Handler(Position p)
{
  Lat = p.Coords.Latitude;
  Long = p.Coords.Longitude;
}

Ideally, once an interop is created for an API, it shouldn't have to be created again.

ASP.NET Core 3.0 Timeline

Razor Components was first announced during DotNET Conf. It is expected that Razor Components will ship with ASP.NET Core 3.0 mid-2019. The following quote from Daniel Roth explains what the goal of Blazor and Razor Components will be over the near term.

Our primary goal remains to ship support for running Blazor client-side in the browser. Work on running Blazor client-side on WebAssembly will continue in parallel with the Razor Components work, although it will remain experimental for a while longer while we work through the issues of running .NET on WebAssembly. We will however keep the component model the same regardless of whether you are running on the server or the client. You can switch your Blazor app to run on the client or the server by changing a single line of code. See the Blazor .NET Conf talk to see this in action and to learn more about our plans for Razor Components:

Getting Started

If you're the type of developer who likes to test things early, you can try Blazor Components today. At the time of writing, Razor Components is still being branded as Server-Side Blazor which can be found at Blazor.NET. Follow the instructions under getting and be sure to choose the “Blazor (Server-Side in ASP.NET Core)” project type.

Pros & Cons

Since only a small amount of JavaScript is required to bootstrap the client and no .NET assemblies are transferred to the client. Even during operation network traffic is light because communication between the browser “thin-client” and the server is a small binary packet. However, because web sockets are used, the client and server must always be connected. This means that Razor Components apps cannot work in offline mode. If offline mode is a must for your application, then the WebAssembly equivalent Blazor application may be a better choice. With that said, Blazor has yet to receive an official release date or promise of support from Microsoft.

Scale with Azure

One last point of concern to some may be the question of “how will Razor Components scale.” Since Razor Components is built with SignalR, it has the advantage of Azure. Azure SignalR Service is a fully managed service infrastructure that works seamlessly with ASP.NET Core SignalR. Integrating SignalR Service requires very little code modification to add automatic capacity provisioning, scaling, or persistent connections.

Wrapping up

Razor Components, the server-side implementation of the Blazor framework is a new take on web development. By utilizing the web browser as a thin-client Razor Components offers a new alternative to JavaScript frameworks. Its component model is simple enough that it maintains a short learning curve, yet is robust enough to be extremely productive. Even though Razor Components is new, its ability to use existing .NET libraries, tooling and optionally JavaScript's ecosystem as well makes it a strong candidate for front end web development.

Building Faster Backends in ASP.NET Core

$
0
0

Web application performance is often ignored until it's too late. If developers are not careful, small inefficiencies can pile up leading to a slow clunky web app. To avoid this fate, the key is consistency - and always staying cognizant of performance bottlenecks. Many small improvements over time are cheaper and easier than trying to cram them in at the end of the project.

We recently looked at how to build faster frontends in ASP.NET Core. Now let's take a look at the other half of the equation - the web server backend. Optimizing your backend performance is different than optimizing your frontend web app. Most frontend performance improvements focus on the size of requests going over the wire. Backend performance, on the other hand, is more focused on getting data efficiently and controlling responses. This article takes a deep dive into backend performance tuning - we take a look at some tools of the trade and common techniques that can help.

Measuring Speed

If you want to improve the performance of your web application, you must first measure it. Measuring performance can be tricky business. Variations caused by other processes in the pipeline can make exact performance numbers hard to obtain. Developers need to know never to trust a single performance number. If you run the same operation under the same conditions a few times, you'll get a range that's good enough to optimize. Additionally, there are certain performance issues that you can only catch while running the application under user load.

To measure performance, developers would likely want to use two different types of tools. First would be a profiling tool to measure individual performance. There are many tools that can do this, but one of the most popular ones is MiniProfiler. MiniProfiler is simply a NuGet package you can pull in to your web application project. It measures the performance of different processes and displays the information while you run your application. Times are stored unobtrusively on the top right corner. You can expand them to get a detailed analysis of the time it takes for different processes to run on your machine. Here's an example of the output from MiniProfiler:

MiniProfiler will also profile SQL queries from Entity Framework - this makes it easy to find long running queries. MiniProfiler will also flag duplicate SQL queries. Here's an example:

You can also add custom profiling steps to your web application. If you have a long running process, you can break it down into steps and track how long each one takes. In the code below, we're adding a custom profiling step to the method:

MiniProfiler is a great tool for testing the performance of an application while you're using it, but it lacks the ability to get aggregate performance data. For this, you'll likely need an application performance monitoring (APM) tool. Application Insights and New Relic are popular, but there are lots of options. These tools will measure the overall performance of your web app, determining the average response time and flagging down slow responses for you.

Once you have your measurement tools in place, you can move onto fixing problems. When fixing performance issues, developers should take measurements before and after each intervention. Also, it is advisable to change only one thing at a time - if you change several factors and re-test, you won't know which (if any) of those interventions worked. Improving application performance is all about running different experiments. Measuring performance will tell you which experiments worked.

Another handy utility for measuring performance is Telerik Test Studio– a test automation solution liked by developers & QAs. While the primary goal is automating UI tests for web/desktop/mobile, Test Studio is also quite helpful in load and performance testing. Developers can capture HTTP(S) traffic and customize requests to gauge impact on performance, and recorded Test Studio web tests can be reused for load testing. The bottom line is, developers should use all available tools at their disposal to measure speed and see how performance tuning can help.

Performance Tips

There are a lot of performance tuning techniques - the best ones are based on real production applications. Performance tips cannot be applied blindly though - developers need to measure the interventions and make sure they work for the given app. Just because something worked in one app, it doesn't mean it'll be good for another application. Let's do a quick run down of some common performance tuning techniques for your backend app server.

Dealing with Databases

Data is pivotal for any app, but databases can also be the most common performance bottleneck. Your database queries need to be efficient - period. Using your favorite profiler, find the offending slow-running query and try running it directly against the database. Developers can also use SQL Server Management Studio and check out the execution plan, if using SQL Server as a database. If using relational databases, you should make sure that the fields you are searching on are hitting the appropriate indexes - if need be, one can add any necessary indexes and try again. If your database query is complex, you can try simplifying it or splitting it up into pieces.

If optimizing SQL queries is not your forte, there's a shortcut. In SQL Server Management studio, go to Tools > Database Tuning Engine Advisor. Run your query through the tool and it'll give you suggestions on how to make it run faster.

Get the Right Stuff

What your web app shows on a given screen should have an exact correlation to what you fetch from your data tier - one should not grab any unnecessary data. Developers need to be wary of reusing expensive item retrievals to grab whole graphs of related objects for small grids.

Another thing to consider is that your users probably aren't going to read 10,000 items you pushed out to client side - at least, not at the same time. Developers must consider fetching data in batches and using pagination to limit the size of datasets retrieved. Modern interface for web apps like Kendo UI or Telerik UI for ASP.NET MVC/Core already have smart UI controls that work seamlessly with chunks of data through pagination - developers don't need to reinvent the wheel.

Cache Slow Calculations

The best way to get data more quickly is to not get it at all. Smart use of caching can radically improve your web application's performance. In ASP.NET Core, data caching comes in two flavors - in-memory caching and distributed caching.

In-memory caching stores cached data on the server. While this is the easiest cache to use, it's also limited to a single server. If you are running multiple servers, each will have a different cache.

Distributed cache uses a data store to keep the cached data. You can run as many servers as you want and they'll all hit the same data cache. The two most common data stores for distributed caching are SQL server and REDIS - both fairly easy to set up.

Because it's so effective, some developers will want to cache everything - this can be counterproductive. Caching adds complexity to your app and the performance boost isn't always worth it. Developers should limit caching to things that are hard to calculate or slow to change. Another technique is to try keeping all data caching logic in a single layer in your app - throwing cache commands all over the place can make it hard to track down potential errors.

Crush it with Response Compression

When improving the performance of your web applications, it's important to minimize the amount of data over the wire. This is especially true for folks using your web app from their phones. One way to send fewer bits is to enable response compression. By default, ASP.NET Core will GZIP several different types of requests. However, it will not GZIP commonly used responses, including CSS, JavaScript, and JSON. Before ASP.NET Core, you used to have to write custom middleware to compress those types of responses. In ASP.NET Core, the middleware is built in... all you need to do is add it to your Startup.cs file, like so:

Don't Create a Logjam

While most logging frameworks keep their performance cost to a minimum, logging still has a cost. Excessive logging can slow down your application during high load times. When in Production, developers should be logging only what's necessary to support monitoring and routine troubleshooting. You should save verbose logging for lower environments where you can afford the performance cost. Also, logging levels are best kept configurable - if you need to temporarily turn up your logging to gather data for an issue, you should be able make that happen without needing to recompile your app.

Ace Your Async Requests

Making use of asynchronous programming with C# Async/Await is a fantastic way to improve the performance of your application, but you need to be aware that these keywords will not run commands in parallel. Await stops the execution of your code - so if you have multiple async requests that are awaiting, your individual performance will be the same as if you ran those requests consecutively.

This doesn't mean you shouldn't async what you can, however. Async still improves the performance of your application, but only under load. By reducing the number of threads waiting around, async/await increases the throughput of your application.

If you want to improve individual performance, you need to make use of the Task Parallel Library (TPL). By managing your own tasks, you can execute things in parallel. If you have several slow calls to make for a method, like calling an external service, you should consider running them in parallel instead of using async/await.

The following example illustrates the two methods. The top method uses the standard async/await flow and the bottom method uses task objects. Running the tasks in parallel uses more code, but running several slow requests in parallel will save time.

Make Your Apps Faster Today

Building performant web applications is a tough job, but ASP.NET Core has lots of tools and features that will help. Developers should begin by measuring performance with tools like MiniProfiler and Application Insights. Then, as you find bottlenecks, go through the checklist to see which interventions help your app. Performance tuning takes patience and experimentation - hopefully, with frontend and backend processes streamlined, you can turn the right knobs to see performance improvements. Performant web apps mean delighted users and elevated engagement - cheers to that.

How Can I Input Random Data into My Test Run?

$
0
0

Random data testing has been around for ages and every now and then our Test Studio support team gets a request like this:

How can I input random data into my test run?

At a first glance this seems to be a feature that's lacking in Telerik Test Studio, and going over the documentation will yield some results like this one here. Now to the trained user this is a straight solution – create a coded step and do it, you know, the “coding QA engineer’s” way. And this is fine.

harry

But then comes the next field, the next value. “Oh this is a number, but I need email, telephone… etc.” Then you will probably think about reusability but there is a pretty big chance that eventually you will have this little code noodle monster spread across the entire project.

noodle

So, how we can prevent that? I’ve been tinkering with “Any-.Net”, a simple old framework for generating all sorts of random data and it seems to be solving the issue pretty well.

So, let’s integrate it in Test Studio:

1. Download “Any-.Net” and add it as a script reference to your Test Studio project:

1

2. Create a simple test that will act as a reusable container for random data. I will call it “SetRandomValues.”

RandomData_BlogPost


3. Open the “SetRandomValues” test and add a coded step to it:

2018-12-07_1258

4. Time to integrate the Any-.Net framework into our project. This will be the only piece of code that you’ll ever require:

[CodedStep(@"New Coded Step")]
        public void SetRandomValues_CodedStep()
        {
            this.SetExtractedValue("randomMail", Any.Any.EmailAddress());
            this.SetExtractedValue("randomPass", Any.Any.Word(8));
            this.SetExtractedValue("randomInt", Any.Any.Integer(0, 100));
        }

Now whenever you need a random value you can simple reference the “SetRandomValues” as test as a step:

testasstep


5. Finally, bind your “Set” actions to the random value(s). here is an example for a “SetText” step which inserts a text into a username field:

RandomData2

That’s it! Having a single test as a random value generator reduces complexity and maintenance. On top of that all values are bound via the built-in functionality, so it doesn’t require any coding.

If you want to try this you can start a free, fully functional 30-day trial:

Try Test Studio

Adding Kendo UI Charts to Our To-Do App

$
0
0

A quick overview to help you add Kendo UI charts to the to-do app we created last time. Check out the full video series for more.

Hello and welcome back to Angular and Kendo UI Unite! If you are new to this series, I highly suggest you start with the first post here, or check out the video series these posts are based on! In today's video, I thought it would be super fun to add a chart to our to-do app that shows the busiest time of day. Let's jump in.

Here's our app as we left it. We have our awesome to-do list using Kendo UI inputs and buttons, and we're using custom Angular animations on load in, add an item and remove an item to make the app look super snazzy. We also added a time picker during the last episode that allows us to go ahead and set a due time for each of the to-do items.

screenshot showing todo list and time picker where we left off from the last post
Follow along with the code found here.

We're going to use the to-do data from our app to populate a chart showing which hours in our day are the busiest. To do that, we need to use a Kendo UI Chart.

Kendo UI has many different charts with lots of awesome options. I highly suggest you check out our docs and see all of the very cool examples we have there.

screenshot of our docs page with our charts

But, to get started with ours, in our application, we just need to do the installation, and thanks to the Angular CLI version six, we can just use this NG add command: ng add@progress/Kendo-Angular-charts.

If we go back over to our todo.component.ts, I'll show you a couple of things that have changed since last we met. I went ahead and created an interface with item due and hour.


interface Todo {
  item: string;
  due:  Date;
  hour: number;
}

Now, item and due were already there from the time picker episode, but if we go to our to-do's, open it up and check it out, you'll see that I've also added an hour key. This uses a new date that's identical to due, but it's also using a custom pipe that I created.

screenshot of todo component with newly updated todos array

So, for those of you who didn't know, Angular enables you to use a pipe in a template, or you can actually use it with a .transform method inside of your component itself. Let me show off the custom pipe I created real quick.

screenshot of hour pipe code

Super simple. Literally, all it's doing is taking the value, which is a date value, and it's getting the hour off of that value. So if the due time is 2:30 a.m., it will change this to 2. If the due time is 10:15 p.m., it will give us the value 22.

The next step is actually organizing our to-do's by the hour. What do I mean? Well, we can't use our to-do's data as it is. We actually need to group it by the hour. So, for instance, if 1:00 a.m. has multiple items, we need to group those together and put them in a group. That way we can make a chart and clearly convey to users, "hey, look 1:00 a.m. is super busy."

So, Kendo UI actually has a group by method, and I'm going to open up our docs to show that off here.

screenshot of our docs talking about group of objects and data query

In order to use our charts group by method, we’ll need to npm install and import the data query package!

Install Kendo Data Query


npm install --save @progress/kendo-data-query

Import Kendo Data Query


import { groupBy, GroupResult } from '@progress/kendo-data-query';

At the top of our todo.component.ts, I'm importing groupBy and GroupResult from Kendo Data Query. What this is going to allow us to do is pretty much exactly what the function is called: organize to-do's by hour.

If there are no todos, go ahead and return null. Otherwise, we're going to take this.hourlyTodos and we're setting it to group by.


  organizeTodosByHour(todos) {
    if (!todos) return null;
    this.hourlyTodos = groupBy(this.todos, [{ field: "hour" }]);
    console.log(JSON.stringify(this.hourlyTodos, null, 2));
  }
  

I’m console logging with JSON.stringify, so that we can see what exactly our method is doing to our to-do's array. How is it reorganizing it? If we head back over to the console, we can see the logs:


[
  {
    "aggregates": {},
    "field": "hour",
    "items": [
      {
        "item": "Take dog to vet",
        "due": "2019-04-10T06:10:00.000Z",
        "hour": 1
      },
      {
        "item": "Create to-do app",
        "due": "2019-04-10T06:00:00.000Z",
        "hour": 1
      }
    ],
    "value": 1
  },
  {
    "aggregates": {},
    "field": "hour",
    "items": [
      {
        "item": "Get oil change",
        "due": "2019-04-11T03:15:00.000Z",
        "hour": 22
      }
    ],
    "value": 22
  },
  {
    "aggregates": {},
    "field": "hour",
    "items": [
      {
        "item": "Finish super hard puzzle",
        "due": "2019-04-10T07:30:00.000Z",
        "hour": 2
      }
    ],
    "value": 2
  },
  {
    "aggregates": {},
    "field": "hour",
    "items": [
      {
        "item": "Pack for Denver",
        "due": "2019-04-11T00:00:00.000Z",
        "hour": 19
      }
    ],
    "value": 19
  }
]

So, now we can see what exactly this group by method has done to our data. We see that it has actually done what we had hoped for and chunked up our items by hour. You can see that we have two 1's that it has put together. And then, below that, we have three different individual times. But, that's exactly what we wanted and exactly what we need for our chart.

Now, I'm sure we're all anxious to get something—ANYTHING on the screen because we've been talking about charts. We've been manipulating our data, but you're like, "Alyssa, just let me see the chart!" So, I give unto thee, the chart! Here in our todo.component.html, we need to add the markup for our chart:


// todo.component.html

<kendo-chart>
  <kendo-chart-title text="Busiest time of day"></kendo-chart-title>
</kendo-chart>

Inside of our Kendo UI chart, we're going to have a Kendo chart title—the busiest time of day—because that's what we're charting here. And then, we have two inner items here to talk about.


// todo.component.html

<kendo-chart>
  <kendo-chart-title text="Busiest time of day"></kendo-chart-title>
  <kendo-chart-series>
    <kendo-chart-series-item 
      [data]="hourlyTodos" 
      [name]="field" 
      field="items.length" 
      categoryField="humanizedValue"
      type="column">
    </kendo-chart-series-item>
  </kendo-chart-series>
</kendo-chart>

The first one is Kendo Chart Series. You can think of this as like your outer chart wrapper. And then, next, you have the actual individual items in the chart. So, the data is the hourly to-do's. The name is field. We’ve also set field to items.length. This is because we want the hours that have more to-do times attached to them to be longer. We’d like the category field to be set to value, which is the hour (what we grouped each of these by).

And then lastly, type of column, which is this could be type of bubble, type of bar, which like column, but coming from the sides. Lots of, I mean, lots of different charts that we could do, but right now, we're sticking with our column. If we go ahead and save that and let it refresh—yay! Here we have our chart and you can see that 1:00 a.m. is in fact busier than another part of my day.

screenshot of todo app with chart of busiest time of day

Wonderful, working perfectly. However, I don't know about you, but I think we could clean it up just a little bit. When you add, remove or change to-do items (like edit their time), the chart doesn't change. Now, if we ponder this, it actually should make a lot of sense why the chart doesn't change.

this.hourlyTodos is being created and set equal to the todos array, organized by hour.


organizeTodosByHour(todos) {
  if (!todos) return null;
  this.hourlyTodos = groupBy(this.todos, [{ field: "hour" }]);
}

What we need to do is call organizeTodosByHour() on add and remove, as well, if we want to go ahead and see our data in the chart updating.

screenshot of calling organize todos by hour method on add and remove

So if we go back and remove something, you can see that it is removed from the chart. If we add something new, you can see that as well is. However, our time picker is not changing.

The way that we grab the event off of the time picker is actually going to be super easy. Inside of Kendo time picker, we're going to bind value change and we're going to set that equal to a method of our choosing. I named ours onTimeChange()


// todo.component.html

<kendo-timepicker [(value)]="todo.due" (valueChange)="onTimeChange()"></kendo-timepicker>

// todo.component.ts
  
  public onTimeChange() {
    this.todos.map((todo) => {
      todo.hour = this.hour.transform(todo.due);
      return todo;
    });
    this.organizeTodosByHour(this.todos);
  }

In the onTimeChange() method, we're mapping through our to-do's. For each to-do, we're creating an hour property and we're setting that equal to todo.due, which is the same due date but we're running it through our custom hour pipe. We haven't yet created a backend so that we can update, remove and add. So, every time the time changes, we needed to manually recreate this hour property here on our to-do's after using the hour pipe to transform the hour. We're also calling our organized to-do's by hour, which we were doing on add and remove. This is so that our hourly to-do's are updated, which is what is required for our chart to change.

Now when we update the time of our to-do’s, our chart will update as well! There are two more touchups I’d like to do to our chart, so hang in there with me—you're almost a chart master yourself.

First of all, I'm not very good at military time. When I look at our chart and see 15 for the time of day, my brain kind of blurs and I have to pause to do the math. I think it would be for the best if we showed our chart it in a 12-hour clock instead of the 24-hour clock. So inside of our organizeTodosByHour() method, I’m going to add a bit of logic that will change our times to a 12-hour clock. I'm actually using modulo here to say, if the value, modulo 12 is not zero, then you're going to go ahead and set the value equal to that value. Modulo, if you don't remember, is taking the remainder from division.


  organizeTodosByHour(todos) {
    if (!todos) return null;
    this.hourlyTodos = groupBy(this.todos, [{ field: "hour" }]);
    

     // Humanizing the category field!!
     for (let group of this.hourlyTodos) {
       // turn the todos into 12 hr clock, not 24
       let hour: number = 12;
       if (group.value % 12 != 0) {
         hour = group.value % 12
       }
       
       // add AM or PM to the todos for the chart view
       if (group.value < 12) {
         group.humanizedValue = `${hour} AM`
       } else {
         group.humanizedValue = `${hour} PM`
       }
    }
  
  }

We also added AM or PM to our to-dos . Super simple, right? If it's greater than 12 or less than 12, set AM or PM. In order to use our new humanizedValue, we used it inside our Kendo UI Chart fo categoryField instead of value:

screenshot of our todo.component.html file where we are using humanized value instead of value

Secondly, I think if we sorted our times in order of earliest in the day to later in the day, it might make more sense as we read the chart.


  organizeTodosByHour(todos) {
    if (!todos) return null;
    this.hourlyTodos = groupBy(this.todos, [{ field: "hour" }]);

     // turn the todos into 12 hr clock, not 24
     for (let group of this.hourlyTodos) {
       let hour: number = 12;
       if (group.value % 12 != 0) {
         hour = group.value % 12
       }
       
       // add AM or PM to the todos for the chart view
       if (group.value < 12) {
         group.humanizedValue = `${hour} AM`
       } else {
         group.humanizedValue = `${hour} PM`
       }
    }
    
     // sort the hourlyTodos in order by hour
     this.hourlyTodos.sort((a, b) => {
       if (a.value < b.value) {
         return -1;
       } else if (a.value > b.value) {
         return 1;
       } else {
         return 0;
       }
     });
  }

So here, you can see we’re using the .sort() method to reorganize our times. If we now check out our chart, we can see the times are all 12-hour clock times, with a.m. or p.m., and organized in order!

final image of chart with times all in 12-hour clock, with AM or PM, and organized in order

I have just had a blast making this series. I hope you have too, learning a bit about Angular and Kendo UI. Check out the video series or check out Github for all of the codes that we've been working on. I wish you all the happiest of coding in the future. Thanks for following along!

How to Use Basic React Hooks for Context

$
0
0

With React Conf 2018 behind us, we have learned that the 16.7 release of React introduces an important new feature: React Hooks. Get "hooked" on React as we take a look at the useContext React Hook!

The Third Basic Hook: Context

We started this series talking about the two most commonly used and easily learned React Hooks and you can see that blog post here: How to Use Basic React Hooks for State and Effects. We explored the React JS Docs Proposal for Hooks and provided some StackBlitz demos that you follow along with and fork each demo we talk about. Understanding how state and effects work is not the whole story, in fact, it will take more than two blog posts to cover Hooks well. We still have one more basic hook to learn about before fully covering the basics.

After reading this article, you should be comfortable with being able to share data between functional components in your application by using various basic hooks and setState. This is a gateway into being able to do more state management in a pattern similar to what you know in Flux and Redux but without importing another library. We can do it with React core. But first we need to understand Context in React.

Using React Hooks for Context

To understand the third basic React Hook useContext, we first need to have a good understanding of the Context API, a stable feature since React 16.3. Like learning most things, sometimes we have to fully understand another concept before moving forward. If you're familiar with Context API, you can skip to the useContext section. However, if Context API is new to you, we'll go over it briefly and show some demos before we moving on to using Context with Hooks. You cannot useContext without first having a Context being provided in your application. I'd also like to show you a StackBlitz demo that will serve as a starting point for the code we will work with. It picks up where we left off with exploring state and effects.

A good example for using Context is a profile component. Think about some of the information that might be displayed on a profile. When I'm logged into xyz.com, I have a cloud of data that needs to be available to all or some of a profile component's child components. We can assume this profile component needs two components: <user> and <team>. One of these two components will display my user name and image, the other will display my team—at my company, we have people on a React, Angular and Vue team, so we could use the frameworks as team names. Back to the code, we can pass the data needed (as an object) into a <provider> component through it's value attribute. We could let any component and its child components share this data.

Let's take a look at how to approach this component by simply passing props through components, which is definitely an option in the pre-Context API era. We propagate our data down through each component in the component tree "prop drilling." Inputs into each component allow passing and passing on state from the outside world through to every single component and it's child components.

Prop Drilling visual

Let's see a code demo of this pre-context era example.

If an application has 10 components, each of which have their own tree of components that in turn have their own tree of components, would you rather manually pass props around to components that may or may not need the data? Or would you rather just consume that data from any point within a component tree? Context allows this sharing of values between components without having to explicitly pass a prop through every level of the tree. Let's try to visualize how the Context API by itself can be applied to class-based components:

Context API visual

Let's also see a working example of that in StackBlitz!

A Primer on Context API

So as the last part of understanding the basic React Hooks, we simply need to understand this: Just how we were able to access state using useState and just how we were able to access a alternative life-cycle pattern with useEffect. We now need to be able to consume a provider using a hook called useContext.

In the Context API demo above we definitely saw a way to share data through many components. But it involved one pattern that always felt a bit clunky to me and really did not help in minimizing the amount of code we needed to write. Going from our simple prop drilling example to a much more maintainable Context API example, we ended up with some code that, while it is a better solution to our problem, really clutters up our components. Let's look at what I'm talking about:

Context API code example

Each and every place I want to consume the context, I have to wrap these ProfileContext.Consumer tags around the DOM elements that I want to consume that provider. It would be nice to just create a const in that functional component with a hook to use the Profile Context. These consumer containers have always looked weird to me. Hooks can make this better.

useContext code example

This is already much nicer to look at. It doesn't feel clunky—in fact, it makes me feel like we actually made the code more readable. This is one example of how Hooks will change the way that we write normal, everyday components.

This calls for an updated StackBlitz example. Let's see our Profile component now using Hooks. Not much to explain—you can see that when we hooked into state using useState, we had two values that we needed to understand that one was the actual state, the other a method to update the state. With useEffect, there are tricks you need to understand like cleanup and the fact that it replaces multiple life-cycle methods. With useContext, we just point it at an existing context and that property now holds a reference to that context. It's that simple.

Look Ma, No Provider

In the demo above, we are introduced to useContext and since we are only reading the data inside of the context, we have passed the object/data directly into the createContext() method of the Context API. This is completely valid and in fact, we don't have to wrap the <Provider> component around the profile component. This is not how I want to leave it though—I actually do want to create that provider, because in order to be able to change the team and assign a different team, I need to create a Provider and, in it's state object, we can assign a function that will run and setState on our team property inside the state object. This change will trigger an update to the state and flow down to the consuming component.

In some cases, we will need to have the ability to update the state. For instance, I want to be able to change the Team that our user is affiliated with.

For this scenario, we will again create a <Provider> and not just passing in a default context state when using createContext

Updating State From a Provider

I want to revisit our Context API example and update it to be able to use setState to update one of our properties. We should be able to update the Team value by calling a function that we will put inside our state as a key value pair.

Let's ensure that the user can initiate a change in Team simply by pressing a button with the name of the team you would like to switch to. We want the change to happen from within the User component, but we also want the buttons to show up at the bottom of the Profile view.

updated profile visual with buttons

With the addition of the buttons, we will need each one to handle a click and pass the proper team framework type to the function, which will take an argument ie. name of team: Vue, Angular or React.

example code for buttons

We will need a function that can handle changing the state, we will make a new property on our state named toggleTeam, it's value will be the actual function which calls setState. We will call this method through the context.

State with added function to change team

Now we can change the Team value as well as read from the context. This pattern does both the setup and subscribing for us.

change team buttons visually working example

I have provided another StackBlitz demo that enhances the original Context API example. Remember, this code below is not using Hooks, we will see next how to do that.

Next, we will look at another example. This one has a similar setup for the buttons and their handler to change Teams. In fact, there is no difference between the button syntax and the state object in this Hooks version. A big benefit of using hooks is that we can omit the usage of <ProfileContext.Consumer> tags wrapped around everything that we want to be able to consume. It added unwelcomed HTML in our component. We simply crate a const in each functional component:

const context = useContext(ProfileContext);

And we just call the context and it's methods as we did before.

I'd like to show you one more example that takes our current profile component and refactors the Change Team buttons into their own component and converts the Context API Provider to be functional and it's this.state to implement useState instead. Like I noted in the last example, we also got rid of the <xxxprovider.consumer> tags and now everywhere we are going with useContext. All of your code is now functional components as well</xxxprovider.consumer>


Wrap Up

I hope that these interactive examples allow you to understand the basics of using React Hooks for Context. If you are new to React, we have more content here on the Telerik blog specifically around All Things React, which contains a plethora of information about React and its ecosystem. Please explore our articles and products and let me know if you have any questions or ideas for articles on subjects relating to React.

Thanks for taking the time to read about React Hooks—below is additional information around the topic that you can find online!

Early Documentation and Articles on Hooks:

React Docs on Hooks
Making Sense of React Hooks
Understanding Hooks in React a Deep Dive
A Simple Intor into Hooks
React 16.7 Hooks Tutorial
Hooked (Formiddable)
Flux Without Fuss: From Containers to Hooks

Video Resources on Hooks

React Conf 2018 Day One Talks 
Share Complex Logic across React Components with Custom Hooks 
Access and Modify a DOM Node with the React useRef and useEffect Hooks 
Share Logic Across Multiple React Components with Custom Hooks 
Use the useState React Hook Test React Components that use React Hooks 
React Hooks a Complete Introduction 
TODO List with Hooks


KendoReact: Creating Robust React Applications

$
0
0
In this second post of the Getting Started with KendoReact series, Eric Bishard helps you better understand KendoReact so you can build more robust applications. See what KendoReact can do for you, the React developer!

Back to the First Post of the series.

Pt 2. Creating Robust Applications with KendoReact

The first thing that we're going to do today is use create-react-app. Then, we'll locate the components we're going to use from the KendoReact site, and install them using node package manager.

We will also install the Kendo default theme.
KendoReact Default Theme

We first build out the project using create-react-app. If you are new to Create React App, check out this article to learn more. Otherwise, let's open our terminal and globally install it (if needed):

npm install create-react-app -g

Once installed we can run create-react-app anytime we want, let's do just that.

create-react-app kendo-react

We'll mostly be working in the src directory. Remember you can always refer to the ;KendoReact documentation to get more information about all the components. For this project we'll be working with Buttons, DropDowns, NumericTextBox and Grid components.

First, let's just install the buttons. We see that in the Buttons documentation that we have an Installation section that let's us know how to get started. We just need to install the Buttons library with npm by running:

npm install @progress/kendo-react-buttons

That will save the package to the project's package.json and all Kendo packages follow this same naming convention:

npm install @progress/kendo-react-<componennt-name>

Now lets install the rest of the packages we need: DropDowns, NumericTextBoxes and also the internationalization package, which is required for globalization features in KendoReact components.

npm install @progress/kendo-react-grid @progress/kendo-data-query @progress/kendo-react-inputs @progress/kendo-react-intl @progress/kendo-react-dropdowns @progress/kendo-react-dateinputs @progress/kendo-react-pdf @progress/kendo-drawing

Now we can go ahead and talk about the theme. In order to get some nice, modern styling, we need to install one of these themes. For this project, we actually won't be doing any customization in CSS, we'll solely rely on the styling from the theme. If you do want to customize, you can use the Progress Theme Builder. This builder lets you customize your theme for any Kendo UI component library. You can use Material, Bootstrap or your own custom settings using those themes as a starting point.

For today, we are actually just going to install the default theme. All we are going to do is run:

npm install @progress/kendo-theme-default

This package is now added to your package.json and also resides in your node_modules directory and we can include it in React with a simple import. Next, we import the theme CSS into our App.js page:

import '@progress/kendo-theme-default/dist/all.css';

Before getting started on the Kendo components, you can delete the contents of App.css, the logo.svg and its import statement at the top of the App.js file. While we're editing the App.js file, let's replace the HTML (JSX) with the following:

<div> <h1>KendoReact Grid</h1> </div>


Stay tuned for the upcoming third post of the series—it's not live quite yet, but you'll be able to find it soon!

Kendo UI TreeView Performance Optimizations Coming Soon

$
0
0

Performance is key to success, which is why we are constantly improving the performance of all of our UI components. This blog takes a look at some of the improvements made to one of our most popular UI components: the TreeView. 

Developers have always been obsessed by performance. What's behind this obsession?

Short answer: Fast interactions and user experiences are key to the product's success. Kendo UI users are building out products that need to be successful, so our UI components need to have the performance to match. This is why we are also obsessed with improving the performance of all of our UI components, especially the ones that deal with lots of data. For this particular blog, post we want to focus on one of our most popular UI components: the TreeView. When it comes to Kendo UI TreeView performance, there are a few things that we should measure and take in to consideration, namely:

  • Loading time
  • Expand and Collapse operations
  • Change check state of nodes
  • Script time to re-initialize TreeView on dataSource filter

The goal of this blog post is to show you what optimizations have been made and what else could be done to enhance your experience with the Kendo UI TreeView.

What Kind of Feedback Have We Received?

Receiving reports for slow performance always ring a bell to developers. Whether it is from team members or through end-users, it seems we can always make something faster. We always have a theoretical maximum that can be achieved within a browser, and sometimes it ends up being a bit of an uphill battle against slowness and issues from various browsers. That being said, the overall scripting time of web components must always be evaluated. Just to give some insight, here are a few things that were reported to us by users dealing with the TreeView in their day-to-day:

  • "DataSource filtering takes a long time to refresh TreeView"
  • "Expand/Collapse operation for larger set of nodes is slow"
  • "Check node with checkChildren option enabled is slow for 10,000 nodes"

Performance Changes Coming in R1 2019

We started analyzing and researching how to get better performance with our Kendo UI TreeView. We revised the client-side scripting time for all TreeView operations and took a deep, hard look at the component. This helped us identify a couple of bottlenecks in our code, which are prime areas for improving performance.

So, what did we do to get rid of these bottlenecks?

Code Refactoring

As with almost any code base, looking back at how something is implemented with years of experience under your belt can lead to seeing new ways of tackling old problems. As we were pouring through our own code, we found several areas that we could refactor. Without getting in to nitty gritty details, we were able to optimize sections of our existing code that helped with some initial performance gain.

Optimizing Selectors and Function Calls

Going through the code, we found functions that were repeatedly called for a certain operation. A quick win was reducing the overall number of times these functions were called. Knowing what we know today about the TreeView and implementations our customers have of this component we found several areas for optimization of our code that ultimately improved the code quality of the component.  We also had a hunch around the CSS selectors that we used internally and ran several CSS selector efficiency tests. Thanks to this we found areas where we could tweak how we do CSS selectors, including removing occurrences where we used pseudo classes in our selectors.

While these may seem minor up front, all of these items combined gives us quite the performance improvement, even with smaller data sets. Expanding this to thousands of nodes gave us a dramatic performance boost!

Implement Caching

An area we realized took a lot of time was traversing through the data items found within any node that has children. Going through and doing something like a filter on the underlying dataSource could take quite a lot of time, which is only made worse when dealing with large data sets. We realized that we could implement a method of caching to improve performance here. The current implementation uses a cached dictionary of dataItems for getting their fields to avoid heavy traversing of the dataSource. This means that scripting time for loading, filtering and expanding nodes ends up greatly benefiting.

Let's Measure!

The above is just a high level of what has been done. For more precise results and actual data to review, we used local data to test the scripting time of the widget. Below, we will measure the time for Expand operation and the time for Filtering operation.

The code used for testing can be found here.

 

Expand

In this sample, the Kendo UI TreeView is configured to show 100 nodes, each containing 100 nodes (10,000 nodes end up being created when all items are expanded).

Pic1 

Filter

The Kendo UI TreeView is configured to show 10,000 nodes and dataSource is filtered to show 2,000 nodes.

Kendo UI 

 

What Else Could You Do to Improve the UX with Kendo UI TreeView?

Everything that has been mentioned in this article are performance gains that can be taken advantage of simply by updating to R1 2019 once it is released. However, there are several ways that a TreeView can be optimized through its implementation and using the available configuration options. Here are some of our recommended options that have been proven to help improve performance across most scenarios today.

  • Use LoadOnDemand true when possible
    Nodes will be lazily initialized, and initialization time will be significantly improved
  • Set valid hasChildren field
    Avoid hard-coding hasChildren field to true.
  • [Expand/Collapse] Disable animation setting before expanding
    treeview.setOptions({ animation: false });
    //expand logic
    treeview.setOptions({ animation: kendo.ui.TreeView.fn.options.animation });
  • [Expand/Collapse] Consequential expand of nodes
  • Display loading icon prior to operation
    To enhance the UX, the user should be aware that a request is being processed:
    kendo.ui.progress(treeview.element.find("[role=tree]"), true);
    //expand/filter logic
    kendo.ui.progress(treeview.element.find("[role=tree]"), false);

Get Ready for Our Enhanced TreeView

All of the above samples were with local data and covered a few common scenarios. Of course, performance depends on the levels of hierarchy and other implementation details so while performance increases are coming across the board, exactly what kind of performance gains you will experience comes down to implementation. The R1 2019 release is just around the corner, so we’re excited to see everyone test and measure these optimizations within their applications. We’ll be informing everyone about the release as we get closer, so start getting excited and keep your eyes out for further announcements!

Animating Performantly in CSS

$
0
0
Learn how to improve animation performance in CSS with a holiday-themed example from Alyssa.

I found this lovely animation online and cleaned it up a bit for a Secret Santa app me and my husband worked on for the holidays. However, we had to comment out the animation and Christmas tree because it was causing our older MacBook laptop to crash. Not that my newest MacBook fared much better, the fans sounded like we were prepping to go into outer space when the animation ran for more than a few minutes.

repeating gif of our snow falling animation in front of a rectangular blocky green christmas tree

The animation, a Christmas tree and snow drawing, are obviously not performant—so much so that we can’t even use them. I wanted to go over the different options we have. Do we even have other options? Can we even animate without crashing browsers in this world of 2018?

The answer is, of course, yes. It simply takes some awareness rather than a haphazard slapping around of animations.

Here is the starting StackBlitz.

The Problem

If we check out the performance panel in our devtools for Chrome, we see bottlenecks in our load time! You're probably asking (in your best enraged angry developer voice), “What could cause this?!” Well, turns out our animations are no bueno. With CSS in modern browsers, you really only have four options when it comes to animating with no problems. As the great Lewis and Irish say in their article, “High performance animations”:

Modern browsers can animate four things really cheaply: position, scale, rotation and opacity.
screenshot showing our non-optimal animations in the chrome devtools performance panel

I slowed the CPU down six-fold to attempt to simulate a chugging MacBook (I would have put it lower if I could have). This particular bottleneck is taking 94.85 ms. Yes, that is just milliseconds, however, if we take longer than 16 ms to render a frame, the people will notice. In terms of frames per second, users like to have at least 60 FPS. When our tree first loads with the “bad” animation, we are getting a horrifying 10 FPS:

performance panel showing a horrifying 10fps

At some points though, like in our bottlenecks above, we are getting 0 - 1 FPS. This is pretty unacceptable, even with the GPU performing at six times slower. All of our tests will be ran at 6x slower, even our final performant code, to compare evenly.

The Solution

As I briefly mentioned before, when it comes to animating cheaply in modern browsers today, we really only have four options.

Modern browsers can animate four things really cheaply: position, scale, rotation and opacity. — Paul Lewis& Paul Irish

Right now, we are animating the snow down the screen with background-position.

// tree.scss

animation: snowing 40s linear infinite forwards;
@keyframes snowing {
  100% {
    background-position: 0px ($size - 4px), 0 ($size - 4px), 0px ($size - 4px), 0px ($size - 4px);
  }
}
Note: They skipped the 0% or beginning part of the keyframe. It will be assumed the starting or default position of the snow.

 

screenshot of site explaining why background positioning is not an optimal choice to use when animating

If you are ever pondering “exactly how good/bad is this CSS change on my browser,” check out CSS triggers to find out. (This is where the above image is from.) So we know that animating background position is not optimal. Our next obvious choice is to replace this with a transform translate. Translate allows you to move DOM elements on their X and Y axis.

// tree.scss

animation: snowing 40s linear infinite forwards;
@keyframes snowing {
  0% {
    transform: translate(0,-$size);
  }
  100% {
    transform: translate(40px, calc(#{$size} - 30%));
  }
}

Our snowing keyframe has two simple steps. The first one starts the snow off at 0 on the X axis and -$size on the Y. Currently we have the size set to 400px. So the snow will start 400px above where it would originally be.

two side-by-side screenshots showing the difference between the snow with translate 0,0 and the snow with translate 0, -size

Note: The border-radius and overflow-hidden have been commented out for these screenshots, to better demo where the snow is.

The end of our animation:

transform: translate(40px, calc(#{$size} - 30%));

The last and final step is telling the snow to end 40px to the right and 30% less than the full size of the .christmas scene down. We are setting it at 30% less than the full height in order to match the highest snowflake:

screenshot of snow being drawn with different background images and radial gradients on the :before element

I’ve sped up the animation here to show you the loop we just created:

gif of our snow animation looping

Apologies for the seemingly “chunky” GIF, check out this specific StackBlitz to see the sped up snow live.

Performance Check

Before

screenshot of performance panel before any changes were made to our animation

After

screenshot of performance panel after we updated the animation

Now as you can tell by the two different screenshots, before and after our animation change, our cleaned up version is an improvement. Not only are our frames per second higher overall, but our CPU usage is MUCH lower overall. This is because we don't need to run a costly background image animation the ENTIRE LIFE of the web page.

There is still a lot that we could clean up, however. We are still using unsavory things like gradients and background images to draw our tree and snow. Be sure to check out my next post (coming soon) for optimizing your drawings in CSS to see how we achieved these sick benchmarks! WOOHOO, look how low THAT CPU usage is! Hot dog!

screenshot of performance panel after the animations and drawings have been optimized

I hope you’ve enjoyed this post, just in time for the holiday season! I’ll see you in the next post to optimize your drawings! Until then, happy coding everyone.

React Summit Lagos 2018

$
0
0
React Summit is a global event that brings frontend developers using React/JavaScript together to discuss the latest and greatest from the framework. In this blog, Christian Nwamba gives his rundown of React Summit Lagos 2018.

Audience cheering at React Summit 2018

React Summit is a global community-driven event aimed at bringing together frontend developers who use React/JavaScript or are hoping to learn more about it. The conference fosters deep, valuable discussions around what’s new, what’s possible and best practices with React.

On October 20, 2018, The Nigerian React Summit event was held at the Havilah Event Center, Yaba Lagos. It saw a large number of developers coming through to learn, network and share insights on all things React.

The event was organized by the Facebook Dev Circles group and chaired by Innocent Amadi, who made tremendous efforts to see that the best speakers were available to deliver amazing sessions.

 

Sessions

Innocent started the event with a brief description of the React Summit goals and potentials for React developers. He opened the stage with an amazing session on The Evolution of React JS. Moving on, he introduced the first speaker Shedrack Akintayo, who spoke on Optimizing Your Use of React LifeCycles—When, Why, How.

After the first speaker, we had a brief question-and-answer session before the moderator introduced the next speaker, Timi Aiyemo. Timi is a Senior Software Consultant at Andela. He loves application development and opportunities to share ideas with others. He recently facilitated four weeks of React workshops and found himself drawn to the struggles of the beginnings.

Timi’s session focused on the top 10 things React newbies should always remember when starting the journey. His session highlighted Serverless React.

Abati Adewale, also known as Ace, delivered a session on leveraging the capabilities of the create-react-app CLI tool for building React applications. Adewale is a web developer and advocate at Ingressive. He is passionate about open source, the web and basketball. He also runs a YouTube channel where he documents his journey through tech and a host of other interesting things. Feel free to check him out on YouTube.

His session covered why you should make create-react-app your best friend and go-to boilerplate for building React apps. He touched on the various reasons why should you use it in production and gave many more tips surrounding the boilerplate.

Another amazing speaker who graced the pulpit was Kesiena Akpobome. He is Technical Team Lead at Andela and a self-proclaimed software architect. He delivered a session on why and how developers can build React applications with TypeScript.

We had Miguel Jimenez come on stage as he shared insights on Metro—a tool built by Facebook for writing React Native applications. Miguel is a Senior Software Engineer at Facebook and is currently working with the JS Foundation team. Before, Miguel was at New Relic for over a year, and before that at Spotify for three years. With these teams, he has consistently built products that optimize for performance, speed, ease of use and memory utilization.

Miguel joined us in person from Facebook’s office in the UK to lead the keynote on Metro. He took us through what makes Metro unique and what to expect from it during the upcoming months.

Finally, we had the amazing Kent C Dodds speaking remotely on Advanced React Patterns. Kent works at PayPal as a full-stack JavaScript Engineer. He represents PayPal on the TC39 (Ecma International, Technical Committee 39). He’s actively involved in the open-source community as a creator and contributor. He is also an Egghead.io instructor, Frontend Masters instructor and Google Developer Expert, among many other things he does in the React and general JavaScript ecosystem. His session covered all you need to know to fall in love with React.

At this point we had a lunch break to re-energize the audience and keep everyone spirited. Oh by the way, we had Jollof Rice . This provided us the chance to hear from the community managers from Andela, Babajide Duroshola and William Imoh, who spoke about the opportunities in Andela and how the best developers can join their pool of developers to further enhance their skills.

Coming back from the lunch break, we had the amazing international speaker and author Christian Nwamba (I guess this is me). I’m a JavaScript evangelist and developer advocate with great love for everything JavaScript and performance. I spoke about responsive images for the web and how responsiveness is not just about media width but also optimization.

After my session, Fiyinfoluwa Adebayo took the stage to introduce developers to the awesome features of Electron. He is a Senior Software Engineer at Andela and Happy Money. He is also a Product Designer at Kompilab. He currently leads a team to extend the functionality of a self-service portal and integrate their microservices architecture with a Salesforce solution to enable servicing of more applications per customer.

Fiyin is an advocate for using the right tools to build products that users understand and love. UI/UX and cars are favorite topics he loves to discuss over cake and coffee. His session focused on understanding Electron and how we can use React to build cross platform desktop apps while working through an example.

After Iyin’s session, we had Temi Lajumoke take the stage and deliver a session on Serverless React. Temi is a Senior Software Engineer at Coursera & Andela.

Next we had Robert John Thas take the stage and deliver a workshop on consuming pre-trained ML models on the Google Cloud Platform. Robert is a Data Engineer, certified Machine Learning Engineer at EnterFive, and a Google Developer Expert.

Robert’s workshop focuses on guiding developers through consuming pre-trained ML models on the Google Cloud Platform. The solution will take an image, read the text in the image and translate it into Hausa, Igbo and Yoruba. This serves to show participants how to implement localization in their React and React-Native Applications.

Sponsors

The event wouldn’t have been possible without the help of our amazing sponsors:

Facebook

Developer Circles from Facebook is a great way for developers to connect and collaborate. Each Circle is locally organized by members of the community.

Andela

Andela helps companies quickly and confidently scale their software teams with world-class, full-time developers.

VanHack

VanHack is a community of over 180,000 software developers, designers and digital marketers who are ready to relocate. 90% of all jobs posted on VanHack get a qualified candidate in less than 24 hours.

TechMeetupsNG

TechMeetupsNG has been set up to create a network of tech communities around Nigeria.

Conclusion

The event was an overall success. We had technical glitches and projector disappointments, but these didn’t deter the spirit of the event in any way. Speakers delivered amazing sessions, the audience was booming and the environment was remarkable. We had fun, we learned from the best and we shared ideas and insights to help better our React development skills.

Moving On

In 2019, we plan to have more known React Experts come over physically. We also hope to better involve local engineering teams who are using React JS or any other frontend framework that could benefit from the principles discussed.

The goal is to work together with other similar conferences to strengthen the ecosystem and, by doing so, call global attention to Nigeria’s engineering talent and credibility.




For more info on building apps with React:  Check out our All Things React page that has a great collection of info and pointers to React information—with hot topics and up-to-date info ranging from getting started to creating a compelling UI.

KendoReact: Adding a Grid, Dropdown List and More

$
0
0
Welcome back to our Getting Started with KendoReact series! In the third entry in this series, Eric Bishard shows off how to use some of our most popular KendoReact components in a React application. See what KendoReact can do for you, the React developer!

Back to the second post of the series.

Pt 3. Adding Grid, Dropdown List and More

I want to address the components that we're planning to use in this project. First of all, we're going to be making a place where users can add a healthy goal and and add a value for the number of iterations for the healthy habit. Kind of like a to-do list, but with a number of times to complete, for the number of times we add that we want to do this task, we will get a radio button rendered for us to check.

Then, we will be creating a grid that contains nutritional information about fruits and vegetables, which we will later work on filtering in different ways. Let's get started with the forms and components needed for the to-do list. We will first be playing with the Grid, DropDowns, NumericTextBox and Buttons.

Documentation for Each Component

Grid, DropDowns, NumericTextBox, Button

Let's import the components into our pages. First, we'll add the grid and it's associated components inside of our App.js file. The DropDownList, NumericTextBox, Grid andGridColumn. By scoping out the documentation, it's apparent I will need the following import statements.

import { DropDownList } from '@progress/kendo-react-dropdowns'; import { NumericTextBox } from '@progress/kendo-react-inputs'; import { Button } from '@progress/kendo-react-buttons'; import { Grid, GridColumn } from '@progress/kendo-react-grid';

Now that we have the imports we need, let's also get some data (nutritional information) to feed our Grid, the json with that data can be found here: nutrition.json, copy that code into a file named nutrition.json, and add that to our src directory.

Copying from a GitHub file can be tricky. Visit the nutrition.json GitHublink above and hit the edit icon on the page. This will create a fork of the file and open it in edit mode, this is the best way to copy the large amount of code inside without getting additional formatting we don't need.

After adding the nutrition.json file, we need to import it into our App.js file.

import nutrition from './nutrition.json';

Next we add a constructor, giving us a place to assign our nutrition data to a property on our project's state along with some options for our drop-down. The constructor goes right above the render function in our App class:

constructor(props) {
  super(props)
  this.state = {
    data: nutrition,
    habitsOptions: [
      'Drink 1 cup of water',
      '1 Hour of Coding',
      '10 pushups',
      'Eat Your Fruits and veggies',
      '1 hour of Reading',
      '10 minutes of Meditation',
    ]
  }
}

Now let’s update our HTML in preparation for our nutritional information grid:

<div className="App" >
  <h1>Healthy Things</h1>
  <div className='healthy-habits'>
  </div>
  <div className='add-habits'>
    <DropDownList data={this.state.habitsOptions} />
    <NumericTextBox />
    <Button>Add Habit</Button>
  </div>
  <div className='nutrition-grid'>
    <Grid data={this.state.data}>
      <GridColumn field='Description' title='Food' />
      <GridColumn field='Measure' title='Amount' />
      <GridColumn field='Protein(g)Per Measure' title='Protein' />
      <GridColumn field='Carbohydrate, by difference(g)Per Measure' title='Carbs' />
      <GridColumn field='Sugars, total(g)Per Measure' title='Sugars' />
    </Grid>
  </div>
</div>

Let's also add a bit of padding to our App class, go into our App.css and add make sure the only CSS we have in that file for now is the CSS below:

.App {
  padding: 1em;
  text-align: center;
}
.healthy-habits ul {
  list-style-type: none;
}

Now we should have a dropdown, numeric textbox and an "Add Habit" button above our grid that is now populated with our nutrition data. Also take note how our data is mapped to each GridColumn using the field attribute.

Things are coming along, so let's take a look at what we have so far..

Grid Version One


Stay tuned for the upcoming fourth Post of the series—it's not live quite yet, but you'll be able to find it soon!

Drawing Performantly in CSS

$
0
0

In the last blog, we showed you how to improve animation performance in CSS with a holiday-themed example. Now, we're going back to tackle the drawing aspect as well!

I found this lovely animation online and cleaned it up a bit for a Secret Santa app that me and my husband worked on for the holidays. However, we had to comment out the animation and Christmas tree because it was causing our older MacBook laptop to crash. Not that my newest MacBook fared much better, the fans sounded like we were prepping to go into outer space when the animation ran for more than a few minutes.

repeating gif of our snow falling animation in front of a rectangular blocky green christmas tree

Part of our paint problem was the way we were animating the falling snow. I wrote this article to cover “Animating Performantly in CSS,” where we reanimate these things in a healthier way. I also thought this article would be too much of a monster if I taught both drawing AND animating, so check that first part out. Here was the starting StackBlitz.

To summarize, though, instead of animating the background-position of the snow, we used transform translate to move the snow down the screen. If you can ever animate something using a transform or opacity change, DO IT.

Modern browsers can animate four things really cheaply: position, scale, rotation and opacity. — Paul Lewis& Paul Irish

After modifying the animation, we noticed performance improvements. Specifically, the warnings in our performance panel went away! Hurray! However, we still have a painting problem. Here is a perhaps too detailed look at the performance behind the scenes:

Note: For better legibility, some of our screenshots have DevTools is undocked to a separate window.

performance panel showing non-optimized code with higher CPU

I slowed the CPU down 6x to to simulate a chugging MacBook (I would have put it lower if I could have). Note: All of our tests will be ran at 6x slower CPU, even our final performant code, to compare evenly.

As Paul Lewis explained in his article “Simplify Paint Complexity and Reduce Paint Areas”:

Paint is the process of filling in pixels that eventually get composited to the users' screens. It is often the longest-running of all tasks in the pipeline, and one to avoid if at all possible.

It might not seem like that much painting, but if you scrub through the timeline, you’ll see that every frame has painting of some kind:

gif scrubbing through frames of “bad” drawing in css

Whereas after we optimize this bad boy, we'll see only an idle CPU in our future frames:

gif scrubbing through frames of “good” drawing in css

So what did we optimize? Well, let’s take a look at how the tree and snow are being drawn right now.

So, the tree is being drawn as multiple linear gradients on the .christmas background image:

background-image:
  // top
  linear-gradient($gradient-angel, darken($leaf-color,0%) 8%, transparent 8.5%),
  linear-gradient(-$gradient-angel, darken($leaf-color,1.5%) 8%, transparent 8.5%),
  // middle
  linear-gradient($gradient-angel, darken($leaf-color,3%) 10%, transparent 10.5%),
  linear-gradient(-$gradient-angel, darken($leaf-color,4.5%) 10%, transparent 10.5%),
  // bottom
  linear-gradient($gradient-angel, darken($leaf-color,6%) 12%, transparent 12.5%),
  linear-gradient(-$gradient-angel, darken($leaf-color,7.5%) 12%, transparent 12.5%),
  // trunk
  linear-gradient(80deg, darken($trunk-color,0%) 5%,  transparent 5.5%),
  linear-gradient(-80deg, darken($trunk-color,1.5%) 5%, transparent 5.5%);
background-position:
  // leaves-top
  $size/2 $size/2.5, $size/2 $size/2.5,
  // leaves-middle
  $size/2 $size/1.8, $size/2 $size/1.8,
  // leaves-bottom
  $size/2 $size/1.4, $size/2 $size/1.4,
  // trunk
  $size/2 $size/1.25, $size/2 $size/1.25;

We’ll start by removing any and all tree styles from christmas.scss. Then, create a file called tree.scss that we will be sure and import in the styles.scss.

screenshot of our styles.scss file

O Tannenbaum, How Lovely Are Your Positioned Branches

I know drawing/positioning/animating in CSS can be scary at times, so let’s go slow and take it one step at a time. Here is the structure for the tree:

<div class="christmas">
  <div class="tree">
    <div class="leaves top"></div>
    <div class="leaves middle"></div>
    <div class="leaves bottom"></div>
    <div class="trunk"></div>
  </div>
</div>

First we need to position our parent .tree so the leaves and trunk can be positioned.

Position: absolute; Position based on nearest non-static positioned parent (out of the page flow)
// tree.scss

$tree-height: $size / 2;
.tree {
  top: calc(50% - #{$tree-height / 2});
  left: 50%;
  position: absolute;
  width: 0;
  height: $tree-height;
}

We are setting the top of .tree to 50% of .christmas (minus half the $tree-height). The left of .tree is at 50% (the middle).

position: absolute;

We are giving the tree position absolute (rather than position fixed like .christmas) because we want the tree and its children to always be positioned in the middle of .christmas. Right now .christmas is position fixed, however, if we wanted to change that and move it about the page, we would need .tree to be position absolute, to stay inside .christmas.

We’ll want to position the leaves and trunk based off the center position of christmas, so we gave it width of 0. If you comment that out, you’ll notice nothing changes, Chrome is guessing the width this .tree should be. But whenever you are positioning children based of a parents exact location, you don’t want to leave the width (or height) up to chance and the browsers interpretation. The height should be, logically, as tall as the tree: height: $tree-height;.

I’ll go ahead and give .tree a border so you can see where it is at on the screen:

screenshot of tree class with red border around as an outline

This is exactly where we need .tree to be, we are ready to start drawing the leaves and trunk!

Drawing Triangles

The next step we need to tackle is drawing the triangles to make the leaves! Drawing a triangle in CSS involves a combination of width/height and using borders. Check out this killer post on CSS Tricks called “The Shapes of CSS” for more fun shapes.

If you jumped ahead and looked at the StackBlitz, you might be overwhelmed by the 75 lines of CSS we used to draw the leaves. However, once broken up into chunks, you’ll see that we are just reusing the same triangle shape over and over again:

screenshot of our tree stylesheet

$leaf-size: $tree-height / 7;
$trunk-width: $tree-height / 6;

.leaves {
  right: 50%;
  position: absolute;
  
  &::before, &::after {
    position: absolute;
    width: 0px;
    height: 0px;
    display: block;
    content: '';
    border: $leaf-size solid transparent;
  }
}

This first part here is setting the field for Christmas tree leaf success. Alone, it looks ridiculous, but we put a lot of reusable styles for all the ::before and ::after elements. Essentially, every div has a ::before and ::after that we can use to style a triangle. So the three parts of the leaves (top, middle and bottom) give us each a ::before and ::after, creating six leaves in total:

screenshot of our tree pointing out top, middle, and bottom segments

Now for the actual drawing of our triangles:

&::before {
  right: 0;
  border-right-color: $leaf-color;
  border-bottom-color: $leaf-color;
}
&::after {
  left: 0;
  border-left-color: darken($leaf-color, 1.5%);
  border-bottom-color: darken($leaf-color, 1.5%);
}

As you can see, every triangle has its width and height set to zero. We now are giving the ::before elements right and bottom borders, and the ::after elements left and bottom borders, to make the two right angles we need.

We’ll reuse these two ::before and ::after leaf shapes on the .leaves .middle and .leaves .bottom. We will just adjust the size and positioning, as well as the z-index. We also are changing the leaf color to be subtly darker as we go down the tree, to get this nice layered effect.

All we need now is a glorious trunk! For this, we are going to draw a trapezoid!

$trunk-edges: $trunk-width / 2;
.trunk {
  right: calc(50% - #{($trunk-width + ($trunk-edges * 2)) / 2});
  bottom: 0;
  z-index: 1;
  position: absolute;
  width: $trunk-width;
  height: 0;
  border-right: $trunk-edges solid transparent;
  border-bottom: $trunk-width solid $trunk-color;
  border-left: $trunk-edges solid transparent;
}

With this lovely CSS, we are using borders again to draw the desired shape. We are centering the trunk of the tree and placing it at the bottom of .christmas. Finally, we are giving it the lowest z-index, so it is behind all the leaves.


screenshot showing a pair of snowflakes by the christmas tree

Redrawing the Snow

The final step to our animation and drawing Christmas tree perfection is… THE SNOW! We need to remove the final bits of bad radial gradients inside background-image:

screenshot of old bad code

We are going to remove anything snow related from christmas.scss and create a new snow.scss file (that we imported inside our styles.scss). Now drawing spheres is surprisingly easier than drawing triangles or trapezoids. A circle is simply a square with its corners rounded to 50%.

So the goal with our HTML is to be able to add more and more elements and therefore adding more and more snow flurries to the screen. A snow flurry will consist of two pieces of snow (one smaller, one larger) and placed “randomly” in the .christmas scene.


screenshot of index.html next to the preview panel

Similar to how we used ::before and ::after pseudo elements to style two leaves on the trees, we’ll do the same for two snowflakes in a flurry. All the duplicate code will be inside .snow-flurry.

$snow-size: 5px;
.snow-flurry {
  position: absolute;
  width: 0;
  height: 0;
  z-index: 5;

  &::before, &::after {
    position: absolute;
    background-color: white;
    border-radius: 50%;
    content: '';
    box-shadow: 0 0 5px 2px white;
  }
}

The second half of these styles are drawing the round flurries for ::before and ::after. IT is also creating a blur on the edges using box-shadow. This is of course a stylistic choice and not mandatory for your flurries to fly!

As we mentioned before, the goal is to have some smaller pieces of snow and some larger. This code allows us to accomplish this with a bit of fun multiplication:

$snow-size: $snow-size * 1.8;
&::before {
  width: $snow-size;
  height: $snow-size;
}

// for smaller snow flakes
$snow-size: $snow-size * .5;
&::after {
  width: $snow-size;
  height: $snow-size;
}

Finally, we are going to take our SASS skills to the next level with this next chunk-o-code:

$flurry-groups-on-screen: 9;
@for $i from 1 through $flurry-groups-on-screen {
  &:nth-child(#{$i})::before {
    top: #{random($size)}px;
    left: #{random($size)}px;
  }
  &:nth-child(#{$i})::after {
    top: #{random($size)}px;
    left: #{random($size)}px;
  }
}

Hold onto your party hats, this really is not that complicated. First off, you’ll see the variable that I lovingly called $flurry-groups-on-screen, which, shockingly, specifies the number of flurry groups on screen. We are using this number to loop through each group and then place each ::before and ::after randomly within the $size of .christmas.

$flurry-groups-on-screen: 9;
@for $i from 1 through $flurry-groups-on-screen {
  &:nth-child(#{$i})::before {
    top: #{random($size)}px;
    left: #{random($size)}px;
  }
  &:nth-child(#{$i})::after {
    top: #{random($size)}px;
    left: #{random($size)}px;
  }
  // so the snow falls at different rates
  &:nth-child(#{$i}) {
    animation: snowing #{random(40) + 20}s linear infinite forwards; 
  }
}

Since we are already looping, I thought it would be a shame not to take advantage for a really cool effect. The final part I want to add to this chunk will call our animation (a slightly modified version from before). However, it will randomize the duration of the animation, making the snow fall at different rates! SO COOL!

Now we are ready to add back in the animation and fire this up in the browser!

$snow-size: 5px;
.snow-flurry {
  position: absolute;
  width: 0;
  height: 0;
  z-index: 5;
  
  @keyframes snowing {
    0% {
      transform: translate(0,-#{$size});
    }
    100% {
      transform: translate(40px, $size);
    }
  }
}

Our starting point for the animation starts at 0, -$size and ends at 40px, $size. It looks killer, especially with our different timings on the falling flakes of snow!

Note: I’ve adjusted the colors of some things to look a bit more pleasing.

gif of final christmas scene

Check out the final StackBlitz.

Hopefully you’ve learned a bit about making performant drawings and animations in CSS! I know it can be tricky but so rewarding if you stick to it! We have (of course!) ended with lower CPU usage and MUCH less painting—we can even run this animation now in our Secret Santa app!

screenshot of performance panel after the animations and drawings have been optimized

If this wasn’t enough animation for you and Angular happens to be your thing too, I’d encourage you to check out this post I wrote about custom animations in Angular. As always, happy coding everyone and happiest of holidays to you all!!

KendoReact: Customizing Components

$
0
0
Welcome back to our Getting Started with KendoReact series! In the fourth entry in this series, Eric Bishard illustrates how to customize the KendoReact Grid component in a React application. See what KendoReact can do for you, the React developer!

Back to the third post of the series.

Pt 4. Customizing KendoReact Components

The first thing that we're going to look into is the NumericTextBox. We do have a DropdownList first, but we already added the data for that list already.

Our NumericTextBox is not looking exactly how we want it to. Out of the box, there is no restriction on what numbers can be used, including negative numbers and decimals. We can't eat a negative amount of fruit and vegetables. As many times as I want to only halfway do my tasks, we don't want the value to be a decimal. This value will become a set of radio buttons for each habit that we create, so this value needs to be a whole number.

The first thing we need to do is formatting. To set the format to not allow decimals, we set a prop input ( format ) to 0. There are other formats to choose from. For instance, you can add C to format the input as currency. 0 is all we need.

<NumericTextBox format="0"/>

In the documentation for the NumericTextBox, there are all the different format types that you can explore. There's also an API that you can go through and check all the ways you can customize this input.

Next, we need to set min to zero so that our users cannot input any negative numbers, and just for the heck of it, we'll also set max to 22.

<NumericTextBox
  format='0'
  min={0}
  max={22}
/>

Now that we have the NumericTextBox set up, let's run the app. With the built-in keyboard navigation, we can raise or lower the amount with the arrow keys so long as the number is between 1 and 22.

Next, we want to be able to click the add button and create a new habit. In order to make this work, we will need to add event listeners to our inputs and button to call handlers that will update our application, in turn creating a list of healthy habits.

Before we do that, let's add some information to our state: habitName, habitId, habitIteration and an array of habits. Our state object needs to be updated as follows:

this.state = {
   data: nutrition,
   habitId: 0,
   habitName: '',
   habitIteration: 0,
   habits: [],
   habitsOptions: [
     'Drink 1 cup of water',
     '1 Hour of Coding',
     '10 pushups',
     'Eat Your Fruits and veggies',
     '1 hour of Reading',
     '10 minutes of Meditation',
   ]
 }

So we added a habitName with an empty string (intentionally left blank), and a habitId set to 0. We're using this to set a key that we need for every list item. Then we added a habitIteration with an initial state of zero. Finally, we add a habits field initializing as an empty array.

Remember, we are just prototyping. Understand that keeping all of our state inside the App.js file and updating state manually is definitely not something you want to do in a scalable production app, but my intention is to teach you the Kendo controls, not build a solid production web application. Just remember that in a real-world web app, you would want to incorporate a state management strategy and/or make our application modular by breaking the UI and logic up into many services, containers and presentational components.

Next, onto our handler functions. We will make a handleNameChange function, which takes the event from DropDownList as an argument. When this function is triggered we setState() to change our habit name. We'll set it to event.target.value . We're going to be doing the same with handleIterationChange(). Copy the code for the handlers below into your App.js file just underneath the constructor.

handleNameChange = (event) => {
  this.setState({ habitName: event.target.value })
}
handleIterationChange = (event) => {
  this.setState({ habitIteration: event.target.value })
}

Now that we have the handler functions for our event listeners, we can add the change listener to the dropdown list, and numeric text box as well the onClick event that will capture our form submission to add a habit. I also want to add a primary class to the button to make it pop on the page a little more (setting primary={true}). With these changes, anytime there's a change in the inputs, it should be immediately reflected in the state, which in turn will update our component. Let's update the inputs and button with these changes:

<DropDownList
  data={this.state.habitsOptions}
  value={this.state.habitName}
  onChange={this.handleNameChange} />
<NumericTextBox
  format='0'
  min={0}
  max={22}
  value={this.state.habitIteration}
  onChange={this.handleIterationChange} />
<Button primary={true}>
  Add Habit
</Button>

We will also need a list of habits to add to as well as a handler for the button onClick event. Let's add an event listener to our button right after we implement a handleAddHabit() handler function.

handleAddHabit = (event) => {
  this.setState({
    habits: this.state.habits.concat([{
      key: this.state.habitId,
      name: this.state.habitName,
      iterations: this.state.habitIteration
    }]),
    habitId: this.habitId++
  });
}

Since we have habits as an array, the first time we add a habit, it will simply add that habit to the array, but for each subsequent operation, we will want to concatenate the new habit being added with the previous habits already existing in the array. We are also adding an iterator as habitId so that each habit will have a unique key.

We have an empty div tag at the top of our page with a heading that says "Healthy Things"—this is where we will put our list of healthy habits. Copy the code below and replace the empty contents of that div.

<ul key='all-habits'>
  {this.state.habits.map((habit) => [
    <li key={habit.key}>
      <h3>{habit.name}</h3>
      <div className='iterations-area'>
        {[...Array(habit.iterations)].map((iteration, index) => {
          return <input key={index} type='radio' />
        })}
      </div>
    </li>
  ])}
</ul>

Now we should see our list populated with the information that the user put into our inputs and a radio button for however many times they want to do that habit. This way, they can check them off as they go. Below is a preview of what you should be seeing at this point:

Add Habit Version One

The next thing we're going to do is work on making our grid not only look a little bit better, but also add some functionality by giving it the ability to filter. Since we have this never ending grid, we're going to set the height by adding the code below to the Grid tag. We save that, and now we no longer have the crazy long grid.

<Grid data={this.state.data} style={{ maxHeight: '500px' }}>

Now we'll be adding the filtering for our grid. If you recall, in the section where we installed the Grid and related dependencies, one of the packages we installed was a data query module. We installed this module for the specific purpose of filtering our data in our grid. You see, I was thinking ahead for ya! Like I said, it's already available to us through the kendo-data-query package, let's import it!

import { filterBy } from '@progress/kendo-data-query';

With that in place, we can create a constant right above our state initialization in the constructor. This will serve as an initial filter (default state of the filter), upon our application loading for the first time:

const initialFilter = {
  logic: 'and',
  filters: [{
    field: 'Description', 
    operator: 'contains',
    value: 'Apple'
  }]
};

Everything we have setup in this initialFilter is something the user will have control over when they are interacting with our grid. The API, and more importantly examples for this, can be found on the Data Query Overview. But in short, we are specifying our logic to be and as opposed to or. field, (the data item field to which the filter operator is applied) will be Description (our first column in the grid), and our operator for comparison will be contains where the description value is "Apple".

While we are dabbling in the constructor, we also need to change the state.data assignment to come from a function that takes initialFilter as an argument returning a data set where initialFilter has already been applied to it. After making that change, our state object will look like this:

this.state = {
  data: this.getNutrition(initialFilter),
  filter: initialFilter,
  habitId: 0,
  habitName: '',
  habitIteration: 0,
  habits: [],
  habitsOptions: [
    'Drink 1 cup of water',
    '1 Hour of Coding',
    '10 pushups',
    'Eat Your Fruits and veggies',
    '1 hour of Reading',
    '10 minutes of Meditation',
  ]
}

Considering we have introduced a new function that we have not yet created, let's do that now.

getNutrition = (filter)  => filterBy(nutrition, filter);

That is enough to get the initial state of the grid working, but we also want the grid itself to be filterable through user interactions. To get this working, let's skip down to the actual <Grid> component in our JSX and set a few more things up. Update the <Grid> start tag to the following:

<Grid data={this.state.data} style={{maxheight: '500px'}}
  filterable={true} filter={this.state.filter}
  onFilterChange={this.handleFilterChange}>

Here we have set filterable to true enabling filtering for the component, filter which will point to state.filter , and we will also need a handler for the change event filterChange . Let's go ahead and set that up because after adding the code above, we now have an error.

handleFilterChange = (event) => {
  this.setState({
    data: this.getNutrition(event.filter),
    filter: event.filter
  });
}

So if we take a look at our application, we now have a grid that has filter functionality. For instance, if we change Apple in our editable filter to Orange, we will see that change take effect immediately in our grid filtering on food descriptions that contain the word Orange.


Continue to the fifth post of the series—it's not live quite yet, but you'll be able to find it soon!

From Responsive to Progressive: Making TripXpert a Progressive Web App

$
0
0

PWAs enable you to take an existing web app and offer it as a native mobile experience. In this blog, we showcase how to do so using our sample travel app, TripXpert.

It's hard to escape all the hype around Progressive Web Apps (PWAs). Everyone involved with the web is excited about the prospect of being able to take their existing web applications and offer them in a more native way on mobile devices. While many of you may have taken a look at what they are and have a good idea of what the characteristics of a PWA might be, what you may not know is that we have a couple of PWA examples using Kendo UI components.

Today, I wanted to dive into one of these applications, TripXpert, which we have showcased as a responsive web app for quite some time. Why bring this up in a PWA conversation? Well, recently the team took time to make TripXpert a full-blown PWA and I wanted to highlight just how we went about adding in this extra functionality.

Wait a Second, What is a PWA?

In case you haven't yet heard about Progressive Web Apps I'll get you caught up in just a paragraph or two.

The quick and dirty around PWAs is that they are responsive web applications that can take advantage of mobile devices' native features. You might initially say that this is close to Cordova and hybrid applications of old, but the main difference is that there is no need to run the application in a shell, or offer plugins or wrappers for native functionality. A PWA is a regular web app that we browse to with our desktop and mobile devices today. We just sprinkle in some extra capabilities on mobile devices when a user opts to add them to the home screen, which is done through the browser rather than the various app stores.

I should mention that beyond just adding native mobile functionality to an app, a PWA is also an optimized application that is reliable and can load instantly even under slow or no internet connections. It is also fast and can provide a native-like experience (responds quickly to interactions, has smooth animations and is devoid of "jank"). Finally, a PWA should also be engaging, which means that it should feel like a natural app on the mobile device—including all of the UX that comes with that mindset. So, it's not quite as easy as just adding in a new setting and getting a PWA, you have to make sure that you're properly optimized to be a PWA. The end result is good for you either way though, as not only are you getting further engagement in your application thanks to mobile users, you also end up having a faster application, which is very important for today's web apps.

Google has a great PWA page that covers everything at a high level, and also provides in-depth links and more resources to explore. It covers what I mentioned above and way more, plus has tools like Lighthouse to help with building and optimizing your PWA, so definitely check it out!

Actually, What is "TripXpert"?

Let me also introduce the application that we'll be talking about throughout this article: TripXpert. Essentially, TripXpert is built to mimic a tourism website that allows you to book complete vacation packages to various locations across the globe. What I like about this scenario is that it gives us a lot of real-world examples to deal with, like displaying a list of packages, creating an enticing layout for each package, providing a detail view that can incorporate our data visualization components and maps, and a few other things. Additionally, from a mobile perspective, users could be looking at potential trips while on the go, making this a great scenario to start taking advantage of device features and create a great PWA.


tripxpert-in-action

TripXpert was built with ASP.NET MVC and the Telerik UI for ASP.NET MVC components. The great thing about these components is that they are built on top of the jQuery edition of the Kendo UI components, so anything I mention in this article can be applied to jQuery, ASP.NET MVC, and ASP.NET Core (also based on our jQuery widgets)!

Here's a full list of the components we used:

  • DropDownList
  • MaskedTextBox
  • Window
  • Button
  • Map
  • Dialog
  • Menu
  • ListView
  • Calendar
  • TabStrip
  • ComboBox
  • ResponsivePanel
  • Kendo UI Validator

At first, this application was meant to showcase the great-looking UI components that we have (just a straight up brag, I know, but I'm biased :wink:), along with putting them together in a larger sample, but it also took on a vital role of showcasing how to build a responsive web app using our UI components. The Kendo UI components are all responsive out of the box, which means that outside of some design choices we've made for the look-and-feel of the app itself, any kind of responsive design approaches will fully work with our components.

Now, to make this a PWA, there are a couple of things that we need to do on top of the responsive features, but I'll get to that a little bit later. First, let's cover what we did around responsiveness.

Making Things Responsive

To make sure that we follow patterns that you might be using today, we started off with adding in Bootstrap v4.1.1. While we do not use it 100% across all of our responsive features (some of that is driven by custom CSS we implemented or classes available in the Kendo UI themes) you'll see plenty of inclusions of the Boostrap spacing utilities sprinkled throughout the HTML. This helps us ensure that things appear in the right places depending on the viewport that we have available, which is very important as the real estate of the application changes—we don't want elements to either appear squished next to each other or weirdly stacked when we resize the browser (especially when we use a mobile device).

Bootstrap isn't the only thing we used though. There's also some work done coming from the Kendo UI jQuery components and our integration with Bootstrap that we can take advantage of to make things truly responsive.

While I can't go through exactly every piece of responsiveness (that would be an article in its own), I can provide a couple of highlights.

Looking over the search area, we can see that we have different views of search depending on our view port.

Desktop


tripxpert-search-desktop

Mobile


tripxpert-search-mobile

As we can see, we drop a lot of extra "fluff" around searches when we get down to a smaller screen size. You can still select the filters that we have in the beginning based on interactions with the search input, but from a real estate perspective, we cut down quite a bit.

This is all handled by working with Bootstrap to set up some rules around when to display a certain element, having worked with the Bootstrap Display Utilities to decide at what size we should hide these inputs. Then, from a Kendo UI component perspective, we simply define that we want the element to have width:100% like we do here:

 

@(Html.Kendo().DropDownList()
    .Name("OfferType")
    .OptionLabel("Offer type")
    .DataTextField("Text")
    .DataValueField("Value")
    .BindTo(new List<SelectListItem>() {
        new SelectListItem() { Text = "All types", Value = "All" },
        new SelectListItem() { Text = "Special offers", Value = "Special" },
        new SelectListItem() { Text = "Regular offers", Value = "Regular" }
    })
    .HtmlAttributes(new { style = "width:100%;", @class = "tx-offertype" })
    .Height(150)
    .Events(x=> x.Change("onOfferTypeChange"))
)

Notice the .HtmlAttributes configuration option above—this is more or less all we need for Kendo UI to adhere to whatever rules we set up with Bootstrap!

The above is just an extract of what we've done to add responsiveness to TripXpert. There's plenty of more responsive features built in (check out how the ListView goes from multiple columns down to a single column on mobile devices) but I want to jump over to what has been done

Let's Make a PWA!

Now, just making a website responsive is really just the first step. How do we take something like TripXpert and make it a full-blown PWA? Well, there are a few things that we have to do on a technical level to "PWA-ify" our application. From a UI perspective (the app has to follow UX guidelines for PWAs afterall), we're luckily covered due to a few reasons, one being the usage of the Kendo UI CSS classes that we can pull out from our themes. Having built-in responsiveness from the Kendo UI components helps out quite a bit as well of course!

Let's take a look at the two things that immediately stick out to take this application from responsive to progressive.

Adding the manifest.json

 

The manifest.json file describes what your application is and how it should behave when a user installs the application to their home screen. Browsers can read this file and get a quick rundown of what to expect from your app. This file is required in order tor browsers like Chrome to provide the "Add to Home Screen" option for your application (which we will see in action later). For a more thorough explanation of what the manifest.json file is, please refer to Google's Web Fundamentals guide around The Web App Manifest.

For reference, here's what we specifically did for TripXpert and its manifest.json file:

 

{
  "name": "TripXpert",
  "short_name": "TripXpert",
  "theme_color": "#858585",
  "background_color": "#858585",
  "display": "standalone",
  "Scope": "./",
  "lang": "en",
  "description": "The ultimate trip planning app!",
  "start_url": "./",
  "icons": [
    {
      "src": "/Images/App/Icons/HomeScreen/homescreen-icons_144X144.png",
      "sizes": "144x144",
      "type": "image/png"
    },
    {
      "src": "/Images/App/Icons/HomeScreen/homescreen-icons_180X180.png",
      "sizes": "180x180",
      "type": "image/png"
    },
    {
      "src": "/Images/App/Icons/HomeScreen/homescreen-icons_192X192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "/Images/App/Icons/HomeScreen/homescreen-icons_512X512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ],
  "splash_pages": null,
  "screenshots": [
    {
      "src": "/Images/Gallery/France/Eiffel-Tower_Attraction.jpg",
      "sizes": "320x320",
      "type": "image/jpeg"
    },
    {
      "src": "/Images/Gallery/Italy/Roman-Colosseum_Lilia-Karakoleva.jpg",
      "sizes": "320x320",
      "type": "image/jpeg"
    }
  ]
}


What we see here is the name of the application, TripXpert, along with the icons that we would like to have associated with the application depending on the size that the device offers. We also set up things like ensuring that the application always starts on ./, even if the user saved the application to their desktop when navigating a particular vacation package, and we also define that it should run as a standalone application so it runs in its own window, rather than in the standard browser UI. This helps us make the user experience feel even closer to a native app.

Hard Labor with Service Workers

 

Beyond just describing how our application should behave when installed, we want to take advantage of some actual native functionality. This includes potentially working with the application offline, syncing data in the background, push notifications and much more! The key to this is service workers and they are what make PWAs bridge the gap between web and native functionality.

For the scope of this article, a service worker is written in JavaScript and the browser runs it in the background, separate from your web application. It cannot access the DOM directly, so you have to handle communication between the service worker and your business logic. A service worker also terminates itself when its not used, and starts up again when it is used, so you can't use service workers themselves to maintain state and data.

For more information on service workers (there's a ton to look in to!), I recommend Google's Service Workers: an Introduction article, which does a great job of diving in to what service workers are and how to start using them in your applications.

The service worker file for TripXpert is a bit long, so rather than pasting it here, I'll link directly to service-worker.js right here.

What you'll notice initially is a variable that we set up to hold files that we want to be cached:

var cachedFiles = [
    path,
    path + "bundles/css?v=9bf_1hN1hPPO3xXNTcN-zh4IFDRFrfVrnaYTdddcBHQ1",
    path + "bundles/js?v=3NJpYh6kMRRulVfyFMXyChUMveyhk6-RqaWX_5pxkQY1",
    path + 'Images/App/TripXpert_logo.svg',
    path + 'Home/GetDestinations',
    path + 'Home/GetSpecialDestinations',
    path + 'Destinations/Destinations_First',
    path + 'Images/Gallery/Barcelona-and-Tenerife/Arc-de-Triomf,-Barcelona,-Spain_Liliya-Karakoleva.JPG?width=320&height=320',
    [...]


This part, especially the first couple of lines, is important to ensure that we keep all of the functionality of our application intact when we install our application to a mobile device. This variable provides all of the paths to JavaScript files that we need to use in our application, and then transitions into pages, images and other files that we need to have in our application.

We use this when the install event of the service worker triggers (when we actually install the application to a device) to actually cache all of the files provided in the cachedFiles array.


self.addEventListener('install', function (e) {
    e.waitUntil(
        caches.open(cacheName).then(function (cache) {
            Promise.all(
                cachedFiles.map(function (url) { cache.add(url) })
            );
        })
    );
});


Now, once we've installed and set up our cached files, we will actually have to handle what happens when requests are made within the application. A service worker will start receiving fetch events when a user navigates to a different page or refreshes a particular page. This is our chance to check if we have something available in the cache, or if we need to retrieve something outside of the application. If it is a resource that we have available locally, let's not waste time and bandwidth by trying to retrieve it from a server somewhere!

I won't go in to a full rundown of what each line means here, but for reference the way we handle this in TripXpert is the following.

self.addEventListener('fetch', function (e) {
    if ((e.request.url.indexOf("kendo") === -1 && e.request.url.indexOf("TripXpert") === -1) ||
        e.request.url.indexOf("t.eloqua") !== -1 ||
        e.request.url.indexOf("d.company") !== -1 ||
        e.request.url.indexOf("facebook") !== -1 ||
        e.request.url.indexOf("google") !== -1 ||
        e.request.url.indexOf("outbrain") !== -1 ||
        e.request.url.indexOf("twitter") !== -1 ||
        e.request.url.indexOf("linkedin") !== -1 ||
        e.request.url.indexOf("Destination") !== -1
    ) {
        return;
    }
 
    e.respondWith(
        caches.match(e.request.url).then(function (resp) {
            return resp || fetch(e.request.url).then(function (response) {
                var clonedResponse = response.clone();
                 
                if (response.redirected) {
                    return new Response(response.body);
                }
 
                caches.open(cacheName).then(function (cache) {
                    cache.put(e.request.url, clonedResponse);
                });
                return response;
            });
        }).catch(function () {
            return caches.match('/');
        })
    );
});


With all of the above, we have the fundamentals of a PWA. Our application can now be installed, it will look like a native application (no browser UI getting in the way), have its own set of icons on various home screens and will work offline without any missing functionality! We aren't adding push notifications or anything like that in this iteration, but this gives us a good baseline for an initial PWA that we can of course expand upon to make even more native-like!

The Proof is in the Pudding

Let's see what this looks like on my mobile device!


tripxpert-mobile-gif

As we can see, on this Android device, Chrome offers me the ability to save this app to my phone's home screen. Now, you'll notice that I get a generic icon rather than this beautiful icon which seems to be due to my custom launcher. For any of you trying this on your own devices, you should be able to see the TripXpert icon instead.

Once I open up the application, we can see that there really isn't a way to tell that this is not a regular mobile application. There is no browser UI bar at the bottom, or any kind of search bar at the top, so from a user's perspective, we've created something that looks great on their device and they access it just like they would any other installed app they picked up from the App Store or Google Play.

The Most Important Bit: Source Code

I've been linking to the actual TripXpert application so far, but what about the source code? It is found right here on GitHub and will give you even further insight on how we set things up (server-side code included)! This is a great way to gain more insight in to just how we created this lovely little application.

Pssst—We Have Other PWAs!

By the way, TripXpert is not the only sample that we have that covers how to build a Progressive Web Application! If you're interested in seeing how this can be done in Angular or React, then I have some great news for you: we have sample PWAs built for these frameworks as well! Check them our right here:

Final Notes

While this blog post didn't take you step-by-step through building TripXpert, it hopefully gave you some ideas and guidance around how you can potentially take your own applications and make them into a PWA. There might be a few steps here, including making your app actually responsive, but once you've got a great layout and user experience for mobile devices, it is only natural to start adding in some more features to make the experience that much better for mobile users! Go forth and PWA!

How to Use a jQuery Progress Bar UI Component in Your Web App

$
0
0

Progress bars are vital components in many modern apps. Learn about the various use cases of progress bars and how to make them for your apps with Kendo UI.

A progress bar is used to show the length of a process. Anytime the end user is required to wait for an action to complete, like a page loading, you should communicate to them where they are in the process. A visual like a progress bar provides a distraction so that the perceived wait time is shorter. A progress bar can also be used to show values other than process length like the amount of health a player has in a game.

In this blog, we will review the `ProgressBar` component. You'll learn how to create different types of progress bars using the Kendo UI `ProgressBar` and the various use cases for each.

Value Progress Bar 

A progress bar has two parts: a track and an indicator. The track represents the maximum value of the process, while the indicator is the current value of the bar. A Kendo UI `ProgressBar` of type `value` displays the progress status as a number inside the track. This is the default progress bar when the `type` parameter is not defined in the component. The `value` parameter determines the length of the indicator. If the `min` and `max` options have not been set, the minimum value of the progress bar will be 0 and the maximum value will be 100. When the `min` and `max` options have been specified, the value will be reflected on the progress bar as a proportion of the maximum value. This is an example of a default progress bar:

 

progressbar01 

 

 
<!DOCTYPE html>
 
<html>
 
  <head>
 
    <metacharset="utf-8">
    <title>Progress Bar</title>
    <scriptsrc="https://code.jquery.com/jquery-1.12.3.min.js"></script>
 
    <style>
      body {font-family: helvetica;}
    </style>
 
  </head>
 
  <body>
 
    <divid="progress"></div></br></br>
 
    <script>
            $(document).ready(function(){
                $('#progress').kendoProgressBar({
                    value: 5,
                     min: 0,
                     max: 10
                  });
 
               });
    </script>
 
  </body>
 
</html>
 

                                                                                                                                             

Percent Progress Bar 

A percentage-based progress bar behaves similarly to a value type progress bar except the progress status text is displayed as a percentage. This kind of progress is ideal when you are able to calculate the length of the process and update the progress until it finishes.

For example, a percent progress bar can be used to show the percentage of content that has been downloaded or the percentage a video that has been loaded. You may want to also use the progress to show statistics like the results of a poll. This is an example of a percent progress bar at 25%:


progressbar1b

 

 
$('#progress').kendoProgressBar({
 
  type: 'percent',
  value: 25
 
});
  

 

If no `min` and `max` are specified, the value will be interpreted as a percentage from 0 to 100. If there is a `min` and `max`, the percent will be calculated by dividing the value by the maximum value. For example, if the `value` is 5, the `min` is 0, and the `max` is 20 the progress bar will show 25%. If the `min` is not 0, then the difference between the `min` and `max` will be used to calculate the percentage.

 

Chunk Progress Bar

A chunk progress bar is divided into sections or chunks. This can be used when you want to indicate the length of a process by the number of steps it takes to complete.

An example use case is when users are submitting a multi-part form. In a checkout form, one step can be entering shipping info, another step entering payment info and the last step can be reviewing the order before it is submitted. This is an example of a progress bar that has two out of three sections filled in:

 

progressbar02 

 

 
$('#progress').kendoProgressBar({
 
  type: 'chunk',
  chunkCount: 3,
  value: 2,
  min: 0,
  max: 3
 
});
 

 

The `chunkCount` along with the `min` and `max` options must be set to display the value in the progress bar.  The `chunkCount` is the number of sections in the progress. The `max` here should correspond to the `chunkCount`. If the `chunkCount` is equal to 5, then the min should be 0 and the max should be 5. The value of the progress bar can be anything from 0-5, where 0 means there are no sections filled in and 5 means the bar is completely filled.

Indeterminate Progress Bar 

A progress bar can either be determinate or indeterminate. A determinate progress bar has a specified process length. All of the progress bar types we have discussed so far have been determinate. An indeterminate progress bar has an unspecified length. It is used when the process length is unknown or its exact value isn’t important to show. In this state, the indicator will display a continuously running animation that travels the length of the track. To create an indeterminate progress bar you set the `value` property to `false`.

 

progressbar03 

 

 
$('#progress').kendoProgressBar({
 
  value: false
 
});
  

 

Specifying a `type`, `min` or `max` is not necessary to initialize this kind of progress bar. However, you may want to initialize your progress with these values if you expect to switch from an indeterminate to a determinate state. To do this you can set the value of the progress using the value method. This example shows the progress set to 75% immediately after it has been created:

 

 

var progress = $('#progress').kendoProgressBar({

  value: false,

  type: 'percent'

}).data('kendoProgressBar');

 

progress.value(75);

 

 

Conclusion

In this lesson, you learned how to create a value progress bar, a percent progress bar and a chunk progress bar. You also saw an example of an indeterminate progress bar which has no value.

In addition to the features described, the Kendo UI `ProgressBar` provides other options to customize the appearance of the component. The style of the indicator can be changed using the progressWrapper field. You can change the position of the text in the progress bar or hide it altogether with the `reverse` and `showStatus` options respectively. If you want to change what the text says, you can use the progressStatus field.

In the next episode, you will take a look at the `Slider` component. A slider lets you make a selection from a range of values.

 

Try out Kendo UI for Yourself

Want to start taking advantage of the more than 70+ ready-made Kendo UI components, like the Grid or Scheduler? You can begin a free trial of Kendo UI today and start developing your apps faster.

Start My Kendo UI Trial

Angular, React, and Vue Versions

Looking for UI component to support specific frameworks? Check out Kendo UI for Angular, Kendo UI for React, or Kendo UI for Vue.

Resources

Designing Custom Themes with the Progress Sass ThemeBuilder

$
0
0

Quickly and easily create the perfect theme for your app and apply it across all of the cool UI libraries from Progress with Sass ThemeBuilder. Grids, charts, pickers, even buttons—all fixed at once! Let’s take a look.

Colors matter. Just ask your marketing department. Sure, you want your apps to look awesome, and part of that means that the color design you use needs to be awesome.  But you also want to keep your product designers from chasing you down the street screaming, “Those are not our brand colors!” It’s just embarrassing for everyone.

Maybe more importantly, you do at least want to make your app look like your other apps so it appears that they came from a single company. And unless you are deliberately trying to trick your customers, you want buttons for major functions to have the same colors they did in your last app. It’s just not cool to have the “enter” button in one app be blue and then in your next app have the “permanently delete all my data” button be blue. Because doing that will also make your UX person’s head explode, which can be messy. 

But… oh gosh… does that mean you really have to go in and manually tweak colors in CSS for each of your UI components? That doesn’t sound like much fun either. But before you start to think that maybe it’s okay if just one UX designer’s head does explode, there’s an easy answer. You just need a tool to help you tweak the design colors for your components all at once. A tool that let’s you pick from popular design themes or tweak your own. A tool that shows you right away exactly what your UI will look like with the new colors. A tool that will let you save your customer themes and edit them later.

If only there was such a tool…

Enter Progress Sass ThemeBuilder

Well, such a tool does exist or else this would be a really short blog. It’s the ThemeBuilder from Progress. And it’s not just a mere CSS theme builder—it’s a Sass theme builder for all of the Kendo UI components. Sass, if you aren’t’ familiar with it, is like “CSS with Superpowers” (their words) and is an extension to CSS that is completely compatible with CSS. Using Sass lets us use variables in our styles and makes it easy to propagate values across a whole library. And I hope you all appreciate that I stayed away from any one of the many jokes about the name “Sass”—you’re welcome!

The Sass ThemeBuilder let’s you quickly and easily create the perfect theme for your app and apply it across all of the cool Kendo UI, Telerik and other UI libraries from Progress. Grids, charts, pickers, even buttons—all fixed at once. Let’s take a look…

To get started, just go to the online utility at:

https://themebuilder.telerik.com/

The first thing you see is a list of products libraries that you can create a theme for, ranging from Angular and React to ASP.NET and PHP. Because each library has unique characteristics, the way to set each theme is slightly different.

ThemeBuilder 

 

If you click on a product (and here I selected “Kendo UI,” which is the basic JavaScript version) you get two choices—start a new theme or import an existing customized one.

ThemeBuilder 

 

The new theme option is obvious but why would you want to import an existing customized theme? This is actually useful in a number of scenarios.

First of all, you might be working with a new standard and are in a cycle of creating a theme, seeing how it looks and maybe doing some user testing, and tweaking the theme. Rather than starting from scratch each time you can just import the theme you developed in your last iteration and tweak that. Or you might have to come back months later and make some changes to reflect new theme standards. Or you might even find some color after a while that you forgot to set. Or that someone else forgot to set, more likely, because of course *you* would never make a mistake like that.

Click on “Start Theming” and you have one more choice to make before getting started—picking the base theme to use as a starting point!

 

ThemeBuilder 

 

There are three options:

  • Our own default theme (which is shown here and uses whites, reds and greys)
  • Bootstrap (based on the Bootstrap 4 theme, which uses whites and blues—my personal favorite)
  • Material (based on Google’s Material guidelines, which uses a white/red/blue/grey mix)
Of course you can change everything but this gives you a place to start that is close to a lot of color themes in popular use. Select one (like Bootstrap, because blue is the best color) and click “Create.”

Now we get to the cool part!

We are now in the tool and we have several options. The first thing we see is a panel on the right-hand side of the screen that shows us a whole bunch of components: menus, buttons, pickers, grids, charts, editors, etc. Notice that you can scroll down this list and see that there are a *lot* of components instantiated here. This is so you can see exactly what the changes you make to the theme will look like across all of the components you are going to use.

 

ThemeBuilder 

 

And these are all real, live components. You can select buttons, collapse grid lines, pick dates, etc. And they all have some actual data in them so when you select a drop-down list, there are several selection options. You need all of this to see what colors are going to show up where.

“But wait,” I hear you complain. “This is too much. I’m not going to use all of these components and it’s hard to find the ones I am using in the middle of this huge library. It’s just crowded.”

And you are quite right, no one is likely going to use all of those components (and if you do, please write to me, I’m sure I can find some kind of prize for you). Which is why we let you customize the list of components that are shown. On the top right, just below the red “download” button, click on “Widgets”. This shows you a list of all the components in that library—all selected by default—and all you have to do is uncheck the ones you don’t want to use.

 

ThemeBuilder 

 

For example, let’s say I was only using the Grid, Chart, TabStrip, ButtonGroup and the DatePicker and TimePicker. If I select only those components and collapse the “widgets” screen, I now see only those five components displayed. Pretty cool, right?

 

ThemeBuilder 

 

Now that we have fixed up our environment, let’s change something! First of all, before we go poking around individual colors, we do still have more options. If we click on the top left to expand the “Color Swatches” panel, we see a bunch of color swatches that we can select. This gives us even more options for using predefined color themes.

 

ThemeBuilder 

 

Or, if we just want to tweak individual colors, we can do that one of two ways: we can just type the color code into the text box for that item, or we can open the color picker and find some color that just looks awesome.

ThemeBuilder 

 

And just as an example, below I changed the first chart color from blue to red—and we can see that in the image below, where the top line on the chart is now red.

 

 ThemeBuilder

 

When you are done, just click on “download,” which is really hard to miss because it’s a big red button. Enter a name and a location and boom—you’re ready.

 

ThemeBuilder 

 

You’ll get a ZIP file that contains two files inside of it. The first is your `.css` file, and the second is a `.scss` file that contains the session settings for your theme. This is the file you use to import into ThemeBuilder later if you want to make some changes.

ThemeBuilder 

The SCSS file (below) is fairly simple but it holds the key parameters. Rather than constantly update and tweak the CSS yourself, this SCSS file gives us a chance to save and implement the changes that we want to make through simple Sass variables. 

 

ThemeBuilder

The CSS file (below) is a bit more complicated because it contains all of the CSS parameters for the Kendo UI library, not just the colors you changed.


ThemeBuilder 

 

Okay, that’s the ThemeBuilder in a nutshell. You can go check it out yourself and take a look. It’s free, you don’t need a license, you don’t need to install anything. Just go to the webpage. Now. Right now! Don’t procrastinate, just go check it out now, and get colorful!

Check Out ThemeBuilder

KendoReact: Using Charts and React Hooks

$
0
0
Welcome back to our Getting Started with KendoReact series! In the fifth and final entry in this series, Eric Bishard illustrates how to use the Chart component from KendoReact and work with React Hooks. See what KendoReact can do for you, the React developer!

Back to the fourth post of the series.

Pt 5. KendoReact Charts and React Hooks

We are going to add a Chart directly below the the existing Grid component. The link I just gave you for the chart is a great place to get a better understanding of the different ways you can customize it. Now, when we want to add any type of chart (sprakline, pie, donut, whatever), we start by installing the Kendo Chart package and another dependency called hammerjs

npm install @progress/kendo-react-charts hammerjs

One thing I want to do here is use the latest addition to the React library (Hooks), but we'll need to update our React packages to use 16.7 Alpha. Let's install that now:

npm install react@next react-dom@next

If you ever want to get the absolute latest bits from React, that's what you should run. Also, we will now see changes in our package.json from:

"dependencies": {
    [...]
    "hammerjs": "^2.0.8",
    "react": "^16.6.0",
    "react-dom": "^16.6.0",
    "react-scripts": "2.0.5"
  }
"dependencies": {
    [...]
    "hammerjs": "^2.0.8",
    "react": "^16.7.0-alpha.0",
    "react-dom": "^16.7.0-alpha.0",
    "react-scripts": "2.0.5"
  }

React Hooks give functional components in React the ability to work with React State, perform side effects to state change and tap into React Context. We will simply be using it to manage some simple state inside a functional component. This is what we as developers have wanted from React—it solves problematic issues with Classes and setState IMHO. It also allows you to get away from classes in the majority of situations you can run into while building components. If you can get your head around Hooks, you will have much less need for classes in React.

Instead of creating another hunk of HTML and components inside the App.js page, let's import a component and move our next block of code outside of the App.js page.

In React, this is as simple as creating a file—we'll call ours PieChartContainer.js and we will put some very basic functional component structure code in there:

export default function PieChartContainer() {
  return (
    <div>
      <span>KENDO PIE CHART</span>
    </div>
  );
}

In the App.js page, let's now add an import and bring the component into the JSX:

import PieChartContainer from './PieChartContainer';
...
<PieChartContainer />

Now we can work on bringing in the few imports we need for using Hooks and Kendo Chart component. As well, we will need the HTML that will replace the placeholder div we have in place now.

Here are the imports we will need:

import React, { useState } from 'react';
import { Button } from '@progress/kendo-react-buttons';
import { Chart, ChartSeries, ChartSeriesItem } from '@progress/kendo-react-charts';
import 'hammerjs';

The first order of business inside the PieChartContainer functional component is to set up the default state and handlers for some inputs I'm going to place on the page. Each input will correspond to a state value, and we will have another state value that upon some event, we can update an array of all three pie chart series values. This object will be used eventually in our Pie Chart.

const [graphProtein, setGraphProtein] = useState(0);
const [graphCarbs, setGraphCarbs] = useState(0);
const [graphSugars, setGraphSugars] = useState(0);
const [seriesData, setSeriesData] = useState([
  graphProtein,
  graphCarbs,
  graphSugars
]);

const handleGraphProteinChange = (e) => {
  setGraphProtein(isNaN(e.target.value) ? 0 : e.target.value)
}
const handleGraphCarbsChange = (e) => {
  setGraphCarbs(isNaN(e.target.value) ? 0 : e.target.value)
}
const handleGraphSugarsChange = (e) => {
  setGraphSugars(isNaN(e.target.value) ? 0 : e.target.value)
}
const handleSeriesDataChange = (e) => {
  setSeriesData([graphProtein, graphCarbs, graphSugars])
}

We will also replace the span placeholder element on our page with the following code, which I created as a precursor to putting our chart on the page. I wanted to make sure I understood what I expected from the user and how I could take those inputs and translate them into a condensed array of each value to feed into the chart, this is just how I work things out when I'm manually prototyping:

<div>
  <p>Protein Amount: -
    <input value={graphProtein} onChange={handleGraphProteinChange} />
  </p>
  <p>Carb Amount: -
    <input value={graphCarbs} onChange={handleGraphCarbsChange} />
  </p>
  <p>Sugar Amount: -
    <input value={graphSugars} onChange={handleGraphSugarsChange} />
  </p>
  <Button primary={true} onClick={handleSeriesDataChange}>Update Pie</Button>
  <p>
    Protein Value is: {graphProtein}, 
    Carbs Value is: {graphCarbs}, 
    Sugars Value is: {graphSugars},
    Series Data is: {seriesData}
  </p>
</div>

Now let's drop in some basic code to get the chart displaying on the page, I took some code from the KendoReact Charts component example and modified to fit my needs:

<div className="food-graph">
  <Chart seriesDefaults={this.state.seriesDefaults} series={this.state.series}></Chart>
</div>

We need to pass some state into the chart. We will have a series and seriesDefault that we will bind to our properties on the state object.

I'm going to give you some more HTML to add directly above the chart and it's surrounding food-graph div and create a sibling div for food-graph-inputs. We're going to enable our users to add some numbers to three sections of our chart, each of which will be a pie chart to represent those numbers. This allows us to visualize the difference between the proteins, sugars and carbs from our grid.

<div className="food-graph-inputs">
  <p>Protein Amount: - 
    <input type="text" onChange={this.handleProteinChange} />
  </p>
  <p>Carb Amount: - 
    <input type="text" onChange={this.handleCarbChange} />
  </p>
  <p>Sugar Amount: - 
    <input type="text" onChange={this.handleSugarChange} />
  </p>
</div>

And with these changes made, we will need to update our state object to supply the default values for series, seriesDefault, graphProtein, graphCarb and graphSugar. Our state should end up looking like the object below:

this.state = {
      data: this.getNutrition(initialFilter),
      filter: initialFilter,
      habitId: 0,
      habitName: '',
      habitIteration: 0,
      habits: [],
      habitsOptions: [
        'Drink 1 cup of water',
        '1 Hour of Coding',
        '10 pushups',
        'Eat Your Fruits and veggies',
        '1 hour of Reading',
        '10 minutes of Meditation',
      ],
      series: [{data: [1,1,1]}],
      seriesDefaults: { type: 'pie'},
      graphProtein: 0,
      graphCarb: 0,
      graphSugar: 0
    }

We need a few functions to handle any changes to the protein, carb and sugar input changes, each will also need to call a handleGraphChange() function after setting their own state. Let's add those four functions now at the bottom of all of our function handlers.

// Chart Functions
  handleProteinChange = (event) => {
    this.setState({ graphProtein: event.target.value });
    this.handleGraphChange();
  }
  handleCarbChange = (event) => {
    this.setState({ graphCarb: event.target.value });
    this.handleGraphChange();
  }
  handleSugarChange = (event) => {
    this.setState({ graphSugar: event.target.value });
    this.handleGraphChange();
  }
  handleGraphChange = () => {
    this.setState({ 
      series: [{
        data: [
          this.state.graphProtein,
          this.state.graphCarb,
          this.state.graphSugar
        ]
      }]
    });
  }


End of Series!

Preserve Your Valuable UX Investment with a Simple Budget Change

$
0
0

Dean is a guest author from our partner truematter - user experience experts who help their customers achieve greater efficiency and engagement.



Let’s say you’re responsible for creating or redesigning a digital product from the ground up. You understand the value of solid user experience (UX) so you involve UX professionals early. They work with developers, designers, content strategists and stakeholders to define and design your product. Heck, the team even makes a prototype and tests it with real users. It’s all very agile. You’re doing it right.

Then it comes time for the development team to produce and ship real code. This is where things can fall apart. If you’re not careful, you might accidentally squander your UX investment as you take your product to launch.

Bon Voyage, UX

After definition and design is done, user experience resources tend to leave the project. Internal team members move on to the next thing. External consultants reach the end of their budget, declare victory and are never seen again. In any case, user experience expertise, input and oversight fades away when it is needed most.

When the UX resources leave, the work isn’t done. As the development team, project managers and business analysts move through implementation, they must make key UX, UI, frontend, design and content decisions themselves.

Amazingly, this happens in organizations that care deeply about UX. Inexplicably, it also happens with development teams ostensibly devoted to agile processes. Leaving UX experts out of the development effort is a common, critical mistake.

Things Change During Development

As an interactive app, site or software project moves through development, questions and issues inevitably arise. Functionality is more difficult to implement than anticipated, requirements must be modified, stakeholders change their mind, third-party tools present unforeseen problems. As these things change, your digital product will change as a result.

These changes will affect user interaction, some quite significantly. This is the moment you need UX experts who can deal with these new usability problems. But at this point they’ve moved on and you probably don’t have any hours left in the budget to ask them anything anyway.

Product testing also means changes as your team discovers problems and implements solutions. But, with nary a UX expert in sight, no one will test your digital product’s user experience. Invariably, you’ll miss important interface problems.

Guesswork Kills Quality

But, you may think, it’s okay. There are more than enough developers, project managers and business analysts to help with UX gray areas. Our product testers are rock solid. We’ve got this. The problem is, these people are not user experience experts.

Most developers are, to put it mildly, not adept at solving UX/UI or design problems. They’ll tell you this themselves. Managers are ready to get the project out the door. They don’t have any extra time or money. The digital product must ship. Business analysts are trained to solve problems for internal stakeholders, not for the people using your product. Testers stick to whatever the test plan says.

These folks will make the best guesses they can about user experience quality. Those guesses will not reflect user experience best practices. Your users will suffer. This why many finished digital products can be so disappointingly different from the original fancy designs and tested prototypes.

Squandering Your UX Investment

So, what happened to the promise of the brilliantly easy-to-use digital product, destined to be an outstanding, push-the-needle business tool for your company? What happened to that significant upfront user experience investment?

It died of neglect.

When it comes to UX, most organizations hold fast to three false notions:

1. It is limited. UX is something you do only at the beginning of a project.

2. It is irrelevant to development. UX work stops at planning and designing.

3. It isn’t always needed. UX has no clear project oversight role, so it’s unneeded as you careen toward launch.

None of these are correct. If all of the changes you make during development happen without UX guidance, the final product will suffer. Noticeably.

The Right Way

You will avoid squandering your UX investment by changing the way you approach user experience:

1. Recognize that UX plays a valuable role throughout your entire project. This is especially true for real-world, spur-of-the-moment decisions made during implementation.

2. Developers should not work in a vacuum. Would you allow your development team to implement a mission-critical project without check-ins with managers, business analysts or testers? Neither should you developers work without input from user experience professionals.

3. Your project needs UX oversight during testing and launch. This follow-through is the best way to protect your user experience investment.

When you change the way you approach user experience, you also have to change the way you manage your UX resources. You must create a process that ensures UX experts are available to help through the launch of your digital product.

Keep a Reserve of UX Help

Always hold back UX resources for mid- to end-of-project decisions, interactions and development needs. User experience professionals should be ready to spring into action through the end of the project.

What will UX resources do in the mid and end phases of a project? Here are just a few examples:

• Collaborate – Participate in regular project scrums, check-ins, demos and interactions with stakeholders.

• Make Interface Decisions – Help developers make interface, design and content decisions, addressing issues that inevitably arise during development.

• Champion the User – Explain to stakeholders and leadership how their mid-project ideas, changes or whims will affect users.

• Test with Users – Test functionality in progress with real end users.

• Test for Quality – Test the product’s quality with an eye for UX problems, then help developers fix them.

• Take Responsibility – Ensure the integrity of the original UX vision for the product.

Reorganize Your Wallet

Yes, keeping user experience experts engaged through the end of the project will affect your budget. You must plan for using and paying your UX resources though launch.

Depending on the size and complexity of your project, you can expect to incur an additional 20 to 30% over your initial UX budget to use for mid-to late-project UX collaboration, input and oversight. This is not a hard and fast rule, but it is a useful guideline. Let’s keep the math simple:

If you spend $10,000 on UX resources to define and design your project, expect to reserve an additional $2,000-$3,000 for follow-through during development, quality assurance testing and launch.

If you spend $100,000 on early-project user experience efforts, hold back and additional $20,000-$30,000.

And so on.

Counting the Cost

These numbers may be eye-opening and somewhat startling, but they hold true for organizations who are making high-quality, easy-to use digital products. That amazing benchmark you envy so much almost certainly planned their budget this way.

And honestly, what costs more? Doing things right the first time, or fixing business-killing problems after the fact? What’s wiser—using the right tool for the right job, or asking your plumber to do your taxes (or your accountant to fix your pipes)? Everyone knows the answers to these questions.

What Is a UX Resource?

Of course, organizations define “UX resources” differently. Some think of UX narrowly, including only information architecture, usability and user testing professionals in the mix. Others define UX more broadly, factoring in visual design, content strategy and frontend interface professionals. Stick to the reserve percentage, and your project will be well-served.

How to Manage Your New UX Reserve Budget

Try the “UX Reserve” method on your next project. You’ll notice significant advances in product quality and user satisfaction. Chances are good your overall costs will actually decrease, because you won’t be spending money on endless UI adjustments.

Internal Team Management

• Resource Availability – Schedule resources for mid to late stages of the process. Reserve specific people early so you don’t lose them later.

• Schedule the Right People – Include UX resources in all scrums, project check-ins or stakeholder demonstrations. Don’t forget to include design, content and frontend professionals.

• Test Your UX – Adjust your quality assurance testing plan to include a UX/UI review.

• Consider Phased Efforts – When projecting future project phases, always factor in a UX reserve.

Managing External Resources

• Think Ahead – Plan to hold back a part of your UX budget to spend mid and late project. If you are authoring an RFP, include this as a requirement.

• Demand a Hold Back Plan – Ensure external consultants are in sync with this plan. Demand they have a plan to hold back time for later stage involvement. Hold them to it. Solid firms will already be thinking this way.

• Break Up the UX Reserve – If you are concerned about preserving budget, consider separating your UX Reserve into two sections, implementation and testing.

General Guidelines

• Sign-Off – Ensure a UX lead signs-off on all major project deliverables. This is no different from getting the approval of developers, managers and business analysts.

• Get Team Buy-In – Make sure your existing team both understands and accepts the value of user experience focus in later stages of your project. It may be awkward at first, but your developers in particular will grow to love it. After a while, they won’t know how they ever did anything different

The UX Reserve Pays for Itself

Including user experience experts throughout your entire project life cycle may seem like a big step, but it’s one you must make if you want to build exceptional digital products. The budget hit will sting at first, but the effort will more than pay for itself through better user experience quality, fewer bugs, easier-to-use functionality, greater user efficiency and more satisfied customers.


Building with UX in Mind

One good way to help your UX efforts is to make sure that you use UI components that were designed with UX in mind, like Kendo UI. Whether you are using a Grid, Chart, Scheduler or any of the components from the extensive library. Check out Kendo UI and see for yourself.
Viewing all 5210 articles
Browse latest View live