Найти - Пользователи
Полная версия: Flask + WTForm - события
Начало » Web » Flask + WTForm - события
1
Alex_Reg
Форумчане! Всем привет.
Прошу у вас помощи, 2 дня бьюсь будто об стену, решить сам не могу. В питоне, фласке и формах совсем новичок, сам занимаюсь back'ом на C#, но босс сказал “Нужно решить”…

На страницу в radioField я вывожу список объектов. По клику на элемент из списка мне нужно вывести более подробную информацию о выбранном объекте в другие контролы:

 <tr><th>Дата создания:</th><td>{{ form.createDate }}</td></tr>
                <tr><th>Автор:</th><td>{{ form.author }}</td></tr>
                <tr><th>Описание:</th><td>{{ form.description }}</td>

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

Код всех участвующих “компонентов” ниже.
Заранее благодарю за отклик и помощь.

Есть форма:

 class SambaGroupChangesForm(FlaskForm):
    id = HiddenField('Id')
    author = TextField('Author')
    createDate = TextField('CreateDate')
    description = TextField('Description')
    changeslist = RadioField('Changes',  choices = [])

Html страница:
 {% extends "base.html" %}
{% block content %}
<form action="" method="post" name="create">
{{ form.hidden_tag() }}
<div class="row d-flex flex-wrap">
    <div class="col-4">
        <table class="table table-hover table-sm">
            <thead class="thead-dark">
                <tr>
                  <th scope="col"></th>
                   <th scope="col">Группы</th>
                </tr>
            </thead>
            <tbody>
            {% for subfield in form.changeslist %}
                <tr>
                    <td>{{ subfield }}</td>
                    <td>{{ subfield.label }}</td>
                </tr>
            {% endfor %}
            </tbody>	
        </table>
    </div>
    <div class="col-4">
    <table class="table table-hover table-sm">
        <thead class="thead-dark">
            <tr>
              <th scope="col"></th>
               <th scope="col">Компания</th>
               <table>
			    <tr><th></th><td>{{ form.id }}</td></tr>
                <tr><th>Дата создания:</th><td>{{ form.createDate }}</td></tr>
                <tr><th>Автор:</th><td>{{ form.author }}</td></tr>
                <tr><th>Описание:</th><td>{{ form.description }}</td>
                <tr><th><input type="submit" class="btn btn-primary" value="Создать"></th></tr>
            </table>
            </tr>
        </thead>
        
    </table>
    </div>
    <div class="col-4">
            {% with messages = get_flashed_messages(with_categories=true) %}
            {% if messages %}
            {% for message in messages %}
            {% if "Error" not in message[1]: %}
            <div class="alert alert-success">
                <strong>Успешно! </strong> {{ message[1] }}</div>
            {% endif %}
            {% if "Error" in message[1]: %}
            <div class="alert alert-warning">
                {{ message[1] }}</div>
            {% endif %}
            {% endfor %}
            {% endif %}
            {% endwith %}
    </div>
</div>
</form>
{% endblock %}
    {% endblock %}

и маршрут:
 @app.route('/sambaGroupChanges/<id>', methods=['GET', 'POST'])
    def SambaGroupChanges(id):
        form = SambaGroupChangesForm(request.values)
        form.changeslist.choices = [(group.EntityId, group.CreateDate) for group in SambaGroupService().GetChanges(id)]
        form.id.data = id
        if form.is_submitted():
            flash(form.changeslist.data + 'Test')
        else:
            flash('Not work')
        return render_template('objectChanges.html', form=form)
py.user.next
Alex_Reg
Понимаю что должно быть событие, которое запускается при клике на элемент из списка, но как это реализовать ?
Через JavaScript. Flask не видит никаких событий в браузере.
Alex_Reg
py.user.next
А можете подсказать, где нужно писать JS код и как примерно будет выглядеть HTML код страницы при таком выводе списка объектов ?

<tbody>
{% for subfield in form.changeslist %}
<tr>
<td>{{ subfield }}</td>
<td>{{ subfield.label }}</td>
</tr>
{% endfor %}
</tbody>
py.user.next
Если ты откроешь исходник этой таблицы в браузере, ты увидишь, что она является внутренней частью HTML-документа (там будет вверху <html> написано). И вот в области <head> этого документа нужно загрузить JavaScript-скрипт, который и будет работать на странице. Загрузить его можно напрямую через тег <script>, а можно и из файла, тоже через тег <script> (обычно так и делают). И вот когда он загрузится, у него будет доступ к DOM (document object model, link) - динамический документ, создающийся в браузере по информации из исходника страницы. На DOM'е постоянно генерятся события, которые можно отслеживать. Если ты двинул мышкой или куда-то кликнул, генерируется соответствующее событие движения мыши или кликанья мышью. В сгенерированном событии внутри хранится информация про событие (координаты мыши или элемент, на котором кликнули). И вот скрипт может прослушивать события на выбранном элементе (установить прослушивание и задать функцию обработки). Когда событие произойдёт, сработает эта заданная функция обработки события и что-то сделает. И вот среди её действий может быть подгрузка части страницы и/или воздействие на стиль элемента в том же динамическом документе. Так ты можешь при срабатывании события догрузить данные с того же сайта, а потом взять элемент в динамическом документе (или создать этот элемент) и вставить в него эти подгруженные данные.

Alex_Reg
 {% extends "base.html" %}
Вот в этом шаблоне должны быть остальные части HTML-документа.

Alex_Reg
На страницу в radioField я вывожу список объектов. По клику на элемент из списка мне нужно вывести более подробную информацию о выбранном объекте в другие контролы:
Это можно как подгружать динамически, так и просто хранить на странице в скрытом виде и по нажатию куда-то просто менять у них CSS-свойство display с none на block.
Alex_Reg
py.user.next
Если ты откроешь исходник этой таблицы в браузере, ты увидишь, что она является внутренней частью HTML-документа (там будет вверху <html> написано). И вот в области <head> этого документа нужно загрузить JavaScript-скрипт, который и будет работать на странице. Загрузить его можно напрямую через тег <script>, а можно и из файла, тоже через тег <script> (обычно так и делают). И вот когда он загрузится, у него будет доступ к DOM (document object model, link) - динамический документ, создающийся в браузере по информации из исходника страницы. На DOM'е постоянно генерятся события, которые можно отслеживать. Если ты двинул мышкой или куда-то кликнул, генерируется соответствующее событие движения мыши или кликанья мышью. В сгенерированном событии внутри хранится информация про событие (координаты мыши или элемент, на котором кликнули). И вот скрипт может прослушивать события на выбранном элементе (установить прослушивание и задать функцию обработки). Когда событие произойдёт, сработает эта заданная функция обработки события и что-то сделает. И вот среди её действий может быть подгрузка части страницы и/или воздействие на стиль элемента в том же динамическом документе. Так ты можешь при срабатывании события догрузить данные с того же сайта, а потом взять элемент в динамическом документе (или создать этот элемент) и вставить в него эти подгруженные данные.
С концепцией разобрался. Теперь проблема в реализации. На форму я поместил простейший скрипт, только для того чтобы понять когда сработает событие.

 <script>
    function doStuff(){
        alert("YO!")
    }
</script>

Он находится в самом верху HTML страницы на которой присутсвует нужный список.
Посмотрев уроки и примеры, остановился на таком привязки события к контролу:

 <tbody>
            {% for subfield in form.changeslist %}
                <tr>
                    <td>{{ subfield (onClick="doStuff()") }}</td>
                    <td>{{ subfield.label }} </td>
                </tr>
            {% endfor %}
</tbody>	

Предполагал что по клику на элемент, а точнее на “радио”, произойдет вызов метода doStuff() и произойдет появление окна. Но, увы, не работает. Не могу понять почему. Судя по исходнику моей страницы, все вроде бы хорошо.

Вот что в исходнике:

 <div class="col-4">
        <table class="table table-hover table-sm">
            <thead class="thead-dark">
                <tr>
                  <th scope="col"></th>
                   <th scope="col">Группы</th>
                </tr>
            </thead>
            <tbody>
            
                <tr>
                    <td><input id="changeslist-0" name="changeslist" onСlick="doStuff()" type="radio" value="043273c7-279d-4dad-83eb-b515f839842b"></td>
                    <td><label for="changeslist-0">2019-07-02T00:58:16.837</label> </td>
                </tr>
            
                <tr>
                    <td><input id="changeslist-1" name="changeslist" onСlick="doStuff()" type="radio" value="043273c7-279d-4dad-83eb-b515f839842b"></td>
                    <td><label for="changeslist-1">2019-07-02T00:58:16.863</label> </td>
                </tr>
            
                <tr>
                    <td><input id="changeslist-2" name="changeslist" onСlick="doStuff()" type="radio" value="043273c7-279d-4dad-83eb-b515f839842b"></td>
                    <td><label for="changeslist-2">2019-07-02T00:58:41.347</label> </td>
                </tr>
            
                <tr>
                    <td><input id="changeslist-3" name="changeslist" onСlick="doStuff()" type="radio" value="043273c7-279d-4dad-83eb-b515f839842b"></td>
                    <td><label for="changeslist-3">2019-07-02T00:58:41.347</label> </td>
                </tr>
            
            </tbody>	
        </table>
    </div>

Что я делаю не так ?
_____________________________________________________

Ну чтож , это оказалось максимально нелепо… Подсветка на форуме помогла найти проблему, она крылась в том, что событие onСlick содержало букву в кириллице - С … От себя такого не ожидал… Именно по этому событие не работало.
Сообщение оставлю, вдруг кому поможет.

py.user.next спасибо за помощь. Плюсик поставил
py.user.next
Alex_Reg
Посмотрев уроки и примеры, остановился на таком привязки события к контролу:
Надо, чтобы скрипт сам находил, куда ему привязаться. Для этого размечаешь HTML-элементы определёнными классами, а потом из скрипта ищешь эти элементы по этим именам классов через метод документа .querySelector(). Когда нужный элемент найден, надо вызвать у него метод .addEventListener() , в который передаётся имя события и функция обработки события.

Так что подучи CSS и JavaScript. Видно, что у тебя в них пробелы, а в Web'е без них никак никак нельзя.
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB