CSS-стиль для внешнего интерфейса для сравнения продуктов в Laravel 10

Я хотел бы отображать продукты в горизонтальной форме, как показано в разделе «Желаемый вид», но сейчас они отображаются в вертикальной форме, как показано в разделе «Существующий вид».

См. скриншот желаемого вида ниже:

Код желаемого образа

магазин-compare.html

 <main class = "main">
        <div class = "page-header breadcrumb-wrap">
            <div class = "container">
                <div class = "breadcrumb">
                    <a href = "index.html" rel = "nofollow"><i class = "fi-rs-home mr-5"></i>Home</a>
                    <span></span> Shop <span></span> Compare
                </div>
            </div>
        </div>
        <div class = "container mb-80 mt-50">
            <div class = "row">
                <div class = "col-xl-10 col-lg-12 m-auto">
                    <h1 class = "heading-2 mb-10">Products Compare</h1>
                    <h6 class = "text-body mb-40">There are <span class = "text-brand">3</span> products to compare</h6>
                    <div class = "table-responsive">
                        <table class = "table text-center table-compare">
                            <tbody>
                                <tr class = "pr_image">
                                    <td class = "text-muted font-sm fw-600 font-heading mw-200">Preview</td>
                                    <td class = "row_img"><img src = "assets/imgs/shop/product-2-1.jpg" alt = "compare-img" /></td>
                                    <td class = "row_img"><img src = "assets/imgs/shop/product-1-1.jpg" alt = "compare-img" /></td>
                                    <td class = "row_img"><img src = "assets/imgs/shop/product-3-1.jpg" alt = "compare-img" /></td>
                                </tr>
                                <tr class = "pr_title">
                                    <td class = "text-muted font-sm fw-600 font-heading">Name</td>
                                    <td class = "product_name">
                                        <h6><a href = "shop-product-full.html" class = "text-heading">J.Crew Mercantile Women's Short</a></h6>
                                    </td>
                                    <td class = "product_name">
                                        <h6><a href = "shop-product-full.html" class = "text-heading">Amazon Essentials Women's Tanks</a></h6>
                                    </td>
                                    <td class = "product_name">
                                        <h6><a href = "shop-product-full.html" class = "text-heading">Amazon Brand - Daily Ritual Wom</a></h6>
                                    </td>
                                </tr>
                                <tr class = "pr_price">
                                    <td class = "text-muted font-sm fw-600 font-heading">Price</td>
                                    <td class = "product_price">
                                        <h4 class = "price text-brand">$12.00</h4>
                                    </td>
                                    <td class = "product_price">
                                        <h4 class = "price text-brand">$14.00</h4>
                                    </td>
                                    <td class = "product_price">
                                        <h4 class = "price text-brand">$15.00</h4>
                                    </td>
                                </tr>
                                <tr class = "pr_rating">
                                    <td class = "text-muted font-sm fw-600 font-heading">Rating</td>
                                    <td>
                                        <div class = "rating_wrap">
                                            <div class = "product-rate d-inline-block">
                                                <div class = "product-rating" style = "width: 90%"></div>
                                            </div>
                                            <span class = "rating_num">(121)</span>
                                        </div>
                                    </td>
                                    <td>
                                        <div class = "rating_wrap">
                                            <div class = "product-rate d-inline-block">
                                                <div class = "product-rating" style = "width: 90%"></div>
                                            </div>
                                            <span class = "rating_num">(35)</span>
                                        </div>
                                    </td>
                                    <td>
                                        <div class = "rating_wrap">
                                            <div class = "product-rate d-inline-block">
                                                <div class = "product-rating" style = "width: 90%"></div>
                                            </div>
                                            <span class = "rating_num">(125)</span>
                                        </div>
                                    </td>
                                </tr>
                                <tr class = "description">
                                    <td class = "text-muted font-sm fw-600 font-heading">Description</td>
                                    <td class = "row_text font-xs">
                                        <p class = "font-sm text-muted">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and</p>
                                    </td>
                                    <td class = "row_text font-xs">
                                        <p class = "font-sm text-muted">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and</p>
                                    </td>
                                    <td class = "row_text font-xs">
                                        <p class = "font-sm text-muted">Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and</p>
                                    </td>
                                </tr>
                                <tr class = "pr_stock">
                                    <td class = "text-muted font-sm fw-600 font-heading">Stock status</td>
                                    <td class = "row_stock"><span class = "stock-status in-stock mb-0">In Stock</span></td>
                                    <td class = "row_stock"><span class = "stock-status out-stock mb-0">Out of stock</span></td>
                                    <td class = "row_stock"><span class = "stock-status in-stock mb-0">In Stock</span></td>
                                </tr>
                                <tr class = "pr_weight">
                                    <td class = "text-muted font-sm fw-600 font-heading">Weight</td>
                                    <td class = "row_weight">320 gram</td>
                                    <td class = "row_weight">370 gram</td>
                                    <td class = "row_weight">380 gram</td>
                                </tr>
                                <tr class = "pr_dimensions">
                                    <td class = "text-muted font-sm fw-600 font-heading">Dimensions</td>
                                    <td class = "row_dimensions">N/A</td>
                                    <td class = "row_dimensions">N/A</td>
                                    <td class = "row_dimensions">N/A</td>
                                </tr>
                                <tr class = "pr_add_to_cart">
                                    <td class = "text-muted font-sm fw-600 font-heading">Buy now</td>
                                    <td class = "row_btn">
                                        <button class = "btn btn-sm"><i class = "fi-rs-shopping-bag mr-5"></i>Add to cart</button>
                                    </td>
                                    <td class = "row_btn">
                                        <button class = "btn btn-sm btn-secondary"><i class = "fi-rs-headset mr-5"></i>Contact Us</button>
                                    </td>
                                    <td class = "row_btn">
                                        <button class = "btn btn-sm"><i class = "fi-rs-shopping-bag mr-5"></i>Add to cart</button>
                                    </td>
                                </tr>
                                <tr class = "pr_remove text-muted">
                                    <td class = "text-muted font-md fw-600"></td>
                                    <td class = "row_remove">
                                        <a href = "#" class = "text-muted"><i class = "fi-rs-trash mr-5"></i><span>Remove</span> </a>
                                    </td>
                                    <td class = "row_remove">
                                        <a href = "#" class = "text-muted"><i class = "fi-rs-trash mr-5"></i><span>Remove</span> </a>
                                    </td>
                                    <td class = "row_remove">
                                        <a href = "#" class = "text-muted"><i class = "fi-rs-trash mr-5"></i><span>Remove</span> </a>
                                    </td>
                                </tr>
                            </tbody>
                        </table>
                    </div>
                </div>
            </div>
        </div>
    </main>

Пожалуйста, смотрите скриншот Existing Look ниже:

Существующий код Look

view_compare.blade.php

<div class = "page-header breadcrumb-wrap">
            <div class = "container">
                <div class = "breadcrumb">
                    <a href = "index.html" rel = "nofollow"><i class = "fi-rs-home mr-5"></i>Home</a>
                     <span></span> Compare
                </div>
            </div>
        </div>
        <div class = "container mb-80 mt-50">
            <div class = "row">
                <div class = "col-xl-10 col-lg-12 m-auto">
                    <h1 class = "heading-2 mb-10">Products Compare</h1>
                    <h6 class = "text-body mb-40">There are products to compare</h6>
                    <div class = "table-responsive">
                        <table class = "table text-center table-compare">

                            <tbody id = "compare">
                                
                               
                            </tbody>
                            
                        </table>
                    </div>
                </div>
            </div>
        </div>

master_dashboard.blade.php

<!--  /// Start Load Compare Data -->

<script type = "text/javascript">

    function compare() {
        $.ajax({
            type: "GET",
            dataType: 'json',
            url: "/get-compare-product/",

            success:function(response){ 

             $('#compareQty').text(response.compareQty);

             const items = response.compare;

             if (!items.length) {
                $('.table-compare').replaceWith('<p>Nothing to compare</p>');
            }

            const getItemDisplayForRowKey = (item, key) => {
                if (key === 'product_qty') {

                    const isInStock = item.product.product_qty > 0;
                    const className = isInStock ? 'in-stock' : 'out-stock';
                    return `<div class = "stock-status ${className} mb-0">${isInStock ? 'In Stock' : 'Out of stock'}</div>`;

                    
                } else if (key === 'product_thambnail') {
                  return `<img src = "${item.product.product_thambnail}" style = "width:300px; height:300px;">`;
              } else if (key === 'selling_price') {
                return `<div product_price"><h4 class = "price text-brand"> AED ${item.product.discount_price || item.product.selling_price}</h4></div>`;
            } else if (key === 'short_descp') {
                return `<div row_text font-xs"><p class = "font-sm text-muted">${item.product.short_descp}</p></div>`;
            } else if (key === 'product_name') {
                return `<div><h6><a href = "{{ url('product/details/'.$product->id.'/'.$product->product_slug) }}" class = "text-heading">${item.product.product_name}</a></h6></div>`;

            }
            return item.product[key];
        }

        const rowHeading = {
            product_thambnail: 'Preview',
            product_name: 'Name',
            product_qty: 'Quantity',
            selling_price: 'Price',
            short_descp: 'Description'
        };

        const html = ['product_thambnail', 'product_name', 'product_qty', 'selling_price', 'short_descp'].map(rowKey => {
            return `
            <tr class = "pr_image">
            <td class = "text-muted font-sm fw-600 font-heading">${rowHeading[rowKey]}</td>
            ${items.map(item => {
              return `<td>${getItemDisplayForRowKey(item, rowKey)}</td>`
          })}
            </tr>
            `
        });

        const actionsRow = `
        <tr>
        <td></td>
        ${items.map(item => {
          return `
          <td class = "row_remove"><a type = "submit" class = "text-muted" id = "${item.id}" onclick = "compareRemove(this.id)"><i class = "fi-rs-trash mr-5"></i><span>Remove</span></td>`;
      })}
        <tr>
        `;

        $('#compare').html(html + actionsRow);
    }
});
    }

    compare();


      // / End Load Compare Data -->
    
    </script> 

// Функция сравнения и удаления

function compareRemove(id){
        $.ajax({
            type: "GET",
            dataType: 'json',
            url: "/compare-remove/"+id,

            success:function(data){
                compare();
                     // Start Message 

                const Toast = Swal.mixin({
                  toast: true,
                  position: 'top-end',
                  
                  showConfirmButton: false,
                  timer: 3000 
              })
                if ($.isEmptyObject(data.error)) {

                    Toast.fire({
                        type: 'success',
                        icon: 'success', 
                        title: data.success, 
                    })

                }else{

                 Toast.fire({
                    type: 'error',
                    icon: 'error', 
                    title: data.error, 
                })
             }

              // End Message  


         }
     })
    }

//Маршрут сведений о продукте

Route::get('/product/details/{id}/{slug}', [IndexController::class, 'ProductDetails']);

//Контроллер индекса

public function ProductDetails($id,$slug){

$product = Product::findOrFail($id);

return view('frontend.product.product_details',compact('product'));

 } // End Method 

Любые предложения приветствуются.

Заранее спасибо.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
0
0
172
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Структура таблицы, которую вы хотите, более сложна, чем та, которую вы сейчас визуализируете. Важно понимать, что для каждой строки вы хотите отобразить свойство каждого объекта продукта. Это говорит нам о том, что нам понадобятся вложенные циклы. Внешний цикл будет проходить по атрибутам продукта, а внутренний цикл — по каждому продукту.

Мы можем начать с массива ключей, которые будут представлять наши строки. Каждый ключ будет свойством продукта, который мы хотим отобразить в этой строке.

Если бы мы просто хотели отображать значение каждого элемента продукта по соответствующему ключу, это было бы очень просто. Однако у нас есть случаи с определенной логикой сопоставления — например, отображение selling_price или discount_price. Поэтому мы собираемся использовать функцию для сопоставления элемента продукта с выходными данными для ключа, инкапсулируя конкретную логику сопоставления.

Мы также должны включить объект для сопоставления ключей строк с понятным отображаемым значением.

Обратите внимание, что в приведенном примере кода я не включил классы CSS или любые другие атрибуты HTML. Это просто базовый HTML.

const response = {
  compare: [
    {
      product: {
        discount_price: null,
        product_thumbnail: 'https://images.unsplash.com/photo-1570913149827-d2ac84ab3f9a?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=100&q=80',
        product_name: 'Product One',
        product_qty: 5,
        selling_price: 100,
        short_descp: 'A little about Product One'
      }
    },
    {
      product: {
        discount_price: 199,
        product_thumbnail: 'https://images.unsplash.com/photo-1570913149827-d2ac84ab3f9a?ixlib=rb-4.0.3&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=100&q=80',
        product_name: 'Product Two',
        product_qty: 0,
        selling_price: 200,
        short_descp: 'A little about Product Two'
      }
    }
  ]
}

$('#compareQty').text(response.compareQty);

const getItemDisplayForRowKey = (item, key) => {
  if (key === 'product_qty') {
    return item.product.product_qty > 0 ? 'In Stock' : 'Stock Out';
  } else if (key === 'product_thumbnail') {
    return `<img src = "${item.product.product_thumbnail}">`;
  } else if (key === 'selling_price') {
    return item.product.discount_price || item.product.selling_price;
  }
  
  return item.product[key];
}

const rowHeading = {
  product_thumbnail: '',
  product_name: 'Name',
  product_qty: 'Quantity',
  selling_price: 'Price',
  short_descp: 'Description'
};

const html = ['product_thumbnail', 'product_name', 'product_qty', 'selling_price', 'short_descp'].map(rowKey => {
  return `
    <tr>
      <td>${rowHeading[rowKey]}</td>
      ${response.compare.map(item => {
        return `<td>${getItemDisplayForRowKey(item, rowKey)}</td>`
      })}
    </tr>
  `
});

$('#compare').html(html);
table {
  border: 1px solid black;
  border-collapse: collapse;
}

tr {
  border: 1px solid black;
}
<script src = "https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class = "page-header breadcrumb-wrap">
  <div class = "container">
    <div class = "breadcrumb">
      <a href = "index.html" rel = "nofollow"><i class = "fi-rs-home mr-5"></i>Home</a>
      <span></span> Compare
    </div>
  </div>
</div>
<div class = "container mb-80 mt-50">
  <div class = "row">
    <div class = "col-xl-10 col-lg-12 m-auto">
      <h1 class = "heading-2 mb-10">Products Compare</h1>
      <h6 class = "text-body mb-40">There are products to compare</h6>
      <div class = "table-responsive">
        <table class = "table text-center table-compare">

          <tbody id = "compare"></tbody>

        </table>
      </div>
    </div>
  </div>
</div>

Большое спасибо за ваш отличный ответ. Могу ли я применить его к моему существующему коду, или я должен пойти в соответствии с вашим кодом.

Muhammad Yaseen 17.04.2023 11:18

@MuhammadYaseen: Намерение состояло в том, чтобы вы заменили то, что находится в вашем обработчике success, кодом выше, чтобы иметь правильную структуру HTML. После этого вам нужно будет добавить свои классы CSS.

76484 17.04.2023 12:51

Спасибо, это работает, но я хочу добавить кнопку удаления в таблицу, которая выглядит следующим образом, где я могу разместить код; <td class = "row_remove"> <a type = "submit" class = "text-muted" id = "${value.id}" onclick = "compareRemove(this.id)"><i class = "fi- rs-trash mr-5"></i> <span>Удалить</span> </a> </td>

Muhammad Yaseen 18.04.2023 16:13

@MuhammadYaseen Что делает функция compareRemove?

76484 18.04.2023 17:15

Спасибо за ответ. Он удаляет отдельный продукт из списка сравнения.

Muhammad Yaseen 18.04.2023 17:39

@MuhammadYaseen: Спасибо. Приводит ли это к совершенно новому HTTP-запросу или нам нужно повторно отображать таблицу во внешнем интерфейсе?

76484 18.04.2023 17:48

@MuhammadYaseen: пример удаления элемента и повторного рендеринга во внешнем интерфейсе можно найти здесь: jsfiddle.net/76484/12yebcxa

76484 18.04.2023 19:10

Спасибо за ваш ответ. В скрипке он работает нормально, но в моем коде, когда я нажимаю кнопку «Удалить», он не удаляет элемент, а добавляет больше элементов, потому что не может получить идентификатор продукта, необходимый для удаления. Кроме того, я обновил master_dashboard.blade.php и добавил функцию compareRemove, которую я добавил в свой пост, который вы можете найти выше.

Muhammad Yaseen 19.04.2023 12:19

@MuhammadYaseen: если вы повторно извлекаете свои элементы после удаления (вызывая compare), вам не нужна эта логика, чтобы найти индекс для удаления - элемент будет удален в следующем ответе на выборку. Однако вам нужно будет переместить обработчик click за пределы compare, иначе он будет неоднократно применяться при вызове compare. jsfiddle.net/76484/p3b08ejL является примером, но он не будет удалять элементы, потому что у него нет API удаления.

76484 19.04.2023 17:54

Спасибо за ваш ответ. Я обновил master_dashboard.blade.php, и теперь функция удаления работает нормально. Поскольку мы сопоставляем элементы, я не могу настроить таргетинг на данные конкретной ячейки таблицы, поскольку все содержится в одном элементе «td». Например, я хочу добавить class = "stock-status in-stock mb-0" для "td", содержащего текст "In Stock" и другие стили для отдельных элементов td. Как мне этого добиться?

Muhammad Yaseen 20.04.2023 07:21

@MuhammadYaseen: вы можете переместить рендеринг <td> в функцию сопоставления и добавить туда логику для применения имен классов. Пример: jsfiddle.net/76484/uopxfsrg

76484 20.04.2023 13:14

Большое спасибо за Ваш ответ. Я получаю сообщение об ошибке «Неопределенная переменная $id», которую я передал в соответствующем блоке else if в обновленном блейд-файле master_dashboard, который выглядит следующим образом: else if (key === 'product_name') { return <div>< h6><a href = "{{ url('product/details/'.$product->id.'/'.$product->product_sl‌​ug) }}" class = "text-heading">${item .product.product_name}</a></h6></‌​div>; } и я поместил php-код в тот же файл, что и; @php $product = App\Models\Product::findOrFail($id); $id = $product->id /@endphp . Кроме того, я добавил функцию маршрута и контроллера, см.

Muhammad Yaseen 22.04.2023 07:53

@MuhammadYaseen: вы не можете выполнять PHP-код в JavaScript. Если вам нужен URL-адрес каждого продукта, вам нужно либо добавить его к каждому продукту в ответе сервера, чтобы он был доступен для вашего JavaScript, либо вы могли бы просто создать его на стороне клиента, используя id и product_slug, как я сделал здесь: jsfiddle.net/76484/yhqt90de

76484 22.04.2023 15:17

Спасибо за ваш ответ, и я получаю какую-то ошибку в моем коде, которая выглядит следующим образом: сравните: 1609 Uncaught TypeError: Не удается прочитать свойства неопределенного (чтение «длина»), и код выглядит следующим образом; if (!items.length) { $('.table-compare').replaceWith('<p>Нечего сравнивать</p>'); } Я не могу понять, где я ошибся.

Muhammad Yaseen 22.04.2023 17:52

@MuhammadYaseen: Это будет означать, что ваш объект response не содержит свойства compare (которое мы присваиваем переменной items). Вам нужно будет проверить свой объект response, чтобы увидеть, что он содержит. Код ожидает свойство compare, значением которого является массив.

76484 22.04.2023 18:12

Спасибо за ваш ответ. Я проверил ответ с помощью console.info(response); сразу после успеха: функция (ответ) { и я получил результат следующим образом; 0: {id: 19, user_id: 3, product_id: 8, created_at: '2023-04-22T06:46:10.000000Z', updated_at: null, …} длина: 6, но все равно показывает ту же ошибку, и я не т видеть продукты на экране.

Muhammad Yaseen 22.04.2023 20:05

@MuhammadYaseen: Изменился ли ответ? Он больше не содержит свойство compare? Я не уверен, что вы меняете ответ сервера, но если вы измените форму этого объекта, код на стороне клиента необходимо будет обновить, чтобы отразить эти изменения. Предполагая, что ответ представляет собой плоский массив объектов продукта, код на стороне клиента должен выглядеть так: jsfiddle.net/76484/rvLe7h9q

76484 22.04.2023 20:10

Спасибо за ответ. Нет, ответ не изменился, и я проверил код следующим образом; успех: функция (ответ) { const items = response.compare; console.info(элементы); if (!items.length) { $('.table-compare').replaceWith('<p>Нечего сравнивать</p>'); } и теперь я получаю значение undefined.

Muhammad Yaseen 22.04.2023 20:17

@MuhammadYaseen Каков ответ? Пожалуйста, добавьте его в свой пост.

76484 23.04.2023 01:07

Спасибо за ваш ответ. Эта проблема решена, но теперь мне нужно перебрать все строки таблицы следующего элемента, который является <td>${rowHeading[rowKey]}</td>, и добавить определенные классы к каждому из значений rowHeading. Для значения «Имя» ключа product_name добавьте class = "pr_title" для достижения следующего <tr class = "pr_title"></tr> и аналогично для значения «Цена» ключа Selling_price добавьте class = "pr_title" для достижения следующего <tr class = "pr_price"></tr>и т. д. для других строк таблицы соответственно.

Muhammad Yaseen 23.04.2023 06:06

Давайте продолжим обсуждение в чате.

76484 23.04.2023 13:39

Другие вопросы по теме