Keats / tera

A template engine for Rust based on Jinja2/Django
http://keats.github.io/tera/
MIT License
3.54k stars 283 forks source link

How to get the value chosen in an html form select, and having that value in a rust variable #779

Closed ErtyDess closed 1 year ago

ErtyDess commented 1 year ago

Hello i have a form with a dropdown select where i chose a date, when a date is chosen i would like to have the chosen value to a rust variable.

main.rs:

#![feature(proc_macro_hygiene, decl_macro)]
#[macro_use] extern crate rocket;
use rocket::{State, form::*, get, post, response::Redirect, routes, response::content};
use rocket_auth::{prelude::Error, *};
use rocket_dyn_templates::Template;
use serde_json::json;
use sqlx::*;
mod api;
use api::{call_api, db_fill, query_select, ResultsStruct};
use std::result::Result;
use std::*;
use serde::{Deserialize, Serialize};
use rocket::serde::json::Json;

#[get("/style.css")]              // <- route attribute
fn style() -> content::RawCss<&'static str> {
content::RawCss(include_str!("style.css"))
}

#[get("/show_on_click")]              // <- route attribute
fn show_on_click() -> content::RawJavaScript<&'static str> {
content::RawJavaScript(include_str!("showOnClick.js"))
}

#[get("/login")]
fn get_login() -> Template {
Template::render("login", json!({}))
}

#[post("/login", data = "<form>")]
async fn post_login(auth: Auth<'_>, form: Form<Login>) -> Result<Redirect, Error> {
let result = auth.login(&form).await;
println!("login attempt: {:?}", result);
result?;
Ok(Redirect::to("/"))
}

#[get("/signup")]
async fn get_signup() -> Template {
Template::render("signup", json!({}))
}

#[post("/signup", data = "<form>")]
async fn post_signup(auth: Auth<'_>, form: Form<Signup>) -> Result<Redirect, Error> {
auth.signup(&form).await?;
auth.login(&form.into()).await?;

Ok(Redirect::to("/"))
}

#[get("/")]
async fn index(user: Option<User>) -> Template {
let color = "";
/*let c_api = thread::spawn( move || {
    let call_api = call_api().unwrap();
    call_api
}).join().expect("Thread panicked");*/

let query_result_fn = thread::spawn( move || {
    let query_result = query_select();
    query_result
}).join().expect("Thread panicked");
let query_result = query_result_fn.await.unwrap();

Template::render("index", json!({ "user": user, /*"c_api": c_api,*/ "query_result": query_result }))
}

#[derive(FromForm, Deserialize, Serialize)]
struct Time {
commence_time: String
}

#[get("/time")]
async fn time_get(user: Option<User>) -> Template {
let date_chosen= ""; // here i would like to have the chosen date in string.

let query_result_fn = thread::spawn( move || {
    let query_result = query_select();
    query_result
}).join().expect("Thread panicked");
let query_result = query_result_fn.await.unwrap();

Template::render("time", json!({ "user": user, /*"c_api": c_api,*/ "query_result": query_result }))
}

#[post("/time", format="json", data="<user>")]
fn post_time(user: Json<Time>) -> String {
String::from(format!(
    "Created user: {}", user.commence_time))
}

#[get("/logout")]
fn logout(auth: Auth<'_>) -> Result<Template, Error> {
auth.logout()?;
Ok(Template::render("logout", json!({})))
}
#[get("/delete")]
async fn delete(auth: Auth<'_>) -> Result<Template, Error> {
auth.delete().await?;
Ok(Template::render("deleted", json!({})))
}

#[get("/show_all_users")]
async fn show_all_users(conn: &State<SqlitePool>, user: Option<User>) -> Result<Template, Error> {
let users: Vec<User> = query_as("select * from users;").fetch_all(&**conn).await?;
println!("{:?}", users);
Ok(Template::render(
    "users",
    json!({"users": users, "user": user}),
))
}

#[tokio::main]
async fn main() -> Result<(), Error> {

let conn = SqlitePool::connect("/home/erty/Programming/rocket_app/users.db").await?;
let users: Users = conn.clone().into();
users.create_table().await?;

/*thread::spawn( move || {
    let db_fill = db_fill().unwrap();
    db_fill
}).join().expect("Thread panicked");*/

let _ = rocket::build()
    .mount(
        "/",
        routes![
            index,
            style,
            show_on_click,
            get_login,
            post_signup,
            get_signup,
            post_login,
            logout,
            delete,
            show_all_users,
            time_get
        ],
    )
    .manage(conn)
    .manage(users)
    .attach(Template::fairing())
    .launch()
    .await
    .unwrap();
Ok(())
}

index.html.tera

{% extends "base" %}

{% block body %}

    {% if not user %}

        <h1 class="text">Please login!</h1>
        <h3 class="text">For the use of this site you need to create an account or login</h3>
        <br>
        <div class="container">
            <a href="/login"><button id="Cbutton" type="Button" class="Cbutton btn btn-primary w-100">Login</button></a>
        </div>

    {% endif %}

    {% if user %}
        <script src="/show_on_click"></script>
        <h1 class="text">Welcome to My Website Index! </h1>
        <br>
        <h3 class="text">You are logged in as {{ user.email }}</h3>
        <br>
            <form action="/time" method="post">
                <select>
                    {% set vec_num = 0 -%}
                    {% for i in query_result %}
                        {% set_global commence_time = query_result[vec_num].commence_time %} 
                        <option value = {{ commence_time }} > {{ commence_time }} </option>
                        {% set_global vec_num = vec_num + 1 %}
                    {% endfor %}
                </select>
                <div class="mb-3 row">
                    <button id="Cbutton" type="Button submit" class="Cbutton btn btn-primary">Submit</button>
                </div>
            </form>
    </div>

    {% endif %}

{% endblock body %}

if i submit i get this error

No matching routes for POST /time application/x-www-form-urlencoded.

Keats commented 1 year ago

This is not a Tera issue. You will to support forms on your rocket endpoint.