Navigating the complexities of a business application’s user interface can be daunting, especially when part of it is constructed with hard-coded HTML. If you’ve ever struggled with implementing updates or ensuring consistency in such systems, you’re not alone. Fortunately, there’s a solution that simplifies the process and enables you to build a modern, responsive interface that functions effortlessly on both mobile and desktop devices—even if you’re starting from scratch.
In my experience, dealing with hard-coded HTML views often meant spending an inordinate amount of time making even the smallest changes—a new button here, a layout adjustment there—while grappling with inconsistencies across the application. Enter Placing Containers: a feature available for two years now, designed to streamline this process by allowing you to define a flexbox-based layout directly in the ViewModel. Combined with the Live Edit feature, which shows changes instantaneously without the need for cumbersome compile-and-refresh cycles, this approach has revolutionized the way I structure and manage interfaces. Let me show you how it works!
Setting Up the Environment with Live Edit
Connecting to the Server
First, I set up a local environment that communicates with the cloud-based server. Using a Turnkey Live Editor, I started a local server directly connected to the publicly available MDriven server. Here’s how I set it up:
- Launch the TurnKey Live Editor: I pressed the “TurnKey live editor” button in the designer. This action started the local TurnKey server.
- Establish Cloud Connection: The server connects to the cloud-based MDriven Server where all the data is stored. Although this connection sometimes introduces a slight delay, it was acceptable since only the view was reloaded, not the entire application.
- Syncing View Assets: The Designer user interface provided access to all the view assets. This allowed me to work on several views simultaneously, comparing the legacy design with the new one built using Placing Containers.
The benefit of this setup is the ability to see changes instantly. Any modifications to the ViewModel or the CSS are reflected immediately in the browser, enabling rapid testing and fine-tuning.
Building the New UI with Placing Containers
The Concept
The idea behind Placing Containers is straightforward: instead of coding each element manually, you define regions or containers where data and interactive elements will be placed. This method automatically arranges the UI based on container properties. For instance, when redesigning a page with an edit button that toggles between different states (normal, error, incomplete), Placing Containers handle the layout without needing custom HTML for each state.
Step-by-Step Implementation
- Analyzing the Old Layout:
I started by carefully examining the existing hard-coded HTML interface. This user interface had several issues:- It was inflexible.
- Any modification required rewriting large portions of HTML.
- Dynamic changes were nearly impossible without rewriting multiple sections of code.
- Creating a New ViewModel:
In the Designer, I copied the old ViewModel, which gave me a view that mirrored the legacy interface in data only. My goal was to make the initial version of the new UI identical to the old one so that users would face no learning curve. However, the new view was built using Placing Containers, behind the scenes. - Defining Containers:
I added containers for different sections of the UI:- Header Container: This area contained navigation elements and dynamic icons. I also introduced a style reference for a “Flex basis zero” to control element alignment.
- Main Content Container: This part of the user interface held the primary data fields and action buttons. Using container properties like grow factors, I controlled how much space each element occupied.
- Footer Container: Even the footer was constructed using containers, ensuring that every part of the user interface follows the same design logic.
- Configuring Dynamic Elements:
The new UI needed to handle state changes dynamically—for example, switching between view and edit modes or showing error states. I implemented these dynamic behaviors within the ViewModel so that the designer would automatically update the user interface based on the state.- Edit Mode: For an element like an edit button, I defined two separate states in the ViewModel. One state would show the standard button, and the other would display a “save” option. The container setup allowed both states to exist, but only one was visible at a time.
- Error Indicators: In the case of errors (like a “not complete” state), I used CSS rules to change colors (e.g., from green to red) and even swapped icons dynamically based on the underlying data.
The Role of CSS and the Challenges of Manual Editing
Even though the Placing Containers significantly reduced the need for writing custom HTML, CSS remained integral to refining the visual details—background colors, spacing, button states, and responsive behavior.
The Pain of Manual CSS Editing
Manual CSS editing, while powerful, can be incredibly tedious. Here are some of the challenges I faced:
- Complex Selectors:
The HTML generated by the designer, due to the Placing Containers, often came with long and intricate selectors. It wasn’t enough to simply copy the selector from the browser’s dev tools; these selectors were overly specific and could break if the HTML structure changed even slightly. - Getting the Right Selector:
To handle this, I would inspect the element using the browser’s developer tools. Most modern browsers let you copy the complete CSS selector for an element. However, I found that these selectors were often too detailed. The process then involved manually stripping out unnecessary parts while retaining the essential parts that correctly identified the element.
Working with CSS Selectors
A major part of the work involved refining CSS selectors. Here’s the process I followed:
- Use Developer Tools:
When a style wasn’t being applied as expected, I right-clicked on the element in the browser and selected “Inspect.” This opened the developer tools, where I could view the HTML structure and the computed styles. - Copy and Simplify:
The browser provided a complete CSS selector, but it was often too long. I would copy the selector and then simplify it by removing overly specific parts. The goal was to create a selector that was specific enough to target the element reliably, but not so specific that minor changes in the HTML structure would break it. - Testing and Iteration:
After simplifying the selector, I updated the CSS file and watched the live view for changes. If the style still didn’t apply correctly, I went back to the developer tools, re-examined the element’s structure, and tweaked the selector further. This trial-and-error process, although time-consuming, was essential to get everything right. - Dynamic CSS Expressions:
Some parts of the UI required CSS to change dynamically based on the state of the ViewModel. For example, I used CSS expressions to alter the appearance of buttons when they switched from normal to error states. In one case, I had two buttons representing different states of completion. The ViewModel determined which button was visible, and the CSS ensured that the correct colours and icons were displayed. This method meant that even though the HTML was generated by the designer, I could still control the presentation dynamically through CSS.
Detailed Walkthrough of the Process
Let’s walk through the process, detailing each major part of the transformation.
Step 1: Assessing the Existing User Interface
The original business application had some views UI built entirely with hand-coded HTML. This meant:
- Every element was hard-coded, leaving little room for dynamic changes.
- The design was rigid; any modification required extensive manual updates.
- Maintaining consistency was nearly impossible when the interface spanned many pages and involved multiple dynamic elements.
The first task was to pinpoint which elements needed improvement. I identified areas such as:
- Navigation Buttons: The edit and save buttons toggled between different states.
- Dynamic Fields: Data fields changed appearance based on user interaction or validation status.
- Responsive Elements: Areas needed to adapt to different screen sizes without breaking the layout.
Step 2: Creating a New ViewModel
In the designer, I created a new ViewModel that replicated the existing interface’s look and feel, but with Placing Containers:
- Identical Appearance Initially: I ensured the new UI was structured exactly like the old one – at first. This was important to ensure a smooth transition for users.
- Foundation for Dynamic Behavior: The ViewModel was set up to support dynamic behavior, behind the scenes. This meant that elements could switch states (e.g., edit mode to view mode) without the need to rewrite the entire HTML.
Step 3: Starting the rewrite with Placing Containers
The next step was to replace the hard-coded HTML with Placing Containers. Here’s how I did it:
- Define the Layout Containers:
I set up containers for major sections of the user interface:- Header Container: For the navigation and dynamic icons.
- Content Container: For the main data and interactive elements.
- Footer Container: For any additional controls or status information.
- Configure Container Properties:
I adjusted container properties such as size, spacing, and alignment. For example, using properties like “grow” factors, I controlled how much space each container occupied relative to the others. - Integrate Dynamic Behavior:
I configured the ViewModel so that containers could change their content based on the application’s state. For example, when an admin clicked the edit button, the container would swap the view mode with an edit mode—showing a different set of buttons and fields.
This approach reduced the need to manage dozens of individual HTML elements. Instead, I was working at a higher level, defining how groups of elements behaved and were styled.
Step 4: Activating Live Edit
After setting up the new ViewModel with a rough structure of Placing Containers, I activated the Live Edit feature. Here’s how Live Edit streamlined the process:
- Instant Feedback:
With Live Edit turned on, any changes I made in the ViewModel or CSS were immediately reflected in the browser. This real-time feedback was invaluable in diagnosing issues quickly. - Direct Cloud Sync:
The local TurnKey server I set up communicated directly with the cloud-based service. Although the connection sometimes introduced a minor delay, it ensured that I was always working with the most up-to-date data. - Efficient Debugging:
When I modified container properties or CSS rules, I could instantly see the effect. For instance, changing the height of a container in the CSS immediately updated the UI, allowing me to fine-tune the layout without multiple reloads.
Step 5: Editing CSS for Fine-Tuning
Even with Placing Containers handling the bulk of the layout, CSS was necessary for the fine details. However, editing CSS manually presented its own set of challenges.
Refining CSS Selectors
One of the biggest challenges was ensuring that the correct selectors were used. The steps I followed included:
- Inspect with Developer Tools:
When a style wasn’t applied as expected, I inspected the element using the browser’s dev tools. This allowed me to see the full structure of the generated HTML. - Copying the Selector:
The dev tools provided a full selector, but it was often too detailed. I copied it as a starting point. - Simplifying the Selector:
I then manually trimmed the selector down. For instance, if the original selector was something like.container > div > div > .button span
, I would simplify it to something like.button span
if that still uniquely identified the element. - Iterative Testing:
After updating the selector in the CSS file, I saved the changes and checked the live view. If the style didn’t apply correctly, I went back to the developer tools and refined the selector further.
Handling Dynamic States in CSS
The designer allowed me to create dynamic CSS expressions that changed styles based on the state of the ViewModel. For example:
- Button States:
I configured buttons so that they could switch from a normal state to an error state. The CSS rules changed colors and icons dynamically depending on the data. - Responsive Adjustments:
Using media queries, I ensured that the UI would adjust gracefully on smaller screens. For example, the header might hide on mobile devices, and other elements would reflow to fit the available space.
This dynamic behavior was managed through a combination of ViewModel expressions and CSS rules, which together provided a responsive and interactive user experience.
Overcoming Specific Challenges
Throughout the process, I encountered several technical challenges. Here are a few examples and how I addressed them:
Selector Specificity
- Problem:
The browser’s dev tools often generate overly specific selectors that can break if the HTML structure changes. - Solution:
I learned to simplify these selectors by removing unnecessary parts while ensuring that the selector remained unique. This required a good understanding of the underlying HTML generated by Placing Containers.
Dynamic CSS Rules Not Updating
- Problem:
Sometimes, changes made directly in Visual Studio’s built-in editor did not trigger an immediate update. Modifications in an external editor did. - Solution:
I monitored the live view closely and compared the results of changes made in different editors. This helped me identify when an external editor was more reliable, and I adjusted my workflow accordingly.
Final Thoughts
The shift from a hard-coded HTML interface to using tools like Placing Containers, Live Edit, and dynamic CSS was undoubtedly some work, but it proved immensely rewarding. This new approach not only made the UI more intuitive and easier to maintain, but also revolutionized the workflow. Features like Live Edit, with its instant feedback, turned what used to be a time-consuming process into something far more efficient and enjoyable.
While tackling manual CSS editing was no small feat—especially when fine-tuning selectors—the method of iteratively testing and refining through browser dev tools made a difference. Every obstacle became an opportunity to improve and streamline the UI further, ensuring it met both functional and aesthetic needs.
This experience highlighted the balance between leveraging advanced tools and embracing the hands-on work they still require. By staying patient, flexible, and persistent, you can craft a user interface that is both modern and reliable across devices.
Why wait? Start integrating these techniques into your projects and see their impact on your workflow and results.
Happy modelling!