CursosEmpresasBlogLiveConfPrecios

Drag and drop con columnas dinámicas

Clase 14 de 24 • Curso de Maquetación con Angular CDK y Tailwind CSS

Clase anteriorSiguiente clase

Contenido del curso

Introducción

  • 1
    ¿Qué es el Angular CDK?

    ¿Qué es el Angular CDK?

    05:55 min
  • 2
    Instalando Angular CDK y TailwindCSS

    Instalando Angular CDK y TailwindCSS

    12:37 min

Maquetando con Tailwind

  • 3
    Maquetando la página de login con Tailwind

    Maquetando la página de login con Tailwind

    14:40 min
  • 4
    Maquetando formularios con Tailwind

    Maquetando formularios con Tailwind

    09:23 min
  • 5
    Componente de botón reutilizable

    Componente de botón reutilizable

    15:53 min
  • 6
    Reto: colores y propiedades dinámicas

    Reto: colores y propiedades dinámicas

    11:29 min

Componentes interactivos con Angular CDK

  • 7
    Creando Overlays

    Creando Overlays

    16:38 min
  • 8
    Múltiples Overlays

    Múltiples Overlays

    05:44 min
  • 9
    Iconos en Angular con Font Awesome

    Iconos en Angular con Font Awesome

    13:38 min
  • 10
    Creando acordeones

    Creando acordeones

    11:53 min
  • 11
    Acordeones dinámicos

    Acordeones dinámicos

    08:49 min

Drag and drop

  • 12
    Drag and drop con ordenamiento

    Drag and drop con ordenamiento

    17:06 min
  • 13
    Drag and drop con transferencia entre columnas

    Drag and drop con transferencia entre columnas

    14:07 min
  • 14
    Drag and drop con columnas dinámicas

    Drag and drop con columnas dinámicas

    Viendo ahora

Modales y listas

  • 15
    Modales y diálogos

    Modales y diálogos

    16:21 min
  • 16
    Modales recibiendo información

    Modales recibiendo información

    13:04 min
  • 17
    Listas con scroll

    Listas con scroll

    12:04 min
  • 18
    Listas con virtual scrolling

    Listas con virtual scrolling

    05:14 min

Table CDK

  • 19
    Tablas

    Tablas

    14:33 min
  • 20
    Estilos en Tablas

    Estilos en Tablas

    13:25 min
  • 21
    Usando un DataSource en Tablas

    Usando un DataSource en Tablas

    14:39 min
  • 22
    Tablas con filtros y debounce

    Tablas con filtros y debounce

    09:02 min

Próximos pasos para completar el Clon de Trello

  • 23
    Mejoras en UX y reusabilidad

    Mejoras en UX y reusabilidad

    13:19 min
  • 24
    Toma el Curso de Autenticación con Angular

    Toma el Curso de Autenticación con Angular

    01:38 min
  • Tomar el examen del curso
    • Cristian Danilo Motta Herrera

      Cristian Danilo Motta Herrera

      student•
      hace 3 años

      ¿no se le puede dar like a un video?

      ¡ este curso está genial !

        Jose Armando Acevedo Angarita

        Jose Armando Acevedo Angarita

        student•
        hace 3 años

        Lo puedes hacer cuando termines el curso

      Ángel David Roque Ayala

      Ángel David Roque Ayala

      student•
      hace 3 años

      Customizar el scroll bar

      En el archivo styles.scss

      /* Agrega estilos personalizados para la barra de desplazamiento */ ::-webkit-scrollbar { width: 8px; height: 8px; } ::-webkit-scrollbar-thumb { background-color: rgba(156, 163, 175, var(--tw-bg-opacity)); border-radius: 4px; } ::-webkit-scrollbar-track { background-color: rgba(229, 231, 235, var(--tw-bg-opacity)); border-radius: 4px; } /* Agrega un efecto hover a la barra de desplazamiento */ ::-webkit-scrollbar-thumb:hover { background-color: rgba(107, 114, 128, var(--tw-bg-opacity)); }
      Camilo Alexander Arias Guerrero

      Camilo Alexander Arias Guerrero

      student•
      hace 3 años

      si quieren mover las listas pueden utilizar cdkDropListOrientation https://material.angular.io/cdk/drag-drop/overview#list-orientation.

        Marco Astudillo

        Marco Astudillo

        student•
        hace 3 años

        Mi solución por si a alguien se le dificulta.

        <div class="flex grow overflow-x-scroll h-full" cdkDropList cdkDropListOrientation="horizontal" (cdkDropListDropped)="dropHorizontal($event)" > <div class="flex items-start w-full" cdkDropListGroup> <div cdkDrag class="rounded bg-gray-200 w-72 p-2 mr-3 shrink-0" *ngFor="let colum of columns" >
        Alexis Duque

        Alexis Duque

        student•
        hace 3 años

        Faltaba el código.

        dropHorizontal (event: CdkDragDrop<Column[]>) { moveItemInArray(this.columns, event.previousIndex, event.currentIndex); }
      Pablo Torres Pérez

      Pablo Torres Pérez

      student•
      hace 3 años

      Les comparto como va mi solución del reto hasta el momento.

      Clase14_reto.jpg
      Acepto retroalimentación https://imgur.com/gallery/u520LTl
        Darwin Rodríguez

        Darwin Rodríguez

        student•
        hace 3 años

        Hola, cómo lo resolviste?

        Yo coloqué la directiva cdkDrap y en un nivel más arriba coloqué las otras directivas pero se rompe la estructura

        Pablo Torres Pérez

        Pablo Torres Pérez

        student•
        hace 3 años

        Hola, acabo de ver el comentario, jeje. Espero ya lo hayas resuelto. Si no, te cuento como lo resolví. Además del 'cdkDrag' que comentas en el div donde colocamos el *ngFor para las columnas, agregué un 'cdkDropList' al div padre donde colocamos 'cdkDropListGroup'. Finalmente, en ese mismo div, coloqué cdkDropListOrientation="horizontal" (cdkDropListDropped)="dropColumn($event)" Quedando así

        <div cdkDropListGroup cdkDropList cdkDropListOrientation="horizontal" (cdkDropListDropped)="dropColumn($event)" [cdkDropListData]="this.columns" class="example-list overflow-hidden" class="flex items-start w-full h-full overflow-x-scroll scrollbar-thumb-rounded-full scrollbar-track-rounded-full scrollbar scrollbar-thumb-blue-200 scrollbar-track-blue-400" > <div class="rounded bg-gray-200 w-72 p-2 mr-3 shrink-0" *ngFor="let column of columns; let i=index;" (click)="getIndex(i)" cdkDrag > <div class="example-box flex flex-row cursor-move flex-grow" class="flex justify-between py-1" > <h3 class="text-sm font-bold ml-2">{{ column.title }}</h4> <button class="flex" aria-expanded="false" type="button" cdkOverlayOrigin #trigger="cdkOverlayOrigin" (click)="toggle(trigger)" > <fa-icon [icon]="faEllipsisH"></fa-icon> </button> </div> <div class="text-sm mt-2 min-h-[2.5rem]" cdkDropList (cdkDropListDropped)="drop($event)" [cdkDropListData]="column.todos" > <div (click)="openDialog(todo)" *ngFor="let todo of column.todos" cdkDrag class="bg-white shadow p-2 rounded mt-2 border-b border-x-gray-300 cursor-pointer hover:bg-gray-400" > {{ todo.title }} </div> <button (click)="addNewTask = !addNewTask"> <fa-icon [icon]="faPlus">Añade una tarjeta</fa-icon> </button> <input class="w-full" type="text" placeholder="Introduzca un título para esta tarjeta" [formControl]="list" *ngIf="addNewTask && ni === i" /> <!-- {{ ni == i }} --> <button class="w-4/12 mt-2 bg-sky-500 rounded-sm text-white" *ngIf="addNewTask && ni === i" (click)="addTask(column.todos)" > Agregar </button> </div> </div> <button (click)="addColumn()" class="bg-white rounded p-1 font-bold w-72 shrink-0" > + Columna </button> </div>

        Y en el ts muy similar a lo visto en clase (por no decir que igual, jeje). Solo me falta trabajar un poco en el tipado del CdkDragDrop<any[]>

        dropColumn(event: CdkDragDrop<any[]>) { console.log(event); if (event.previousContainer === event.container) { moveItemInArray(this.columns, event.previousIndex, event.currentIndex); } else { transferArrayItem( event.previousContainer.data, event.container.data, event.previousIndex, event.currentIndex ) } }
      Emilia Margarethe Ericksson

      Emilia Margarethe Ericksson

      student•
      hace 2 años

      comparto un poco de mi avance :)

      practice.png

      José Nicolás Aristizabal Ramírez

      José Nicolás Aristizabal Ramírez

      student•
      hace 3 años

      Así vamos ... excelente curso.

      Captura de pantalla 2023-03-31 a la(s) 3.38.49 p.m..png

      Diego Inostroza

      Diego Inostroza

      student•
      hace 2 años

      Si están usando la sintaxis de angular 17:

      <div class="flex flex-col h-screen"> <app-nav-bar></app-nav-bar> <div class="w-full grow bg-sky-600 px-4 pb-4"> <div class="flex flex-col h-full"> <div> <h2 class="text-xl font-bold text-white my-4">Demo Board</h3> </div> <div class="flex grow items-start w-full h-full overflow-x-scroll" cdkDropListGroup> @for (column of columns; track column) { <div class="rounded bg-gray-200 w-72 p-2 mr-3 shrink-0"> <h3 class="text-sm font-bold ml-2"> {{column.title}} </h4> <div class="text-sm mt-2 min-h-[2.5rem]" cdkDropList (cdkDropListDropped)="drop($event)" [cdkDropListData]="column.tasks"> @for (task of column.tasks; track task.id) { <div (click)="openDialog()" cdkDrag class="bg-white shadow p-2 rounded mt-2 border-b border-x-gray-300 cursor-pointer hover:bg-gray-400"> {{ task.title }} </div> } </div> </div> } <button (click)="addColumn()">Add Column</button> </div> </div> </div> </div>
      David Matias Casco Lobos

      David Matias Casco Lobos

      student•
      hace 3 años

      Me está gustando mucho el curso

      Diego Lozano

      Diego Lozano

      student•
      hace 3 años

      Para conectar Overlays a elementos dinámicos pueden hacer lo siguiente: Declarar el trigger en .TS:

      triggerOrigin: any;

      Ese será la entrada de la propiedad 'cdkConnectedOverlayOrigin'

      <ng-template cdkConnectedOverlay [cdkConnectedOverlayOrigin]="triggerOrigin"

      Luego crean un método Toggle:

      toggle(trigger: any) { this.triggerOrigin = trigger; this.isOpen = !this.isOpen }

      Luego tomamos el Toggle como parámetro pasándolo al template:

      <button class="btn btn-primary" cdkOverlayOrigin #trigger="cdkOverlayOrigin" (click)="toggle(trigger)">Open overlay</button> ... <div style="margin-top:100px"> <button *ngFor="let btn of btns" cdkOverlayOrigin #trigger="cdkOverlayOrigin" (click)="toggle(trigger)">{{btn}}</button> </div>

      Y listo, ya tendrían su Overlay en elementos dinámicos.

      Ángel David Roque Ayala

      Ángel David Roque Ayala

      student•
      hace 3 años

      Tenia problemas para agregar la directiva [cdkDropListConnectedTo] de forma dinamica, asi que lo solucione de la siguiente forma:

      Ts:

      Agregue una nueva propiedad a la interfaz

      export interface Column { id: string; title: string; todos: ToDo[]; }

      y una vez agregado un id a cada columna agrege un getter para obtener la lista de los ids:

      get columnsIds() { return this.columns.map(column => column.id); }

      Y finalmente agregue cada id a cada elemento del dom y la directiva cdkDropListConnectedTo:

      <div class="text-sm mt-2 min-h-[2.5rem]" cdkDropList (cdkDropListDropped)="drop($event)" [cdkDropListData]="column.todos" [id]="column.id" [cdkDropListConnectedTo]="columnsIds" >
        Alberto Cruz

        Alberto Cruz

        student•
        hace 3 años

        Excelente! Gracias por el aporte

      Max Andy Diaz Neyra

      Max Andy Diaz Neyra

      student•
      hace 7 meses

      Mi solucion para el desafio de mover las columnas en Angular 19:

      import { Component, signal } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { CdkDragDrop, CdkDrag, CdkDropList, moveItemInArray, CdkDropListGroup, transferArrayItem, } from '@angular/cdk/drag-drop'; import { NavbarComponent } from '../../components/navbar/navbar.component'; import { Column, Todo } from '../../models/todo.model'; @Component({ selector: 'app-board', imports: [ CdkDrag, CdkDropList, CdkDropListGroup, NavbarComponent, FormsModule, ], templateUrl: './board.component.html', styles: [ ` /* Animate items as they're being sorted. */ .cdk-drop-list-dragging .cdk-drag { transition: transform 250ms cubic-bezier(0, 0, 0.2, 1); } /* Animate an item that has been dropped. */ .cdk-drag-animating { transition: transform 300ms cubic-bezier(0, 0, 0.2, 1); } `, ], }) export class BoardComponent { newColumnName = signal(''); newTodoName = signal(''); isOpenFormColumn = signal(false); columns = signal<Column[]>([ { title: 'To Do', todos: [ { id: '1', title: 'Make dishes', }, { id: '2', title: 'Buy a unicorn', }, ], }, { title: 'Doing', todos: [ { id: '3', title: 'Watch Angular Path in Platzi', }, ], }, { title: 'Done', todos: [ { id: '4', title: 'Play video games', }, ], }, ]); drop(event: CdkDragDrop<Todo[]>) { transferArrayItem( event.previousContainer.data, event.container.data, event.previousIndex, event.currentIndex, ); // moveItemInArray(this.todos, event.previousIndex, event.currentIndex); } dropHorizontal(event: CdkDragDrop<Column[]>) { moveItemInArray(this.columns(), event.previousIndex, event.currentIndex); } addColumn() { this.columns.update((prev) => [ ...prev, { title: this.newColumnName(), todos: [], }, ]); this.newColumnName.set(''); } openFormColum() { this.isOpenFormColumn.set(true); } closeFormColum() { this.isOpenFormColumn.set(false); } addTodo(title: string) { const index = this.columns().findIndex((column) => column.title === title); this.columns.update((prev) => { const newTodos: Todo[] = [ ...prev[index].todos, { id: Math.random().toString(), title: this.newTodoName(), }, ]; prev[index].todos = newTodos; return prev; }); this.newTodoName.set(''); this.closeFormTodo(title); } openFormTodo(title: string) { this.columns.update((prev) => prev.map((column) => { if (column.title === title) { column.isOpemFormCard = true; return column; } return column; }), ); } closeFormTodo(title: string) { this.columns.update((prev) => prev.map((column) => { if (column.title === title) { column.isOpemFormCard = false; return column; } return column; }), ); } }
        Max Andy Diaz Neyra

        Max Andy Diaz Neyra

        student•
        hace 7 meses

        Aqui les dejo mi model:

        export interface Todo { id: string; title: string; } export interface Column { title: string; todos: Todo[]; isOpemFormCard?: boolean; }
        Max Andy Diaz Neyra

        Max Andy Diaz Neyra

        student•
        hace 7 meses

        Mi HTML:

        <div class="flex flex-col h-screen"> <app-navbar></app-navbar> <div class="w-full grow bg-sky-600 px-4 pb-4"> <div class="flex flex-col h-full"> <div> <h2 class="text-xl font-bold text-white my-4">Demo Board</h3> </div> <div class="flex grow items-start w-full h-full overflow-x-scroll" cdkDropListGroup cdkDropList (cdkDropListDropped)="dropHorizontal($event)" [cdkDropListData]="columns()" cdkDropListOrientation="horizontal" > @for (column of columns(); track column.title) { <div class="rounded bg-gray-200 w-72 p-2 mr-3 shrink-0" cdkDrag> <div class="flex justify-between py-1"> <h3 class="text-sm font-bold ml-2">{{ column.title }}</h4> </div> <div class="text-sm py-2" cdkDropList (cdkDropListDropped)="drop($event)" [cdkDropListData]="column.todos" > @for (todo of column.todos; track todo.id) { <div cdkDrag class="bg-white shadow p-2 rounded mt-2 border-b border-x-gray-300 cursor-pointer hover:bg-gray-400" > {{ todo.title }} </div> } </div> @if (column.isOpemFormCard) { <div class="flex flex-col bg-gray-200 py-1 shrink-0 rounded-lg space-y-2" > <input type="text" class="rounded-lg" placeholder="New todo name" [(ngModel)]="newTodoName" /> <div> <button (click)="addTodo(column.title)" class="px-2 py-1 text-gray-800 bg-sky-600 rounded-lg" > + Add card </button> <button (click)="closeFormTodo(column.title)" class="px-2 py-1 text-gray-500" > x </button> </div> </div> } @else { <button (click)="openFormTodo(column.title)" class="px-2 py-1 text-gray-500" > + Add a card </button> } </div> } @if (isOpenFormColumn()) { <div class="flex flex-col w-72 px-1 bg-gray-200 py-1 shrink-0 mr-3 rounded-lg space-y-2" > <input type="text" class="rounded-lg" placeholder="New column name" [(ngModel)]="newColumnName" /> <div> <button (click)="addColumn()" class="px-2 py-1 text-gray-800 bg-sky-600 rounded-lg" > + Add column </button> <button (click)="closeFormColum()" class="px-2 py-1 text-gray-500" > x </button> </div> </div> } @else { <button class="bg-gray-200 py-2 px-5 w-72 rounded-lg bg-opacity-45 shrink-0 text-left outline-none mr-3" (click)="openFormColum()" > + Add column </button> } </div> </div> </div> </div>
      Wilberk Ledezma

      Wilberk Ledezma

      student•
      hace un año

      Nicobytes, es uno de los mejores profesores en esta plataforma.

      Adrian Lima

      Adrian Lima

      student•
      hace 2 años

      Para los que esten usando Angular 17 con signals, asi fue como logre arrastrar las columnas entre si:

      En el HTML coloqué los siguientes atributos:

      • cdkDropList
      • cdkDropListOrientation
      • cdkDropListDropped
      • cdkDropListData

      No hay que olvidarnos que como nuestro "columns" es un signal, tenemos que subscribirnos a el "[cdkDropListData]="columns()""

      Y en el div de cada columna es decir la que tiene la clase "rounded" coloqué el "cdkDrag"

      <div class="flex grow items-start w-full h-full overflow-x-scroll" cdkDropListGroup cdkDropList cdkDropListOrientation="horizontal" (cdkDropListDropped)="dropColumns($event)" [cdkDropListData]="columns" > @for (column of columns(); track column) { <div class="rounded bg-gray-200 w-72 p-2 mr-3 shrink-0" cdkDrag> <div class="flex justify-between py-1"> <h3 class="text-sm font-bold ml-2">{{ column.title }}</h4> </div> ```Por ultimo en el TypeScript simplemente cree la función dropColumns que mueve los arrays dentro de las columnas: ```js dropColumns(event: CdkDragDrop<Column[]>) { moveItemInArray(event.container.data, event.previousIndex, event.currentIndex); } ```Recuerda que"columns" debe de ser un signal: ```ts columns = signal<Column[]>([]); addColumn() { this.columns.update((columns) => [...columns, {title: 'New Column', todos: []}]) } ```Gracias :)
      Elioenai Garcia

      Elioenai Garcia

      student•
      hace 2 años

      Para resolver el reto de Drag&Drop horizontal, se pueden apoyar de la siguiente documentación, realmente no es muy complicado. Saludos 😉

      https://material.angular.io/cdk/drag-drop/overview#cdk-drag-drop-horizontal-sorting
      Emilio Nicolás Mendoza Patti

      Emilio Nicolás Mendoza Patti

      student•
      hace 2 años

      Va quedando bien, lo que sigue es hacer las funcionalidades de Add card, rename list, delete list

      trello-clon.png
      Adrian Silva

      Adrian Silva

      student•
      hace 2 años

      Mi solución a los retos: Para el scroll cree un component.scss:

      /* Estilos para navegadores webkit */ /* Cambiar el color del pulgar y de la pista del scroll */ ::-webkit-scrollbar-track { background-color: rgba(0, 0, 0, 0.11); border-radius: 10px; } ::-webkit-scrollbar { width: 8px; background-color: gray; border-radius: 10px; } ::-webkit-scrollbar-thumb { background-color: rgba(255, 255, 255, 0.432); border-radius: 10px; }

      Para el input: En component.ts:

      newTitle = new FormControl(''); isAddingCol = false; addColumn(){ if (this.isAddingCol === false){ this.isAddingCol = true; // para el focus del input, se le asigna una vez ya este en pantalla setTimeout(() => { document.getElementById('newTitle')?.focus(); }, 10); }else{ this.columns.push({ title: this.newTitle.value!, todos: [], }) this.isAddingCol = false; this.newTitle.setValue(""); } }
      LUIS ANTONIO CALVO QUISPE

      LUIS ANTONIO CALVO QUISPE

      student•
      hace 3 años

      Reto Cumplido!

      Reto.png

      En las respuestas les pasare el código …, si pueden mejorar algo, me gustaría que lo comentaran

        LUIS ANTONIO CALVO QUISPE

        LUIS ANTONIO CALVO QUISPE

        student•
        hace 3 años

        html

        <div class="flex flex-col h-screen"> <app-navbar></app-navbar> <div class="w-full grow bg-sky-600 px-4 pb-4"> <div class="flex flex-col h-full"> <div> <h2 class="text-xl font-bold text-white my-4">Demo Board</h3> </div> <div class="flex grow overflow-x-scroll h-full" cdkDropList cdkDropListOrientation="horizontal" (cdkDropListDropped)="dropHorizontal($event)"> <div class="flex grow items-start w-full h-full overflow-x-scroll" cdkDropListGroup> <div class="rounded bg-gray-200 w-72 p-2 mr-3 shrink-0" *ngFor="let column of columns" cdkDrag> <div class="flex justify-between py-1 pr-2"> <h3 class="text-sm font-bold ml-2">{{ column.title }}</h4> <button type="button" (click)="column.isOpenList = !column.isOpenList" cdkOverlayOrigin #overlayList="cdkOverlayOrigin"> <fa-icon [icon]="faEllipsis"></fa-icon> </button> <ng-template cdkConnectedOverlay [cdkConnectedOverlayOrigin]="overlayList" [cdkConnectedOverlayOpen]="column.isOpenList"> <div class="divide-y bg-white w-72 p-2 space-y-2"> <div class="flex justify-center relative"> <p>List Actions</p> <button class="absolute right-0 mr-2" (click)="column.isOpenList = !column.isOpenList"> <fa-icon class="w-full" [icon]="faXmark"></fa-icon> </button> </div> <div class="text-slate-700"> <p class="p-2">Add card...</p> <p class="p-2">Copy list...</p> <p class="p-2">Move list...</p> <p class="p-2">Watch</p> </div> <div class="text-slate-700"> <p class="p-2">Sort by...</p> </div> </div> </ng-template> </div> <div class="text-sm mt-2 min-h-[2.5rem]" cdkDropList (cdkDropListDropped)="onDrop($event)" [cdkDropListData]="column.todos"> <div *ngFor="let todo of column.todos" cdkDrag class="bg-white shadow p-2 rounded mt-2 border-b border-x-gray-300 cursor-pointer hover:bg-gray-400"> {{ todo.title }} </div> </div> <cdk-accordion> <cdk-accordion-item #accordionAdd="cdkAccordionItem"> <button class="w-full pt-3 pb-2 px-2 font-semibold text-slate-500 text-sm flex justify-between" type="button" [style.display]="accordionAdd.expanded ? 'none' : ''" (click)="accordionAdd.toggle()"> + Add a card <fa-icon [icon]="faImages"></fa-icon> </button> <div [style.display]="accordionAdd.expanded ? '' : 'none'"> <input class="w-full min-h-[5.0rem] p-2 mt-2 bg-white rounded border-b border-x-gray-300" placeholder="Enter a title for this card ..." [(ngModel)]="isNameTodo"/> <div class="flex items-center justify-between mt-2"> <div class="flex space-x-4"> <app-btn [colorBtn]="'sky'" (click)="addTodo(column.title)" (click)="accordionAdd.toggle()">Add card</app-btn> <button (click)="accordionAdd.toggle()"> <fa-icon class="w-full" [icon]="faXmark"></fa-icon> </button> </div> <fa-icon class="mr-2" [icon]="faEllipsis"></fa-icon> </div> </div> </cdk-accordion-item> </cdk-accordion> </div> <cdk-accordion> <cdk-accordion-item #accordionAddColumn="cdkAccordionItem"> <button class="rounded bg-gray-200 w-72 p-2 mr-3 shrink-0 text-sm font-bold text-left" type="button" (click)="accordionAddColumn.toggle()" [style.display]="accordionAddColumn.expanded ? 'none' : ''"> + Add Column </button> <div class="rounded bg-gray-200 w-72 p-2 mr-3 shrink-0" [style.display]="accordionAddColumn.expanded ? '' : 'none'"> <input class="w-full min-h-[5.0rem] p-2 mt-2 bg-white rounded border-b border-x-gray-300" placeholder="Enter a title for this column ..." [(ngModel)]="isNameColumn"/> <div class="flex items-center justify-between mt-2"> <div class="flex space-x-4"> <app-btn [colorBtn]="'sky'" (click)="addColumn()" (click)="accordionAddColumn.toggle()">Add column</app-btn> <button (click)="accordionAddColumn.toggle()"> <fa-icon class="w-full" [icon]="faXmark"></fa-icon> </button> </div> <fa-icon class="mr-2" [icon]="faEllipsis"></fa-icon> </div> </div> </cdk-accordion-item> </cdk-accordion> </div> </div> </div> </div> </div>
        LUIS ANTONIO CALVO QUISPE

        LUIS ANTONIO CALVO QUISPE

        student•
        hace 3 años

        Ts

        import { Component } from '@angular/core'; import { faImages } from '@fortawesome/free-regular-svg-icons'; import { faEllipsis,faXmark } from '@fortawesome/free-solid-svg-icons'; import { CdkDragDrop, moveItemInArray, transferArrayItem } from '@angular/cdk/drag-drop'; import { Todo } from 'src/app/model/Todo.model'; import { Column } from 'src/app/model/Column.model'; @Component({ selector: 'app-board', templateUrl: './board.component.html', styleUrls: ['./board.component.scss'] }) export class BoardComponent { faImages = faImages; faEllipsis = faEllipsis; faXmark = faXmark; // Auxiliar isOpenList = false; isNameTodo = ''; isNameColumn = ''; columns: Column[] = [ { title: 'Todo', isOpenList: false, todos: [ { id:'1', title:'Task 1' }, { id:'2', title:'Task 2' }, { id:'3', title:'Task 3' } ] }, { title: 'Doing', isOpenList: false, todos: [ { id:'4', title:'Task 4' }, { id:'5', title:'Task 5' }, { id:'6', title:'Task 6' } ] }, { title: 'Done', isOpenList: false, todos: [ { id:'7', title:'Task 7' }, { id:'8', title:'Task 8' }, { id:'9', title:'Task 9' } ] } ] onDrop(event: CdkDragDrop<any[]>){ if (event.previousContainer === event.container) { moveItemInArray(event.container.data, event.previousIndex, event.currentIndex) } else { transferArrayItem( event.previousContainer.data, event.container.data, event.previousIndex, event.currentIndex ) } } addColumn(){ this.columns.push({ title: this.isNameColumn, isOpenList: false, todos: [] }) } addTodo(columnCurrent: string){ // Obtener el índice de la columna "Doing" const todoIndex = this.columns.findIndex(column => column.title === columnCurrent); let lastTodoId = '0'; // Inicializar el ID en '0' // Obtener el último ID dentro del arreglo de todos de la columna del todo, si es hay items if (this.columns[todoIndex].todos.length > 0) { lastTodoId = this.columns[todoIndex].todos[this.columns[todoIndex].todos.length - 1].id; } // Convertir el último ID en un número entero y sumarle 1 const newId = parseInt(lastTodoId) + 1; // Crear un nuevo todo con el ID dinámico y el título ingresado const newTodo = { id: newId.toString(), title: this.isNameTodo }; // Agregar el nuevo todo al arreglo de todos de la columna "Doing" console.log(newTodo); this.columns[todoIndex].todos.push(newTodo); this.isNameTodo = ''; } dropHorizontal (event: CdkDragDrop<any[]>) { console.log('weii') moveItemInArray(this.columns, event.previousIndex, event.currentIndex); } }

    Escuelas

    • Desarrollo Web
      • Fundamentos del Desarrollo Web Profesional
      • Diseño y Desarrollo Frontend
      • Desarrollo Frontend con JavaScript
      • Desarrollo Frontend con Vue.js
      • Desarrollo Frontend con Angular
      • Desarrollo Frontend con React.js
      • Desarrollo Backend con Node.js
      • Desarrollo Backend con Python
      • Desarrollo Backend con Java
      • Desarrollo Backend con PHP
      • Desarrollo Backend con Ruby
      • Bases de Datos para Web
      • Seguridad Web & API
      • Testing Automatizado y QA para Web
      • Arquitecturas Web Modernas y Escalabilidad
      • DevOps y Cloud para Desarrolladores Web
    • English Academy
      • Inglés Básico A1
      • Inglés Básico A2
      • Inglés Intermedio B1
      • Inglés Intermedio Alto B2
      • Inglés Avanzado C1
      • Inglés para Propósitos Específicos
      • Inglés de Negocios
    • Marketing Digital
      • Fundamentos de Marketing Digital
      • Marketing de Contenidos y Redacción Persuasiva
      • SEO y Posicionamiento Web
      • Social Media Marketing y Community Management
      • Publicidad Digital y Paid Media
      • Analítica Digital y Optimización (CRO)
      • Estrategia de Marketing y Growth
      • Marketing de Marca y Comunicación Estratégica
      • Marketing para E-commerce
      • Marketing B2B
      • Inteligencia Artificial Aplicada al Marketing
      • Automatización del Marketing
      • Marca Personal y Marketing Freelance
      • Ventas y Experiencia del Cliente
      • Creación de Contenido para Redes Sociales
    • Inteligencia Artificial y Data Science
      • Fundamentos de Data Science y AI
      • Análisis y Visualización de Datos
      • Machine Learning y Deep Learning
      • Data Engineer
      • Inteligencia Artificial para la Productividad
      • Desarrollo de Aplicaciones con IA
      • AI Software Engineer
    • Ciberseguridad
      • Fundamentos de Ciberseguridad
      • Hacking Ético y Pentesting (Red Team)
      • Análisis de Malware e Ingeniería Forense
      • Seguridad Defensiva y Cumplimiento (Blue Team)
      • Ciberseguridad Estratégica
    • Liderazgo y Habilidades Blandas
      • Fundamentos de Habilidades Profesionales
      • Liderazgo y Gestión de Equipos
      • Comunicación Avanzada y Oratoria
      • Negociación y Resolución de Conflictos
      • Inteligencia Emocional y Autogestión
      • Productividad y Herramientas Digitales
      • Gestión de Proyectos y Metodologías Ágiles
      • Desarrollo de Carrera y Marca Personal
      • Diversidad, Inclusión y Entorno Laboral Saludable
      • Filosofía y Estrategia para Líderes
    • Diseño de Producto y UX
      • Fundamentos de Diseño UX/UI
      • Investigación de Usuarios (UX Research)
      • Arquitectura de Información y Usabilidad
      • Diseño de Interfaces y Prototipado (UI Design)
      • Sistemas de Diseño y DesignOps
      • Redacción UX (UX Writing)
      • Creatividad e Innovación en Diseño
      • Diseño Accesible e Inclusivo
      • Diseño Asistido por Inteligencia Artificial
      • Gestión de Producto y Liderazgo en Diseño
      • Diseño de Interacciones Emergentes (VUI/VR)
      • Desarrollo Web para Diseñadores
      • Diseño y Prototipado No-Code
    • Contenido Audiovisual
      • Fundamentos de Producción Audiovisual
      • Producción de Video para Plataformas Digitales
      • Producción de Audio y Podcast
      • Fotografía y Diseño Gráfico para Contenido Digital
      • Motion Graphics y Animación
      • Contenido Interactivo y Realidad Aumentada
      • Estrategia, Marketing y Monetización de Contenidos
    • Desarrollo Móvil
      • Fundamentos de Desarrollo Móvil
      • Desarrollo Nativo Android con Kotlin
      • Desarrollo Nativo iOS con Swift
      • Desarrollo Multiplataforma con React Native
      • Desarrollo Multiplataforma con Flutter
      • Arquitectura y Patrones de Diseño Móvil
      • Integración de APIs y Persistencia Móvil
      • Testing y Despliegue en Móvil
      • Diseño UX/UI para Móviles
    • Diseño Gráfico y Arte Digital
      • Fundamentos del Diseño Gráfico y Digital
      • Diseño de Identidad Visual y Branding
      • Ilustración Digital y Arte Conceptual
      • Diseño Editorial y de Empaques
      • Motion Graphics y Animación 3D
      • Diseño Gráfico Asistido por Inteligencia Artificial
      • Creatividad e Innovación en Diseño
    • Programación
      • Fundamentos de Programación e Ingeniería de Software
      • Herramientas de IA para el trabajo
      • Matemáticas para Programación
      • Programación con Python
      • Programación con JavaScript
      • Programación con TypeScript
      • Programación Orientada a Objetos con Java
      • Desarrollo con C# y .NET
      • Programación con PHP
      • Programación con Go y Rust
      • Programación Móvil con Swift y Kotlin
      • Programación con C y C++
      • Administración Básica de Servidores Linux
    • Negocios
      • Fundamentos de Negocios y Emprendimiento
      • Estrategia y Crecimiento Empresarial
      • Finanzas Personales y Corporativas
      • Inversión en Mercados Financieros
      • Ventas, CRM y Experiencia del Cliente
      • Operaciones, Logística y E-commerce
      • Gestión de Proyectos y Metodologías Ágiles
      • Aspectos Legales y Cumplimiento
      • Habilidades Directivas y Crecimiento Profesional
      • Diversidad e Inclusión en el Entorno Laboral
      • Herramientas Digitales y Automatización para Negocios
    • Blockchain y Web3
      • Fundamentos de Blockchain y Web3
      • Desarrollo de Smart Contracts y dApps
      • Finanzas Descentralizadas (DeFi)
      • NFTs y Economía de Creadores
      • Seguridad Blockchain
      • Ecosistemas Blockchain Alternativos (No-EVM)
      • Producto, Marketing y Legal en Web3
    • Recursos Humanos
      • Fundamentos y Cultura Organizacional en RRHH
      • Atracción y Selección de Talento
      • Cultura y Employee Experience
      • Gestión y Desarrollo de Talento
      • Desarrollo y Evaluación de Liderazgo
      • Diversidad, Equidad e Inclusión
      • AI y Automatización en Recursos Humanos
      • Tecnología y Automatización en RRHH
    • Finanzas e Inversiones
      • Fundamentos de Finanzas Personales y Corporativas
      • Análisis y Valoración Financiera
      • Inversión y Mercados de Capitales
      • Finanzas Descentralizadas (DeFi) y Criptoactivos
      • Finanzas y Estrategia para Startups
      • Inteligencia Artificial Aplicada a Finanzas
      • Domina Excel
      • Financial Analyst
      • Conseguir trabajo en Finanzas e Inversiones
    • Startups
      • Fundamentos y Validación de Ideas
      • Estrategia de Negocio y Product-Market Fit
      • Desarrollo de Producto y Operaciones Lean
      • Finanzas, Legal y Fundraising
      • Marketing, Ventas y Growth para Startups
      • Cultura, Talento y Liderazgo
      • Finanzas y Operaciones en Ecommerce
      • Startups Web3 y Blockchain
      • Startups con Impacto Social
      • Expansión y Ecosistema Startup
    • Cloud Computing y DevOps
      • Fundamentos de Cloud y DevOps
      • Administración de Servidores Linux
      • Contenerización y Orquestación
      • Infraestructura como Código (IaC) y CI/CD
      • Amazon Web Services
      • Microsoft Azure
      • Serverless y Observabilidad
      • Certificaciones Cloud (Preparación)
      • Plataforma Cloud GCP

    Platzi y comunidad

    • Platzi Business
    • Live Classes
    • Lanzamientos
    • Executive Program
    • Trabaja con nosotros
    • Podcast

    Recursos

    • Manual de Marca

    Soporte

    • Preguntas Frecuentes
    • Contáctanos

    Legal

    • Términos y Condiciones
    • Privacidad
    • Tyc promociones
    Reconocimientos
    Reconocimientos
    Logo reconocimientoTop 40 Mejores EdTech del mundo · 2024
    Logo reconocimientoPrimera Startup Latina admitida en YC · 2014
    Logo reconocimientoPrimera Startup EdTech · 2018
    Logo reconocimientoCEO Ganador Medalla por la Educación T4 & HP · 2024
    Logo reconocimientoCEO Mejor Emprendedor del año · 2024
    De LATAM conpara el mundo
    YoutubeInstagramLinkedInTikTokFacebookX (Twitter)Threads