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
Related
I am using mongoose-paginate-v2 on the backend to paginate the response from my DB. I am trying to setup the front end to move through the data and send a request for the new data as needed. (That part seems to be working). The problem I am having is the DOM seems to freak out after pressing the next / back buttons a few times. VIDEO of problem which is at the end of the 20sec vid: (https://drive.google.com/file/d/1btfeKqXELEMmBnFPpkCbBLY5uhrC1bvE/view?usp=sharing)
What I have tried: I have tried .emtpy, .remove, and now .replace all seem to have the same problem. I have also moved the code around to try and make it unti the prior .then() was complete. Here is the code:
Front End:
<% include ../partials/header%>
<div class="container-fluid pt-3">
<div class='row'>
<div class="col-md-1">
<button class="btn btn-outline-primary sticky-top">Start New Call</button>
</div>
<div class="col-md-11">
<table class="table">
<thead class="sticky-top">
<tr>
<th scope="col">Incident #</th>
<th scope="col">Type</th>
<th scope="col">Location</th>
<th scope="col">Units</th>
<th scope="col">Dispatch</th>
<th scope="col">Clear</th>
<th scope="col">Disposition</th>
<th scope="col">Recall</th>
</tr>
</thead>
<tbody id="callTable">
<tr id="row1"><td></td></tr>
<tr id="row2"><td></td></tr>
<tr id="row3"><td></td></tr>
<tr id="row4"><td></td></tr>
<tr id="row5"><td></td></tr>
<tr id="row6"><td></td></tr>
<tr id="row7"><td></td></tr>
<tr id="row8"><td></td></tr>
<tr id="row9"><td></td></tr>
<tr id="row10"><td></td></tr>
</tbody>
</table>
<div class="row">
<div class="col-3"></div>
<div class="text-center col-2">
<button id="back" class="btn btn-outline-success mr-auto"><i class="fas fa-step-backward"></i><strong>Back</strong></button>
</div>
<div class="justify-content-center d-flex col-2 align-items-center">
<strong>Page <span id="pgnum">##</span> of <span id="totalpgs">##</span></strong>
</div>
<div class="text-center col-2">
<button id="next" class="btn btn-outline-success ml-auto"><strong>Next</strong><i class="fas fa-step-forward"></i></button>
</div>
<div class="text-center col-3"></div>
</div>
</div>
</div>
</div>
<% include ../partials/footer %>
<script>
//Data Management Script
let list=[];
axios.get('/api/cnc/incidents')
.catch(err=>{
console.log(err);
})
.then(data=>{
return list=data;
})
//Setup Function to get data...
async function getPage(page){
axios.get('/api/cnc/incidents/'+page)
.catch(err=>{
console.log(err);
})
.then(response=>{
console.log(response);
calls = response.data.docs;
callNumber = 'Not Assigned';
next = response.data.hasNextPage,
back = response.data.hasPrevPage,
nextPage = response.data.nextPage,
prevPage = response.data.prevPage;
$('#pgnum').text(response.data.page);
$('#totalpgs').text(response.data.totalPages);
if(next === true){
$('#next').removeAttr('disabled');
$('#next').click(function () {
getPage(nextPage);
});
}else{
$('#next').attr('disabled', 'disabled');
}
if(back === true){
$('#back').removeAttr('disabled');
$('#back').click(function () {
getPage(prevPage);
});
}else{
$('#back').attr('disabled', 'disabled');
}
// activities.sort((a, b) => b.date - a.date)
calls.sort((a, b) => (a.times.dispatch > b.times.dispatch) ? -1 : 1)
return calls;
}).then(calls=>{
let i = 1;
calls.forEach(call => {
//Set default callNumber.
callNumber = 'Not Assigned'
//Update to call number from DB.
if(call.incidentNumber){
callNumber = call.incidentNumber;
}
//Change _id to Radio ID.
if(call.units.length > 0){
let assignedUnits = call.units;
let idArray = list.data[0];
const filtered = [];
function compare(assignedUnits,idArray){
assignedUnits.forEach((unit)=>{
idArray.forEach((unitId)=>{
if(unit === unitId._id){
filtered.push(unitId.id);
}
})
})
return filtered;
}
compare(assignedUnits, idArray);
callUnits = filtered.join(', ');
}else{
callUnits = ['None']
}
if(typeof call.disposition !== 'undefined'){
callDisposition = call.disposition.selected;
}else{
callDisposition = '';
}
if(call.times.clear === undefined){
callClear = '';
}else{
callClear = call.times.clear;
}
//Insert Data into DOM. and make TR the link to edit
$('#row'+i).replaceWith('<tr id="row'+i+'" onClick="editRun(\''+call._id+'\')"><th>'+callNumber+'</th><td>'+call.callType+'</td><td>'+call.address.placeName+' '+call.address.streetAddress+'</td><td>'+callUnits+'</td><td>'+call.times.dispatch+'</td><td>'+callClear+'</td><td>'+callDisposition+'</td><td id="recall">'+call.recall.length+' personnel</td></tr>');
i++;
});
})
}
//Get the first page of data...
getPage(1);
function editRun(runId){
window.location.href= '/api/cnc/incident/input/'+runId;
}
//Update Navbar correctly
$('document').ready(function(){
$('.top-nav').removeClass('active').addClass('text-light').removeClass('text-dark');
$('#incidentTab').addClass('active').addClass('text-dark').removeClass('text-light');
});
</script>
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:
I have tried to implement this paging solution that I found online from this link:
http://jasonwatmore.com/post/2016/01/31/AngularJS-Pagination-Example-with-Logic-like-Google.aspx
I think the issue is in the way the functions are called, because the setPage function gets called before I have all my data so it does not know how many total items there are to be displayed etc. Can someone take a quick look and see what I'm doing wrong?
function HistoryController($window, $scope, $modal, $state, toaster, PagerService, HistoryFactory, $timeout) {
var vm = this;
vm.uploads = [];
vm.includeCancelled = false;
vm.uploadDataModal = {};
vm.pager = {};
vm.setPage = setPage;
activate();
function activate() {
getHistory();
vm.setPage(1);
}
function setPage(page) {
if (page < 1 || page > vm.pager.totalPages) {
return;
}
// get pager object from service
vm.pager = PagerService.GetPager(vm.uploads.length, page);
// get current page of items
vm.items = vm.uploads.slice(vm.pager.startIndex, vm.pager.endIndex + 1);
}
function getHistory() {
HistoryFactory.getHistory(vm.includeCancelled).then(
function(response) {
_.each(response.data, function(upload) {
upload.inProgress = upload.status && ['INPROGRESS','NEW'].indexOf(upload.status.statusCd.trim()) > -1;
});
vm.uploads = response.data;
if($state.params.reupload){
uploadProductionData();
$state.params.reupload = false;
}
});
}
Here is the html
<div class="chrthdr" ui-view="header"></div>
<div id="userResults">
<div class="card card-full-width">
<div class="card-header dark-blue">
<a class="card-config" data-toggle="uploadHistory" data-placement="left"><i class="glyphicon glyphicon-info-sign"></i></a>
<div class="card-title">Data History</div>
</div>
<div class='form-horizontal range-date' style="overflow-y: auto;">
<form>
<div class="panel-body">
<div>
<span class="btn btn-primary btn-xs pull-left" style="margin-bottom: 5px; margin-right: 5px" type="button" ng-click="vm.uploadProductionData()">Upload Data</span>
<label>
<input type="checkbox" ng-model="vm.includeCancelled">Include removed executions
</label>
<!--<span class="btn btn-primary btn-xs pull-left" style="margin-bottom: 5px; margin-left: 5px" type="button" ng-click="vm.viewTemplates()">Download Template</span>-->
</div>
<div>
<table class="table">
<tr>
<th>Upload Date</th>
<th>Product</th>
<th>Comments</th>
<th>Template</th>
<th>Last Updated By</th>
<th>Last Updated</th>
<th>Status</th>
<th>Actions</th>
</tr>
<tr ng-repeat="upload in vm.uploads | orderBy:'uploadDate':true">
<td style="white-space: nowrap;">{{upload.uploadDate}}</td>
<td>{{upload.product}}</td>
<td style="white-space: nowrap;">{{upload.comments}}</td>
<td style="white-space: nowrap;">{{upload.templateName}}</td>
<td style="white-space: nowrap;">{{upload.lastUpdatedByUser}}</td>
<td style="white-space: nowrap;">{{upload.lastUpdateDate}}</td>
<td style="white-space: nowrap;">{{upload.status.statusName}}</td>
<td>
<button class="btn btn-primary btn-xs pull-left" style="margin-bottom: 5px; " ng-hide="upload.status.statusCd === 'NEW' || upload.status.statusCd === 'ERROR'" ng-click="vm.loadStagingPage(upload.dataLoadExecutionId, upload.product, upload.status)">View</button>
<span class="btn btn-primary btn-xs pull-left" style="margin-bottom: 5px; " type="button" ng-click="vm.cancelDataExecution(upload.dataLoadExecutionId)" ng-show="upload.inProgress || upload.status.statusCd === 'ERROR'">Remove</span>
</td>
</tr>
</table>
</div>
<div class="text-center">
<ul ng-if="vm.pager.pages.length" class="pagination">
<li ng-class="{disabled:vm.pager.currentPage === 1}">
<a ng-click="vm.setPage(1)">First</a>
</li>
<li ng-class="{disabled:vm.pager.currentPage === 1}">
<a ng-click="vm.setPage(vm.pager.currentPage - 1)">Previous</a>
</li>
<li ng-repeat="page in vm.pager.pages" ng-class="{active:vm.pager.currentPage === page}">
<a ng-click="vm.setPage(page)">{{page}}</a>
</li>
<li ng-class="{disabled:vm.pager.currentPage === vm.pager.totalPages}">
<a ng-click="vm.setPage(vm.pager.currentPage + 1)">Next</a>
</li>
<li ng-class="{disabled:vm.pager.currentPage === vm.pager.totalPages}">
<a ng-click="vm.setPage(vm.pager.totalPages)">Last</a>
</li>
</ul>
</div>
</div>
</form>
</div>
</div>
This is a very common mistake of not understanding asynchronous calls.
HistoryFactory.getHistory(vm.includeCancelled).then({}) is async, meaning that it will make the call and then continue executing code after the async call. When the async call has finished, the code inside .then({}) will then execute which could be 5 milliseconds or 5 seconds.
So here:
function activate() {
getHistory(); // async call, doesn't wait
vm.setPage(1); // executed immediately after, data not ready
}
Needs to be:
function activate() {
getHistory();
}
And changegetHistory() to:
function getHistory() {
HistoryFactory.getHistory(vm.includeCancelled).then(
function(response) {
_.each(response.data, function(upload) {
upload.inProgress = upload.status && ['INPROGRESS','NEW'].indexOf(upload.status.statusCd.trim()) > -1;
});
vm.uploads = response.data;
if($state.params.reupload){
uploadProductionData();
$state.params.reupload = false;
}
// Now call setPage after data is finished
vm.setPage(1);
});
}
In the following html code, when one row is in an editing mode(the edit button on this row is clicked), the edit button on the rest of the rows shall be disabled. And when one row is in the edit mode, data will show up in a text input field.
<table class="table">
<thead>
<tr>
<th class="col-sm-4">Branch Name</th>
<th class="col-sm-3">Branch ID</th>
<th class="col-sm-3">Foo</th>
<th class="col-sm-1">Doo</th>
<th class="col-sm-3"></th>
</tr>
</thead>
<tr ng-repeat="branch in branches">
<td id="name" ng-bind="branch.name"></td>
<td id="ID" ng-bind="branch.id"></td>
<td id="foo" data-editable>
<span ng-hide="editMode" ng-bind="branch.foo"></span>
<input class="form-control" data-ng-show="editMode" id="foo" data-ng-model="branch.foo"/>
</td>
<td id="doo" data-editable>
<span ng-hide="editMode" ng-bind="branch.doo"></span>
<input class="form-control" data-ng-show="editMode" id="do" ng-model="branch.doo"/>
</td>
<td>
<button type="submit" class="btn btn-default" data-ng-disabled="editing" data-ng-show="!editMode" data-ng-click="editMode = true; editEntry(branch)">Edit</button>
<span ng-show="editMode" class="pull-right">
<button type="submit" class="btn btn-default" data-ng-disabled="!enableToSave(branch)" data-ng-click="editMode = false; saveEntry(branch)">Save</button>
<button type="submit" class="btn btn-default" ng-show="editMode" data-ng-click="editMode = false; cancelEditing(branch)">Cancel</button>
</span>
</td>
</tr>
</table>
The control mechanics is the "editMode".The Javascript/AngulaJS code is something like the followings:
$scope.editing = false;
$scope.editEntry = function(branch) {
if ($scope.editing !== false) {
...
} else {
$scope.editing = true;
....
}
}
$scope.saveEntry = function(branch){
...
$scope.editing = false;
}
$scope.cancelEditing = function(branch){
if ($scope.editing !== false) {
$scope.editing = false;
...
}
}
$scope.enableToSave = function(branch){
...
}
The approach, however, doesn't seem to be reliable. Any better approaches?
Try to use ng-repeat instance instead of single model
Like this
<button type="submit" class="btn btn-default" data-ng-disabled="branch.isDisable" data-ng-click="saveEntry(branch)">Save</button>
<button type="submit" class="btn btn-default" ng-show="branch.isDisable" data-ng-click="cancelEditing(branch)">Cancel</button>
Create a mapper when click on edit make other disabled
Like this
$scope.editEntry = function(branch) {
branch.isDisable=false;
$scope.branches.forEach(function(x){
if(x.id!=branch.id)
x.isDisable=true;
})
}
You need a parametric check on your table:
<tr ng-repeat="branch in branches" ng-disabled="editingOther(branch.id)">
...
<button type="submit" class="btn btn-default" data-ng-disabled="editing" data-ng-click="editEntry(branch)">Edit</button>
then in Angular
$scope.editing = false;
$scope.editing_entry = null;
$scope.editEntry = function(branch) {
$scope.editing = true;
$scope.editing_entry = branch.id;
}
$scope.editingOther = function(branch_id) {
return $scope.editing && $scope.editing_entry != branch_id;
}
I put a ng-disabled on the tr element as an example, you will need to build your own desired logic for the other rows.
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.