Sprint 62 -Gebotsliste

base.html.twig

<section id="projectBids" class="contentSection">
    <div class="grid-narrow1">
        <h2 class="hl-2">{{ 'projectBids.bids'|trans }}</h2>
    </div>
    <div class="js-projectBids projectDetails--bidLoadingSpace"></div>
</section>

ajax/bids.html.twig

{# table with project bids from today #}
{% set todayTitle = '<h3 class="hl-3">' ~ 'projectBids.today'|trans ~ ' - ' ~ "now"|date("d.m.Y") ~ '</h3>' %}
{% if arrayProjectBids.today is defined %}
    {# prepare values for table macro #}
    {% set arrayTodayColUsername = ['projectBids.colTitle.username'|trans, 'text'] %}
    {% set arrayTodayColBidValue = ['projectBids.colTitle.bidValue'|trans, 'number'] %}
    {% set arrayTodayColDate = ['projectBids.colTitle.time'|trans, 'date'] %}
    {% for row in arrayProjectBids.today %}
        {% set arrayTodayColUsername = arrayTodayColUsername|merge(['<a href="' ~ path('user_profile', {'userId' : row.userId}) ~'">' ~ row.username ~ '</a>']) %}
        {% set arrayTodayColBidValue = arrayTodayColBidValue|merge([row.bidValue|aux_money(0)]) %}
        {% set arrayTodayColDate = arrayTodayColDate|merge([row.timestamp|date("H:i") ~ ' ' ~ 'projectBids.oclock'|trans]) %}
    {% endfor %}
    {# project detail bid table with all prepared values #}
    {{ mod.table3Col(todayTitle, 'contentSection--subsection contentBox-bidTable', arrayTodayColUsername, arrayTodayColBidValue, arrayTodayColDate) }}
{% else %}
    <section class="contentSection--subsection">
        <div class="grid-narrow1">
            {{ todayTitle|raw }}
            <p>{{ 'projectBids.noBids'|trans }}</p>
        </div>
    </section>
{% endif %}

modules.html.twig

{#
  general 3 column table macro

  - headline (text; allowed tags: h2 and h3)
  - css (text; class on contentSection)
  - aCol1 (array; ['HEADLINE', 'TYPE', 'VALUE1', 'VALUE2', 'VALUE3', ...])
  - aCol2 (array; ['HEADLINE', 'TYPE', 'VALUE1', 'VALUE2', 'VALUE3', ...])
  - aCol3 (array; ['HEADLINE', 'TYPE', 'VALUE1', 'VALUE2', 'VALUE3', ...])

  - HEADLINE (text)
  - TYPE ("text"|"date"|"number")
  - VALUE1-N (text content)

Hint: Length of values of each aCol-Array must be equal.

#}

modules.html.twig

{% macro table3Col(headline, css, aCol1, aCol2, aCol3) %}
    {# check valid input #}
    {% if aCol1 is iterable and  aCol1|length == aCol2|length and aCol1|length == aCol3|length %}

        {% set col1Type = aCol1[1] in ['text', 'date', 'number'] ? aCol1[1] : 'text' %}
        {% set col2Type = aCol2[1] in ['text', 'date', 'number'] ? aCol2[1] : 'text' %}
        {% set col3Type = aCol3[1] in ['text', 'date', 'number'] ? aCol3[1] : 'text' %}
        {% set allowedHeadlineTags = '<h2><h3>' %}
        {% set allowedContentTags = '<a>' %}

        <section class="{{ css|default('contentSection') }}">
            <div class="grid-narrow1">
                {{ headline|striptags(allowedHeadlineTags)|raw }}
                <table class="uxTable uxTable-info">
                    <thead>
                        <tr>
                            <th class="uxTable--{{ col1Type }}">{{ aCol1[0] }}</th>
                            <th class="uxTable--{{ col2Type }}">{{ aCol2[0] }}</th>
                            <th class="uxTable--{{ col3Type }}">{{ aCol3[0] }}</th>
                        </tr>
                    </thead>
                    <tbody>
                        {% for cell in aCol1 %}
                            {% if loop.index0 > 2 %}
                                <tr>
                                    <td class="uxTable--{{ col1Type }}">{{ cell|striptags(allowedContentTags)|raw }}</td>
                                    <td class="uxTable--{{ col2Type }}">{{ aCol2[loop.index0]|striptags(allowedContentTags)|raw }}</td>
                                    <td class="uxTable--{{ col3Type }}">{{ aCol3[loop.index0]|striptags(allowedContentTags)|raw }}</td>
                                </tr>
                            {% endif %}
                        {% endfor %}
                    </tbody>
                </table>
            </div>
        </section>
    {% endif %}
{% endmacro %}

projectDetails.js

AUX.projectDetails = {

    init: function () {
        AUX.projectDetails.bids.init();
    },

    bids : {

        timestampLastOpen: Date.now(),

        config : {
            durationSkipLoadAgain: 2 * 60 * 1000, // 2min in milliseconds
            $bidsSection: $('.js-projectBids')    // sections in main area with bid tables
        },

        /**
         * initialization of bids event handler
         */
        init : function () {
            if ($('.js-bids').length > 0) {
                var positionTopBids = AUX.projectDetails.bids.config.$bidsSection.offset().top,
                    viewportHeight = window.innerHeight;

                AUX.projectDetails.bids.handleBidsClick();

                // if url was opened with hash --> load  content directly
                if (window.location.hash === '#projectBids') {
                    $('.js-bids a').trigger("click");
                }

                // add state to history to enable history back for this ajax block
                $('.js-bids').on('menuItemActive', function () {
                    if (Modernizr.history) {
                        window.history.pushState(null, null, "#projectBids");
                    }
                });

                // load content as soon as content enters the viewport
                $(window).scroll(function() {
                    // detect if "bids table"-content scroll position is above 10% from the bottom of the viewport
                    if (($(this).scrollTop() + (viewportHeight * 0.9)) > positionTopBids) {
                        AUX.projectDetails.bids.doUpdateIfNeeded();
                    }
                });
            }
        },

        /**
         * handling for click on bids link
         */
        handleBidsClick : function () {
            $('.js-bids > a').on('click', function () {
                AUX.projectDetails.bids.doUpdateIfNeeded();
            });
        },

        /**
         * if content not already loaded or last request is older than 2min
         * - update count of bids in content navigation
         * - load new bid table content if needed
         */
        doUpdateIfNeeded : function () {
            if (AUX.projectDetails.bids.config.$bidsSection.is(":empty") ||
                    (Date.now() - AUX.projectDetails.bids.timestampLastOpen) > AUX.projectDetails.bids.config.durationSkipLoadAgain) {

                AUX.projectDetails.bids.updateBidCount();
                AUX.projectDetails.bids.updateBids();

                AUX.projectDetails.bids.timestampLastOpen = Date.now();
            }
        },

       /**
        * ajax update for amount of bids
        */
       updateBidCount : function () {
            var url = $('.js-numberProjectBids').data("url"),
                method = 'post',
                data = 'ajax=1';

            $.ajax({
                type: method,
                url: url,
                data: data,
                dataType: 'json',
                success: function (json) {
                    $('.js-numberProjectBids').text('(' + json.message + ')');
                },
                error: function () {
                    $('.js-numberProjectBids').remove();
                }
            });
        },

        /**
         * ajax update of content section with bid tables
         * reload entire page, if something went wrong
         */
        updateBids : function () {
            var url = $('.js-bids a').data("url"),
                method = 'post',
                data = 'ajax=1';

            AUX.projectDetails.bids.config.$bidsSection.loadingLayer('show');

            $.ajax({
                type: method,
                url: url,
                data: data,
                dataType: 'html',
                success: function (html) {
                    // show new content
                    AUX.projectDetails.bids.config.$bidsSection.html(html);
                    AUX.projectDetails.bids.config.$bidsSection.loadingLayer('hide');
                    $("body").trigger("contentNavReInit"); // recalculate content height
                },
                error: function () {
                    // reload page (contentNav should not render navigation item again)
                    window.location.reload();
                }
            });
        }

    }

};

Gebotsliste

By phpiet

Gebotsliste

  • 438