How to make button effect out of circle - html

I have a HTML code link to back end python flask, I would like to create only one button that could make each HTML tr (table row) url_for works in a loop (line by line) to update DB record. but now the result is only the first line tr url_for works to update the record. the rest line didn't work at all.
Please help.
the code works for loop but has multiple button. each button in tr.
<tbody>
{% for entry in entries %}
<tr>
<form action="{{url_for('log')}}" method="post">
<td>{{entry.aa}}</td>
<td>{{entry.bb}}</td>
<td>{{entry.cc}}</td>
<td>
<button class="btn btn-success btn-xs" type="submit" name="edit" value={{entry.id}}>Show Detail/Edit</button>
</td>
</form>
</tr>
{%endfor %}
</tbody>
I expect one button that run loop for all tr to trigger a url_for. that will update DB record. but no work for second tab row.
<form action="{{url_for('show')}}" method="post">
{% for entry in entries %}
<tr>
<td>
<div class="form-group">
<input name="aa" value="{{entry.aa}}">
</div>
</td>
<td>
<div class="form-group">
<input name="bb" value="{{entry.bb}}">
</div>
</td>
<td>
<div class="form-group">
<input name="cc" value="{{entry.cc}}">
</div>
</td>
</tr>
<!-- </form> -->
{%endfor %}
<div align="right">
<button type="submit" class="btn btn-default">Go</button>
</div>
</form>
#app.route("/show",methods=['POST','GET'])
def show():
cur=g.db.execute('update box set aa=(\'%s\'),bb=(\'%s\') where cc=(\'%s\')'
%(request.form['aa'],request.form['bb'],request.form['cc']))
g.db.commit()

You are making several forms when loop run.
you need to make only one form to submit all data at once. start form tag before loop starting and form tag end after loop end.
Make sure input fields name must be unique duplication will effect on all rows.

Related

.Net Core MVC: How to capture multiple Buttons inside single Form with one Postmethod?

I have a table, which gets filled at Runtime. In the last Row I want to add one button to each Column and when one button is pressed it shall Link to the same Post method, but with a different value.
<form method="post" asp-action="ChangeAll">
<input asp-for="DataId" type="hidden" />
<table>
<thead>
.....
</thead>
<tbody>
....data dynamically loaded
(
<td>
<input type="checkbox" name="boxes" value="#Model.RowId" />
</td> )
//last Row:
<tr>
<td>
<input type="submit" value="Update" />
<input type="hidden" name="selectedAction" value="#MyEnum.Value1" hidden />
</td>
......
<td>
<input type="submit" value="Update" />
<input type="hidden" name="selectedAction" value="#MyEnum.Value20" hidden />
</td>
</tr>
</tbody>
</table>
</form>
[HttpPost]
public async Task<IActionResult> ChangeAll(int[] boxes, int DataId, string
selectedAction){
The problem with the above is that no matter what button I click, it always posts back the value of the first button (MyEnum.Value1).
I have tried to add an asp-action="ChangeAll" to each button, but the behaviour stays the same.
So, how can I get the value of the Button I actually clicked?
In your code, All the hidden input have the same name, So when you submit the form. It will bind the first one. You can change your code like this:
<form method="post" asp-action="ChangeAll" id="Form">
.....
<input type="hidden" name="selectedAction" id="select" hidden />
<tr>
<td>
<input type="submit" value="Update" data-action="#MyEnum.Value1" onclick="choice(this,event)"/>
</td>
........
<td>
<input type="submit" value="Update" data-action="#MyEnum.Value20" onclick="choice(this,event)"/>
</td>
</tr>
</form>
<script>
function choice(a,event){
event.preventDefault();
var result = $(a).data("action");
document.getElementById("select").value = result;
document.getElementById("Form").submit();
}
</script>
In the above code, I only wrote one hidden input and customized an attribute--data-action to accept #MyEnum.Valuexx's value, and then assigned this value to the hidden input.

HTML / FLASK - Dynamic Table with Checkboxes per row

With Flask / HTML, I am dynamically populating a table of directory listings where I would like the user to have the option to select single or multiple directories via a checkbox, however when I check the box on any table row besides the first, only the first row's checkbox is being selected. I have ensured that the value of the checkboxes are independent, however I would like to have each row's checkbox to be unique to one another.
HTML:
<div id="select-form">
<form action="" method="post">
<h1>{{ directory.user_entered_path }}</h1>
<table cellspacing="0" class="table">
<tbody>
<tr>
<td class="head">Filename</td>
<td class="head">Type</td>
<td class="head">Size</td>
<td class="head">Select</td>
</tr>
{% for file in dir_list %}
<tr>
<td name="name"> {{ file.file_name }}</td>
<td> {{ file.file_type }} </td>
<td> {{ file.file_size }}</td>
<td><input class="form-check-input" type="checkbox" id="inlineCheckbox1" value="{{file}}">
<label class="form-check-label" for="inlineCheckbox1"> </label></td>
</tr>
{% endfor %}
</tbody>
</table>
</form>
</div>
I tried the following:
To the end of your html, within the <form></form> I added a submit button for convenience, I don't know of another way to create a post request.
<form action="" method="post">
<h1>{{ directory.user_entered_path }}</h1>
<table cellspacing="0" class="table">
<tbody>
<tr>
<td class="head">Filename</td>
<td class="head">Type</td>
<td class="head">Size</td>
<td class="head">Select</td>
</tr>
{% for file in dir_list %}
<tr>
<td name="name"> {{ file.file_name }}</td>
<td> {{ file.file_type }} </td>
<td> {{ file.file_size }}</td>
<td><input class="form-check-input" type="checkbox" name="check" id="inlineCheckbox1" value="{{file}}">
<label class="form-check-label" for="inlineCheckbox1"> </label></td>
</tr>
{% endfor %}
</tbody>
</table>
<!-- added this button -->
<button type="submit" name="submit-button" value="Submit">submit</button>
</form>
Then I added this route to a flask app.py
from flask import request, render_template
#app.route('/stack-dynamic-checkboxes', methods=["POST", "GET"])
def dynamic_checkboxes():
if request.method == 'POST':
if request.form['submit-button'] == "Submit":
for checkbox in request.form.getlist('check'):
print(checkbox)
def afile(x):
return {'file_name':f'file {x}',
'file_type':f'type {x}',
'file_size':f'size {x}'}
dir_list = [afile(x) for x in range(10)]
directory = {'user_entered_path':'a path'}
return render_template( 'testing/stack-dynamic-checkboxes.html',
directory=directory,
dir_list=dir_list )
When I run the app and navigate to the page with your html, select some checkboxes and press submit, I get information about the files printed to my console. They are all dictionaries in this format
{'file_name': 'file 0', 'file_type': 'type 0', 'file_size': 'size 0'}
I hope this was wat you were looking for.
I've been searching for a way to do this for a while. I'm glad you posted this question because I didn't understand the way I had to set up the HTML part correctly, so, thank you!
In the future, It would be nice to have a little bit more context, what your code looks like perhaps, as I'm uncertain whether this is what you were looking for

how to merge a new table into an exist one without put into same form?

I have a question here and wondering if you could provide your help.
how I could merge second "stage" entries as a vertical table to the right side of the table IP_address ?
I don't want them merge into same , because that will cause some issue.
thank you in advance.
<table width="100%" class="table" >
<thead>
<tr>
<th >IP</th>
<th >Stage</th>
</tr>
</thead>
<tbody>
<form id="myform" name="myform" action="{{url_for('show_select')}}" method="post">
{% for entry in entries %}
<tr>
<td>
<div class="form-group">
<input id="IP" name="IP" class="IPS" value="{{entry.ip_address}}" readonly>
</div>
</td>
</tr>
{%endfor %}
</form>
{% for entry in entries %}
<tr>
<td>
<div id="f1_container" name="container">
<div id="cube" class="cube" >
<div class="cube__face cube__face--stage_1">
<input id="stage_1" type="button" class="btn-default" name="stage" value="test" >
</div>
</div>
</div>
</td>
</tr>
{%endfor %}
</tbody>
</table>
What Pablo was trying to point out in the comments was that the <form> HTML element is not a valid descendant of <tbody>. The documentation states under "Permitted content":
Zero or more <tr> elements.
Which means having a form directly inside a <tbody> is invalid markup, and as such can lead to unexpected behavior.
The option I see fit your use case best would be using the form attribute of the input element. However, unless the input has the type submit you won't be able to submit the form with it without the use of JavaScript.
For the form attribute to work you will need to generate a unique ID for each form and use it when generating the code. Due the lack of a template engine tag this solution will assume the use of Jinja2 (based on the syntax and the url_for call), but the concept should be the same for any other template language.
Your two options are to either use the iterator variable to make sequential IDs, or if your records have one, use a unique ID from the records themselves. For this solution I will use the loop variable to generate the IDs.
<table width="100%" class="table">
<thead>
<tr>
<th>IP</th>
<th>Stage</th>
</tr>
</thead>
<tbody>
{% for entry in entries %}
<tr>
<td>
<!-- moved form inside the table cell, gave it a unique ID -->
<form id="myform-{{loop.index0}}" name="myform" action="{{url_for('show_select')}}" method="post">
<div class="form-group">
<input id="IP" name="IP" class="IPS" value="{{entry.ip_address}}" readonly>
</div>
</form>
</td>
<td>
<div id="f1_container" name="container">
<div id="cube" class="cube">
<div class="cube__face cube__face--stage_1">
<!-- type changed to submit, added form attribute matching the value given to the form's id attribute -->
<input type="submit" form="myform-{{loop.index0}}" class="btn-default" name="stage" value="test">
</div>
</div>
</div>
</td>
</tr>
{% endfor %}
</tbody>
</table>

How to disable/ hide all buttons after one click on any button (cshtml)

i would like to know how to disable/hide all the buttons once user clicks on any of the buttons. I am only allowed to use c# or html. I have found solutions in Javascript but i cannot use it. (i did not upload my razor c# code due to lack of space)
I am creating a program that allows user to vote for any one of the candidates. Once user has clicked and chosen on one candidate, the voting result will be displayed and user should not be allowed to vote again.
<!DOCTYPE html>
<html>
<head>
<title>Elections</title>
</head>
<body>
<form id="form1" method="post">
<div>
<table>
<tr>
<td>Harry</td>
<td><input id="Harry" name="submit" type="submit" value="Vote Harry" /></td>
</tr>
<tr>
<td>John</td>
<td><input id="John" name="submit" type="submit" value="Vote John" /></td>
</tr>
<tr>
<td>Bryan</td>
<td><input id="Bryan" name="submit" type="submit" value="Vote Bryan" /></td>
</tr>
<tr>
<td>Jack</td>
<td><input id="Jack" name="submit" type="submit" value="Vote Jack" /></td>
</tr>
</table>
</div>
<div>
#if (result != "")
{
<p>#result</p>
}
<!--Ensure that user has voted before showing the vote results-->
#if (voteCheck == true)
{
<p>Total Votes: #Session["totalVotes"]</p> <!--using session allows values to be kept even after button click-->
<p> Harry: #Session["Harry"]</p>
<p> John: #Session["John"]</p>
<p> Bryan: #Session["Bryan"]</p>
<p> Jack: #Session["Jack"]</p>
}
</div>
</form>
</body>
</html>
You need an action attribute to the form action="youraction/controller here"
And in youraction you write some C# code return list of display value ("none" or "")
And in cshtml you add style="display:#display"
<input id="Harry" name="submit" type="submit" style="display:#display" value="Vote Harry" />
You could simply add a Ternary operator that check the session object and sets the disabled property accordingly.
<input id="Harry" #(Session["Harry"] != null ? "disabled" : "") name="submit" type="submit" value="Vote Harry" />

delete row corresponding to button clicked in jsp

userdetails.jsp
<tr>
<td>
<%
out.println(rs.getString(1));
name=rs.getString(1);
out.print("<input type='hidden' name='user' value='"+name+"'");
%>
</td>
<td>
<%out.println(rs.getString(2));
%>
</td>
<td>
<%out.println(rs.getString(3));
%>
</td>
<td>
<%out.println(rs.getString(4));
%>
</td>
<td>
<input type="Submit" name="delete_user" value="Delete"/>
</td>
</tr>
when i click the delete button only first row is getting deleted and not the row corresponding to which button is clicked
You're putting multiple hidden input values and delete buttons altogether in the same form. When you use request.getParameter() to get the hidden input value, you will indeed only get the first one, regardless of the delete button pressed.
You need to group the hidden input and the delete button in their own forms.
<td>
<form action="delete" method="post">
<input type="submit" name="delete_user" value="Delete" />
<input type="hidden" name="user" value="<%=rs.getString(1)%>" />
</form>
</td>
This way the request will always have the one and the right user name as parameter.
Said that, using scriptlets in JSP is 90's way of writing JSPs and also mingling database logic in a JSP is not really a good practice. I'd suggest to get yourself through this answer.
You can add the user name to the button value upon clicking it:
<input type="Submit" name="delete_user" value="Delete" onclick="this.value += ' <% out.print(name); %>'; this.disabled = true; " />
Then in the server side code, parse the value: get the text after first space, which is the user name to delete and reference only row with that user name.