You are here:  » prices.php grouping by merchant + priceasc


prices.php grouping by merchant + priceasc

Submitted by Erik on Sun, 2020-02-02 22:22 in

Hi David,

I removed the dedupe filter for merchants since a merchant can have multiple products by sizes listed. What I am wondering is if you have any ideal recommendation for querying prices.php on the product page so I can set up a grouped section for each merchant where I would code in an accordion to expand.

Right now it's like:

<?php
 
foreach($prices["products"] as $product): 
?>

I'm wondering if there's a smooth way to (1) sort by merchant with best price, (2) for each merchant show the best price and (3) have a subsection with all prices to expand.

/Erik

Submitted by support on Mon, 2020-02-03 11:22

Hi Erik,

Here's a complete html/prices.php with prices grouped by merchant and all but the first price for each merchant initially hidden. See the <button> added in place of the empty heading above the Visit Store column for the reveal code to use as required...

<?php
  $prices_showVoucherCodes = FALSE;
  foreach($prices["products"] as $product)
  {
    if ($product["voucher_code"])
    {
      $prices_showVoucherCodes = TRUE;
    }
  }
?>
<div class='row pt_pr'>
  <div class='small-12 columns'>
    <table>
      <thead>
        <tr>
          <th><?php print translate("Stockist"); ?></th>
          <th class='hide-for-small-only'><?php print translate("Catalogue Product Name"); ?></th>
          <th><?php print translate("Price"); ?></th>
          <?php if ($prices_showVoucherCodes): ?>
            <th><?php print translate("Voucher Code"); ?></th>
          <?php endif; ?>
          <th><button type='button' class='tiny radius' style='margin-bottom:0;' onclick='$(".priceHidden").show();'>Show All Prices</button></th>
        </tr>
      </thead>
      <tbody>
        <?php
          $productsByMerchant = array();
          foreach($prices["products"] as $product)
          {
            if (!isset($productsByMerchant[$product["merchant"]]))
            {
              $productsByMerchant[$product["merchant"]] = array();
            }
            $productsByMerchant[$product["merchant"]][] = $product;
          }
          foreach($productsByMerchant as $merchant => $products)
          {
            foreach($products as $k => $product)
            {
            ?>
            <tr <?php print ($k?"class='priceHidden' style='display:none;'":"");?> >
              <?php if (file_exists("logos/".$product["merchant"].$config_logoExtension)): ?>
                <td class='pt_pr_mlogo'><a href='<?php print tapestry_buyURL($product); ?>'><img alt='<?php print htmlspecialchars($product["merchant"],ENT_QUOTES,$config_charset); ?> <?php print translate("Logo"); ?>' src='<?php print $config_baseHREF."logos/".str_replace(" ","%20",$product["merchant"]).$config_logoExtension?>' /></a></td>
              <?php else: ?>
                <td class='pt_pr_mtext'><a href='<?php print tapestry_buyURL($product); ?>'><?php print $product["merchant"]; ?></a></td>
              <?php endif; ?>
              <td class='hide-for-small-only'><?php print $product["original_name"]; ?></td>
              <td class='pt_pr_price'><?php print tapestry_price($product["price"]); ?></td>
              <?php if ($prices_showVoucherCodes): ?>
                <td class='pt_pr_vouchercode'><?php print $product["voucher_code"]; ?></td>
              <?php endif; ?>
              <td class='pt_pr_visit'><a class='button tiny radius success' href='<?php print tapestry_buyURL($product); ?>'><?php print translate("Visit Store"); ?></a></td>
            </tr>
            <?php
            }
          }
        ?>
      </tbody>
    </table>
  </div>
</div>

Cheers,
David.
--
PriceTapestry.com

Submitted by Erik on Mon, 2020-02-10 21:10

This is great, thank you David it gave me something to work off of :)

/Erik

Submitted by Erik on Wed, 2020-02-19 20:06

Hi David,

As a follow up here, I'm wondering if you have any recommendation for how I could tweak this code to group the products by merchant?

I would like to place all of each merchant's products into one div, having the best price showing and having a button there to expand the merchant's products.

To set up this div, would I then place the opening tag in between these two?

foreach($productsByMerchant as $merchant => $products)
          {

[HERE]

            foreach($products as $k => $product)
            {

The only thing I'm wondering is just how your for loop works to works to sole out all after the first one to have this:
$k?"class='priceHidden' style='display:none;'":"");

Submitted by support on Thu, 2020-02-20 15:39

Hi Erik,

A div surrounding table rows would be invalid markup however the merchant name can be used as part of the row ID (using tapestry_hyphenate() function to make valid as part of an HTML5 element ID) and then a link to toggle the hidden elements for that merchant shown below the first price (using Foundation -loop icon to indicate toggle functionality) - something like this;

<?php
  $prices_showVoucherCodes = FALSE;
  foreach($prices["products"] as $product)
  {
    if ($product["voucher_code"])
    {
      $prices_showVoucherCodes = TRUE;
    }
  }
?>
<div class='row pt_pr'>
  <div class='small-12 columns'>
    <table>
      <thead>
        <tr>
          <th><?php print translate("Stockist"); ?></th>
          <th class='hide-for-small-only'><?php print translate("Catalogue Product Name"); ?></th>
          <th><?php print translate("Price"); ?></th>
          <?php if ($prices_showVoucherCodes): ?>
            <th><?php print translate("Voucher Code"); ?></th>
          <?php endif; ?>
          <th>&nbsp;</th>
        </tr>
      </thead>
      <tbody>
        <?php
          $productsByMerchant = array();
          foreach($prices["products"] as $product)
          {
            if (!isset($productsByMerchant[$product["merchant"]]))
            {
              $productsByMerchant[$product["merchant"]] = array();
            }
            $productsByMerchant[$product["merchant"]][] = $product;
          }
          foreach($productsByMerchant as $merchant => $products)
          {
            foreach($products as $k => $product)
            {
            ?>
            <tr <?php print ($k?"class='priceHidden_".tapestry_hyphenate($merchant)."' style='display:none;'":"");?> >
              <?php if (file_exists("logos/".$product["merchant"].$config_logoExtension)): ?>
                <td class='pt_pr_mlogo'><a href='<?php print tapestry_buyURL($product); ?>'><img alt='<?php print htmlspecialchars($product["merchant"],ENT_QUOTES,$config_charset); ?> <?php print translate("Logo"); ?>' src='<?php print $config_baseHREF."logos/".str_replace(" ","%20",$product["merchant"]).$config_logoExtension?>' /></a></td>
              <?php else: ?>
                <td class='pt_pr_mtext'><a href='<?php print tapestry_buyURL($product); ?>'><?php print $product["merchant"]; ?></a></td>
              <?php endif; ?>
              <td class='hide-for-small-only'><?php print $product["original_name"]; ?></td>
              <td class='pt_pr_price'><?php print tapestry_price($product["price"]); ?>
                <?php if (!$k && count($products)): ?>
                  <br />&nbsp;<a onclick='$(".priceHidden_<?php print tapestry_hyphenate($merchant); ?>").toggle();' style='cursor:pointer;'><i class='fi-loop'></i> <?php print (count($products)-1); ?> more</a>&nbsp;
                <?php endif; ?>
              </td>
              <?php if ($prices_showVoucherCodes): ?>
                <td class='pt_pr_vouchercode'><?php print $product["voucher_code"]; ?></td>
              <?php endif; ?>
              <td class='pt_pr_visit'><a class='button tiny radius success' href='<?php print tapestry_buyURL($product); ?>'><?php print translate("Visit Store"); ?></a></td>
            </tr>
            <?php
            }
          }
        ?>
      </tbody>
    </table>
  </div>
</div>

Toggle link could go under merchant name of course if you prefer - anywhere within the loop with $merchant in context...

Cheers,
David.
--
PriceTapestry.com

Submitted by Erik on Mon, 2020-02-24 21:48

Thanks David, this was a great improvement!

Best,
Erik