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

How To: Capture iOS Traffic with Fiddler

$
0
0

In this step by step tutorial, learn how to setup your iOS device to use Fiddler as a proxy and capture web traffic from your phone.

Last week we learned how to capture the traffic from you Android device with Fiddler. Now, let’s see how it’s done on iOS.

Prerequisites

First you have to have Fiddler installed on your desktop machine. The PC and the iOS device should be discoverable on the same network. This was the tricky part for me, as even when I have them on the same network, they couldn’t communicate with each other. I had to use the mobile hotspot on my machine to make them discoverable.

Just ping the device IP from your machine to be sure they can communicate.

Setting up Fiddler

First, you should enable the Allow remote computers to connect setting in Fiddler

  1. Open Fiddler and select Tools -> Options
  2. Choose the Connections tab
  3. Select the Allow remote computers to connect checkbox to enable the setting.
  4. Restart Fiddler in order the changes to take effect.

Fiddler is now listening on port 8888 (this is the default port, you can change it from the setting above).

Allow remote computers to connect

Setting up the iOS Device

Once Fiddler is listening, we should use it as a proxy in iOS.

  1. Open Settings -> WiFi
  2. Find your current network and click the i icon
  3. Scroll to bottom and choose Manual on the HTTP Proxy choice
  4. Type your IP address in the Server field
  5. Type the Fiddler listening port (8888 by default) in the Port field

Configure proxy

Your device’s traffic should be visible in Fiddler.

Capture HTTPS Traffic

With the current setup you should be able to capture HTTP traffic. However, if you try to open any HTTPS website, you’ll get the This site’s security certificate is not trusted! error. To fix this, you should trust the Fiddler root certificate.

  1. In your browser, navigate to http://ipv4.fiddler:8888
  2. Click on the Fiddler root certificate link to download it
  3. Install the certificate on your device.

Now you should be able to capture HTTPS traffic too.

Cleaning Up

Once you’re done debugging, don’t forget to remove the WiFi proxy from your device.

This is all you need to know about capturing web traffic from iOS devices. If you have any questions or problems, just leave a comment below.

We always love hearing feedback, so feel free to share your thoughts on what you'd like to see with us over on our Feedback Portal. And if you're new to Fiddler, you can get started today - download Fiddler for free right here


Successful Digital Products Start With Discovery

$
0
0

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


When creating a digital product, be sure you don't skip that crucial first step: Determining the problem that needs to be solved.

You’ve decided to create a digital product. You have a great idea and business case for your new site, app, or software suite. It’s tempting to dive right in – you’re ready to get started! You look over your marketing analysis, set out a few technical requirements, and get someone from marketing to mock up how it will look. You’re almost ready to build the thing. Most teams go into development just like this. But there’s a big problem with this approach. You’ve skipped the crucial first step in creating a successful digital product: Determining the problem that needs to be solved.

The Solution Can’t Come First

If you decided to go into space and set off in the rocket the very next day with just a star map and a radio, you might have a fantastic and impressive intergalactic adventure. But it’s very unlikely you would accomplish anything, or even ever return home. How could you? You never defined a mission, let alone what it would take to complete it and get back to Earth. The same is true for digital product creators who skip the Discovery phase.

“Come to terms with the fact that you don’t know your users’ problems.”

Identify the Problem(s)

The first step in creating a successful site, app, or software suite for other people, is to come to terms with the fact that you don’t know your users’ problems. This is crucial. You know what you want them to do, but that’s not the same as understanding their tasks and issues. You don’t know what they need from you. For that, you need Discovery.

Discovery Before Strategy

For any truly successful digital product that improves business and reaches project goals, Discovery comes before anything else. Do not make any decisions about how your site, app, or software will look, what functionality it will support, or anything else until Discovery is complete.

“Don’t assume you know anything about what your digital product should do.”

Don’t Guess, Do Your Research

Discovery is where you conduct your fact finding, information gathering, and research doing. It’s where you find out what users really need from your digital product and realize your assumptions about what the thing should look like and how it should act were totally wrong. Don’t assume you know anything about what your digital product should do or how it should do it before you understand what your users need and why they need it. Your assumptions are really nothing more than guesses and almost 100% of the time they will be wrong.

By the way, this goes for any help you bring in as well. If a consulting firm gives you design, structure, or any other strategic recommendations before Discovery, they’re just guessing at your users’ problems and solutions, hoping it will work out. It won’t, and you’ll end up wasting time and money on a solution that doesn’t address the real issues.

Discovery Leads to Success

We won’t lie – Discovery is a time-intensive, thorough, painstaking process. It has to be. It’s the only way you’ll know the strategic direction your site, app, or software suite should take. It’s the only way you’ll know what your users need on all fronts: functionality, structure, content, and design. It’s the only way to make a digital product that solves the business problems it exists to solve in the first place.

Discovery will Happen Either Way

If you don’t set out to conduct an intentional, informative Discovery, it doesn’t mean Discovery won’t ever happen. It will happen on its own – you’ll learn things about your users, technical needs, timeline, and every other aspect of your project. But you’ll learn them in a haphazard, undocumented way, and you’ll often learn about them too late to do anything about it. It’s a very risky and costly way to run a project.

When you complete Discovery, you’ll be able to see what the path forward must be.

Discovery Reduces Risk

Going through a proper Discovery will lessen risk in all areas of your project: budget, timeline, requirements, meeting user needs, the list goes on. It will also bring a definition and clarity to your project that will help you stay on track strategically and create helpful and thorough requirements for your developers. When you complete Discovery, you’ll be able to see what the path forward must be and you’ll have specific user data to use against any unwanted meddling and opinionated stakeholders.

Deciding to Start with Discovery

The first step to conducting a successful Discovery is to decide to do it. You’ll need to set aside the time, resources, and planning to get it done. You’ll need to ask for stakeholders’ time and coordinate getting users together for user exercises. That all takes intention and a commitment to doing it right. But, believe it, the extra time and effort will spell out increased success for your project in the end.

As you start your Discovery, you’re going to do four things:*

  1. Talk to real users and get data from them through user research exercises.
  2. Take stock of what you have and what you need.
  3. Study the competition. (It’s amazing how many teams skip this step.)
  4. Identify and clarify your business goals.

Once you complete these things, then and only then will you be ready to talk strategy – what the product should look like, how it should function, what information it should give users. Only then are you ready to move forward creating and developing your digital product.

*Here’s a list of great resources for getting started with user exercises:

Persona creation dos and don’ts: http://blog.truematter.com/2018/dos-donts-creating-powerful-user-personas/
Why made-up personas don’t work: http://blog.truematter.com/2018/made-personas-dont-work/
How to conduct user observation: http://blog.truematter.com/2018/let-users-show-whats-not-working/
How user testing helps with design: http://blog.truematter.com/2018/user-testing-made-better-designer/
Intro to card sorting with examples: https://usabilitygeek.com/card-sorting-quick-guide-for-beginners/
How to use cards to improve your IA and content strategy: https://www.smashingmagazine.com/2014/10/improving-information-architecture-card-sorting-beginners-guide/
How to conduct different types of user interviews: https://www.interaction-design.org/literature/article/how-to-conduct-user-interviews
Intro to running a successful UX interview: http://theuxreview.co.uk/user-interviews-the-beginners-guide/
How to conduct a user-focused survey: https://uxmastery.com/better-user-research-through-surveys/
Running a successful UX survey: https://www.surveygizmo.com/survey-blog/6-tips-ux-surveys/
Think user testing is just a luxury?: http://blog.truematter.com/2018/think-user-testing-luxury-ask-airbnb/

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: Kendo UI. Get great UX 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.

Build Mobile-Friendly Web Apps with React Native Web

$
0
0

Creating a multi-platform application is even easier with React Native Web, which lets us build and deploy to the web and mobile platforms alike.

Over the years, building web applications that are mobile friendly has become easier with the advent of media queries and the introduction of service workers. Using media queries, we could make web applications become different shapes when viewed on mobile devices. Service workers, with their powerful features, present web applications with powers only native applications have been known to possess — push notifications, background sync, etc.

React Native is a multi-platform solution developed by Facebook that lets you build mobile apps using JavaScript. These mobile apps are considered multi-platform because they’re written once and deployed across many platforms, like Android, iOS and the web. Today, we’ll see how we can utilize this powerful technology to build platform-focused applications on the web.

We’ll be building a simple application that displays user information from a random API using React Native components like ScrollView, Text and Image.

Prerequisites

To follow this tutorial, you’ll need to have Node> 6.0 installed. You’ll also need a package manager NPM (this comes packaged with Node) or Yarn (follow the installation guide here).

Basic knowledge of JavaScript and React is also required. You can follow the official React tutorial here to get up to speed with React.

Getting Started

Before we get started, we’ll need to set up the project and install project dependencies. We’ll be making use of Create React App to bootstrap our application. We’re using Create React App because it can be configured to alias React Native. We’ll be installing polyfills for some of the latest JavaScript APIs like Promise, Array.from, etc., as the transpiler doesn’t provide those.

To bootstrap your application using Create React App, run the following command:

    yarn create react-app random-people
or
    npx create-react-app random-people

Run the following command to install the project’s development dependencies:

    yarn add --dev babel-plugin-module-resolver babel-plugin-transform-object-rest-spread babel-plugin-transform-react-jsx-source babel-preset-expo
or
    npminstall --save-dev babel-plugin-module-resolver babel-plugin-transform-object-rest-spread babel-plugin-transform-react-jsx-source babel-preset-expo  

The babel-plugin-module-resolver is a plugin that resolves your project modules when compiling with Babel. We’ll use this package to alias react-native to react-native-web when setting up the project config.

To build and run our application, we’ll be using Expo. Expo is an open-source toolchain built around React Native for building Android and iOS applications. It provides access to the system’s functionality like the Camera, Storage, etc.

Install the expo-cli by running the following command:

    yarn global add expo-cli
            or
    npm i g expo-cli

The next step is to install expo locally, alongside React Native and React Native Web. Run the command below to install the packages:

    yarn add expo react-native react-native-web react-art
            or
    npm i expo react-native react-native-web react-art

After downloading the packages needed to run and build the application, the next step is to setup the configuration files. Create a file called .babelrc in the root of your project and update it with the following:

//.babelrc{"presets":["babel-preset-expo"],"env":{"development":{"plugins":["transform-object-rest-spread","transform-react-jsx-source"]}},"plugins":[["module-resolver",{"alias":{"^react-native$":"react-native-web"}}]]}

Create a file named app.json. This file is used to configure parts of your application that don’t belong in the code like the application name, description, sdkVersion, etc. You can find the options available for the app.json file here.

Let’s update the package.json file to include commands for running our application on Android and iOS emulators. Also, we’ll include the main field referencing the App.js file. This file will act as the entry file for the expo-cli. Open the package.json file in a file editor of choice:

// package.json{"name":"random-people","version":"0.1.0","private":true,"main":"./App.js",..."scripts":{"start-web":"react-scripts start","build-web":"react-scripts build","test-web":"react-scripts test","eject-web":"react-scripts eject","start-native":"expo start","android":"expo android","ios":"expo ios","build:ios":"expo build:ios","build:android":"expo build:android",},...}

Run npm run start-web to run the application and visit http://localhost:3000 to view the application.

Home Component

Our application is a simple demo that displays users via the random user API. Using the API, we’ll get display a name and avatar of the returned users through some of the components provided by React Native. Within the src/ directory, create a file named home.js. Open this file using an editor and update it with the snippet below:

    //home.js
    import React from "react";
    import {
      ScrollView,
      ActivityIndicator,
      StyleSheet
    } from "react-native";
    
    class Home extends React.Component {
      state = {
        users: [],
        loading: true
      };
      componentDidMount() {
        // TODO: get users
      }
    
      render() {
        return (
          <ScrollView
            noSpacer={true}
            noScroll={true}
            style={styles.container}
          >
           <ActivityIndicator
                style={[styles.centering, styles.gray]}
                color="#ff8179"
                size="large"
/>
          </ScrollView>
        );
      }
    }
    
    var styles = StyleSheet.create({
      container: {
        backgroundColor: "whitesmoke"
      },
      centering: {
        alignItems: "center",
        justifyContent: "center",
        padding: 8,
        height: '100vh'
      },
    });
    
    export default Home;

In the snippet above, the Home component renders a [ScrollView](https://facebook.github.io/react-native/docs/scrollview) component that houses the component’s elements. Currently, the component displays an [ActivityIndicator](https://facebook.github.io/react-native/docs/activityindicator#docsNav); this will be replaced by the user list when the call to the API is complete.

We create styles for the elements using the StyleSheet component. This allows us to style the component using properties similar to CSS properties.

Let’s create a method that gets random users from the Random User API. This method will be called during the componentDidMount lifecycle. Update the home.js component to include the getUsers method:

    // home.js
    import React from 'react';
    ...
    
    class Home extends React.Component {
      state = {
        ...
      };
      componentDidMount() {
        this.getUsers();
      }
    
      async getUsers() {
        const res = await fetch("https://randomuser.me/api/?results=20");
        const { results } = await res.json();
        this.setState({ users: [...results], loading: false });
      }
      ...
    }

We can easily make requests using the native Fetch API. Results from the request are parsed and added to state. When the request is complete, we’ll hide the ActivityIncidator by setting loading to false.

App Component

The AppComponent holds the logic for the application. We’ll update the default view created by Create React App to suit that of our application by adding logic to display native components.

Create a new file named App.js in the root of your project. This file will be similar to the src/App.js file. The root App.js file will act as the entry file for expo, and the src/App.js file exists for Create React App builds. Update both files with the snippet below:

import React from'react';import{
      AppRegistry,
      StyleSheet,
      View,}from'react-native';import Home from'./home'classAppextendsReact.Component{render(){return(<View style={styles.appContainer}><Home /></View>);}}const styles = StyleSheet.create({
      appContainer:{
        flex:1,},});
    
    AppRegistry.registerComponent('App',()=> App);exportdefault App;

In the snippet above, we register our App component using the AppRegistry. The AppRegistry is the entry point of React Native applications.

Creating User Item

Each user item will be displayed using a View component. The View component is an important building block that supports layout using flexbox, styling and accessibility. The View component of each item will be within a SwipeableFlatList. Each item will display the user’s avatar, name and email. Create a file called user-item.js within the src/ folder and update it with the code below:

// user-item.jsimport React from"react";import{ View, Image, Text, StyleSheet }from"react-native";constUserItem=({ item: user })=>{return(<View style={styles.row}><Image style={styles.rowIcon} source={user.picture.medium}/><View style={styles.rowData}><Text style={styles.rowDataText}>{`${user.name.title}${
user.name.first
            }${user.name.last}`}</Text><Text style={styles.rowDataSubText}>{user.email}</Text></View></View>);};const styles = StyleSheet.create({
      row:{
        flexDirection:"row",
        justifyContent:"center",
        alignItems:"center",
        padding:15,
        marginBottom:5,
        backgroundColor:"white",
        borderBottomWidth: StyleSheet.hairlineWidth,
        borderBottomColor:"rgba(0,0,0,0.1)"},
      rowIcon:{
        width:64,
        height:64,
        marginRight:20,
        borderRadius:"50%",
        boxShadow:"0 1px 2px 0 rgba(0,0,0,0.1)"},
      rowData:{
        flex:1},
      rowDataText:{
        fontSize:15,
        textTransform:"capitalize",
        color:"#4b4b4b"},
      rowDataSubText:{
        fontSize:13,
        opacity:0.8,
        color:"#a8a689",
        marginTop:4}});exportdefault UserItem;

To display the avatar of each user, we make use of the Image component. The component takes a source prop which acts the src which we are used to on the web. The component can be styled further as we have using styles.rowIcon property.

Next, we’ll create the UserList to display each UserItem.

Creating Users List

The FlatList component is one that is performant in its list rendering methods. It lazy-loads the items within the list, and only loads more items when the user has scrolled to the bottom of the list. The SwipeableFlatList is a wrapper around the FlatList provided by React Native Web, which makes each item within the list swipeable — so each item will reveals a set of actions when swiped.

Let’s create the SwipeableFlatList for the users returned from the API. Import the SwipeableFlatList component from the react-native package and update the render function to display the list. Create a file called user-list.js and update the file with the following:

import React from"react";import{ SwipeableFlatList }from"react-native";import UserItem from"./user-item";constUserList=({ users })=>{return(<SwipeableFlatList
          data={users}
          bounceFirstRowOnMount={true}
          maxSwipeDistance={160}
          renderItem={UserItem}/>);};exportdefault UserList;
  • data: this prop represents the data that will be fed to each item within the list. The data prop is usually an array.
  • bounceFirstRowOnMount: if true, it triggers on a bounce animation on the first item in the list, signifying that it has hidden actions within.
  • maxSwipeDistance: this prop sets a maximum swipeable distance for each item.
  • Finally, the renderItem prop takes a function that renders an item; this function will be passed an item prop that contains the data to be displayed.

Let’s update the home.js file to include the new UserList. Open the /src/home.js file and update it with the following:

import React from"react";import{ ScrollView, StyleSheet, ActivityIndicator }from"react-native";import UserList from"./user-list";classHomeextendsReact.Component{
      state ={
        users:[],
        loading:true};...render(){return(<ScrollView noSpacer={true} noScroll={true} style={styles.container}>{this.state.loading ?(<ActivityIndicator
                style={[styles.centering]}
                color="#ff8179"
                size="large"/>):(<UserList users={this.state.users}/>)}</ScrollView>);}}const styles = StyleSheet.create({...});exportdefault Home;

Now if you visit http://localhost:3000 on your browser, you should see a list of users, similar to the screenshot below:

If you can’t see users listed, go through the tutorial again to see what you’ve have missed along the way.

We’re using a SwipeableFlatList component which means each user item is swipeable, so let’s add actions that you can swipe to reveal. What’s the need of a SwipeableFlatList if it doesn’t reveal anything.

Adding Actions to Item

Each item within the list will be provided a set of actions that will be revealed when swiped to the left. The actions set will use the TouchableHighlight component encompassed by the View component. The TouchableHighlight component is used when we require viewers to respond to touches, more or less acting like a button. Create a file named user-actions.js in the src/ folder. Open the file and copy the following contents into it:

import React from"react";import{
      View,
      TouchableHighlight,
      Text,
      Alert,
      StyleSheet
    }from"react-native";const styles = StyleSheet.create({
      actionsContainer:{
        flex:1,
        flexDirection:"row",
        justifyContent:"flex-end",
        alignItems:"center",
        padding:10},
      actionButton:{
        padding:10,
        color:"white",
        borderRadius:6,
        width:80,
        backgroundColor:"#808080",
        marginRight:5,
        marginLeft:5},
      actionButtonDestructive:{
        backgroundColor:"#ff4b21"},
      actionButtonText:{
        textAlign:"center"}});constUserActions=()=>{return(<View style={styles.actionsContainer}><TouchableHighlight
            style={styles.actionButton}
            onPress={()=>{
Alert.alert("Tips","You could do something with this edit action!");}}><Text style={styles.actionButtonText}>Edit</Text></TouchableHighlight><TouchableHighlight
            style={[styles.actionButton, styles.actionButtonDestructive]}
            onPress={()=>{
Alert.alert("Tips","You could do something with this remove action!");}}><Text style={styles.actionButtonText}>Remove</Text></TouchableHighlight></View>);};exportdefault UserActions;

The TouchableHighlight component takes an onPress callback that is triggered when the component is clicked. Each callback triggers an Alert display. Styles are also applied to the encompassing View component and other components on the page.

To include the actions on each user item, update the UserList component to include the renderQuickActions prop, which also takes a function.

    import React from "react";
    ...
    import UserActions from "./user-actions";
    
    const UserList = ({ users }) => {
      return (
        <SwipeableFlatList
          ...
          renderQuickActions={UserActions}
        />
      );
    };
    
    export default UserList;

Now when you swipe left on any user item it reveals two actions. It should be similar to the screenshot below:

Actions revealed on swipe

Header Component

Now that we’ve successfully fetched users and displayed them using native components, let’s liven the application by setting a header. Using the SafeAreaView component, we’ll create an area with defined boundaries. This will act as the header for our application. Create file called header.js and update it with the code below:

// src/header.jsimport React from'react';import{SafeAreaView, View, Text, StyleSheet}from'react-native';constHeader=({ onBack, title })=>(<SafeAreaView style={styles.headerContainer}><View style={styles.header}><View style={styles.headerCenter}><Text accessibilityRole="heading" aria-level="3" style={styles.title}>{title}</Text></View></View></SafeAreaView>);const styles = StyleSheet.create({
      headerContainer:{
        borderBottomWidth: StyleSheet.hairlineWidth,
        borderBottomColor:'#ff4e3f',
        backgroundColor:'#ff8179',},
      header:{
        padding:10,
        paddingVertical:5,
        alignItems:'center',
        flexDirection:'row',
        minHeight:50},
      headerCenter:{
        flex:1,
        order:2},
      headerLeft:{
        order:1,
        width:80},
      headerRight:{
        order:3,
        width:80},
      title:{
        fontSize:19,
        fontWeight:'600',
        textAlign:'center',
        color:'white'},});exportdefault Header;

Now let’s add the Header component to the App component. This will display a simple header at the top of the application. Update the App.js file to include the Header component:

import React from'react';...import Header from'./header';classAppextendsReact.Component{render(){return(<View style={styles.appContainer}><Header title="Random People"/><Home /></View>);}}const styles = StyleSheet.create({...});
    
    AppRegistry.registerComponent('App',()=> App);exportdefault App;

After the application refreshes the header will be added to the top of the application.

View after adding the header

Looks great, doesn’t it? It won’t be winning any awards, but it might win a lot of prospective react-native-web users. We’ve been able to achieve a lot of functionality after writing minimal code.

Let’s see the various methods we can use to test the application on mobile.

Testing on Mobile

To test the application on mobile, the expo-cli provides various method to test the application mobile. The first is using a URL generated after running the application. This URL can be visited on your mobile browser to test the application.

Run the npm run start-native command within your project folder to run the application using expo. Expo typically starts your application on port 19002, so visit http://localhost:19002 to view the expo dev tools. Within the dev tools you can send a link as an SMS or email to your mobile phone.

You can select any of the three connection options — an external tunnel, LAN or Local connection. For the local connection, your mobile phone and work PC have to be connected to the same network, but the tunnel works regardless.

The next option for testing on a mobile device is using a emulator. Using Android studio or Xcode, you can boot emulators for their respective platforms. Download and install the tool for the platform of choice — Xcode for iOS or Android studio for Android. After installation, run npm run android or npm run ios to start the application on any of the emulators.

Deploying the Application

We’ll be deploying our application to the Android Play store. To achieve this, we’ll need to update the app.json to include Android specific properties. Open the app.json file and update the file to include the android field:

{"expo":{"sdkVersion":"31.0.0","name":"random-people","slug":"random-people","version":"0.1.0","description":"An application for displaying random people","primaryColor":"#ff8179","android":{"package":"com.random.people"}}}

The android.package field is a unique value that will represent your package in the app store. You can read more on the package-naming convention here. After updating the file, run the npm run build:android command.

This command will present you with a prompt, asking you to provide a keystore or to generate a new one. If you have an existing keystore, you can select this option or let expo generate one for your application.

Prompt to generate keystore.

After completion, a download link will be generated for your application. Clicking on this link will trigger a download for your APK.

To deploy the downloaded APK to the Android Play Store, visit the Play Console to create an account. After creating an account, you’ll be required to pay a registration fee of $25 before proceeding. After completing the registration process, visit this page and follow the steps to upload your application to the Play Store.

Summary

Using the React Native Web and React Native libraries, we’ve been able to create an application that can be deployed on several platforms using native components. Building multi-platform applications has never been easier. You can view the source code for the demo here.


For More Info on Building Apps with React

Want to learn more about creating great user interfaces with React? Check out Kendo UI for React, our complete UI component library for React that allows you to quickly build high-quality, responsive apps. It includes all the components you’ll need, from grids and charts to schedulers and dials. Learn more about how you can get started with KendoReact.

Xamarin.Forms 3 For You and Me

$
0
0

This article dives into some exciting new features in the Xamarin.Forms 3.0 release and how developers can leverage them in Xamarin apps.

Most developers are genuinely excited by software. Modern software runs the world and developers get to shape the future. Developers often cannot wait for the next hotness to drop - for their chosen platforms and tools. Developers are known to stay on cutting edge and are eager to try out latest bits. This comes with the obvious risk of bricking computers or wasting hours getting things to work - but hey, new software is just cool. 

However, the realities of being a Professional Software Developer™️ often bring in cautiousness. Developers get wary of hot untested bits because of how easily development environments/tools can get messed up. Amidst this dilemma, comes the new Xamarin.Forms 3.0 release.

While still fairly new, Xamarin.Forms 3.0 has shown surprising maturity - existing features work while long awaited new functionality brings joy to developers. All the while Xamarin.Forms 3 release demonstrates stability, thus lowering barriers for developer adoption.

But what can Xamarin.Forms 3.x do for developers? This article takes a lap around some new features that developers should find rather useful to integrate into their Xamarin apps. You get to play around with the latest and greatest, while enjoying platform stability - what's there to lose?

Cascading Style Sheets

No way. Say it ain't so. The dark magic of CSS has found it's way into our beloved Xamarin.Forms?

Shut the front door!

Yeah, that was the initial reaction from many .NET developers. But the point is CSS styling of XAML is optional and actually works beautifully. Developers used to building for web do not need to learn anything new, as CSS in Xamarin.Forms obeys the same rules. CSS parsing is maturing and pre-processors like LESS/SASS may also be used. 

To use CSS in Xamarin.Forms, developers can simply create a file with a *.css extension and start writing normal CSS.

.importantStuff {
    font-size: 24;
    font-style: bold;
    color: #FF0000;
}

#individId {
    margin: 10 0 0 10;
}

label, button {
    background-color: #c0d6f9
}

Check that out. That CSS is specifying classes, individual element IDs, and entire types of elements. And setting property values is done the same way as in regular old CSS.

Sold on CSS and can't wait to use it? Good - this is how you'd use an individual CSS file within a XAML file in Xamarin.Forms.

<ContentPage.Resources>
    <StyleSheet Source="PATH TO CSS RELATIVE TO XAML PAGE">
</ContentPage.Resources>

<ContentPage.Content>
    <Label Text="This is important" StyleClass="importantStuff">
</ContentPage.Content>
CSSStyles
 

That example shows loading up the CSS, and then applying a class to a Label control. CSS in Xamarin.Forms is here to stay and if building for web and mobile, you can now start sharing styles. Find out more on CSS in Xamarin.Forms with the docs!

Flex Layout

This may sound suspicously like FlexBox from the web - and for good reason! Xamarin.Forms's newest layout rendering FlexLayout was actually inspired from the FlexBox Layout in CSS. So the idea behind FlexLayouts is to give the container (or the layout) many different (flexible) options to layout its children to best fill available space.

You may be thinking - awesome, show me more!

Here's the best thing about the FlexLayout - making use of all of its sweet layout options is as simple as adding controls to it and then tweaking some properties on the Layout and some attached properties (akin to how you set a control's position in a grid Grid.Row="3") on controls.

Let's take a peek at an example that combines some CSS with some FlexLayout goodness. And let's see this in action using some beautiful Pie Charts that come built-in with Telerik UI for Xamarin. Pro tip developers - you don't need to reinvent the wheel on complex UI. Telerik UI really shows off the engineering behind each control through performance and flexible APIs.

The CSS:
.chart {
    flex-basis: 25%;
    height: 100;
}

.third {
    flex-basis: 33.33%;
    height: 150;
}

.half {
    flex-basis: 50%;
    height: 200;
}

.full {
    flex-basis: 100%;
    height: 250;
}
The XAML:
<FlexLayout Direction="Row" Wrap="Wrap" AlignItems="Center" AlignContent="Start" >

    <telerikChart:RadPieChart StyleClass="chart">
        <telerikChart:RadPieChart.Palette>
            <local:OrangePalette />
        </telerikChart:RadPieChart.Palette>
        <telerikChart:RadPieChart.BindingContext>
            <local:ChartViewModel />
        </telerikChart:RadPieChart.BindingContext>
        <telerikChart:RadPieChart.Series>
            <telerikChart:PieSeries RadiusFactor="0.8"
                                    ValueBinding="Value"
                                    ItemsSource="{Binding Data}" />
        </telerikChart:RadPieChart.Series>
    </telerikChart:RadPieChart>

    <telerikChart:RadPieChart StyleClass="chart">
        <telerikChart:RadPieChart.Palette>
            <local:BrightPalette />
        </telerikChart:RadPieChart.Palette>
        <telerikChart:RadPieChart.BindingContext>
            <local:ChartViewModel />
        </telerikChart:RadPieChart.BindingContext>
        <telerikChart:RadPieChart.Series>
            <telerikChart:PieSeries RadiusFactor="0.8"
                                    ValueBinding="Value"
                                    ItemsSource="{Binding Data}" />
        </telerikChart:RadPieChart.Series>
    </telerikChart:RadPieChart>

    <telerikChart:RadPieChart StyleClass="chart, half">
        <telerikChart:RadPieChart.Palette>
            <local:DarkPalette />
        </telerikChart:RadPieChart.Palette>
        <telerikChart:RadPieChart.BindingContext>
            <local:ChartViewModel />
        </telerikChart:RadPieChart.BindingContext>
        <telerikChart:RadPieChart.Series>
            <telerikChart:PieSeries RadiusFactor="0.8"
                                    ValueBinding="Value"
                                    ItemsSource="{Binding Data}" />
        </telerikChart:RadPieChart.Series>
    </telerikChart:RadPieChart>

   ...
   ...

The XAML markup and CSS combined produce a layout like this in portrait orientation:

FlexPortrait
 

And like so in landscape orientation:

FlexLandscape
 

The FlexLayout is doing all the work of resizing and making sure everything has enough room to be displayed no matter the orientation for us - how nifty. This works on any container control no matter what be the containing children in the visual tree. And there's a whole lot more to FlexLayout too - Check out the docs for the full story.

Android Bottom Tabs

This next Xamarin.Forms 3.0 feature should be labeled - it's about time!. On Android, navigational tabs generally are on the top. But let's face it, iOS has taught us that the rightful place for tabs are at the bottom of the screen.

DroidTopNav
 

So, in Xamarin.Forms 3, we now have a way to move the tabs to the bottom of the screen, just as Steve Jobs would have wanted had he designed Android himself.

DroidBottomNav
 

Getting the tabs to be rendered at the bottom of the screen is way easier than anything else you ever had to do in Android.

var tabsPage = new Xamarin.Forms.TabbedPage();
tabsPage.On<Xamarin.Forms.PlatformConfiguration.Android>().SetToolbarPlacement(ToolbarPlacement.Bottom);

Yeah - that's it. Xamarin.Forms - making Android development tolerable since 2014 something.

Summing It All Up

So there you have it - a quick lap around some of the new and best features of Xamarin.Forms 3.

Styling XAML controls and pages using CSS is here to stay. Sure it seems a bit weird. But considering that you can use all of your hard won CSS knowledge from the web world, like selectors and cascading rules and apply it to Xamarin.Forms - it's pretty much a no-brainer to start using it. Again, it's an optional feature and developers can choose between XAML Styles or CSS.

The FlexLayoutis another nifty little rendering feature. Here is the second worthy bit of inspiration from the web world happily brought over to Xamarin.Forms. This time, add some controls to a FlexLayout layout - and let the layout do the calculations of where everything should appear on screen for you. Developers can read up on how flexible its layout options are.

Then Android bottom tabs - the mobile world as it should be.

In all, developers should definitely give Xamarin.Forms 3 a spin - it's stable and provides some exciting new features. Staying on the cutting edge has some awesome benefits - and may be you'll be so inclined to look forward to Xamarin.Forms 4.0. Onwards and to the future!

Make Your React Apps Pop with Data Visualizations

$
0
0

Spicing up your apps with data visualizations doesn't have to be hard. Here are a few ways you can get started making your apps more visually appealing and intuitive for your end users.

Many of the applications that we write end up dealing with data. Whether it is displaying, modifying, or manipulating it in some way - data is usually the core of our apps. Usually it might be enough to just display raw data on a page and let the user draw conclusions from it, but many of us are visual learners and a simple way to get people's attention is through some sort of visual medium. Enter data visualization.

There are many solutions out there to add a graphic representation of your data, but some of them can be pretty complex. There should be a way to get advanced data visualizations without advanced configuration! That's why this post was created; to spend some time to go through how adding the KendoReact data visualization components (charts and gauges) can make your application truly pop with just a few lines of code. Easy configuration for the easy win! Let's get right to it.

Installation

First, let's go ahead and make sure that we can use any of the code we find in this blog post and any documentation by running a quick npm install for a few packages. This way our project is prepped and ready to go.

npm install --save @progress/kendo-react-charts @progress/kendo-drawing @progress/kendo-react-intl hammerjs

What we've installed above is the overall kendo-react-charts package, which contains all of the KendoReact charts, the kendo-drawing framework which helps us actually render the charts (makes sense from the name, right?), the kendo-react-intl package (to help with any localization or globalization scenarios), and finally hammerjs which we have as a dependency to assist with the interactivity and events of the KendoReact charts.

Also, we shouldn't forget to install our favorite theme to work with our components! In this case we'll be using the Material theme and following the directions in this documentation article gives us a way to install the theme that is the most natural to our existing process around CSS.

With the installation taken care of, let's go ahead and check out what we can do with some of these data visualizations!

Adding our First Chart

Before actually start rendering charts on a page, let's figure out what kind of data that we may want to display. In this particular case we want to highlight daily sales for an imaginary product. Since we have seven days of the week to work with let's set up an array that looks something like this:

state = { salesPerDay: [12, 9, 13, 7, 10, 8, 12] }

Alright, let's take this excellent data and make some sort of visualization out of it!

To start we will need to import pieces of the KendoReact chart, specifically

import { Chart, ChartSeries, ChartSeriesItem, } from '@progress/kendo-react-charts';

This will put us in a good spot as we can now define a chart, as well as any number of series within said chart. The KendoReact charts support having multiple series, of the same or different types, and with these three imports here we can lay out anything we'd like for our charts in a declarative way.

The chart component can be set up in our JSX using the following:

<Chart> <ChartSeries> <ChartSeriesItem type="column" data={this.state.salesPerDay} /> </ChartSeries> </Chart>

As we can see from the above code snippet we define a <Chart>, then define that we want to have some sort of series through <ChartSeries>, with <ChartSeriesItem> being an individual series. The configuration of this series is pretty basic, so let's set our type as column (there's a ton of other types to chose from!) and pass in our data. This gives us a chart that already looks pretty good:

react
 

Maybe a column structure like this isn't the best for tracking daily sales, so with a quick modification of setting type="line" we update our chart.

kendoui

To add some more interactivity to the chart, and to make it more apparent what the value of each of our markers might be, let's go ahead and add some tool tips to the party.

The tool tip can be defined on a series-by-series basis and is defined by importing and using ChartSeriesItemTooltip. This is the defined within each ChartSeriesItem component that the tool tip should be used with.

In our case with everything updated the whole component looks like this.

import React from 'react'; import ReactDOM from 'react-dom'; import { process } from '@progress/kendo-data-query'; import { Chart, ChartSeries, ChartSeriesItem, ChartSeriesItemTooltip, } from '@progress/kendo-react-charts'; import "hammerjs"; class App extends React.Component { state = { salesPerDay: [12, 9, 13, 7, 10, 8, 12] } render() { return ( <div> <Chart> <ChartSeries> <ChartSeriesItem type="line" data={this.state.salesPerDay}> <ChartSeriesItemTooltip visible="true" /> </ChartSeriesItem> </ChartSeries> </Chart> </div> ); } } ReactDOM.render( <App />, document.querySelector('my-app') );

The way this was added in was to not have our ChartSeriesItem be self-closing and instead add in a <ChartSeriesItemTooltip>, with the visibility defined as true. There are a ton of options, including defining templates for generic HTML to be displayed, for these tool tips. Beyond just the initial display we have plenty that can be done to tweak things to your liking.

charts-tooltips

The last thing we may want to do with this is add in values to our X-axis to make sure we know what this data represents. Since we call this data salesPerDay it makes sense to try to add in some connection to the days of the week. Monday - Sunday makes a lot of sense here (sorry all "the week starts on Sunday" advocates ). We can expand our sales array entries and have them be objects with sales and day fields. This leaves us with an array of objects connected to our chart.

salesPerDay: [ { sales: 12, day: "Mon" }, { sales: 9, day: "Tues" }, { sales: 13, day: "Wed" }, { sales: 7, day: "Thurs" }, { sales: 10, day: "Fri" }, { sales: 8, day: "Sat" }, { sales: 12, day: "Sun"} ]

If we immediately look over on our page a problem that pops up now is that we don't see our data points any more. Have no fear, this is very easy to "fix" by defining which fields are tied to what in the chart with some quick binding. Specifically we can update our ChartSeriesItem to have field="sales" and "categoryField="day" props added. In the KendoReact chart we can remember that the categoryField (and axis) is generally tied to the X-axis in these cases, while the field (or value field) tends to be on the Y-axis.

With just a few lines of code we end up with chart that is ready to wow our users! We're also now binding to fields which means we can open this up to more advanced scenarios pretty easily. For reference, here's the full code in action that you can run in StackBlitz to see the end result:

A New Color of Paint

The chart above looks pretty good, but specifically follows our standard Material theme. What if we want to take full control over how this chart looks? We all have custom designs and colors that we need to stick to (perhaps a company-wide UX design standard) and we of course want to make our chart fit in to this.

The easiest way would be to follow the customization guidelines for the KendoReact Material theme. Since this is done via Sass variables it can be pretty easy to tweak this theme to fit in to your design criteria. There's even a chart-specific section that goes in to specific variables for the chart.

We also can take a declarative or programmatic approach, defining styles within each part of our component, which is the way we will continue throughout this article.

Let's start with our end-goal of the design of our chart. Sales in general tend to mean a business is going well, and is associated with money, so let's stick with a green theme for the chart, with the primary green color being #4EA952.

final-chart

A logical place to start is to set the green background of the chart. We will need to introduce a new part of the chart here, the ChartArea. This element gives us control over things like the width and height of the chart, and also lets us define the background color. This will be added in to our chart configuration as an element that is self-closing, so we will just add <ChartArea background="#4EA952" /> under our <Chart> tag.

chart-with-green-background

Alright, maybe not the best looking (yet!) so let's continue to tweak some things. The default blue of our series might be a bit odd here, so let's make this in to something close to white (but not quite) like #F9FCF9.

<ChartSeriesItem type="line" color="#F9FCF9" data={this.state.salesPerDay} field="sales" categoryField="day"> <ChartSeriesItemTooltip visible={true} /> </ChartSeriesItem>

We should also address the color we have on the X-axis and Y-axis here. We mentioned this earlier when we talked about displaying the Mon-Sun at the bottom of our chart. This will be done by setting up ChartValueAxis and ChartCategoryAxis elements. Importing these from our chart package lets us define specifics around the X and Y axes, like default font color in our case, along quite a few other things.

Let's take a look at our implementation first and then explain what has been done to set up the default colors of these axis items.

<ChartValueAxis> <ChartValueAxisItem labels= /> </ChartValueAxis> <ChartCategoryAxis> <ChartCategoryAxisItem labels= /> </ChartCategoryAxis>

As we see in the snippet above, we've also added in ChartValueAxisItem and ChartCategoryAxisItem which is actually where we are defining if the labels are visible to begin with (default is true here by the way) and what color they should be.

Right now all that we're doing is setting colors, but these AxisItems are very important when we want to customize our chart. For example, the ChartValueAxisItem lets us define max and min values so we don't always have 0 as the lowest value. This is useful where the values start very high to begin with, or we want to see negative values as well. The ChartCategoryAxisItem provides us with the means of changing the default binding level for dates (day, week, month, year) as well as intervals for where in the data we want to display points. Great in scenarios where performance is of a concern and we may not want to display absolutely every data point initially.

That being said, in this case we are just setting the color to be that of our series item to be consistent.

series-and-axis-updated

Looking much better! The last detail would be to address the lines we have in the background since these make it easier to identify what value we might be dealing with at an initial glance.

In the KendoReact chart we have the majorGridLines and minorGridLines properties that we can work with. In this particular case we only have majorGridLines as we only have lines associated with every regular tick, but if we wanted to be even more granular with our data we could also set up minor tick values to highlight data items between our larger/more important values (major).

To set these up we could work with our existing ChartValueAxisItem and ChartCategoryAxisItem elements, but a super useful item to cover here would also be ChartAxisDefaults. The great thing about this component is that it lets us configure defaults that we want all or our axis items to inherit from and we would only need to define some additional axis values when we have a very specific change for one (or both) axes item(s). In fact, we could even remove the previous ChartCategoryAxis and ChartValueAxis sections of our Chart component if we wanted to since they would inherit from this element. We may want to extend this later so we can leave them in for now.

The ChartAxisDefaults component can be included in our <Chart> component directly and be self-closing. We should define the majorGridLines property when we do this as well, giving us <ChartAxisDefaults majorGridLines= />. the dashType prop us by default a line, and while there are a lot of variations the "dot" version is what we had in our original image.

If we run this code we will see that we have successfully implemented the design we originally set out to achieve!

final-chart

Here's the full source code for what we just did.

Quick and Simple Data Visualizations

Sometimes a chart may not be the best way to display information. Say you want to highlight a percentage value from 0-100, or maybe some sort of progress bar. This is where the KendoReact Gauges come in to play. These type of visualizations, combined with the charts, give us quite a range of visuals to deal with.

All of these components can be found in same package so installing them is a breeze with npm install --save @progress/kendo-react-gauges @progress/kendo-drawing @progress/kendo-react-intl.

A huge hit is the ArcGauge component, which can be added to any React component by using import { ArcGauge } from '@progress/kendo-react-gauges';.

The quickest way to render this component is to add a variable to our state like the following:

this.state = { value: 78 };

And within our render we can throw in the ArcGauge and bind it to said value.

render() { return ( <ArcGauge value={this.state.value} /> ); }

The resulting gauge looks like this:

gauge-without-labels

Which, while it looks nice, is missing a way for us to see what the actual value might be. This can easily be achieved by setting the arcCenterRender prop, which can be passed a function and return pretty much whatever we want. This gives us the potential to either pass a simple string of a particular format, or we can have some fun customization with the gauge label changing formatting or colors along with the ArcGauge itself.

For our particular sample, let's say that we are dealing with percentages so we want to have our value followed by "%" displayed in the arc of our ArcGauge. We can start by defining the arcCenterRender prop to a function (we'll write the function in a bit) giving us something like arcCenterRender={this.centerLabelRenderer}. Then, within the constructor of our React component we can define centerLabelRenderer.

this.centerLabelRenderer = (value,color) => { return (<h3 style=>{value}%</h3>); }

The convenient thing here is that value and color will always be passed down from what we've already set on the ArcGauge itself. So, if the value or color of our gauge changes, so can the label inside. Since this is a template that accepts HTML elements we can really return whatever we want. In this case, let's just make this a simple h3 and bind to both color and value.

Here's everything put together.

Once we've set this up we end up with a clean and easy-to-read visualization.

gauge-with-label

Adding Visualizations to Anything

Last but not least there's another type of visualization we can cover, and that's the Sparkline component.

sparklines-in-grid

These little visualizations are great as their main purpose is to be injected in places where a quick visualization might make sense, but we don't need to see things like axes, coordinates, legends, titles, or other surrounding elements. As seen in the image above it works out very well in scenarios where we may want to display our chart within the cell of a data grid which would end up being quite cumbersome from a UX perspective if we added in the full chart.

Even though it is a small component in size, it still packs a powerful punch! We can call it the "noisy cricket" of the KendoReact data visualization package. Currently the Sparkline supports the following types, all with built-in tool tips and other helpful features.

  • Line (default if no type is set)
  • Bar
  • Column
  • Area
  • Pie
  • Bullet

To get started with this component we simply have to import the Sparkline component from our kendo-react-charts package:

import { Sparkline } from '@progress/kendo-react-charts';

From there we can just work with our original salesPerDay data (without the dates) and bind this to the Sparkline component.

class App extends React.Component { state = { salesPerDay: [ 12, 9, 13, 7, 10, 8, 12 ] } render() { return ( <div> <Sparkline data={this.state.salesPerDay} /> </div> ); } }

That's it! Now we have a Sparkline component rendered in our page. Of course, it will probably make more sense when integrating in to other components, but this is where a custom render can come in to play.

As usual, here's the full source code for this sample:

Visualize All the Things!

Spicing things up in our applications can sometimes seem like a bit of a daunting task, but it doesn't have to be that way! By working with our existing data and simply binding it to a chart, gauge, or even a little sparkline visualization we can very easily start taking our application to the next level and make our applications even more intuitive for our end users to understand and interact with. Hopefully this post inspired you to get some ideas around how data visualizations can be added to your own applications!

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.

Build a Cryptocurrency Dashboard with Kendo UI - Part 1

$
0
0

In this step-by-step series, learn how to research, design and build a dashboard to monitor cryptocurrency trades.

Project overview

In this series, we will be building a dashboard to monitor cryptocurrency trades. In this part of the series, we will do research to decide what features the app needs to have and design a prototype so we know what we will be building. In the rest of the series, we will be building the app feature by feature. Cryptocurrencies, such as Bitcoin, are a special kind of electronic payment system. Just like the stock market, there are exchanges where you can trade different coins. As a cryptocurrency investor, you want an easy way to analyze the market so that you can make better trades. Coming up, we will get the requirements for this project and define the features based on the information given.

Want to learn more about the technology that supports cryptocurrency? Check out this great Blockchain Overview on Altcoin Magazine written by Simeon Georgiev.

Requirements

You want to see a list of all the currency pairs and select them to get more data. A currency pair (ETC/BTC) has a base currency (ETC) and a quote currency (BTC) used to price the base currency. There are a few currencies that a currency can be quoted for and you would like to toggle between the data for those options. You want to be able to select a currency pair and see its trade history. You need to be able to see if it has been rising in price or falling over time so you can know when to buy and when to sell. Studying price movements in a market is known as technical analysis and you can learn more about it on Investopedia. Next, you will need a way to visualize the price movements so you can easily spot trends. The trend is a pattern. It can be upward, downward, or sideways. Finally, to jazz up the app we want to be able to change the theme.

Now, we will consider the technologies and tools to build these features. This impacts our workflow and how we will break down our tasks. There are two parts to the app we are concerned with, the view and the data. We don’t want to create the components from scratch so we will need a UI toolkit that has components for displaying and visualizing data. That is why we will be using Kendo UI. The Kendo UI toolkit has grids and charts among other components and a JavaScript API so we can program the data into these components. There are several public APIs with trading data for cryptocurrencies. We will use Cryptopia’s API because it has the endpoints that correspond to the kind of data we want to retrieve. Next, we will translate our features into the Kendo UI components and API endpoints we will need to use.

Cryptocurrency Trading Pair List

The first feature is to display a list of the currencies. A grid is ideal for this because we will have lots of data to show and we want the user to be able to sort the data by different parameters. The parameters we will show for each currency pair is the current price, the highest and lowest price, and the volume. Volume is the number of trades that have taken place over a period of time. We also need to show the trading pair in different currencies. The currencies we will quote the base currency in are BTC (Bitcoin), USDT (Tether), and LTC (LiteCoin). A tab strip with each of these currencies as its labels will be placed above the grid. Selecting a tab will update the grid with the relevant market data. We can use this API endpoint from Cryptopia to get a list of the trade pairs:

https://www.cryptopia.co.nz/api/GetMarkets/base_market

Where base_market is replaced with BTC, USDT, or LTC.

Market History for a Trade Pair

The next feature is to visualize the data for each trade pair with a chart. We want a chart to see what the closing prices were for a trading pair over a given time. A line chart is best for this use case. The x-axis will represent the time and the y-axis will represent the closing price. When you hover over the line you will see a label with the price. The Cryptopia API lets us specify time histories in one-hour increments. The default is 24 hours. This shows the trading history from 24 hours in the past to the current time. This is the API endpoint we will use to get the trading history for a particular trading pair:

https://www.cryptopia.co.nz/api/GetMarketHistory/trading_pair/time

The trading_pair parameter would be replaced with BTC_USDT for the BTC/USDT trade pair for example. Time would be replaced with a number in hours. We will give the user the option to select the depth of the history by providing a button group with predefined times. There will also be a date time picker so you can explicitly choose how far back in time you want to see. Last, we will use a splitter so we can toggle the views for the grid and chart and create a custom theme for our design.

Summary

Our cryptocurrency dashboard will show a list of the trading pairs and a chart with the history of closing prices for each trading pair. We will use the Splitter, Grid, TabStrip, LineChart, ButtonGroup, and DateTimePicker components from the Kendo UI toolkit. We will use Cryptopia’s public API for the data. The first task that we completed today was doing research and planning. The next tasks are the following:

  • Begin coding app
  • Configure the data source for the grid and chart
  • Implement the grid
  • Implement the chart
  • Add a custom theme

For the next task, we will code the least complex components. This includes the Splitter, TabStrip, ButtonGroup, and DateTimePicker. The purpose of this is to have the structure of the layout in place and complete a large chunk of the project quickly. The Grid and LineChart are more complex and we will need these components to get them fully functional.

Stay tuned for the next post, coming out soon.

Resources

What’s New in R1 2019 for jQuery in Kendo UI

$
0
0

We've added or enhanced a number of components with the first release of the year for Kendo UI for jQuery. Check out what's new.

A new year brings new goodies with Kendo UI! In this blog post I want to jump into a more detailed view of what we have released with R1 2019 for the jQuery components found in Kendo UI.

New and Improved Components

MultiViewCalendar

jquery-mvc-core-multiviewcalendar-material 

The MultiViewCalendar component is built to give users an easier time viewing multiple calendars side-by-side. Probably the most common functionality is to display two months at a time and select a set of dates across the two calendars.

DateRangePicker

jquery-mvc-core-daterangepicker-material
 

The DateRangePicker takes the idea of the MultiViewCalendar component but adds it in a drop down! Just like with the DatePicker, but of multiple dates. Out-of-the-box this will give users a start and end date, which you as a developer can pull the value from with a single API call.

Ripple

jquery-ripple-effect
 

While it’s a bit subtle, Material Design calls for a “ripple” effect across many of its interactions and animations. Most often this is seen on things like button clicks or selection in check boxes and radio buttons.

Since this effect can be a bit tricky to make yourself we went ahead and created a generic way for you to create a ripple effect across any HTML element!

ScrollView

jquery-mvc-core-scrollview-material
 

You’ve probably seen something like our ScrollView component before. Easily recognizable by the little dots on the bottom of each image, along with the left and right icons to help scroll between the images, this is an easy way to cycle through many images while only taking up a fixed real estate in your application. This component originates from the hyrid mobile UI library that we’ve offered for a while but we want to bring this over to the regular Kendo UI library to help with adding this in to responsive web applications.

Switch

jquery-mvc-core-switch-material
 

The Switch component has already been available from Kendo UI, but it was a part of the hybrid mobile UI portion. This component is fairly popular across desktop applications nowadays so it’s safe to say that it shouldn’t be available only for hybrid apps. We wanted to make sure this component could be used in web applications without having to pull in additional files.

Material Theme for the ThemeBuilder

There are plenty of you out there using the Kendo UI ThemeBuilder, but in case you’re not familiar the ThemeBuilder is a tool that let’s you completely customize any of the Kendo UI themes to fit with your design guidelines with just a couple of clicks. All components are rendered out on the page and whatever changes you do to the theme will automatically be shown in each of the components.

While we’ve had the ThemeBuilder for quite some time, the ability to customize the Material theme was not available. Well, that was true until the R1 2019 release! Head over to the ThemeBuilder and you’ll see a whole set of available color swatches for the Material theme along with form elements to update the theme with color pickers or HEX values.

Miscellaneous Improvements

We have included a ton of bug fixes and various features across all Kendo UI components, but here are a few additional highlights:

  • The Editor component now supports the placeholder attribute
  • Exporting a hierarchical Grid to Excel now has expand and collapse icons in the generated Excel file
  • We’ve improved upon the Scheduler’s Recurrence Editing to make it even more intuitive and cover more recurrence scenarios
  • The TreeView component received a huge performance boost (check out this blog post for more information)

Join us for the Webinar

I tried to cover all the important bits in this blog post, but there’s a ton more that came out with the R1 release! For a look at all the goodies I mentioned here, plus more, you should sign up for the R1 2019 Kendo UI release webinar that we’re hosting on January 22nd at 11 AM ET. Seats are limited so make sure that you reserve your seat today! If you just can't wait, feel free to download the latest bits or jump into a free trial today and let us know what you think.

ASP.NET Core 2.2 Goes Bootstrap 4

$
0
0

ASP.NET Core 2.2 brings a migration from Bootstrap 3 to Bootstrap 4, major changes to project templates and the user interface, and more. We break down what's new.

ASP.NET Core 2.2 hit global availability on December 4, 2018. With the release of ASP.NET Core 2.2, project templates were overhauled. The change focused on migrating from Bootstrap 3 to Bootstrap 4, while at the same time modernizing and simplifying the user interface (UI). This overhaul included the default Identity UI boilerplate and scaffolding generated content. These changes are welcome as Bootstrap 4 gains traction as the new community default for HTML/CSS UI frameworks.

Bootstrap 3 vs. 4

The main goal of Bootstrap remains the same—to provide simple components for building responsive, mobile-first sites. However, the Bootstrap framework itself has changed pretty significantly from version 3 to 4. Bootstrap 4 now uses Sass (.scss) by default in its source code, unlike the previous version which was built on Less. The underlying grid has been expanded to use Flexbox, which provides simpler and more flexible layout options. Panels, wells, and thumbnails are now replaced with the concept of cards. Other notable features include white spacing utilities, a new look & feel, and an extra break point for extra large (XL) screen sizes.

Get Sass'y

Bootstrap 4 is built with the Sass CSS extension language (or pre-processor). Sass allows developers to use powerful features not typically available with CSS. Advanced features include nesting, variables, functions, and operators that can be used to produce flexible and reusable CSS libraries. With Sass, complex tasks like changing the theme of an app are reduced to a simple value change in a settings file.

In the following example, a map of colors comprise a theme for a Bootstrap app:

$theme-colors: (
  "primary": #84329b,
  "secondary": #02bceb
);

Changing settings scratches the surface of what's possible. Almost every aspect of Bootstrap can be customized, and it's fully documented.

While the source .scss files aren't included with the ASP.NET Core 2.2 project templates, they're easy to add to and compile with .NET tooling. If you're interested, continue reading through the Dependency Management section below.

Flexbox

Bootstrap's grid system is now built with Flexbox—a module of CSS that defines a CSS box model optimized for UI design and the layout of items. With Flexbox, the grid system has been simplified and made more versatile.

Columns can be created without explicitly setting a numeric width. Instead of writing the class .col-{breakpoint}-{#}, it can be simplified as col. This improvement makes dealing with dynamic content much easier as the grid defaults to an equal width for each .col element.

<div class="col">
  First Column
</div>
<div class="col">
  Second Column
</div>

<!-- Dynamic items -->
<div class="row">
  @foreach (var item in data)
  {
    <div class="col">
      @item
    </div>
  }
</div>

Bootstrap also ships with a full set of Flexbox utilities used to manage layout and alignment of grid elements. The flex utilities simplify previously difficult tasks like stretching all elements to an equal height or vertically aligning an element within a parent.

<div class="d-flex align-items-center">...</div>

vertical-align

<div class="d-flex align-items-stretch">...</div>

stretch-align

Cards

Cards are another area in which Bootstrap has changed in a big way. Cards are a replacement for wells and panels in prior versions of Bootstrap. Cards are more representative of a modern approach to UI design. Cards can include titles, images, and actionable items. They're perfect for focusing a user's attention.

<!-- A single card -->
<div class="card">
  <img class="card-img-top" src=".../100px200/" alt="Card image cap">
  <div class="card-body">
    <h5 class="card-title">Card title</h5>
    <p class="card-text">This is a longer card with supporting text below as a natural lead-in to additional content. This content is a little bit longer.</p>
    <p class="card-text"><small class="text-muted">Last updated 3 mins ago</small></p>
  </div>
</div>

Combined with the new card-deck container, cards can be used to compose a rich UI with groups that automatically line up.

<!-- A deck of cards -->
<div class="card-deck">
  <div class="card">...</div>
  <div class="card">...</div>
  <div class="card">...</div>
</div>

cards

These are just a few of the improvements that can be expected from Bootstrap itself. Next, we'll discuss the improvements made to the ASP.NET Core project templates and Identity features.

File New Project

File > New > Project experience

The ASP.NET Core new project web app template has been updated in this release with a simplified default index page. In previous versions, the index page included a sample carousel and additional elements. Carousels were once a popular UI feature but have decreased in popularity over the years. The removal of these items is a welcome change. There's less boilerplate code to remove when starting a new app.

aspnet21-index 

The new experience is cleaner with only a few example UI elements remaining. Examples include the top menu bar and alert box. A welcome message directing users to documentation replaces columns of reference links.

aspnet22-index

The Identity pages, which include login and registration screens, were also updated with the new Bootstrap style. The changes to specific Identity pages are less visually drastic than the index page.

Identity

In ASP.NET Core 2.1, Identity evolved to utilize a Razor Class Library (RCL). The RCL adds Identity to the project as a self-contained package represented as a single .dll library. Along with the Identity library, a scaffolding tool was added to override pages "hidden" within the Identity library itself. Because the Identity library includes many views that incorporate Bootstrap classes, it's important that the Identity library update along with the project template while retaining backwards compatibility.

aspnet22-login

An effort was made to ensure that the Identity library is flexible enough to serve both ASP.NET Core 2.1 and 2.2 users. Depending on which version of ASP.NET Core is used, the Identity library emits the correct markup for either Bootstrap 3 or 4. To support this requirement, an option can be set to specify the default UI framework for Identity.

The default UI framework is now set using the AddDefaultUI method and passing in the desired framework version as a parameter. For example, (UIFramework.Bootstrap4):

services.AddDefaultIdentity<IdentityUser>()
  .AddDefaultUI(UIFramework.Bootstrap4)
  .AddEntityFrameworkStores<ApplicationDbContext>();

In addition to the ability to choose between versions, the scaffolding system generates the correct Bootstrap markup, thus ensuring its compatibility. The Identity scaffolding tool generates pages used to override the pre-packaged Identity pages. The scaffolding tool can be accessed by right-clicking the project in the Visual Studio's Solution Explorer window and choosing Add Scaffolded Item> Identity.

scaffold-items

From the Add Scaffold dialog, individual pages from the Identity library can be generated. Alternatively, all pages can be generated at once.

scaffold-dialog

The pages generated by the tool are written to the Identity area of the app. These pages use Bootstrap 4 styles and serve as a good starting point for customization.

Dependency Management

Throughout the history of ASP.NET Core, there have been default options included for client-side dependency management such as NuGet and Bower. Because client-side development evolves so rapidly, a default is no longer included and developers can choose to handle dependency management however they see fit. Client-side packages can be managed from a variety of tools, such as npm, Yarn, and Bower. There are various command line (CLI) tools and Visual Studio extensions available to simplify the process; however, most of these tools were "born" outside of the .NET ecosystem and require additional setup and installation. These tools often introduce unnecessary files to the project as well. For example, the node_modules folder is notorious for being massive.

Libman is a simplified client-side dependency tool. It's included with Visual Studio 2017 and is an alternative for ASP.NET Core development. Libman can resolve client-side dependencies from a Content Delivery Network (CDN) or a file system while only targeting the files needed by the project. Developers can choose to retrieve single minified JavaScript and CSS files, or entire folders, which is useful for .scss development.

Let's use Libman to add the Bootstrap 4 .scss source code to a project. Right-click the project, and choose Add> Client-Side Library to display the Libman dialog used for fetching packages.

add-client-side-library

Next, choose a package provider. This can be the CDN cdnjs, the file system, or a package provider called unpkg. We'll use unpkg to retrieve the files, since unpkg allows us to quickly and easily load any file from any npm package without needing npm itself. Supply the package name and version number, then select the files to include in the project.

using-unpkg

When clicking Install, Libman fetches the files and loads them into the target location. You can then work with the files in our project as needed. In this example, we're using .scss files, which need to be compiled into .css files the browser understands. To compile the files, install the BuildWebCompiler NuGet package—a .NET-based tool that can compile client-side assets. The NuGet package is added through Visual Studio's NuGet Package Manager window or via command line with Install-Package BuildWebCompiler.

BuildWebCompiler

With BuildWebCompiler installed, instruct the compiler to build the Bootstrap source code. A compilerconfig.json configuration file that uses simple input/output properties is needed to complete the task:

[
  {
    "outputFile": "wwwroot/css/bootstrap.css",
    "inputFile": "wwwroot/lib/bootstrap/scss/bootstrap.scss"
  }
]

If using a custom build of Bootstrap, you'll likely need to modify the <link /> tags within your app's _Layout.cshtml file:

<environment include="Development">
    <link href="~<myCustomPath>/css/bootstrap.css" rel="stylesheet" />
</environment>
<environment exclude="Development">
    <link href="~<myCustomPath>/css/bootstrap.min.css" rel="stylesheet" />
</environment>

Telerik UI for ASP.NET Core Bootstrap 4 theme

For the ultimate Bootstrap 4 experience, use the Bootstrap 4 theme in Telerik UI for ASP.NET Core. Since UI for ASP.NET Core supports Bootstrap 4, there are over 60 UI components that seamlessly integrate with ASP.NET Core 2.2 apps. In addition, developers can leverage the Kendo UI and Telerik Web UI Theme Builder. The Theme Builder not only customizes the Telerik UI components, but native Bootstrap 4 components as well. The Theme Builder also supports .scss files for developers who want to integrate with their custom Bootstrap builds.

theme-builder

If you're interested in seeing how UI for ASP.NET Core performs with your project, test drive it by downloading a 30 day free trial.

Wrap Up

ASP.NET Core 2.2 project templates have seen quite the improvement. The template improvements span across project basics, Identity & tooling, and dependency management. Bootstrap itself has changed significantly from version 3 to 4 with Sass source code, new grid layouts, cards, and much more. By updating the project templates, the ASP.NET team has set the stage for the next generation of ASP.NET Core apps.


How to Use Basic React Hooks for Reducers

$
0
0

In the next post in our series on React Hooks, we'll learn how to use reducers by walking through a sample todo app. Get "hooked" as we take a look at the useReducer React Hook!

In the past few articles, we have become familiar with React Hooks. In our first article, we learned about State & Effect which allows us access to local state and side effects inside a functional component.

In our second article we learned about React's Context API and demonstrated how to use it with regular classes in a profile component. The Context API allows us to share data with child components using a provider and consumer. But until Hooks came around this was not achievable with functional components. So we refactored with the useContext hook. This involved changing classes in our project to functional components eventually removing all classes from our demo making everything easier to read with less syntax. In both cases we learned hooks gave us the ability to migrate our code from classes to functional components as Hooks can only be used inside functional components or other hooks.

In this article, we take what we have learned and apply that knowledge to a more advanced demo using the useReducer hook. Understanding the basic useState hook can prepare us for learning about useReducer so if you have not read the first article of this series it is highly encouraged before moving on.

If you have been programming React under a rock or you have just taken up React, Redux is the more popular way of working with unidirectional data in React and is encouraged by the React team as well. It has become a standard in the React community and ecosystem, and that's why React has built useReducer into React, which gives you a way to use the Redux pattern without depending on the Redux library just to do simple UI state management.

In React, Your Only Job is to Manage State

Well, not completely, and I agree this heading is a bit baity. But it's many developers opinion that the main things you should always consider when building React applications is to understand what your state currently looks like and what your UI looks like. This will drive how you manage its state and build your application around it.

Don't worry, we do use separation of concerns in a proper React application, so the state vs UI are kept compartmentalized. We can typically just build out UI and then focus on managing its state. This determines what we do next and we get to decide exactly what happens each time the UI is interacted with and how that might mutate the state we are managing.

A Primer on Reducers

Let's talk about the difference between a Redux state reducer and the JavaScript method Array.prototype.reducer.

The canonical array prototype example is a sum function. When we call the reducer on an array that contains only numbers, we can return a single value summing up all values in the array and returning the total as a single value. The reducer can be fed an initial value to start with as well. Let's briefly take a look at some code that demonstrates the reduce method from JavaScript's Array.prototype method called reduce().

const votesByDistrict = [250, 515, 333, 410];
const reducer = (accumulator, currentValue) => {
  return accumulator + currentValue;
}

console.log(votesByDistrict.reduce(reducer));
// expected output: 1508

// and below we simply add a value to start from:

console.log(votesByDistrict.reduce(reducer, 777));
// expected output: 2285

If you have worked with Redux reducers, you probably see a similarity in the example I just explained and how Redux reducers work. You can easily see why the Redux Reducer shares a similar name.

A sum function is the simplest example, but inside that reducer, you can do any work you want iteratively between those curly braces. Think of it as a recipe that no matter what the contents of the array, this function always produces the same result considering the same input. A pure function. This is a powerful concept especially when used to manage state for an application.

The Redux Reducer, similar to the Arrays reducer, returns the accumulation of something - in our case 'state' based on all previous and current actions and state modifications that have taken place in the past.

So Redux style reducers act as a reducer of state. It receives a state and action. The state gets reduced (accumulated) based on the action type and then returned as the new state. Each time we reduce we can refer to that operation as a single cycle.

Just like in cooking a Bordeaux style Bordelaise sauce, we start with many ingredients. Butter, shallots, veal, pepper and of course wine. All of these ingredients are combined together in a pan and simmered or (reduced) down. Repeated, given the same steps, using the same ingredients, same amounts, same stove and same temperatures, we should yield the same result each time. A single wonderfully awesome sauce. Still wondering where they get the name reducer?

Let's Build a Working Example

We are going to build a Todo application. To start out with, we want our Todo list to have an initial Todo item that simply says: "Get Started."

When we add a new Todo item, the process is to first dispatch an action.

This action get's handled by a Reducer function. Our action type is ADD_TODO and our reducer function switches on these types. When the reducer function notices type ADD_TODO, it acts on it by taking the old state spreading that existing state out and appending our new Todo item to the end, then returning the new state as the result.

Another action we might create could be COMPLETE_TODO or better yet, TOGGLE_COMPLETE. I like the latter as it gives us the ability to incomplete, so to speak, if the user clicks the wrong Todo.

In this case our reducer doesn't add any new items to the list, it modifies one property of an existing Todo item. So let's pick up where we left off above. If we started out with one Todo that says "Get Started" and then we add a new Todo: "Take a break," our new state should look like this:

{ 
  id: 1, 
  name: 'Get started', 
  complete: false 
},
{ 
  id: 2, 
  name: 'Take a break', 
  complete: false 
}

Notice that each Todo has several properties, one of them, an id. This is a unique key and we use it specifically to know which Todo we want to update.

The reducers job for TOGGLE_COMPLETE is to update that complete property from it's current value of false to the opposite value of true. Once this is done, any changes will be propagated down to any components that use this piece of state, causing them to update. Our list can be thought about as the listener, and once we add or complete or remove a Todo, the list should immediately reflect those new changes.

So, since each completed property in our Todo starts out as false, if we call TOGGLE_COMPLETED on the Todo with the id of 1, our state should get updated to look like the following:

{ 
  id: 1, 
  name: 'Get started', 
  complete: true // We changed it!
},
{ 
  id: 2, 
  name: 'Take a break', 
  complete: false 
}

We have just described (albeit in a simple example) the entire Redux cycle, also referred to as unidirectional data flow.

This was not easily achievable in React without a library like Redux. But now, thanks to the advent of Hooks, we can easily implement the Redux reducer pattern in any React application without using a library like Redux.

I will admit that using state in this manner should probably be reserved for working with internal state, and that this will not mean the large applications where state is managed by Redux are now obsolete. That is not the case here. But it gives React developers a clear and concise Redux-style way of managing internal state right away without installing any dependencies.

The State We Will be Managing

Traditionally in Redux, a decision on how to categorize state and where to store it was one of the biggest questions from a beginner's perspective. It's actually the first question in their Redux FAQ and here is what they state:

There is no “right” answer for this. Some users prefer to keep every single piece of data in Redux, to maintain a fully serializable and controlled version of their application at all times. Others prefer to keep non-critical or UI state, such as “is this drop-down currently open”, inside a component's internal state.

Hooks are powerful in the layer of the application where we keep track of things like “is drop-down open” and "is menu closed." We can take care of proper management of the UI data in a Redux-style manner without leaving React core.

In a machine whose sole responsibility is to constantly change and append state, the reducer is the part that is different about each operation. It's the logic that either increments a counter or manages a complex object that changes to have ramifications on the current state. Giving us access to that as well as setState from within functional components is the final piece of the puzzle - and at the same time, the first piece to a new puzzle.

Let's take a look at how we manage the very simple Todo type application. It's a perfect example for demonstration purposes. Here are the rules of our Todo app.

We are going to need a few moving pieces in order to contrive even a simple real world case for using useReducer. We will need to keep track of how our state is modified and updated using actions like "add," "complete" and "clear." Using a pattern familiar to Redux, we typically would associate each of these processes with a particular action type that is handled by a dispatcher:

  • A form field allowing us to enter a task
  • A dispatcher handling our form when it submits
  • An actual object that holds the our tasks
  • An actual Task Component to encompass everything
  • An actual Reducer that handles the modifying of our state

Let's start by adding and composing all of these pieces together. I don't typically go over how to setup a React project because that can be done many ways - instead I like to give my users a StackBlitz demo that they can fork and work on along side the tutorial. Once forked, this project is yours to do with as you want. You can use this information and this code however you want.

Where we start is with a brand new project and for this tutorial we will do everything inside the index.js file. Once finished, you may want to make it a point to extract each piece of logic and all components out to their own files. This is a great exercise, especially for beginners.

In our simple example, we will have the Todo component that we create be the actual root level component of our application, which would look something like the following:

import React from 'react';
import { render } from 'react-dom';
import './style.css';

const Todo = () => {
  return (
    <>
      Todo Goes Here
    </>
  );
}

render(<Todo />, document.getElementById('root'));

But the code I want you to start out with is a little bit further along than that. I have added enough to get us started, including a form and input field that does not yet submit. I have also added a styled list and a chunk of Json, which we can use as a seed for generating Todo items to test that our list renders out and that the shape of our data conforms to our HTML.

You will need to fork this StackBlitz Demo to follow along with the tutorial. There is a fork button on the StackBlitz demo - once you click it you can give it a new name, and this will create a clone of my starting point for you to work on.

Now that we have the project forked, we will make our first change by importing the useReducer hook from React. Update the first line in the file as follows:

import React, { useReducer } from 'react';

We need to add our call to the useReducer now. It takes state and action as arguments. We assign that to an array object which is a tuple (two values) - this is destructuring because the useReducer() matches this as its return value:

Add the following line just above the return statement in the Todo component:

const [todos, dispatch] = useReducer(todoReducer, initialState);

items will be the piece of state which is the actual list of Todo items, and dispatch will be the actual reducer used to make changes to that list of items. In the return statement we create a group of divs for each item our items array.

Our application will now have errors because we have not yet created a function called todoReducer. Let's add that code right below the line that we setup our initialState assignment on.

const todoReducer = (state, action) => {
  switch (action.type) {
    case 'ADD_TODO': {
      return (action.name.length)
        ? [...state, {
          id: state.length ? Math.max(...state.map(todo => todo.id)) + 1 : 0,
          name: action.name,
          complete: false
        }]
        : state;
    }
    default: {
      return state;
    };
  }
}

This may seem complex at first. All it's doing is setting up a function that takes state and action. We then switch on that action.type. At first we will only have one action, but we want to setup a default catch all as well. This default will simply return the current state.

But if it catches a real ADD_TODO we will return the current state, spread out, with our payload appended on to the end. The tricky part is assigning the new ID. What we have done here is taken the existing list of Todos and returned the max id plus one, otherwise zero.

Since I have already setup an initialState, we are good to move onto the next step. We need to make sure that when typing in the input field, when we hit enter, the value we have input gets sent off to a function that will do the reducing.

So first let's replace the div with the className todo-input with the following:

<div className="todo-input">
  <form onSubmit={addTodo}>
    <input ref={inputRef} type="search" id="add-todo" placeholder="Add Todo..." />
  </form>
</div>

What this does is ensure that when we hit enter, we send the form information off to a function called addTodo(). We also reference the input using the ref attribute and give that element a reference value of inputRef. Making these changes means we need to now do two more things.

1) We need to create a property called inputRef which calls the useRef hook. 2) We need to create a function called addTodo().

Let's start with creating the inputRef property. At the top of your Todo component, add the following property:

const inputRef = useRef();

We will use the ref attribute to get a reference to the input, this will allow us to access its value later. This reference will be backed by a local property in our Todo functional component, but that will just be a call to the useRef hook which allows us to access all of the ref goodness inside a functional component. With a local property named inputRef we will be able to make calls like: inputRef.value.

You will also need to import that hook just like we did with useReducer. Update the first line of the index.js file to reflect the following:

import React, { useReducer, useRef } from 'react';

Finally we need to create the addTodo() function that will use this reference and will be responsible for dispatching our action of type ADD_TODO. Just above the return add the following function:

function addTodo(event) {
  event.preventDefault();
  dispatch({
    type: 'ADD_TODO',
    name: inputRef.current.value,
    complete: false
  });
    inputRef.current.value = '';
}

Inside of our function we are first calling preventDefault() in order to keep the page from refreshing when we hit submit the form.

We then dispatch our ADD_TODO action using the inputRef to access the input value from the form. All Todos initially get a completed value of false. Finally we set the inputRef value to nothing. This clears the input field. Good enough for a demo.

Finally, we have one more update we need to make before the ADD_TODO will work. Inside of our JSX we are still mapping over initialState. We need to change that from:

{initialState.map((todo) => (

to:

{todos.map((todo) => (

Now we should have a working useReducer hook that is utilizing our addTodo function in order to dispatch our action to the todoReducer.

Adding Completed Todos

Let's bring in a familiar hook from our first blog post: useEffect. I just want to make sure we have a working example of that hook inside this project as well, so we will update the document.title every time that we check off a Todo to display the count or number of completed Todos in our list.

Just above our addTodo() function, let's add the logic for figuring out how many completed Todos we have. We will then need a useEffect method to update the document.title when it changes:

const completedTodos = todos.filter(todo => todo.complete);
useEffect(() => {
  // inputRef.current.focus();
  document.title = `You have ${completedTodos.length} items completed!`;
})

To do this we will need to bring in that hook as well:

import React, { useReducer, useRef, useEffect } from 'react';

We are not done yet - we now need to add an event that will call the function which will dispatch our COMPLETED_TODO. Add a onClick handler to our div with the className of todo-name.

<div className="todo-name" onClick={() => toggleComplete(todo.id)}>
  {todo.name}
</div>

Next we need a function to handle this click event. It's simple and only dispatches a simple id and the action type. Add this right below our addTodo() function:

function toggleComplete(id) {
  dispatch({ type: 'TOGGLE_COMPLETE', id });
}

Finally we add the case to our todoReducer:

case 'TOGGLE_COMPLETE': {
  return state.map((item) =>
    item.id === action.id
      ? { ...item, complete: !item.complete }
      : item
  )
}

I have also setup a style, and we will add or remove that style based on whether the todo has a completed value of true. Just below the todos.map code, let's change the line of code that looks like this:

<div key={todo.id} alt={todo.id} className="column-item">

to this:

<div className={`column-item ${todo.complete ? 'completed' : null}`}
  key={todo.id}>

We don't need that alt attribute anymore, so we removed it. That should do it! Now when we click on our Todos it will dispatch an action and set the completed value to true on that specific Todo, and now our filter will pick up on this by way of the useEffect method which in turn updates the document.title. We will also get our className completed applied and our completed Todo will become opaque to represent a completed Todo.

At this point we pretty much have everything working except for the delete functionality, as well as the button that should clear all Todos from the list. To round out our demo we will repeat what we have already learned in order to make these last two pieces of functionality work.

Deleting a Todo

It should be pretty trivial at this point to hook (pun intended) up a delete and clear todos button. The styling and HTML have already been taken care of, so we just need to make them work.

Let's start by adding the onClick() event for the close icon inside the todos HTML:

<div className="todo-delete" onClick={() => deleteTodo(todo.id)}>
  &times;
</div>

We'll add the function that will dispatch the action - these don't have to be their own function, we could dispatch right from the onClick() or we could setup a similar switch statement to handle all of the dispatching. We can take whatever approach to this we want. I wanted to add them one by one for purposes of this demo.

Now we create a function that will handle the dispatch:

function deleteTodo(id) {
  dispatch({ type: 'DELETE_TODO', id });
}

And you guessed it, we now just need to add a case in our reducers switch statement to handle the reduction, this is where we actually remove a Todo from the list and return the old state minus the deletion. We can do this easily because we have provided an id. In the same way we know which Todo to complete by passing an id, we can also delete an item, we just need to ensure that it returns the new state. We can achieve this with the array filter prototype.

case 'DELETE_TODO': {
  return state.filter((x) => x.id !== action.id);
}

Clearing All Todos

For the clearing of todos, we actually don't need much. When the action gets dispatched for the CLEAR_TODOS, the only thing being passed is the actual action type, no payload, because once we get into the reducer, we are simply going to return an empty array.

Here are the three different pieces of code you will need to make that happen.

Add an onClick() to the HTML button:

onClick={() => clearTodos()}

Add a function to handle the dispatch:

function clearTodos() {
  dispatch({ type: 'CLEAR_TODOS' });
}

And a case in our reducer function:

case 'CLEAR_TODOS': {
  return [];
}

Wrap Up

We have now worked our way through building the basics of a Todo application. We started with the basic structure of the Todo list and how to simply repeat our a list for each Todo, and eventually created all of the logic to manage the state of the list using a Redux style approach to state management. We covered adding a new Todo, deleting, completing a Todo and finally the ability to reset the entire Todo list (the easiest part of the reducer to complete).

Look out for more articles from us that will continue our journey into Hooks and advanced Redux concepts. We have covered the basics so far and plan on showing you how to continue to take advantage of all the wonderful ways that you can utilize React Hooks and other bleeding edge features of the framework.

I hope that this has helped you understand the basics of using React Hooks for reducers. 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.

SOLID Principles of UX, Part 2: Ergonomics & Beauty

$
0
0

In this second installment of Jessica Engstrom's five-part series on UX principles for developers, she explores the importance of ergonomics, beauty, inclusion, usability and accessibility.

If you missed my first post, you can catch up right here: SOLID Principles of UX, Part 1: Make Software Understandable. Otherwise, let's dive into part 2 below.

Ergonomics

Thinking about ergonomics is always a good idea. Having the right desk chair at work, the right keyboard and even the right pillow at night can make a huge difference. Ergonomics is something we should investigate when it comes to our user interfaces as well.

Reading up on platform design guidelines and using familiar components can help with this. The more the user must think about how to perform a task, the harder it will be to keep them. We want to minimize the learning curve, breaking down complicated tasks into smaller bits so it feels easy to understand and use.              

Given that we now see more and more devices of different shapes and resolutions and that many of them have touch-enabled screens, we need to take that into consideration.
Using simulators and emulators to test out our layout on different devices is invaluable.
When I design an app, I usually start designing at 5” which is somewhere in the middle of the “phone range.” Then I test the layout at 4” and 6” as well, just to make sure that it works.

If it doesn’t, I tweak until it works on all three.

Not testing it on both smaller and larger screens may cause some ergonomic issues and the same is true for not testing on a touch device. Like that you could accidentally press two buttons with one tap.

A human finger pad is on average 12mm across, so we must make sure that we add some space between the touch elements.

Some of the emulators and simulators have the option of “faking” touch so you don’t have to go out and buy multiple devices in all different sizes.

Take a thing like contrast as an example. If we have a little bad contrast between the background and our text or elements, they will be hard to read for anybody with eye-issues. But if we fix the contrast it will work both for people with and without eye-issues, so we have nothing to lose.

There have been many many studies done about typefaces and fonts. Many of them say that using a serif font family if you have large amount of text will help with eye fatigue. But if you are designing something for children in the “learning to read”-age or dyslexic people it might be a better idea to use a san-serif font family since some studies shows that it’s easier for those groups to recognize the letter because of the simplicity in the form.

Inclusion, Usability and Accessibility

We live in a world where we are becoming more and more aware of how inclusivity can benefit us all. Bringing inclusion, usability and accessibility to our design will benefit everybody, not only a certain group.

Having an inclusive design means that it’s usable for as many people as possible, no matter what region you live in, what device you are on or how fast your internet connection is.

If we look at the ISO standard (9241-11:2018) for Usability (Ergonomics of human-system interaction) it describes usability like this:

extent to which a system, product or service can be used by specified users to achieve specified goals with effectiveness, efficiency and satisfaction in a specified context of use

In other words an efficient page or app where the user feels comfortable navigating and feels like they are doing so in an effective and efficient way.

Accessibility is about not discriminating anyone regardless of age, disability or where you live. Of course we’re not discriminating on purpose, but it is according to the UN a basic human right to have access to information and communications technologies (including the web) so it doesn’t hurt to look into it.

We might think that “amputees are not my target audience” so I don’t have to think about one-handed navigation and that may very well be true, however we are not only excluding anyone who amputated their arm, but also anyone who had an accident and broke their arm or injured themselves at the gym and the parents of newborns.

Designing for people with bad eyes, color deficiency and dyslexia will not only benefit those groups but all our users!

Beauty

Although that it sounds obvious that a beautiful UI will appeal to the user, there are still too many UIs out there that have been neglected or not prioritized for it. Now, what "beautiful" is, as you all know, is individual and impossible to pinpoint. But what you can do is make sure you give the design part of the project a fair amount of time and read up on the design guidelines for the platform you are publishing on.

When apps are clearly made for one platform but gets released on multiple platforms there is a risk of an unattractive appearance. Like when apps have a back button in the UI on Android (or Windows phone back in the day) that have a hardware button for that.

Then it’s very clear that the app is not made for the platform and the UI feels off.

This is what I mean with beautiful. Not the latest and hottest design but a design that looks professional, that is aligned properly and looks like it fits in.

Do utilize the different platform design languages out there. Google has material design, Apple has human interface design and Microsoft has Microsoft design language or fluent.

A lot of research has gone into these guidelines and they will help you achieve much of what you just read about.

Stay tuned for the next post in this series, or for more, feel free to check out the webinar we recently hosted on the topic right here.

Resources

Check your website for contrast: http://www.checkmycolours.com/

ISO standard (9241-11:2018) for Usability: https://www.iso.org/standard/63500.html

Microsoft has a good inclusive design 101 guide on their design page: https://www.microsoft.com/design/inclusive/

Getting Started with Expander and Accordion for Xamarin.Forms

$
0
0

Have you ever been in a situation where you wanted to show more data inside your mobile app? Perhaps the issue was insufficient screen size on your mobile device, which makes it difficult to fit all the information you want to share. This is not an issue anymore! Telerik UI for Xamarin solves that for you. 

There are two new controls that you can find with the UI toolkit, which first shipped in the R3 2018 release. These controls solve the limited real estate problem on a mobile device while delivering a very elegant UI. Let me introduce you the Expander and Accordion controls of Telerik UI for Xamarin.

This blog post will get you familiar with these two controls and all the features and customization capabilities they provide. Both controls can expand or collapse their content and hold various components in their content panel. 

Expander control

Accordion control

As you can see both controls have a similar UI, but at the same time they serve different purposes. You can use the Expander to display the content of a single item, but if you want to have multiple items and only one of them to have the ability to expand at a time, you should go for the Accordion control.

Expander

RadExpander control has two main parts:

  • ExpanderHeader
  • Content

The snippet below shows how to define RadExpander in XAML:

<telerikPrimitives:RadExpander x:Name="expander" HeaderText="More Options">
   <telerikPrimitives:RadExpander.Content>
      <StackLayout Margin="10, 20, 10, 20">
         <StackLayout Orientation="Horizontal" Spacing="10">
            <telerikPrimitives:RadCheckBox/>
            <Label Text="Make my profile private"/>
         </StackLayout>
         <StackLayout Orientation="Horizontal" Spacing="10">
            <telerikPrimitives:RadCheckBox  />
            <Label Text="Only show my posts to people who follow me" />
         </StackLayout>
      </StackLayout>
   </telerikPrimitives:RadExpander.Content>
</telerikPrimitives:RadExpander>

Features

Here are some of the features the Expander control ships with:

  • Collapsed and Expanded States
  • Animation
  • Customization Options
  • Theming support

Collapsed and Expanded States

The control hosts the content in an expandable container that can be easily expanded/collapsed by tapping on its header. The current state of the control can be switched by the IsExpanded property.

The image below shows what the control looks like in its expanded/collapsed states:

Expander First Look

Animation

The RadExpander control provides a property which allows you to enable or disable the animation when the content is collapsed / expanded. If you want to enable/disable the animation you need to use the IsAnimationEnabled property. By default, the Animation is enabled.

Customization Options

The visual appearance of the control can be customized in a variety of ways, like:

  • Animation duration and easing can be set through the AnimationDuration and AnimationEasing properties.
  • Border Styling. You can change the color and thickness of the border surrounding the component.
  • Header location.The Expander Header can be placed at the top or at the bottom of the expandable container.
  • Header Customization.If the default Expander Header control doesn't suit your needs, you can use ExpanderHeader content control. This content control provides various of properties to customize the indicator’s text, location, color, rotation animation, font family and size. If you want to customize the ExpanderHeader, check our help article.

The image below shows what the RadExpander control looks like after customization:

Expander customization

Accordion

The RadAccordion control contains a set of collapsible content panels. Each panel (AccordionItem) consists of a Header (AccordionItemHeader) and Content. The Accordion control expands only one of its items at a time within the available space.

The snippet below shows how the RadAccordion can be defined in XAML:

<telerikPrimitives:RadAccordion x:Name="accordion">
   <telerikPrimitives:AccordionItem HeaderText="Attachments"IsExpanded="True">
      <telerikPrimitives:AccordionItem.Content>
         <telerikInput:RadButton Text="Attach files"
                         Margin="70, 20, 70, 20"
                         BorderColor="Blue"
                         BorderThickness="2"/>
      </telerikPrimitives:AccordionItem.Content>
   </telerikPrimitives:AccordionItem>
   <telerikPrimitives:AccordionItem HeaderText="Settings">
      <telerikPrimitives:AccordionItem.Content>
         <StackLayout Margin="10, 20, 10, 20">
            <StackLayout Orientation="Horizontal" Spacing="10">
               <telerikPrimitives:RadCheckBox  />
               <Label Text="Make my profile private" />
            </StackLayout>
            <StackLayout Orientation="Horizontal" Spacing="10">
               <telerikPrimitives:RadCheckBox  />
               <Label Text="Only show my posts to people who follow me" />
            </StackLayout>
         </StackLayout>
      </telerikPrimitives:AccordionItem.Content>
   </telerikPrimitives:AccordionItem>
   <telerikPrimitives:AccordionItem HeaderText="Rating">
      <telerikPrimitives:AccordionItem.Content>
         <telerikInput:RadShapeRating x:Name="rating" Margin="20"/>
       </telerikPrimitives:AccordionItem.Content>
   </telerikPrimitives:AccordionItem>
</telerikPrimitives:RadAccordion>

Features

Here are some of the features the Accordion control ships with:

  • Collapsed and Expanded States
  • Animation
  • Customization Options
  • Theming support

Collapsed and Expanded States

The RadAccordion control is designed in such a way that opening one AccordionItem automatically closes the previous displayed content.

The image below shows this functionality:

Accordion First Look

Animation While Expanding/Collapsing

The Animation that RadAccordion control provides while expanding/collapsing its content can be enabled/disabled through the IsAnimationEnabled property.

Customization Options

The Accordion control's header provides the following options for customization: 

  • Animation duration and easing can be set through the AnimationDuration and AnimationEasing properties.
  • Border Styling. You can change the way the Border around the control looks with the BorderColor and BorderThickness properties of the AccordionItem.
  • Header Customization.If the default AccordionItemHeader does not suit your needs, you can use AccordionItemHeader content control. This content control provides various properties to customize the indicator’s text, location, color, rotation animation, font family and size. If you want to customize the AccordionItemHeader, check our help article.

Here's what the RadAccordion control looks like after customization:

Accordion customization

Both RadAccordion and RadExpander come with built-in Theming Support. Using a predefined theme provides your application with a consistent look and feel across all platforms.

We would love to hear what you think about Expander and Accordion controls and how we can continue to improve them. If you have any ideas for features to add, do not hesitate to share this information with us on our Telerik UI for Xamarin Feedback portal.

Don’t forget to check out the various demos of the controls in our SDK Sample Browser and the Telerik UI for Xamarin Demos application.

If you have not yet tried the Telerik UI for Xamarin suite, take it out for a spin with a 30-day free trial, offering all the functionalities and controls at your disposal at zero cost.

Happy coding with our controls!

Creating a Reusable, JavaScript-Free Blazor Modal

$
0
0

In this guide, Chris Sainty helps you learn how to build a reusable modal without using any JavaScript for your Blazor and Razor applications.

Modals are a common feature of today’s web applications. You will find them in most UI frameworks, and they range from simple confirmation boxes to full-blown forms. In this post, I’m going to walk you through building a JavaScript-free, reusable modal for your Blazor/Razor Components applications. To make things even more interesting, we’re going to build the modal in such a way that we can pass it components to display instead of just plain text or markup strings.

For anyone new to Blazor, let me give you a quick overview. Blazor is a SPA-like framework developed by Microsoft. There is a client-side model, which runs via a WebAssembly-based .NET runtime. There’s also a server-side model (Razor Components), which runs on the standard .NET Core runtime. You can find out more at Blazor.net.

Getting Set Up

If you’re new to Blazor development, then you will need to make sure you have the latest version of the .NET Core SDK installed. You will also need to install the Blazor Language services, as well as the Blazor templates via the dotnet CLI.

dotnet new -i Microsoft.AspNetCore.Blazor.Templates

Creating a Blazor Library

We want to be able to use our modal in whatever projects we see fit. The best way to achieve this is by using the Blazor Library project included in the CLI templates we installed above. This project type works in a similar way to a class library and allows us to share components and their assets (images, CSS, etc.) between Blazor applications.

As this project type is currently only available using the dotnet CLI, we can run the following commands to create a new directory as well as the Blazor Library project.

mkdir BlazorModal
cd BlazorModal
dotnet new blazorlib

Now we have a new Blazor library project we can open in Visual Studio. Before we do anything else, let’s remove some of the default items that come with the template. The only thing we want to keep is the styles.css, so the project should look like this.

EmptyBlazorLibrary

The first thing we are going to build is the ModalService. This is going to be the glue which will join our modal component with any other components that wish to use it. In the root of the project, add a new class called ModalService.cs with the following code.

using Microsoft.AspNetCore.Blazor;using Microsoft.AspNetCore.Blazor.Components;using System;namespace BlazorModal.Services
{publicclassModalService{publicevent Action<string, RenderFragment> OnShow;publicevent Action OnClose;publicvoidShow(string title, Type contentType){if(contentType.BaseType !=typeof(BlazorComponent)){thrownewArgumentException($"{contentType.FullName} must be a Blazor Component");}var content =newRenderFragment(x =>{ x.OpenComponent(1, contentType); x.CloseComponent();});
OnShow?.Invoke(title, content);}publicvoidClose(){
OnClose?.Invoke();}}}

So what’s going on here?

The class exposes two methods, Show() and Close(), as well as a couple of events. The Show method is the interesting one, though. After checking that the type passed in via the contentType argument is a Blazor component, it creates a new RenderFragment using said type. This is then passed into the OnShow event so it can be used by an event handler. We’ll get to that in a bit.

Now before we go any further, I know what some of you are thinking… What’s a RenderFragment??

In simple terms, a RenderFragment represents a piece of UI. Blazor uses these RenderFragments to output the final HTML in the browser. In the code above, if we passed in a type of Foo, the resulting HTML would look like this.

<Foo></Foo>

There are many interesting uses for RenderFragment especially when dealing with dynamic component generation, but that is a topic for another time. Let’s crack on.

IServiceCollection Extension

When creating a library, I always find it a good idea to provide an extension method which can handle registering services with the DI container. It makes sure that everything gets registered with the correct scope, plus consumers only have to add a single line to their apps. Add a new class to the root of the project called ServiceCollectionExtension.cs with the following code.

using BlazorModal.Services;using Microsoft.Extensions.DependencyInjection;namespace BlazorModal
{publicstaticclassServiceCollectionExtensions{publicstatic IServiceCollection AddBlazorModal(this IServiceCollection services){return services.AddScoped<ModalService>();}}}

Now that the service is in place, we can build the modal component. I always like to separate the logic and the markup of my components. This is achieved by creating a base class with all the logic that the component will inherit, leaving the component with just markup.

First add a new Razor View named Modal.cshtml, then add a new class called Modal.cshtml.cs. The reason for this naming is so that Visual Studio will nest the base class under the Razor View. You don’t have to follow this convention, but it does keep the solution window nice and tidy. Also be sure it’s a Razor View you select and not a Razor Page — Razor Pages won’t work.

Let’s look at the base class logic first.

Oh! One other thing. You will need to change the name of the base class. As you can see in the code below, I’ve stuck Base on the end. Again, you can call it what you want. Model is another popular choice. But this is to stop a name clash with the code generated by Modal.cshtml.

Component Logic

using BlazorModal.Services;using Microsoft.AspNetCore.Blazor;using Microsoft.AspNetCore.Blazor.Components;using System;namespace BlazorModal
{publicclassModalBase: BlazorComponent, IDisposable
{[Inject] ModalService ModalService {get;set;}protectedbool IsVisible {get;set;}protectedstring Title {get;set;}protected RenderFragment Content {get;set;}protectedoverridevoidOnInit(){
ModalService.OnShow += ShowModal;
ModalService.OnClose += CloseModal;}publicvoidShowModal(string title, RenderFragment content){
Title = title;
Content = content;
IsVisible =true;StateHasChanged();}publicvoidCloseModal(){
IsVisible =false;
Title ="";
Content =null;StateHasChanged();}publicvoidDispose(){
ModalService.OnShow -= ShowModal;
ModalService.OnClose -= CloseModal;}}}

Working from the top, we inject an instance of the modal service. Then we’re declaring a few parameters that we’ll be using in the markup side of the component. We’re overriding one of Blazor’s lifecycle methods, OnInit, so we can attach the ShowModal and CloseModal methods to the respective OnShow and OnClose events from the modal service.

The ShowModal and CloseModal methods are pretty self-explanatory. The only part that is probably worth pointing out is the call to StateHasChanged. We need to call StateHasChanged due to the fact that these methods are invoked from outside of the component. And all this method does is tell the component that something has changed so it needs to re-render itself.

Finally, the component implements the IDisposable interface so we can unregister the event handlers when the component is destroyed.

Now let’s look at the markup side.

Component Markup

@inherits ModalBase

<div class="bm-container @(IsVisible ? "bm-active" : string.Empty)">

    <divclass="bm-overlay"onclick="@CloseModal"></div><divclass="blazor-modal"><divclass="bm-header"><h3class="bm-title">@Title</h3><buttontype="button"class="bm-close"onclick="@CloseModal"><span>&times;</span></button></div><divclass="bm-content">
            @Content
        </div></div></div>

The first line is a directive stating the component is inheriting from ModalBase. Next we have a container div with a bit of Razor syntax which uses the IsVisible property to toggle the bm-active class. This is what’s responsible for showing or hiding the component.

The next div is for creating a darkened overlay that the modal will sit on. This also has a onclick handler which closes the modal if a user clicks anywhere on the overlay.

Then we come to the modal itself. It has a header which displays the title along with a button that can be used to close the modal. The @Content marker is where the RenderFragment we talked about earlier will be displayed.

Adding a Bit of Style

No component would be complete without a bit of styling. There is nothing special or clever her — I’m by no means a CSS guru. But the following classes should give everything a nice clean look and feel with the modal being centered both horizontally and vertically on the page. All thanks to the wonders of Flexbox!

.bm-container{display: none;align-items: center;justify-content: center;position: fixed;width:100%;height:100%;z-index:2;}.bm-overlay{display: block;position: fixed;width:100%;height:100%;z-index:3;background-color:rgba(0,0,0,0.5);}.bm-active{display: flex;}.blazor-modal{display: flex;flex-direction: column;width:50rem;background-color:#fff;border-radius:4px;border:1px solid #fff;padding:1.5rem;z-index:4;}.bm-header{display: flex;align-items: flex-start;justify-content: space-between;padding:002rem 0;}.bm-title{margin-bottom:0;}.bm-close{padding:1rem;margin: -1rem -1rem -1rem auto;background-color: transparent;border:0;-webkit-appearance: none;cursor: pointer;}

Testing it Out

We have now built our modal, but it would be good to see it all in action. Let’s add a standalone Blazor app to the solution so we can try it out. This will work just as well with a server-side project if you prefer.

Right-click on the solution and Add > New Project. Then select ASP.NET Core Web Application and give it a name. I’m going to call it BlazorTest. Finally, select Blazor as the project type from the dialogue.

If you prefer, you could use the CLI with the following command.

dotnet new blazor -n BlazorTest

We also need to add a project reference from the BlazorTest (or whatever you’ve called it) to the BlazorModal project. Your solution should now look like this.

SolutionWithTestProject

Setting Up the Test Project

Now that we have a test project, we need to do three things to register our modal for use.

First, we need to add the following lines into the _ViewImports.cshtml.

@using BlazorModal
@using BlazorModal.Services

@addTagHelper *, BlazorModal

The using statements will save us having to use fully qualified names when using the ModalService. The addTagHelper will import all components from the specified namespace.

Second, we need to add our ModalService to the DI container. Due to our earlier work creating the service collection extension method, we just need to add the following to the ConfigureServices method in Startup.cs.

using BlazorModal;// Other code omitted for brevitypublicvoidConfigureServices(IServiceCollection services){
services.AddBlazorModal();}

The third and final task is to add the modal component to the MainLayout.cshtml.

@inherits BlazorLayoutComponent

<Modal/><divclass="sidebar"><NavMenu/></div><!—Remainingcodeomittedforbrevity-->

We have now setup the test project to use our modal component.

Creating a Test Component

In order to test our modal we are going to create a simple form component that we will display in our modal. In the Pages folder, add a new Razor View called SimpleForm.cshtml and add the following code.

@if (ShowForm)
{
<divclass="simple-form"><divclass="form-group"><labelfor="first-name">First Name</label><inputbind="@FirstName"type="text"class="form-control"id="first-name"placeholder="Enter email"/></div><divclass="form-group"><labelfor="last-name">Last Name</label><inputbind="@LastName"type="text"class="form-control"id="last-name"placeholder="Enter email"/></div><buttononclick="@SubmitForm"class="btn btn-primary">Submit</button></div>
}
else
{
<divclass="alert alert-success"role="alert">
Thanks @FirstName @LastName for submitting the form.
</div>
}

@functions {
bool ShowForm { get; set; } = true;
string FirstName { get; set; }
string LastName { get; set; }

void SubmitForm()
{
ShowForm = false;
}
}

The component takes the user’s first and last names and then shows them a personalized message after they click submit.

All that’s left is to call it. Let’s make some additions to the Index component to call our modal with the simple form we’ve just created.

@page "/"
@inject ModalService ModalService

<h1>Hello, world!</h1>
Welcome to your new app.

<SurveyPromptTitle="How is Blazor working for you?"/><hr/><buttononclick="@ShowModal">Show Modal</button>

@functions {
private void ShowModal()
{
ModalService.Show("Simple Form", typeof(SimpleForm));
}
}

And we’re done! This is what the finished Index component looks like.

Running Our Test App

We can now run our test app and if all has gone to plan it should work something like this.

BlazorModal

Wrapping Up

In this post, we’ve built a reusable modal without using any JavaScript. We’ve also built it in such a way that we can display other components which I think is a really nice feature and fits nicely with Blazor’s component model.

All the code for this post is available on my GitHub.

Related News

Looking for more news and info on Blazor? Check out these recommended resources:

Building Documentations with Vue Using Vuepress

$
0
0

In this tutorial, learn how you can build your documentation with VuePress, which offers a flexible, configurable and easy to deploy option for creating static sites.

As a developer, trustworthy documentation is a must. Presenting a clear guide of the different aspects of an application helps make information accessible not just to consumers of your application but also to yourself as the need arises. Therefore, having access to a system that eases the process of creating robust and reliable documentation is a plus, and this is where VuePress comes into play.

VuePress is a static site generator that is comprised of two parts: a minimalistic static site generator with a powerful theming system and plugin API, alongside a default theme for generating documentation in no time. VuePress is powered by Vue, Vue Router and webpack. It generates single-page applications that offer great performance, have pre-rendered HTML and are SEO-friendly.

In this post, we’ll walk through how to create documentations with Vue using VuePress. Before we get started, make sure you have Node and NPM installed on your PC. To ensure you have them installed, run the following command on a terminal:

    node -v &&npm -v

Note: VuePress requires Node.js version >= 8.

If these commands don’t exist, visit the official Node website to download and install it on your PC.

Once you’re sure that Node and NPM are available on your PC, run the following command to install VuePress globally:

npm i -g vuepress@next
        OR
    yarn global add vuepress@next

To use the lastest VuePress features like Plugins and Themes, we’ll need to install the version 1.0 alpha.

We’ll be writing markdown, which VuePress compiles into HTML using a library called markdown-it. To get started, create a folder called vue-docs and enter the folder:

    $ mkdir vue-docs &&cd$_

Creating Project Files

VuePress analyzes and parses folders and files according to their structure. VuePress has a strict folder-naming convention and it needs to be followed for VuePress to successfully parse and compile the folders and files.

Typically, the VuePress folder structure looks like this:

    vue-docs/
      docs/
        .vuepress/
          styles/
          config.js
        README.md
        guide/
          README.md

Inside the .vuepress directory is where we can further customize the default VuePress theme, create global configuration and create custom components. The .vuepress/styles folder contains global style files. Here we can override the default vuepress colors.

The config.js file is the entry file for configuration and the README.md is the index file and will route to the / path. The guide folder would route to /guide/, and any files within it will have the /guide/ prefix.

Inside the vue-docs directory, run npm init -y to create a package.json file and scaffold a new project. Next, install vuepress locally by running the following command:

npm i vuepress@next

With VuePress installed, we’re set to go, as VuePress provides a default documentation theme. But in order to personalize the application, we’ll need to configure it further since the default theme doesn’t come with enough content.

Within the vue-docs directory, create a folder named docs and cd into the folder. This folder houses all the project configurations and content.

mkdir docs &&cd$_

Create a .vuepress folder within the docs directory, place cd into the folder and create a file called config.js:

mkdir .vuepress &&cd$_&&touch config.js

The config.js file will hold the general configuration of the application. Within the file, we can describe the application, give it a title and further configure the interface of the application, providing navigation links and choosing how to display the navigation bar. You can read more on the configuration options here.

Open the config.js file and copy the code below into it.

module.exports ={
  title:'Vue Docs',
  description:'Building documentations with Vue using VuePress',
  themeConfig:{
    nav:[{ text:'Getting Started', link:'/getting-started/'},{ text:'API', link:'/api/'},],},};

In the config file, we provided a title for the application as well as the descriptions. In the themeConfig object, we tell VuePress the structure for the navigation. On the header, two anchor elements will be displayed, routing to /getting-started and /api. Before we create content for those routes, we’ll create the index page.

Creating the Index Page

The README.md file located in the root of the docs directory is parsed and compiled as the index page. Using front-matter, we can declare the page as home and VuePress will provide a landing page view with a CTA (call to action) button.

Create a README.md file within the docs folder, open it using an editor and update it with the code below:

    ---
    home: true
    actionText: Get Started
    actionLink: /getting-started/
    ---
    ## Great documentation
    We can create robust and reliable documentations using VuePress

    ## Robust services
    Satisfied conveying an dependent contented he gentleman agreeable do be. Warrant private blushes removed an in equally totally if. Delivered dejection necessary objection do mr prevailed. Mr feeling do chiefly cordial in do. Water timed folly right aware if oh truth. Imprudence attachment him his for sympathize. Large above be to means. Dashwood do provided stronger is. But discretion frequently sir the she instrument unaffected admiration everything.

To boot up a dev server after configuring and creating an index page, run the following command within the vue-doc/ folder:

    vuepress dev docs

This will start up a server on http://localhost:8080. Your view should be similar to the screenshot below:

Vue

Creating Routes

In the config file, we included anchor links to two non-existent routes, /getting-started and /api. To create these routes, we need to create two folders within the docs folder that match the naming of these routes. First, we’ll create the /getting-started route. To do this, create a folder named getting-started within the docs folder:

mkdir getting-started &&cd$_

Within the newly created getting-started folder, create a file README.md, which will serve as the index view of the route. Open the file and update it with the code below:

    ---
    title: Vue-docs| Getting started
    description: Getting started with documentations using VuePress
    ---
    # Getting started

    !\[Hero\](https://images.unsplash.com/photo-1513985768785-f12f38ce03cb?ixlib=rb-0.3.5&ixid=eyJhcHBfaWQiOjEyMDd9&s=1eb9fd6388ea9c35e1c7731a8d9e0bdf&auto=format&fit=crop&w=750&q=80)

    Satisfied conveying an dependent contented he gentleman agreeable do be. Warrant private blushes removed an in equally totally if. Delivered dejection necessary objection do mr prevailed. Mr feeling do chiefly cordial in do. Water timed folly right aware if oh truth. Imprudence attachment him his for sympathize. Large above be to means. Dashwood do provided stronger is. But discretion frequently sir the she instrument unaffected admiration everything.

    Tiled say decay spoil now walls meant house. My mr interest thoughts screened of outweigh removing. Evening society musical besides inhabit ye my. Lose hill well up will he over on. Increasing sufficient everything men him admiration unpleasing sex. Around really his use uneasy longer him man. His our pulled nature elinor talked now for excuse result. Admitted add peculiar get joy doubtful.

    Comfort reached gay perhaps chamber his six detract besides add. Moonlight newspaper up he it enjoyment agreeable depending. Timed voice share led his widen noisy young. On weddings believed laughing although material do exercise of. Up attempt offered ye civilly so sitting to. She new course get living within elinor joy. She her rapturous suffering concealed.

Below the header is an external image asset included using the markdown format. Using frontmatter, we can set dynamic properties on each page like the page title, and description.

When you visit the http://localhost:8080/getting-started/ path, you should see a view similar to the screenshot below:

Vue

 

On the navigation bar, you can see that the getting started link has been highlighted, this is a plugin that is package with VuePress. We’ll talk more on using plugins later in the article. Separating and grouping more content requires basic knowledge of Markdown and front-matter. Additional pages within the getting-started path can be added by creating markdown files within the getting-started folder.

Next, we’ll create the /api route. Create a folder named api in the docs root directory, within the api folder, create a file README.md:

mkdir api &&cd$_&&touch README.md

Open the file using an editor and update it with the contents below:

    ---
    title: Vue-doc API
    description: API reference for VUE-docs
    ---
    # API
    Tiled say decay spoil now walls meant house. My mr interest thoughts screened of outweigh removing. Evening society musical besides inhabit ye my. Lose hill well up will he over on. Increasing sufficient everything men him admiration unpleasing sex. Around really his use uneasy longer him man. His our pulled nature elinor talked now for excuse result. Admitted add peculiar get joy doubtful.

    Comfort reached gay perhaps chamber his six detract besides add. Moonlight newspaper up he it enjoyment agreeable depending. Timed voice share led his widen noisy young. On weddings believed laughing although material do exercise of. Up attempt offered ye civilly so sitting to. She new course get living within elinor joy. She her rapturous suffering concealed.

    Or kind rest bred with am shed then. In raptures building an bringing be. Elderly is detract tedious assured private so to visited. Do travelling companions contrasted it. Mistress strongly remember up to. Ham him compass you proceed calling detract. Better of always missed we person mr. September smallness northward situation few her certainty something.

    View fine me gone this name an rank. Compact greater and demands mrs the parlors. Park be fine easy am size away. Him and fine bred knew. At of hardly sister favour. As society explain country raising weather of. Sentiments nor everything off out uncommonly partiality bed.

    Resolution possession discovered surrounded advantages has but few add. Yet walls times spoil put. Be it reserved contempt rendered smallest. Studied to passage it mention calling believe an. Get ten horrible remember pleasure two vicinity. Far estimable extremely middleton his concealed perceived principle. Any nay pleasure entrance prepared her.

We dynamically set page title and description properties on this page using frontmatter. When you visit http://localhost:8080/api/ you should get a view similar to the one below:

Vue

Changing Styles

Updating color constants in our application is fairly straightforward. To using custom color constants, create a new file called override.styl in docs/.vuepress/. Using the variable names assigned to color as stated in the official documentation, we’ll edit the override.styl script to change the accentColor. Copy the content below into the override.styl file:

    $accentColor = #227CD9

You’ll immediately notice a change in your view as the accent color is updated to a lower shade of blue.

Using Plugins

VuePress supports external plugins that can be used to extend your application. With the help of plugins, you can add an extra layer of functionality to your application. With the help of plugins, your application can register a service worker, thus caching content and making your application offline first.

There’s an image present in our application, and, using an official VuePress plugin, we’ll add the Medium zoom animation to the images. The first step is to install the plugin. Run the command below to install the plugin:

    yarn add -D @vuepress/plugin-medium-zoom

After the installation is complete, we’ll reference the plugin in the config.js file. In the config.js file, add an extra field named plugins in the exported object. The value of the field will be an array containing your project’s plugins. Update the config.js file to add the Medium zoom plugin:

    module.exports ={
      title:'Vue Docs',
      description:'Building documentations with Vue using VuePress',
      themeConfig:{...},
      plugins:{'@vuepress/medium-zoom':true},};

After restarting your development server, you’ll notice that the image zoom feature has been added to the application.

There are several official plugins provided by VuePress — some have been built into the project and some require manual installation. Visit the plugins page of the documentation to view the provided plugins.

Using Themes

If the official VuePress theme doesn’t feel like enough, you’ll be glad to know that VuePress comes with support for external plugins. Using an external theme is very similar to using a plugin. So the first step as always is to install the theme and then reference it in the config.js file.

After installing a theme, update the config.js file to include a theme field:

module.exports ={
  title:'Vue Docs',
  description:'Building documentations with Vue using VuePress',
  themeConfig:{
    nav:[{ text:'Getting Started', link:'/getting-started/'},{ text:'API', link:'/api/'},],},
  plugins:{'@vuepress/back-to-top':true,'@vuepress/medium-zoom':true},
  theme:'**installed_theme**',};

Now you’ve successfully created the documentation system. To build your application in preparation for deployment, run the command below in your project folder:

    vuepress build docs

This will create a dist folder within the .vuepress directory. You can easily deploy this folder using a static deployment provider like Netlify, Zeit Now and Github pages.

Conclusion

Creating documentations using static site generators ensures that your sites are fast, configurable, easily maintained and secure. With VuePress, sites can be generated in no time, with little or no configuration. These sites are static, and as such they can be deployed easily with an array of cheap and mostly free options to pick from. You can further modify the basic site we’ve created to suit your needs using the many features provided by VuePress. These features and more are available in the official documentation also built using VuePress.

For More Info on Vue

Want to learn about creating great user interfaces with Vue? Check out Kendo UI for Vue, our complete UI component library that allows you to quickly build high-quality, responsive apps. It includes all the components you’ll need, from grids and charts to schedulers and dials.

Kendo UI R1 2019 Release Webinar Recap

$
0
0

The R1 2019 release webinar for Kendo UI highlighted many of the latest features that we recently added. Catch up with a summary of the webinar and its recording.

Recently, we shipped the R1 2019 release of Kendo UI. To help developers understand the impact of this release, we hosted a release webinar that walked through the latest features. This blog post is a summary of the webinar as well as answers to questions asked by attendees. 

The latest release of Kendo UI is packed with features. We’ve added a slew of new controls, numerous grid improvements, and native support for Vue, rounding out Kendo UI’s native support for three of the most popular JavaScript frameworks (Angular, React, and Vue). Carl Bergenhem (PM for Kendo UI) provided an overview of the latest release in a series of blog posts:

Kendo UI R1 2019 Release Webinar

Our webinar highlighted many of the great features we’ve added to the R1 2019 release of Kendo UI:

The webinar was hosted by Eric Bishard, Carl Bergenhem, Alyssa Nicoll, and myself (John Bristowe). Don’t worry if you didn’t get a chance to watch it live. We’ve posted it to our YouTube channel. In fact, you can watch it now!

Webinar Questions and Answers

During the webinar, we asked attendees to ask questions and offered the very cool drone as a prize for the best one. The winner is Bill Schubarg. Congratulations and thanks for your great question!

We answered a number of questions during the webinar as well as on Twitter through the hashtag, #HeyKendoUI. Here’s a sampling of the questions we received along with their answers:

What are the jQuery requirements for the latest version of Kendo UI and/or its upgrade path?

A list of prerequisites is available on our website. The current official version of Kendo UI requires jQuery 1.12.4. Usually, each newly released jQuery version introduces breaking changes and is not compatible with the existing Kendo UI versions. In such cases, use the previous jQuery version until the next official Kendo UI version that resolves the issue is released. Normally, the jQuery version that is shipped with the Kendo UI service packs is not changed but is updated in major releases.

Does the new DateRangePicker widget support different cultures?

Yes, we do offer localization/globalization throughout all of our widgets, including the DateRangePicker! You can read more about this support on our website: Localization Overview.

Does Kendo UI for Vue support mobile development?

Yes, you can use Kendo UI for Vue to build responsive web applications that work well in mobile browsers. You can also use Kendo UI for Vue to build a PWA. I’d also recommend NativeScript if you’re looking to build a native mobile application with JavaScript and Vue.

Does the Grid component in Kendo UI for Vue have a pop-up editor?

The Grid component wrapper supports editing with a pop-up editor. At the same of this writing for the R1 2019 release, the native Grid component does not support editing through a pop-up editor.

Thank You

Thanks to everyone who joined us for the webinar, we received a lot of great feedback. We hope you love the new features and improvements we've made to Kendo UI in the R1 2019 release. Please feel free to leave your thoughts in our Feedback Portal or in the comments below.

Telerik R1 Release Webinar Recap

$
0
0
R1 2019 was a big Telerik release, with a focus on delivering Modern UI and Developer Productivity. Let's recap the webinar and product features!

It’s the first day at work after the nice and relaxing holidays. You are fresh and pumped to start the new year right by getting stuff done. But by mid-day, you quickly realize you are back exactly where you had left. The same stringent delivery deadlines and projects with UI so antiquated that they give you the chills.

Time to chin up. Your beloved Telerik developer tools just had a big R1 2019 release, that sets the tone for the rest of the year. To deliver your software development projects on time and to the delight of your users, you need awesome tooling. Modern, cutting-edge developer tooling should elevate your development experience and enable you to deliver solutions faster than what you would have envisioned even a few months back. That’s exactly what the latest Telerik DevCraft release promises. No matter what be your app platform – mobile, web or desktop, this R1 release should make developers more productive.

Relive the Content

On Jan 18th 2019, Ed Charbeneau and I (Sam Basu) hosted the Telerik R1 Release Webinar - livestreamed from our global HQ in Boston. It is always a daunting ask for us to do justice to all the product updates in the Telerik family within an hour, but we try. If you missed our webinar, got interrupted or just want to catch up, we have the recording up in full HD.

Something for Everyone

Telerik DevCraft is a diverse product portfolio and R1 2019 was a big release. Across all product updates though, the theme remains the same - Modern UI and Developer Productivity.

Telerik products have always been future-facing - riding the waves of what's latest in the .NET developer ecosystems. We are known to support new tools/technologies in .NET land before they are even released formally. Along those lines, Telerik R1 2019 release comes with support for Preview bits of two big upcoming giants - WPF/WinForms on .NET Core 3 and Visual Studio 2019 for all .NET tooling.

FutureFacing
 

We try pushing the envelope towards the future, while keeping existing products stable with continued enhancements. You can benefit from all of our R1 release goodness - just go get the latest Telerik bits through NuGet, Control Panel or plain downloads. Since we strive to make developers successful, we take pride and pour in efforts behind Documentation and Feedback portals - both redesigned recently.

Here's a quick sampling of major product updates across the Telerik family:

Web

Telerik UI for ASP.NET Core, MVC and AJAX

  • New MultiViewCalendar & DateRangePicker components
  • New grid features for ASP.NET MVC/Core
  • New MultiColumnComboBox for ASP.NET AJAX

Telerik UI for Blazor

  • Early preview bits to support experimental Blazor & server-side Razor components
  • Essential Grid & few more controls

Mobile

Telerik UI for Xamarin

  • New PDFViewer, Popup & DockLayout controls
  • New scheduling features, including add/edit & recurring appointments
  • Header & footer support in ListView
  • Localization & Globalization support

Desktop

Telerik UI for WPF & WinForms

  • New NavigationView (aka Hamburger menu)
  • Diagram Ribbon UI & HyperlinkButton controls for WPF
  • Charts support in RadSpreadsheet & RadSpreadProcessing
  • New TabbedForm, FontDropDownList, ButtonTextBox & TimeSpanPicker controls for WinForms
  • New Grid features, including TimeSpan editor & TimeSpan column for WinForms
  • New MultiColumnComboBox column in WPF Grid
  • Support for high-performance asynchronous exporting for WPF
  • New CrystalDark theme for WinForms

Reporting, Testing, and Productivity Tools

Telerik Reporting & Report Server

  • Improved Web Viewers User Experience for Telerik Reporting
  • Report Definitions Localization for Telerik Reporting & Report Server
  • Scalability of the Report Scheduling Service for Telerik Report Server
  • Improved Report Preview User Experience for Telerik Report Server
  • Deploy report rendering engine along with the reports web service on .NET Core – both on Windows and Linux

Telerik Fiddler & JustMock

  • Fiddler now cross-platform for Mac & Linux
  • Fiddler Decoding of encoded requests/responses
  • JustMock supports .NET Core
  • New JustMock Developer Console
  • JustMock CLI support for CI/CD pipelines

Addressing Feedback

One of the consistent pieces of feedback we get during Telerik Release webinars is the desire to see more of a desired/most used technology. We all have our beloved products and it is only natural to want to see more of it. From our side, it is quite a serious challenge to cover all the product updates across the Telerik family within an hour. Our teams pour in their efforts to make releases shine and each product deserves air time.

So, how do we do justice to all products? We'll try changing up the webinar format a little - starting with our R2 release, you'll see the next Telerik Release Webinar split up in two:

  1. Part 1 | 45 mins - Intro + Web technologies + Report technologies
  2. Part 2 | 45 mins - Mobile technologies + Desktop technologies + Productivity tools

With a single webinar registration, you'll be able to attend either or both sections, with a small break in between. We hope this new format will cater to specific interests and be better suited to showcase the plethora of product updates we cover during the release webinar.

Pertinent Q/A

We answered a lot of questions during the webinar - both on Twitter and on the Q/A panel. A few of the Q/A were important enough to resurface for everyone's visibility:

Q: Will Telerik UI for Blazor just be Kendo UI Core wrappers?
A: Telerik UI for Blazor is not made of Kendo UI wrappers and will have no jQuery dependencies. We are writing native UI Components for Blazor from the ground up.

Q: Is Blazor fully compatible with Internet Explorer and Edge?
A: Blazor running client-side through WebAssembly is meant for modern evergreen browsers, but has fallback support for older browsers through polyfills. Telerik UI for Blazor will have the same browser support as the Blazor framework, both for client-side runtime or Razor Server Components.

Q: With Telerik UI for Blazor, is it safe to assume that Blazor components will support Material Design?
A: Telerik UI for Blazor will support three themes out of the box - Default (a flat theme), Bootstrap 4 and Material Design.

Q: Can we build Mac desktop apps with .NET Core 3?
A: Not yet. While .NET Core runtime is perfectly compatible on Mac/Linux, there is no UI technology yet that can lift & shift Windows desktop apps. Xamarin.Mac or Mac support for Xamarin.Forms are good candidates for reaching the Mac desktop.

Q: Any plans/news to support/embrace UNO UWP Platform and Universal XAML?
A: We are keeping a close eye on Uno and Universal XAML promise in particular.

Until Next Time

That's it then for the Telerik R1 Release. We're known to make Modern UI for .NET technologies and this is one of the most exciting times to be a .NET developer. With R1, we tried pushing the envelope on web/mobile/desktop fronts while enriching utilitarian reporting services and making developers more productive.

Hope you all enjoy the new features across Telerik products. Use them and please give us feedback - If you haven't yet, be sure to download a trial or upgrade to the latest release here. We'll see you all during our next R2 release. Until then, happy coding!


KendoReact R1 2019 Webinar Recap

$
0
0

We recently hosted a webinar that highlighted the latest features in the R1 2019 release of KendoReact. Catch a summary of the webinar as well as answers to some of the questions that were asked.

The KendoReact R1 2019 release is packed with new components, features and styling options. To get access to these features, one simply needs to install the latest version of the individual packages that you may already be using from KendoReact. The latest bits are amazing, but we also cover all updates that have been released since our last webinar (R3 2018)!

KendoReact

In case you missed it, here's a summary of the top highlights that we covered during the webinar:

A more in depth review of the latest features can be read in our What's New in KendoReact R1 2019 article by Carl Bergenhem!

KendoReact R1 2019 Release Webinar

The webinar was hosted by John Bristowe, Carl Bergenhem, and myself Eric Bishard. Don't worry if you didn't get a chance to watch it live. We've posted it to our YouTube channel. In fact, you can watch it now!

Webinar Prize Winner

During the webinar, we asked attendees to ask questions and offered a very cool drone as a prize for the best one. The winner is Harry Singh. Congratulations and thanks for your great question!

Webinar Questions and Answers

We answered a number of questions during the webinar as well as on Twitter through the hashtag, #HeyKendoReact. Here's a sampling of the questions we received along with their answers:

Do we have inline filtering? something like jqGrid?
Grid Filtering is what you're looking for.

Does Grid Filtering work with server side filtering as well?
Yes. Since you control the state and Grid Filtering works with controlled state, you can format a request to the server and filter it server-side and send it back.

I have a license for Kendo UI for jQuery, does it also cover KendoReact?
Yes, Kendo UI (our traditional license) is a bundle that contains all of our support for JS frameworks - so you already have access!

DropDownButton wasn't actually demoed I think... is it just a DropDownList without the arrow?
The KendoReact DropDownButton looks like the Button and when clicked, it displays a popup list with action items (each and individual button). Check that component out on the KendoReact DropDownButton docs page!

When you buy a license do you get access to the source files?
Yes, all licenses come with source code access!

Are the column filters stored pre-session or is there any other mechanism to store it per user rather than using a database to store it?
It's up to you! As the grid state can easily be serialized you can create session storage, use local storage, or something else to save and load the state :).

Can I use an object instead of a string for DropDownList items?
Yes, Just take a look at our data and value binding for our KendoReact DropDownLists.

How am I notified that a filter is on a column without having to click on each one individually?
Since filters can be tied to your state, you could always use that as a way to be notified (programmatically). You can also apply filters via the state (and outside of the component) to filter the Grid's data.

When do you think we will have the DateTimePicker, we want to convert our app to React from jQuery Kendo UI and we use that component a lot?
It's on our road map and this component in particular was specifically mentioned at the end of the Webinar by Carl. He said the DateTimePicker will most likely be one of the last things needed to round out support in KendoReact for form elements. Very soon!

Has anyone ever asked for a control like the Splitter that can turn a pane into a window similar to what you can do in Visual Studio?
Great suggestion. We have not, but we take feedback from our customers very seriously. We have a feedback portal specifically for requests like this. Please submit your idea!

How much time of the whole development process can you say a front end developer saves using Kendo UI?
That's a tough question to provide a definitive answer. These components are built to save development time, absolutely.

How many panes can be added in one Splitter?
Unlimited panes and sub-panes! However, I do recommend thinking about the structure from a UX point of view. Don't go too crazy!

I wanted to know if we can show any indicator on which column the grid was filtered on, this is especially helpful when multiple columns are filtered on?
Yes, the icon is updated when the filter is applied.

Does the Grid handle drag & drop?
Not yet, however; we are working on this!

Do we need to use React 16 or React 15 for KendoReact?
We support React 16+ :)

Does InputMask save the mask characters also or just the digits when posting the data? I'm guessing it only saves the digits?
It's up to you! We have props for both, the value (with mask) and the raw value (without the mask).

Are TypeScript definitions available, or will they be made available? (Is this on the road map)?
While our demos are in plain JS, you can use TS and we offer TS definitions! We have people using KendoReact with TypeScript already :)

Ah great, I could not find it that easy, must work my google-fu?
I don't think it's your google-fu, it isn't super clear on our site! I'll take that as a note to make it easier to find.

We've tried the grid for one of our projects and found it quite lagging in responsiveness (8000+ lines, paginated, but needs filtering) so unfortunately we had to revert to another table component, are there also changes to the speed of the grid component itself?
Please reach out to Carl Bergenhem for details around this. We would love to work with you to improve this scenario, but we may need more information.

What is your YouTube channel?
Kendo UI TV on YouTube

Thank You

Thanks to everyone who joined us for the webinar, we received a lot of great feedback. We hope you love the new features and improvements we've made to KendoReact in the R1 2019 release. Please feel free to leave your thoughts in our Feedback Portal or in the comments below.

Build a Chat App with Twilio and KendoReact

$
0
0

Learn to build a Twilio Chat application with React and the KendoReact conversational UI components. In this tutorial Twilio developer advocate Phil Nash shows you step-by-step how to easily and quickly create the app.

Twilio Programmable Chat provides an SDK and robust back-end for real time chat applications, but it's missing a front-end. If you need a chat UI, as well as a whole bunch of other useful components, then KendoReact might be what you're looking for.

Kendo UI provides well designed and tested components that you can use within your React, Angular, Vue and jQuery applications. In this post we will build a Twilio Chat application with React and the KendoReact Conversational UI components.

What You'll Need

If you want to build along with this tutorial, then you'll need a few things:

If you want to skip ahead, you can check out the code for this application in this GitHub repo.

Let's get started

We're going to use the React and Express starter application that I built in this post as the basis for this app. This app gives us an easy way to run a Node.js server and React front-end with one command and comes with endpoints ready to create Access Tokens for Twilio Programmable Chat. Download or clone the application, change into the directory, and install the dependencies:

git clone -b twilio https://github.com/philnash/react-express-starter.git twilio-chat-kendo
cd twilio-chat-kendo
npminstall

Copy the .env.example file to .env then fill in the blanks with your Twilio account SID, the chat service, and API keys you generated earlier.

cp .env.example .env

Run the application to make sure everything is working so far. On the command line run:

npm run dev

You will see an application that looks like this open in your browser at localhost:3000.

TwilioKendoReact1

We have our Twilio Chat application ready and our React app set up. Let’s get building.

Preparing to Chat

There’s a bit of work we need to do before we start on the chat integration. We need to install some dependencies, remove the example app, and add a bit of style. Let’s start with those dependencies.

We’ll need the twilio-chat module to connect with Twilio Chat and then a few KendoReact modules that will provide the components we’re going to use:

npminstall twilio-chat @progress/kendo-react-conversational-ui @progress/kendo-react-inputs @progress/kendo-react-buttons @progress/kendo-react-intl @progress/kendo-theme-material

Next, strip src/App.js back to the basics, including the CSS for the KendoReact Material theme:

import React,{ Component }from'react';import'@progress/kendo-theme-material/dist/all.css';classAppextendsComponent{ constructor(props){super(props);} render(){return<p>Hello world</p>;}}exportdefault App;

To give the application a bit more style and layout (without too much effort) add the Bootstrap CSS to the <head> of public/index.html:

<!DOCTYPE html><htmllang="en"><head><!-- rest of the head --><title>React App</title><linkrel="stylesheet"href="https://stackpath.bootstrapcdn.com/bootstrap/4.1.3/css/bootstrap.min.css"integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO"crossorigin="anonymous"/></head>

With that done it’s time to build our first component.

Building a Login Form

For users to join our chat we need them to log in and choose a username. If you are building this into an existing application, you probably already have users and a login system. For this post we're just going to fake it by presenting a login form that asks for a username.

Create a new file, `src/Login.js`, and open it up. We'll make this a functional component as the login form itself doesn't need to store any state. Start with the following boilerplate: 
import React from'react';constLogin= props =>{return;};exportdefault Login;

To make our Login form fit in with our conversational UI, we’ll use KendoReact components. At the top import the Button and Input components:

import React from'react';import{ Button }from'@progress/kendo-react-buttons';import{ Input }from'@progress/kendo-react-inputs';

Modify the Login function to return the following JSX:

constLogin= props =>{return(<formclassName="k-form"onSubmit={props.handleLogin}><fieldset><legend>Log in</legend><divclassName="mb-3"><Inputname="username"label="Username"required={true}style={{ width:'100%'}}value={props.username}onChange={props.handleUsernameChange}/></div><div><Buttontype="submit"primary={true}>
            Sign in</Button></div></fieldset></form>);};

That’s quite the chunk of JSX, so let’s break it down. The whole thing is a <form> containing a <fieldset> and <legend>. Then inside there is an <Input> component and a <Button> component. These are the KendoReact components that we imported. They act like regular <input> and <button> elements but fit in with the KendoReact style.

The JSX also includes some properties we need to provide the component with; a username and two functions to handle events. We’ll add these to the <App> component so we can pass them in as properties.

Open up src/App.js and start by importing the new <Login> component.

import React,{ Component }from'react';import'@progress/kendo-theme-material/dist/all.css';import Login from'./Login';

Define the two functions that we’ll be passing to the <Login> component. One function needs to handle the user typing in the input and update the username stored in the state. The other handles the form being submitted and will set the state to show that the user is logged in. Add these below the <App> component’s constructor in src/App.js:

 handleLogin(event){
    event.preventDefault();this.setState({ loggedIn:true});} handleUsernameChange(event){this.setState({ username: event.target.value });}

In the constructor we need to initialize the state and bind these functions to the component:

 constructor(props){super(props);this.state ={
      username:'',
      loggedIn:false};this.handleLogin =this.handleLogin.bind(this);this.handleUsernameChange =this.handleUsernameChange.bind(this);}

Now let’s update the render function to show the username if the state says the user is logged in, and the <Login> component otherwise.

 render(){let loginOrChat;if(this.state.loggedIn){
      loginOrChat =<p>Logged inas{this.state.username}</p>;}else{
      loginOrChat =(<LoginhandleLogin={this.handleLogin}handleUsernameChange={this.handleUsernameChange}username={this.state.username}/>);}return(<divclassName="container"><divclassName="row mt-3 justify-content-center">{loginOrChat}</div></div>);}

If your application is still running, return to the browser and you will see the login form. Otherwise start the app with npm run dev and open localhost:3000. Enter your name in the form and press enter or click “Sign in”.

TwilioKendoReact2

Hooking up Programmable Chat

Now we can use the username to generate an access token, and connect our logged in user with chat. Create a new file called src/ChatApp.js and open it up. We’ll create a class based component for the chat app, so add the following boilerplate:

import React,{ Component }from'react';classChatAppextendsComponent{}exportdefault ChatApp;

There are a few things we need to do in this component:

  • Retrieve an access token from the server and initialize the Twilio Chat client
  • Setup a chat channel and join it, loading any existing messages
  • Create a function to send a message
  • Render the KendoReact Conversational UI

Before any of that we’ll need to import two modules; twilio-chat and the KendoReact conversationalUI. At the top of src/ChatApp.js add:

import React,{ Component }from'react';import Chat from'twilio-chat';import{ Chat as ChatUI }from'@progress/kendo-react-conversational-ui';

Let’s set up some initial state in the constructor too. We’ll need a list of messages, an error state in case anything goes wrong, and a boolean to show if the chat is loading, which will start as true.

classChatAppextendsComponent{ constructor(props){super(props);this.state ={
      error:null,
      isLoading:true,
      messages:[]};}}

Getting an Access Token

The starter project is already setup to return a token when we pass an identity to the /chat/token endpoint. We’ll use the fetch API to make the request as part of the componentDidMount lifecycle event. We use componentDidMount here as the React documentation tells us that this is a good place to load external data.

The response with the access token will be JSON, so we’ll need to parse it using the response object’s json method, then once it’s parsed, we can use the token to initialize the Chat client.

Creating the Chat client returns a promise so we can chain all these methods. Once the Chat client is created we will pass off to another method to finish the setup. We should also handle any errors with a catch method.

Add this code to the ChatApp class below the constructor:

 componentDidMount(){   fetch('/chat/token',{
      headers:{'Content-Type':'application/x-www-form-urlencoded'},
      method:'POST',
      body:`identity=${encodeURIComponent(this.props.username)}`}).then(res => res.json()).then(data => Chat.create(data.token)).then(this.setupChatClient).catch(this.handleError);}

Write the method to handle the error. We’ll set a message in the state and log the full error so we can debug if we have any trouble.

 handleError(error){
    console.error(error);this.setState({
      error:'Could not load chat.'});}

Setting up a Chat Channel

We’ve initialized our Chat client with an access token but there’s more to do. Once the promise resolves we need to use the new chat client to join a channel. As this is our first time through the process we’ll check to see if the channel exists. If so, we’ll attempt to join it; otherwise, we’ll create it then join it.

Add the following setupChatClient method to the class:

 setupChatClient(client){this.client = client;this.client
      .getChannelByUniqueName('general').then(channel => channel).catch(error =>{if(error.body.code ===50300){returnthis.client.createChannel({ uniqueName:'general'});}else{this.handleError(error);}}).then(channel =>{this.channel = channel;returnthis.channel.join().catch(()=>{});}).then(()=>{// Success!}).catch(this.handleError);}

We catch the error in the middle in case the channel doesn’t exist (a 50300 error) and create the channel. Also, if joining a channel throws an error we catch it and do nothing. This handles the case when the user is already a member of the channel.

If everything works the code will get to the success comment. At this stage the channel has loaded, so we can set our state isLoading variable to false. We also need to load existing messages and set up a listener for new messages.

Replace the // Success! comment above with:

.then(()=>{this.setState({ isLoading:false});this.channel.getMessages().then(this.messagesLoaded);this.channel.on('messageAdded',this.messageAdded);})

Receiving Messages

We need to write the messagesLoaded and messageAdded methods we just referenced above, but before we do we need to consider the format that the KendoReact conversational UI wants the messages. We need to translate the message object from the format Twilio provides it to that which can be used by the conversational UI component.

Let's write a function that can take a message from the Chat service and return a message object for KendoReact:

 twilioMessageToKendoMessage(message){return{
      text: message.body,
      author:{ id: message.author, name: message.author },
      timestamp: message.timestamp
    };}

Now we can write the messagesLoaded and messageAdded methods. messagesLoaded runs when we first load the existing messages to a channel so we fill up state.messages with all the messages we receive.

 messagesLoaded(messagePage){this.setState({
      messages: messagePage.items.map(this.twilioMessageToKendoMessage)});}

messageAdded will receive one message as its argument so we use the callback version of setState to add the message to the list. Note we also use the spread operator (...) to copy the existing messages into the new state.

messageAdded(message){this.setState(prevState =>({
      messages:[...prevState.messages,this.twilioMessageToKendoMessage(message)]}));}

Sending Messages

We also need a function to send a message to a channel. This function will be called by the KendoReact Conversational UI when a user types a message in the message box and sends it by clicking the send button or pressing enter. To handle it, we need to send the message text onto the channel. Displaying the message will be handled by the existing messageAdded event we are listening to on the channel.

Add the following function to the ChatApp class:

 sendMessage(event){this.channel.sendMessage(event.message.text);}

Tidying up and Rendering the Conversational UI

We have some final parts to complete before we can see the chat in action. We should handle the component being unmounted. We can do this by shutting the chat client instance down.

 componentWillUnmount(){this.client.shutdown();}

The Conversational UI expects a user object, which we will create using our user identity. We also need to bind all of our callback functions to the component. Add the following to the constructor:

 constructor(props){super(props);this.state ={
      error:null,
      isLoading:true,
      messages:[]};this.user ={
      id: props.username,
      name: props.username
    };this.setupChatClient =this.setupChatClient.bind(this);this.messagesLoaded =this.messagesLoaded.bind(this);this.messageAdded =this.messageAdded.bind(this);this.sendMessage =this.sendMessage.bind(this);this.handleError =this.handleError.bind(this);}

Rendering the Chat

Now we have everything in place we can render the Conversational UI. Create a render method in src/ChatApp.js that handles the various states of the component. If there are errors or if the chat is still loading, we will render a message, otherwise we will render the KendoReact Conversational UI component, passing the user object, the messages and the callback method to be run when the user sends a message.

 render(){if(this.state.error){return<p>{this.state.error}</p>;}elseif(this.state.isLoading){return<p>Loading chat...</p>;}return(<ChatUI
        user={this.user}
        messages={this.state.messages}
        onMessageSend={this.sendMessage}
        width={500}/>);}

Lastly we need to render this entire component from the <App> component. Import the <ChatApp> component at the top of src/App.js.

import React,{ Component }from'react';import Login from'./Login';import ChatApp from'./ChatApp';import'@progress/kendo-theme-material/dist/all.css';

Now update the render function of the <App> component to return the <ChatApp> component when the user is logged in.

render(){let loginOrChat;if(this.state.loggedIn){
    loginOrChat =<ChatApp username={this.state.username}/>;}else{
    loginOrChat =(<Login
        handleLogin={this.handleLogin}
        handleUsernameChange={this.handleUsernameChange}
        username={this.state.username}/>);}return(<div className="container"><div className="row mt-3">{loginOrChat}</div></div>);

Reload the app, login and start chatting. You can open another browser window and login with a different name to see the messages going back and forth.

TwilioKendoReact3

This is Just the Start

Twilio Programmable Chat is a powerful SDK for chatting and KendoReact's Conversational UI makes it really easy to display the chat in a React application. Most of the work we had to do was generating an access token and setting up the Twilio Chat. Once we'd written a couple of functions that translated the messages from Twilio to KendoReact and from KendoReact to Twilio the UI just fell into place.

You can get all the code for this application in the GitHub repo.

Check out the KendoReact documentation for other features of this UI, such as suggested actions, useful when the other side is a bot, and message attachments, for ways to display media messages or other views, like lists or carousels, within your chat.

The KendoReact Conversational UI is also available for jQuery, Angular and Vue if you prefer a different framework, and there are plenty of other useful components you could use to build your application.

Have you used KendoReact before? Or are you building chat into your app and on the lookout for a sweet UI? Let me know what you think in the comments or on Twitter at @philnash.


Learn More about KendoReact and Conversational UI

Want to explore KendoReact and Conversational UI further? Check out these resources to dig a little deeper.

How to Use Drag and Drop with the Angular 7 CDK + Kendo UI

$
0
0

A new feature in the CDK, as of version 7, is drag-and-drop that I keep hearing so much about. So I decided to return to the very snazzy Kendo UI Angular 7 todo app that we worked on earlier, and this is what we will include in it today.

Below I've included links to the full source code and a video walkthrough of the app - feel free to take a look and follow along, or just keep reading.

img_1 adding and removing items from our todo list

Check out the code on github!
You can also watch this episode on Angular Air walking through this app.

Let's Begin

To get going with the drag-and-drop feature from the CDK, we’ll first need to install the Angular CDK with all of its wondrous features, including drag-and-drop.

Install CDK

npm i @angular/cdk

Now we need to import the DragDropModule into our NgModule.

Import CDK in Your NgModule

// app.module.ts

import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { TodoComponent } from './todo/todo.component';
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { ButtonsModule } from '@progress/kendo-angular-buttons';
import { InputsModule } from '@progress/kendo-angular-inputs';

import { DragDropModule } from '@angular/cdk/drag-drop';

@NgModule({
  declarations: [
    AppComponent,
    TodoComponent,
  ],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    ButtonsModule,
    InputsModule,
    DragDropModule,
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

cdkDrag

Now we can start implementing the drag-and-drop, using the cdkDrag directive that we can place on any element we’d like to drag! For our app, we want to drag the Kendo UI buttons around in the list:

<div *ngIf="todos" class="list-group">
  <button kendoButton type="button" class="todo" @todoItem cdkDrag
    *ngFor="let todo of todos; index as i" >
    <span (click)="removeTodo(todo, i)">{{todo}}</span>
  </button>
</div>  

img_2 dragging and dropping todo items all over the page

img_3 bitmoji of me pondering

cdkDropList

So it is true, the buttons are now draggable. However, we’d like the list items to stay inside the list. Luckily, the CDK peeps have already thought of this. They have created a cdkDropList directive that can be set around the cdkDrag elements.

<div *ngIf="todos" class="list-group" cdkDropList>
  <button kendoButton type="button" class="todo" @todoItem cdkDrag
    *ngFor="let todo of todos; index as i" >
    <span (click)="removeTodo(todo, i)">{{todo}}</span>
  </button>
</div>  
img_4 gif of me dragging elements inside the todo list, the list never changes though

So now our draggable items are constrained inside the cdkDropList area. However, if you’ll notice once you drop a to-do list item, our data model is not being updated, therefore we are never actually able to update our list. Luckily, the CDK team has thought of this as well!!

All we need to do is use this event to update our data model this.todos! We will do this by creating a method that will call the CDK’s moveItemInArray method. I called it reorderList.

  reorderList(event: CdkDragDrop<string[]>) {
    moveItemInArray(this.todos, event.previousIndex, event.currentIndex);
  }
</string[]>

We then call reorderList on the div wrapping our list (that also has cdkDropList) when the cdkDropListDropped event is fired.

img_5 screenshot of html file pointing at cdkDropListDropped event we are calling

Our to-do list is now reordering when we drag and drop!

img_6 gif of dragging and dropping todo items, they are actually reordering now

Note that we don’t have persistent data in this app, so on refresh the list will reset. Once we added calls to save our data to a database, we would need to ensure we also called save on the drop event cdkDropListDropped.

Animating

As lovely as this is, we can add a bit of polish by transitioning our elements as we drag them. The drag-and-drop directives add classes and transforms to the elements allowing for animations to be possible!

screenshot from docs of classes being added my drag-and-drop

.cdk-drag - Adding transition to this class will animate as the user is sorting through a list .

All we need to do to utilize them is add transitions:

/* Animate items as they're being sorted. */
.cdk-drop-list-dragging .cdk-drag { 
  transition: transform .5s cubic-bezier(0.88, -0.19, 0.26, 1.27);
}

So now look how wonderfully the list updates with this simple transition on the buttons as they drag and drop!

gif of dragging and dropping todo items with animations

I’ve been really impressed with the well thought out decisions that the CDK team has made and how easy to use the drag-and-drop module is. There are even more things we didn’t cover, like attaching data, dragging from one list to another (like Trello), and customizing the drag area using a handle!

What About Mobile?

On the Angular Air podcast I linked to above, we went over this app and how I implemented the drag-and-drop. My good friend and co-panelist Mike Brocchi mentioned a great point, "what about mobile"? Again I’m astounded by the Angular CDK team’s thoughtfulness. I navigated to their docs and tried using it in my phone:

gif of dragging and dropping on mobile

As you can see, I’m able to grab the item and drag it around using mobile touch events, by default, out-of-the-box!

If you’d like to learn more about how this app was created with Kendo UI for Angular or more about the Angular Animations being used, check out these resources:

A Snazzy To-Do App Using Kendo UI and Angular

VIDEOBLOG

Custom Angular Animations in Our Kendo UI To-Do App

VIDEOBLOG

As always, thanks for following along and happy coding everyone!!!

Creating a Responsive Layout in React

$
0
0

Learn the basic steps to setup a React application with Flexbox and make your layout responsive.

In order to really move forward with any React application beyond just the individual component level, you need an outer layer that provides styles to help you layout your site. But contrary to what others would have you believe, it's not to hard to use some basic CSS and a few React Component packages to help us achieve some basic levels of responsiveness in an application.

Our goal will be to build a web page that changes at several breakpoints and changes the way we display our content on the page like the image below:



A lot of the time you will want the freedom of not being tied to a framework like Bootstrap or Material, you want to roll your own, but you also don't want to reinvent the wheel. In this tutorial we will use Flexbox, some basic media queries to create breakpoints determining how to render our layout.

I have a KendoReact Menu component that I know I want to use. It will need to switch between vertical and horizontal modes in order for me to use it the way that I envision. For mobile, I want my menu component to render horizontal (left to right) at the top of the page, like a top-nav menu bar, but on Tablet and desktop, I would like the menu to be vertical (top to bottom) along the left side of the page.

Initially, we will start with just one breakpoint and later in the tutorial add another. I'm going to start with an already setup StackBlitz demo, just so I don't have to go over any of the React setup. We want to focus just on building our application, not on setting it up. If you want to follow along by coding, you can fork this initial StackBlitz demo, otherwise just read along knowing that you can grab any StackBlitz example I provide throughout the course (there are four of them) to play with the code. Each StackBlitz demo will contain the end product of all of the steps we have talked about up until that point.

The demos have a few dependencies. There's react-media-hook, which we use to track a single breakpoint. We use react-responsive-image to render images using the picture tag at different resolutions. I will also be using the KendoReact Menu as mentioned before, which has a horizontal and vertical mode that we can switch when we hit our small to medium breakpoint.

Take a look at the StackBlitz demo below, and then we can talk about what's going on next.


The Starting Point for Our Tutorial

So with this first example in StackBlitz, we already have a lot of stuff going on. We are using a kendo-theme for the Menu (this is normal if you plan on working with the suite of components, but just understand that it will only style any KendoReact components that we add and nothing else). We also have a custom.css file which is exactly what it says, custom styles. For now we just have some global styles for our app container, a .navbar and .main style will be used specifically for navigation and our main content. Finally we have a site-container class that will act as a Flexbox container and set direction for it's items inside of it. With this concept in Flexbox we will create a basic layout that we can easily change depending on breakpoints that we setup later.

If you are new to Flexbox, I suggest A Guide to Flexbox, an article from CSS Tricks, to explain the basics of Flexbox. Otherwise continue on!

Let's start with the main.js file. This file's main purpose is to load the App shell or App component, a functional component named App.

If we then focus our attention to the render method of the App component, we will see that we have a very basic layout of two divs encapsulated in a container div. This setup is so that we can take advantage of Flexbox for the main layout.

With Flexbox we can have a container div and two divs inside of it. The container class needs a few class rules telling it to display its inner contents as Flexbox. We will specify that the direction will be column.

.container {
  display: flex;
  flex-direction: column;
}

Think of two boxes stacked on top of each other. If they are perfectly square, they would continue stacking and making a longer column as you add more. The items will be laid one on top of the other (stacked like a column).

We will apply this pattern to our example, but we only want two container items. One will be our top navigation and we will restrict its height, and the other will be our content area.

Here it is with the navigation bar at the top and a content area at the bottom. This layout is pretty easy to achieve with Flexbox and zero media queries.

But I would like my navbar to go from being a top bar to a side bar when I hit a specific width (415 pixels). This is not a standard or anything, but I feel that most devices that hit this number or higher are not a mobile phone. The bigger deal is to get a few breakpoints setup so you can test your layout - the breakpoints can always be tweaked.

In order to see a change when we hit 415 pixels, we need to activate a media query. this is done by meeting it's requirements. Take the following CSS:

@media screen and (min-width: 415px){
  .site-container {
    flex-direction: row;
  }
}

It's one line of CSS, but it switches our Flexbox container to display its contents in a row format. Let's see what this looks like now.

Not exactly what we wanted, but we are already getting somewhere. By changing the direction of our flex-direction to row, we are now displaying the items within the container side by side, which is the effect I was going for. But I want the left menu column to only be 120 pixels wide and the main content area that just says "Hello World," we want that to take up the rest of the browser width.

Luckily with Flexbox this is super simple. We can add the following code to the media query and these rules will take effect once we hit that breakpoint at 415 pixels.

.site-container > * {
  flex: 1;
}

That flex: 1 is a bit confusing, I know. I actually recommend some reading on this part of Flexbox, because it's not super intuitive by just seeing this line of code. You see, flex: 1 is actually shorthand for flex: 1 1 0 which is what I am going to use so that the rule is as descriptive as possible.

A brief explanation of the flex property, is that when you say flex: 1;
or flex: 1 1 0; you are setting the following properties:

flex-grow: 1;  Grow in same proportion as the window-size

flex-shrink : 1;  Shrink in same proportion as the window-size

flex-basis : 0;  If 2 divs are present, each div will take 50%.

I will also start adding the webkit-flex CSS prefixes for different browsers into the StackBlitz demos for good measure. I show them below once, but in the rest of the examples in this article, I will omit them for brevity.

.site-container > * {
  -webkit-flex: 1 1 0;
  -ms-flex: 1 1 0;
  flex: 1 1 0;
}

Now that we have our main content div taking up as much space as it can, if we just add a few properties like width and height to the navbar div, we will constrain it and our main content div will be forced to make up the difference. We can add the following CSS to the media query:

.navbar {
  padding-top: 0.75em;
  max-width: 120px;
  min-height: 100vh;
}

This is great. Based off of a media query, we made our two sections layout in a different flex direction. But our KendoReact MenuWrapper component needs a copy of the current media query so that it can make a decision to either display the menu horizontally like it does by default or display it vertically when it hits that 415 pixel boundary. You can see the docs for the menu component and the vertical mode.

To do this, we will create a Hook inside the main.js, or more specifically the App component, and we will import useMediaPredicate from the package react-hook-media.  This is a popular React hook that in a sense, creates a subscription to the media query that our component will constantly listen for changes. We can set it to a constant and pass that into the MenuWrapper as a prop, we'll call it isMediumPlus because it will be true if it's above 415 pixels and it will be false if it is under 415 pixels.

To do this, we need to import the package:

import { useMediaPredicate } from 'react-media-hook';

Just inside the App component, we will set up the constant and name it something that describes what it is doing:

const checkIfMediumPlus = useMediaPredicate(
  '(min-width: 415px)'
);

The argument to the useMediaPredicate() method is the actual rule we want to check for. If the browser has a minimum width of at least 415 pixels, the return value is true, otherwise false. We can then pass that property into the <MenuWrapper /> component as a prop:

<MenuWrapper isMediumPlus={checkIfMediumPlus} />

Now the only thing we have left do is to go into the MenuWrapper file and add the isMediumPlus prop to the functional component. To add the prop, we just add an parameter to the functional component. We also want to replace the value being passed into the <Menu /> component itself so that instead of being false, we pass the prop in.

const MenuWrapper = ({isMediumPlus}) => {
  return (
    <div className="nav">
      <Menu
        items={items}
        vertical={isMediumPlus}
        style={{ display: 'inline-block' }}
      />
    </div>
  );
}

We finally have everything we need in place so that when we make the transition from the small to medium breakpoint. When we trip that 415 pixel wide boundary, we actually re-flow the flex items and set the menu to vertical so that it fits into the sidenav displaying in a vertical stack.

On an interesting note, if you inspected the KendoReact Menu in the developer tools, you will notice that it also uses Flexbox to position its menus and buttons.

Here is the StackBlitz demo that shows the progress we have made:


In the next section we will add some images to our content area and display different images on small (mobile) vs medium browser widths. If the site is loaded on mobile it will only render the smaller image, but if loaded on medium or larger (415 pixels plus) it will render a different image as its source.

By using the <picture /> tag and srcSet we can create a more responsive experience and serve only the image we need at a particular size. What's important to me is answering a few questions:

How do I deliver high quality images? How do I ensure unnecessary bits are not being downloaded?

So when you are using plain HTML, using the picture tag is easy enough. In React though, I actually prefer working with a package called react-responsive-image that will give us a nice component that can help make using the <picture /> element even easier!

After a quick install of react-responsive-image, we will actually render an image right above the text that says "Hello World." For our demo's sake, since we are rendering the contents of navbar and our main content area in the same file, we will just add our responsive image component directly to the App.js page.

Below are two images that I want to show. The one labeled small will be shown for sizes 0 through 414 pixels. The one labeled medium-up will be displayed on everything 415 pixels and larger.

Small (https://i.imgur.com/OxjKMBr.png)


Medium-Up (https://i.imgur.com/sgz5R9d.png)


First we will need to import the ResponsiveImage and ResponsiveImageSize components, this information is on the front page of react-responsive-image GitHub page. Create a constant for each size:

import { ResponsiveImage, ResponsiveImageSize } from 'react-responsive-image';
...
const small = 'https://i.imgur.com/OxjKMBr.png';
const medium = 'https://i.imgur.com/sgz5R9d.png';

const App = () => {
...

The way we use these two components together is that a ResponsiveImage component will have multiple ResponsiveImageSize components nested inside. Each ResponsiveImageSize represents a different image you want to show at a different resolution. Like I said I only want to think about two different images right now. One that displays on small and one on medium. Below is the code that will make it break at my desired 415 pixels, we will place it just above the paragraph tag that says "Hello World."

<div className='main'>
  <ResponsiveImage>
    <ResponsiveImageSize
      minWidth={0}
      path={small}
    />
    <ResponsiveImageSize
      minWidth={415}
      path={medium}
    />
  </ResponsiveImage>
  <p>Hello World</p>
</div>

We now have everything working together. At this point our project looks like the following StackBlitz demo:


We will do one more set of changes in this blog post - we will position the text and some informational content below the image on small and to the right of the image if we are on medium and up.

Let's create a div around the image and the text. Instead of "Hello World" we will render some useful information about KendoReact. By giving those divs that we wrapped around the image and the text some classes, we can create a new breakpoint at 600 pixels that lays out our content a little more nicely at the larger resolution.

<div className='kendo-image'>
  <ResponsiveImage>
    <ResponsiveImageSize
      minWidth={0}
      path={small}
    />
    <ResponsiveImageSize
      minWidth={415}
      path={medium}
    />
  </ResponsiveImage>
</div>
<div className='kendo-details'>
  <h1>KendoReact Components</h1>
  <p>Building UI for business apps is hard, even on React. Make it easy with our native React UI and DataViz components.</p>
</div>

With this change I actually want to introduce a new image for our medium size. It will take the place of our medium-up image which we will rename to large. Our small image will stay the same. But this new medium image will be slightly larger but same format as the small image. Here it is along with the other images from before, we will need to update our constants that hold the value for each image using the images below:

Small (https://i.imgur.com/OxjKMBr.png)


Medium (https://i.imgur.com/ZrM4G3j.png)


Large (https://i.imgur.com/sgz5R9d.png)


const small = 'https://i.imgur.com/OxjKMBr.png';
const medium = 'https://i.imgur.com/ZrM4G3j.png';
const large = 'https://i.imgur.com/sgz5R9d.png';

Finally we will add a new media query setting a breakpoint at 600 pixels and a few more styles to our custom.css file.

.main {
  display: -webkit-flex;
  display: -ms-flexbox;
  display: flex;
  -webkit-flex-direction: column;
  -ms-flex-direction: column;
  flex-direction: column;
}
.kendo-image img {
  width: 100%;  
}
.kendo-details h2 {
  margin-top: 0.25em;
}

We have added the regular styles in the code above, they will set the div with the class of main to also use Flexbox and act like a container, its contents flex-direction will be column by default. Next we will add a new large sized media query as well as put some more CSS into the medium sized media query:

@media screen and (min-width: 415px){
  ...
  .kendo-details {
    padding: 0 1em 0 0;
  }
}

The code above simply adds padding to the div with the class name kendo-details. Now we are ready to add our final breakpoint to represent devices with a larger screen.

@media screen and (min-width: 600px){
  .main {
    -webkit-flex-direction: row;
    -ms-flex-direction: row;
    flex-direction: row;
  }
  .kendo-details {
    padding: 0 1em 0 1.5em ;
  }
  .kendo-image img {
    min-width: 150px;
    max-width: 223px;
  }
}

Here, we change the direction of the items inside the div with the class name of main. We also add more padding to the div with the class name kendo-details. Finally, for our div with the class name kendo-image, we target any images inside of it and ensure that when the screen is above 60 pixels that the image will not get any larger than 223 pixels wide (that's the actual width of the image) as well it will not go any smaller than 150 pixels. 

We can now look at the final state of our demo in the StackBlitz below. This demo should show all of our progress up until this point and in fact we are way better off now to start building a real application now that we have some of these basic responsive practices down.


Play around with the demo and resize the window from small to large to see how the different media queries change the direction our divs layout at each stage.

Please let me know in the comments if you would like to learn more about responsive design in React as we have only scratched the surface. These are the basics and also some of the more modern techniques in building responsive web pages, but by no means can we claim to be responsive ninjas yet. Maybe a second article continuing from this point is in order? Let us know in the comments!

Why You Should Move to Continuous Scrolling Now - and How to Do It

$
0
0

Check out the new continuous scrolling in Telerik Reporting, which delivers more data that is easier to work with in fewer actions: a better experience.

Scroll, scroll, scroll. We all love it. We all do it. Every day, everywhere. Facebook, Twitter or just in your favorite news site. Do not try to fool me that you do not scroll, because after a minute you will scroll. Scroll, scroll, scroll.

I am very happy to let you know that now you can scroll, and scroll, and scroll, in your beloved Telerik Report Viewer too. The new page mode gives you the ability to read the whole report just on a few scrolls. No need to click somewhere to navigate or enter a page number.

scrolling animation

Benefits

There are a lot of reasons why you should move to continuous scrolling. Here's some of them that I found most interesting.

  • Fewer clicks - Scrolling is easier for users than clicking (and then scrolling again) and requires less action.
  • Better content exposure - Continuous scroll lets users find the content they might not otherwise see.
  • Great for mobile - Continuous scrolling is especially beneficial for any mobile or touch users.
  • Increase the number of content pieces (also known as page depth) – the user can see and comprehend more data just in one look.
  • Continuous scroll makes it easier to read the piece you’re on, and then makes it easier to read the next.

How Does it Work?

Telerik Report Viewer page scroll mode has the behavior of a continuous scroll. When the report is ready, N pages are rendered in the viewport to fill in the visible part of your report viewer. A next or previous page is loaded on demand after you do what? That’s right after you scroll.

How to Enable It?

After updating your Telerik Report Viewer to the latest version, the continuous scroll will be the new default page mode for your viewer. If for some reason we cannot imagine yet, you do not like the new page mode, there is an easy way to switch to the old single page mode by setting the following property to your Telerik Report Viewer.

[pageMode: telerikReportViewer.PageModes.SINGLE_PAGE,]

Expected Behavior

Of course, there is no need to tell you that all already known navigation mechanisms will continue to work for the continuous scroll mode. For example, if you are on page 2 and want to go to page 150, just type the wanted page in the navigation input in the Telerik Report Viewer toolbar. Do you love clicking? The beautiful buttons in the toolbar area will be there for you, to help you navigate to the next or previous page, or just to jump to the end or to the begging of your report.

toolbar_navigation_part

To summarize. More data, easy to work with, fewer actions, better experience. That is the new Telerik Report Viewer page scroll mode. Upgrade and enjoy it.

Try it Out and Share Feedback

We want to know what you think—you can download a free trial of Telerik Reporting or Telerik Report Server today and share your thoughts in our Feedback Portal, or right in the comments below.

Start your trial today: Reporting Trial   Report Server Trial

Tried DevCraft?

You can get Reporting and Report Server with Telerik DevCraft. Make sure you’ve downloaded a trial or learn more about DevCraft bundles. DevCraft gives you access to all our toolsets, allowing you to say “no” to ugly apps for the desktop, web or mobile.

Viewing all 5210 articles
Browse latest View live