'magento configuration product to custom laravel configurable product using ajax

Currently I am trying to convert Magento Configurable product to Custom Laravel configurable product.

In step one I am displaying all the attributes from backend

Step 1: Select Attributes enter image description here (Here I have displayed all the attributes from backend) my view blade code

 <div class="container">
        <div class="row p-b-35">
          <div class="form-group">
            @foreach($attributes as $attribute)
            <div class="form-check complete">
             <input type="checkbox" id="{{$attribute->id}}" name="attribute[]" value="{{$attribute->id}}">
             <label for="{{$attribute->id}}">
              {{$attribute->name}}
            </label>
          </div>
          @endforeach
        </div> 
      </div>
      <button  class="btn btn-cons btn-primary" id="stepOne">Next</button>
    </div> 

once the user check the attribute I have use ajax to store the attribute id

ajax code

$('#stepOne').click(function(e){
        e.preventDefault();

      var attribute = "";
          $(":checkbox").each(function () {
              var ischecked = $(this).is(":checked");
              if (ischecked) {
                  attribute += $(this).val() + ",";
          }
      });
        $.ajax({
          url: "/configStepOne",
          type:"POST",
          data:{
            "_token": "{{ csrf_token() }}",
            attribute:attribute,
          },
          success:function(response){
            $('#successMsg').show();
              $('#stepOneResponse').append(response.html);
          },
          error: function(response) {
             console.log(response.responseJSON.message);
          },
          });
        });

In mine controller method (configStepOne)

  public function configStepOne(Request $request) {
      if (!is_null(Session::get('attributes'))) {
            Session::forget('attributes');
      }
      Session::put('attributes', $request->attribute);

      $config_attribute_array = [];
      if (!is_null(Session::get('attributes'))) {
        $config_attribute = Session::get('attributes');
        $config_attribute = substr($config_attribute, 0, -1);
        $config_attribute_array = explode(',', $config_attribute);
      } 
      $html = "";
      foreach($config_attribute_array as $value) {
        $config_attr = Attributee::findOrFail($value);
        $html .= '<p class="small hint-text m-b-20">'.$config_attr->name.'</p>';
        foreach($config_attr->options as $option) {
          $html .= '<div class="form-check complete">';
          $html .= '<input type="checkbox" id="'.$config_attr->name. '-' .$option->id.'-'.$option->option.'" name="option[]" value="'.$option->id.'">';
          $html .= '<label for="'.$config_attr->name.'-'.$option->id.'-'.$option->option.'">'.$option->option.'</label>';
          $html .= '</div>';
        }
        $html .= '<br>';
      }

      return response()->json(['success'=>'Successfully', 'html' => $html]);
    }

Here I am trying to get the attributes respective options from backend and append the response to blade view

Step 2: Attribute Values enter image description here In mine blade view I have

<div id="stepOneResponse">
      
    </div>
   <button  class="btn btn-cons btn-primary" id="stepTwo">Next</button>

From ajax append the blade view is updated as

<div id="stepOneResponse">
   <p class="small hint-text m-b-20">Color</p>
   <div class="form-check complete"><input type="checkbox" id="Color-1-Red" name="option[]" value="1"><label for="Color-1-Red">Red</label></div>
   <div class="form-check complete"><input type="checkbox" id="Color-2-Black" name="option[]" value="2"><label for="Color-2-Black">Black</label></div>
   <div class="form-check complete"><input type="checkbox" id="Color-7-Blue" name="option[]" value="7"><label for="Color-7-Blue">Blue</label></div>
   <div class="form-check complete"><input type="checkbox" id="Color-8-Green" name="option[]" value="8"><label for="Color-8-Green">Green</label></div>
   <br>
   <p class="small hint-text m-b-20">Size</p>
   <div class="form-check complete"><input type="checkbox" id="Size-3-XL" name="option[]" value="3"><label for="Size-3-XL">XL</label></div>
   <div class="form-check complete"><input type="checkbox" id="Size-4-SM" name="option[]" value="4"><label for="Size-4-SM">SM</label></div>
   <div class="form-check complete"><input type="checkbox" id="Size-9-medium" name="option[]" value="9"><label for="Size-9-medium">medium</label></div>
   <div class="form-check complete"><input type="checkbox" id="Size-10-Extra small" name="option[]" value="10"><label for="Size-10-Extra small">Extra small</label></div>
   <br>
   <p class="small hint-text m-b-20">Format</p>
   <div class="form-check complete"><input type="checkbox" id="Format-13-Download" name="option[]" value="13"><label for="Format-13-Download">Download</label></div>
   <div class="form-check complete"><input type="checkbox" id="Format-14-DVD" name="option[]" value="14"><label for="Format-14-DVD">DVD</label></div>
   <br>
</div>
<button  class="btn btn-cons btn-primary" id="stepTwo">Next</button>

ajax code :

 $('#stepTwo').click(function(e){
            e.preventDefault();

          var option = "";
          var option_id = "";
              $("#stepOneResponse :checkbox").each(function () {
                  var ischecked = $(this).is(":checked");
                  if (ischecked) {
                      option += $(this).val() + ",";
                      option_id += $(this).attr('id') + ",";
                  }
              });
            $.ajax({
              url: "/configStepTwo",
              type:"POST",
              data:{
                "_token": "{{ csrf_token() }}",
                option:option,
                option_id:option_id,
              },
              success:function(response){
                $('#successMsg').show();
                 console.log(response);
                  $('#stepTwoImageResponse').append(response.imageHtml);
                  $('#stepTwoPriceResponse').append(response.priceHtml);
                  $('#stepTwoQtyResponse').append(response.qtyHtml);
                  $('#count').text(response.count);

              },
              error: function(response) { 
                 console.log(response.responseJSON.message);
              },
              });
            });

In Controller method configStepTwo

public function configStepTwo(Request $request) {
      if (!is_null(Session::get('options'))) {
              // Session::forget('option');
      }
      Session::put('options', $request->option);
      Session::put('options_id', $request->option_id);

      $config_attribute = "";
      $config_attribute_opt_string = "";
      $config_attribute_array = [];
      $config_attribute_opt_array = [];
      $config_attribute_opt_array_id = [];
      if (!is_null(Session::get('attributes'))) {
        $config_attribute = Session::get('attributes');
        $config_attribute = substr($config_attribute, 0, -1);
        $config_attribute_array = explode(',', $config_attribute);
        // dd($config_attribute_array);    
      } 

      if (!is_null(Session::get('options'))) {
        $config_attribute_opt = Session::get('options');
        $config_attribute_opt = substr($config_attribute_opt, 0, -1);
        $config_attribute_opt_array = explode(',', $config_attribute_opt);
        // dd($config_attribute_opt_array);    
      } 


      if (!is_null(Session::get('options_id'))) {
        $config_attribute_opt_id = Session::get('options_id');
        // $config_attribute_opt_id = strstr($config_attribute_opt_id, '-', true);
        $config_attribute_opt_id = substr($config_attribute_opt_id, 0, -1);
        $config_attribute_opt_array_id = explode(',', $config_attribute_opt_id);
      } 
      foreach ($config_attribute_opt_array_id as $key => $value) {
        $config_attribute_opt_string .= strstr($value, '-', true). ',';
      // $config_attribute_opt_string .= $value. ',';
      }

      $config_attribute_opt_string = substr($config_attribute_opt_string, 0, -1);
      $config_attribute_opt_array_id = explode(',', $config_attribute_opt_string);
      $array_count = array_count_values($config_attribute_opt_array_id);
      $count = 1;
      foreach ($array_count as $key => $value) {
        $count *= $value;
      }

      Session::put('count', $count);

      $imageHtml = "";
      $imageHtml .= '<div class="form-group col-lg-4" id="multi_config_image" style="display: none">
      <label for="type">Select attribute </label>
      <select name="image_attribute_id" class="form-control" id="image_attribute_id">
      <option value="">Select</option>';
      foreach($config_attribute_array as $value) {
        $config_attr = Attributee::findOrFail($value);
        $imageHtml .= '<option value="'.$config_attr->name.'">'.$config_attr->name.'</option>'; 
      }
      $imageHtml .= '</select>';

      foreach($config_attribute_opt_array as $value) {
        $config_opt = AttributeOption::findOrFail($value);

        $imageHtml .= '<div id="image_option_id">';
        $imageHtml .= '<div class="row '.$config_opt->attribute->name.'" style="display: none;">'. $config_opt->option.'<input type="file" name="option_image"  class="form-control" >';
        $imageHtml .= '</div>';
        $imageHtml .= '</div>';
      }
      $imageHtml .= '</div>';

      $priceHtml = "";
      $priceHtml .= '<div class="form-group col-lg-4" id="multi_config_price" style="display: none">
      <label for="type">Select attribute </label>
      <select name="price_attribute_id" class="form-control" id="price_attribute_id">
      <option value="">Select</option>';
      foreach($config_attribute_array as $value) {
        $config_attr = Attributee::findOrFail($value);
        $priceHtml .= '<option value="'.$config_attr->name.'">'.$config_attr->name.'</option>'; 
      }
      $priceHtml .= '</select>';

      foreach($config_attribute_opt_array as $value) {
        $config_opt = AttributeOption::findOrFail($value);
        $priceHtml .= '<div id="price_option_id">';
        $priceHtml .= '<div class="row '.$config_opt->attribute->name.'" style="display: none;">'. $config_opt->option.'<input type="text" name="option_price[]"  class="form-control" >';
        $priceHtml .= '</div>';
        $priceHtml .= '</div>';
      }
      $priceHtml .= '</div>';

      $qtyHtml = "";
      $qtyHtml .= '<div class="form-group col-lg-4" id="multi_config_qty" style="display: none">
      <label for="type">Select attribute </label>
      <select name="qty_attribute_id" class="form-control" id="qty_attribute_id">
      <option value="">Select</option>';
      foreach($config_attribute_array as $value) {
        $config_attr = Attributee::findOrFail($value);
        $qtyHtml .= '<option value="'.$config_attr->name.'">'.$config_attr->name.'</option>'; 
      }
      $qtyHtml .= '</select>';

      foreach($config_attribute_opt_array as $value) {
        $config_opt = AttributeOption::findOrFail($value);
        $qtyHtml .= '<div id="qty_option_id">';
        $qtyHtml .= '<div class="row '.$config_opt->attribute->name.'" style="display: none;">'. $config_opt->option.'<input type="text" name="option_qty[]"  class="form-control" >';
        $qtyHtml .= '</div>';
        $qtyHtml .= '</div>';
      }
      $qtyHtml .= '</div>';
      return response()->json(['success'=>'Successfully',
       'imageHtml' => $imageHtml,
       'priceHtml' => $priceHtml,
       'qtyHtml' => $qtyHtml,
       'count' => $count,
     ]);
    }

Here When user select the attribute option , option are stored and used in next step where user can store the option value with respect to attribute

Step 3: Bulk Images, Price and Quantity

enter image description here

After selecting "Apply unique price by attribute to each sku" enter image description here View file

<p class="small hint-text m-b-10 m-t-20">
 Price
</p>
<div class="form-check">
  <input type="radio" name="price" id="price1">
  <label for="price1">
    Apply single of price to all SKUs
  </label>
</div>
<div class="form-check">
  <input type="radio" name="price" id="price2">
  <label for="price2">
    Apply unique prices by attribute to each SKU
  </label>
</div>
<div class="form-check">
 <input type="radio" name="price" id="price3" checked="checked">
 <label for="price3">
  Skip price at this time
</label>
</div>
<div class="form-group col-lg-4">
 <input type="text" class="form-control" name="single_config_price" id="single_config_price" style="display: none" placeholder="Please enter Price">
</div>
<div id="stepTwoPriceResponse">
  
</div>
<button  class="btn btn-cons btn-primary" id="stepThree">Next</button>

Here I have shown only for price response. Please consider it that Image and Quantity section too Here I have tried to append all the attribute select option .. and when user select the attribute another input section appear respectively where the user can enter the attribute option value

When user hit next Ajax is call having code

$('#stepThree').click(function(e){
            e.preventDefault();

          var option = "";
              $("input[name='option_price[]']").each(function () {
                if($(this).val()) {
                      option += $(this).val() + ",";
                }
              });
              console.log(option);
            $.ajax({
              url: "/configStepThree",
              type:"POST",
              data:{
                "_token": "{{ csrf_token() }}",
                option:option,
              },
              success:function(response){
                $('#successMsg').show();
                 console.log(response);
                 $("#tabImageNav").removeClass("active");
                 $("#tabImage").removeClass("active");
                  $('#tabDetailNav').addClass('active');
                  $('#tabDetail').addClass('active');
                  $('#table').append(response.table);
              },
              error: function(response) {
                // $('#nameErrorMsg').text(response.responseJSON.errors.message);
                 console.log(response.responseJSON.message);
              },
              });
            });
    });

In configStepThree method from controller
   public function configStepThree(Request $request) {
      if (!is_null(Session::get('mulit_options'))) {
              // Session::forget('mulit_options');
      }
      Session::put('mulit_options', $request->option);

      $config_attribute = "";
      $config_attribute_opt_string = "";
      $config_attribute_array = [];
      $config_attribute_opt_array = [];
      $config_attribute_opt_array_id = [];
      if (!is_null(Session::get('attributes'))) {
        $config_attribute = Session::get('attributes');
        $config_attribute = substr($config_attribute, 0, -1);
        $config_attribute_array = explode(',', $config_attribute);
      } 

      if (!is_null(Session::get('options'))) {
        $config_attribute_opt = Session::get('options');
        $config_attribute_opt = substr($config_attribute_opt, 0, -1);
        $config_attribute_opt_array = explode(',', $config_attribute_opt);
      } 


      if (!is_null(Session::get('options_id'))) {
        $config_attribute_opt_id = Session::get('options_id');
        $config_attribute_opt_id = substr($config_attribute_opt_id, 0, -1);
        $config_attribute_opt_array_id = explode(',', $config_attribute_opt_id);
      } 
      foreach ($config_attribute_opt_array_id as $key => $value) {
        $config_attribute_opt_string .= strstr($value, '-', true). ',';
      }


      $count = Session::get('count');

      $table = "";
      $table .= '<table class="table table-hover " >';
      $table .= '<thead>';
      $table .= '<tr>';
      $table .= '<th style="width:30%">Image</th>';
      $table .= '<th style="width:30%">SKU</th>';
      $table .= '<th style="width:40%">Quantity</th>';
      foreach ($config_attribute_array as $key => $attribute) {
       $config_attr = Attributee::findOrFail($attribute);
       $table .= '<th style="width:40%">'.$config_attr->name.'</th>';
     }
     $table .= '<th style="width:40%">Price</th>';
     $table .= '</tr>';
     $table .= '</thead>';
     $table .= '<tbody>';

     //This is what I want as collection
    $collection = [
       [
         'Color' => 'Red',
         'Size' =>  'XL',
         'Format' => 'Download',
         'price' => '200',
         'qty' => '1',
         'image' => 'path',
         'image_count' => '0'
       ],
       [
         'Color' => 'Red',
         'Size' =>  'SM',
         'Format' => 'Download',
         'price' => '200',
         'qty' => '1',
         'image' => 'path',
         'image_count' => '0'
       ],
       [
         'Color' => 'Black',
         'Size' =>  'XL',
         'Format' => 'Download',
         'price' => '300',
         'qty' => '1',
         'image' => 'path',
         'image_count' => '0'
       ],
       [
         'Color' => 'Black',
         'Size' =>  'SM',
         'Format' => 'Download',
         'price' => '300',
         'qty' => '1',
         'image' => 'path',
         'image_count' => '0'
       ]
     ];
     // dd($collection);
     // for ($i=1; $i <= $count; $i++) { 
         foreach ($collection as $key => $value) {
      $table .= '<tr>';
      $table .= '<td class="v-align-middle semi-bold"><img src="../assets/img/thumbnail.jpg" class="img-thumbnail"><span class="badge bage-alert bagde-top">'.$value['image_count'].'</span></td>';
      $table .= '<td class="v-align-middle">Simple but not simpler</td>';
      $table .= '<td class="v-align-middle semi-bold">'.$value['qty'].'</td>';
       foreach ($config_attribute_array as $key => $attribute) {
        $config_attr = Attributee::findOrFail($attribute);
        $table .= '<td class="v-align-middle semi-bold">'.$value[''.$config_attr->name.''].'</td>';
      }
      $table .= '<td class="v-align-middle semi-bold">'.$value['price'].'</td>';
      $table .='</tr>';
       }
    // }
    $table .= '</tbody>';
    $table .= '</table>';
    return response()->json(['success'=>'Successfully',
     'table' => $table,
   ]);
  }

Step : 4 Summary Table enter image description here view blade file code

Here I want to display all the values respective from previous steps.

Note

  $collection = [
       [
         'Color' => 'Red',
         'Size' =>  'XL',
         'Format' => 'Download',
         'price' => '200',
         'qty' => '1',
         'image' => 'path',
         'image_count' => '0'
       ],
       [
         'Color' => 'Red',
         'Size' =>  'SM',
         'Format' => 'Download',
         'price' => '200',
         'qty' => '1',
         'image' => 'path',
         'image_count' => '0'
       ],
       [
         'Color' => 'Black',
         'Size' =>  'XL',
         'Format' => 'Download',
         'price' => '300',
         'qty' => '1',
         'image' => 'path',
         'image_count' => '0'
       ],
       [
         'Color' => 'Black',
         'Size' =>  'SM',
         'Format' => 'Download',
         'price' => '300',
         'qty' => '1',
         'image' => 'path',
         'image_count' => '0'
       ]
     ];

is static collection that I have mannually created. I want this collection to be created dynamically iterating the values from previous step. Please let me know how can I achieve this.

Please do not judge me on my code. I am bit new to this and my code is not clean and I have repeated the code not following DRY principle.



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source