Arhn - архитектура программирования

Использовать элемент выбора без выпадающего списка

В настоящее время у меня есть страница с ценами на моем веб-сайте, которая использует html-элементы <select> и <option>, чтобы пользователи могли выбрать тарифный план.

Это код для раскрывающегося списка выбора плана:

<select name="plan" class="form-control" id="subscription-plan">
    @foreach ($plans as $key => $plan)
        <option value="{{ $key }}">{{ $plan }}</option>
    @endforeach
</select>

А вот как выглядит форма:

введите здесь описание изображения

Я хотел бы добавить 2 карты, содержащие информацию о плане, которую пользователь может выбрать и действовать так же, как раскрывающийся список, за исключением того, что он не является раскрывающимся. id="subscription-plan" важен, потому что он отправляет соответствующий план, выбранный пользователем, в Stripe API, который выставляет счет кредитной карте пользователя на сумму, установленную в Stripe. Кто-нибудь знает, как я мог этого добиться?

Я хотел бы сделать что-то вроде этого (но без выпадающего стиля):

<select name="plan" class="form-control" id="subscription-plan">
                @foreach ($plans as $key => $plan)
                    <option value="{{ $key }}">
                        <div class="card mb-5 mb-lg-0">
                            <div class="card-body">
                                <h5 class="card-title text-muted text-uppercase text-center">Monthly</h5>
                                <h6 class="card-price text-center">$8.44<span class="period">/month</span></h6>
                            </div>
                        </div>
                    </option>
                @endforeach
            </select>

ОБНОВЛЕНИЕ: я пробовал это:

@foreach ($plans as $key => $plan)
        <div class="col-6">
            <label>
                <input type="radio" name="plan" value="{{ $key }}" class="card-input-element" id="subscription-plan">

                <div class="panel panel-default card-input">
                    <div class="panel-heading">{{ $plan }}</div>
                    <div class="panel-body">2 Memorials</div>
                </div>
            </label>
        </div>
    @endforeach

Этот код работает и дает мне желаемый эффект наличия выбираемых карт, но API Stripe теперь получает только «ежемесячный» план, даже если пользователь отправляет данные своей кредитной карты после выбора «годового» плана. Это потому, что теперь оба входа имеют id="subscription-plan". введите здесь описание изображения

Полоса JavaScript:

        const stripe = Stripe('{{ env('STRIPE_KEY') }}');
        const elements = stripe.elements();
        const cardElement = elements.create('card');
        cardElement.mount('#card-element');
        const cardHolderName = document.getElementById('card-holder-name');
        const cardButton = document.getElementById('card-button');
        const clientSecret = cardButton.dataset.secret;
        const plan = document.getElementById('subscription-plan').value;

        cardButton.addEventListener('click', async (e) => {
            const { setupIntent, error } = await stripe.handleCardSetup(
                clientSecret, cardElement, {
                    payment_method_data: {
                        billing_details: { name: cardHolderName.value }
                    }
                }
            );
            if (error) {
                // Display "error.message" to the user...
            } else {
                // The card has been verified successfully...
                console.log('handling success', setupIntent.payment_method);

                axios.post('subscribe',{
                    payment_method: setupIntent.payment_method,
                    plan : plan
                }).then((data)=>{
                    location.replace(data.data.success_url)
                });
            }
        });

ОБНОВЛЕНИЕ 2: я заменил const plan = document.getElementById('subscription-plan').value; на var plan = document.querySelector('input[name="plan"]:checked').value;. Теперь я получаю Uncaught TypeError: Cannot read property 'value' of null в консоли, когда пытаюсь отправить.


  • Вы устанавливаете элемент checked по умолчанию? Может быть, ничего не установлено. Также убедитесь, что вы обновляете значение plan всякий раз, когда пользователь нажимает переключатели, или повторно собирайте его перед отправкой запроса. 11.02.2020
  • Да, я пробовал это, но это все равно не сработало. 11.02.2020

Ответы:


1

Это должно быть выполнимо, просто повторяя планы по созданию карт и вообще не используя выбор. Вы можете настроить выбор карты с помощью обработчиков onclick или рассматривать карты как переключатели, как показано здесь: https://codepen.io/stefanzweifel/pen/RNvGwz

Затем вместо использования значения выбора вы должны использовать значение радио.

05.02.2020
  • Этот код решил аспект дизайна моего вопроса. Спасибо, мой друг. 07.02.2020

  • 2

    вы можете просто использовать атрибут size для select

    <select name="plan" class="form-control" size=3 id="subscription-plan">
      <option value="1">
        <div class="card mb-5 mb-lg-0">
          <div class="card-body">
            <h5 class="card-title text-muted text-uppercase text-center">Monthly</h5>
            <h6 class="card-price text-center">$8.44<span class="period">/month</span></h6>
          </div>
        </div>
      </option>
    
      <option value="2">
        <div class="card mb-5 mb-lg-0">
          <div class="card-body">
            <h5 class="card-title text-muted text-uppercase text-center">Daily</h5>
            <h6 class="card-price text-center">$0.44<span class="period">/day</span></h6>
          </div>
        </div>
      </option>
      <option value="3">
        <div class="card mb-5 mb-lg-0">
          <div class="card-body">
            <h5 class="card-title text-muted text-uppercase text-center">Yearly</h5>
            <h6 class="card-price text-center">$80.44<span class="period">/year</span></h6>
          </div>
        </div>
      </option>
    </select>

    05.02.2020

    3

    Я решил проблему с JavaScript самостоятельно. Что я сделал, так это изменил var plan = document.querySelector('input[name="plan"]:checked').value; только на var plan;. Затем я добавил: $('input:radio').on('click', function(e) { plan = this.value; });.

    Теперь форма правильно отправляет правильный план на основе параметра, который пользователь выбирает для Stripe API. Для меня оказалось удивительно сложной задачей заставить эту форму работать без использования элементов <select> и <option>. Вот готовый рабочий код:

    HTML

    <div class="col-6">
            <label>
                <input type="radio" name="plan" value="monthly" class="card-input-element" checked="checked">
    
                <div class="panel panel-default card-input">
                    <div class="panel-heading">Monthly</div>
                </div>
            </label>
        </div>
        <div class="col-6">
            <label>
                <input type="radio" name="plan" value="yearly" class="card-input-element">
    
                <div class="panel panel-default card-input">
                    <div class="panel-heading">Yearly</div>
                </div>
            </label>
        </div>
    

    JavaScript

    <script src="{{ asset('js/jquery-3.4.1.min.js') }}"></script>
    <script>
        window.addEventListener('load', function() {
            const stripe = Stripe('{{ env('STRIPE_KEY') }}');
            const elements = stripe.elements();
            const cardElement = elements.create('card');
            cardElement.mount('#card-element');
            const cardHolderName = document.getElementById('card-holder-name');
            const cardButton = document.getElementById('card-button');
            const clientSecret = cardButton.dataset.secret;
            var plan;
            $('input:radio').on('click', function(e) {
                plan = this.value;
            });
    
            cardButton.addEventListener('click', async (e) => {
                const { setupIntent, error } = await stripe.handleCardSetup(
                    clientSecret, cardElement, {
                        payment_method_data: {
                            billing_details: { name: cardHolderName.value }
                        }
                    }
                );
                if (error) {
                    // Display "error.message" to the user...
                } else {
                    // The card has been verified successfully...
                    console.log('handling success', setupIntent.payment_method);
    
                    axios.post('subscribe',{
                        payment_method: setupIntent.payment_method,
                        plan : plan
                    }).then((data)=>{
                        location.replace(data.data.success_url)
                    });
                }
            });
        });
    </script>
    

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

    08.02.2020
    Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..