Quantcast
Channel: DHTMLX Blog
Viewing all 208 articles
Browse latest View live

JavaScript Data Grid with Laravel 5 Usage Guide

$
0
0

PHP is probably one of the most popular programming languages. Especially if we talk about the web development. Following the intention to complexity reduction, dozens of PHP frameworks have been created. One of the most popular among them is Laravel. You can check this framework popularity survey made by sitepoint to make sure that Laravel at least deserves your attention.

js data grid

Spoiler! That’s how dhtmlxGrid will look like in the version 5.0 ;)

This article’s aim is to describe the basics of Laravel usage. This framework was created for the development of web applications following the model–view–controller (MVC) architectural pattern. One of the core features of Laravel is a modular packaging system that allows adding new components to your project. Since we’re not interesting in the creation of a simple “Hello, World!” application, we’ll use this feature to create something that looks like an actual web app. We’ll use our dhtmlxGrid component for our task. It’s a JavaScript grid control that you can use for creating Ajax-enabled tables with rich in-cell editing, built-in filtering, searching, and grouping capabilities.

dhtmlxGrid doesn’t require a big amount of code for using it, and one article will be enough to create a working example.

Step 1. Using Composer to Install Laravel


Composer is a package manager for PHP that we can use to create a new Laravel project and install the required dhtmlxGrid files. If you use a Linux distribution, Composer is possibly available through a repository, and you can install it using your package manager like you install any other package. Otherwise, you can follow this installation guide.

There’s a well-written guide that describes in detail how you can install Laravel, create and configure a new project. We’ll use previously installed Composer.

Run in your terminal:

composer create-project  laravel/laravel --prefer-dist dhtmlxGrid

This command will create a new Laravel project in a directory named dhtmlxGrid. If you want, you can check if everything works well. Open the newly created directory and run the server:

cd dhtmlxGrid
php artisan serve

Now you can open http://localhost:8000/ in your browser. Here’s what you should get:

laravel 5 with grid

Everything works which means that we can return to our application. Now we need to install dhtmlxConnector which enables access to external data sources. We need it for saving and loading the data. The best thing about using Laravel is the possibility to add this component to a project via composer using a single command.

You can use the Packagist website if you want to find a proper package. You can find comprehensive information about the component that you want to use. Composer installation command, requirements, short description, link to the documentation page, etc.:

server side connector

In our case, to install dhtmlxConnector you should use the following command:

composer require dhtmlx/connector-php

Step 2. Get the dhtmlxGrid Package


After the installation complete, we should download the package with dhtmlxGrid. Within the public folder of your project create a new directory named dhtmlxGrid and unpack the content of the package into it.

Step 3. Create the Database


You can download the pre-created zip archive that contains the database dump file we can use. Unpack the archive and you’ll see the dhtmlx_samples.sql file.

Now, we can create a new database. If you use MySQL run:

mysql -u root -p

After you insert the password, you can create a new database and import the data from the dump file into it:

CREATE DATABASE grid;
USE grid;
 \. /path/to/file/dhtmlx_samples.sql

After you finish with this task, we can finally create the application.

Step 4. Create a Model


We need to specify the appropriate model class to get the access to the data. Create a new file named Grid.php within the app directory of your project:

<?php
namespace App;
use Illuminate\Database\Eloquent\Model;

class Grid extends Model
{
    protected $table = "scheduler_events";
    public $primaryKey = "event_id";
    public $timestamps = false;
}

That’s it. Now we can create the View Object.

Step 5. Create the View Object


Within the resources/views directory, create a new file named grid.php:

<!DOCTYPE html>
<head>
    <script src="dhtmlxGrid/codebase/dhtmlxgrid.js"></script>
    <link rel="stylesheet" href="dhtmlxGrid/codebase/dhtmlxgrid.css">
</head>

<body>
    <div id="grid_here" style="width: 600px; height: 400px;"></div>
    <script type="text/javascript" charset="utf-8">
        mygrid = new dhtmlXGridObject('grid_here');
        mygrid.setHeader("Start date,End date,Text");
        mygrid.init();
        mygrid.load("./grid_data");
        var dp = new dataProcessor("./grid_data");
        dp.init(mygrid);
    </script>
</body>

Step 6. Create the Controller


The controller that we want to create will do two things: load the view, and load and process the data.

To load and process data we will use GridConnector:

$connector = new GridConnector(null, "PHPLaravel");
$connector->configure(new Grid(),"event_id","start_date,end_date,event_name");
$connector->render();

The GridConnector constructor takes 2 parameters:

  • null – null is passed, as a model, not a database is used;
  • $PHPLaravel – the module for working with PHP, the hardcoded value;


The configure method configures the GridConnector object without rendering data and takes 5 parameters:

  • new $modelName – the method creating a model. In this case, new Grid() that we have defined earlier;
  • $id – the name of the id field;
  • $text – a comma separated list of rendered data fields;
  • $extra – (optional) a comma separated list of extra fields;
  • $relation_id – (optional) used for building hierarchy in case of Tree and TreeGrid;


Now, within the app/Http/Controllers folder create a new file, GridController.php:

<?php
namespace App\Http\Controllers;
use App\Grid;
use Dhtmlx\Connector\GridConnector;

class GridController extends Controller
{
    public function data() {                                    
        $connector = new GridConnector(null, "PHPLaravel");    
        $connector->configure(                                  
            new Grid(),                              
            "event_id",                                        
            "start_date, end_date, event_name"                  
        );                                                      
        $connector->render();                                  
    }                                                          
}

Step 7. Final Configuration


We should edit the .env file that you can find within the root file of your project. We need to change four lines to give Laravel access to the previously created database:

DB_HOST=localhost
DB_DATABASE=grid
DB_USERNAME=root
DB_PASSWORD=yourpassword

Now, let’s deal with routes. If you open the app/Http/routes.php file you’ll find the default route configuration that may look like this:

Route::get('/', function () {
    return view('welcome');
});

This code will perform the GET request after you open your project in a browser. As a result, the welcome view from the resources/views folder will be returned. We should replace it with the previously created view, grid.php. The other step is to use GridController to save and load data. All you need to do is to replace the existing route with the following:

Route::get('/', function () {
    return view('grid');
});

Route::match(['get', 'post'], '/grid_data', "GridController@data");

One more step left. Laravel protects your application from cross-site request forgeries by generating a CSRF “token” for each active user session managed by the application. You can read more about the mechanisms of protection on this page if you want, but what we need to do now is to exclude one particular URI from CSRF protection. The one that triggered when created data is supposed to be saved. We need to add a proper value to the $except property in the file app/Http/Middleware/VerifyCsrfToken.php:

protected $except = [
    'grid_data'
];

Step 8. Run the Application


Open your project’s directory and run in terminal:

php artisan serve

Open http://localhost:8000/ in your browser and you’ll see the working dhtmlxGrid:

laravel with datagrid

Here’s the table that contains the data from our database.

That’s all. We hope you have enjoyed the tutorial.

The post JavaScript Data Grid with Laravel 5 Usage Guide appeared first on DHTMLX Blog.


Using Scheduler with Scalatra Framework and MongoDB

$
0
0

Today we’ll show you the way of using JavaScript Event Calendar with Scalatra Web Framework. Scalatra is a free and open source web application framework written in Scala. To install it, please follow the instructions you could find here. When installation is completed, we can start.

scheduler with scalatra

The demo is available on GitHub, so you’re welcome to check it right now.

Step 1: Create a new scalatra app


Open a folder where you want to create a new project and run the following command:

g8 scalatra/scalatra-sbt

There will be some questions about the application, so you need to fill them out and then you may continue. As a result, we should get something like this:

scalatra app

Now, let’s go to the app directory and make sure that it works.

cd scheduler-scala
sbt
jetty:start

To open the page, call “browse” command in the console or open http://127.0.0.1:8080 in a browser. We should get the Hello World app to proceed to the next steps.

hello world

Got it? Great! Let’s move on.

We can’t proceed without Scheduler, so it’s high time to download it. Now we can open scheduler-scala\src\main\webapp, create dhtmlxScheduler folder and unpack the scheduler codebase content to it:

scheduler and scala

Then open scheduler-scala\src\main\webapp\WEB-INF\templates\views and create index.jade file with the following content:

- attributes("title") = "Scheduler Sample"
script(type='text/javascript' src='/dhtmlxScheduler/dhtmlxscheduler.js')
link(rel='stylesheet' href='/dhtmlxScheduler/dhtmlxscheduler.css')

#scheduler_here.dhx_cal_container(style='width: 100%; height: 700px')
    .dhx_cal_navline
        .dhx_cal_prev_button
        .dhx_cal_next_button
        .dhx_cal_today_button
        .dhx_cal_date
        .dhx_cal_tab(name='day_tab')
        .dhx_cal_tab(name='week_tab')
        .dhx_cal_tab(name='month_tab')
    .dhx_cal_header
    .dhx_cal_data

script
    |scheduler.config.xml_date="%Y-%m-%d %H:%i:%s";
    |scheduler.init("scheduler_here",new Date(2016,3,18));
    |scheduler.load("/data", "json");
    |var dp = new dataProcessor("/data/");
    |dp.init(scheduler);
    |dp.setTransactionMode("REST");

That’s how we’re creating a simple page layout for scheduler and adding required scripts and styles from scheduler codebase. We also need to initialize “/data” url as a datasource for the calendar. We’ll add the handlers to the server side later.

Now open scheduler-scala\src\main\scala\com\scheduler\app\SchedulerServlet.scala and replace this part:

 get("/") {
   <html>
     <body>
       <h1>Hello, world!</h1>
       Say <a href="hello-scalate">hello to Scalate</a>.
     </body>
   </html>
 }

By this one:

get("/") {
   contentType = "text/html"
   jade("/index")
 }

As you can see, we start using index.jade as the main app page. If everything is done correctly in the previous steps, we should see an empty scheduler when we start the app:

event calendar with scalatra

All the fundamental preparations are done, so we can move to the next step and load our scheduler app with data.

Step 2: Data loading


First of all, we need to add route handlers for data loading. For this, open scheduler-scala\project\build.scala and add the following dependency to libraryDependencies:

"org.mongodb" %% "casbah" % "2.7.2"

As a result, we get the following:

libraryDependencies ++= Seq(
       "org.mongodb" %% "casbah" % "2.7.2",
       "org.scalatra" %% "scalatra" % ScalatraVersion,
       "org.scalatra" %% "scalatra-scalate" % ScalatraVersion,
       "org.scalatra" %% "scalatra-specs2" % ScalatraVersion % "test",
       "ch.qos.logback" % "logback-classic" % "1.1.5" % "runtime",
       "org.eclipse.jetty" % "jetty-webapp" % "9.2.15.v20160210" % "container",
       "javax.servlet" % "javax.servlet-api" % "3.1.0" % "provided"
     ),

Open scheduler-scala\src\main\scala\ScalatraBootstrap.scala and put following code:

import com.mongodb.casbah.Imports._
import com.scheduler.app._
import org.scalatra._
import javax.servlet.ServletContext
import com.mongodb.casbah.commons.conversions.scala.{RegisterConversionHelpers, RegisterJodaTimeConversionHelpers}


class ScalatraBootstrap extends LifeCycle {
  override def init(context: ServletContext) {
    RegisterConversionHelpers()
    RegisterJodaTimeConversionHelpers()
    val mongoClient = MongoClient()
    val mongoColl = mongoClient("scheduler")("events")

    context.mount(new SchedulerServlet(mongoColl), "/*")
  }
}

Here we have created connection to MongoDB, got the link to MongoDB collection and passed it to our controller (with the mongoColl variable).

Since we’ve passed a collection into the controller, we need to modify its signature and add the necessary parameter into it. So open scheduler-scala\src\main\scala\com\scheduler\app\SchedulerServlet.scala and put following code:

package com.scheduler.app

import java.text.SimpleDateFormat
import java.util.Date

import com.mongodb.casbah.Imports._
import org.joda.time.DateTime
import org.joda.time.format.DateTimeFormat

class SchedulerServlet(mongoColl: MongoCollection) extends SchedulerscalaStack {
  var dateFormat = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")

  def getEvent(params: Map[String, String]): MongoDBObject = {
    MongoDBObject(
      "text" -> params("text"),
      "start_date" -> dateFormat.parseDateTime(params("start_date")),
      "end_date" -> dateFormat.parseDateTime(params("end_date"))
    )
  }

  get("/") {
    contentType = "text/html"
    jade("/index")
  }

  get("/init") {
    mongoColl += getEvent(Map("text" -> "My Test Event A", "start_date" -> "2016-04-18 03:00:00", "end_date" -> "2016-04-18 11:00:00"))
    mongoColl += getEvent(Map("text" -> "My Test Event B", "start_date" -> "2016-04-20 07:00:00", "end_date" -> "2016-04-20 12:00:00"))
    mongoColl += getEvent(Map("text" -> "Friday Event", "start_date" -> "2016-04-22 06:00:00", "end_date" -> "2016-04-22 15:00:00"))
  }

  get("/data") {
    val evs = for{
      x <- mongoColl
    } yield MongoDBObject("id" -> x.get("_id").toString(),
      "text" -> x("text"),
      "start_date" -> x.as[DateTime]("start_date").toString(dateFormat),
      "end_date" -> x.as[DateTime]("end_date").toString(dateFormat))

    contentType = "application/json"
    "[%s]".format(evs.mkString(","))
  }

}

In the above code we’ve added the MongoCollection parameter for controller – SchedulerServlet(mongoColl: MongoCollection) and created the “/init” and “/data” handlers.

The “/init” handler is made just to generate some test data for the collection.
The “/data” handler is intended for loading data into scheduler. It gets all the records from database and sends them to the client side in the JSON format.

As you may remember, we have the following string in our index.jade:

scheduler.load("/data", "json");

It sends a request to the server to load data to the scheduler in JSON format.

Now we can restart our server and open http://127.0.0.1:8080/init. After this initial data for scheduler should be generated. Then we just need to open http://127.0.0.1:8080/ and scheduler with initial events will appear.

calendar in scala

Step 3: Adding, editing and deleting data


We have a scheduler with events, but it doesn’t possess any useful features yet. Let’s provide it with such necessary abilities as adding, deleting and editing data.

Open scheduler-scala\src\main\scala\com\scheduler\app\SchedulerServlet.scala and add the insert, update, and delete handlers. We will also add a function that will get responses.

The resulting code will look like this:

package com.scheduler.app

import java.text.SimpleDateFormat
import java.util.Date

import com.mongodb.casbah.Imports._
import org.joda.time.DateTime
import org.joda.time.format.DateTimeFormat


class SchedulerServlet(mongoColl: MongoCollection) extends SchedulerscalaStack {
 var dateFormat = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss")

 def getEvent(params: Map[String, String]): MongoDBObject = {
   MongoDBObject(
     "text" -> params("text"),
     "start_date" -> dateFormat.parseDateTime(params("start_date")),
     "end_date" -> dateFormat.parseDateTime(params("end_date"))
   )
 }
 
 def getResponse(mode: String, tid: String): String = {
   var response = Map("type" -> mode)
   if(tid != null) response += ("tid" -> tid)

   "{%s}".format((response map {case (k,v) => "\""+k+"\":\""+v+"\""}).mkString(","))
 }

 get("/") {
   contentType = "text/html"
   jade("/index")
 }

 get("/init") {
   mongoColl += getEvent(Map("text" -> "My Test Event A", "start_date" -> "2016-04-18 03:00:00", "end_date" -> "2016-04-18 11:00:00"))
   mongoColl += getEvent(Map("text" -> "My Test Event B", "start_date" -> "2016-04-20 07:00:00", "end_date" -> "2016-04-20 12:00:00"))
   mongoColl += getEvent(Map("text" -> "Friday Event", "start_date" -> "2016-04-22 06:00:00", "end_date" -> "2016-04-22 15:00:00"))
 }

 get("/data") {
   val evs = for{
     x <- mongoColl
   } yield MongoDBObject("id" -> x.get("_id").toString(),
     "text" -> x("text"),
     "start_date" -> x.as[DateTime]("start_date").toString(dateFormat),
     "end_date" -> x.as[DateTime]("end_date").toString(dateFormat))

   contentType = "application/json"
   "[%s]".format(evs.mkString(","))
 }

  post("/data/:id"){
   val newEvent:MongoDBObject = getEvent(params)

   mongoColl += newEvent
   contentType = "application/json"
   getResponse("inserted", newEvent("_id").toString())
 }

 put("/data/:id") {
   val query = MongoDBObject("_id" -> new ObjectId(params("id")))
   val event:MongoDBObject = getEvent(params)
   mongoColl.findAndModify(query, event)
   contentType = "application/json"
   getResponse("updated", null)
 }

 delete("/data/:id"){
   val query = MongoDBObject("_id" -> new ObjectId(params("id")))
   mongoColl.remove(query)
   contentType = "application/json"
   getResponse("deleted", null)
 }
}

When we restart the server and open http://127.0.0.1:8080 in browser again, our calendar will be able to create, edit and delete events. What is more, now all the changes will be automatically saved in the database and won’t disappear after reloading the page.

The demo is available on GitHub, so you’re welcome to check it right now.

The post Using Scheduler with Scalatra Framework and MongoDB appeared first on DHTMLX Blog.

Suite 5.0 is Out! Material Design, New TreeView Control and More

$
0
0

Major update of dhtmlxSuite library is finally rolling out, and we are happy to present a new version with lots of awesome updates! Starting from 5.0, our JavaScript UI library is available in new Google’s Material skin, supports Font Awesome icon fonts, has a new Tree component and has many other updates that we’ll describe further.

Material Skin is added and became a default one

We caught up with the modern trends in order your outstanding applications made with DHTMLX could look fresh and up to date! Meet our components in new Material Design and apply to your apps right now.

suite-material

Browse our samples and check Suite components in new skin

What is more, starting from Suite 5.0, new skin became default so in order to continue using SkyBlue, Web or Terrace, you’ll need to copy the needed skin file from skins/skin_name/* to codebase/.

TreeView component is added

New Tree control joined the library! It won’t replace dhtmlxTree component that we have now, but could become a good alternative for many cases. It’s more lightweight and faster with big datasets, so if you need fast javascript tree control without some complex features for now – dhtmlxTreeView is for you.

treeview

Visit TreeView page

Nevertheless, TreeView already contains useful functionality as drag-n-drop, checkboxes, multi-selection and more. We are going to enhance our new component and your feature requests are definitely needed.

Font Awesome support

With dhtmlxSuite 5.0, our controls support Font Awesome, popular icon fonts. If you are not aware about these icons, you may find the related information here.

fa_icons

Form Builder Tool

Forms creation becomes much simpler with a new developer tool – Form Builder. It allows you to build forms of any complexity within minutes. It’s not a part of Visual Designer but a standalone program. In a couple of weeks we’ll provide a video tutorial that will describe the whole process of working with this tool. For now you may check the documentation.

form builder dhtmlx

Try Form Builder right now

Note: We are still working on Form Builder to make it more convenient and user-friendly, so don’t hesitate to leave us your feedbacks and suggestions (drop us an email to support@dhtmlx.com).

Updated Look of Visual Designer

Though we haven’t updated Visual Designer functionality yet, you may check a new design of it. It’s a small step to further updates of this tool.

Visual Designer

Fixes and improvements

You may find a full what’s new list here.

There is no complex migration, make sure about it here and upgrade your library right now!

New website design as a part of major 5.0 version release

If you visit our website often, you’ve probably noticed that it got completely new mobile-friendly design, improved navigation and modern look. We hope that you like our solution and will visit us even more often :) And sure, feel free to leave your thoughts and comments regarding new http://www.dhtmlx.com/, we are always happy to get feedback from you!

new design

The customers with active support subscription will receive a link to the updated version via email (within 24h). The standard edition can be found here.

Have a nice day everyone!

The post Suite 5.0 is Out! Material Design, New TreeView Control and More appeared first on DHTMLX Blog.

dhtmlxScheduler 5.1: Horizontal Scroll for the Timeline and New Server-Side Integrations

$
0
0

In dhtmlxScheduler 5.1 we’re eager to present you with the two most long-awaited updates of the Timeline view – a horizontal scroll inside the Timeline and a major performance update of the Timeline view.

However, we didn’t confine the release to these features. Now integrating your JavaScript scheduler with different server-side technologies will be smooth and easy with our brand new guides and complete demos on GitHub for Node.js, PHP, ASP.NET Core and Ruby on Rails.

So here is dhtmlxScheduler 5.1 trial version – test it now and leave your feedback!

Horizontal Scroll in the Timeline View [PRO]

Horizontal scroll in the TimelineCheck the sample>

The highlight of v5.1 is the implementation of the horizontal scroll inside the Timeline, which offers the most convenient solution for surfing the calendar within impressively vast time intervals. Thus, managing events gets much easier, as end users may rapidly reach the necessary dates in the Timeline. You can find new properties for adding a horizontal scrollbar in our docs.

We also added an autoscroll option, so that end users could change the event’s duration or move it forward simply by dragging it along the Timeline while it’s being scrolled automatically. You can set up the speed and sensibility of the autoscroll in order to meet your requirements.

Autoscroll in the Timeline viewCheck the sample >

Smart Rendering and Performance Update of the Timeline View [PRO]

Before v5.1 the work of the Timeline view could become rather slow when large amounts of events and sections were displayed. The newly introduced smart rendering feature greatly optimizes the performance of the Timeline view by rendering only the rows, columns, and events, which users see on the screen. New elements are being rendered while users are scrolling through the Timeline.

This update allows you to use large Timelines in your app without any kind of delays or lags from the UI. If you already have an application with the Timeline view, which shows around 100 sections or more, – this improvement should be noticeable.

Smart rendering is enabled in the scrollable Timeline by default.

Please note that all these improvements required a significant rework of the Timeline markup, which affected all versions and modes of the Timeline view – Tree Timeline, Daily Timeline, Cells/Bars modes.
You might need to make some slight code changes in order to successfully migrate to the latest version. Please check our migration notes to find out more.

New Server-Side Integrations

Starting your work with dhtmlxScheduler will be much easier now, as we introduced several new guides with a step-by-step explanation of how to initialize Scheduler using different backend frameworks. Check the first bunch of guides devoted to Node.js, PHP, PHP/Laravel, Ruby on Rails and ASP.NET Core and their online demos on GitHub.

Node.jsPHPRuby on RailsLaravelASP.NET Core

We also invite you to write us what server-side frameworks you use, so that we could prepare integration guides that would be the most helpful for your work. Just leave a comment below or provide an answer through our survey form.

Adding a Header Label for Columns

One of the minor improvements of v5.1 is an ability to add a label above the section column of the Timeline:
Label for Column Section Header

Updating Scheduler.NET to the version 4.0

Apart from updating our JavaScript scheduling component, our dev team also rolled out a major update 4.0 of our Scheduler for ASP.NET. Now Scheduler.NET acquires all the latest features of dhtmlxScheduler: trendy Material skin, horizontal scroll in the Timeline view, smart rendering and performance update of the Timeline view.

Hope you’ll enjoy our release! To try out the latest version right now download the evaluation package here >

Feel free to leave your feedback in the comments’ section below and don’t forget to tell us which server-side framework you use for the future guides about server-side integration.

Our customers will receive the news about the update and the latest PRO version 5.1 via email within 24 hours (or find the download link in the Client’s Area).

Related Material:

The post dhtmlxScheduler 5.1: Horizontal Scroll for the Timeline and New Server-Side Integrations appeared first on DHTMLX Blog.

Major Update 4.0 of DHTMLX Scheduler.NET

$
0
0

We’re happy to introduce the Major Update 4.0 of our Scheduling component specially tailored for ASP.NET!
V4.0 brings out the most anticipated features:

  • Modern Material skin
  • Horizontal scrollbar for the Timeline view
  • Smart rendering update

Read more about the release on Scheduler.NET website >

Material skin for Scheduler.NET

We invite our clients to get the latest version in their Client Area.

If you’re new to Scheduler.NET download a free trial version here.

The post Major Update 4.0 of DHTMLX Scheduler.NET appeared first on DHTMLX Blog.

Maintenance Release of dhtmlxGantt 6.0.2 [PRO]

$
0
0

As promised, we’ve delivered a maintenance release of our JavaScript Gantt chart library with updated TypeScript definitions and several important fixes soon after the November major version of dhtmlxGantt 6.0 rolled out.

Updated type definitions are already available at @types/dhtmlxgantt (https://www.npmjs.com/package/@types/dhtmlxgantt).
This release brings them up to date with dhtmlxGantt v6.0 API.

The list of 6.0.2 fixes:

  • (fixed) ReferenceError: getResourceAssignments is not defined when importing Gantt into Vue.js project
  • (fixed) Script error on deleting task after assigning resource to it via resource form
  • (fixed) JS error in resource diagram after second initialization of Gantt
  • (fixed) Script error on toggle timeline visibility when marker extension is used
  • (fixed) Page freeze on gantt.parse if tasks tree contains cyclic references, script error is thrown instead

V6.0.2 is available for PRO customers in their Client Area. We’ll also send a notification about the release via email.

New to dhtmlxGantt? Get a 30-day free trial of the latest major version 6.0.

The post Maintenance Release of dhtmlxGantt 6.0.2 [PRO] appeared first on DHTMLX Blog.

Maintenance Release of dhtmlxSpreadsheet 3.0.1 and 3.0.2

$
0
0

Not so long ago dhtmlxSpreadsheet was entirely renewed and updated to the major version 3.0. The previous month was fruitful in terms of new improvements. Our dev team delivered two maintenance updates of our JavaScript spreadsheet library:

    V3.0.1 updates (November 8, 2018):
  • (fixed) Incorrect behavior of the undo operation
  • (fixed) Incorrect behavior of the cut-paste operation on a group of cells
    V3.0.2 updates (December 6, 2018):
  • (fixed) Issues with hotkeys behavior
  • (fixed) Issues with the placement of the selection handle
  • (fixed) Issues with the loss of focus on the active cell
  • (fixed) Incorrect behavior of selection on the active cell
  • (fixed) Incorrect behavior of hotkeys on the active cell
  • (fixed) Incorrect behavior of scrolling by arrow keys

Please find the release notes in our documentation.

Our current clients are invited to the Client Area to download the latest version of dhtmlxSpreadsheet. We’ll also send them an email notification with the download link.

To try out the updated dhtmlxSpreadsheet – just fill in the form here (30-day free trial).

Stay tuned and drop us a line about your impressions of the recent updates!

The post Maintenance Release of dhtmlxSpreadsheet 3.0.1 and 3.0.2 appeared first on DHTMLX Blog.

dhtmlxRichText 1.0: Launching a Brand New JavaScript Rich Text Editor

$
0
0

Today DHTMLX library is joined by a brand new JavaScript component for real-time text editing – dhtmlxRichText!

The new component is a JavaScript rich text editor with support for parsing and serialization in HTML and Markdown formats. It has a flexible structure with an adjustable toolbar, two modes for displaying the editor in the most convenient way, fullscreen mode, and support for localization. The editor is compatible with all major browsers, including IE11+. The component goes with special wrappers for the most widely used client-side frameworks – Angular, React, and Vue.js.

Download a free Trial version of dhtmlxRichText 1.0 >

Parsing and Serialization in HTML and Markdown formats

Our rich text editor is aimed at processing content in HTML and Markdown formats. The setValue method allows parsing a text in the standard HTML format or Markdown format, which is fulfilled with the help of the Marked.js parser.

var htmlText = `<h1>Meet DHTMLX Rich Text Editor!</h1>` +
`<p>The demo will show you a customizable JavaScript rich text editor.</p>` +
`<p><i>Read more in</i><a href="https://docs.dhtmlx.com"><i>documentation</i></a></p>.`
 
richtext.setValue(htmlText);

Parse HTML and MarkdownCheck parsing HTML sample >
Check parsing Markdown sample >

The getValue method enables the serialization of your edited and formatted text in HTML or Markdown:

// getting content in the markdown format
var content = richtext.getValue("markdown");

Serialize HTML or MarkdownCheck the sample >

Modes for Convenient Editing

The text editor is equipped with two built-in modes for arranging its layout in the most suitable way to meet your needs: classic mode and document mode. You can define the desired mode on the initialization stage via the mode configuration option. Check the sample >

Classic modeClassic modeDocument modeDocument mode

Besides, you can add a special toolbar control for enabling a fullscreen mode in the process of editing the text if necessary. The API methods let you enter or exit the fullscreen mode:

// enter full screen
richtext.fullScreen();
 
// exit full screen
richtext.exitFullScreen();
Adjustable Toolbar

The toolbar structure can be modified depending on your requirements via the toolbarBlocks configuration option. There are default blocks of controls: Undo, Style, Decoration, Colors, Align, and Link blocks, and two additional controls: Clear and Fullscreen, which can be included in the toolbar:

var richtext = new dhx.RichText(document.body, {
    // full toolbar
    toolbarBlocks: [
        "undo", "style", "decoration", "colors",
        "align", "link", "clear", "fullscreen"
    ]
});

Full toolbarToolbar with all blocks of controls
You are free to change the order of controls’ arrangement and apply a wide range of customization options.

Flexible Customization

Our JavaScript text editor provides such customization possibilities as changing the icon font pack, adding custom toolbar controls, updating or deleting the existing controls.

By default, the editor makes use of the Material-style icons. However, you can replace them with any other icon font pack like Font Awesome. Check the sample >

Adjusting the toolbar controls to your needs takes little effort, as the data collection API supplies you with all the necessary methods.

For instance, it’s possible to add a custom button, which will serve to show the number of characters in the text:

            rich.toolbar.data.add({
                type: "button",
                value: "Count Characters",
                id: "calc"
            }, 24);

Custom Toolbar ButtonCheck the sample >

This operation is possible due to the getStats method:

var chars = richtext.getStats().chars,

You can also specify in which part of your app you’d like to display the result of the operation. Check documentation >

Initialization with Angular, React, and Vue.js

dhtmlxRichText provides specially tailored initialization guides for the most popular client-side frameworks: Angular, React, and Vue.js. It makes implementing the editor in apps based on different technologies much quicker. Check documentation:

So, let’s get started!

Get a 30-day free trial, evaluate our JavaScript rich text editor, leave us your feedback and ideas on the features you’d prefer to see in the following releases in the comments’ section or through the survey here.

By the way, dhtmlxRichText is a complementary component in the Complete bundle – get more JavaScript widgets and save money!

Related Material:

The post dhtmlxRichText 1.0: Launching a Brand New JavaScript Rich Text Editor appeared first on DHTMLX Blog.


Video Tutorial: How to Create a JavaScript Gantt Chart with Node.js

$
0
0

We’re glad to introduce a video tutorial describing how to initialize dhtmlxGantt with Node.js. In this video, we’ll show you how to easily:

  • create a basic JavaScript Gantt chart on the page
  • connect it to the Node.js backend
  • populate the Gantt chart with data
  • and send user changes back to the backend where you can save them to your data storage

This video doesn’t show the code that would save the user changes made to Gantt on the backend. However, you can find detailed instructions on how to do that in a complete tutorial on Node.js integration using MySQL from our blog.

In order to create a basic Gantt chart on your own, follow these steps:

  1. Download dhtmlxGantt free trial version
  2. Consult a demo on GitHub
  3. Get acquianted with the integration guide in our documentation

Hope it will come in useful for you! If you have any questions, don’t hesitate to leave them in the comments’ section below.

Stay tuned for the upcoming video tutorials – Gantt with PHP Laravel is on its way!

Subscribe to DHTMLX youtube channel to be the first to get the news about DHTMLX video tutorials, release overviews and product updates >

The post Video Tutorial: How to Create a JavaScript Gantt Chart with Node.js appeared first on DHTMLX Blog.

Customer Spotlight: dhtmlxGantt for XB Software

$
0
0

This time we’re happy to share a success story of building an MVP based on dhtmlxGantt and React.js framework by XB Software development team from Belarus.

XB Software is a leading full-cycle custom web development company. They create comprehensive ERP solutions and reliable logistics systems. They render web and mobile app development, software testing and staff augmentation services. The company is ISO27001 and ISO9001 certified.

The Challenge

We’ve recently faced quite a hard task when our client asked us to develop a project management solution for their ERP system in a short time. The client’s company engaged in logistics is growing rapidly with an increasing number of employees and vehicles. For that reason, they need a project management tool for optimizing their supply chain and inventory management. Our team really had no time for building a complex web app. So we decided to create a minimum viable product, which would help us tailor-make the most suitable solution for our client as soon as possible.

We made up our mind to use a Gantt chart with the following features:

  • Ability to start a new project
  • Ability to rename and delete the existing project
  • Ability to create and edit tasks and task dependencies
  • Ability to switch between the existing projects
  • Ability to start a new project using an existing one as a template

Another question was which client-side framework to choose for the development. After pondering a while, we picked one of the most popular technologies – React.

Then we should find a third party library for a project management system in order to save us time and effort. A JavaScript Gantt chart by DHTMLX appeared to be the right choice, as it provides all the necessary functionality for our project and can be integrated with React without trouble.

Implementation

We started with the basic functionality so that our client could evaluate our solution at once and provide us with feedback.

Our MVP allows creating a new project by simply adding new tasks to the grid or using templates. Projects consist of different task types with dependencies, which can be defined by end users. Manipulating the task duration is easy with the help of a simple drag-and-drop feature. Besides, it’s possible to define the task completion in percent. Moreover, our development team made it possible for users to create their own custom templates based on the existing projects. It enables them to work with multiple projects and switch between the tasks and projects on the fly.

dhtmlxGantt with React

We launched our product with this basic set of features and continued to develop more complex functionality like the resource usage diagram:

dhtmlx gantt react

Result

The solution offered to our client contributed to the company’s efficiency, according to their estimations. In our turn, we received useful feedback and got a better understanding of our client’s needs. We’ll keep on with implementing new features in our project management system using dhtmlxGantt.

We’re very grateful to XB Software for sharing their experience and choosing our JavaScript Gantt chart for their project.

Don’t hesitate to tell us your story – every DHTMLX client who submitted a success story to our blog is eligible for a discount on the new licenses or support plan extension.

The post Customer Spotlight: dhtmlxGantt for XB Software appeared first on DHTMLX Blog.

Maintenance Release: Scheduler 5.1.1, RichText 1.0.1 and Gantt 6.0.4

$
0
0

And here comes the last portion of maintenance releases this year! Our dev team worked hard to ensure that everything is flawless in the recently updated Scheduling component v5.1, the newest JavaScript rich text editor v1.0 and our top-notch JavaScript Gantt 6.0.

Find out what was improved by our developers in dhtmlxRichText 1.0.1:

  • (Fixed) Incorrect undo behavior with the setValue method
  • (Fixed) Issue with the link background on switching between links
  • (Fixed) Issue with toolbar modifiers after removing a letter

Download the rich text editor’s latest trial version >

Get acquainted with dhtmlxRichText public roadmap and vote for the most anticipated features!

Check the list of updates in dhtmlxScheduler 5.1.1:

  • (Fixed) Keyboard navigation focus not being highlighted in the timeline
  • (Fixed) Incorrect initial height of timeline_scale_header if second_scale specified
  • (Fixed) Bug with event_min_dy not affecting section height if only one event is located inside a section
  • (Fixed) Bug with quick info popup self-closing when the same event is clicked multiple times
  • (Fixed) Script error which fired after deleting event in Year view
  • (Fixed) Incorrect initial display of scrolled timeline if no events loaded into the scheduler
  • (Fixed) Ability to enable smart rendering for non-scrollable timelines
  • (Fixed) Issue with scroll position resetting on date change when key_nav extension is enabled in the timeline
  • (Fixed) Incorrect value old_date argument of onBeforeViewChange event in some cases
  • (Fixed) Incorrect display of scrollable timeline with ignored time cells
  • (Fixed) Incorrect behavior if scrolling happened during drag-create of new events in day/week views
  • (Fixed) onAfterSchedulerResize event not firing in Timeline view
  • Performance improvement for event rendering in Week view

Download the Scheduler’s latest trial version >

Cath up with the latest updates in dhtmlxGantt 6.0.4:

  • (Fixed) Incorrect task position after task vertical dnd in order_branch=’marker’ mode
  • (Fixed) Script error after deleting a sub-tree which contains selected task
  • (Fixed) Script error on Save/Cancel lightbox containing resource filters

Download dhtmlxGantt 6.0.4 trial version >

Make the most out of the announced updates and enjoy the improved functionality of our components. Current clients may download their latest versions of DHTMLX products in the Client’s Area.

Looking forward to the hot and promising 2019! Happy Holidays!

The post Maintenance Release: Scheduler 5.1.1, RichText 1.0.1 and Gantt 6.0.4 appeared first on DHTMLX Blog.

UI vs UX (and how they intertwine)

$
0
0

The differences between UI and UX have been underlined in many articles, however, their interdependence has not been enough put to the forefront.

Long story short:
UI stands for User Interface, and it deals with visual, graphic and front-end design.
UX stands for User Experience, and it deals with the well-running functionalities of a website, and its interactivity with the end user.

Short story long:

User Interface Design

UI (User Interface) involves the aesthetic appearance of a website, and how the content elements are presented to users of that website.
All basic elements that make up website’s pages fall under the incidence of UI design.
These are:

  • Text
  • Images
  • Background images
  • Hero images
  • Links
  • Videos
  • Video thumbnails
  • Lists
  • Photo galleries, etc.

They are organized so as to form a guided tour for visitors who come and see the pages of a website. Users expect to be taken from a place they land on the website to a new section of a page and a new part of the message, and so on. They’ll infer the meaning of the overall message by connecting the dots among different parts of the message, spread all throughout the website pages, under the form of text, links, images, and videos. That organization of elements within website pages belongs to user interface design.
It requires graphic skills, an eye for aesthetics and an ability to combine elements according to pre-existent design guidelines.
Then, where aesthetics meets practical purposes, UX comes in.

User Experience Design

As the arrangement of elements in web pages needs to meet practical purposes and users’ expectations, User Interface design is part of UX.

UI is created within a larger frame of User Experience design and best practices.

In addition to basic aesthetics, UX involves research, hence, it approaches to market research through the skills needed to perform such tasks.
So, the following will be added to the process of building a website, as necessary parts of good design:

  • Research
  • Creating mockups and prototypes
  • Testing
  • Improving user interactions with the website
  • Optimization for better user experience on the website pages
  • Findability – testing and optimization, etc.

Here are some stats regarding the impact of good UX design on a website (translated in profit figures):
UI vs UXSource >

Improvements can go a long way, including all minor and major aspects of user experience, like in the case below:
UI vs UX mobileSource >

I.e. For WordPress users, plenty of plugins help create better user interactions with a website. So, there are plugins such as Shortcoder, which generates shortcodes a designer integrates into a website to add functionalities such as contact forms, galleries, videos, etc. Shortcodes are small pieces of code marked by brackets, that perform a certain function on the website.
Shortcoder helps you avoid writing code by yourself and prevent creating long lines of code that are both a headache and a non-feasible task for those who are not developers.

Terms you should be familiar with as a UX designer

Once you dive into learning UX skills, tips and tricks, you will come across some specific terms you should get familiar with:

Code refactoring:
The term refers to restructuring code behind a website, without changing its functionalities. It helps to make a cleaner code, reduce the code complexity and improve the code readability.

Minimal viable product:
This term refers to creating a product (website, in this case), with sufficient features so that it can be welcomed by early adopters. This first version of the website should contain the most valuable features that will make it stand out from the crowd.

Unit testing:
Unit testing refers to the first level of tests that’ll be run in the process of building a website. It refers to testing individual units (features) of the website and seeing that every item is in place, up and running.

Retrospective UX:
This is a technique of looking back at one iteration, with the intention to use the findings for optimization of next iterations in User Experience design.

Software development kit:
This term refers to software or a set of software development tools that UX designers use for building a new website.

A/B testing:
This term is akin to the one used for conversion rate optimization in marketing. It refers to testing two different versions of a website in order to see which one provides a more valuable user experience for visitors on that website.

Skills needed for good UI and UX

Whether as a UI or UX designer, you should master skills such as:
HTML, CSS, and JavaScript – these are the basic elements you should start from. Thus, you’ll be able to code for yourself and make modifications to the front-end design, by changing lines of code in the backend.
Databases – these skills teach how relational logic works and can give insights into the design process of building websites the right way.
Algorithms – with a conceptual understanding of what algorithms can do, you’ll increase your chances to become a good UX designer.

To wrap up:

By learning the skills above, you’ll see clearly the meaning of all terms that are UI and UX design-related. With a solid theoretical understanding of UI and UX design, you’ll get involved into building more efficient, successful websites that both look good and are welcome by visitors in their experience with the website pages.

The post UI vs UX (and how they intertwine) appeared first on DHTMLX Blog.

Maintenance Release: Gantt 6.0.7, Scheduler 5.1.6, Pivot 1.3.3

$
0
0

The work of our development team on our products continues vigorously at the beginning of the new year. In January we’ve released maintenance versions of three products: Gantt, Scheduler, and Pivot. Check the updates below:

Pivot 1.3.3 (January 10, 2019)

  • (Fixed) Issues with styles of cells in export data
  • (Fixed) Incorrect styles of filters’ popups

Get the latest trial version of our pivot component 1.3.3 >

Scheduler 5.1.6 (January 11, 2019)

  • (Fixed) Incorrect position of events scheduled on Sat-Sun with start_on_monday = false in the Month view
  • (Fixed) Script error in a scrollable timeline with the current time marker
  • (Fixed) Incorrect argument value of the onYScaleClick handler in a scrollable timeline after horizontal scrolling
  • (Fixed) The bug that caused a scrollable timeline to be rendered empty until the next refresh after reloading sections
  • (Fixed) The bug with a scrollable timeline which caused some cells of Tree timeline folders not being rendered after horizontal scrolling
  • (Fixed) Unexpected behavior of event resize with the all_timed extension, only the last event chunk should be resizeable
  • (Fixed) Event disappearing during resize in the all_timed=”short” mode

Download Scheduler 5.1.6 trial version >

Gantt 6.0.7 (January 16, 2019)

  • Reduced the number of redundant repaints of the resource diagram
  • (Fixed) Script error from the resource diagram after deleting a task
  • (Fixed) Script error from the fullscreen extension after exiting fullscreen mode on the Esc key
  • (Fixed) Incorrect state of links drag and drop when dragging a link between multiple charts on the page. Creating links between gantts is not supported
  • (Fixed) Script error after deleting multiple selected tasks using keyboard navigation
  • (Fixed) Default mapping of inline editors. Inline editors shouldn’t block keyboard shortcuts on task cells

Get the latest version of our Gantt chart library 6.0.7 >

If you have an active license subscription, please find the latest versions in your Client’s area.

Stay tuned for future updates!

The post Maintenance Release: Gantt 6.0.7, Scheduler 5.1.6, Pivot 1.3.3 appeared first on DHTMLX Blog.

dhtmlxGantt 6.1 with Time Constraints, Backward Scheduling, S-curve and dataProcessor Update

$
0
0

It’s high time to roll out the next all-encompassing update of our JavaScript Gantt chart library! Version 6.1 comes out with a wide range of various features and performance enhancements, which we hope will boost the efficiency of your project management apps to a new level.

Download the latest v6.1 of our js gantt chart and give it a try in your project!

Here is a quick overview of the brand new dhtmlxGantt features:

  • Time constraints for tasks for a more flexible project scheduling
  • Backward planning to focus on your project’s deadline
  • Adding custom content such as an S-curve in the overlay
  • Defining project-level work calendars
  • Creating tooltips for each and every element of dhtmlxGantt
  • Ability to import dhtmlxGantt as an ES6 module
  • Routing options for dataProcessor
  • TypeDefinitions included in the package from now on

Read our release article to get all the details or take in our release video:

Custom Content in the Overlay (Gantt with S-Curve)

A new possibility of adding an overlay to dhtmlxGantt allows developers to embed any custom content in the top layer over the Gantt chart. It comes in useful if advanced analytics for estimating the project’s success is needed – for example, an S-curve showing progress or increasing expenses of a project. As you can see from the graph, the blue line depicts the planned progress of the project while the red line reflects the actual progress in percentage. The further two lines diverge, the bigger is the gap between the estimated and actual progress. As soon as the graph reaches today’s date, the red line becomes dotted and shows the predicted progress based on the previous data.

Gantt S-curveCheck the sample >

You can add an overlay simply by using a div container or an HTML canvas. For the content itself, you may choose any third-party library. We’ve used Chart.js in the example above. It takes just two steps to make everything work:
1) include the overlay extension on the page
2) and use the addOverlay() method with a function, which specifies the logic of adding overlay content as a parameter:

var overlay = gantt.ext.overlay.addOverlay(function(container){
    var canvas = document.createElement("canvas");
    container.appendChild(canvas);
    canvas.style.height = container.offsetHeight + "px";
    canvas.style.width = container.offsetWidth + "px";
 
    var ctx = canvas.getContext("2d");
    var myChart = new Chart(ctx, {
        type: "line",
        // full chart configuration
    });
});

Feel free to experiment with any other custom content to be displayed over the Gantt chart and help managers to handle their projects intelligently.

Tooltips For All Gantt Elements

By default, tooltips are available only for tasks in the Gantt chart area. However, now you are free to provide tooltips wherever you need, for example, for the cells of the timeline scale or a resource diagram:

Gantt chart tooltipsCheck the sample >

gantt.ext.tooltips.tooltipFor({
  selector:".gantt_scale_cell",
  html:function (event, node) {
    var relativePosition = gantt.utils.dom.getRelativeEventPosition(event, gantt.$task_scale);
    return gantt.templates.task_date(gantt.dateFromPos(relativePosition.x));
  }
});
Applying Time Constraints for Tasks

Apart from common task dependencies, project managers can put time constraints on tasks in order to prioritize them. Time constraints make project planning faster and easier, as Gantt will automatically schedule all tasks as soon as a project manager puts the necessary constraints on some of them.

Let’s dive deeper into the 8 types of time constraints Gantt chart offers:

1) As soon as possible (ASAP) means that an independent task starts with the start of a project and a dependent task – as soon as its predecessor task has finished.
2) As late as possible (ALAP) means vice versa. An independent task ends at the same time that the project does, whereas a dependent task ends exactly when its immediate successor begins.

All other constraints apply both to dependent and independent tasks in the same way:

3) Start no earlier than (SNET) indicates that a task should start on a particular date or any time after it.
4) Start no later than (SNLT) highlights the latest date when a task can start.
5) Finish no earlier than (FNET) means that a task should end on a particular date or any time after it.
6) Finish no later than (FNLT) vice versa sets a deadline for a task to finish.
7) Must start on (MSO) determines an exact date for a task to start.
8) Must finish on (MFO) sets an exact date for a task to end.

It’s possible to set a time constraint either via the lightbox constraint control or with the help of inline editors right in the grid:

Time constraintsCheck the sample >

Backward Planning Strategy

The functionality of time constraints allowed us to introduce a backward planning strategy in addition to the default forward planning. Backward planning presupposes that tasks are scheduled from the end of the project with a focus on the entire project’s deadline:

Gantt Chart Backward PlanningCheck the sample >

gantt.config.schedule_from_end = true;
gantt.config.project_end = new Date(2019, 4, 1);

This strategy makes use of As late as possible time constraint type with the last task finishing on the last day of the project.

Please note that time constraints influence the auto-scheduling of tasks. The updated auto-scheduling feature changes the project’s schedule taking into account the applied time constraints. Anyway, we’ve included support for backward compatibility. The compatibility mode restores the previous behavior of the auto-scheduling extension. You can enter this mode via the following configuration option if you’d like to stick to the old auto-scheduling logic:

gantt.config.auto_scheduling_compatibility = true;
Project-Level Work Calendars

With this functionality, our Gantt chart augments its flexibility, as from now on it’s possible to set working hours and days not only for a particular task or resource but also for groups of tasks in sub-projects. Thus, all tasks inherit a work calendar of their parent-project. However, one can assign another work calendar to a specific task of the project in contrast to the project’s calendar.

Project-Level Work CalendarCheck the sample >
You can enable this option, which is disabled by default:

gantt.config.inherit_calendar = true;
Routing Options for dataProcessor

Now we’re approaching a range of important performance enhancements in v6.1. Newly introduced custom routing options will help you avoid lots of coding during the integration of dhtmlxGantt with both REST and non-REST API backend. An update of the dataProcessor will also simplify the pre and post handling of the requests sent to the database.

Angular, React and Vue.js developers will benefit from the updated API, as dataProcessor will help to link dhtmlxGantt with data-saving components in their applications. We’ve also upgraded our Ajax module which now supports promises – all these changes aimed at making the work with data simpler and more flexible. Check our sample >

dhtmlxGantt Import as an ES6 Module

The update brings out a convenient and developer-friendly way to add Gantt to your applications. You can import Gantt as an ES6 or AMD module writing just one line of code:

import { gantt, Gantt } from 'dhtmlx-gantt';

This will allow you to use any popular script loader you choose. Meanwhile, we’ll prepare thorough guides on importing dhtmlxGantt into React, Angular, and RequireJS-based apps. Stay tuned!

And last but not least, we’ve included TypeDefinitions in the package!

So here we go… download Gantt 6.1 free trial, play around with custom content in the overlay, add new tooltips, apply time constraints for tasks, assign new project-level work calendars, make use of the backward planning strategy and enjoy all other useful features. You’re welcome to send us your feedback in the comments’ section below.

If you’re eager to know what we have planned for the future updates, consult our Gantt chart roadmap.

If you’re our current client with an active support subscription, we invite you to get the latest version 6.1 in your client’s area.

Related Material:

The post dhtmlxGantt 6.1 with Time Constraints, Backward Scheduling, S-curve and dataProcessor Update appeared first on DHTMLX Blog.

dhtmlxRichText 1.1: API to Work with Text, Block Quotes, and Advanced Statistics

$
0
0

A recently launched dhtmlxRichText, JavaScript rich text editor, receives its first minor update v1.1 with expanded functionality. We’ve provided developers with an easy and convenient way to work with content instantly via the editor’s API. The release also brings out a new toolbar block quote control for adding text quotes, an ability to serialize content into plain text, and advanced statistics for counting the number of characters, words and other text elements.
Rich text editor with block quotes and statistics

Download JavaScript rich text trial version 1.1 and let’s dive deeper into the release details!

Working With Rich Text Editor API

Starting with v1.1 developers gain access to the API of our JavaScript rich text editor that enables them to work with the text directly. Using the getEditorAPI() method you will get all the available methods for text processing such as adding a new text into the editor, styling it, adding a data model or returning it in the JSON format.

For example, the update() method helps you to change the style of a text, e.g. apply a new style to it:

var api = rich.getEditorAPI();
 
rich.getEditorAPI().update({
    modifier: "color",
    value: "#BB2B1A"
  }, api.getSelection());
});

Learn more about all the available API methods in the documentation.

Editor with Quotation Marks

We’ve added a new block quote control to our set of default toolbar controls to easily turn ordinary text into quotations:

Block quote control for text quotesCheck the sample >

The block quote control is included in the toolbar by default. Additionally, you can include a new statistics control for displaying a number of characters or other elements:

var richtext = new dhx.Richtext(document.body, {
    // full toolbar
    toolbarBlocks: [
        "undo", "style", "decoration", "colors",
        "align", "link", "clear", "stats", "fullscreen"]
    ]
});
Advanced and Custom Statistics

New API methods make RichText a more effective tool for text processing. From now on, our editor is able to count both characters with and without spaces as well as words using the getStats() method.

var stats = richtext.getStats();
{chars: 467, words: 80, charsExlSpace: 393}

Rich text editor statisticsCheck the sample >

The number of all counted elements can be displayed together or separately, depending on the needs of end users.

Showing the number of characters including spaces in a text:

var chars = richtext.getStats().chars;

Showing the number of words in a text:

var chars = richtext.getStats().words;

Showing the number of characters without spaces in a text:

var chars = richtext.getStats().charsExlSpace;

You can also determine where and how to display the numbers counted by RichText. For instance, the editor may show these statistics in a separate container after an end user clicks on a button.

However, the abilities of RichText are not limited to counting just words and characters. With the help of the customStats configuration property you can get any statistical characteristics you need (for example, a number of sentences):

Text editor with custom statisticsCheck the sample >

Plain Text Format

Besides converting content into HTML and Markdown formats, RichText gets an ability to serialize it into plain text via the getValue() method:

// getting content as a plain text
var content = richtext.getValue("text");

Content serialization in plain textCheck the sample >

Other Enhancements

Apart from new features, our dev team made a couple of improvements in the existing functionality. Among the most essential updates is support for the Asian languages. You can find the whole list in our docs.

Hope you’ll enjoy the update and find the newly added features useful for your applications! In any case, we invite you to share your ideas and feedback in our 1-minute survey. Also, feel free to leave your comments below!

If you’re interested in our plans for future development of rich text editor, consult its public roadmap and influence the development by voting for your preferred functionality.

Current clients will find a download link for the updated version in their Client’s Area.

Related Material:

The post dhtmlxRichText 1.1: API to Work with Text, Block Quotes, and Advanced Statistics appeared first on DHTMLX Blog.


dhtmlxSpreadsheet 3.1: Import and Export to Excel, Number Formatting, and More

$
0
0

We continue to gradually enhance our JavaScript components – and now it’s the turn of dhtmlxSpreadsheet to receive new powers and abilities.
javascript spreadsheet v3.1

The JavaScript spreadsheet was completely updated 4 months ago. The recent minor v3.1 brings out several features, which are essential for conveniently working with data:

  • Export of data from Spreadsheet to Excel
  • Import of data from Excel to Spreadsheet
  • Number formatting
  • Auto filling of cells
  • Hotkeys behavior in a range of cells

Before we go over the release details – download the latest trial version of JavaScript spreadsheet 3.1 to test it on the fly.

Import and Export to Excel

The current update enables end users to import Excel data into a web spreadsheet component as well as export data from Spreadsheet to Excel.
Export and import of Excel data into SpreadsheetCheck the samples with import of Excel data into Spreadsheet and export of Spreadsheet data to Excel >

The export and import operations became possible due to our two new WebAssembly-based libraries Excel2Json and Json2Excel. These libraries were developed by our team as open-source tools for converting Excel files into the JSON format and vice versa. They make use of the Rust programming language and WebAssembly.

In order to use the export and import of Excel files into your JavaScript spreadsheet, you only need to take 3 steps:
1) Install the corresponding library for export and import
2) Specify the necessary options in the Spreadsheet configuration and link the component to the installed libraries
3) Apply the related API methods

Read a detailed instruction on the import of data to Excel and export of data to Excel in the documentation.

Number Formatting

V3.1 comes out with an ability to set different formats for numeric values in cells. Spreadsheet default number formats are common (“”), currency (“$#,##0.00”), number (“#,##0.00”), and percent (“#,##0.00%”).

Applying a number format to a value is easy with the setFormat method:

// applies the currency format to the cell A1
spreadsheet.setFormat("A1","currency");

Besides, there is the getFormat method, which allows you to define what number format is applied for a particular cell:

var format = spreadsheet.getFormat("A1");
// ->"currency"

On top of all, you can modify the default number formats or even create custom formats via the formats configuration option. For example, you can change the name of the predefined currency format for “U.S. dollar” and add two new formats with ids – “euro” and “franc”:

var spreadsheet = new dhx.Spreadsheet(document.body, {          
    formats: [
        {
            name: "U.S. Dollar",
            id: "currency",
            mask: "$#,##0.00"
        },
        {
            name: "Euro",
            id: "euro",
            mask: "[$€]#.##0,00",
            example: "1000.50"
        },
        {
            name: "Swiss franc",
            id: "franc",
            mask: "[$CHF ]#.##0,00"
        }
    ]
});

Custom number formattingCheck the sample >

By the way, our Spreadsheet component automatically detects the format of content in cells due to the autoFormat configuration option enabled by default. However, you are free to disable it if you want.

Automatic Filling of Cells with Content

From now on, there is no more need for tediously typing in data by hand, as our JavaScript Spreadsheet is able to fill cells with data automatically. The autofill is based on a range of widespread patterns. For instance, in order to get a sequence of consecutive numbers from 1 to n, you just need to enter 1 and 2 into the first two cells and drag the fill handle to grab and autofill as many cells as you need. The spreadsheet can also automatically create sequences of odd and even numbers. Moreover, there is a pattern for making a series of numbers with letters.

Auto filling of cellsCheck the user guide >

Enhanced Hotkeys Navigation

We’ve improved hotkeys behavior for easier spreadsheet navigation inside a range of cells:

  • Enter – moves the selected cell down within the selected range
  • Shift + Enter – moves the selected cell up within the selected range
  • Tab – moves the selected cell right within the selected range
  • Shift + Tab – moves the selected cell left within the selected range

Hotkeys behavior in a range of cellsCheck the user guide >

So the next step is to download dhtmlxSpreadsheet 3.1 free trial version and test all the new features yourself!

We’re looking forward to your feedback about the release – share your thoughts in the comments below or write to us: info@dhtmlx.com

Current clients are invited to download the latest version in their Client’s Area.

Related Materials:

The post dhtmlxSpreadsheet 3.1: Import and Export to Excel, Number Formatting, and More appeared first on DHTMLX Blog.

Using DHTMLX Gantt Chart with Salesforce for Project Management Apps

$
0
0

In this article, we’ll talk about what benefits you can get by using our JavaScript Gantt chart to create project management applications for Salesforce. We’ll focus on the list of the main features that can be implemented with dhtmlxGantt and try to explain the main reasons for choosing Salesforce.

Why Choose Salesforce?

First of all, let’s see why dealing with Salesforce can be a good idea. At the moment, Salesforce takes the place of one of the most popular CRM platforms in the market of enterprise software. The company was ranked first by Fortune in its 100 Best Companies to Work For in 2018. Also, according to the latest statistics, Salesforce’s CRM market share is 19,4%, and it has 150,000 customers. Among the categories of provided services, you can find commerce cloud, sales cloud, service cloud, data cloud, marketing cloud, community cloud, analytics cloud, app cloud, and IoT.

The company offers almost every kind of enterprise software that you can think of. A wide range of software solutions can satisfy the most demanding customers. Moreover, any third-party developer that have enough skills can create and deliver a Salesforce component or provide modernization services for the existing components. Such an approach allows maintaining a wide diversity of available solutions and attracts developers for profitable collaboration. AppExchange is the Salesforce store where you can find all software solutions available at the moment. We’ll return to it later, but for now, you can use it to ensure that Salesforce apps can meet the needs of any business organization.

Why Use dhtmlxGantt as a Development Tool?

dhtmlxGantt is a comprehensive development tool for creating full-featured Gantt chart applications. It allows building cross-browser and cross-platform project management apps. Let’s look at some interesting features of this library.

High-performance applications created with dhtmlxGantt allow processing an incredibly large number of tasks simultaneously. This feature will be in high demand among companies that work on complex projects. dhtmlxGantt can render 10,000+ tasks, and the app will work flawlessly and without any lags. It doesn’t matter whether you work with 10, 100, or 1000 tasks at the same time. In any case, you will still work with a stable running application.

The zooming feature allows focusing on a particular part of a project. The available range includes month, days and hours view. Also, dhtmlxGantt allows displaying the whole week or just the working days.

Baselines help to ensure that you meet your deadlines. Here’s how it works. You can use baselines to mark the initial plan for your project. dhtmlxGantt allows displaying it alongside with its current actual state. A project manager can compare the current state of a project with the initial plan to define if there’s a necessity to correct the chosen approach.

The auto scheduling feature can be used by managers to make automatic changes to the schedule. It can be pretty useful in case of unpredicted delays. This feature allows updating the start date of the dependent task if the end date of the task it depends on changes. Implementing this feature, you can free users from the need to reschedule the whole project manually.

Advanced resource management features allow allocating and managing multiple resources. Resource load diagrams and histograms can be used by company management for accurate workload estimation:

Gantt resource load diagram for Salesforce

It’s hard to imagine a Gantt chart application that gained significant popularity among users without being able to do anything except rendering Gantt charts on the screen. Therefore, some additional functionality will never be redundant. The good news is that there are about 20 ready-to-use extensions that will allow you to meet the requirements of fairly diverse users. Tooltips, full-screen mode, status line, auto scheduling, smart rendering, and custom content — all these and many other features provide plenty of opportunities to achieve the desired look and feel.

If a user has to manage hundreds of tasks, it may be pretty hard to define those of them that have the most significant impact on the overall project time. The Critical Path Method allows significantly simplifying the work on such projects. This method enables defining the sequence of tasks that determine the overall duration of the project:

Critical path calculation in Gantt for Salesforce

Extensive customization features is another advantage of dhtmlxGantt. By default, dhtmlxGantt provides seven skins, including Material-based one. Also, there is a range of predefined templates. It’s up to you how your Gantt chart application will look like. You can change any element of a user interface, such as tasks, links, or tooltips. Also, you can modify the existing templates of the grid, timeline, lightbox, and other elements.

Do DHTMLX Gantt Chart and Salesforce Suit Each Other?

After we considered the main advantages of both Salesforce and dhtmlxGantt, it’s time to talk about how they can work together. At the moment of this writing, AppExchange offers 30 applications that implement some variations of Gantt chart:

AppExchange on Salesforce

Among them, there are 20 paid solutions. As you can see, this is an example of not the most competitive environment. For example, there are almost 600 schedulers, and more than 300 calendars available at the moment. Therefore, if you have an idea of a Gantt chart application that implements unique functionality, it’s more likely that your solution will be noticed.

As a developer, you won’t face significant third-party libraries’ compatibility issues during the development of your Gantt chart app for Salesforce since dhtmlxGantt enables smooth and secure integration thanks to LockerService. The development toolkit that you’ll use provides extensive customization possibilities that will be very important when it’ll come to the creation of a unique enterprise application. Last but not least, you can receive support from an experienced team of DHTMLX developers with 10+ years of expertise in web and mobile app development.

If you’re interested in implementing our Gantt chart library in your Salesforce app, don’t hesitate to contact us to get all the details and a live demo.

The post Using DHTMLX Gantt Chart with Salesforce for Project Management Apps appeared first on DHTMLX Blog.

How to convert an Excel file to HTML and JSON with DHTMLX open-source tools

$
0
0

While working on the latest releases of dhtmlxSpreadsheet, our development team created three new tools, which assisted us in converting Excel data into the JSON format (and vice versa) and generating HTML tables from Excel files. We didn’t think long and made these tools open-source and available to everyone. So, what are these three libraries and how do they work?

Based on WebAssembly and Rust

All three libraries were developed using the WebAssembly standard and Rust programming language. These technologies contribute to highly reliable code and fast performance. There are no vulnerabilities in the process of conversion, and you don’t have to worry about the safety of your data while it’s being processed. The small size of code allows you to perform the operations extremely quickly. Thus, you can use our open-source tools in your projects to maintain high-speed and secure websites and web apps.

Turning your Excel data into JSON and back

The first two open-source libraries enable you to transform the data kept in your Excel files into the JSON format and back from JSON to Excel. You can find a detailed description and instructions on GitHub:

You can install the libraries in two ways: via npm or cdn. After the data conversion, you’ll have both data and styles saved in Excel or JSON.

One of the most common use cases, when you might need to convert Excel into JSON and vice versa, is embedding your Excel sheets into a web-based spreadsheet. For example, our JavaScript spreadsheet makes use of the Excel2Json and Json2Excel libraries to provide end users with the ability to import and export Excel files. The spreadsheet has a set of features for further styling and formatting data to achieve the desired appearance.

Displaying Excel data as HTML tables

The third open-source tool Excel2Table was built on the basis of the Excel2Json library, which parses Excel files. The data is rendered as an HTML table preserving all the styles from Excel sheets.

Using the Excel2Table is very straightforward and simple:

1. The first step is to run the following command line to install the library:

npm i excel2table

2. Then import the library into your project:

import "excel2table";

3. And all that is left is to call the render function:

excel2table.render(html_container, data, config);

You can find all the parameters of this function and other technical details described in our GitHub repository.

As a result, you’ll have a precise HTML version of your Excel sheet:
Convert Excel to HTML

Generating such HTML tables comes in useful if you need to equip your app with a preview feature like an Excel file viewer. Or you may link an Excel file to a particular HTML table on your website and update your webpage with the table dynamically when something has changed in Excel sheets. It reduces the amount of manual work on website administration and helps you keep important information up-to-the-minute. Additionally, you can always style your HTML table in accordance to your webpage design to unify their look and feel.

All the three libraries are distributed under the MIT license, which allows you to use them both in non-commercial and commercial projects. If you have any questions regarding the usage of these libraries, please refer them to our team.

We’ll be looking forward to your feedback!

The post How to convert an Excel file to HTML and JSON with DHTMLX open-source tools appeared first on DHTMLX Blog.

Maintenance Release: dhtmlxGantt 6.1.2 and dhtmlxSpreadsheet 3.1.2

$
0
0

Time runs so fast that it’s hard to keep up with its pace and let you know about everything going on in DHTMLX development team. But there are those small things that really matter and make your work with our JavaScript components stable. So, meet the latest pack of improvements in our JavaScript Gantt chart and JavaScript spreadsheet.

What’s new in dhtmlxGantt 6.1.2

March 26, 2019

Updates:

  • (Added) A method for getting the active cell – keyboard navigation

Fixes:

  • (Fixed) Incorrect work of the resource panel after creating a new datastore to overwrite the previous one
  • (Fixed) Incorrect values of query parameters in the POST mode of dataProcessor
  • (Fixed) An incorrect result of gantt.getClosestWorkTime when called without specifying a direction
  • (Fixed) Issue when the English locale couldn’t override the previously added locale
  • (Fixed) Script error with gantt.undo and indent actions in the grid
  • (Fixed) SalesForce compatibility: new resize listener was broken in SF, fallback is added

Download trial version >
What’s new list in documentation >

What’s new in dhtmlxSpreadsheet 3.1.2

March 25, 2019

Fixes:

  • (Fixed) Issues with text styles in Excel export
  • (Fixed) An issue with underlining right-aligned text

Download trial version >
What’s new list in documentation >

Current clients are invited to download the latest versions of their components in the Client’s Area.
We’ll be eager to hear your feedback and ideas on the future updates in the comments below!

The post Maintenance Release: dhtmlxGantt 6.1.2 and dhtmlxSpreadsheet 3.1.2 appeared first on DHTMLX Blog.

How to Specify Columns of the Grid in Gantt – DHTMLX Gantt Video Tutorial

$
0
0

We’re happy to announce a new series of our video tutorials devoted to the configuration of DHTMLX Gantt chart!

In the first video from our series, we’ll show you how to specify columns of the left-hand grid and give you a small overview of templating and formatting functions in dhtmlxGantt:

The columns of the grid in a Gantt chart are specified as an array of objects inside the ‘columns’ config.
A typical configuration can look like this:

gantt.config.columns = [
    {name: "text", tree: true, width: '*', resize: true},
    {name: "start_date", align: "center", resize: true},
    {name: "duration", align: "center"},
    {name: "add", width: 44}
];

In fact, this is the configuration you’ll have by default even if you don’t specify this setting in your app.

Columns have quite a lot of optional properties. An important thing to know is that only the ‘name’ property is mandatory. Its main purpose is to define the content of cells. By default, the cell will take the value from the matching property of the task:

document.addEventListener("DOMContentLoaded", function(event) {

    gantt.config.columns = [
        {name: "text", tree: true, width: '*', resize: true},
        {name: "start_date", align: "center", resize: true},
        {name: "duration", align: "center"},
        {name: "add", width: 44}
    ];

  gantt.init("gantt_here");
 
 
  gantt.parse({
    data: [
        {
            id: 1, text: "Project #2", start_date: "01-04-2018", duration: 18, order: 10,
            progress: 0.4, open: true
        },
        {
            id: 2, text: "Task #1", start_date: "02-04-2018", duration: 8, order: 10,
            progress: 0.6, parent: 1
        },
        {
            id: 3, text: "Task #2", start_date: "11-04-2018", duration: 8, order: 20,
            progress: 0.6, parent: 1
        }
    ],
    links: [
        {id: 1, source: 1, target: 2, type: "1"},
        {id: 2, source: 2, target: 3, type: "0"}
    ]
  });
});

Check a live example >

As you can see in our example above, the column named ‘text’ displays values from the ‘text’ property of the task object. The same applies to the start date and duration.

The only exception is the column named ‘add’ – it’s a predefined value that displays the ‘+’ sign which allows users to add children for the task.

Basic Grid in DHTMLX GanttBasic Grid configuration in DHTMLX Gantt

Based on that, you can specify your own columns. For example, to define four custom columns in the grid such as ‘Task name’, ‘Holder’, ‘Start Time’, and ‘Progress’, we should specify the columns parameter, where ‘text’, ‘holder’, ‘start_date’, and ‘progress’ are the names of the data properties.

gantt.config.columns =  [
   {name:"text",       label:"Task name",  tree:true, width: 150 },
   {name:"holder",     label:"Holder",     align:"center", width: 80 },
   {name:"start_date", label:"Start time", align:"center", width: 80 },
   {name:"progress",   label:"Progress",   align:"center", width: 80 },
];

Custom columns of the grid in DHTMLX GanttCustom columns in the grid of dhtmlxGantt

But what if you want to format values before displaying them inside cells? In this case, you’ll need to use the ‘template’ property of the column. Here is how our previous example can look like if we use the template in it:

gantt.config.columns =  [
    {name:"text",       label:"Task name",  tree:true, width:"*" },
    {name:"start_date", label:"Start time", align: "center" },
    {name:"staff",      label:"Holder(s)", template:function(obj){
                                return obj.holder+"("+obj.progress")"} }
];

Check a live example >

DHTMLX Gantt templateThe template property in dhtmlxGantt

The template will be called each time the column is repainted and the return value will be put into the inner HTML of the cell. This is an important trait of almost all templates used in the Gantt chart. The content of the templated element is completely replaced after each update. It means that if you modify such DOM element directly from code, all your changes will be lost after the template is called next time.

Therefore, if you need to change the type of the cell line in response to a user action, the best way is not to change styles directly, but to set the necessary styles and markup using the template function.

gantt.config.columns =  [
    {name:"text",       label:"Task name",  tree:true, template(task){
            if(gantt.getState().selected_task == task.id){
                return "<b>" + task.text + "</b>";
            }else{
              return task.text;
            };
        } },
    {name:"start_date", label:"Start time", align: "center" },
    {name:"staff",      label:"Holder(s)", template:function(obj){
            return obj.holder+"("+obj.progress+")"} }
    ];

Check a live example >

Secondly, it’s important to note that templates deal with raw HTML values and don’t sanitize data you return from them in any way. It’s a conscious design decision, which allows you to freely customize most of the Gantt elements. But it has one serious consequence – such templates can serve as entry points for XSS attacks. Let’s consider the next example:

document.addEventListener("DOMContentLoaded", function(event) {
    gantt.config.columns =  [
    {name:"text",       label:"Task name",  tree:true, template(task){
            if(gantt.getState().selected_task == task.id){
                return "<b>" + task.text + "</b>";
            }else{
              return task.text;
            };
        } },
    {name:"start_date", label:"Start time", align: "center" },
    {name:"staff",      label:"Holder(s)", template:function(obj){
            return obj.holder+"("+obj.progress+")"} }
    ];

 gantt.init("gantt_here");
 
  gantt.parse({
    data: [
        {
            id: 1, text: "<img onerror='javascript:alert(\"it can`t be good\")' src='' />", start_date: "01-04-2018", duration: 18,
            progress: 0.4, holder:"Mike", open: true
        },
        {
            id: 2, text: "Task #1", start_date: "02-04-2018", duration: 8,
            progress: 0.6, holder:"John", parent: 1
        },
        {
            id: 3, text: "Task #2", start_date: "11-04-2018", duration: 8,
            progress: 0.6, holder:"Mike", parent: 1
        }
    ],
    links: [
        {id: 1, source: 1, target: 2, type: "1"},
        {id: 2, source: 2, target: 3, type: "0"}
    ]
  });
});

Check a live example >

It’s the same date as before, but this time we’ve added a certain HTML string into the task text. Now, look at what happens when we run the example. The javascript code that we’ve put in the data has been executed on the page. If the backend of a real application returned such data, that code would run in browsers of every user who would open this project. These types of attacks are often used to inject malicious code into an application in order to steal any sensitive data or change the content of your page. It’s a responsibility of a backend developer to ensure that the data feed returns data without unsafe HTML in it. Once you ensure your data source is secure and can be trusted, Gantt templates are perfectly safe.

In addition, to be able to set the Grid configuration, you can also change it dynamically. For example, if you want to give a user an ability to switch between detailed and compact Grid views.

Detailed view of the grid in GanttDetailed view of the grid in Gantt

You can do it simply by assigning a new value to the columns config and repainting Gantt.

document.addEventListener("DOMContentLoaded", function(event) {

    var largeGrid = [
    {name: "text",       label:"Name",  tree:true, width: 200 },
    {name: "start_date", label:"Start", align: "center", width: 70 },
        {name: "end_date",   label:"End", width: 70 },
        {name: "duration",   label:"Duration", width: 70 },
    {name: "staff",      label:"Holder(s)", template:function(obj){
            return obj.holder+"("+obj.progress+")"}, width: 70  },
        {name: "add", width: 44}
    ];
    var largeGridWidth = 550;
   

    var smallGrid = [
    {name: "text",       label:"Task name",  tree:true, width: 200  },
    {name: "start_date", label:"Start time", align: "center", width: 70  },
    {name: "staff",      label:"Holder(s)", template:function(obj){
            return obj.holder+"("+obj.progress+")"}, width: 70  }
    ];
    var smallGridWidth = 340;

    gantt.toggleGrid = function(){
        var newGrid;
        var newGridWidth;
        if(gantt.config.columns == largeGrid){
            newGrid = smallGrid;
            newGridWidth = smallGridWidth
        }else{
            newGrid = largeGrid;
            newGridWidth = largeGridWidth;
        }

        gantt.config.columns = newGrid;
        gantt.config.grid_width = newGridWidth;
        gantt.render();
    };

    gantt.config.columns = smallGrid;
    gantt.config.grid_width = smallGridWidth;
  gantt.init("gantt_here");

Check a live example >

If you’d like to try to configure a grid of the Gantt chart on your own, just follow these steps:

Hope this tutorial will come in useful for you! Don’t hesitate to leave your comments below if you have any questions.

Check other video tutorials by DHTMLX:

The post How to Specify Columns of the Grid in Gantt – DHTMLX Gantt Video Tutorial appeared first on DHTMLX Blog.

Viewing all 208 articles
Browse latest View live