Jump to content


Photo
- - - - -

Как модифицировать элемент цена-количество


Best Answer Flowerchek , 11 September 2016 - 21:50

Ок. Значит я сделала этот элемент :)

Правда это больше похоже на костыли и подпорки, но все же он работает.

 

Возможно кому-то это пригодиться (мало ли у кого такой же причудливый заказчик). Поэтому оставлю базовый код здесь. 

 

Добавила media/zoo/applications/jbuniversal/cart-elements/price/eclquant - свой элемент (простая xml). 

 

eclqant.php

<?php

// no direct access
defined('_JEXEC') or die('Restricted access');

/**
 * Class JBCartElementPriceProperties
 */
class JBCartElementPriceEclquant extends JBCartElementPrice
{
    /**
     * Check if element has value
     * @param array $params
     * @return bool
     */
    public function hasValue($params = array())
    {
        return $this->getValue();
    }

    /**
     * @param array $params
     * @return mixed|null|string
     */
    public function edit($params = array())
    {
        if ($layout = $this->getLayout('edit.php')) {
            return self::renderEditLayout($layout, array(
                'value' => $this->get('value')
            ));
        }

        return null;
    }

    /**
     * @param array $params
     * @return array|mixed|null|string|void
     */
    public function render($params = array())
    {
        if ($layout = $this->getLayout()) {
            return self::renderLayout($layout, array(
                'value' => $this->getValue()
            ));
        }
    }
}

tmpl/eclquant.php

<?php

// no direct access
defined('_JEXEC') or die('Restricted access');


$value = trim($value);
?>
<?php if ($value): ?>
    <input class="jbprice-eclquant-input jbaddprice" data-quant="<?php echo $value ?>" value="<?php echo $value ?>"/>
    <input type="hidden" value="<?php echo $value; ?>" />
<?php endif; ?>

tmpl/edit.php

<?php

// no direct access
defined('_JEXEC') or die('Restricted access');

echo $this->_jbhtml->text($this->getControlName('value'), $value, $this->_jbhtml->buildAttrs(array(
    'placeholder' => JText::_('JBZOO_ELEMENT_PRICE_ECLQUANT_QUANT')
)));

?>

Самое инетерсное в assets/js/eclquant.js

;
(function ($, window, document, undefined) {

    $(window).load(function() {
        function eclquantFormat(value) {
            if (parseInt(value) !== parseFloat(value)) {
                return value.toFixed(2)
            }
            return value
        }

        $('.quantity-wrapper.jsQuantity').each(function(index, el) {
            var quantity = $(el).data('JBZooQuantity')
            var priceElement = $(el).parent().parent()
            // setup onChange value
            $(el).on('change.JBZooQuantity', function (ev, prev, cur) {
                priceElement.find('.jbprice-eclquant-input').each(
                    function (i, eclq) {
                        $(eclq).val(eclquantFormat($(eclq).data('quant') * cur))
                    }
                )
            })

            priceElement.find('.jbprice-eclquant-input').each(
                function(i, eclq) {
                    $(eclq).val(eclquantFormat($(eclq).data('quant') * quantity.getValue()))
                    // setup reverse onChange value
                    $(eclq).on('change', function(e) {
                        var quant = $(eclq).data('quant')
                        var now = $(eclq).val()
                        quantity.setValue(Math.ceil(now / quant))
                    })
                }
            )
        })
    });
})(jQuery, window, document);

Что делает элемент:

* на увеличение количества/quantity увеличивает на заданное число значение этого элемента

* при попытке изменить значение этого элемента, он вычисляет количество и обновляет значение элемента количество; 

 

Т.е. он работает как следующий паттерн. Я добавляю этот элемент к параметрам цены (штук в пачке), и устанавливают его равным 6.

Далее мне рисуется input с числом равным 6. При увеличении количества увеличивается и это значение в input (например при количестве 10, штук будет 60). При изменении значения самого элемента (скажем с 12 на 13), он автоматически округлит до ближайшего целого (т.е. количество станет 3, а значение в элементе станет 18). 

 

Аналогично я сделала и с квадратными метрами. 

 

 

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

Go to the full post


  • This topic is locked This topic is locked
8 replies to this topic

#1 Flowerchek

Flowerchek
  • JBZoo User (rus)
  • User rate: 3.2
  • posts: 44
  • topics: 14

Posted 07 September 2016 - 10:09

Здравствуйте, уважаемые разработчики JBZoo. 

 

Делаю сайт, связанный с пиломатериалами.

 

Пиломатериалы поставляются в пачках (т.е. цена указана для одной пачки). В одной пачке сколько-то досок (задается при создании товара). Доски имеют ширину и длину, в зависимости от этого можно высчитать покрываемую площадь. 

 

Нужно как-то связать три поля (input'а):

* количество пачек (всегда целое)

* всего штук

* общая площадь (м2)

 

При этом пользователь может менять любое из этих полей (количество досок, общую площадь), а в итоге округляться будет количество пачек (до большего). 

 

Например, в одной пачке 6 досок. Если пользователь вводит 7 штук, то количество пачек становиться равным 2. 

 

Подскажите, пожалуйста, как лучше реализовать этот кейс и в какую сторону смотреть.

Кажется, самое простое, это, наверное, создать для этого отдельный элемент/виджет?

Attached Thumbnails

  • index.png

  • 0

#2 SmetDenis

SmetDenis
  • Administrators
  • User rate: 139.4
  • posts: 16232
  • topics: 200

Posted 08 September 2016 - 05:42

Сделать подобную вещь коробочными средствами точно не получится.

Ближайший самый простой способ - это использовать готовые списки, а цену настроить как массу вариаций. Скорее всего этот способ для вас будет крайне не удобен.

 

К сожалению, сделать "по быстрому" подобное решение не получится.


  • 0
JBZoo v4.0 и новый чудный мир Open Source GPL
Отключайте проверку лицензий как можно скорее!



— Есть два типа людей: Кто еще не делает бекапы и кто уже делает бекапы.


#3 Flowerchek

Flowerchek
  • Topic Starter
  • JBZoo User (rus)
  • User rate: 3.2
  • posts: 44
  • topics: 14

Posted 08 September 2016 - 08:33

Спасибо. Это я уже поняла :) Но я неплохо знаю Joomla, PHP и JavaScript и могу сама что-нибудь доделать.

 

А ведь я могу создать элемент в media/zoo/applications/jbuniversal/cart-elements/price/{мой_элемент}

 

Сделать что-то на подобии элемента properties. А затем дописать для него widget на javascript? Как это лучше организовать (или куда положить), чтобы при обновлении мой элемент не удалился/затерся? Т.е. куда класть элементы для цены?

 

И еще вопрос, если где-нибудь документация по API связанная с тем как создавать widget и класс JBCartElementPrice (может примеры какие-нибудь)? Или исходный текст лучшая документация?

 

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


Edited by Flowerchek, 08 September 2016 - 08:36.

  • 3

#4 Flowerchek

Flowerchek
  • Topic Starter
  • JBZoo User (rus)
  • User rate: 3.2
  • posts: 44
  • topics: 14

Posted 08 September 2016 - 22:50

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

 

В целом идея такая -- я созданию два input, и в зависимости от изменений quantity меняю их значения и наоборот. Делать хочу через javascript. Инпуты создавать научилась (через создание отдельного элемента). Теперь хочу подключить javascript (который и будет реализовывать основную логику).

 

1) Как мне на созданный input (который рисуется через jbzoo) повесить кастомный javascript? Как я поняла это делается widget. Есть ли какая-нибудь статья/инструкция (читала -- не нашла). Может подскажите, красивый способ.

 

2) Как я могу ловить изменения элемента quantity (количества) в javascript, при этом интересует только тот quantity, который находиться в одной группе с этим элементом. Знаю, что цена как-то меняется (при это сам quantity изменяющий цену код не содержит), а значит там паттерн типа наблюдателя (listener)... Как мне еще одного наблюдателя добавить на событие onchange текущего quantity (может вы мне красивый метод подскажите).

 

К сожалению документации про javascript и jbzoo очень мало :( 

Помогите, пожалуйста.


  • 3

#5 Flowerchek

Flowerchek
  • Topic Starter
  • JBZoo User (rus)
  • User rate: 3.2
  • posts: 44
  • topics: 14

Posted 10 September 2016 - 08:47

Ответит кто-нибудь, не?


  • 0

#6 Flowerchek

Flowerchek
  • Topic Starter
  • JBZoo User (rus)
  • User rate: 3.2
  • posts: 44
  • topics: 14

Posted 10 September 2016 - 14:22

Ребята! Подскажите мне, пожалуйста, как в javascript можной поймать изменение quantity?

 

Я нашла, assets/js/cart/cart.js как это делается в виджете. Но как подключить и создать свой виджет документации нет :( Подскажите хотя бы, как ловить изменения quantity и по возможности, как для этого же quantity можно установить новое значение.

 

Вообщем, чтобы было понятно, я сейчас делаю так:

;
(function ($, window, document, undefined) {

    $(window).load(function() {
        $('.quantity-wrapper.jsQuantity').each(function(i, el) {
            $(el).data('JBZooQuantity').options.onChange = function() {
                // my staff here, depend on quantity change
            }
        })
    });
})(jQuery, window, document);

Заранее благодарю. 


Edited by Flowerchek, 10 September 2016 - 16:13.

  • 2

#7 Flowerchek

Flowerchek
  • Topic Starter
  • JBZoo User (rus)
  • User rate: 3.2
  • posts: 44
  • topics: 14

Posted 11 September 2016 - 21:50   Best Answer

*
POPULAR

Ок. Значит я сделала этот элемент :)

Правда это больше похоже на костыли и подпорки, но все же он работает.

 

Возможно кому-то это пригодиться (мало ли у кого такой же причудливый заказчик). Поэтому оставлю базовый код здесь. 

 

Добавила media/zoo/applications/jbuniversal/cart-elements/price/eclquant - свой элемент (простая xml). 

 

eclqant.php

<?php

// no direct access
defined('_JEXEC') or die('Restricted access');

/**
 * Class JBCartElementPriceProperties
 */
class JBCartElementPriceEclquant extends JBCartElementPrice
{
    /**
     * Check if element has value
     * @param array $params
     * @return bool
     */
    public function hasValue($params = array())
    {
        return $this->getValue();
    }

    /**
     * @param array $params
     * @return mixed|null|string
     */
    public function edit($params = array())
    {
        if ($layout = $this->getLayout('edit.php')) {
            return self::renderEditLayout($layout, array(
                'value' => $this->get('value')
            ));
        }

        return null;
    }

    /**
     * @param array $params
     * @return array|mixed|null|string|void
     */
    public function render($params = array())
    {
        if ($layout = $this->getLayout()) {
            return self::renderLayout($layout, array(
                'value' => $this->getValue()
            ));
        }
    }
}

tmpl/eclquant.php

<?php

// no direct access
defined('_JEXEC') or die('Restricted access');


$value = trim($value);
?>
<?php if ($value): ?>
    <input class="jbprice-eclquant-input jbaddprice" data-quant="<?php echo $value ?>" value="<?php echo $value ?>"/>
    <input type="hidden" value="<?php echo $value; ?>" />
<?php endif; ?>

tmpl/edit.php

<?php

// no direct access
defined('_JEXEC') or die('Restricted access');

echo $this->_jbhtml->text($this->getControlName('value'), $value, $this->_jbhtml->buildAttrs(array(
    'placeholder' => JText::_('JBZOO_ELEMENT_PRICE_ECLQUANT_QUANT')
)));

?>

Самое инетерсное в assets/js/eclquant.js

;
(function ($, window, document, undefined) {

    $(window).load(function() {
        function eclquantFormat(value) {
            if (parseInt(value) !== parseFloat(value)) {
                return value.toFixed(2)
            }
            return value
        }

        $('.quantity-wrapper.jsQuantity').each(function(index, el) {
            var quantity = $(el).data('JBZooQuantity')
            var priceElement = $(el).parent().parent()
            // setup onChange value
            $(el).on('change.JBZooQuantity', function (ev, prev, cur) {
                priceElement.find('.jbprice-eclquant-input').each(
                    function (i, eclq) {
                        $(eclq).val(eclquantFormat($(eclq).data('quant') * cur))
                    }
                )
            })

            priceElement.find('.jbprice-eclquant-input').each(
                function(i, eclq) {
                    $(eclq).val(eclquantFormat($(eclq).data('quant') * quantity.getValue()))
                    // setup reverse onChange value
                    $(eclq).on('change', function(e) {
                        var quant = $(eclq).data('quant')
                        var now = $(eclq).val()
                        quantity.setValue(Math.ceil(now / quant))
                    })
                }
            )
        })
    });
})(jQuery, window, document);

Что делает элемент:

* на увеличение количества/quantity увеличивает на заданное число значение этого элемента

* при попытке изменить значение этого элемента, он вычисляет количество и обновляет значение элемента количество; 

 

Т.е. он работает как следующий паттерн. Я добавляю этот элемент к параметрам цены (штук в пачке), и устанавливают его равным 6.

Далее мне рисуется input с числом равным 6. При увеличении количества увеличивается и это значение в input (например при количестве 10, штук будет 60). При изменении значения самого элемента (скажем с 12 на 13), он автоматически округлит до ближайшего целого (т.е. количество станет 3, а значение в элементе станет 18). 

 

Аналогично я сделала и с квадратными метрами. 

 

 

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


Edited by Flowerchek, 12 September 2016 - 17:36.

  • 6

#8 SmetDenis

SmetDenis
  • Administrators
  • User rate: 139.4
  • posts: 16232
  • topics: 200

Posted 12 September 2016 - 06:32

К сожалению документации про javascript и jbzoo очень мало  

По сути вся документация тут - https://github.com/J.../jQuery-Factory

Но она редко кому нужна, т.к обычно наши подписчики не знают JavaScript.

Советую начать с него, так все виджеты работают на этой библиотеке.

 

Я нашла, assets/js/cart/cart.js как это делается в виджете. Но как подключить и создать свой виджет документации нет Подскажите хотя бы, как ловить изменения quantity и по возможности, как для этого же quantity можно установить новое значение.

 

Плагин JBZooQuantity создает кастомное событие на главном диве. К нему можно подключится как к любому другому событию в jQuery.

 

Событие называется "change.JBZooQuantity" срабатывает классе jsQuantity

$( ".jsQuantity" ).on( "change.JBZooQuantity", function() {
    console.log(arguments);
});

 

Фабрика помогает заметно упростить возню с jQuery, например слушать событие можно так http://llfl.ru/skdacd

При условии что jsQuantity находится внутри 

 

PS не ожидал увидеть человека, который может что-то сделать на JS :)

Извините, не отвечал из-за выходных.


  • 1
JBZoo v4.0 и новый чудный мир Open Source GPL
Отключайте проверку лицензий как можно скорее!



— Есть два типа людей: Кто еще не делает бекапы и кто уже делает бекапы.


#9 Flowerchek

Flowerchek
  • Topic Starter
  • JBZoo User (rus)
  • User rate: 3.2
  • posts: 44
  • topics: 14

Posted 12 September 2016 - 17:35

Отлично, именно эту магию вида 

'change.JBZooQuantity .jsQuantity'

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

 

Собственно, код своего элемента обновила (в том числе и в предыдущем комментарии). 

 

Тему помечаю, как разрешенную. Спасибо. 


  • 3




Click to return to top of page in style!