Ich habe versucht, die Bildvorschau mit Rails / jQuery zu implementieren

Einführung

Beim Erstellen der Portfolio-Site hatte ich eine Funktion zum Hochladen von Bildern, aber es gab ein Problem, bei dem es schwierig war zu verstehen, ob ein Bild richtig ausgewählt werden konnte, da es keine Vorschaufunktion gab.

Aus diesem Grund habe ich beschlossen, eine Bildvorschau-Funktion hinzuzufügen und diese zu implementieren.

Obwohl es einige Probleme gibt, habe ich es implementiert, daher möchte ich es zusammenfassen.

Annahme

Detail der Funktion

Bild-Upload-Ablauf

  1. Drücken Sie das Eingabe-Tag für die Dateieingabe
  2. Bildauswahl
  3. Ersetzen Sie das Plastikbild durch das ausgewählte Bild

Zum Zeitpunkt der Validierung / Nachbearbeitung

Implementierung

View

erb:app/views/posts/_form.html.erb



<%= form_with(model: post, local: true) do |form| %>

	<!--···Kürzung···-->

	<div class="form-file custom-file mb-3">
    <% if post.image.present? %>
      <div class="form-image-uploader__saved-img">
        <span class="form-image-uploader__saved-img-inner">
          <%= image_tag post.image.to_s %>
        </span>
      </div>
      <div class="block-toggle">
        <div class="block-toggle__press">
          <div class="btn btn-outline-secondary">
            <i class="fas fa-arrow-circle-down"></i>Bild ändern
          </div>
        </div>
        <div class="block-toggle__content" style="display:none;">
          <label for="post_image" class="form-image-uploader__preview">
            <%= image_tag 'nophoto.jpg' %>
          </label>
          <%= form.file_field :image, class:'form-image-uploader__save' %>
          <%= form.hidden_field :image_cache, class:'form-image-uploader__cache' %>
        </div>
      </div>
    <% else %>
      <label for="post_image" class="form-image-uploader__preview">
        <%= image_tag 'nophoto.jpg' %>
      </label>
      <%= form.file_field :image, class:'form-image-uploader__save' %>
      <%= form.hidden_field :image_cache, class:'form-image-uploader__cache' %>
    <% end %>
  </div>

	<!--···Kürzung···-->

<% end %>

JS

Das this.noPhotoImgPath der ImgUplorader -Klasse legt einen beliebigen Pfad fest.

app/javascript/packs/application.js



/*Slide Toggle
------------------------------------------------------*/
$(document).on('turbolinks:load', () =>{
  $('.block-toggle__press .btn').on('click', event =>{
    $(event.currentTarget).parent('.block-toggle__press').next('.block-toggle__content').slideToggle(700);
  });
});

/*Image uplorader
------------------------------------------------------*/
$(document).on('turbolinks:load', () =>{

  const imgUplorader = new ImgUplorader;
  imgUplorader.copyToSaveInput();

});

class ImgUplorader{
  constructor(){
    this.selectorPreview = '.form-image-uploader__preview';
    this.selectorSave = '.form-image-uploader__save';
    this.selectorCache = '.form-image-uploader__cache';
    this.noPhotoImgPath = '/assets/nophoto.jpg';// <=Nophoto Legen Sie den Bildpfad fest

  }

  /*
  * Change preview image to nophoto image when image is not selected
  * @param input : Element of current target
  */
  copyToSaveInput(){
    $(document).on('change', this.selectorSave, event => {

      const input = $(event.currentTarget);
      const filesLength = input[0].files.length;
      const cacheDefaultVal = $(input).next(this.selectorCache)[0].defaultValue;

      // Change preview image to nophoto image when image is not selected
      if (this.hasNotImg(filesLength)) {
        this.changeNoPhotoImg(input);
        return;
      }

      // Change preview image to selected image when image is selected
      this.changeSelectedImg(input);

    });
  }

  /*
   * Return true when input doesn't have file
   * @param filesLength : file length of input
   * @return bool
  */
  hasCacheDefaultImg(filesLength){
    if(filesLength == 0){
      return true;
    }

    return false;
  }

  /*
   * Return true when input doesn't have file
   * @param filesLength : file length of input
   * @return bool
  */
  hasNotImg(filesLength){
    if(filesLength == 0){
      return true;
    }

    return false;
  }

  /*
   * Change preview image to nophoto image when image is not selected
   * @param input : Element of current target
  */
  changeNoPhotoImg(input){
    $(input).prev(this.selectorImg).children('img').attr('src', this.noPhotoImgPath);
  }

  /*
   * Change preview image to selected image when image is selected
   * @param input : Element of current target
  */
  changeSelectedImg(input){
    const reader = new FileReader();
    reader.onload = (progressEvent) => {
      $(input).prev(this.selectorImg).children('img').attr('src', progressEvent.currentTarget.result);
    }

    const file = input[0].files[0];
    reader.readAsDataURL(file);
  }
}

SCSS

app/assets/stylesheets/application.scss



/*form-image-uploader
------------------------------------------------------*/
.form-image-uploader {
  @at-root {
    #{&}__saved-img {
      margin-bottom: 1em;

      @at-root {
        #{&}-inner {
          border: 1px solid #ced4da;
          border-radius: 0.25rem;
          display: inline-block;
        }
      }

      img {
        max-height: 300px;
      }
    }

    #{&}__preview {
      display: inline-block;
      border: 1px solid #ced4da;
      border-radius: 0.25rem;
      position: relative;
      cursor: pointer;

      img {
        max-width: 100px;
        width: auto;
        max-height: 100px;
        height: 100%;

        &:hover {
          opacity: 0.7;
        }
      }
    }
  }
}

/*block-toggle
------------------------------------------------------*/
.block-toggle {
  @at-root {
    #{&}__press {
      cursor: pointer;
      margin-bottom: 0.5em;
    }

    #{&}__content {
      border: 1px solid #ced4da;
      border-radius: 0.25rem;
      padding: 0.5em;
    }
  }
}

Überprüfung

Die folgende Überprüfung des Vorgangs wurde in Chrome, Firefox und Safari durchgeführt.

Zum Zeitpunkt der neuen Buchung

_2020-11-03_6.39.46.mov.gif

Beim Bearbeiten eines Beitrags

_2020-11-03_6.41.47.mov.gif

Aufgabe

--Wenn der ausgewählte Bildname lang ist, ist der Dateiname horizontal lang und überschreitet das umschließende HTML-Element. --Nach der Auswahl eines Bildes klicken Sie auf die Schaltfläche "Abbrechen" → Es wäre schön, eine Funktion hinzufügen zu können, um das Vorschaubild auf noptho zurückzusetzen.

schließlich

Das nächste Mal möchte ich eine Bildvorschau-Funktion implementieren, die die oben genannten Probleme löst.

Referenzartikel

[Rails] Implementierung der Bildvorschau-Funktion --Qiita

Vorschau auf mehrere Bootstrap4-benutzerdefinierte Dateien

Recommended Posts

Ich habe versucht, die Bildvorschau mit Rails / jQuery zu implementieren
Ich habe versucht, die ähnliche Funktion durch asynchrone Kommunikation zu implementieren
[Rails] Ich habe versucht, die Stapelverarbeitung mit der Rake-Task zu implementieren
Ich habe versucht, das Iterator-Muster zu implementieren
Ich habe versucht, die Ajax-Verarbeitung der ähnlichen Funktion in Rails zu implementieren
Ich habe versucht, mit Rails eine Gruppenfunktion (Bulletin Board) zu erstellen
Ich habe versucht, AdoptOpenJDK 11 (11.0.2) mit dem Docker-Image zu überprüfen
[Rails] Ich habe versucht, die Version von Rails von 5.0 auf 5.2 zu erhöhen
Ich habe versucht, die Sitzung in Rails zu organisieren
Ich habe versucht, das Hochladen von Dateien mit Spring MVC zu implementieren
Ich habe versucht, TCP / IP + BIO mit JAVA zu implementieren
Ich habe versucht, mit HCE-F von Android eine Funktion zu implementieren, die Felica Lite entspricht
Ich habe versucht, Sterling Sort mit Java Collector zu implementieren
[Rails] Implementieren Sie die Image-Posting-Funktion
Ich habe versucht, die Methode der gegenseitigen Teilung von Eugrid in Java zu implementieren
Rails-API-Modus Ich habe versucht, die Mehrfachsuchfunktion für Schlüsselwörter mithilfe von Arrays und iterativer Verarbeitung zu implementieren.
Ich habe versucht, die Verarbeitungsgeschwindigkeit mit spiritueller Technik zu erhöhen
[Rails] Ich habe versucht, eine Mini-App mit FullCalendar zu erstellen
Ich habe versucht, mit Java zu interagieren
Ich habe versucht, die Methode zu erklären
[Rails] Ich habe versucht, die Anwendung zu löschen
Ich habe versucht, das Problem der "mehrstufigen Auswahl" mit Ruby zu lösen
Ich möchte eine Browsing-Funktion mit Ruby on Rails hinzufügen
Ich habe versucht, mit Docker eine Plant UML Server-Umgebung zu erstellen
Ich habe versucht, eine flexible ODER-Zuordnung mit MyBatis Dynamic SQL zu implementieren
Ich habe versucht zu verstehen, wie die Rails-Methode "redirect_to" definiert ist
Ich habe versucht, den Betrieb des gRPC-Servers mit grpcurl zu überprüfen
Ich habe versucht zu verstehen, wie die Rails-Methode "link_to" definiert ist
[JQuery] So zeigen Sie das ausgewählte Bild als sofortige Vorschau an + Fügen Sie ein Bildposting-Juwel hinzu
Ich habe versucht, die verwendeten Methoden zusammenzufassen
[Rails] Implementierung einer mehrschichtigen Kategoriefunktion unter Verwendung der Abstammung "Ich habe versucht, ein Fenster mit Bootstrap 3 zu erstellen"
Ich habe versucht, mit Web Assembly zu beginnen
Versuchen Sie, eine Anmeldefunktion mit Spring-Boot zu implementieren
So implementieren Sie TextInputLayout mit Validierungsfunktion
Ich habe versucht, die Stream-API zusammenzufassen
Ich habe versucht, Selen wie JQuery zu verwenden
So implementieren Sie die Image-Veröffentlichung mithilfe von Schienen
[Rails] Ich habe versucht, eine Transaktion zu implementieren, die mehrere DB-Prozesse kombiniert
Ich habe versucht, das Problem der Tribonacci-Sequenz in Ruby mit Wiederholung zu lösen.
[Rails] Implementieren Sie die Produktkauffunktion mit einer bei PAY.JP registrierten Kreditkarte
Ich habe versucht, den Zugriff von Lambda → Athena mit AWS X-Ray zu visualisieren
Ich möchte ein Komitee mit Rails vorstellen, ohne zu schmutzig zu werden
Ich habe versucht, die Geschwindigkeit von Graal VM mit JMH zu messen und zu vergleichen
Immerhin wollte ich den Inhalt von MySQL mit Docker in der Vorschau anzeigen ...
Ich habe versucht, den Ablauf bei der Bildanalyse mit Vision Framework und Core ML herauszufinden
Ich habe versucht, polymorph in Nogizaka zu implementieren.
Ich habe versucht, die Federbeinkonfiguration mit Coggle zu verwalten
Ich habe versucht, Anmeldeinformationen mit JMX zu verwalten