[JAVA] Faites entrer votre nom et votre adresse e-mail avant de supprimer votre compte utilisateur

référence

Pull Request

Préparation

rails new user_delete_app -d postgresql

bin/rails g scaffold user name:string email:string

bin/rails db:create

bin/rails db:migrate

Ajout lié à Slim à Gemifile

gem 'slim-rails'
gem 'html2slim'

Frappez ce qui suit dans le terminal

bundle exec erb2slim app/views app/views -d

[Insérer Tailwind](https://qiita.com/sakusakupg/items/a5f61818b76c7009f8ff#tailwind%E3%82%92%E5%85%A5%E3%82%8C%E3%81%A6%E3%81% BF% E3% 82% 8B)

préparation des données sur les semences

db/seeds.rb


User.create(
  [
    {name: 'Jane Cooper', email: '[email protected]'},
    {name: 'Cody Fisher', email: '[email protected]'},
    {name: 'Esther Howard', email: '[email protected]'},
    {name: 'Jenny Wilson', email: '[email protected]'},
    {name: 'Kristin Watson', email: '[email protected]'},
    {name: 'Cameron Williamson', email: '[email protected]'}
  ]
)

Frappez ce qui suit dans le terminal

bin/rails db:seed

slim:app/views/users/index.html.slim


p#notice
  = notice
.ml-5
  .flex.flex-col.py-5
    .-my-2.overflow-x-auto(class="sm:-mx-6 lg:-mx-8")
    .py-2.align-middle.inline-block.min-w-full(class="sm:px-6 lg:px-8")
      .shadow.overflow-hidden.border-b.border-gray-200(class="sm:rounded-lg")
        table.min-w-full.divide-y.divide-gray-200
          thead
            tr
              th.px-6.py-3.bg-gray-200.text-left.text-xs.leading-4.font-medium.text-gray-500.uppercase.tracking-wider
                | Name
              th.px-6.py-3.bg-gray-200.text-left.text-xs.leading-4.font-medium.text-gray-500.uppercase.tracking-wider
                | Email
              th.px-6.py-3.bg-gray-200.text-left.text-xs.leading-4.font-medium.text-gray-500.uppercase.tracking-wider
                | Show
              th.px-6.py-3.bg-gray-200.text-left.text-xs.leading-4.font-medium.text-gray-500.uppercase.tracking-wider
                | Edit
              / th.px-6.py-3.bg-gray-200.text-left.text-xs.leading-4.font-medium.text-gray-500.uppercase.tracking-wider
              /   | Destroy
          tbody.bg-white.divide-y.divide-gray-200
            - @users.each do |user|
              tr
                td.px-6.py-4.whitespace-no-wrap.text-sm.leading-5.text-gray-500
                  = user.name
                td.px-6.py-4.whitespace-no-wrap.text-sm.leading-5.text-gray-500
                  = user.email
                td.px-6.py-4.whitespace-no-wrap.text-sm.leading-5.text-gray-500
                  = link_to 'Show', user
                td.px-6.py-4.whitespace-no-wrap.text-sm.leading-5.text-gray-500
                  = link_to 'Edit', edit_user_path(user), class: 'disabled'
                / td.px-6.py-4.whitespace-no-wrap.text-sm.leading-5.text-gray-500
                /   = link_to 'Destroy', user, method: :delete, data: {confirm: 'Are you sure?'}
  .mx-8
    = link_to 'New User', new_user_path, class: 'bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded disabled'

slim:app/views/users/show.html.slim


ruby:
  delete_modal_id = "id-#{SecureRandom.uuid}"
  delete_btn_id = "id-#{SecureRandom.uuid}"

p#notice
  = notice
.min-h-screen.bg-gray-100.m-10
  .bg-white.shadow.overflow-hidden.sm:rounded-lg
    .px-4.py-5.border-b.border-gray-200.sm:px-6
      h3.text-lg.leading-6.font-medium.text-gray-900
        |Détails de l'utilisateur
      p.mt-1.max-w-2xl.text-sm.leading-5.text-gray-500
        |Écran des détails de l'utilisateur
      .px-4.py-5.sm:p-0
        dl
          .sm:grid.sm:grid-cols-3.sm:gap-4.sm:px-6.sm:py-5
            dt.text-sm.leading-5.font-medium.text-gray-500
              | Name:
            dd.mt-1.text-sm.leading-5.text-gray-900.sm:mt-0.sm:col-span-2
              = @user.name
              .mt-8.sm:mt-0.sm:grid.sm:grid-cols-3.sm:gap-4.sm:border-t.sm:border-gray-200.sm:px-6.sm:py-5
                dt.text-sm.leading-5.font-medium.text-gray-500
                  | Email:
                dd.mt-1.text-sm.leading-5.text-gray-900.sm:mt-0.sm:col-span-2
                  = @user.email
      .btn-wrapper
        button.bg-red-500.hover:bg-red-700.text-white.font-bold.py-2.px-4.m-3.rounded(
          type="button"
          data-modal-open="##{delete_modal_id}"
        )
          |Suppression de compte
    .pt-4
      = link_to 'Edit', edit_user_path(@user), class: 'bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded disabled'
      |  |
      = link_to 'Back', users_path, class: 'bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded'

.fixed.z-10.inset-0.overflow-y-auto.hidden(id="#{delete_modal_id}" data-modal)
  .flex.items-end.justify-center.min-h-screen.pt-4.px-4.pb-20.text-center.sm:block.sm:p-0
    .fixed.inset-0.transition-opacity
      .absolute.inset-0.bg-gray-700.opacity-75
    span.hidden.sm:inline-block.sm:align-middle.sm:h-screen
    .inline-block.align-bottom.bg-white.rounded-lg.px-4.pt-5.pb-4.text-left.overflow-hidden.shadow-xl.transform.transition-all.sm:my-8.sm:align-middle.sm:max-w-lg.sm:w-full.sm:p-6 aria-labelledby="modal-headline" aria-modal="true" role="dialog"
      .sm:flex.sm:items-start
        .mx-auto.flex-shrink-0.flex.items-center.justify-center.h-12.w-12.rounded-full.bg-red-100.sm:mx-0.sm:h-10.sm:w-10
          svg.h-6.w-6.text-red-600 fill="none" stroke="currentColor" viewbox=("0 0 24 24")
            path d=("M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z") stroke-linecap="round" stroke-linejoin="round" stroke-width="2"
        .mt-3.text-center.sm:mt-0.sm:ml-4.sm:text-left
          h3#modal-headline.text-lg.leading-6.font-medium.text-gray-900
            |Suppression de compte
          .mt-2
            p.text-sm.leading-5.text-gray-500
              |Supprimer, "#{@user.name}Veuillez appuyer sur le bouton Supprimer le compte.
      .mt-5.mx-8
        input.shadow.appearance-none.border.rounded.w-full.py-2.px-3.text-gray-700.leading-tight.focus:outline-none.focus:shadow-outline(placeholder="Saisissez votre nom d'utilisateur" data-activation-target="##{delete_btn_id}" data-activation-value="#{@user.name}")
      .mt-5.sm:mt-4.sm:flex.sm:flex-row-reverse
        span.flex.w-full.rounded-md.shadow-sm.sm:ml-3.sm:w-auto
          = link_to \
            @user,\
            method: :delete,\
            class: "disabled inline-flex justify-center w-full rounded-md border border-transparent px-4 py-2 bg-red-600 text-base leading-6 font-medium text-white shadow-sm hover:bg-red-500 focus:outline-none focus:border-red-700 focus:shadow-outline-red transition ease-in-out duration-150 sm:text-sm sm:leading-5",\
            tabindex: -1,\
            id: delete_btn_id do
            |Suppression de compte
        span.mt-3.flex.w-full.rounded-md.shadow-sm.sm:mt-0.sm:w-auto
          button.inline-flex.justify-center.w-full.rounded-md.border.border-gray-300.px-4.py-2.bg-white.text-base.leading-6.font-medium.text-gray-700.shadow-sm.hover:text-gray-500.focus:outline-none.focus:border-blue-300.focus:shadow-outline-blue.transition.ease-in-out.duration-150.sm:text-sm.sm:leading-5(type="button" data-modal-close)
            |Annuler

Sujet principal

Implémentation partielle modale

app/javascript/src/js/modal.js


document.addEventListener('click', (e) => {
  const clicked = e.target.closest('[data-modal-open]')
  if (clicked) {
    const targetSelector = clicked.getAttribute('data-modal-open')
    const target = document.querySelector(targetSelector)
    if (target) {
      target.classList.remove('hidden')
    }
  }
})

document.addEventListener('click', (e) => {
  const clicked = e.target.closest('[data-modal-close]')
  if (clicked) {
    const targetSelector = clicked.getAttribute('data-modal-close')
    if (targetSelector) {
      const target = document.querySelector(targetSelector)
      if (target) {
        target.classList.add('hidden')
      }
    } else {
      const target = clicked.closest('[data-modal]')
      if (target) {
        target.classList.add('hidden')
      }
    }
  }
})

Entrez votre nom ou votre adresse e-mail dans le formulaire pour activer le bouton de suppression

app/javascript/src/scss/application.scss


@import "btn";

app/javascript/src/scss/_btn.scss


.disabled {
  @apply opacity-50 cursor-not-allowed pointer-events-none;
}

app/javascript/src/js/activation.js


document.addEventListener('input', (e) => {
  const input = e.target
  const targetSelector = input.dataset.activationTarget
  if (targetSelector) {
    const activationValue = input.dataset.activationValue
    const targets = document.querySelectorAll(targetSelector)
    if (input.value === activationValue) {
      targets.forEach((target) => {
        target.classList.remove('disabled')
        target.removeAttribute('tabindex')
      })
    } else {
      targets.forEach((target) => {
        target.classList.add('disabled')
        target.setAttribute('tabindex', -1)
      })
    }
  }
})

0cef6f0c3a5eb75bb9ab4a4a2c1cde5d.gif

Placez le curseur sur l'entrée-> cliquez sur Tab-> cliquez sur Entrée J'ai pu supprimer le bouton même s'il était désactivé, donc je l'ai évité avec tabindex: -1.

Processus de suppression du contrôleur

          = link_to \
            @user,\
            method: :delete,\
            class: "disabled inline-flex justify-center w-full rounded-md border border-transparent px-4 py-2 bg-red-600 text-base leading-6 font-medium text-white shadow-sm hover:bg-red-500 focus:outline-none focus:border-red-700 focus:shadow-outline-red transition ease-in-out duration-150 sm:text-sm sm:leading-5",\
            tabindex: -1,\
            id: delete_btn_id do
            |Suppression de compte

  # DELETE /users/1
  # DELETE /users/1.json
  def destroy
    @user.destroy
    respond_to do |format|
      format.html { redirect_to users_url, notice: 'User was successfully destroyed.' }
      format.json { head :no_content }
    end
  end

Contrôle de fonctionnement

1ed7288e046e28d414c6c3fcbd312986.gif

Recommended Posts

Faites entrer votre nom et votre adresse e-mail avant de supprimer votre compte utilisateur
Écrivez ABNF en Java et transmettez l'adresse e-mail