How do I open up a download dialog box using Flask? - javascript

I'm trying to let the user download an mp3 file after a text-to-speech convert using gTTS. The flash message appears but the download dialog does not open.
Here is the Python code:
def mytts():
if request.method == 'POST':
if not request.form['text']:
flash('Text needed to proceed', 'error')
else:
text_input = request.form['text']
tts = gTTS(text=text_input, lang='en')
f=TemporaryFile()
tts.write_to_fp(f)
flask.send_file(f,as_attachment=True,attachment_filename="MyTTSOutput.mp3", mimetype="audio/mpeg")
f.close()
flash('Successful Text-to-Speech Convert')
return redirect(url_for('mytts'))
return render_template('mytts.html')
HTML Code (the form part only):
<form action="" method=post class="form-horizontal">
<h2>Convert Text To Speech</h2>
<div class="control-group">
<div class="controls">
<textarea name="text" rows=10 class="input-xlarge" placeholder="Enter text to be converted here" required>{{ request.form.text }}</textarea>
</div>
</div>
<div class="control-group">
<div class="controls">
<button type="submit" class="btn btn-success">CONVERT!</button>
<button type="button" class="btn btn-info">HOME</button>
</div>
</div>
</form>
Please help.

You need to return the result of send_file. It generates a response object, Flask can only do something with that object if it's returned from the view function.
with TemporaryFile() as f:
tts.write_to_fp(f)
return send_file(f, as_attachment=True, attachment_filename="tts.mp3")

Related

Text becomes automatically capital in input field form. I am working on PHP and Codeigniter3

When I type any text in the input field it automatically becomes capital, whereas I haven't used anything like strtouppercase and also the caps lock is off. I am working in admin panel and facing this issue whereas in student form there are also forms but there I am not facing as such problem.
I want the text to be types as I want. Be it uppercase lowercase or first word capital but here in this case each character becomes capital.
This is my controller code:
//This method is for loading the view.
public function updatedirectorMessage()
{
$data['side_bar_values'] = $this->side_bar_values;
$this->view("admin/update_director_message", $data);
}
//This method is for inserting data.
public function update_directorMessage_handler()
{
$description = $this->input->post('director_message');
$this->Configuration_model->updateConfiguration('DIRECTOR_MESSAGE', $description);
}
This is my model code
function updateConfiguration($title,$description){
$this->db->where('TITLE',$title);
$data['DESCRIPTION'] =$description;
$this->db->update('configuration',$data);
}
This is my view code
<div id="min-height" class="container-fluid" style="padding:30px">
<div class='card'>
<div class="card-body">
<form action="<?=base_url()?>AdminPanel/update_directorMessage_handler" method="post">
<div class="form-group">
<label for="">Director Message</label>
<textarea name="director_message" id="" cols="30" rows="10" ><?=$director_message?></textarea>
<input type="submit" name="update" value="Update" class="btn btn-primary" >
</div>
</form>
</div>
</div>
</div>

How load forms in modal dynamically?

I'm trying to load forms in modal dynamically using jquery and ajax in python but when i submit the form i get the error werkzeug.exceptions.BadRequestKeyError: 400 Bad Request: The browser (or proxy) sent a request that this server could not understand. KeyError: 'title'.
Mentioning that I recently started using jquery and ajax with python, could you help me please?
I want to reuse modal section to load multiple forms with jquery.
The code is as below.
HTML: lockbox.html
<input class="btn add" type="button" value="New">
<!--Modal-->
<dialog class="modal">
<div class="modal-header">
<h4 class="modal-title"></h4>
<button class="close-modal">X</button>
</div>
<div class="modal-body">
</div>
<div class="modal-footer">
<button class="close-modal">Cancel</button>
</div>
</dialog>
Javascript
$('.add').on('click', function () {
$.ajax({
type: "get",
url: "/newentry",
success: function (data) {
$('.modal-body').html(data);
$('.modal-header').css('background-color', '#0688fa');
$('.modal-title').text('New register');
$('.modal-footer').css('background-color', '#0688fa');
modalBox.showModal();
}
});
});
Python route
#app.route('/newentry')
def newentry():
return render_template('app/addpass.html')
HTML: addpass.html
<form method="post" class="addPass" action="/addPassReg">
<div class="field-block">
<label for="title">Title: </label>
<input type="text" id="title" value="">
</div>
<div class="field-block">
<label for="user">User: </label>
<input type="text" id="user" value="">
</div>
<div class="field-block">
<label for="passw">Password: </label>
<input type="text" id="passw" value="">
</div>
<div class="field-block">
<input type="submit" value="Save" class="btn save">
</div>
</form>
Python route
#app.route('/addPassReg', methods = ['POST', 'GET'])
def addPassReg():
#cur = mysql.connection.cursor()
if request.method == 'POST':
print('is post')#for debug
print(request.args.listvalues)#trying to know the error
title = request.form['title']
user = request.form['user']
passwd = request.form['passw']
if title and user and passwd:
return json.dumps({'message' : 'OK.'})
else:
print('After')
return redirect(url_for('lockbox'))#json.dumps({'html' : 'Complete please.'})
if request.method == 'GET':
print('is get')#for debug
else:
print('whats up?')#for debug
return redirect(url_for('lockbox'))
When I reuse the modal just to see data it's OK, but for forms I realize that it doesn't work and I don't know if it doesn't recognize the form data or I'm doing something wrong.

form is published even if the form content is blank when submit and reload the form in flask

Flask (1.1.2)
I tried to clear value of form by clicking button "Publish" but I don't know why script is not executing on click.
Java Script is well implemented
<script type=text/javascript src="{{ url_for('static', filename='js/main.js') }}"></script>
But button with argument 'onClick' isn't executing the function 'clear()'
<button type="submit" class="btn btn-success" id="submit" onclick="clear()">Publish</button>
Form:
<div class="entry-con">
<h1>Write own entry</h1>
<hr>
<form method="POST">
<!-- <div class="form-group">
<input class="form-control form-control-lg" type="text" name="title" placeholder="Title">
</div> -->
<div class="form-group">
<textarea class="form-control" rows="3" name="note" id="note" placeholder="Content"></textarea>
</div>
<button type="submit" class="btn btn-success" id="submit" onclick="clear()">Publish</button>
</form>
</div>
Main.js:
function clear() {
var content = document.getElementById('note')
content.value = ""
console.log()
}
views.py:
from flask import Blueprint, render_template, request, flash
from flask_login import login_required, login_user, logout_user, current_user
from .models import Note
from . import db
views = Blueprint('views', __name__)
#views.route('/', methods=['GET', 'POST'])
def index():
if request.method == 'POST':
note = request.form.get('note')
if len(note) < 1:
flash('Note is too short!', category='error')
else:
new_note = Note(data=note, user_id=current_user.id)
db.session.add(new_note)
db.session.commit()
flash('Note added!', category='success')
return render_template("index.html", user=current_user)
GitHub Repository: https://github.com/Inexpli/Flask-WebApp
How it looks like:
https://i.stack.imgur.com/DmhJu.png
So, the solution to my problem was just add a redirect function after saving form values, because whenever I was reloading the page, post method still was holding the values ​​of form.
I am still confused that i had to get solution on my own while it is pretty common situation in creating web applications.

jqWidgets: How can I post an HTML form inside a jqxWindow?

I created the following HTML form inside a jqxWindow widget for a Laravel project:
<div id="provinceWindow">
<div id="provinceWindowHeader"></div>
<div id="provinceWindowContent">
<form id="provinceForm" method="POST" action="{{route('province.store')}}">
{{ csrf_field() }}
<input type="hidden" name="provinceId" id="provinceId" value=""/>
<div class="form-group row">
<div class="col-6"><label>English province name</label></div>
<div class="col-6"><input type="text" name="provinceNameEn" id="provinceNameEn" maxlength="20"/></div>
</div>
<div class="form-group row">
<div class="col-6"><label>Spanish province name</label></div>
<div class="col-6"><input type="text" name="provinceNameSp" id="provinceNameSp" maxlength="20"/></div>
</div>
<br/>
<div class="form-group row justify-content-center">
<input type="button" value="Submit" id="submitBtn" class="btn btn-sm col-3" />
<span class="spacer"></span>
<input type="button" value="Cancel" id="cancelBtn" class="btn btn-sm col-3" />
</div>
</form>
</div>
</div>
This is the javascript file:
$(document).ready(function () {
var datarow = null;
$.ajaxSetup({
headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')}
});
//-----------------------------
// Window settings
//-----------------------------
$('#provinceWindow').jqxWindow({
autoOpen: false,
isModal: true,
width: 400,
height: 160,
resizable: false,
title: 'Province name',
cancelButton: $('#cancelBtn'),
initContent: function () {
$('#submitBtn').jqxButton();
$('#submitBtn').on('click', function () {
$('#provinceForm').submit();
});
}
}).css('top', '35%');
The file routes\web.php has only one resourse route defined for this page:
// Routes for province maintenance
Route::resource('province', 'provinceController');
Checking the available routes with php artisan route:list command, I get these:
Method URI Name Action
GET|HEAD / APP\Http\Controllers\homeController#index
GET|HEAD province province.index APP\Http\Controllers\provinceController#index
POST province province.store APP\Http\Controllers\provinceController#store
GET|HEAD province/create province.create APP\Http\Controllers\provinceController#create
GET|HEAD province/{province} province.show APP\Http\Controllers\provinceController#show
PUT|PATCH province/{province} province.update APP\Http\Controllers\provinceController#update
DELETE province/{province} province.destroy APP\Http\Controllers\provinceController#destroy
GET|HEAD province/{province}/edit province.edit APP\Http\Controllers\provinceController#edit
My controller action:
public function store(Request $request)
{
$fields = $request->all();
if ($request->provinceId == '') {
$province = new province($fields);
$validator = Validator::make($fields, $province->rules());
if ($validator->fails()) {
return redirect('')->withErrors($validator)->withInput();
}
else {
$province->save();
}
return view('province/index');
}
}
The form is shown on top of a jqxGrid widget, as a modal window, in order to capture the required information and perform the CRUD operations for the corresponding DB table.
The problem is, when I click the "Submit" button the window is closed and nothing else happens. The form is not posted to the indicated action and the data entered get lost.
It does not matter if I initialize the submitBtn inside the initContent or outside of it. The form is never posted.
I also tried the Close event of the jqxWindow to no avail.
If I take a look to the generated HTML it looks like this:
<form id="provinceForm" method="POST" action="http://mis:8080/province">
<input type="hidden" name="_token" value="Y9dF5PS7nUwFxHug8Ag6PHgcfR4xgxdC43KCGm07">
<input type="hidden" name="provinceId" id="provinceId" value="">
<div class="form-group row">
<div class="col-6">
<label>English province name</label>
</div>
<div class="col-6">
<input type="text" name="provinceNameEn" id="provinceNameEn" maxlength="20">
</div>
</div>
<div class="form-group row">
<div class="col-6">
<label>Spanish province name</label>
</div>
<div class="col-6">
<input type="text" name="provinceNameSp" id="provinceNameSp" maxlength="20">
</div>
</div>
<br>
<div class="form-group row justify-content-center">
<input type="button" value="Submit" id="submitBtn" class="btn btn-sm col-3 jqx-rc-all jqx-button jqx-widget jqx-fill-state-normal" role="button" aria-disabled="false">
<span class="spacer"></span>
<input type="button" value="Cancel" id="cancelBtn" class="btn btn-sm col-3">
</div>
</form>
Pressing the submit button takes me to the home page and nothing gets added to the DB table.
I guess the issue has something to do with Laravel routes because I get no errors.
What is missing or what is wrong with this approach?
Any light is appreciated.
Alright, because I erroneously added in my Model a validation, that was not needed, for a column (there was already a constraint defined at the DB table level), it was not possible to fulfill the validator when saving a new record. I commented that line in my Model and, that was it!
protected $rules = array(
'provinceNameEn' => 'required|alpha|max:20',
'provinceNameSp' => 'required|alpha|max:20'
//'deleted' => 'required|in:M,F' // This is already validated in a DB constraint.
);
I noticed the control was returned to my home page but without any message or error, but if you pay attention to my controller it was precisely the behavior programmed. However, there is no implementation to display the error messages, so I added dd($validator); before that return statement. There I read the message and finally found the solution.

Adding a request variable in a Django template

I am currently uploading a file to the server in Django as follows (For some unrelated reasons, I cannot use models for this form):
<div class="input-group" style="padding-top: 10px">
<div><input class="form-control" id="filename" value="Select a ZIP file to upload..." disabled></div>
<div class="input-group-btn"><input type="button" id="get_file" class="btn btn-primary" value="Browse"
style="margin-right: 3px;margin-left: 3px"></div>
<div class="input-group-btn"><input type="submit" id="upload"
class="btn btn-success" value="Upload" style="display: none"></div>
<input type="file" id="upload_file" name="upload_file" accept=".zip">
</div>
And then I some JavaScript as:
document.getElementById('get_file').onclick = function() {
document.getElementById('upload_file').click();
};
$('input[type=file]').change(function (e) {
document.getElementById('filename').value = ($(this).val());
document.getElementById('upload').style.display = "inline"
});
document.getElementById('upload').onclick = function() {
};
This works fine and I can upload the file just fine. However, now along with a file, I also want to send a string identifier. I am not sure how I can insert another request parameter on submit from this template?
The Django side looks like:
def upload(request):
"""
if request.method == 'POST' and request.FILES['upload_file']:
# Do things
So I need to add another parameter, so that I can do something like: request.GET.get('identifier') and this identifier key/value is inserted in the template code.
Does adding a hidden input inside the form work?
<input type="hidden" name="identifier" value="..."/>

Categories

Resources