[Rails] About flea market app product editing function (preview editing / DB update)

Introduction

My name is Kusano. This post is about the clone application product editing function of the flea market EC site that was developed by the team at the programming school. The text is poor because it is a memo for myself, but I hope it will help beginners as much as possible. As the title says, the content is about preview editing and DB update. I think there are many immature points. Please point out any deficiencies. I will improve it from time to time. By the way, I have graduated from the school itself, and I will post it as a review of what I learned.

Finished product

Product edit screen (preview image part)

Image from Gyazo

Product edit screen (category section)

Image from Gyazo

Product edit screen (sales commission / profit department)

Image from Gyazo

Transition screen when update is successful

Image from Gyazo

Implementation procedure

  1. Routing editing

--Update_done route setting (transition screen when update is successful)

  1. Controller editing

--edit method settings --update method setting --Error handling --Image deletion --update_dane method setting

  1. View editing / creating

--Call preview image --Adjusting category calls --Transition screen when update is successful

  1. JS editing

--Generate and delete preview images and input tags --Display of sales commissions and profits

1. Routing editing

Update_done Generate a route. This is the routing to display the transition screen when the update is successful.

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' #Add this
    end
  end

2. Controller editing

The description of the controller edited this time is as follows.

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] = 'Could not update [Please insert one or more 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] = 'Could not update'
        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

First, set the edit method. Since the instance variable used in other methods is used, there is a call from before_action for refactoring. The instance variables used are as follows. (2) An array to which the name and id of the parent category are assigned ③ category All child categories in the model ④ Array to which the name and id of the child category are assigned ⑤ category All grandchild categories in the model ⑥ Array to which the name and id of the grandchild category are assigned ⑦ Applicable product information ⑧ category All parent categories in the model ⑨ Image of the corresponding product ⑩ Category_id (grandchild number) of the corresponding product

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
    #▼ ① Here, substitute the child / grandchild category of the corresponding product into a 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
     #② ▼ Array assignment of parent category name and id
     @parent_array = []
     @parent_array << @item.category.parent.parent.name
     @parent_array << @item.category.parent.parent.id
    end
     #③ ▼ Assign all child categories to instance variables
     @category_children_array = Category.where(ancestry: child.ancestry)
     #④ ▼ Array assignment of child category name and id
     @child_array = []
     @child_array << child.name #Get name / id based on the variable generated in ⑤
     @child_array << child.id
     #⑤ ▼ Assign all grandchild categories to instance variables
     @category_grandchildren_array = Category.where(ancestry: grandchild.ancestry) 
     #⑥ ▼ Array assignment of grandchild category name and id
     @grandchild_array = []
     @grandchild_array << grandchild.name #Get name / id based on the variable generated in ⑤
     @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])                                #⑦ Assign the corresponding product information to the instance variable
  end

  def category_parent_array
    @category_parent_array = Category.where(ancestry: nil)        #⑧ Assign all parent categories to instance variables
  end

  def show_all_instance
    @user = User.find(@item.user_id)
    @images = Image.where(item_id: params[:id])                   #⑨ Substitute the image of the corresponding product into the instance variable
    @images_first = Image.where(item_id: params[:id]).first
    @category_id = @item.category_id                              #⑩ Get the category id from the record of the corresponding product and assign it to the instance variable (the id obtained at this time is the grandchild category id)
    @category_parent = Category.find(@category_id).parent.parent                    
    @category_child = Category.find(@category_id).parent
    @category_grandchild = Category.find(@category_id)
  end

If you classify and rearrange each, it will be as follows.

** For displaying product information as an initial value in the input tag ** ⑦ Applicable product information ** For displaying the product image as the initial value in the preview ** ⑨ Image of the corresponding product ** For displaying the category as the initial value in the input tag **

--Information to get parent / child / grandchild name / id and use in collection_select on view side ⑩ Category_id (grandchild number) of the corresponding product (2) An array to which the name and id of the parent category are assigned ④ Array to which the name and id of the child category are assigned ⑥ Array to which the name and id of the grandchild category are assigned

--Information used by collection_select on the view side when re-entering ⑧ category All parent categories in the model ③ category All child categories in the model ⑤ category All grandchild categories in the model

Next is the setting of the update method. As with edit, the product information you want to update is called 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] = 'Could not update [Please insert one or more 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] = 'Could not update'
        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

First of all, this description describes error handling with an if statement so that it cannot be updated when there is no image. The description of item_params [: images_attributes] .nil? Checks if the images in params are empty. If the .nil? method is empty, it will be ture, render will return to the edit screen, and flash.now [: alert] will display an error message.


    if item_params[:images_attributes].nil?
      flash.now[:alert] = 'Could not update [Please insert one or more images]'
      render :edit
    else

If the if statement above is false, ② will move. The contents described are the id of the image entered when exit_ids presses the update button, and the id of the image before update saved in the DB. exit_Generate an array called ids and item_params[:images_attributes]I want to retrieve the id value contained in the multidimensional array, so I expand the key and value in order with each statement. (|a,b|→ a key, b value) And the dig method is used to retrieve the value from the multidimensional array. item_params [: images_attributes](multidimensional array) .dig (: "# {a (parent key)}" ,: id (child key)) .to_i (numerical value) Extract the id and assign it to the array I will. Then, get the corresponding record before update from the DB for ids, extract the id with the map method and substitute it.


      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 }

By the way, if you check the contents of item_params [: images_attributes] using binding.pry, it will be displayed as follows. I clicked the update button with one image. The value you want to assign to exit_ids in ② is the value "322" in the child array.

Terminal (console start)


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

In ③, the exit_ids and ids are compared, and when the image called on the edit screen as the initial value is deleted from the DB, the corresponding data in the DB is deleted. By subtracting exit_ids from ids, you can leave only the deleted ids. Assign it to delete__db, retrieve the record from the DB based on it, and delete it using the destroy_all method. The reason for using _all is so that multiple records can be deleted.


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

In ④, product information is updated. If it can be updated by error handling of the if statement, it will transition to the screen that tells the update success through the update_dine route. If it is not updated, the screen returns to the edit screen and an error message is displayed. @ Item.touch described in the very first line is for updating including the update_at column (update date and time) of the items table. The reason for writing this will be explained later.


      @item.touch
      if @item.update(item_params)
        redirect_to  update_done_items_path
      else
        flash.now[:alert] = 'Could not update'
        render :edit
      end

Next is the setting of the update_done method. A link to the updated product detail page is set up on the screen that informs the update success. The update_at column (update date and time) of the items table was updated by describing @ item.touch in ④ of the update method earlier. Use the order method and first method, and assign the first one to @item_update in descending order in the update_at column.

app/controller/items_controller.rb&nbsp;



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

3. View edit

It will be long if all the descriptions are included, so I will omit them here.

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


#▼ Description of product image
.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
Exhibition image
      .lavel__Required
        [Mandatory]
  #image-box-1{class:"#{@images.last.id}"}
#▼ ① Display of preview image
    - @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__hidden delete
    %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 of category
  .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"}

#abridgement

The preview image is displayed with the following description. .item-image__operetion--edit__delete__hidden The point is the description hidden of deletion. I will explain when editing 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__hidden delete

The categories are displayed in the description below. The if statement is conditional on the case without grandchildren and the case with grandchildren. The contents {} are described in the collection_select tag, but this is described in relation to the order of the arguments when describing the options when assigning the id.

Category


  .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"}

The following description is a view file of the transition screen when the update is successful.

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


= render "top/header"
.done#fullsize
  .done__title
Product information has been updated
  .done__backlink
    = link_to 'Back to top page', root_path, class: 'link'
  .done__backlink
    = link_to 'Check for updated products', item_path(@item_update), class: 'link'
  .done__backlink
    = link_to 'View the list of products on sale', users_path, class: 'link'
= render "top/lower-photo"
= render "top/footer"
= render "top/btn"

4. JS editing

Edit the js file as follows.

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){
      //Read the File object specified by readAsDataURL of FileReader
      var fileReader = new FileReader();
      //Add file to DataTransfer object
      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);
     //When the number of images reaches 10, delete the box when it exceeds
      if (num == 10){
        $('#image-box__container').css('display', 'none')
      }
      //When loading is complete, store the URL of file in 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'>Delete</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__Insert html before the container element
        $('.img-label').before(html);
        $('#append-js-edit').append(buildFileField1(num));
      };
      //image-box__Change the class of container and change the size of the drop box with CSS.
      $('#image-box__container').attr('class', `item-num-${num}`)
    });
  });
// ④
  //Delete the box when 10 sheets have been registered
  $(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(){
    //Get preview element pressed to delete
    var target_image = $(this).parent().parent();
    //Get the filename of the preview image that was pressed to delete
    var target_id = $(target_image).attr('id');
    var target_image_file = $('input[value="'+target_id+'"][type=hidden]');
    //Delete preview
    target_image.remove()
    target_image_file.remove()
    //image-box__Change div tag class with container class every time you delete
    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(){
    //Get preview element pressed to delete
    var target_image = $(this).parent().parent();
    var target_id = Number($(target_image).attr('id'));
    //Get the filename of the preview image that was pressed to delete
    var target_image_file = $('#append-js-edit').children('div').children('input[value="'+target_id+'"][type=file]');
    //Delete preview
    target_image.remove()
    target_image_file.remove()
    //image-box__Change div tag class with container class every time you delete
    var num = $('.item-image').length
    $('#image-box__container').show()
    $('#image-box__container').attr('class', `item-num-${num}`)
  })

Get the last saved image id in the description on the first line and assign it to the image_id variable. In the second line, count the number of tags assigned id = 1 in the div in the view file and assign them to the append_div_count variable. Add it on the third line, Assign to the noreset_id variable. noreset_id is for setting to the value option of the input tag that is newly displayed when an image is added. Use this to perform the delete operation. Also, set the id option to delete the div tag that is the parent of the preview image, aiming for the same numerical value. (②)


      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

The following description is the HTML of the preview image generated by firing the event when the image data is input to the input tag.

The point is the description of file in the description of deletion. Distinguish from the hidden description that was said when editing the view, and determine whether it is a newly generated input tag or the input tag that is displayed from the beginning.


 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'>Delete</div>
                    </div>
                  </div>`

The following description is the HTML of the input tag generated by firing the event when the image data is input to the input tag.


 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>`;

The description below is that the event will be fired when the screen is fully loaded by the ready method, and the box for inputting images will be deleted when the number of preview images is 10.


  //Delete the box when 10 sheets have been registered
  $(document).ready(function(){
    var image_num = $('.item-image').length
    if (image_num==10){
      $('#image-box__container').css('display', 'none')
    }
  });

The following description is the description that the event is fired and the input tag is generated when the screen is loaded by the ready method. If you do not do this, the input to the first input tag will be input to the existing displayed input tag and will be misaligned, so it must be generated when the screen is loaded.


  $(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));
  });

The following description deletes the input tag and preview image in which the image data called by edit is input when you click Delete displayed at the lower left of the preview image.


  $(document).on("click", '.item-image__operetion--edit__delete__hidden', function(){
    //Get preview element pressed to delete
    var target_image = $(this).parent().parent();
    //Get the filename of the preview image that was pressed to delete
    var target_id = $(target_image).attr('id');
    var target_image_file = $('input[value="'+target_id+'"][type=hidden]');
    //Delete preview
    target_image.remove()
    target_image_file.remove()
    //image-box__Change div tag class with container class every time you delete
    var num = $('.item-image').length
    $('#image-box__container').show()
    $('#image-box__container').attr('class', `item-num-${num}`)
  })

In the description below, click Delete displayed at the bottom left of the preview image for the input tag where the called image data is input and the newly generated preview image generated when a new image is input to the input tag. It is deleted when you do.


  $(document).on("click", '.item-image__operetion--edit__delete__file', function(){
    //Get preview element pressed to delete
    var target_image = $(this).parent().parent();
    var target_id = Number($(target_image).attr('id'));
    //Get the filename of the preview image that was pressed to delete
    var target_image_file = $('#append-js-edit').children('div').children('input[value="'+target_id+'"][type=file]');
    //Delete preview
    target_image.remove()
    target_image_file.remove()
    //image-box__Change div tag class with container class every time you delete
    var num = $('.item-image').length
    $('#image-box__container').show()
    $('#image-box__container').attr('class', `item-num-${num}`)
  })

The following description calculates and outputs the sales commission and sales profit when the price is entered. The edited part is the content described in the 2nd and 4th columns, and the sales commission and sales profit are calculated and displayed when the screen is loaded by the ready method.

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("Circle");
    }
  });
  $(document).ready(function(){
    feeIncluded.text(Math.floor($("#item_exhibition_price").val() * fee).toLocaleString());
    if($('sales_commission_price').present!=0){
      sales_commission_price.append("Circle");
    }
  });
});
  
$(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("Circle");
    }
  });
  $(document).ready(function(){
    salesProfit.text(Math.ceil($("#item_exhibition_price").val() * tax).toLocaleString());
    if($('sales_commission_price').present!=0){
      sales_profit_proce.append("Circle");
    }
  });
});

This completes the editing function. Thank you for reading this far.

Recommended Posts

[Rails] About flea market app product editing function (preview editing / DB update)
[Ruby on Rails] Post editing function (update, delete)
Credit card registration function implementation with Payjp.js V2 on Rails Flea market app
About error handling of comment function
Implemented comment function
About the function double-java
App creation comment function asynchronous
About adding a like function
[Rails] About flea market app product editing function (preview editing / DB update)
Real-time comment function with Action Cable (2/2)
[Rails] About the Punk List function
[Rails] About implementation of like function
[Rails] Comment function (registration / display / deletion)
Real-time comment function with Action Cable (1/2)
[Ruby on Rails] Comment function implementation
[Rails] Comment function implementation procedure memo
[Rails] About the Punk List function
[Rails] Implementation of image preview function
[Rails] About implementation of like function