Extracting value of checkbox generated dynamically through flask - javascript

Is there a way to read through an HTML page and return the value of the dynamic checkboxes which are clicked?
Now, I know how to get values from static check boxes even without using JS but since I am generating the below check boxes using data from Database I am not sure how to pin point each one and know which one the user checked,
When I went through developer tools in chrome I can see that the value of the generated check boxes changes but when I refer to them it still does not work.
<!DOCTYPE html>
<html lang="en">
<form action="/test" method="post">
<button type="submit" id="exporst-btn" class="btn btn-primary">Import Test Data <span class="glyphicon glyphicon-import"></span></button>
<br>
<br>
<div id="table">
<table class="table table-condensed">
<thead>
<tr>
<th>Selection</th>
<th>Slno</th>
<th>Region</th>
</tr>
</thead>
<tbody>
{% for obj in TD %}
<tr>
<td>
<input type="checkbox" name="chb[]" > {{obj.OEHR_Mtest_Slno}}
</td>
<td>
{{obj.OEHR_Mtest_Slno}}
</td>
<td>
{{obj.OEHR_Mtest_SF_Part_Number}}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
<!--<p id="export" name="test"></p>-->
<input type="hidden" id="exp" name="test">
<button type="submit" id="export-btn" class="btn btn-success">Execute <span class="glyphicon glyphicon-play"></span></button>
</form>
</body>
<script type="text/javascript"><!--
$('#export-btn').click(function () {
alert($('#mytable').find('input[type="checkbox"]:checked').length + ' checked');
});
</script>
</html>
I can use the above JS to know how many checkboxes have been checked, I want to know the value of the ones checked and I am not able to get that.

If I'm not mistaken,
var foo = $('#mytable').find('input[type="checkbox"]:checked')
will return an array of html elements which are checkboxes, and are checked. You can then do:
var bar = [];
foo.each(function (index) {
var baz = this.parentNode.textContent || this.parentNode.innerText;
if (baz && baz.length > 0)
bar.push(baz);
});
console.log(bar);
That will make bar an array of the values which were checked. It gets the checkboxes which were checked, finds their parents (<td> tags), and gets the text inside (which skips the <input> tags). This will do it client-side.

Because you're dynamically generating the checkboxes, it's helpful to also dynamically generate the values for the checkboxes. That way, when you POST the request via the submit button, Flask can determine which checkboxes were checked by reading the values. I would change your HTML to:
{% for obj in TD %}
<tr>
<td>
{# Assuming obj.OEHR_Mtest_Slno is a unique value #}
<input type="checkbox" name="chkbox" value="{{obj.OEHR_Mtest_Slno}}"> {{obj.OEHR_Mtest_Slno}}
</td>
<td>
{{obj.OEHR_Mtest_Slno}}
</td>
<td>
{{obj.OEHR_Mtest_SF_Part_Number}}
</td>
</tr>
{% endfor %}
Then in your backend, you can access the values via:
# Use .getlist if you are using HTML form elements with the same name
chkbox_values = request.form.getlist('chkbox') # returns a list of values that were checked

Related

Laravel 7 - Update value of checkbox without form or button

I'm stuck with my project, please help...
This is the situation: In my project I have to assign a teacher to give permission to grade students, because a group can have 2 or more teachers, but only one has to have permission to grade, so... I added a column in my table 'teachers' in the database with the name 'grade' of type boolean. And in my view I added a checkbox... How do I change the value of a checkbox without using any form or button to trigger the action and activate the checkbox in the teacher who is going to have permission to grade? And this value should also be updated in the database.
This is my view...
<!--teachers-->
<table class=" table table-sm table-striped table-bordered ">
<thead class="text-white bg-primary">
<tr>
<th>#lang('show.Identifier')</th>
<th>#lang('show.email')</th>
<th>#lang('show.grade')</th>
<th>#lang('show.delete')</th>
</tr>
</thead>
<tbody class="small text-center">
#foreach ($group->teachers as $teacher)
<tr>
<td >{{$teacher->Identifier}} </td>
<td >{{$teacher->email}} </td>
<td>
<input id="active" {{$teacher->grade == 1 ?'checked':''}} type="checkbox" name="grade" value="1">
</td>
<td>
<form method="post" action="{{url('Groups/Disenroll/'.$group->idGroup.'?idTeacher='.$teacher->idTeacher)}}">
{{csrf_field()}}
<button type="submit" class="btn btn-sm btn-outline-danger" > <i class="material-icons small" >call_split</i></button>
</form>
</td>
</tr>
#endforeach
</tbody>
</table>
And this is an image of the table, if it helps...
I think you can use something like JQuery for this.
You can firstly add a class of toggle-class to your checkbox
<input class="active toggle-class" {{$teacher->grade == 1 ?'checked':''}} type="checkbox" name="grade">
And secondly, make sure that you have a way to keep track of who's doing the grades.
Add data-id="{{ $teacher->Identifier}}" on your checkbox
<input data-id="{{ $teacher->Identifier}}" class="active toggle-class" {{$teacher->grade == 1 ?'checked':''}} type="checkbox" name="grade">
In your web.php add a new route
Route::get('/path/to/updateGrader/status', [App\Http\Controllers\MyController::class, 'updateGraderStatus']);
Add the below code to where your checkbox is located
$('.toggle-class').on('change',function(){
let status = $(this).prop('checked') == true ? true : false;
let grader_id = $(this).data('id');
$.ajax({
type:'GET',
dataType:'json',
url:'/path/to/updateGrader/status', // add your earlier created route here
data:{'grade': status, 'grader_id': grader_id},
success: function(data){
console.log('success');
}
});
});
In your Controller, MyController in our case create a new function
public function updateGraderStatus(Request $request)
{
$grader = MyModel::find($request->grader_id);
$grader->grade = $request->grade;
$grader->save();
}
Please let me know if this helps you. I didn't test it out but I think this is how you would go about it.

Map a button to a row in a table created using Flask (with Javascript/Jquery)

I'm learning a bit of web programming (cs50) and I'm facing a problem which I can't find a solution to..
As a project, I'm writing a website which act as a Password Manager.
Backend is written in Python, using Flask.
I have a page which list all the passwords an user have saved in the database, it's displayed as a table like so :
(element[0] refer to the name of the password, element[1] to the password itself and element[2] to it's rowid (used to try to give unique id's))
<table class="table table-striped table-dark">
<thead class="thead-light">
<tr>
<th>Password name</th>
<th>Password</th>
</tr>
<tbody>
{% for element in codes %}
<tr>
<form action="" method="post" id="form{{ element[2] }}">
<td name="name"><b>{{ element[0] }}</b></td>
<td id="password{{ element[2] }}" name="password" class="hidetext">{{ element[1] }}</td>
<td id ="{{ element[2] }}">
<select class="form-control" name="option">
<option disabled selected value>Options :</option>
<option value="1">Reveal password</option>
<option value="2">Modify password</option>
<option value="3">Delete password</option>
</td>
<td>
<button type="submit" onclick="apply();">Confirm</button>
</td>
</form>
</tr>
{% endfor %}
</tbody>
</thead>
</table>
So a row has 4 fields, the name, the passwords, a select menu, a button to apply the option chosen in the select menu.
The issues I'm encountering are mostly "How to access data of the row the user is interacting with". I tried to solve this using the DOM :
While on the website, in the console if I inspect the submit button, I can access all the data like so :
var row = $0.offsetParent;
var selection = $(row).previousElementSibling.value;
if (selection == 1) {
var pass = row.previousElementSibling.previousElementSibling;
$(pass).toggleClass('hidetext');
In my actual code, I replaced $0 by $(this) I thought it would do the trick but I'm obviously wrong.
To prevent the normal action of the button, I'm using this :
$(document).ready(function() {
$('form').each(function(){
$(this).submit(function(e){
e.preventDefault();
})
})
})
And for the two others options, I have pretty much the same issue the console give the same error (TypeError) as the first one.
else if (selection == 2) {
var formId = $(row).previousElementSibling.id;
$('#form' + formId).attr('action', '/modify_saved')
$(this).submit();
}
else if (selection == 3) {
var formId = $(row).previousElementSibling.id;
$('#form' + formId).attr('action', '/delete_password')
$(this).submit();
}
else {
return false;
}
Sorry if this is a little all over the place, I'm trying to put everything in order as I'm writing this message :-)

How to calculate value from a dynamically generated table and its rows using angular js?

I am trying to find the value for net worth from the table.
Net Worth = Sum(Stock Price * Shares Held)
Below is the table which is created as per user selection.
For ex: from the above table, Net Worth = (842.21*1 + 230.16*2 + 1002.2*2).
I am trying with ng-change as the networth can change every time the user adds or deletes stocks. Besides, I am also facing the css issue as networth goes down when a row is getting added to table.
Here is the plnkr.
<section class="pickstocks">
<label class="basiclabel">Manage Portfolio</label>
<div class="pickstocks-align">
<table>
<thead>
<tr>
<th>STOCK</th>
<th>PRICE</th>
<th>SHARES</th>
<th>WEIGHT</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="stock in stocksArray" class="portfoliokey">
<td>{{stock.key}}</td>
<td class="portfoliovalue">{{"₹" + stock.value}}</td>
<td class="changer">
<input type="button" id="num1" ng-click="decrementValue( stock.index )" value="-">
<input type="button" id="number{{ stock.index }}" value="1" />
<input type="button" ng-click="incrementValue( stock.index )" value="+" />
</td>
<td>{{stock.weight}}</td>
</tr>
</tbody>
</table>
<div class="networth">
<h3>Networth</h3>
</div>
</div>
</section>
Here is the Plunker for reference
The first thing to do is to store the weight field just like another field in the stock object.
mystock.weight = function(){return this.value*this.shares};
Making it into a function of the shares and value field lets us update the other two fields dynamically changing the networth. Also adding shares as a field to the stock object lets us update it easier later, so we only have to increment/decrement the field like so.
$scope.stocksArray[$scope.stocksArray.indexOf(stock)].shares++;
The biggest part of changing the code was objectifying it. Taking the stocks and representing it with objects allows us to easily modify and access the values later.
Once that was done all you have to do is make a method that returns the sum of all of the weights like so.
$scope.getNetWorth = function(){
let total = 0;
for(let i = 0; i < $scope.stocksArray.length; i++){
total += $scope.stocksArray[i].weight()
}
return total.toFixed(2);
}
And then reference it in the html like so {{"₹" +getNetWorth()}}
In the future try to use OOP practices to simplify your code and turn your data into object representations, it will save you time and headache trying to manipulate and access your data later.
you need to calculate sum at each instance
<tr ng-repeat="stock in stocksArray" class="portfoliokey">
<td>{{stock.key}}</td>
<td ng-init="totalAmount = totalAmount + (stock.value*stock.index)" class="portfoliovalue">{{"₹" + stock.value}}</td>
<td class="changer">
<input type="button" id="num1" ng-click="decrementValue( stock.index )" value="-">
<input type="button" id="number{{ stock.index }}" value="1" />
<input type="button" ng-click="incrementValue( stock.index )" value="+" />
</td>
<td>{{stock.weight}}</td>
</tr>
and total will be
<div class="networth">
<h3>{{totalAmount }}</h3>
</div>

Populating dropdown input in view with scope object

I have a dropdown menu/textbox which is used for when users are typing in something to save. Also, if it is saved it will load on the page here as well.
<tbody data-ng-repeat="(wholesalerIndex,wholesaler) in wholesalers" >
<tr >
<td >
<label class="control-label">{{wholesaler.ORDER}}</label>
</td>
<td class="col-md-3">
<div>
<input type="text" class="form-control dropdown-toggle" data-toggle="dropdown" data-ng-disabled="formReadOnly" data-ng-model="wholesaler.WHSLE_NAME" data-ng-keyup="comboWholesalerBoxOptions(wholesaler.WHSLE_NAME, 'wholeSalerNameOptions')" />
<ul>
<li data-ng-repeat="wholeSalerOption in wholeSalerNameOptions | unique: 'NAME'" style="width:100%"><a data-ng-click="changeWholesalerData(wholeSalerOption, wholesaler)">{{wholeSalerOption.NAME}}</a></li>
</ul>
</div>
</td>
<td >
<button data-ng-click="upWholesaler(wholesaler)">Up</button>
<button data-ng-click="downWholesaler(wholesaler)">Down</button>
</td>
</tr>
</tbody>
There is an order of these rows being created below and it can be moved up or down. {{wholesaler.ORDER}} is the current order of the row. I want the input dropdown to be populated with {{wholesaler.NAME}} when a button is pressed.
I can't figure out how to get it to populate. Putting it next to {{wholeSalerOption.NAME}} just makes the name add onto the end of the dropdown search results. value="wholeSalerOption.NAME" also doesn't do anything.
How do I get this field to update like other ones without interfering with its ability to do it's search?

Get form contents from array of forms

I currently make a list of "forms" based on an array using twig in my html. It is kind of hard to explain what I am trying to do, but if you look at my code below it should be clear to see. Based on which pay button the user presses, I want to get the corresponding amount.
EDIT:
The problem I am having is that I cannot access the input (.payAmountForm) based on which pay button the user clicked. I tried using the selector in my js file, however I get the error provided at the bottom.
html table
<table>
<thead>
<tr class="rowTable header">
<th class="cell">Date Submitted</th>
<th class="cell">Report Name</th>
<th class="cell">Details</th>
<th class="cell">Message</th>
<th class="cell">Amount</th>
<th class="cell">Pay</th>
</tr>
</thead>
<tbody>
{% for report in submittedReports.result %}
<tr class="rowTable">
<td class="cell">{{report.dateSubmitted}}</td>
<td class="cell">{{report.errorName}}</td>
<td class="cell">
<button type="button" class="displayDetailsModal detailsButton" data-toggle="modal"
data-target="#detailsModal" data-whatever="#getbootstrap"
data-ID={{report.reportID}}>
View
</button>
</td>
<td class="cell">
<button type="button" class="messageButton" data-toggle="modal"
data-target="#messageModal" data-whatever="#getbootstrap"
data-ID={{report.reportID}}>
Edit
</button>
</td>
<td class="cell">
<div class="input-group payInput">
<span class="input-group-addon">$</span>
<input type ="text" class="form-control payAmountForm" maxlength="11" data-id={{report.reportID}}>
</div>
</td>
<td class="cell">
<button data-ID={{report.reportID}} class="btn btn-success payButton" type="button" value="Pay">Pay</button>
</td>
</tr>
{% endfor %}
</tbody>
</table>
js file contents
$(document).ready(function () {
$(".payButton").click(function(event) {
payInfo = [];
event.preventDefault();
alert($(this).attr("data-ID"));
payInfo.amount = $(".payAmountForm [data-ID]=" + $(this).attr("data-ID")).val();
});
});
I am using jquery. The error I am getting is
Uncaught Error: Syntax error, unrecognized expression: .payAmountForm [data-ID]=1
Missing quotes around data-id attribute at html; also selector is incorrect , currently selecting child element of .payAmountForm ; try removing space between class selector and attribute selector ; adding quotes around data-id attribute at html
Also missing closing brackets at attributes selector
<input type ="text" class="form-control payAmountForm" maxlength="11" data-id="{{report.reportID}}">
payInfo is an Array at js at Question, not an Object ; try using Array.prototype.push()
payInfo.push(
$(".payAmountForm[data-id='" + $(this).attr("data-ID") +"']").val()
);
or to create an array of objects
payInfo.push(
{"amount": $(".payAmountForm[data-id='" + $(this).attr("data-ID") +"']").val()
}
);
$(document).ready(function() {
$(".payButton").click(function(event) {
payInfo = [];
event.preventDefault();
// alert($(this).attr("data-ID"));
payInfo.push({
"amount": $(".payAmountForm[data-id='" + $(this).attr("data-ID")
+ "']").val()
});
console.log($(".payAmountForm[data-id='" + $(this).attr("data-ID") + "']")
, $(this).attr("data-ID")
, payInfo);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<input type="text" class="form-control payAmountForm" maxlength="11" data-id="{{report.reportID}}" value="">
<button data-ID="{{report.reportID}}" class="btn btn-success payButton" type="button" value="Pay">Pay</button>

Categories