News:

Looking for documentation? Take a look on our wiki

Main Menu

Can I add a custom field in the 'short by' list?

Started by panoss, September 06, 2016, 19:31:14 PM

Previous topic - Next topic

GJC Web Design

Congrats...

You could post your code here if u want to..
GJC Web Design
VirtueMart and Joomla Developers - php developers https://www.gjcwebdesign.com
VM4 AusPost Shipping Plugin - e-go Shipping Plugin - VM4 Postcode Shipping Plugin - Radius Shipping Plugin - VM4 NZ Post Shipping Plugin - AusPost Estimator
Samport Payment Plugin - EcomMerchant Payment Plugin - ccBill payment Plugin
VM2 Product Lock Extension - VM2 Preconfig Adresses Extension - TaxCloud USA Taxes Plugin - Virtuemart  Product Review Component
https://extensions.joomla.org/profile/profile/details/67210
Contact for any VirtueMart or Joomla development & customisation

panoss

Thanks, I will post it but I 'll have to 'fix' it so that it will be understandable.
Coming soon (this reminds of something... ;D), in the next 3 days.
Virtuemart 3.2.4 on Joomla! 3.8.0

Milbo

Btw, you should also check the vm3.0.17.6

and we cannot add all for sorting, that would be too much in most cases. Then you would need a config for that and it would slow down a lot shops.
Should I fix your bug, please support the VirtueMart project and become a member
______________________________________
Extensions approved by the core team: http://extensions.virtuemart.net/

panoss

Quote from: Milbo on September 09, 2016, 13:25:59 PM
Btw, you should also check the vm3.0.17.6
Milbo what do you mean?
I 'm already using Virtuemart 3.0.17.6 (on Joomla 3.62).
Virtuemart 3.2.4 on Joomla! 3.8.0

Milbo

Should I fix your bug, please support the VirtueMart project and become a member
______________________________________
Extensions approved by the core team: http://extensions.virtuemart.net/

PRO

you can actually make your own sortby code using the same native code, & add your parameters

I have 3 sort by boxes on some of my categories.

You can also in your sublayouts/products.php

Loop through the customs for the value

panoss

#21
Ok, this is the code I promised.
It creates 2 list boxes, for Color and Size, and we order by them.
Color and Size are two custom fields we create.
I hope you won't have any trouble, I have tested exactly as I desrcibe it.

1. Install joomla - VirtueMart Bundle. This firstly installs joomla.
2. After installing joomla, you will be transfered to the screen for VirtueMarts 's installation, choose 'Reset all tables and install sample data'.
3. install my plugin (the attachment, sorter.zip) (the attachment).
After installing it, go to Extensions>Plugins> find plugin 'VMCustom - sorter' and enable it.

4. File \administrator\components\com_virtuemart\models\product.php
Line 650 is like this:
if ($this->searchplugin !== 0) {
Replace with:
      $this->searchplugin = true;
if ($this->searchplugin !== 0) {

...and save.         

Same file, line   222:
$this->__state_set = true;
Replace with:
      
$this->__state_set = true;
               
JPluginHelper::importPlugin('vmcustom');
$dispatcher = JDispatcher::getInstance();
$dispatcher->trigger('plgVmPopulateState', array(&$app));

...and save.

5. Override template
Create folder:  \templates\ vmbeez5\html\com_virtuemart\category .
In this folder copy file: \components\com_virtuemart\views\category\tmpl\default.php   

So now, we shall modify the override (\templates\vmbeez5\html\com_virtuemart\category\default.php).


    At line 89-91:
       <div class="vm-pagination vm-pagination-top">
<?php echo $this->vmPagination->getPagesLinks (); ?>
<span class="vm-page-counter"><?php echo $this->vmPagination->getPagesCounter (); ?></span>
</div>

   

    Replace with:
      <div class="vm-pagination vm-pagination-top">
                        <?php echo $this->vmPagination->getPagesLinks(); ?>
                        <span class="vm-page-counter"><?php echo $this->vmPagination->getPagesCounter(); ?></span>
                        <form method="post" name="ordering_form" autocomplete="on" >   
                           
                            <div class="custom_fields_ordering">
                               
                                <div class="ordering-title">
                                    <label>-</label>
                                    <?php echo vmText::_('ORDERING'); ?>
                                </div>                               
                                <div>
                                <label for="custom_color_ordering"><?php echo jText::_('Color'); ?></label>
                                <select id="custom_color_ordering" name="custom_color_ordering" class="select_ordering" value="<?php echo $custom_color_ordering?>">
                                   <option value=""></option>
                                   <option value="ASC" <?php if($composite_weight_ordering=='ASC'){echo ' selected="selected"';} ?>><?php echo jText::_('ASC'); ?></option>
                                   <option value="DESC" <?php if($composite_weight_ordering=='DESC'){echo ' selected="selected"';} ?>><?php echo jText::_('DESC'); ?></option>
                                </select>
                                </div>

                                <div>
                                <label for="custom_size_ordering"><?php echo jText::_('Size'); ?></label>
                                <select id="custom_size_ordering" name="custom_size_ordering" class="select_ordering">
                                   <option value=""></option>
                                   <option value="ASC" <?php if($custom_size_ordering=='ASC'){echo ' selected="selected"';} ?>><?php echo jText::_('ASC'); ?></option>
                                   <option value="DESC" <?php if($custom_size_ordering=='DESC'){echo ' selected="selected"';} ?>><?php echo jText::_('DESC'); ?></option>                           
                                </select>
                                </div>       
                               
                                 <div>
                                     <label>-</label>                                     
                                     <button>ok</span></button>
                                </div>
                               
                            </div>
                           
                        </form>
                    </div>


Line 22, of the same file, is empty:
Paste this code:      
$custom_color_ordering = JFactory::getApplication()->getUserState('com_virtuemart.mycustomfields.custom_color_ordering');
$custom_size_ordering = JFactory::getApplication()->getUserState('com_virtuemart.mycustomfields.custom_color_ordering');     

...and save.



6.With phpmyadmin create a function (it's from http://stackoverflow.com/questions/153633/natural-sort-in-mysql) in your database: in phpmyadmin select your database, Click on 'SQL' tab where you will execute the query that creates the function in your database.
In the text box paste the code:

DROP FUNCTION IF EXISTS `udf_FirstNumberPos`;
DELIMITER ;;
CREATE FUNCTION `udf_FirstNumberPos` (`instring` varchar(4000))
RETURNS int
LANGUAGE SQL
DETERMINISTIC
NO SQL
SQL SECURITY INVOKER
BEGIN
    DECLARE position int;
    DECLARE tmp_position int;
    SET position = 5000;
    SET tmp_position = LOCATE('0', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
    SET tmp_position = LOCATE('1', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
    SET tmp_position = LOCATE('2', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
    SET tmp_position = LOCATE('3', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
    SET tmp_position = LOCATE('4', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
    SET tmp_position = LOCATE('5', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
    SET tmp_position = LOCATE('6', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
    SET tmp_position = LOCATE('7', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
    SET tmp_position = LOCATE('8', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;
    SET tmp_position = LOCATE('9', instring); IF (tmp_position > 0 AND tmp_position < position) THEN SET position = tmp_position; END IF;

    IF (position = 5000) THEN RETURN 0; END IF;
    RETURN position;
END
;;

DROP FUNCTION IF EXISTS `udf_NaturalSortFormat`;
DELIMITER ;;
CREATE FUNCTION `udf_NaturalSortFormat` (`instring` varchar(4000), `numberLength` int, `sameOrderChars` char(50))
RETURNS varchar(4000)
LANGUAGE SQL
DETERMINISTIC
NO SQL
SQL SECURITY INVOKER
BEGIN
    DECLARE sortString varchar(4000);
    DECLARE numStartIndex int;
    DECLARE numEndIndex int;
    DECLARE padLength int;
    DECLARE totalPadLength int;
    DECLARE i int;
    DECLARE sameOrderCharsLen int;

    SET totalPadLength = 0;
    SET instring = TRIM(instring);
    SET sortString = instring;
    SET numStartIndex = udf_FirstNumberPos(instring);
    SET numEndIndex = 0;
    SET i = 1;
    SET sameOrderCharsLen = CHAR_LENGTH(sameOrderChars);

    WHILE (i <= sameOrderCharsLen) DO
        SET sortString = REPLACE(sortString, SUBSTRING(sameOrderChars, i, 1), ' ');
        SET i = i + 1;
    END WHILE;

    WHILE (numStartIndex <> 0) DO
        SET numStartIndex = numStartIndex + numEndIndex;
        SET numEndIndex = numStartIndex;

        WHILE (udf_FirstNumberPos(SUBSTRING(instring, numEndIndex, 1)) = 1) DO
            SET numEndIndex = numEndIndex + 1;
        END WHILE;

        SET numEndIndex = numEndIndex - 1;

        SET padLength = numberLength - (numEndIndex + 1 - numStartIndex);

        IF padLength < 0 THEN
            SET padLength = 0;
        END IF;

        SET sortString = INSERT(sortString, numStartIndex + totalPadLength, 0, REPEAT('0', padLength));

        SET totalPadLength = totalPadLength + padLength;
        SET numStartIndex = udf_FirstNumberPos(RIGHT(instring, CHAR_LENGTH(instring) - numEndIndex));
    END WHILE;

    RETURN sortString;
END
;;



At VirtueMart>Products>Custom fields,we create 2 custom fields:
7. Create custom field Color:
Custom Field Type: String
Title: Color
Cart Attribute: Yes
Default value: Red;Green;Blue
Layout position: addtocart
Is a list? Yes
Save & Close.

8. Create custom field Size:
Custom Field Type: String
Title: Size
Cart Attribute: Yes
Default value: Small;Medium;Large;Extra Large
Layout position: addtocart
Is a list? Yes
Save & Close.

9. At VirtueMart>PRODUCTS>Products: we edit the products of the category 'Wear' (it's has 5 products only), we assign to each product a value for their new custom fields, Color and Size:
In tab 'Custom Fields', in 'Custom Field Type' we select  'Color', so at the bottom of the screnn we see 'String Color' an a list box.
We select the color we want and save.
The same for field 'Size'.

So we set Color and Size For as many products we want.

10. Testing: we go to to the shop 's front page, choose category 'Wear', choose 'ASC' for the list box 'color' and click 'OK'!


Virtuemart 3.2.4 on Joomla! 3.8.0

panoss

#22
Or another much simpler way:
1. Install the bundle with joomla db prefix='sftlr_'.
2. Install and enable my plugin (the attachment in my previous post).
3. Delete all tables of the db.
4. Copy - paste the SQL code (from this post's attachment) in phpmydamin SQL tab (used for Running queries), and run it (click 'go').

5. Test it: go to to the shop 's front page, choose category 'Wear', choose 'ASC' for the list box 'color' and click 'OK'!
Virtuemart 3.2.4 on Joomla! 3.8.0

panoss

Quote from: PRO on September 12, 2016, 16:44:27 PM
you can actually make your own sortby code using the same native code, & add your parameters
Which code exactly are you refering to?
In model 'product' function 'sortSearchListQuery'?
Or elsewhere?
Virtuemart 3.2.4 on Joomla! 3.8.0

PRO

#24
Quote from: panoss on September 16, 2016, 13:40:26 PM
Quote from: PRO on September 12, 2016, 16:44:27 PM
you can actually make your own sortby code using the same native code, & add your parameters
Which code exactly are you refering to?
In model 'product' function 'sortSearchListQuery'?
Or elsewhere?

I do it in my template functions file
I also have a component that I store extra sort by box info
If you notice the function below, I just build the link with Jroute
You can also build your own link & add a parameter to the url. (then in your products.php sublayout loop through the products you want to filter by in the url)

<?php function cSort($free=1){
$jinput = JFactory::getApplication()->input;
$searchnone=$jinput->get('keyword',0);
$ccat = $jinput->getInt('virtuemart_category_id', 0);
$item = $jinput->getInt('Itemid', 0);
$requestorder=$jinput->get('orderby',0);
$descorder=$jinput->get('dir',0);
$priceurl=JRoute::_('index.php?option=com_virtuemart&view=category&virtuemart_category_id='.$ccat.'&Itemid='.$item.'&orderby=product_price');
$highpriceurl=JRoute::_('index.php?option=com_virtuemart&view=category&virtuemart_category_id='.$ccat.'&Itemid='.$item.'&dir=DESC&orderby=product_price');
$freeshipurl=JRoute::_('index.php?option=com_virtuemart&view=category&virtuemart_category_id='.$ccat.'&Itemid='.$item.'&orderby=product_weight');
$bestsalesurl=JRoute::_('index.php?option=com_virtuemart&view=category&virtuemart_category_id='.$ccat.'&Itemid='.$item.'&dir=DESC&orderby=product_sales');
$cathomeurl=JRoute::_('index.php?option=com_virtuemart&view=category&virtuemart_category_id='.$ccat.'&Itemid='.$item);
$html = '';
$html.='<div class="orderby-displaynumber width20 min175">';
$html.='   <div class="floatleft vm-order-list">';
$html.='      <div class="orderlistcontainer"><div class="title baby shadow bblack min175 center">Sort by <img src="images/down.gif" alt="Sort" /></div>';
$html.='      <div class="orderlist min175"><div>';
$html.='<div><a rel="nofollow" title="Sort By Lowest Price" href="'.$priceurl.'">Lowest Price</a></div>';
$html.='<div class="btop"><a rel="nofollow" title="Sort By Highest Price" href="'.$highpriceurl .'">Highest Price</a></div>';
if ($free==1){
$html.='<div class="btop"><a rel="nofollow" title="Sort By Free Shipping" href="'.$freeshipurl .'">Free Shipping</a></div>';
}
$html.='<div class="btop"><a rel="nofollow" title="Sort By Best Selling" href="'.$bestsalesurl .'">Best Selling</a></div>';
$html.='</div></div></div></div></div>';
return $html;
}
?>


Then, I can add additional dropdown boxes like this


<?php function dropSort($sortstring,$title='Sort By'){
if (!empty($sortstring) or (!empty($tlink))){
$infolinks= explode(',', $sortstring);
$html = '';
$html.='<div class="orderby-displaynumber width20 min175">';
$html.='   <div class="floatleft vm-order-list">';
$html.='<div class="orderlistcontainer"><div class="title baby shadow bblack min175 center">'.$title.' <img src="images/down.gif" alt="Sort" /></div>';
$html.='<div class="orderlist"><div>';
$i=1;
foreach ($infolinks as $links){
      $link = strstr($links,"|") ;
      $link=str_replace( '|', '', $link );
      $linkanchor=str_replace( $link, '', $links );
      $linkanchor=str_replace( '|', '', $linkanchor );
      if (!empty($linkanchor)){
   $html.='<div class="i'.$i.'" style="padding-top:10px;"><a title="'.$linkanchor.'" href="'.$link.'">'.$linkanchor.'</a></div>';
      }
      $i++;}
$html.='</div></div></div></div></div>';
return $html;
}
}
?>


I store the dropdown box in this format (comma seperated)

Anchor | Link,Anchor|Link



See here 
banquettablespro              .com/round-banquet-tables

You can see the 4 sort boxes using the same Jquery code & css.
I actually link to related categories & joomla articles with it

I store the related categories via cat id.
then use this function to make the dropdown

<?php function loadCats($ids,$title='Sort By'){
$ids=explode(',', $ids);
$db = JFactory::getDbo();
$query = $db->getQuery(true);
$query->select('category_name,virtuemart_category_id');
$query->from($db->quoteName('#__virtuemart_categories_en_gb'));
//$query->where($db->quoteName('virtuemart_category_id')." = ".$db->quote($ids) );
$db->setQuery($query);
$rows = $db->loadAssocList();
foreach ($rows as $row){
if (in_array($row['virtuemart_category_id'], $ids)){
  $string.=$row['category_name'].'|'.JRoute::_('index.php?option=com_virtuemart&view=category&virtuemart_category_id='.$row['virtuemart_category_id'].'&Itemid='.$item).',';
  }
}
return dropSort($string,$title);
}?>


I store additional info in a separate component.
BUT you can actually store it in your category description, but you would just have to parse it out.
So you could store your description normal.
Then separate your extra custom stuff with some certain characters etc. So you can grab it with your code