Creating a Jira-inspired table layout in Angular by embedding components in a structured format

I'm attempting to recreate the functionality of Jira where I can create a "gadget" that can be added to a board, resized, moved, and deleted.

(For those unfamiliar with why this might be useful, think of gadgets like the "Gantt" gadget. You can add a gadget to your dashboard to display tasks in a Gantt format, or a deadline tracker, tasks counter, Sprint burn chart, etc.)

After struggling for several days and feeling ready to give up, I am reaching out for assistance.

HTML:

  • It's quite simple - just a list and a slider. When people visit the page, they can click the plus button, which will bring up a slider with a list of items (gadgets) that can be clicked on to insert the gadget.

CSS:

  • Also straightforward, mainly for formatting the slider.

TS:

  • Equally simple, primarily interacting with the slider.

// AngularJS imports and component details are here...
.container {
  /* CSS styles for container */
}

.slider {
  /* Slider styles */
}

.toggle-btn {
  /* Toggle button styles */
}

.slider-list {
  /* List styling for slider items */
}

.slider-item {
  /* Styling for individual slider item */
}

/* Additional CSS code... */

<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.7.0/angular.min.js"></script>
<div class="container">
  <div class="slider" [ngClass]="{'slider-open': sliderOpen}">
    <ul class="slider-list">
      <!-- Slider item markup -->

    </ul>
  </div>
  <button (click)="toggleSlider()" class="toggle-btn">&#43;</button>
</div>

The main goal is as follows:

I aim to add gadgets to the screen similar to Jira's gadgets.

Imagine the screen as a 10x10 matrix. When clicking an item from the slider (like the book item), I want to insert the component into the first empty space in the matrix. Additionally, I should be able to resize it (e.g., from 1x1 to 2x1), move it around, and delete it.

This is why I have included the import statement: "import { ReadingNowTrackerComponent } from './gadgets/ReadingNow Tracker/ReadingNowTracker.component';". My attempts to place this component in the matrix resulted in overflow issues or failure to position correctly.

If you could assist by reviewing my code and helping me achieve the desired outcome, I would greatly appreciate it.

Thank you!

Answer №1

Disclaimer: The following information pertains specifically to the actions of "dragging" and "resizing."

For drag and drop functionality, the CdkDrag Module can be utilized.

The initial step involves using the function cdkDragConstrainPosition. It is important to note that this function may vary between different versions. In the most recent version, you can implement it as follows:

evaluatePosition(pos: {x:number,y:number}, 
                   dragRef: DragRef, 
                   dimensions: DOMRect, 
                   pickupPositionInElement: {x:number,y:number})
  {
    return {x:Math.floor((pos.x-pickupPositionInElement.x) /30)*30,
       y: Math.floor((pos.y-pickupPositionInElement.y) /30)*30}
  }

Subsequently, a CdkDrag element is created in the following manner:

<div class="example-boundary">
  <div #border class="border" [ngStyle]="borderStyle"></div>
  <div
    #gadget
    class="example-box"
    cdkDragBoundary=".example-boundary"
    cdkDrag
    [cdkDragConstrainPosition]="evaluatePosition"
    [ngStyle]="gadgetStyle"
  >
    I can only be dragged within the dotted container
    <div
      #drag
      class="corner"
      cdkDragBoundary=".example-boundary"
      cdkDrag
      [cdkDragConstrainPosition]="evaluatePosition"
      (cdkDragStarted)="dragStarted(gadget,border)"
      (cdkDragEnded)="dragEnded($event,gadget,border,drag)"
      (cdkDragMoved)="dragMove($event,gadget)"
    ></div>
    <div class="indicator"></div>
  </div>
</div>

Key components include:

  1. example-boundary: the designated draggable zone
  2. #gadget: the element eligible for dragging
  3. #drag: the corner used for resizing
  4. #border: a visible border indicating position
  5. indicator: necessary for visual indication

The code also includes:

  borderStyle: any = { visibility: 'hidden' };
  gadgetStyle: any = {};
  rectOrigin: any;
  evaluatePosition(..){...}

  dragStarted(el: HTMLElement, border: HTMLElement) {
    this.rectOrigin = el.getBoundingClientRect();
    this.borderStyle = {
      x: this.rectOrigin.client.x + 'px',
      y: this.rectOrigin.y + 'px',
      width: this.rectOrigin.width + 'px',
      height: this.rectOrigin.height + 'px',
      visibility: 'visible',
      transform: el.style.transform,
    };
  }
  dragEnded(
    event: CdkDragEnd,
    el: HTMLElement,
    border: HTMLElement,
    drag: HTMLElement
  ) {
    this.borderStyle = { visibility: 'hidden' };
    this.gadgetStyle = {
      width: border.clientWidth + 'px',
      height: border.clientHeight + 'px',
    };
    drag.style.transform = 'translate3D(0,0,0)';
  }
  dragMove(event: CdkDragMove, el: HTMLElement) {
    this.borderStyle = {
      x: this.rectOrigin.x + 'px',
      y: this.rectOrigin.y + 'px',
      width: this.rectOrigin.width + event.distance.x + 'px',
      height: this.rectOrigin.height + event.distance.y + 'px',
      visibility: 'visible',
      transform: el.style.transform,
    };
  }

Reference the corresponding stackblitz for further details.

TODO

  1. Develop a component based on the provided code
  2. Utilize
    <ng-container></ng-container>
    instead of plain text
  3. Embed the component within a suitable container

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Discovering the absolute path to @font-face fonts using Firebug

Is it possible to retrieve the absolute URL of a web font specified within an @font-face rule using tools like Firebug? For example: When inspecting the main.css file for a website in Firebug, you may come across this code snippet: @font-face { font ...

Creating a Runescape Tracker: What essentials should I include?

Hello everyone, I am a beginner in the world of programming and I am excited to learn. I have heard that the best way to learn is by working on a project. I have always been interested in creating a Skill Tracker for my clan. Can you offer any advice on wh ...

Comparison of single-line and multi-line CSS styles placement

There seems to be a debate among CSS developers regarding the preference for multi-line or single-line formatting. Some argue that multi-line is favored for its ease in finding specific properties within the CSS file. However, others believe that single- ...

The Angular Material date picker unpredictably updates when a date is manually changed and the tab key is pressed

My component involves the use of the Angular material date picker. However, I have encountered a strange issue with it. When I select a date using the calendar control, everything works fine. But if I manually change the date and then press the tab button, ...

Utilizing Bootstrap, the layout structure consists of 4 columns for desktop, 3 columns for small laptops, 2 columns for tablets, and

I need assistance with setting up responsive columns in my HTML code using Bootstrap. Specifically, I want 4 columns per row on desktop, 3 columns per row on tablet, and 2 columns per row on mobile devices. Despite searching on Stack Overflow, I couldn&apo ...

What is the best way to restrict datalist options while preserving the "value" functionality?

After finding a creative solution by @Olli on Limit total entries displayed by datalist, I successfully managed to restrict the number of suggestions presented by a datalist. The issue arises from the fact that this solution only covers searching through ...

`Angular application having trouble loading Azure Maps`

Hey there! I'm currently working on integrating Azure Maps into a basic Angular application. The error message I encountered is shown below. Any insights on why this might be happening and what steps can be taken to resolve it? atlas.min.js:2509 Err ...

Attach a sticker to the input field

I want to position a label on top of an input tag permanently, rather than having it inside the input tag where it jumps to the top when clicked. Here is my attempted solution: input { font-size: 18px; padding: 10px 10px 10px 5px; -webkit-appeara ...

Align the text in the center of the button vertically

Struggling to vertically center text on a button? I understand the frustration! I've been working on this issue for a whole day with no success. My setup involves NEXT.js and TailwindCSS. <main> <div class='flex justify-center ite ...

Assistance required for posting Jquery files

Attempted to upload a file using jQuery with a hidden form and an Input element, triggering the file browser with jQuery. The changed input is then sent to a PHP server script. Encountered an issue where submitting the form with $("form1").submit(); worke ...

Adaptable Design for Smartphones

Currently in the process of creating a website for my brother with Joomla 3.4 and Bootstrap. This marks my first venture into building a responsive site, so I'm seeking guidance on essential elements to include in my CSS such as font sizes in specific ...

Modifying a group of Components in Angular using a Service

Managing a set of Components involves changing their properties using a Service. The Components have a minimal model and are meant to remain compact. They are being rendered with *ngFor. The Service possesses a large Object and should possess the abilit ...

What are the solutions for addressing popping behavior during hover effects?

Hello everyone, I am experiencing an issue with the image hover effect on my website. How can I make it enlarge smoothly instead of just fading in and out? To better demonstrate, I have provided a helpful example https://i.stack.imgur.com/TcZKy.jpg Any as ...

Using Sweet Alert to enhance the user confirmation experience on your website

I need to replace the standard confirm dialog with a customized one using Sweet Alert. The JavaScript function I want to use is located in the MasterPage. function checkDelete() { swal({ title: "Are you sure?", text: "You will not be able to r ...

The labels in production are getting cut off when creating a view in ASP .NET MVC

Upon viewing a Create View on my PC, I noticed that the main form and labels are adequately spaced: https://i.sstatic.net/1Q2bC.png However, once the website is deployed to IIS and accessed on the same PC with the same browser, everything appears cramped ...

Is your data coming in as NaN?

I am currently developing a basic webpage that has the capability to calculate your stake and determine your return, reminiscent of a traditional betting shop. As of now, I have successfully hard coded the odds into my page. However, while testing my code ...

Enumerate all interdependencies among 2 directories or libraries in an Angular application

I am currently working on a large Angular project and need to refactor some code by identifying dependencies between two specific folders/libs (using nx). Here is an example of the file structure: /apps /lib-1 a.service.ts b.component.t ...

The pseudo right arrow is failing to display in the vertical center

My pseudo right arrow is not displaying vertically centered within the .nav-link class. Can anyone suggest how I can achieve vertical alignment for my right arrow in an <a> tag? I have already attempted using top:50% but it did not work. Here is th ...

Ways to modify the .MuiSelect-nativeInput element within Material-UI

const styles = makeStyles((theme) => ({ root: { margin: "0px 20px" }, textStyle: { fontFamily: "Comfortaa", }, container: {}, textField: { fontFamily: "Comfortaa", }, dropDownFormSize: { width: &qu ...

The Karma testing feature in Angular Quickstart encounters issues right from the start

When attempting to run karma tests after a clean install of the official Angular quickstart on Windows 10, I encountered an issue. Following a series of four commands, here is what happened: C:\projects\temp>git clone https://github.com/angul ...