Delete data-id attribute value - javascript

I am new on javascript yet. I trying to delete value with data-id button, but data-id value is get always first value on my table. I click on the button with the data-id of "5" but as the id it is "1" (the topmost id) every time. Sorry my bad english.
My table codes:
<table class="table table-striped">
<thead>
<tr>
<th>#</th>
<th>Category Name</th>
<th>Status</th>
<th>User</th>
<th>Management</th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td><span class="label label-success">#item.ID</span></td>
<td>#item.CategoryName</td>
<td>#if (item.Status == true)
{
<b class="label label-success">Active</b>
}
else
{
<b class="label label-danger">Passive</b>
}
</td>
<td>#item.User.Name</td>
<td>
<button class="btn btn-default btn-sm">Edit</button>
<button class="btn btn-default btn-sm" id="btn-Delete" onclick="DeleteCategory()" data-id="#item.ID">Delete</button>
</td>
</tr>
}
</tbody>
</table>
My javascript codes:
function DeleteCategory() {
var caughtID= $("#btn-Delete").attr("data-id");
$.ajax({
url: "/Category/Delete/" + caughtID,
type: "POST",
dataType: "json",
success: function (response) {
if (response.Success) {
bootbox.alert(response.Message, function () {
location.reload();
});
}
else {
bootbox.alert(response.Message, function () {
//it's null yet
});
}
}
})
}

Id need to be unique, but in your case without id also it can be achievable, what you want to do.
Change:-
onclick="DeleteCategory()"
To:-
onclick="DeleteCategory(this)"
And then:-
function DeleteCategory(ele) {
var caughtID= $(ele).data("id");
.....rest code
DEMO EXAMPLE:-
function DeleteCategory(ele){
alert($(ele).data('id'));
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<button class="btn btn-default btn-sm" id="btn-Delete" onclick="DeleteCategory(this)" data-id="1">Delete</button>
<button class="btn btn-default btn-sm" id="btn-Delete" onclick="DeleteCategory(this)" data-id="2">Delete</button>
<button class="btn btn-default btn-sm" id="btn-Delete" onclick="DeleteCategory(this)" data-id="3">Delete</button>
A pure jQuery solution is:-
change id="btn-Delete" to class ="btn-Delete" and remove onclick like below:-
<button class="btn btn-default btn-sm btn-Delete" data-id="#item.ID">Delete</button>
And then change only this line:-
var caughtID= $("#btn-Delete").attr("data-id");
To:-
var caughtID = $(this).data("id");

As Rory commented id attributes must be unique!. You should change the id of the button to class and make click on the static element. Because the button is dynamically created it may cause a problem that you are facing.
<button class="btn btn-default btn-sm btn-Delete" data-id="#item.ID">Delete</button>
$(document).ready(function() {
$('table').on('click', '.btn-Delete', function(event) {
event.preventDefault();
var caughtID = $(this).attr("data-id");
$.ajax({
url: "/Category/Delete/" + caughtID,
type: "POST",
dataType: "json",
success: function(response) {
if (response.Success) {
bootbox.alert(response.Message, function() {
location.reload();
});
} else {
bootbox.alert(response.Message, function() {
//it's null yet
});
}
}
})
});
});

Related

Angularjs orderBy in ng-repeat is affecting index. How to remove the correct elements from array?

I have an array of values I'm displaying in a table. When I don't order them, my removal code works exactly as intended. I would like to order the values in the ng-repeat to group the data by role name, but that makes my splice function remove the wrong value. What is the correct way to remove my selected value?
Html that works:
<tbody data-ng-repeat="oneUserRole in ui.userRoleResultsList track by $index">
<tr>
<td>{{oneUserRole.UserId}}</td>
<td>{{oneUserRole.RoleName}}</td>
<td>{{oneUserRole.Details}}</td>
<td class="text-center">
<button type="button" class="btn btn-sm btn-danger" title="Delete" data-ng-click="ui.removeUserRole($index)"><i class="fa fa-trash-o" aria-hidden="true"></i></button>
<td>
</tr>
<tbody>
Html that doesn't work (sorts as desired, but removal doesn't work due to issue with index):
<tbody data-ng-repeat="oneUserRole in ui.userRoleResultsList | orderBy: 'RoleName' track by $index">
<tr>
<td>{{oneUserRole.UserId}}</td>
<td>{{oneUserRole.RoleName}}</td>
<td>{{oneUserRole.Details}}</td>
<td class="text-center">
<button type="button" class="btn btn-sm btn-danger" title="Delete" data-ng-click="ui.removeUserRole($index)"><i class="fa fa-trash-o" aria-hidden="true"></i></button>
<td>
</tr>
<tbody>
JavaScript:
$scope.ui.removeUserRole = function (index) {
// remove row from array.
$scope.ui.userRoleResultsList.splice(index, 1);
// other code to remove selected item from db omitted here.
}
If u would change
<button type="button" class="btn btn-sm btn-danger" title="Delete" data-ng-click="ui.removeUserRole($index)"><i class="fa fa-trash-o" aria-hidden="true"></i></button>
to
<button type="button" class="btn btn-sm btn-danger" title="Delete" data-ng-click="ui.removeUserRole({oneUserRole.UserId)"><i class="fa fa-trash-o" aria-hidden="true"></i></button>
And then make it filter out on userId like so :
$scope.ui.removeUserRole = function (userId) {
for(let i = $scope.ui.userRoleResultsList.length; i > 0; i--) {
if(userId == $scope.ui.userRoleResultsList[i]) {
$scope.ui.userRoleResultsList.splice(i, 1);
break;
}
}
}
It should work I think
I ended up trying the suggestions of both Jelle and Frank Modica. Thanks to each of you for your quick responses. The most efficient way was to pre-filter the list coming from the controller, rather than change the html.
Here is my controller function that gets the data into the $scope.ui.userRoleResultsList:
// ******************************************************************
// Get the existing active User Roles
// ******************************************************************
function LoadUserRoleResultsList() {
var errorSummary = 'Error retrieving UserRoles list';
$scope.ui.userRoleResultsList = [];
$scope.promise =
$http.get(appConfig.GetRootUrl() + '/AdminUserRoles/UserRoleList')
.then(function onSuccess(response) {
var result = apiResponseParser.Parse(response);
if (result.isSuccessful && result.data !== null) {
// presort by rolename.
$scope.ui.ddlUserRoleTypes = result.data;
$scope.ui.userRoleResultsList = $filter('orderBy')($scope.ui.ddlUserRoleTypes, 'RoleName');
}
else {
ReportErrorMessage(errorSummary, result.message);
}
})
.catch(function onError(response) {
console.log(response, " = caught response Error");
ReportHttpError(errorSummary, response);
});
}
The magic is in the two lines after the // presort by rolename comment.

Laravel and Javascript - Deleting multiple rows from database

I am trying to delete several items from a database using checkboxes and javascript. The code I have already works and deletes the rows, however I am getting an error and that error actually prevents the page from refreshing and thus shwoing the updates results.
Here is what I have:
Route
Route::delete('/admin/videos/deleteselected', 'VideosController#deleteAllSelected')->name('videos.deleteAllSelected');
Controller
public function deleteAllSelected(Request $request)
{
$ids = $request->ids;
Video::where('id',explode(",",$ids))->delete();
//store status message
Session::flash('success_msg', 'Video(s) deleted successfully!');
return redirect()->route('videos.index');
}
View
<!-- videos list -->
#if(!empty($videos))
<div class="row text-center">
<div>
{{ $videos->links() }}
</div>
</div>
<div class="content table-responsive table-full-width">
<table class="table table-striped">
<button style="margin-bottom: 10px" class="btn btn-primary delete_all" data-url="{{ route('videos.deleteAllSelected') }}">Delete All Selected</button>
<thead>
<th>ID</th>
<th><input type="checkbox" id="master"></th>
<th>Thumb</th>
<th>Duration</th>
<th>Manage</th>
</thead>
<!-- Table Body -->
<tbody>
#foreach($videos as $video)
<tr id="tr_{{$video->id}}">
<td>
<div>
{{$video->id}}
</div>
</td>
<td>
<div class="text-center">
<input type="checkbox" class="sub_chk" data-id="{{$video->id}}">
</div>
</td>
<td>
<div>
<img class="img-thumbnail" src="{{$video->imgurl}}" alt="video thumbnail">
</div>
</td>
<td>
<div>
{{$video->duration}}
</div>
</td>
<td>
<div><i class="fa fa-info"></i> Details</div>
<div><i class="fa fa-pencil"></i> Edit</div>
<div><i class="fa fa-trash"></i> Delete</div>
</td>
</tr>
#endforeach
</tbody>
</table>
</div>
<div class="row text-center">
{{ $videos->links() }}
</div>
#endif
Javascript Code
$(document).ready(function () {
$('#master').on('click', function(e) {
if($(this).is(':checked',true))
{
$(".sub_chk").prop('checked', true);
} else {
$(".sub_chk").prop('checked',false);
}
});
$('.delete_all').on('click', function(e) {
var allVals = [];
$(".sub_chk:checked").each(function() {
allVals.push($(this).attr('data-id'));
});
if(allVals.length <=0)
{
alert("Please select videos.");
} else {
var check = confirm("Are you sure you want to delete this ?");
if(check == true){
var join_selected_values = allVals.join(",");
$.ajax({
url: $(this).data('url'),
type: 'DELETE',
headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')},
data: 'ids='+join_selected_values,
success: function (data) {
if (data['success']) {
$(".sub_chk:checked").each(function() {
$(this).parents("tr").remove();
});
alert(data['success']);
} else if (data['error']) {
alert(data['error']);
} else {
alert('Whoops Something went wrong!!');
}
},
error: function (data) {
alert(data.responseText);
}
});
$.each(allVals, function( index, value ) {
$('table tr').filter("[data-row-id='" + value + "']").remove();
});
}
}
});
$('[data-toggle=confirmation]').confirmation({
rootSelector: '[data-toggle=confirmation]',
onConfirm: function (event, element) {
element.trigger('confirm');
}
});
$(document).on('confirm', function (e) {
var ele = e.target;
e.preventDefault();
$.ajax({
url: ele.href,
type: 'DELETE',
headers: {'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')},
success: function (data) {
if (data['success']) {
$("#" + data['tr']).slideUp("slow");
alert(data['success']);
} else if (data['error']) {
alert(data['error']);
} else {
alert('Whoops Something went wrong!!');
}
},
error: function (data) {
alert(data.responseText);
}
});
return false;
});
});
The error i get i cant actually copy it as it appears in a javascript alert. But please find attached an image of it:

Is there a way to use the info from <tr> body fields in dropdown?

This is the code I want to place in a dropdown menu.
<tbody id="todoist_table_list_tbody">
<tr>
<td field='task_name'>Title </td>
<td field='task_priority'>Priority</td>
<td field='task_due_date'>Due Date</td>
<td field='task_created_date'>Date Added</td>
<td>
<button class="btn btn-sm btn-primary pull-right m-t-n-xs"
field='delete_task' type="submit"><strong>Delete</strong></button>
<button class="btn btn-sm btn-primary pull-right m-t-n-xs"
field='start_timer' type="submit"><strong>Start</strong></button>
<button class="btn btn-sm btn-danger pull-right m-t-n-xs"
field='stop_timer' type="submit"><strong>Stop</strong></button>
</td>
</tr>
</tbody>
I have an existing body where all this works according to which row. I want to place all of this in a dropdown to select which ever node I want.
function end_timer(){
if (timer_instance_dictionary != null){
timer_instance_dictionary['end_time'] = moment().format()
historical_times.push(timer_instance_dictionary)
timer_instance.set({})
clearInterval(timer_interval)
}
}
$("button[field='start_timer']").click( function(){
end_timer()
task_id = $(this).closest("tr").attr("id")
upload_dictionary = current_tasks_dictionary[String(task_id)]
upload_dictionary['start_time'] = moment().format()
upload_dictionary['task_id'] = task_id
timer_instance.set(upload_dictionary)
})
$("button[field='stop_timer']").click( function(){
end_timer()
})
$("button[field='delete_task']").click( function(){
task_id = $(this).closest("tr").attr("id")
upload_dictionary = current_tasks_dictionary[String(task_id)]
upload_dictionary['deleted_time'] = moment().format()
archived_tasks.push(upload_dictionary)
todoist_delete_task(task_id)
alert(task_id)
})
function endTimer() {
console.log("ended timer");
// End timer code here
}
function startTimer() {
console.log("started timer");
// Start timer code here
}
function stopTimer() {
console.log("stopped timer");
// Stop timer code here
}
$(".choice").change(function() {
if ($(this).val()==="Start") {
startTimer();
} else if ($(this).val()==="Stop") {
stopTimer();
} else if ($(this).val()==="End") {
endTimer();
}
});
$(".choice2").change(function() {
var $val=$(this).val();
if ($val==="Start") {
startTimer();
} else if ($val==="Stop") {
stopTimer();
} else if ($val==="End") {
endTimer();
}
$(".choice2").each(function() {
$(this).val($val);
});
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<select class='choice'><option>Timer Options</option><option>Start</option><option>Stop</option><option>End</option></select>
<select class='choice'><option>Timer Options</option><option>Start</option><option>Stop</option><option>End</option></select>
<select class='choice'><option>Timer Options</option><option>Start</option><option>Stop</option><option>End</option></select>
<select class='choice2'><option>Timer Options</option><option>Start</option><option>Stop</option><option>End</option></select>
<select class='choice2'><option>Timer Options</option><option>Start</option><option>Stop</option><option>End</option></select>
<select class='choice2'><option>Timer Options</option><option>Start</option><option>Stop</option><option>End</option></select>
Depending on what you want, I think the choice 1 class and choice 2 class display features that would be useful to you.

Automatic scroll not working on click in angularJS

I have to scroll in a particular block(in may case table) when I will click on button.
vm.uploadOmrFile = function() {
vm.formSubmitted = true;
if (!vm.partners) {
return;
} else if (!vm.omrConfigurations) {
return;
} else if (!vm.schools) {
return;
} else if (!vm.classes) {
return;
}
formdata.append('classId', vm.configuration.classId);
// formdata.append('omrConfigId', vm.configuration.omrConfigId);
formdata.append('schoolId', vm.configuration.schoolId);
// formdata.append('tenantId', vm.configuration.tenantId);
var request = {
method: 'POST',
url: xxxxxx,
data: formdata,
transformRequest : angular.identity,
headers: {
'Content-Type': undefined
}
};
// SEND THE FILES.
$http(request)
.success(function (d) {
vm.badrecords = 0;
vm.uploadresponse = d;
vm.records = d.studentAssessments;
vm.records.forEach(function(record){
if(record.output.type == 'invalid-csv') {
vm.badrecords += 1;
}
})
})
.error(function (error) {
toastr(error);
});
setTimeout(function() {
// set the location.hash to the id of
// the element you wish to scroll to.
$location.path('/omr-upload');
$location.hash('message');
$anchorScroll();
}, 20000);
}
This is html file
<!doctype html>
<html>
<div class="modal-footer">
<button ng-click="vm.uploadOmrFile()" formnovalidate
class="btn btn-success" value="Upload"
dismiss="modal">Upload</button>
<button type="button" class="btn btn-danger" data-
dismiss="modal">Cancel</button>
</div>
<tr>
<td class="nopadding noborder">
<table class="table">
<tr>
<td colspan="4">
<div class="alert alert-danger" id="message" ng-
if="vm.uploadresponse vm.uploadresponse.hasError"
role="alert">{{vm.uploadresponse.hasError}}
<strong>{{vm.uploadresponse.message}}</strong>
<br> Total Records Parsed:{{vm.records.length}}
<br>RecordsError: {{vm.badrecords}}
</div>
<div class="alert alert-success" id="message" ng-
if="vm.uploadresponse && !vm.uploadresponse.hasError">
<strong>{{vm.uploadresponse.message}}</strong>
<br> Total Records Parsed : {{vm.records.length}}
<br>Records with Error: 0
</div>
</td>
</tr>
<tr ng-if="vm.uploadresponse &&
vm.uploadresponse.hasError">
<th>Name</th>
<th>Sheet ID</th>
<th>Record Type</th>
<th>Messages</th>
</tr>
<tr ng-repeat="record in vm.records" ng-
if="vm.uploadresponse && vm.uploadresponse.hasError">
<td>{{record.name}}</td>
<td>{{record.omrsheet}}</td>
<td>{{record.output.type}}</td>
<td>
<div style="height:100px;overflow-y:scroll">
<div ng-repeat="msg in record.output.messages"
class="error">
<p>{{msg}}</p>
</div>
</div>
</td>
</tr>
<tr ng-if="vm.uploadresponse &&
!vm.uploadresponse.hasError">
<td>
<h2><i class="glyphicon glyphicon-thumbs-up" aria-
hidden="true"></i> All records fine!
<button class="btn btn-warning btn-lg" ng-
click="vm.saveOMR()">Click to Save OMR
data</button>
</h2>
</td>
</tr>
</table>
</td>
</tr>
</html>
My problem is when i Click to upload button It should go table section of html and upload button calling "uploadOmrFile()".
In my case scroll not going to table section.
I am using id as "message", which is uses location.hash.
setTimeout(function()
{
document.getElementById('message').scrollIntoView({block: 'start',
behavior: 'smooth'}); },1000);`
Paste This code After getting response

Live search on a web grid table with pagination working only on the actual page

I want to implement a live search on a web grid table which has pagination. However, my search only shows elements which are present in the actual page. I want my search function to do a search on all the element present in the table. Not only the ones actually displayed. Below is my search script:
<script type="text/javascript">
$(document).ready(function () {
$("#filter").keyup(function () {
// Retrieve the input field text and reset the count to zero
var filter = $(this).val(), count = 0;
console.log(filter);
// Loop through each row of the table
$("table tr").each(function () {
// If the list item does not contain the text phrase fade it out
if ($(this).text().search(new RegExp(filter, "i")) < 0) {
$(this).fadeOut();
// Show the list item if the phrase matches and increase the count by 1
} else {
$(this).show();
count++;
}
});
/* var numberItems = count;
$("#filter-count").text("Number of Comments = "+count);*/
});
});
my html page:
<div>
<div id="homeMessage">
Please see below the list of books available.
</div>
<br />
<div id="divCurrentRented">
<form id="live-search" action="" class="styled" method="post">
<fieldset>
<input type="text" class="form-control" id="filter" value="" placeholder="Search by title or author..."/>
<span id="filter-count"></span>
</fieldset>
</form>
</div>
<br />
<div id="divCurrentRented">
#{
WebGrid obj = new WebGrid(Model, rowsPerPage: 5);
}
#obj.Table(htmlAttributes: new
{
id="tableCurrentRented",
#class = "table"
},
headerStyle: "webgrid-header",
footerStyle: "webgrid-footer",
alternatingRowStyle: "webgrid-alternating-row",
rowStyle: "webgrid-row-style",
columns: obj.Columns(
obj.Column("Title", header: "Title"),
obj.Column("Author", header: "Author"),
obj.Column("Avaible", header: "Available", canSort:false),
obj.Column(header: "Rent", format:#<button type="button" class="btn btn-default">Rent it</button>)
))
</div>
<div style="text-align:right">
#obj.Pager(mode: WebGridPagerModes.All)
</div>
<br />
Any idea of how to do this?
The HTML:
<table id="tableCurrentRented" class="table">
<thead>
<tr class="webgrid-header">
<th scope="col">
Title </th>
<th scope="col">
Author </th>
<th scope="col">
Available </th>
<th scope="col">
Rent </th>
</tr>
</thead>
<tbody>
<tr class="webgrid-row-style">
<td>Le Bossu de Notre Dame</td>
<td>Victor Hugo</td>
<td>Yes</td>
<td><button type="button" class="btn btn-default" data-toggle="modal" data-target="#myModal" data-id="9" data-title="Le Bossu de Notre Dame">Yes</button></td>
</tr>
<tr class="webgrid-alternating-row">
<td>Oliver Twist</td>
<td>Charles Dickens</td>
<td>Yes</td>
<td><button type="button" class="btn btn-default" data-toggle="modal" data-target="#myModal" data-id="1" data-title="Oliver Twist">Yes</button></td>
</tr>
<tr class="webgrid-row-style">
<td>Pride and Prejudice</td>
<td>Jane Austen</td>
<td>Yes</td>
<td><button type="button" class="btn btn-default" data-toggle="modal" data-target="#myModal" data-id="5" data-title="Pride and Prejudice">Yes</button></td>
</tr>
<tr class="webgrid-alternating-row">
<td>Sense and Sensibility</td>
<td>Jane Austen</td>
<td>Yes</td>
<td><button type="button" class="btn btn-default" data-toggle="modal" data-target="#myModal" data-id="6" data-title="Sense and Sensibility">Yes</button></td>
</tr>
<tr class="webgrid-row-style">
<td>The Mayor of Casterbridge</td>
<td>Thomas Hardy</td>
<td>Yes</td>
<td><button type="button" class="btn btn-default" data-toggle="modal" data-target="#myModal" data-id="3" data-title="The Mayor of Casterbridge">Yes</button></td>
</tr>
</tbody>
</table>
My controller method:
public ActionResult SearchBooks()
{
var listBook = datamanager.GetAllBooks();
List<ViewBook> listViewBook = new List<ViewBook>();
foreach (Book b in listBook)
{
ViewBook viewBook = new ViewBook();
viewBook.BookID = b.BookId;
viewBook.Title = b.Title;
viewBook.Author = b.Author;
if (b.Rented ?? true)
{
viewBook.Avaible = "No";
}
else
{
viewBook.Avaible = "Yes";
}
listViewBook.Add(viewBook);
}
return View(listViewBook);
}
I have succeeded in passing all the models of my list to the javascript:
var data = #Html.Raw(Json.Encode(Model));
However, when I do this:
$(data).each(function () {
to loop through each element of data, I get this error:
Cannot use 'in' operator to search for 'opacity' in undefined
Any idea how I can solve this?
Javascript
$("#filter").keyup(function () {
$.ajax({
type: "GET",
contentType: "application/json; charset=utf-8",
dataType: "json",
url: 'Search?q='+$("#filter").val(),
success:
function (result) {
$("#tableCurrentRented tbody").empty();
$.each(result.Books, function (index, item) {
var cls=(index%2==0)?"webgrid-row-style":"webgrid-alternating-row";
var html = ' <tr class="'+cls+'">'+
'<td>'+item.Title +'</td>'+
'<td>'+item.Author +'</td>'+
'<td>'+item.Avaible +'</td>'+
' <td><button type="button" class="btn btn-default" data-toggle="modal" data-target="#myModal" data-id="'+item.BookID +'" data-title="'+item.Title+'">'+item. +'</button></td></tr>';
$("#tableCurrentRented tbody").append(html);
});
},
error: function (xhr, status, err) {
}
});
});
Add new method for searching in controller
public ActionResult Search(string q)
{
var listBook = datamanager.GetAllBooks().Where(X=> X.Title.Contains(q)).ToList();
List<ViewBook> listViewBook = new List<ViewBook>();
foreach (Book b in listBook)
{
ViewBook viewBook = new ViewBook();
viewBook.BookID = b.BookId;
viewBook.Title = b.Title;
viewBook.Author = b.Author;
if (b.Rented ?? true)
{
viewBook.Avaible = "No";
}
else
{
viewBook.Avaible = "Yes";
}
listViewBook.Add(viewBook);
}
return Json(new { Books = listViewBook }, JsonRequestBehavior.AllowGet);
}
It seems you have a "Model" variable holding the data. Perhaps you should consider filtering the data in this Model directly and passing the filtered Model to the webgrid. The problem, how I understand it, is that you're trying to fetch already rendered values rather than considering the entire collection of data before rendering the filtered data.

Categories