PHP Classes

File: templates/create_poll.twig

Recommend this page to a friend!
  Packages of Matthew Asham   Binkterm PHP   templates/create_poll.twig   Download  
File: templates/create_poll.twig
Role: Auxiliary data
Content type: text/plain
Description: Auxiliary data
Class: Binkterm PHP
Bulletin board system based on the Web
Author: By
Last change:
Date: 5 days ago
Size: 10,042 bytes
 

Contents

Class file image Download
{% extends "base.twig" %} {% block title %}{{ t('ui.polls.create.title', {}, locale, ['common']) }} - {{ system_name }}{% endblock %} {% block content %} <div class="row"> <div class="col-lg-8 offset-lg-2"> <div class="card"> <div class="card-header d-flex justify-content-between align-items-center"> <h5 class="mb-0"><i class="fas fa-poll"></i> {{ t('ui.polls.create.heading', {}, locale, ['common']) }}</h5> <span class="badge bg-primary">{{ t('ui.polls.create.cost_badge', {'cost': poll_cost}, locale, ['common']) }}</span> </div> <div class="card-body"> {% if credit_balance < poll_cost %} <div class="alert alert-danger"> <i class="fas fa-exclamation-triangle"></i> <strong>{{ t('ui.polls.create.insufficient_credits', {}, locale, ['common']) }}</strong><br> {{ t('ui.polls.create.insufficient_credits_help', {'cost': poll_cost, 'balance': credit_balance}, locale, ['common']) }} </div> {% else %} <div class="alert alert-info"> <i class="fas fa-info-circle"></i> {{ t('ui.polls.create.cost_info_prefix', {}, locale, ['common']) }} <strong>{{ poll_cost }} {{ t('ui.polls.create.credits', {}, locale, ['common']) }}</strong>. {{ t('ui.polls.create.current_balance', {}, locale, ['common']) }} <strong>{{ credit_balance }} {{ t('ui.polls.create.credits', {}, locale, ['common']) }}</strong> </div> <form id="createPollForm"> <div class="mb-3"> <label for="question" class="form-label">{{ t('ui.polls.create.question_required', {}, locale, ['common']) }}</label> <input type="text" class="form-control" id="question" maxlength="500" required placeholder="{{ t('ui.polls.create.question_placeholder', {}, locale, ['common']) }}"> <div class="form-text"> <span id="questionCount">0</span>/500 {{ t('ui.polls.create.characters_minimum', {}, locale, ['common']) }} </div> </div> <div class="mb-3"> <label class="form-label">{{ t('ui.polls.create.options_required', {}, locale, ['common']) }}</label> <div id="optionsContainer"> <div class="input-group mb-2 option-row"> <span class="input-group-text">1</span> <input type="text" class="form-control option-input" maxlength="200" required placeholder="{{ t('ui.polls.create.option_placeholder', {}, locale, ['common']) }}"> <button type="button" class="btn btn-outline-danger remove-option" disabled> <i class="fas fa-times"></i> </button> </div> <div class="input-group mb-2 option-row"> <span class="input-group-text">2</span> <input type="text" class="form-control option-input" maxlength="200" required placeholder="{{ t('ui.polls.create.option_placeholder', {}, locale, ['common']) }}"> <button type="button" class="btn btn-outline-danger remove-option" disabled> <i class="fas fa-times"></i> </button> </div> </div> <button type="button" class="btn btn-sm btn-outline-primary" id="addOption"> <i class="fas fa-plus"></i> {{ t('ui.polls.create.add_option', {}, locale, ['common']) }} </button> <div class="form-text">{{ t('ui.polls.create.options_help', {}, locale, ['common']) }}</div> </div> <div class="alert alert-warning"> <i class="fas fa-exclamation-circle"></i> <strong>{{ t('ui.polls.create.note_label', {}, locale, ['common']) }}</strong> {{ t('ui.polls.create.note_text', {}, locale, ['common']) }} </div> <div class="d-flex justify-content-between"> <a href="/" class="btn btn-secondary">{{ t('ui.common.cancel', {}, locale, ['common']) }}</a> <button type="submit" class="btn btn-success" id="submitBtn"> <i class="fas fa-check"></i> {{ t('ui.polls.create.submit', {'cost': poll_cost}, locale, ['common']) }} </button> </div> </form> {% endif %} </div> </div> </div> </div> <script> $(document).ready(function() { function uiT(key, fallback, params = {}) { if (window.t) { return window.t(key, params, fallback); } return fallback; } function apiError(payload, fallback) { if (window.getApiErrorMessage) { return window.getApiErrorMessage(payload, fallback); } return payload && payload.error ? payload.error : fallback; } let optionCount = 2; // Character counter for question $('#question').on('input', function() { const len = $(this).val().length; $('#questionCount').text(len); }); // Add option button $('#addOption').on('click', function() { if (optionCount >= 10) { alert(uiT('ui.polls.create.max_options_allowed', 'Maximum 10 options allowed')); return; } optionCount++; const newOption = ` <div class="input-group mb-2 option-row"> <span class="input-group-text">${optionCount}</span> <input type="text" class="form-control option-input" maxlength="200" required placeholder="${uiT('ui.polls.create.option_placeholder', 'Enter option')}"> <button type="button" class="btn btn-outline-danger remove-option"> <i class="fas fa-times"></i> </button> </div> `; $('#optionsContainer').append(newOption); updateRemoveButtons(); }); // Remove option button $(document).on('click', '.remove-option', function() { $(this).closest('.option-row').remove(); updateRemoveButtons(); renumberOptions(); }); function updateRemoveButtons() { const rows = $('.option-row'); optionCount = rows.length; // Disable remove buttons if only 2 options remain if (optionCount <= 2) { $('.remove-option').prop('disabled', true); } else { $('.remove-option').prop('disabled', false); } // Hide add button if at max options if (optionCount >= 10) { $('#addOption').hide(); } else { $('#addOption').show(); } } function renumberOptions() { $('.option-row').each(function(index) { $(this).find('.input-group-text').text(index + 1); }); optionCount = $('.option-row').length; } // Form submission $('#createPollForm').on('submit', function(e) { e.preventDefault(); const question = $('#question').val().trim(); const options = []; $('.option-input').each(function() { const val = $(this).val().trim(); if (val) { options.push(val); } }); // Validation if (question.length < 10) { alert(uiT('ui.polls.create.question_min_length', 'Question must be at least 10 characters')); return; } if (options.length < 2) { alert(uiT('ui.polls.create.min_options_required', 'Please provide at least 2 options')); return; } if (options.length > 10) { alert(uiT('ui.polls.create.max_options_allowed', 'Maximum 10 options allowed')); return; } // Check for duplicates const uniqueOptions = [...new Set(options)]; if (uniqueOptions.length !== options.length) { alert(uiT('ui.polls.create.options_unique_required', 'All options must be unique')); return; } // Disable submit button $('#submitBtn').prop('disabled', true).html(`<i class="fas fa-spinner fa-spin"></i> ${uiT('ui.polls.create.creating', 'Creating...')}`); // Submit $.ajax({ url: '/api/polls/create', method: 'POST', contentType: 'application/json', data: JSON.stringify({ question: question, options: options }) }) .done(function(response) { const fallback = uiT('ui.polls.create.created_success_spent', 'Poll created successfully! You spent {spent} credits.', { spent: response.credits_spent }); const successMessage = window.getApiMessage ? window.getApiMessage(response, fallback) : fallback; alert(successMessage); window.location.href = '/'; }) .fail(function(xhr) { const error = apiError(xhr.responseJSON, uiT('errors.polls.create_failed', 'Failed to create poll')); alert(uiT('ui.polls.create.error_prefix', 'Error: ') + error); $('#submitBtn').prop('disabled', false).html(`<i class="fas fa-check"></i> ${uiT('ui.polls.create.submit', 'Create Poll ({cost} credits)', { cost: {{ poll_cost }} })}`); }); }); updateRemoveButtons(); }); </script> {% endblock %}