Laravel 7 - Update value of checkbox without form or button - javascript

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.

Related

how to use two submit functions for update save form angular js

I am using angular js for form save. after saved i loaded all data to the grid. data can edit using edit button. i am using two separate functions to save data.
check my form
<form class="form-horizontal" ng-submit="saveEmpDetils(); update()"
novalidate="novalidate">
Name <input type="text" ng-model="user.name"/>
Age <input type="text" ng-model="user.age"/>
City <input type="text" ng-model="user.city"/>
<button type="submit">Save</button>
<button type="submit">Update</button>
</form>
load data to the grid
<table datatable="" id="empDetialTable" dt-options="dtOptions"
dt-columns="dtColumns" class="table table-bordered table-hover">
<thead>
<tr>
<th>Name</th>
<th>Age</th>
<th>City</th>
<th class="text-center">Action</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="employer in employerDetailList">
<td>{{employer.name}}</td>
<td>{{employer.age}}</td>
<td>{{employer.city}}</td>
<td data-title="'Action'" class="text-center">
<div class="btn-group-xs">
<a ng-click="editUser(employer)" target="_self"
class="btn btn-flat btn-xs btn-primary"
data-toggle="tooltip"
data-placement="bottom" title="Edit" tooltip>
<i class="ion ion-edit"></i>
</a>
</td>
</tr>
</tbody>
</table>
when i click edit button, data loaded to the form. i done it. when click the edit, save button should hide and update button should show. after click the update button, update function should only submit. how i do it.
As far I understood, You need to update and save within same modal or form If I am not wrong.
So,
Although there can be multiple ways of doing it. Such as you can
pass id of employer in routes for the employer you want to edit and
validate if id exists then call edit function and if not then save
function.
I suppose the save and edit is in modal then you can maintain a scope variable that suppose isEdit so you will have $scope.isEdit = false //initially and when user click on edit button set $scope.isEdit to true. Then validate if $scope.isEdit is true then call for update function otherwise call for save function.
Change this
<form class="form-horizontal" ng-submit="saveEmpDetils(); update()" novalidate="novalidate">
to
<form class="form-horizontal" ng-submit="saveEmpDetils();" novalidate="novalidate">
and your saveEmpDetails must be something like this
$scope.saveEmpDetails = function() {
if ($scope.isEdit) {
$scope.update() //your update function
} else {
//your save function
}
}

How to save all rows of a dynamic table in AngularJS?

I am trying to add the rows dynamically for one of the variables which is of type String array in my db. But it only saves the last value entered in the row rather than saving all of them in an array. Below is my view code:
<div class="row" ng-class='{red:true}'>
<label for="remedy">Remedy</label>
</div>
<input name="remedy" id="remedy" ng-model="error.remedy" required>
<br/>
<div class="row" ng-class='{red:true}'>
<a href="#!/errorcreate" class="btn btn-primary btn-small" ng-click="addRemedyRow()" ng-class='{red:true}'>Add Row</a></div>
<br/>
<table style="width:100%">
<thead>
<tr>
<th ng-class='{red:true}'>Remedy</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="rowContent in remedyrows">
<td>{{rowContent.remedy}}</td>
</tr>
</tbody>
</table>
{{error.remedy}}
<button type="submit" class="btn btn-default">Create</button>
Cancel
And this is the code in javascript:
$scope.remedyrows = [];
$scope.addRemedyRow = function() {
$scope.remedyrows.push({
remedy: $scope.error.remedy
});
Below is the output I am receiving (in a screenshot):
I added dsdfg as second row and my final error.remedy value just shows dsdfg rather than showing an array of both values : [wdssdsd,dsdfg]. error is the main document of which remedy is one of the fields of type String array.
Any ideas on how to achieve this?
Instead of error.remedy, which is used as holder for future remedyrow, use intermediate variable output for displaying results and sending them to the server:
Javascript:
$scope.output = $scope.remedyrows.map(function(x) { return x.remedy; });
$http({data: $scope.output, method: 'POST', url: url});
HTML:
{{output | json}}
you could have achieved it by following way:
$scope.remedyrows = [];
$scope.output;
$scope.addRemedyRow = function() {
$scope.remedyrows.push({
remedy: $scope.error.remedy
});
$scope.output = $scope.remedyrows.toString();
}
and in html
{{output}}

Angular Show Password after click

I have an inventory page that also contains a password field.
I would like to hide the password when the page is loaded, best would be to have points displayed **** and after click password is shown or a pop up.
JS
var get_cert = function () {
$http.get($scope.url.cert_list).then(
function (response) {
$scope.certs = response.data;
}
);
}
// execute get function
get_cert();
HTML
<div class="panel panel-default">
<table class="table table-striped valign_middle">
<tr class="table_header">
<td>Name</td>
<td>Pass</td>
</tr>
<tr ng-repeat="cert in certs | filter:search | orderBy:['name']">
<td>{{cert.name}}</td>
<td>
<button class="w3-btn w3-black w3-hover-green w3-ripple" ng-click="get_cert()">Show</button>
<span ng-show="get_cert()">{{cert.password}}</span>
</td>
</tr>
</table>
<button ng-show="!cert.showPw" class="w3-btn w3-black w3-hover-green w3-ripple" ng-click="cert.showPw = true">Show</button>
<span ng-show="cert.showPw">{{cert.password}}</span>
You can use ng-click to do cert.showPw = true, which will append a property called showPw (a boolean) to the object. Combined with ng-show, you can easily switch between the two.
This way you'll keep your controller free of any additional logic needed. You may include ng-click on the span which holds the password which will set showPw = false to switch it back to a button.
See my JSFiddle for full example.
Create a input
<input type="password" name="???">
Then you can change its type to "text" with
$("#idOfInout")type = 'text';

Extracting value of checkbox generated dynamically through flask

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

MVC/Javascript: how to post an array of integers in a form submission?

Before doing a form submit for my MVC webpage, I want to see a list of key fields to the controller. However the parameter on the controller is null.
My JavaScript is as follows;
$("#savePropertiesToBeAssigned").click(function (e) {
e.preventDefault();
var $propertyIds = $("#propertyRows").find($(".selectProperty:checked"));
var propertyIds = [];
$.each($propertyIds, function () {
var propertyId = $(this).data("msurvey-property-id");
propertyIds.push(propertyId);
});
var $form = $(this).closest("form")[0];
$form.action += "?PropertyIds=" + propertyIds + "&page=" + GetHiddenField("msurvey-page");
$form.submit();
});
The MVC Action is;
[HttpPost]
public async Task<ActionResult> AddFromContract(int[] PropertyIds, int? page)
{
var pageNumber = page.GetValueOrDefault(1);
return RedirectToAction("AddFromContract", new { page = pageNumber });
}
The PropertyIds comes through wrongly as null, whilst the page has the correct value.
EDIT - I am displaying the View in response to a comment:
#{
ViewBag.Title = "Add properties from the contract into the survey";
}
#using (Html.BeginForm("AddFromContract", "PropertySurvey", FormMethod.Post))
{
<div id="hiddenFields"
data-msurvey-page="#ViewBag.Page"></div>
<input type="hidden" id="propertyIds" name="propertyIds" />
<fieldset>
<legend>#ViewBag.Title</legend>
#if (ViewBag.PagedList.Count > 0)
{
<section id="PropertyList" style="margin-right: 28px;">
<p>
The properties below have already been added to the contract <b>#SessionObjectsMSurvey.SelectedContract.ContractTitle</b>, but are NOT in this survey
<b>#SessionObjectsMSurvey.SelectedContract.SurveyTitle.</b>
</p>
<table class="GridTbl">
<thead>
<tr>
<th>UPRN</th>
<th>Block UPRN</th>
<th>Address</th>
<th style="text-align: center;">
Select All<br/>
<input type="checkbox" id="selectAll"/>
</th>
</tr>
</thead>
<tfoot>
<tr>
<td colspan="3" style="text-align: right;">Select the properties you want to include in the survey, and click on the Save button.</td>
<td style="text-align: center;">
<button id="savePropertiesToBeAssigned" class="btn-mulalley">
Save
</button>
</td>
</tr>
</tfoot>
<tbody id="propertyRows">
#foreach (var property in ViewBag.PagedList)
{
<tr>
<td>#property.UPRN</td>
<td>#property.BlockUPRN</td>
<td>#property.Address</td>
<td style="text-align: center;">
<input type="checkbox"
name="selectProperty"
class="selectProperty"
data-msurvey-property-id="#property.PropertyId"/>
</td>
</tr>
}
</tbody>
</table>
#Html.PagedListPager((IPagedList) ViewBag.PagedList, page => Url.Action("AddFromContract", new {page}))
</section>
}
else
{
<p>Either no properties have been entered, or all of them have been assigned to the survey.</p>
}
</fieldset>
}
#section scripts
{
#Scripts.Render("~/bundles/page/propertyTransfer")
}
There is no need for any javascript to solve this. You already have checkbox elements in you form, and if they have the correct name and value attributes, they will bind to your model in the POST method.
Delete the <input type="hidden" id="propertyIds" name="propertyIds" /> and change the the view to
#foreach (var property in ViewBag.PagedList)
{
<tr>
<td>#property.UPRN</td>
....
<td style="text-align: center;">
<input type="checkbox" name="propertyIds" value="#property.PropertyId" />
</td>
</tr>
}
and delete the script.
When the form submits, the value of all checked checkboxes will be sent to the controller, and because the checkbox has name="propertyIds" they will bind to your int[] PropertyIds in the POST method.
You will also need to change <div id="hiddenFields" data-msurvey-page="#ViewBag.Page"></div> to
<input type="hidden" name="page" value="#ViewBag.Page" />
Side note: I recommend you start using view models rather that using ViewBag, including a view model for the collection, which would contain properties int ID and bool IsSelected so that you can strongly type your view to your model.

Categories