[JAVA] [Rails] À propos de la fonction d'édition du produit de l'application Furima (édition d'aperçu / mise à jour de la base de données)

introduction

Mon nom est Kusano. Cet article concerne la fonction d'édition de produit d'application clone du site EC du marché libre qui a été développé par l'équipe de l'école de programmation. Le texte est médiocre car c'est une note pour moi, mais j'espère qu'il aidera autant que possible les débutants. Comme le titre l'indique, le contenu concerne l'édition d'aperçu et la mise à jour de la base de données. Je pense qu'il y a de nombreux points immatures. Veuillez signaler toute lacune. Je vais l'améliorer de temps en temps. En passant, je suis diplômé de l'école elle-même, et je le posterai comme un compte rendu de ce que j'ai appris.

Produit fini

Écran d'édition du produit (aperçu de la partie de l'image)

Image from Gyazo

Écran d'édition du produit (section catégorie)

Image from Gyazo

Écran d'édition du produit (frais de vente / service des bénéfices)

Image from Gyazo

Écran de transition lorsque la mise à jour est réussie

Image from Gyazo

Procédure de montage

  1. Modification du routage

--Update_done route setting (écran de transition lorsque la mise à jour est réussie)

  1. Modification du contrôleur

--edit paramètre de méthode --update paramètre de méthode --La gestion des erreurs --Supprimer l'image --update_dane paramètre de méthode

  1. Afficher l'édition / la création

--Appeler l'image d'aperçu --Ajustement des appels de catégorie

  1. Édition JS

--Générer et supprimer des images d'aperçu et des balises d'entrée --Affichage des frais de vente et des bénéfices

1. Modification du routage

Update_done Génère une route. Il s'agit du routage pour afficher l'écran de transition lorsque la mise à jour est réussie.

config/routes.rb 


  resources :items do
    resources :comments,  only: [:create, :destroy]
    resources :favorites, only: [:create, :destroy]
    collection do
      get 'get_category_children', defaults: { fomat: 'json'}
      get 'get_category_grandchildren', defaults: { fomat: 'json'}
      get 'search'
      get 'post_done'
      get 'delete_done'
      get 'detail_search'
      get 'update_done' #Ajoute ça
    end
  end

2. Modification du contrôleur

La description du contrôleur édité cette fois est la suivante.

app/controller/items_controller.rb 


class ItemsController < ApplicationController
before_action :category_parent_array, only: [:new, :create, :edit]
before_action :set_item, only: [:show, :edit, :update, :destroy]
before_action :show_all_instance, only: [:show, :edit, :destroy]

#Omission

  def edit
    grandchild = @item.category
    child = grandchild.parent
    if @category_id == 46 or @category_id == 74 or @category_id == 134 or @category_id == 142 or @category_id == 147 or @category_id == 150 or @category_id == 158
    else
     @parent_array = []
     @parent_array << @item.category.parent.parent.name
     @parent_array << @item.category.parent.parent.id
    end
     @category_children_array = Category.where(ancestry: child.ancestry)
     @child_array = []
     @child_array << child.name
     @child_array << child.id

     @category_grandchildren_array = Category.where(ancestry: grandchild.ancestry)
     @grandchild_array = []
     @grandchild_array << grandchild.name
     @grandchild_array << grandchild.id

  end

  def update
    if item_params[:images_attributes].nil?
      flash.now[:alert] = 'Mise à jour impossible [Veuillez insérer une ou plusieurs images]'
      render :edit
    else
      exit_ids = []
      item_params[:images_attributes].each do |a,b|
        exit_ids << item_params[:images_attributes].dig(:"#{a}",:id).to_i
      end
      ids = Image.where(item_id: params[:id]).map{|image| image.id }
      delete__db = ids - exit_ids
      Image.where(id:delete__db).destroy_all
      @item.touch
      if @item.update(item_params)
        redirect_to  update_done_items_path
      else
        flash.now[:alert] = 'Impossible de mettre à jour'
        render :edit
      end
    end
  end

  def update_done
    @item_update = Item.order("updated_at DESC").first
  end

#Omission

  private
  def item_params
    params.require(:item).permit(:name, :item_explanation, :category_id, :item_status, :auction_status, :delivery_fee, :shipping_origin, :exhibition_price,:brand_name, :days_until_shipping, images_attributes: [:image, :_destroy, :id]).merge(user_id: current_user.id)
  end

  def set_item
    @item = Item.find(params[:id])
  end

  def category_parent_array
    @category_parent_array = Category.where(ancestry: nil).each do |parent|
    end
  end

  def show_all_instance
    @user = User.find(@item.user_id)
    @images = Image.where(item_id: params[:id])
    @images_first = Image.where(item_id: params[:id]).first
    @category_id = @item.category_id
    @category_parent = Category.find(@category_id).parent.parent
    @category_child = Category.find(@category_id).parent
    @category_grandchild = Category.find(@category_id)
  end
end

Tout d'abord, définissez la méthode d'édition. Puisque la variable d'instance utilisée dans d'autres méthodes est utilisée, il y a un appel de before_action pour la refactorisation. Les variables d'instance utilisées sont les suivantes. (2) Un tableau auquel le nom et l'identifiant de la catégorie parent sont affectés ③ catégorie Toutes les catégories enfants du modèle ④ Un tableau auquel le nom et l'identifiant de la catégorie enfant sont affectés ⑤ catégorie Toutes les catégories de petits-enfants du modèle ⑥ Un tableau auquel sont attribués le nom et l'identifiant de la catégorie petit-enfant ⑦ Informations produit applicables ⑧ catégorie Toutes les catégories parents du modèle ⑨ Image du produit correspondant ⑩ Category_id du produit correspondant (valeur numérique du petit-enfant)

app/controller/items_controller.rb&nbsp;


class ItemsController < ApplicationController
before_action :category_parent_array, only: [:new, :create, :edit]
before_action :set_item, only: [:show, :edit, :update, :destroy]
before_action :show_all_instance, only: [:show, :edit, :destroy]

#Omission

  def edit
    #▼ ① Ici, attribuez la catégorie enfant / petit-enfant du produit correspondant à la variable
    grandchild = @item.category
    child = grandchild.parent
    if @category_id == 46 or @category_id == 74 or @category_id == 134 or @category_id == 142 or @category_id == 147 or @category_id == 150 or @category_id == 158
    else
     #② ▼ Remplacez le nom et l'identifiant de la catégorie parente dans un tableau
     @parent_array = []
     @parent_array << @item.category.parent.parent.name
     @parent_array << @item.category.parent.parent.id
    end
     #③ ▼ Attribuer toutes les catégories enfants aux variables d'instance
     @category_children_array = Category.where(ancestry: child.ancestry)
     #④ ▼ Remplacez le nom et l'identifiant de la catégorie enfant dans un tableau
     @child_array = []
     @child_array << child.name #Récupère le nom / id en fonction de la variable générée dans ⑤
     @child_array << child.id
     #⑤ ▼ Attribuez toutes les catégories de petits-enfants aux variables d'instance
     @category_grandchildren_array = Category.where(ancestry: grandchild.ancestry) 
     #⑥ ▼ Remplacez le nom et l'identifiant de la catégorie des petits-enfants dans un tableau
     @grandchild_array = []
     @grandchild_array << grandchild.name #Récupère le nom / id en fonction de la variable générée dans ⑤
     @grandchild_array << grandchild.id
  end
  end

#Omission

  private
  def item_params
    params.require(:item).permit(:name, :item_explanation, :category_id, :item_status, :auction_status, :delivery_fee, :shipping_origin, :exhibition_price,:brand_name, :days_until_shipping, images_attributes: [:image, :_destroy, :id]).merge(user_id: current_user.id)
  end

  def set_item
    @item = Item.find(params[:id])                                #⑦ Attribuez les informations produit correspondantes à la variable d'instance
  end

  def category_parent_array
    @category_parent_array = Category.where(ancestry: nil)        #⑧ Attribuez toutes les catégories parentes aux variables d'instance
  end

  def show_all_instance
    @user = User.find(@item.user_id)
    @images = Image.where(item_id: params[:id])                   #⑨ Remplacez l'image du produit correspondant dans la variable d'instance
    @images_first = Image.where(item_id: params[:id]).first
    @category_id = @item.category_id                              #⑩ Récupérez l'identifiant de la catégorie à partir de l'enregistrement du produit correspondant et attribuez-le à la variable d'instance (l'identifiant obtenu à ce moment est l'identifiant de la catégorie petit-enfant)
    @category_parent = Category.find(@category_id).parent.parent                    
    @category_child = Category.find(@category_id).parent
    @category_grandchild = Category.find(@category_id)
  end

Si vous classez et réorganisez chacun d'eux, ce sera comme suit.

** Pour afficher les informations produit en tant que valeur initiale dans la balise d'entrée ** ⑦ Informations produit applicables ** Pour afficher l'image du produit comme valeur initiale dans l'aperçu ** ⑨ Image du produit correspondant ** Pour afficher la catégorie comme valeur initiale dans la balise d'entrée **

--Informations pour acquérir les noms et les identifiants des parents, des enfants et des petits-enfants et les utiliser dans collection_select du côté de la vue ⑩ Category_id du produit correspondant (valeur numérique du petit-enfant) (2) Un tableau auquel le nom et l'identifiant de la catégorie parent sont affectés ④ Un tableau auquel le nom et l'identifiant de la catégorie enfant sont affectés ⑥ Un tableau auquel sont attribués le nom et l'identifiant de la catégorie petit-enfant

--Informations utilisées par collection_select du côté vue lors de la réentrée ⑧ catégorie Toutes les catégories parents du modèle ③ catégorie Toutes les catégories enfants du modèle ⑤ catégorie Toutes les catégories de petits-enfants du modèle

Vient ensuite le réglage de la méthode de mise à jour. Comme pour la modification, les informations sur le produit que vous souhaitez mettre à jour sont appelées before_action.

app/controller/items_controller.rb&nbsp;


class ItemsController < ApplicationController
before_action :set_item, only: [:show, :edit, :update, :destroy]

#Omission

  def update
    # ①
    if item_params[:images_attributes].nil?
      flash.now[:alert] = 'Mise à jour impossible [Veuillez insérer une ou plusieurs images]'
      render :edit
    else
    # ②
      exit_ids = []
      item_params[:images_attributes].each do |a,b|
        exit_ids << item_params[:images_attributes].dig(:"#{a}",:id).to_i
      end
      ids = Image.where(item_id: params[:id]).map{|image| image.id }
    # ③
      delete__db = ids - exit_ids
      Image.where(id:delete__db).destroy_all
    # ④
      @item.touch
      if @item.update(item_params)
        redirect_to  update_done_items_path
      else
        flash.now[:alert] = 'Impossible de mettre à jour'
        render :edit
      end
    end
  end


#Omission

  private
  def item_params
    params.require(:item).permit(:name, :item_explanation, :category_id, :item_status, :auction_status, :delivery_fee, :shipping_origin, :exhibition_price,:brand_name, :days_until_shipping, images_attributes: [:image, :_destroy, :id]).merge(user_id: current_user.id)
  end

  def set_item
    @item = Item.find(params[:id])
  end
end

Tout d'abord, cette description décrit la gestion des erreurs avec une instruction if afin qu'elle ne puisse pas être mise à jour lorsqu'il n'y a pas d'image. La description de item_params [: images_attributes] .nil? Vérifie si les images dans les paramètres sont vides. Si la méthode .nil? Est vide, elle devient ture, et le rendu revient à l'écran d'édition et flash.now [: alert] affiche un message d'erreur.


    if item_params[:images_attributes].nil?
      flash.now[:alert] = 'Mise à jour impossible [Veuillez insérer une ou plusieurs images]'
      render :edit
    else

② se déplace lorsqu'il devient faux dans l'instruction if plus tôt. Le contenu décrit est l'identifiant de l'image saisi lorsque exit_ids appuie sur le bouton de mise à jour et les identifiants de l'image avant mise à jour enregistrés dans la base de données. exit_Générer un tableau appelé ids et item_params[:images_attributes]Puisque je veux récupérer la valeur de l'id contenue dans le tableau multidimensionnel, développez la clé et la valeur dans l'ordre avec chaque instruction. (|a,b|→ une clé, valeur b) Et la méthode dig est utilisée pour récupérer la valeur du tableau multidimensionnel. item_params [: images_attributes](tableau multidimensionnel) .dig (: "# {a (clé parent)}",: id (clé enfant)) .to_i (en faire une valeur numérique) Extraire l'identifiant et l'affecter au tableau Je vais. Ensuite, récupérez l'enregistrement correspondant avant la mise à jour de la base de données pour les identifiants, extrayez l'identifiant avec la méthode map et remplacez-le.


      exit_ids = []
      item_params[:images_attributes].each do |a,b|
        exit_ids << item_params[:images_attributes].dig(:"#{a}",:id).to_i
      end
      ids = Image.where(item_id: params[:id]).map{|image| image.id }

En passant, si vous vérifiez le contenu de item_params [: images_attributes] à l'aide de binding.pry, il sera affiché comme suit. J'ai cliqué sur le bouton de mise à jour avec une image. La valeur que vous souhaitez attribuer à exit_ids dans ② est la valeur "322" dans le tableau enfant.

Terminal (console de démarrage)


[1] pry(#<ItemsController>)> item_params[:images_attributes]
=> <ActionController::Parameters {"0"=><ActionController::Parameters {"id"=>"322"} permitted: true>} permitted: true>

En (3), les exit_ids et ids sont comparés, et lorsque l'image appelée sur l'écran d'édition comme valeur initiale est supprimée du DB, les données correspondantes dans le DB sont supprimées. Vous ne pouvez laisser que les identifiants supprimés en soustrayant exit_ids des identifiants. Affectez-le à delete__db, récupérez l'enregistrement de la base de données en fonction de celui-ci et supprimez-le à l'aide de la méthode destroy_all. La raison de l'utilisation de _all est que même plusieurs enregistrements peuvent être supprimés.


      delete__db = ids - exit_ids
      Image.where(id:delete__db).destroy_all

Dans ④, les informations sur le produit sont mises à jour. S'il peut être mis à jour par la gestion des erreurs de l'instruction if, il passera à l'écran indiquant le succès de la mise à jour via la route update_dine. S'il n'est pas mis à jour, l'écran revient à l'écran d'édition et un message d'erreur s'affiche. @ Item.touch décrit dans la toute première ligne est pour la mise à jour, y compris la colonne update_at (date et heure de mise à jour) de la table des éléments. La raison de l'écriture sera expliquée plus tard.


      @item.touch
      if @item.update(item_params)
        redirect_to  update_done_items_path
      else
        flash.now[:alert] = 'Impossible de mettre à jour'
        render :edit
      end

Vient ensuite le paramétrage de la méthode update_done. Un lien vers la page de détails du produit mis à jour est mis en place sur l'écran qui informe le succès de la mise à jour. La colonne update_at (date et heure de mise à jour) de la table items a été mise à jour en décrivant @ item.touch dans ④ de la méthode de mise à jour plus tôt. Utilisez la méthode order et la première méthode pour affecter le premier élément de la colonne update_at à @item_update dans l'ordre décroissant.

app/controller/items_controller.rb&nbsp;



  def update_done
    @item_update = Item.order("updated_at DESC").first
  end

3. Afficher la modification

Puisqu'il sera long si toutes les descriptions sont incluses, je les omettrai ici.

haml:app/views/items/_form_edit.html.haml&nbsp;


#▼ Description de l'image du produit
.new__page__header
  = link_to image_tag("logo/logo.png ", alt: "logo"), root_path
= form_for @item do |f|
  = render 'layouts/error_messages', model: f.object
  .name__field#1
    .form__label
      .lavel__name
Image de l'exposition
      .lavel__Required
        [Obligatoire]
  #image-box-1{class:"#{@images.last.id}"}
#▼ ① Affichage de l'image d'aperçu
    - @images.each do |img|
      .item-image{id:img.id}
        = image_tag(img.image.url,{width:"188",height:"180"})
        .item-image__operetion
          .item-image__operetion--edit__delete__suppression masquée
    %label.img-label{for: "img-file"}
      #image-box__container{class:"item-num-#{@images.length}"}
        #append-js-edit
          = f.fields_for :images do |image|
            .js-file_group{"data-index" => "#{image.index}"}
              = image.file_field :image, type: 'file', value:"#{image.object.id}",style: "",  id:"img-file", class:'js-file-edit',name: "item[images_attributes][#{@item.images.count}][image]", data:{index:""}
        %i.fas.fa-camera

#Omission

#▼ Description de la catégorie
  .append__category
    .category
      =f.collection_select :category_id, @category_children_array, :id, :name, {selected:@child_array}, {class:"serect_field"}
    - if @category_id == 46 or @category_id == 74 or @category_id == 134 or @category_id == 142 or @category_id == 147 or @category_id == 150 or @category_id == 158
      .category__grandchild#children_wrapper
        =f.collection_select :category_id, @category_grandchildren_array, :id, :name, {},{selected:@grandchild_array, id:"child__category",class:"serect_field"}
    - else
      .category__child#children_wrapper
        =f.collection_select :category_id, @category_children_array, :id, :name, {},{selected:@child_array, id:"child__category", class:"serect_field"}
      .category__grandchild#grandchildren_wrapper
        =f.collection_select :category_id, @category_grandchildren_array, :id, :name, {selected:@grandchild_array}, {class:"serect_field"}

#réduction

L'image d'aperçu s'affiche avec la description suivante. .item-image__operetion - edit__delete__hidden Le point est la description cachée de la suppression. Je vous expliquerai lors de l'édition de js.


    - @images.each do |img|
      .item-image{id:img.id}
        = image_tag(img.image.url,{width:"188",height:"180"})
        .item-image__operetion
          .item-image__operetion--edit__delete__suppression masquée

Les catégories sont affichées dans la description ci-dessous. Le branchement conditionnel est effectué dans l'instruction if lorsqu'il n'y a pas de petit-enfant et lorsqu'il y a un petit-enfant. Le contenu {} est décrit dans la balise collection_select, mais cela est décrit en relation avec l'ordre des arguments lors de la description des options lors de l'attribution de l'id.

Catégorie


  .append__category
    .category
      =f.collection_select :category_id, @category_children_array, :id, :name, {selected:@child_array}, {class:"serect_field"}
    - if @category_id == 46 or @category_id == 74 or @category_id == 134 or @category_id == 142 or @category_id == 147 or @category_id == 150 or @category_id == 158
      .category__grandchild#children_wrapper
        =f.collection_select :category_id, @category_grandchildren_array, :id, :name, {},{selected:@grandchild_array, id:"child__category",class:"serect_field"}
    - else
      .category__child#children_wrapper
        =f.collection_select :category_id, @category_children_array, :id, :name, {},{selected:@child_array, id:"child__category", class:"serect_field"}
      .category__grandchild#grandchildren_wrapper
        =f. :category_id, @category_grandchildren_array, :id, :name, {selected:@grandchild_array}, {class:"serect_field"}

La description suivante sera le fichier de vue de l'écran de transition lorsque la mise à jour est réussie.

haml:app/views/items/_form_edit.html.haml&nbsp;


= render "top/header"
.done#fullsize
  .done__title
Les informations sur le produit ont été mises à jour
  .done__backlink
    = link_to 'Retour en haut de la page', root_path, class: 'link'
  .done__backlink
    = link_to 'Vérifier les produits mis à jour', item_path(@item_update), class: 'link'
  .done__backlink
    = link_to 'Voir la liste des produits en vente', users_path, class: 'link'
= render "top/lower-photo"
= render "top/footer"
= render "top/btn"

4. Édition JS

Modifiez le fichier js comme suit.

app/assets/javascript/edit_items.js&nbsp;


$(function(){
  var dataBox = new DataTransfer();
  var file_field = document.getElementById('img-file')
  $('#append-js-edit').on('change','#img-file',function(){
    $.each(this.files, function(i, file){
      //Lire l'objet File spécifié par readAsDataURL de FileReader
      var fileReader = new FileReader();
      //Ajouter un fichier à l'objet DataTransfer
      dataBox.items.add(file)
      var num = $('.item-image').length + 1 + i
      var aaa = $('.item-image').length + i
// ①
      var image_id = Number($('#image-box-1').attr('class'))
      var append_div_count = Number($('div[id=1]').length) 
      var noreset_id = image_id + append_div_count

      fileReader.readAsDataURL(file);
     //Lorsque le nombre d'images atteint 10, supprimez la case lorsqu'elle dépasse
      if (num == 10){
        $('#image-box__container').css('display', 'none')
      }
      //Lorsque le chargement est terminé, stockez l'URL du fichier dans src
      fileReader.onloadend = function() {
        var src = fileReader.result
// ②
        var html= `<div class='item-image' data-image="${file.name}" data-index="${aaa}" id="${noreset_id-1}">
                    <div class=' item-image__content'>
                      <div class='item-image__content--icon'>
                        <img src=${src} width="188" height="180" >
                      </div>
                    </div>
                    <div class='item-image__operetion'>
                      <div class='item-image__operetion--edit__delete__file'>Effacer</div>
                    </div>
                  </div>`
        const buildFileField1 = (num)=> {
// ③
          const html = `<div  class="js-file_group" data-index="${num}" id=1>
                          <input class="js-file-edit" type="file"
                          name="item[images_attributes][${append_div_count+9}][image]"
                          id="img-file" data-index="${num}value="${noreset_id}" >
                        </div>`;
          return html;
        }
        $('.js-file-edit').removeAttr('id');
        //image_box__Insérer html avant l'élément conteneur
        $('.img-label').before(html);
        $('#append-js-edit').append(buildFileField1(num));
      };
      //image-box__Changez la classe du conteneur et changez la taille de la boîte de dépôt avec CSS.
      $('#image-box__container').attr('class', `item-num-${num}`)
    });
  });
// ④
  //Supprimer la boîte lorsque 10 feuilles ont été enregistrées
  $(document).ready(function(){
    var image_num = $('.item-image').length
    if (image_num==10){
      $('#image-box__container').css('display', 'none')
    }
  });
// ⑤
  $(document).ready(function(){
    $('.js-file-edit').removeAttr('id');
    var num = $('.item-image').length - 1
    var image_id = Number($('#image-box-1').attr('class'))
    var append_div_count = Number($('div[id=1]').length) 
    var noreset_id = image_id + append_div_count
    const buildFileField = (num)=> {
      const html = `<div  class="js-file_group" data-index="${num}" id=1>
                      <input class="js-file-edit" type="file"
                      name="item[images_attributes][100][image]"
                      id="img-file" data-index="${num}" value="${noreset_id}" >
                    </div>`;
      return html;
    }
    $('#append-js-edit').append(buildFileField(num));
  });
// ⑥
  $(document).on("click", '.item-image__operetion--edit__delete__hidden', function(){
    //Obtenir l'élément d'aperçu appuyé pour le supprimer
    var target_image = $(this).parent().parent();
    //Obtenez le nom de fichier de l'image d'aperçu qui a été pressée pour supprimer
    var target_id = $(target_image).attr('id');
    var target_image_file = $('input[value="'+target_id+'"][type=hidden]');
    //Supprimer l'aperçu
    target_image.remove()
    target_image_file.remove()
    //image-box__Changez la classe de la balise div qui a la classe de conteneur chaque fois que vous la supprimez
    var num = $('.item-image').length
    $('#image-box__container').show()
    $('#image-box__container').attr('class', `item-num-${num}`)
  })
// ⑦
  $(document).on("click", '.item-image__operetion--edit__delete__file', function(){
    //Obtenir l'élément d'aperçu appuyé pour le supprimer
    var target_image = $(this).parent().parent();
    var target_id = Number($(target_image).attr('id'));
    //Obtenez le nom de fichier de l'image d'aperçu qui a été pressée pour supprimer
    var target_image_file = $('#append-js-edit').children('div').children('input[value="'+target_id+'"][type=file]');
    //Supprimer l'aperçu
    target_image.remove()
    target_image_file.remove()
    //image-box__Changez la classe de la balise div qui a la classe de conteneur chaque fois que vous la supprimez
    var num = $('.item-image').length
    $('#image-box__container').show()
    $('#image-box__container').attr('class', `item-num-${num}`)
  })

Obtenez le dernier identifiant d'image enregistré dans la description sur la première ligne et affectez-le à la variable image_id. Sur la deuxième ligne, comptez le nombre de balises attribuées id = 1 dans le div du fichier de vue et attribuez-les à la variable append_div_count. Ajoutez-le sur la troisième ligne, Affectez à la variable noreset_id. noreset_id sert à définir l'option de valeur de la balise d'entrée qui est nouvellement affichée lorsqu'une image est ajoutée. Utilisez ceci pour effectuer l'opération de suppression. En outre, définissez l'option id pour supprimer la balise div qui est le parent de l'image d'aperçu, en visant la même valeur numérique. (②)


      var image_id = Number($('#image-box-1').attr('class'))
      var append_div_count = Number($('div[id=1]').length) 
      var noreset_id = image_id + append_div_count

La description ci-dessous est le HTML de l'image d'aperçu générée par le déclenchement d'un événement lorsque les données d'image sont entrées dans la balise d'entrée.

Le point est la description du fichier dans la description de la suppression. Distinguez-vous de la description cachée qui a été dite lors de la modification de la vue et déterminez s'il s'agit d'une balise d'entrée nouvellement générée ou de la balise d'entrée qui est affichée depuis le début.


 var html= `<div class='item-image' data-image="${file.name}" data-index="${aaa}" id="${noreset_id-1}">
                    <div class=' item-image__content'>
                      <div class='item-image__content--icon'>
                        <img src=${src} width="188" height="180" >
                      </div>
                    </div>
                    <div class='item-image__operetion'>
                      <div class='item-image__operetion--edit__delete__file'>Effacer</div>
                    </div>
                  </div>`

La description ci-dessous est le HTML de la balise d'entrée générée par le déclenchement d'un événement lorsque des données d'image sont entrées dans la balise d'entrée.


 const html = `<div  class="js-file_group" data-index="${num}" id=1>
                          <input class="js-file-edit" type="file"
                          name="item[images_attributes][${append_div_count+9}][image]"
                          id="img-file" data-index="${num}value="${noreset_id}" >
                        </div>`;

La description ci-dessous est que l'événement sera déclenché lorsque l'écran est complètement chargé par la méthode prête, et si le nombre d'images de prévisualisation est de 10, la zone de saisie des images sera supprimée.


  //Supprimer la boîte lorsque 10 feuilles ont été enregistrées
  $(document).ready(function(){
    var image_num = $('.item-image').length
    if (image_num==10){
      $('#image-box__container').css('display', 'none')
    }
  });

La description suivante est la description que l'événement est déclenché et que la balise d'entrée est générée lorsque l'écran est complètement chargé par la méthode prête. Si cela n'est pas fait, l'entrée de la première balise d'entrée sera entrée dans la balise d'entrée affichée existante et sera mal alignée, elle doit donc être générée lorsque l'écran est chargé.


  $(document).ready(function(){
    $('.js-file-edit').removeAttr('id');
    var num = $('.item-image').length - 1
    var image_id = Number($('#image-box-1').attr('class'))
    var append_div_count = Number($('div[id=1]').length) 
    var noreset_id = image_id + append_div_count
    const buildFileField = (num)=> {
      const html = `<div  class="js-file_group" data-index="${num}" id=1>
                      <input class="js-file-edit" type="file"
                      name="item[images_attributes][100][image]"
                      id="img-file" data-index="${num}" value="${noreset_id}" >
                    </div>`;
      return html;
    }
    $('#append-js-edit').append(buildFileField(num));
  });

La description suivante supprime la balise d'entrée et l'image d'aperçu dans laquelle les données d'image appelées par modification sont entrées lorsque vous cliquez sur Supprimer affiché en bas à gauche de l'image d'aperçu.


  $(document).on("click", '.item-image__operetion--edit__delete__hidden', function(){
    //Obtenir l'élément d'aperçu appuyé pour le supprimer
    var target_image = $(this).parent().parent();
    //Obtenez le nom de fichier de l'image d'aperçu qui a été pressée pour supprimer
    var target_id = $(target_image).attr('id');
    var target_image_file = $('input[value="'+target_id+'"][type=hidden]');
    //Supprimer l'aperçu
    target_image.remove()
    target_image_file.remove()
    //image-box__Changez la classe de la balise div qui a la classe de conteneur chaque fois que vous la supprimez
    var num = $('.item-image').length
    $('#image-box__container').show()
    $('#image-box__container').attr('class', `item-num-${num}`)
  })

Dans la description ci-dessous, cliquez sur Supprimer affiché en bas à gauche de l'image d'aperçu pour la balise d'entrée où les données d'image appelées sont entrées et l'image d'aperçu nouvellement générée générée lorsqu'une nouvelle image est entrée dans la balise d'entrée. Il est supprimé lorsque vous le faites.


  $(document).on("click", '.item-image__operetion--edit__delete__file', function(){
    //Obtenir l'élément d'aperçu appuyé pour le supprimer
    var target_image = $(this).parent().parent();
    var target_id = Number($(target_image).attr('id'));
    //Obtenez le nom de fichier de l'image d'aperçu qui a été pressée pour supprimer
    var target_image_file = $('#append-js-edit').children('div').children('input[value="'+target_id+'"][type=file]');
    //Supprimer l'aperçu
    target_image.remove()
    target_image_file.remove()
    //image-box__Changez la classe de la balise div qui a la classe de conteneur chaque fois que vous la supprimez
    var num = $('.item-image').length
    $('#image-box__container').show()
    $('#image-box__container').attr('class', `item-num-${num}`)
  })

La description suivante calcule et sort les frais de vente et le bénéfice des ventes lorsque le prix est saisi. La partie éditée est le contenu décrit dans les 2e et 4e colonnes, et les frais de vente et le bénéfice des ventes sont calculés et affichés lorsque l'écran est chargé par la méthode prête.

app/assets/javascript/sales_commission.js&nbsp;


$(function() {
  var input=$("#item_exhibition_price"),fee=1/10,feeIncluded=$("#sales_commission_price");
  input.on("input",function(){
    feeIncluded.text(Math.floor($(this).val() * fee).toLocaleString());
    if($('sales_commission_price').present!=0){
      sales_commission_price.append("Cercle");
    }
  });
  $(document).ready(function(){
    feeIncluded.text(Math.floor($("#item_exhibition_price").val() * fee).toLocaleString());
    if($('sales_commission_price').present!=0){
      sales_commission_price.append("Cercle");
    }
  });
});
  
$(function() {
  var input=$("#item_exhibition_price"),tax=9/10,salesProfit=$("#sales_profit_proce");
  input.on("input",function(){
    salesProfit.text(Math.ceil($(this).val() * tax).toLocaleString());
    if($('sales_commission_price').present!=0){
      sales_profit_proce.append("Cercle");
    }
  });
  $(document).ready(function(){
    salesProfit.text(Math.ceil($("#item_exhibition_price").val() * tax).toLocaleString());
    if($('sales_commission_price').present!=0){
      sales_profit_proce.append("Cercle");
    }
  });
});

Ceci termine la fonction d'édition. Merci d'avoir lu jusqu'ici.

Recommended Posts

[Rails] À propos de la fonction d'édition du produit de l'application Furima (édition d'aperçu / mise à jour de la base de données)
[Ruby on Rails] Fonction de post-édition (mise à jour, suppression)
Payjp.js V2 avec Rails Implémentation de la fonction d'enregistrement de carte de crédit Application Flima
[Rails] Implémentation de la fonction de prévisualisation d'image
[Rails] À propos de la mise en œuvre de la fonction similaire