Yes, let's preview the image. ~ part5 ~

Premise

--Use ruby on rails 6.0.0. --User functions are assumed to be introduced by devise. --All view files are in haml format. ――By the way, I'm using MacBook Air (Retina, 13-inch, 2020).

Introduction

This is the synopsis of the last time (part4) . We were able to implement functions for registering and editing product information that includes multiple images. It feels like the work is done.

By the way, the introduction and procedure are described in detail in <a href="https://qiita.com/silvercrow222/items/55aeb5d13ec2bde305db""> part1 , so please take a look if you are interested.

Come on! All that remains is the preview!

Preview

Let's start with js. What you do is similar to what you did with the form.

Create a function for html generation and display a new form at the same time. If you delete the image, the preview will also disappear.

app/assets/javascripts/product.js


$(function() {
  // ~abridgement~
  const buildImg = (index, url)=> {
    const html = `<img data-index="${index}" src="${url}" width="100px" height="100px">`;
    return html;
  }
  // ~abridgement~
  $('#image-box').on('change', '.file', function(e) {
    const targetIndex = $(this).parent().data('index');
    const file = e.target.files[0];
    const blobUrl = window.URL.createObjectURL(file);

    if (img = $(`img[data-index="${targetIndex}"]`)[0]) {
      img.setAttribute('src', blobUrl);
    } else {
      $('#image-box').append(buildFileField(fileIndex[0]));
      fileIndex.shift();
      fileIndex.push(fileIndex[fileIndex.length - 1] + 1)
    }
  });
  // ~abridgement~
  $('#image-box').on('click', '.remove', function() {
    // ~abridgement~
    $(`img[data-index="${targetIndex}"]`).remove();
  });
});

It's been a long time, but it's like this. Only the middle part is complicated, so I don't think I'll be so prepared.

Let's add explanations in order.

const buildImg = (index, url)=> {
    const html = `<img data-index="${index}" src="${url}" width="100px" height="100px">`;
    return html;

First of all, it is a function to generate html, but I think that it is okay because there is nothing particularly difficult. The image is displayed while specifying the size with the url passed as an argument.

$('#image-box').on('change', '.file', function(e) {
    //Get the unique index assigned to the form.
    const targetIndex = $(this).parent().data('index');
    //Get the URL of the image file on the web.
    const file = e.target.files[0];
    const blobUrl = window.URL.createObjectURL(file);
    //Conditional branching depending on the presence or absence of an image with the corresponding index
    if (img = $(`img[data-index="${targetIndex}"]`)[0]) {
      //Replace the URL of the image obtained in the previous line.
      img.setAttribute('src', blobUrl);
    } else {
      $('#previews').append(buildImg(targetIndex, blobUrl));
      $('#image-box').append(buildFileField(fileIndex[0]));
      fileIndex.shift();
      fileIndex.push(fileIndex[fileIndex.length - 1] + 1)

This is the process when the next image is selected. The content is like this.

It's difficult to get the URL on the 5th and 6th lines, but I'm not sure about this, so I'll investigate it in detail later. Rest assured that the operation itself will work.

By the way, the part after else is just a preview display added to the original description, so please see the previous part for details.

The reason I moved them below else is that in the previous state, a new form was displayed just by replacing the image. So by putting these guys under else, the form will be added only when adding an image.

  $(`img[data-index="${targetIndex}"]`).remove();

This is the last one, but I'm just deleting the preview with the delete button. That's really it.

Now that the js process is complete, let's add a preview that should be displayed in advance on the edit screen.

haml:app/views/products/_form.html.haml


= form_with model: @product, local: true do |f|
  = f.text_field :name, placeholder: 'name'
  #image-box
    #previews
      - if @product.persisted?
        - @product.images.each_with_index do |image, i|
          = image_tag image.src.url, data: { index: i }, width: '100', height: '100'
   = f.fields_for :images do |i|
      // ~abridgement~
  = f.submit 'SEND'

I added the part *@product.persisted? *. The images associated with the product are taken out one by one by url and displayed using image_tag.

By the way, .each_with_index is a method that assigns numbers one by one at the same time as .each by setting two arguments.

Now, the preview function is also implemented. That means

Finally

Finally completed! !! It took quite a while, but I managed to finish it. Huh.

Although it was completed, it was only functional, so I feel like I'm slowly marking up.

However, I was able to implement all the contents of the specification. I'm sorry I wrote it for a long time even though I'm not really doing much difficult things.

I don't think it's there, but thank you for a long time if anyone has read it to the end. I hope it will be helpful for you.

Recommended Posts

Yes, let's preview the image. ~ part5 ~
Let's verify the image search filter
Image processing: Let's play with the image
Let's roughly implement the image preview function with Rails + refile + jQuery.
Image preview function
Let's understand the function!
Image preview function implementation
Quick learning Java "Introduction?" Part 2 Let's write the process
Let's grasp the operation image (atmosphere) of the DI container of Spring
Let's make the app better
Output about the method Part 1
Implementation of image preview function
Let's understand the if statement!
Let's try the S2Struts tutorial (# 3_180425)
Let's solve the roman numerals
Let's understand the guard statement!
Let's try the S2Struts tutorial (# 5_180526)
Let's try the S2Struts tutorial (# 4_180505)
Let's try the S2Struts tutorial (# 1_180423)
Let's solve the FizzBuzz problem!
Let's understand the for-in statement!
Let's try the S2Struts tutorial (# 2_180424)
Let's understand the switch statement!
JavaFX-Load Image in the background
I tried to implement the image preview function with Rails / jQuery
Replace preview by uploading by clicking the image in file_field of Rails
[JQuery] How to preview the selected image immediately + Add image posting gem