Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flask - Toggle button with dynamic label

I am new to Flask and want to create a On/Off toggle button on my website. I was wondering if and how this is possible also including a dynamic label. The following picture shows what I have in mind:

I was thinking about using a wtfforms SubmitField but I don't quite know how to implement this dynamic behavior between my routes.py file and my html template. I was thinking something like this:

forms.py:

from flask_wtf import FlaskForm
from wtforms import SubmitField

class PowerSwitchForm(FlaskForm):
    power_switch = SubmitField("ON")

routes.py:

from flask import render_template, flash, redirect, url_for
from app import app
from app.forms import PowerSwitchForm

@app.route('/power', methods=['GET', 'POST'])
def power():
  power_switch = PowerSwitchForm()
  if power_switch.power_switch.label.text == "ON" and power_switch.validate():
    flash("Power has been turned ON")
    power_switch.power_switch.label.text = "OFF"
    return redirect(url_for('power')
  elif power_switch.power_switch.label.text == "OFF" and power_switch.validate():
    flash("Power has been turned OFF")
    power_switch.power_switch.label.text = "ON"
    return redirect(url_for('power')
  return render_template('power.html', form0=power_switch)

power.html:

<!DOCTYPE html>

{% extends "base.html" %}

{% block content %}
<h2>Power switch</h2>
<form action="" method="post" novalidate>
  {{ form0.hidden_tag() }}
  {{ form0.power_switch() }}
</form>    
{% endblock %}
like image 354
uitty400 Avatar asked Jun 27 '18 08:06

uitty400


People also ask

How do I add an action to a button in flask?

In the Flask code you can add an action under every if statement of the corresponding button like rendering a template or running a python script. In the HTML code you can add as many buttons as you want just be sure to add the right values and names. Streamlit is our favorite way to create python web apps due to its simplicity.

Can I create my own navigation bar using flask?

Now you are able to create your own navigation bar using Flask so enjoy :) Are you new on Medium ? Don’t hesitate to subscribe for less than $ 5 here to benefit without limits and improve your skills.

How to use variable rules in flask for dynamic routing?

However, this can be solved using the flask with something called dynamic routing . We shall now look at a better approach using Variable Rules. We will add a <variable name> with each route. Optionally, we can also define the converter with each variable name <converter: variable name>. By default, the converter is String.


2 Answers

You can use jquery to handle the desired operation when the toggle button is clicked. Also, if there is a backend process that should be performed when the button is toggled, ajax can be used. This answer demonstrates both. bootstrap-toggle is a library that enables simple implementation of a toggle. To use, copy the header tag values below:

Simple toggle that displays "toggled" or "untoggled":

<html>
  <body>
    <head>
      <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/css/bootstrap.min.css">
      <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
      <script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.2/js/bootstrap.min.js"></script>
      <link href="https://gitcdn.github.io/bootstrap-toggle/2.2.2/css/bootstrap-toggle.min.css" rel="stylesheet">
      <script src="https://gitcdn.github.io/bootstrap-toggle/2.2.2/js/bootstrap-toggle.min.js"></script>
    </head>
    <input type="checkbox" class='toggle' checked data-toggle="toggle">
    <div class='status'>Toggled</div>
  </body>
  <script>
  $(document).ready(function() {
   $('.toggle').click(function() {
      var current_status = $('.status').text();
      if (current_status === 'Untoggled'){
         $('.status').html('Toggled');
      }
      else{
        $('.status').html('Untoggled');
      }

    });
   });
 </script>
</html>

enter image description here

Toggle that triggers backend script for both "toggled" or "untoggled":

In the template, slightly change the script:

<script>
 $(document).ready(function() {
  $('.toggle').click(function() {
   var current_status = $('.status').text();
   $.ajax({
    url: "/get_toggled_status",
    type: "get",
     data: {status: current_status},
     success: function(response) {
      $(".status").html(response);
     },
     error: function(xhr) {
      //Do Something to handle error
     }
   });
  });
});
</script>

Then, in your app, create a route /get_toggled_status:

@app.route('/get_toggled_status') 
def toggled_status():
  current_status = flask.request.args.get('status')
  return 'Toggled' if current_status == 'Untoggled' else 'Untoggled'

This example does the same thing as the pure html/jquery solution, however, it does demonstrate how the backend can be communicated with when using the toggle.

like image 61
Ajax1234 Avatar answered Sep 19 '22 06:09

Ajax1234


I am also new to Flask. And here is the pure python code with flask that I've tried. Looks it work.

in templates/demo.html :

{% extends "bootstrap/base.html" %}
{% import "bootstrap/wtf.html" as wtf %}

{% block content %}
<div class="page-header">
    {{ wtf.quick_form(form) }}
</div>
{% endblock %}

in demo.py :

from flask              import Flask, render_template, redirect, url_for                          
from flask_bootstrap    import Bootstrap
from flask_wtf          import FlaskForm
from wtforms            import SubmitField

class PowerState(FlaskForm) :
    state = SubmitField('OFF')

app = Flask(__name__)
Bootstrap(app)

app.config['SECRET_KEY'] = 'YOUR SECRET KEY'

@app.route('/', methods=['GET', 'POST'])
def home() :
    form = PowerState()

    if form.validate_on_submit() :
        if form.state.label.text == 'OFF' :
            PowerState.state = SubmitField('ON')
        elif form.state.label.text == 'ON' :
            PowerState.state = SubmitField('OFF')

        return redirect(url_for('home'))
    return render_template('demo.html', form=form)

then run : flask run

Regards, Alex.Wu

like image 43
hyperAsrpgwu Avatar answered Sep 18 '22 06:09

hyperAsrpgwu