/*Build smarter, not harder*/
Build faster and more efficiently with reusable structures, seamless front-end integration, and powerful data handling. All within one language, allowing you to focus on what matters most: creating innovative, scalable applications without the hassle of managing multiple technologies.
Try nowDataFlex for you
Streamlined efficiency through advanced data handling
Embrace modular, reusable structures with an object-oriented UI design.
Achieve consistency and seamless integration with the front end.
One language, no need for CSS and JavaScript.
Let the code talk
With DataFlex, less code speaks volumes. Compare yourself...
DataFlex
Use AllWebAppClasses.pkg
Use cPersonDataDictionary.dd
Object oPeople is a cWebView
    Object oPerson_DD is a cPersonDataDictionary
    End_Object
    Set Main_DD to oPerson_DD
    Set Server to oPerson_DD
    Set psCaption to "People"
    Set piMaxWidth to 1024
    Set piColumnCount to 12
    Procedure OnLoad
        Send Clear of oPerson_DD /* Clear the form for input. */
    End_Procedure
    Object oWebMainPanel is a cWebPanel
        Set piColumnCount to 12
        Object oWebGroupPerson is a cWebGroup
            Set piColumnSpan to 6
            Set piColumnCount to 6
            Object oWebFormFirstName is a cWebForm
                Entry_Item Person.firstname
                Set piColumnSpan to 6
                Set psLabel to "First name"
                Set peLabelPosition to lpTop
            End_Object
            
            Object oWebFormLastName is a cWebForm
                Entry_Item Person.lastname
                Set piColumnSpan to 6
                Set psLabel to "Last name"
                Set peLabelPosition to lpTop
            End_Object
            
            Object oWebFormAddress is a cWebForm
                Entry_Item Person.Address
                Set piColumnSpan to 6
                Set psLabel to "Address"
                Set peLabelPosition to lpTop
            End_Object
            
            Object oWebFormPostalCode is a cWebForm
                Entry_Item Person.postalcode
                Set piColumnSpan to 6
                Set psLabel to "Postalcode"
                Set peLabelPosition to lpTop
            End_Object
            
            Object oWebFormCity is a cWebForm
                Entry_Item Person.city
                Set piColumnSpan to 6
                Set psLabel to "City"
                Set peLabelPosition to lpTop
            End_Object
            Object oWebFormCountry is a cWebForm
                Entry_Item Person.country
                Set piColumnSpan to 6
                Set psLabel to "Country"
                Set peLabelPosition to lpTop
            End_Object
            Object oWebButtonSubmit is a cWebButton
                Set piColumnSpan to 2
                Set piColumnIndex to 2
                Set psCaption to "Submit"
            
                Procedure OnClick
                    Boolean bErr
                    Get Request_Validate of oPerson_DD to bErr
                    If (not(bErr)) Begin
                        Send Request_Save of oPerson_DD /* Save the person to the DB if validation was successful. */
                        Send RefreshListFromDD of oWebListPersons /* Refresh the weblist. */
                        Send Clear of oPerson_DD /* Clear the form for input. */
                    End
                End_Procedure
            End_Object
        End_Object
        Object oWebListPersons is a cWebList
            Object oWebColumnFirstName is a cWebColumn
                Entry_Item Person.firstname
                Set psCaption to "First name"
                Set piWidth to 100
            End_Object
            Object oWebColumnLastName is a cWebColumn
                Entry_Item Person.lastname
                Set psCaption to "Last name"
                Set piWidth to 100
            End_Object
            Object oWebColumnAddress is a cWebColumn
                Entry_Item Person.Address
                Set psCaption to "Address"
                Set piWidth to 100
            End_Object
            Object oWebColumnPostalcode is a cWebColumn
                Entry_Item Person.postalcode
                Set psCaption to "Postalcode"
                Set piWidth to 100
            End_Object
            Object oWebColumnCity is a cWebColumn
                Entry_Item Person.city
                Set psCaption to "City"
                Set piWidth to 100
            End_Object
            Object oWebColumnCountry is a cWebColumn
                Entry_Item Person.country
                Set psCaption to "Country"
                Set piWidth to 100
            End_Object
            
        End_Object
    End_Object
End_Object
PHP
// frontend
<h2>Insert a new person</h2>
<form action="submit_person.php" method="post">
    <label for="firstname">First name:</label>
    <input type="text" id="firstname" name="firstname" required><br><br>
    <label for="lastname">Last name:</label>
    <input type="text" id="lastname" name="lastname" required><br><br>
    <label for="address">Address:</label>
    <input type="text" id="address" name="address" required><br><br>
    <label for="postalcode">Postalcode:</label>
    <input type="text" id="postalcode" name="postalcode" required><br><br>
    <label for="city">City:</label>
    <input type="text" id="city" name="city" required><br><br>
    <label for="country">Country:</label>
    <input type="text" id="country" name="country" required><br><br>
    <input type="submit" value="Submit">
</form>
<h2>Saved People</h2>
<?php
// Database configuration
$servername = "localhost";
$username = "root";  // adjust to your database username
$password = "";      // adjust to your database password
$dbname = "phpperson";  // the name of your database
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}
// Select all records from the person table
$sql = "SELECT id, firstname, lastname, address, postalcode, city, country FROM persons";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
    echo "<table border='1'>
            <tr>
                <th>ID</th>
                <th>Name</th>
                <th>Address</th>
                <th>Postal Code</th>
                <th>City</th>
                <th>Country</th>
            </tr>";
    
    // Output data of each row
    $rows = $result->fetch_all(MYSQLI_ASSOC);
    foreach ($rows as $row) {
        $name = sprintf("%s %s", $row['firstname'], $row['lastname']);
        echo "<tr>
                <td>{$row['id']}</td>
                <td>{$name}</td>
                <td>{$row['address']}</td>
                <td>{$row['postalcode']}</td>
                <td>{$row['city']}</td>
                <td>{$row['country']}</td>
              </tr>";
    }
    echo "</table>";
} else {
    echo "No records found.";
}
// Close connection
$conn->close();
?>
// backend
<?php
// Database configuration
$servername = "localhost";
$username = "root";  // adjust to your database username
$password = "";      // adjust to your database password
$dbname = "phpperson";  // the name of your database
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
}
// Get person details from the form
$firstname = $_POST['firstname'];
$lastname = $_POST['lastname'];
$address = $_POST['address'];
$postalcode = $_POST['postalcode'];
$city = $_POST['city'];
$country = $_POST['country'];
// Prepare SQL statement
$sql = "INSERT INTO persons (firstname, lastname, address, postalcode, city, country) VALUES (?, ?, ?, ?, ?, ?)";
$stmt = $conn->prepare($sql);
if ($stmt) {
    // Bind parameters
    $stmt->bind_param("ssssss", $firstname, $lastname, $address, $postalcode, $city, $country);
    // Execute statement
    if ($stmt->execute()) {
        echo "Data successfully saved.";
    } else {
        echo "Error saving data: " . $stmt->error;
    }
    // Close statement
    $stmt->close();
} else {
    echo "Error preparing statement: " . $conn->error;
}
// Close connection
$conn->close();
// Redirect back to the form
header("Location: index.php");
exit;
?>
React
// frontend
import React, { useState, useEffect } from 'react';
import axios from 'axios';
import { Container, Typography, Box, TextField, Button, TableContainer, Table, TableHead, TableRow, TableCell, TableBody, Paper } from '@material-ui/core';
function App() {
  const [nawData, setNawData] = useState([]);
  const [firstname, setFirstname] = useState('');
  const [lastname, setLastname] = useState('');
  const [address, setAddress] = useState('');
  const [postalcode, setPostalcode] = useState('');
  const [city, setCity] = useState('');
  const [country, setCountry] = useState('');
  useEffect(() => {
    axios.get('api/person')
      .then(response => {
        setNawData(response.data);
      })
      .catch(error => {
        console.error('There was an error while trying to get person data:', error);
      });
  }, []);
  const handleSubmit = (e) => {
    e.preventDefault();
    const payload = { firstname, lastname, address, postalcode, city, country };
    axios.post('api/person', payload)
      .then(response => {
        setNawData([...nawData, { id: response.data.id, ...payload }]);
        setFirstname('');
        setLastname('');
        setAddress('');
        setPostalcode('');
        setCity('');
        setCountry('');
      })
      .catch(error => {
        console.error('There was an error trying to save a new person record', error);
      });
  };
  return (
    <Container>
      <Typography variant="h4" gutterBottom>
        Person Details
      </Typography>
      <form onSubmit={handleSubmit}>
        <Box display="flex" flexDirection="row" flexWrap="wrap" mb={2}>
          <Box mr={1}>
            <TextField label="Firstname" value={firstname} onChange={e => setFirstname(e.target.value)} />
          </Box>
          <Box mr={1}>
            <TextField label="Lastname" value={lastname} onChange={e => setLastname(e.target.value)} />
          </Box>
          <Box mr={1}>
            <TextField label="Address" value={address} onChange={e => setAddress(e.target.value)} />
          </Box>
          <Box mr={1}>
            <TextField label="Postalcode" value={postalcode} onChange={e => setPostalcode(e.target.value)} />
          </Box>
          <Box mr={1}>
            <TextField label="City" value={city} onChange={e => setCity(e.target.value)} />
          </Box>
          <Box mr={1}>
            <TextField label="Country" value={country} onChange={e => setCountry(e.target.value)} />
          </Box>
          <Button type="submit" variant="contained" color="primary">
            Save
          </Button>
        </Box>
      </form>
      <TableContainer component={Paper}>
        <Table>
          <TableHead>
            <TableRow>
              <TableCell>Firstname</TableCell>
              <TableCell>Lastname</TableCell>
              <TableCell>Address</TableCell>
              <TableCell>Postalcode</TableCell>
              <TableCell>City</TableCell>
              <TableCell>Country</TableCell>
            </TableRow>
          </TableHead>
          <TableBody>
            {nawData.map(record => (
              <TableRow key={record.id}>
                <TableCell>{record.firstname}</TableCell>
                <TableCell>{record.lastname}</TableCell>
                <TableCell>{record.address}</TableCell>
                <TableCell>{record.postalcode}</TableCell>
                <TableCell>{record.city}</TableCell>
                <TableCell>{record.country}</TableCell>
              </TableRow>
            ))}
          </TableBody>
        </Table>
      </TableContainer>
    </Container>
  );
}
export default App;
// backend
app.get('/api/person', (req, res) => {
  const connection = new Connection(config);
  connection.on('connect', err => {
    if (err) {
      console.error(err);
      res.status(500).send('Database connection failed');
      return;
    }
    const request = new Request('SELECT * FROM Persons', (err, rowCount) => {
      if (err) {
        throw err;
      }
      connection.close();
    });
    let results = []
    request.on('row', (columns) => {
      const record = {};
      columns.forEach(column => {
        record[column.metadata.colName] = column.value;
      });
      results.push(record);
    });
    request.on('doneInProc', (rowCount, more) => {
      console.log(results);
      res.json(results);
      console.log(rowCount + ' rows returned');
    });
    connection.execSql(request);
  });
  connection.connect();
});
app.post('/api/person', (req, res) => {
  const { firstname, lastname, address, postalcode, city, country } = req.body;
  const connection = new Connection(config);
  connection.on('connect', err => {
    if (err) {
      console.error(err);
      res.status(500).send('Database connection failed');
      return;
    }
    const request = new Request(
      `INSERT INTO Persons (firstname, lastname, address, postalcode, city, country)
      OUTPUT INSERTED.id
       VALUES (@firstname, @lastname, @address, @postalcode, @city, @country)`,
      (err, rowCount, rows) => {
        if (err) {
          console.error(err);
          res.status(500).send('Failed to insert data');
        } else {
          res.status(201);
        }
        connection.close();
      }
    );
    request.addParameter('firstname', TYPES.NVarChar, firstname);
    request.addParameter('lastname', TYPES.NVarChar, lastname);
    request.addParameter('address', TYPES.NVarChar, address);
    request.addParameter('postalcode', TYPES.NVarChar, postalcode);
    request.addParameter('city', TYPES.NVarChar, city);
    request.addParameter('country', TYPES.NVarChar, country);
    let results = []
    request.on('row', (columns) => {
      const record = {};
      columns.forEach(column => {
        record[column.metadata.colName] = column.value;
      });
      results.push(record);
    });
    request.on('doneInProc', (rowCount, more) => {
      res.json(results);
    });
    connection.execSql(request);
  });
  connection.connect();
});
The Essence of DataFlex
DataFlex is an all-in-one solution that combines Studio, Framework,
Language, and Data, streamlining your development process.
DataFlex Studio is the IDE for DataFlex programming. Streamline your coding experience with an intuitive environment.
The Framework simplifies application design, complemented by an extensive collection of web controls and libraries.
Rooted in an object-oriented approach, DataFlex emphasizes readability, making it a user-friendly language for developers.
Simplify and ensure consistency by setting up data in Business Rules and Data Dictionaries once.
How to get started
What's new in DataFlex
We consistently innovate DataFlex versions, delivering multiple releases annually. Explore the latest features in the newest DataFlex Release!
Go to What's New PageGet applications built in a snap using the Navigation Designer. This new panel in the Studio helps you develop drill-down applications by visualizing the navigation paths between views and widgets in your app. Easily generate new views by dropping them from the palette onto the designer, configure navigations through the Properties panel, and customize default settings for the Navigation Designer that best fit your development needs.
Not sure which layout is best for your end-users? Let them decide! Developers may now create dynamic dashboards in DataFlex WebApps or Windows applications using FlexTron® that end-users can customize themselves. The Studios WebApp Designer can model widgets, and templates are available for the dashboard and widgets.
Empower your coding by taking advantage of the new Composite class, a new object-oriented class type that allows for creating compositions of multiple objects to make developing in DataFlex easier and more flexible. Composite combines the nesting syntax of objects with reusability of classes, all fully supported in the Studio.
Why millions use DataFlex
 
          
          
          DataFlex empowers programmers to be more and do more. They are not only coders, they are also business analysts and process architects. They are actively involved in the concepts of analytics and conceptualization. - Christian Hartlieb, CEO, Somentec Software GmbH
 
          
          "Data Access Worldwide helps us to grow new solutions for our customers. In the last few years, that collaboration has expanded to include two major new functionalities" - Bas Mathon, Managing Director, Quantaris
 
          
          We used DataFlex because it enabled rapid development and because the database was reliable. While our competitors kept falling, we just kept evolving maintaining a lead in our niche markets. - Alex Heffer, Product Manager, XLS
