I am trying to read my query from controller and I already have the Ajax call to get it through my button. but my problem is there is no changes happening on my index view, the table hasn't change and can't figure out why.
Here is my View:
#{
ViewBag.Title = "LoadInfo";
}
#model IEnumerable<MyApp.Models.LoadInfo>
<html>
<body>
<input style="text-align:left; width:250px" id="txtSearch" type="text" />
<button type="button" id="search" onclick="search()" class="btn btn-primary">Search</button>
<div class="tableFixHead" ; style="margin-top: 10px;">
<table class="table">
<thead>
<tr>
<th>ID</th>
<th>Name</th>
<th>Address</th>
<th></th>
</tr>
</thead>
<tbody>
#foreach (var item in Model)
{
<tr>
<td>#item.ID</td>
<td>#item.Name</td>
<td>#item.Address</td>
</tr>
}
</tbody>
</table>
</div>
</body>
</html>
<script>
function search() {
var search = document.getElementById("txtSearch").value
$.ajax({
url: '/Home/LoadInfo',
type: 'GET',
data: {
'name': search
},
success: function (data) {
alert("success")
},
error: function (jqXhr, textStatus, errorThrown) {
alert(errorThrown);
}
});
}
</script>
Controller:
public ActionResult LoadInfo(string name)
{
List<readDetails> userDetails = new List<readDetails>();
string constr = ConfigurationManager.ConnectionStrings["ConString"].ConnectionString;
using (MySqlConnection con = new MySqlConnection(constr))
{
string query = "SELECT ID, Name, Address FROM EmpDetails WHERE Name like '%" + name + "%' LIMIT 500";
using (MySqlCommand cmd = new MySqlCommand(query))
{
cmd.Connection = con;
con.Open();
using (MySqlDataReader sdr = cmd.ExecuteReader())
{
while (sdr.Read())
{
userDetails.Add(new readDetails
{
op = sdr["ID"].ToString(),
op_desc = sdr["Name"].ToString(),
doc_id = sdr["Address"].ToString(),
});
}
}
con.Close();
}
}
return View(userDetails);
}
I also using this controller to my starting page load not sure if this is cause of the problem, do I need to create a separate controller and view for initial loading and for my search functionality.
The result alerts me to "success" but its weird because my table is not changing or refreshing just like if you do a simple query with filter from query browser.
You need to add html() function for table's <tbody> element to override existing results with the new one:
$.ajax({
url: '/Home/LoadInfo',
type: 'GET',
data: {
'name': search
},
success: function (data) {
alert("success");
$('.table tbody').html(data); // override previous results
},
error: function (jqXhr, textStatus, errorThrown) {
alert(errorThrown);
}
});
If the response contains entire <table> element, you should omit tbody selector:
$('.table').html(data);
Also you might try to return PartialView(), e.g. return PartialView(userDetails); instead of entire view page if the search results are provided in same search page.
Update:
Since the data returns entire HTML page, the current controller action should be modified to return JSON response like this example:
public ActionResult LoadInfo(string name)
{
List<readDetails> userDetails = new List<readDetails>();
string constr = ConfigurationManager.ConnectionStrings["ConString"].ConnectionString;
using (MySqlConnection con = new MySqlConnection(constr))
{
string query = "SELECT ID, Name, Address FROM EmpDetails WHERE Name like '%" + name + "%' LIMIT 500";
using (MySqlCommand cmd = new MySqlCommand(query))
{
cmd.Connection = con;
con.Open();
using (MySqlDataReader sdr = cmd.ExecuteReader())
{
while (sdr.Read())
{
userDetails.Add(new readDetails
{
op = sdr["ID"].ToString(),
op_desc = sdr["Name"].ToString(),
doc_id = sdr["Address"].ToString(),
});
}
}
con.Close();
}
}
return Json(userDetails, JsonRequestBehavior.AllowGet);
}
Then, replace existing <tbody> contents with data from response:
$.ajax({
url: '/Home/LoadInfo',
type: 'GET',
data: {
'name': search
},
dataType: 'json',
success: function (data) {
alert("success");
var tblbody = $('.table').find('tbody');
tblbody.empty(); // remove existing rows
var row = '';
$.each(data, function(i, item) {
row += $('<tr>').append($('<td>').text(item.ID), $('<td>').text(item.Name), $('<td>').text(item.Address));
tblbody.append(row); // add new rows
});
},
error: function (jqXhr, textStatus, errorThrown) {
alert(errorThrown);
}
});
At this point the search results should appear on the same table instead of returning entire HTML content.
Related
I am new to Ajax.I tried to update my HTML table after successfully insert of data in database using Ajax instead of loading the entire form by using window.location.reload().
Insert Method
[WebMethod]
public static void SaveUser(Employee objEmployee) //Employee is the class
{
//My Code for insert
}
This works fine as the data inserts successfully.Ajax insert defined below
Update Method
public static void GetData() //Tried using datatable as return type nothing happened
{
//var dt = new DataTable();
using (var con = new SqlConnection(Constr))
{
const string query = "select * from TblUser";
using (var cmd = new SqlCommand(query, con))
{
using (var sda = new SqlDataAdapter())
{
cmd.Connection = con;
sda.SelectCommand = cmd;
using (TableData)
{
sda.Fill(TableData);
//return TableData;
}
}
}
}
}
On button save my ajax script is like this
<script type="text/javascript">
$(function () {
$("#btnSave").click(function () {
alert("TESST");
var user = {};
user.FName = $("#FirstName").val();
user.LName = $("#Surname").val();
user.MName = $("#MiddleName").val();
// Some others are also there
user.CreatedDateTime = new Date();
user.ModifiedDateTime = new Date();
$.ajax({
type: "POST",
url: "Default.aspx/SaveUser",
data: '{objEmployee: ' + JSON.stringify(user) + '}',
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function () {
alert("User has been added successfully.");
//Another Ajax to update the grid
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "Default.aspx/GetData",
data: "{}",
dataType: "json",
success: function () {
},
error: function () {
alert("Error while Showing update data");
}
});
},
error: function () {
alert("Error while inserting data");
}
});
return false;
});
});
</script>
I have binded to HTML Table like this
<table id="dataTables-example" role="grid">
<thead>
<tr role="row">
<th>Name</th>
<th>Email Id</th>
<th>Mobile(H)</th>
<th >Mobile(O)</th>
<th>Joining Date</th>
<th>Birth Date</th>
</tr>
</thead>
<tbody>
<% for (var data = 0; data < TableData.Rows.Count; data++)
{ %>
<tr class="gradeA odd" role="row">
<td class="sorting_1"><%=TableData.Rows[data]["FName"]%></td>
<td><%=TableData.Rows[data]["EMail"]%></td>
<td><%=TableData.Rows[data]["Telephone"]%></td>
<td><%=TableData.Rows[data]["Mobile"]%></td>
<td><%=TableData.Rows[data]["DOJ"]%></td>
<td><%=TableData.Rows[data]["DOB"]%></td>
</tr>
<% } %>
</tbody>
</table>
My Issues
My update method is called after insert but I am not able to see the updated data.
After page refresh as the webmethod is static multiple data shows.
Loop trough the received data and set them to your table :
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "Default.aspx/GetData",
data: "{}",
dataType: "json",
success: function (data) {
for (var i = 0; i < data.d.length; i++) {
$("#dataTables-example tbody").append("<tr><td>" + data.d[i].FName+ "
</td><td>" + data.d[i].EMail+ "</td><td>" + data.d[i].Telephone+ "
</td></tr>");
}
},
error: function () {
alert("Error while Showing update data");
}
});
I am using AJAX to call an ActionResult and return a list of files. The data is stored in a dictionary object in the model then passed to the view. I have a foreach loop in the view that checks to see if the object is null. If not, it loops through the dictionary and produces table rows for each key/value pair. The problem is, the HTML is never generated and nothing is displayed. Using Firebug I have stepped through the entire process and everything is returned as it should be. Any help finding out why would be appreciated.
The AJAX:
function () {
$.ajax({
url: '#Url.Action("GetExpenseReportUploads", "MyExpenseReports")',
type: "GET",
async: true,
cache: false,
data: { DirectoryName: "ER_#=EPR_ID#" },
success: function() {
alert("success!");
},
error: function(errorThrown) {
console.log(errorThrown);
}
});
}
The Controller:
public ActionResult GetExpenseReportUploads(string DirectoryName)
{
ExpenseReport.MVC.Models.MyExpenseReports model = new MyExpenseReports();
IEnumerable<string> fileArray = Directory.EnumerateFiles(Server.MapPath("~/Files/" + DirectoryName + "/")).Select(fn => "~/Files/" + DirectoryName + "/" + Path.GetFileName(fn));
//model.EPR_Uploads = Path.GetFileName(fileArray);
Dictionary<string, string> fileNames = new Dictionary<string, string>();
foreach (string filePath in fileArray)
{
string fileName = Path.GetFileName(filePath);
fileNames.Add(filePath, fileName);
model.EPR_Uploads = fileNames;
}
model.EPR_Upload_DirectoryName = DirectoryName;
return View(model);
}
The View:
<table>
#if (Model.EPR_Uploads != null)
{
foreach (KeyValuePair<string, string> upload in Model.EPR_Uploads)
{
<tr>
<td>
#using (Html.BeginForm("DeleteUpload", "MyExpenseReports", FormMethod.Post))
{
#Html.HiddenFor(m => m.FileId, new { #value = #upload.Value })
#Html.HiddenFor(m => m.EPR_Upload_DirectoryName)
}
<input type="submit" id="DeleteUploadBtn" value="Delete File" formaction="#Url.Action("DeleteUpload", "MyExpenseReports", new { FileId = #upload.Value, EPR_ID = "#=EPR_ID#", DirectoryName = Model.EPR_Upload_DirectoryName })" />
</td>
<td>
</td>
<td>
</td>
</tr>
}
}
You're mixing server-side processing and client-side processing. If you want the table to be built after your client-side AJAX call, you don't want to use the server-side model (Model.EPR_Uploads).
Instead, use a post-load client call to build the HTML. For example:
function () {
$.ajax({
url: '#Url.Action("GetExpenseReportUploads", "MyExpenseReports")',
type: "GET",
async: true,
cache: false,
data: { DirectoryName: "ER_#=EPR_ID#" },
success: function(data, textStatus, jqXHR) {
$("#tableId").append("<tr><td>" + data.EPR_Upload_DirectoryName + "</td></tr>";
},
error: function(errorThrown) {
console.log(errorThrown);
}
});
You'll need to change your Controller to return data in JSON so you can properly parse it on the client side.
Hopefully this helps.
I'm facing a strange issue with autocomplete.
First issue:
based on the tutorial found here, only the first letter of the found items is showing in the list of autocomplete items
Here is an illustration:
My action at debug time
Dummy data returned, always the same regardless of the search pattern just for testing
In the rendered view, this is what happens:
The Javascript for autocomplete of this scenario is as follows:
$("#Email").autocomplete('#Url.Action("FindEmail", "Administration")',
{
dataType: 'json',
parse: function(data) {
var rows = new Array();
for (var i = 0; i < data.length; i++) {
rows[i] = {
data: data[i].Value,
value: data[i].Value,
result: data[i].Value
};
}
return rows;
},
width: 300,
minLength: 3,
highlight: false,
multiple: false
});
Second issue:
I've changed my code to work with a more comfortable Ajax call for me that depends on Model mapping rather than sending a q and limit parameters as in the previous tutorial, and as I've seen in many other tutorials, but the Ajax call isn't firing, not even giving me an error.
My code for this scenario is based on this Stack Overflow Answer
Here is my controller and view code related:
//[HttpPost]
[SpecializedContextFilter]
[Authorize]
[OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
public JsonResult FindEmail(RegistrationModel model) //Notice the use of model instead of string q and string limit
{
//Just a dummy implementation
var rez = new List<ValueModel>
{
new ValueModel {Description = "atest1#test.com", Value = "atest1#test.com"},
new ValueModel {Description = "atest2#test.com", Value = "atest2#test.com"},
new ValueModel {Description = "atest3#test.com", Value = "atest3#test.com"},
new ValueModel {Description = "atest4#test.com", Value = "atest4#test.com"}
};
//var retValue = rez.Select(r => new { email = r.Value }).OrderBy(x => x).Take(10);
//return Json(retValue, JsonRequestBehavior.AllowGet);
return Json(rez, JsonRequestBehavior.AllowGet);
}
View JavaScript:
$("#Email").autocomplete({
source: function(request, response) {
$.ajax({
url: '#Url.Action("FindEmail", "Administration")',
type: "POST",
dataType: "json",
data: { email: $("#Email").val(), conferenceId: $("#ConferenceId").val() },
success: function(data) {
response($.map(data, function(item) {
return { label: item.Value, value: item.Value, id: item.Value };
}));
},
select: function(event, ui) {
$("input[type=hidden]").val(ui.item.id);
}
});
}
});
Firefox console view:
I've tried a lot of codes for the second scenario, most of them are Stack Overflow answers, but nothing is happening!
I'm my missing anything ?
Note: jQuery plugins are included, Ajax is already working in the same page, so I'm not sure whats the problem
Thanks for any help.
Here is a full working example, see screen grab.
These are the steps that I had take to get the second example working.
Script-references/Markup/Js
<script src="~/Scripts/jquery-1.8.2.js"></script>
<script src="~/Scripts/jquery-ui-1.8.24.min.js"></script>
<input id="ConferenceId" value="1" />
<div class="ui-widget">
<label for="Email">Email: </label>
<input id="Email">
</div>
<script type="text/javascript">
$("#Email").autocomplete({
source: function (request, response) {
$.ajax({
url: '#Url.Action("FindEmail", "Administration")',
type: "POST",
dataType: "json",
data: { email: $("#Email").val(), conferenceId: $("#ConferenceId").val() },
success: function (data) {
response($.map(data, function (item) {
return { label: item.Value, value: item.Value, id: item.Value };
}));
},
select: function (event, ui) {
$("input[type=hidden]").val(ui.item.id);
}
});
}
});
</script>
Models
public class RegistrationModel
{
public string Email { get; set; }
public string ConferenceId { get; set; }
}
public class ValueModel
{
public string Description { get; set; }
public string Value { get; set; }
}
Controller Action
I had to add the [HttpPost] attribute.
[HttpPost]
public JsonResult FindEmail(RegistrationModel model) //Notice the use of model instead of string q and string limit
{
//Just a dummy implementation
var rez = new List<ValueModel>
{
new ValueModel {Description = "atest1#test.com", Value = "atest1#test.com"},
new ValueModel {Description = "atest2#test.com", Value = "atest2#test.com"},
new ValueModel {Description = "atest3#test.com", Value = "atest3#test.com"},
new ValueModel {Description = "atest4#test.com", Value = "atest4#test.com"}
};
return Json(rez, JsonRequestBehavior.AllowGet);
}
Screen grab
I am kind of new to KnockoutJS and trying to use it.
I am having trouble binding the element using knockoutjs. Please see the fiddle below and help in resolving and correcting me.
It is basically not binding the value to the span element.
http://jsfiddle.net/EpyRA/
HTML:
<div id="taxyear">
<table style="width: 100%;" cellpadding="4" cellspacing="4">
<tr>
<td style="width: 25%">
<span>Name:</span><span data-bind="value: ReturnData.Name"></span>
</td>
</tr>
</table>
</div>
Javascript:
var myWeb = myWeb || {};
$(function () {
(function (myWeb) {
"use strict";
var serviceBase = '../Services/Data.asmx/',
getSvcUrl = function (method) { return serviceBase + method; };
myWeb.ajaxService = (function () {
var ajaxGetJson = function (method, jsonIn, callback) {
$.ajax({
url: getSvcUrl(method),
type: "GET",
data: jsonIn,
dataType: "json",
contentType: "application/json",
success: function (json) {
callback(json);
}
});
},
ajaxPostJson = function (method, jsonIn, callback) {
var test = { "Name": "testRaju", "SourceID": "ABCD" };
//just return data instead of calling for testing
callback(test);
};
return {
ajaxGetJson: ajaxGetJson,
ajaxPostJson: ajaxPostJson
};
})();
} (myWeb));
(function (myWeb) {
"use strict";
myWeb.DataService = {
getReturnData: function (jsonIn, callback) {
myWeb.ajaxService.ajaxPostJson("GetReturnData", jsonIn, callback);
}
};
} (myWeb));
//Constructor for a ReturnData object
myWeb.ReturnData = function () {
this.Name = ko.observable();
this.SourceID = ko.observable();
},
//View Model
myWeb.prdviewmodel = (function () {
var prd = ko.observable();
loadReturnDataCallback = function (jsonReturnData) {
alert(jsonReturnData.Name);
prd = new myWeb.ReturnData()
.Name(jsonReturnData.Name)
.SourceID(jsonReturnData.SourceID);
},
loadReturnData = function () {
myWeb.DataService.getReturnData("{'YearID':'" + 22 + "'}", myWeb.prdviewmodel.loadReturnDataCallback);
};
//public
return {
loadReturnData: loadReturnData,
loadReturnDataCallback: loadReturnDataCallback,
ReturnData: prd
}
})();
//hookup knockout to our viewmodel
myWeb.prdviewmodel.loadReturnData();
ko.applyBindings(myWeb.prdviewmodel);
});
Thanks in Advance,
Sam
I see a couple of minor issues:
When binding against a span, you would want to use the text binding rather than the value binding.
In the AJAX callback, you would want to set the prd observable's value by calling it as a function, rather than setting it as a new value.
In the UI, you can make use of the with binding to ensure that it does not try to bind to a property of the observable, before it has been loaded.
Here is an updated fiddle: http://jsfiddle.net/rniemeyer/Bdz5a/
I have been all over looking to try and solve my issue. I am thinking it may be on my back end but not sure. I am trying to use autocomplete to fill in a textbox but show in the drop down a description with the value.
My Method for grabbing the Data:
[WebMethod]
public static ArrayList GetQueries(string id)
{
queries q;
var cs = Global.CS;
var con = new SqlConnection(cs);
var da = new SqlDataAdapter(querystring, con);
var dt = new DataTable();
da.Fill(dt);
ArrayList rows = new ArrayList(dt.Rows.Count);
for (int i = 0; i < dt.Rows.Count; i++)
{
var val = dt.Rows[i]["Query_ID"];
var des = dt.Rows[i]["Description"];
q = new queries();
q.label = val.ToString();
q.value = val.ToString() + " -- " + des.ToString();
var json = new JavaScriptSerializer().Serialize(q);
rows.Add(json);
}
return rows;
}
public class queries
{
public string label { get; set; }
public string value { get; set; }
}
It is returning an arraylist.
My JQuery Method to get data and autocomplete.
$("[id$=QueryManager]").change(function () {
var id = $("[id$=QueryManager] :selected").val();
$.ajax({
type: 'POST',
url: 'Upload.aspx/GetQueries',
data: JSON.stringify({ id: id }),
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (data) {
fillit(data);
},
error: function (ex) {
alert('Request Status: ' + ex.status + '\n\nStatus Text: ' + ex.statusText + '\n\n' + ex.responseText);
}
});
});
function fillit(data) {
$("#QueryTxt").autocomplete({
delay: 0,
minLength: 0,
source: function (data, response) {
response($.map(data, function (item) {
return {
label: item.label,
value: item.value
}
}));
}
});
};
I have tried it with both the serialize and without to no results. When this code runs it shows that autocomplete is working (via the box showing up below) but there is no data in it.
I am not sure what I am doing wrong, any help is appreciated.
What I'm doing below is that on the "Select" event I take the values returned from the query and set the text of the drop down to the description and Id value from the data brought back. Then I set a dummy textbox's value as the description. "colDescName" is just a variable I was using as my textbox id.
$("#" +colDescName).autocomplete({
minLength: 2,
select: function( event, ui )
{
var rowElement=event.target.id;//Drop down Id
setTimeout(function()
{
$("#"+rowElement).val(ui.item.value+':'+ui.item.id)
},100);//need a slight delay here to set the value
$("#TextBoxId").val(ui.item.value);
//ui.item.value is the description in the drop down.
//ui.item.id is the Id value from the drop down
},
source: function (request, response) {
var term = request.term;
if (term in cache) {
response(cache[term]);
return;
}
lastXhr = $.getJSON("Upload.aspx/GetQueries", request, function (data, status, xhr) {
cache[term] = data;
if (xhr === lastXhr) {
response(data);
}
}).error(function () {
console.log("error");
});
}
});
What object is "$("[id$=QueryManager]")" that you have the change method on? Would you need the change event if you can use the above code?
EDIT
OK an easier way is set your textbox "$("#QueryTxt")" to an autocomplete box before executing any change events on your "QueryManager" manager dropdown. Then when a change event does occur in your "QueryManager" , call:
$(this).autocomplete('search', 'your data here');
That will then execute the search function and call the autocomplete's url with your required data