In the past I've used jQuery/Ajax to capture the key press of an end user, and build up a WHERE clause to filter data on a Web form.
I'm now taking advantage of the strongly type facilitates in ASP.NET 4.5. I was wondering if anyone has a way of performing real-time filtering/searching on a Gridview.
Basically, I have three grids, all showing different information. I want the end-user to key in or select from a drop down list (generic searching) and all girds reflect those changes.
I'm not adverse to resorting back to the old method, just didn't; know if there was anything new I could use?
So you can look at this. I hope this help you.
Here is the HTML:
<input id="searchInput" value="Type To Filter">
<br/>
<table>
<thead>
<tr>
<th>Column1</th>
<th>Column2</th>
</tr>
</thead>
<tbody id="fbody">
<tr>
<td>cat</td>
<td>one</td>
</tr>
<tr>
<td>dog</td>
<td>two</td>
</tr>
<tr>
<td>cat</td>
<td>three</td>
</tr>
<tr>
<td>moose</td>
<td>four</td>
</tr>
<tr>
<td>mouse</td>
<td>five</td>
</tr>
<tr>
<td>dog</td>
<td>six</td>
</tr>
</tbody>
</table>
And here is the JavaScript code:
$("#searchInput").keyup(function () {
// Split the current value of searchInput
var data = this.value.split(" ");
// Create a jQuery object of the rows
var jo = $("#fbody").find("tr");
if (this.value == "") {
jo.show();
return;
}
// Hide all the rows
jo.hide();
// Recusively filter the jquery object to get results.
jo.filter(function (i, v) {
var $t = $(this);
for (var d = 0; d < data.length; ++d) {
if ($t.is(":contains('" + data[d] + "')")) {
return true;
}
}
return false;
})
// Show the rows that match.
.show();
}).focus(function () {
this.value = "";
$(this).css({
"color": "black"
});
$(this).unbind('focus');
}).css({
"color": "#C0C0C0"
});
Enter link description here
Related
I have a "DOM" list in MVC 4 using jQuery to add elements dynamically but at the moment of removing all the elements
The table no longer allows me to add more elements, I have tried to use length and comparisons but it does not work.
Am probably missing something obvious but can't see what it is. Any ideas?
Example
Here is my table code
<div><img src="~/Images/splus.png" alt="Add Product" style="border:0"/></div>
<table id="dataTable" border="0" cellpadding="0" cellspacing="0">
<thead>
<tr>
<th></th>
<th></th>
<th>Product</th>
<th>Quantity</th>
<th></th>
</tr>
</thead>
<tbody>
#if (Model != null && Model.Count > 0)
{
int j = 0;
int index = 1;
foreach (var i in Model)
{
<tr>
<td>#index</td>
<td>#Html.HiddenFor(a => a[j].SEQ_NO, new { id = "nrow", Value = index })</td>
<td>#Html.DropDownList("PRODUCTS", "Select Product")</td>
<td>#Html.TextBoxFor(a => a[j].QUANTITY)</td>
<td>
<img src="~/Images/sminus.png" alt="Add Product" style="border:0"/>
</td>
</tr>
index += 1;
j++;
}
}
</tbody>
</table>
Here is my jQuery Code when i click on Add New
$("#addNew").click(function (e) {
e.preventDefault();
var last = $('#dataTable>tbody>tr:last');
if (last.length > 0) {
var name = last.children().find('input,select')[0].name;
var index = Number(name.replace(/[^0-9]/gi, '')) + 1;
var tr = ('<tr>' + last.html().replace(/[0-9]+__/gi, index + '__') + '</tr>').replace(/\[[0-9]+\]+[.]/gi, '[' + index + '].');
numberRows($('#dataTable tbody').append(tr));
}
});
UPDATE:
Add "REMOVE CODE"
$(document).on('click', '#remove', function (e) {
e.preventDefault();
$(this).parent().parent().remove();
numberRows($('#dataTable tbody'));
});
Am probably missing something obvious but can't see what it is. Any ideas?
var name = last.children().find('input,select')[0].name;
This line of code requires one last child, which means after you removed the last under , the name will be undefined. In fact, the Add New function won’t even pass the if (last.length > 0) since when the last got removed, the last.length becomes 0.
You can debug in devtools, and will see:
BEFORE the last got removed:
AFTER the last got removed:
Thus, to fix this issue, the simplest solution is to not remove the last but hide it. Please check below code:
$(document).on('click', '#remove', function (e) {
e.preventDefault();
if ($('#dataTable>tbody>tr').length > 1) {
$(this).parent().parent().remove();
//numberRows($('#dataTable tbody'));
}
else {
$(this).parent().parent().hide();
}
});
Ps. Not sure what happens in numberRows() function so I commented it.
I'm developing a web application using Asp.Net Core(Razor Pages),and I have a table with three columns,one representing cellphone numbers,the other one text messages that are supposed to be sent to each one and the last one showing results.I'm looking for a way to update the last column of each row and have it highlighted as each messages is being sent to the cellphone number by clicking the Send To All button down the table.How can I accomplish it? Thanks for your responses in advance.
<div class="row mt-2">
<table class="table table-striped table-responsive-md">
<thead class="thead-dark">
<tr>
<th>
#Html.DisplayNameFor(model => model.MessageList[0].ReceiverCellPhone)
</th>
<th>
#Html.DisplayNameFor(model => model.MessageList[0].Text)
</th>
<th>
#Html.DisplayNameFor(model => model.MessageList[0].Result)
</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model.MessageList)
{
<tr>
<td>
#Html.DisplayFor(modelItem => item.ReceiverCellPhone)
</td>
<td>
#Html.DisplayFor(modelItem => item.Text)
</td>
<td>
#Html.DisplayFor(modelItem => item.Result)
</td>
<td></td>
</tr>
}
</tbody>
</table>
<button type=submit value=Send to All/>
</div>
I think in scenarios like this, we want to have our javascript as unobtrusive as possible by attaching events to actions through javascript rather than through the html attributes.
with that, you would probably want something like the following:
document.getElementById('ButtonId').addEventListener('click', function() {
// you are now in the button click context
// you can now either fire one asyncronous request which encapsulates all the
rows or you can iterate through the table rows and fire individual requests. The below shows the second example
var table = document.getElementById('TableId');
var url = "url to endpoint you want to call';
for (var i = 1; i < table.rows.length; i++) { // 1 so we miss the header
// get the relevant id of the request you want to send
var id = "whatever cell you need";
let request = new XMLHttpRequest();
request.onreadystatechange = function () {
if (this.readyState === 4) {
//success so you can change the cell you want to change
} else {
document.body.className = 'error';
}
}
request.open("post", url, true);
request.send('this should be whatever you want to send to the request - id object maybe");
}
});
if you want to put the function as a proper function or variable then you can easily do that as well to make the code a little easier to read
I haven't used Razor syntax for a while but this is the idea:
An array of model comes to the view and your model needs to have an ID property.
When you're rendering the html use that ID to identify each row of your model, for example:
<tr id="#item.Id">
and each row can have its own trigger like this for example:
<button onClick="sendMessage(#item.Id)">
a JavaScript function can take that function sendMessage(id) and then you can query that row and update its UI. for example before sending the request you can create an loading element and using JavaScript promise, update that to a success or fail icon.
But if I'm understanding right you want to have a send all button. In that case you can just query third <td> of each row and update its UI:
document.querySelectorAll('td:nth-child(3)').forEach(e => {
//update UI
})
Hope this was helpful.
I have here a view model which has two list objects. I will display them as two tables in my view. I've already created EditorFor for them. I'll place four buttons (move one right, move all right, move one left, move all left) for the exchange operations. I've googled everywhere and no goal on how to accomplish that, because I need to move the entire object, replace all "name" and "id" tags, reorder indexes and so on, because this way my lists will be posted correctly. I'm using Datatables.net and jQuery too.
Does anybody have a clue on how to do that?
Thank you in advance. The code goes below
EDIT
Since list elements on ASP.NET MVC are indexed like "ListName_0__Code"(for Id) and "ListName[0].Code" (for name) how to properly reorder these indexes?
EditorFor
#model ViewModels.UserPermissionDetails
<tr id="#Model.Id">
<td>
#Html.HiddenFor(m => m.Code)
#Html.HiddenFor(m => m.Login)
#Html.HiddenFor(m => m.Name)
#Html.HiddenFor(m => m.IdEmpUser)
#Html.DisplayFor(m => m.Code)
</td>
<td>#Html.DisplayFor(m => m.Login)</td>
<td>#Html.DisplayFor(m => m.Nome)</td>
</tr>
View
<table id="tbBlock">
<thead>
<tr>
<th>Code</th>
<th>Login</th>
<th>Name</th>
</tr>
</thead>
<tbody>
#Html.EditorFor(model => model.BlockList)
</tbody>
</table>
<table id="tbAllow">
<thead>
<tr>
<th>Code</th>
<th>Login</th>
<th>Name</th>
</tr>
</thead>
<tbody>
#Html.EditorFor(model => model.AllowList)
</tbody>
</table>
Exchange method (jQuery)
function addElement(OriginTableId, DestinyTableId, OriginListName, DestinyListName) {
var originTb = $(OriginTableId).DataTable(); //initialize DataTable.Net for origin table
var destinyTb = $(DestinyTableId).DataTable(); //initialize DataTable.Net for destiny table
var objectLine = $('#' + originTb.$('tr.selected').attr('id')); //get selected line that will be moved
//Name replacing code piece
var elementsFromLine = $(objectLine.children()[0]).children().toArray();
elementsFromLine.forEach(function (item, index, array) {
$(item).attr('id', $(item).attr('id').replace(OriginListName, DestinyListName)); //Replace 'OriginListName_0' with 'DestinyListName_0'
$(item).attr('name', $(item).attr('name').replace(OriginListName, DestinyListName)); //Replace 'OriginListName[0]' with 'DestinyListName[0]'
});
//Reordering code piece here, how to?
$(DestinyTableId + ' tbody').append(objectLine.clone(true, true));
objectLine.parent().remove();
}
It will be much easier for you to calculate and set the name values with the index only before you submit the form, not for every move action.
#Html.HiddenFor(m => m.Code, new { #class = "code" } })
// same for all the inputs you send to server
$("button[type='submit']").on("click", function (e) {
e.preventDefault();
updateIndexes();
$("form").submit();
});
function updateIndexes() {
$("#tbAllow").find("tbody").children("tr").each(function (i) {
var prefix = "BlockList[" + i + "].";
var $tr = $(this);
$tr.find("input.code").attr("name", prefix + "Code");
$tr.find("input.login").attr("name", prefix + "Login");
// same for all the inputs you send to server
});
};
My setup is as follows...
I have a service which brings back data from a stored procedure to a UI in no particular order. The UI binds the data to an MVC partial using knockout which looks like this...
#{ ViewBag.Title = "People List"; }
<h2>People List</h2>
<table id="people">
<thead>
<tr>
<th>Name</th>
<th>Gender</th>
<th>Job Title</th>
<th>Job Description</th>
</tr>
</thead>
<tbody data-bind="foreach: people">
<tr>
<td style="width: 125px;"><span data-bind="text: Name"></span></td>
<td style="width: 75px;"><span data-bind="text: Gender"></span></td>
<td style="width: 105px;"><span data-bind="text: JobTitle"></span></td>
<td style="width: 300px;"><span data-bind="text: JobDescription"></span></td>
</tr>
</tbody>
</table>
<button style="margin-top: 15px;" data-bind="click: sortByName">Sort by Name</button>
The JS for the VM looks like this...
<script type="text/javascript">
function Person(data) {
this.Name = ko.observable(data.Name);
this.Gender = ko.observable(data.Gender);
this.JobTitle = ko.observable(data.JobTitle);
this.JobDescription = ko.observable(data.JobDescription);
}
function PersonListVM() {
var self = this;
self.people = ko.observableArray([]);
$.getJSON('#Url.Action("DisplayPeople", "People")',
function (results) {
for (var i = 0; i < results.length; i++) {
self.people.push(new Person(results[i]));
}
});
self.sortByName = function () {
self.people.sort(function (x, y) {
return x["Name"] == y["Name"] ? 0 : (x["Name"] < y["Name"] ? -1 : 1);
});
};
};
ko.applyBindings(new PersonListVM());
</script>
I can get and display data with no problem, even adding another dummy person in a VM function goes off without a hitch. But sorting by name seems to do nothing. There are no errors, but I'm obviously doing something wrong. This is supposed to be a pretty simple search, what am I missing?
PS: The reason I'm supplying the property name as a string is because I want to make a sortable, paginated grid out of this table, sorting by table headers. My goal is to be able to pass in any valid property on which the table can be sorted dynamically but this is just as experiment working up to it.
Even though you're accessing your properties using array syntax, they're still ko.observables. You need to "unwrap" the observable to get at the value.
Try this instead:
return x['Name']() == y['Name']() ? 0 : (x['Name']() < y['Name']() ? -1 : 1);
Just off the top of my head have you tried using dot syntax to access the person object properties instead of array syntax?
self.people.sort(function (x, y) {
return x.Name == y.Name ? 0 : (x.Name < y.Name ? -1 : 1);
});
OK So I have view with data in table and i made delete option like in this tutorial
http://ricardocovo.com/2010/09/02/asp-mvc-delete-confirmation-with-ajax-jquery-ui-dialog/
But Now I have a question How Can I get a Name from the correct line to write something like this
Do you really want to delete "Product Name"
I think he asked about ASP.NET MVC, not Web forms, so the code will be as below
The view will be
<table id="table">
<tr>
<td>Id</td>
<td>Name</td>
<td> </td>
</tr>
#foreach(var item in Mode.Items) {
<tr>
<td>#item.Id</td>
<td>#item.Name</td>
<td><button class="deleted-link" value="Delete">delete</button></td>
</tr>
}
</table>
<div id="delete-dialog" title="Confirmation">
</div>
and the Jquery script on the view should be
$(function(){
//alert($('.deleted-link'));
$('.deleted-link').each(function(){
$(this).click(function(data){
var id = $(this).parent().parent().find('td :first').html();
$('#delete-dialog').html('<p>Are you sure you want to delete the item with id = {' + id + '} ?</p>');
$('#delete-dialog').dialog('open');
});
});
$('#delete-dialog').dialog({
autoOpen: false, width: 400, resizable: false, modal: true, //Dialog options
buttons: {
"Continue": function () {
$(this).dialog("close");
},
"Cancel": function () {
$(this).dialog("close");
}
}
});
});
You can see the code example at http://jsfiddle.net/SVgEL/
Hope this help.
You can try some thing Like this
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
ImageButton imb = (ImageButton)e.Row.FindControl("deleteButton");
string recordName = e.Row.Cells[3].Text;
imb.OnClientClick = "return confirm('Are You sure Want to Delete the record:- "+ recordName.ToUpper()+" ? ');";
}
}
Normal click Event with button
Delete
What about passing the model to the view and displaying the name?
Cant add comments, sorry for posting here in answers space.
If you dont want to pass the model you can always just pass the name as a parameter to the delete function from the table view.
Assuming that you are already using jQuery, check this out:
<script type="text/javascript">
function removeCar(theLink) {
var theTR = $(theLink).parents('tr');
var model = $(theTR).children('td._model').html();
var theConfirm = confirm("Are you sure you want to remove " + model + "?");
if (theConfirm == true)
$(theTR).remove();
}
</script>
<table>
<thead>
<tr>
<th>Make</th>
<th>Model</th>
<th></th>
</tr>
</thead>
<tbody>
<tr>
<td>Audi</td>
<td class="_model">A3</td>
<td>Remove</td>
</tr>
<tr>
<td>Audi</td>
<td class="_model">A4</td>
<td>Remove</td>
</tr>
<tr>
<td>Audi</td>
<td class="_model">A5</td>
<td>Remove</td>
</tr>
</tbody>
</table>