How can I make a continually updating query in MVC 3? - c#

I am looking for a simple way to make a piece of text, which happens to be a number, on my view update in near-real-time.
I have a piece of text in my view that looks like this:
<% if (ViewData["TotalRecords"] != null)
{ %>
<%= ViewData["TotalRecords"].ToString() +
" records available to search."%>
<% } %><br />
I want ViewData["TotalRecords"] to be a constantly updating value, every 60 seconds or so.
The query underneath is:
public static string GetTotalRecords()
{
DataContext dc = new DataContext();
return dc.Records.Count().ToString("#,##0");
}
How can I make this into some kind of Ajax-enabled dynamic piece of text?

Move that part to separate action
public ActionResult TotalRecords()
{
var totalRecords = GetTotalRecords();
return PartialView(totalRecords);
}
In parent view, initially render that action with
<div id="totalRecords">
#Html.RenderAction("TotalRecords")`
</div>
And script with setInterval to reload TotalRecords action every 60 seconds
<script>
$(function(){
setInterval("reloadTotalRecords", 60 * 1000);
});
function reloadTotalRecords()
{
$('#totalRecords').load('#Url.Action("TotalRecords")');
}
</script>

There's going to have to be some JavaScript in there somewhere. A setTimeout could be used to call an ajax method that returns the number, which then is used to update the content in the browser.
You could use jQuery to target the specific element. There are some examples on this question.

I believe this should solve your question:
jQuery Ajax setTimeout JSON
Use the JavaScript setTimeout function to call an Ajax function every 60 seconds.
Something like:
function updateContent() {
$.ajax({
url: 'url',
cache:false,
success: function(data) {
$('#item-id').html(data.NewValue);
},
dataType: 'json'
});
}
$(function () {
setTimeout(updateContent, 60000);
}

I would jump into SignalR. Sounds interesting.

Related

How to call C# method from Javascript in ASP.NET Core?

I have a username textbox in my Index.cshtml file and I want to check for matches in our Active Directory whenever the user changes the text inside the textbox and then maybe display it in a DropDownList, so the user can choose form it.
So I call a JavaScript function on the oninput event of the textbox and now the question is how do I call my C# method FindUser() in Index.cshtml.cs from that JS function? I have tried a lot of what I've read, ajax call doesn't work, adding [WebMethod] and making the method static doesn't work and most on the internet is on MVC which I'm not using.
Textbox in Index.cshtml:
<input type="text" class="form-control" oninput="findUsers()" />
JavaScript function:
function findUsers() {
$.ajax({
url: 'Index\FindUser',
success: function (data) {
alert(data);
},
error: function (error) {
alert("Error: " + error);
}
})
}
leads the browser to alert
Error: [object Object]
Method in Index.cshtml.cs:
public void FindUser()
{
// code
}
The method is not even called from the JS function.
Also I've read a few times that calling a C# method from the view is not the proper way of doing it. If so, how can I achieve my goal then?
I see you're using Razor pages. A method in razor page model is not a routed method (it can't be called by requesting a route), and that's why trying to send an ajax request to Index\FindUser won't work, and the error returned by server would be 404 not found.
Alternatively you can use razor page handlers.
In your Index.cshtml.cs rename the method FindUser() to OnGetFindUser() or OnGetFindUserAsync() if the method is an asynchronous method.
You can then call this method by sending a request to "Index?handler=FindUser".
// Note the difference in method name
public IActionResult OnGetFindUser()
{
return new JsonResult("Founded user");
}
function findUsers() {
$.ajax({
type: 'GET',
// Note the difference in url (this works if you're actually in Index page)
url: '?handler=FindUser',
success: function (data) {
alert(data);
},
error: function (error) {
alert("Error: " + error);
}
})
}
Further suggested read
I am not very experienced yet, I have only started programming last year, but I hope I can help a little bit.
I also had a similar problem, but I could not execute a function directly from JavaScript. You could maybe create an API call to C# and make the API execute the function you want, and then return the data back to the client.
If I don't misunderstand, you want the user to type some text, and then return from your database a list based on the typed text.
You could use an onChange in the input tag, and each time it changes, it executes an API request to the server, which will search whatever you need and return it as a json. Then in JavaScript, you parse the data and put it in a select tag.
Hope it helps.
Ok so first off, you are calling jquery inside javascript function.
Calling a controller action method from ajax is pretty easy.
https://api.jquery.com/jquery.ajax/
You need to determine the request type, the url, the datatype returned, parameters passing etc and then set a breakpoint on the controller action and on the ajax request success and error functions. Then you will be able to see why it has succeeded or failed.
The way i would do it would be to give the input an id, then when a user types text catch the event.
https://api.jquery.com/category/events/
Don't confused jquery and javascript.
Jquery is a framework that packs javascript inside it.
Javascript is the native language.
You can use onkeyup or onblur like this
onblur: When you leave the input field, a function is triggered
onkeyup: A function is triggered when the user releases a key in the
input field
Then modify your code like this
html file:
<input type="text" class="form-control" id="username" oninput="findUsers()" />
js
function findUsers() {
var username= document.getElementById("username").value;
$.ajax({
type: 'GET',
url: '/Home/FindUser
dataType: 'json',
data: {username},
success: function (data) {
console.log(data);
},
error: function (error) {
console.log(error);
}
});
}
You must return something like this. You are using void keyword so it will not return anything to FE side
public JsonResult FindUser(string username)
{
var object = {
// something here
}
return Json(object);
}
Change your API like this:
public bool FindUser(string value)
{
if (value == "Joe")
return true;
else
return false;
}
Then call it like this:
<script type="text/javascript">
function findUsers() {
var value = document.getElementById("value").value;
$.ajax({
type: 'GET',
url: '/Home/FindUser,
data: value,
dataType: 'json',
success: function (data) {
alert(data);
},
error: function (error) {
alert(error);
}
});
}
</script>
<br />
<input type="text" class="form-control" id="value" oninput="findUsers()" />
you can call method exactly you want with
small addition to Index.cshtml. First line may be:
#page "{handler?}"
then call from ajax:
url:'/index/FindUser'
in Index.cshtml.cs calling method:
void OnGetFindUser(){}

ASP Core 2.0 - Calling Controller Functions from a View

I'm a complete beginner with ASP Core and web development in general, so I apologize if this is painfully obvious.
I am looking for a way to call a function that is present in my Controller from my View. This function would be called in reaction to the user clicking a button on their webpage.
Controller Function:
public ActionResult Change(int n)
{
ViewData["currentChoice"] = choiceArray[n];
return View();
}
View:
#{
Choice currentPoint = ViewData["currentChoice"] as Choice;
<h2>#currentPoint.text</h2>
}
//Button - Call Change function in the Controller
I have previously created a button that links to another page, in this case "Question/Change", but I do not want a redirect. The desired final result would simply update the text on the screen by changing the ViewData.
In MVC Controller Actions(functions) are invoked through http requests that originate from your view in the form of anchor elements, AJAX calls, or form submissions.
MVC has nice helpers to generate correct URLs for anchor elements that map to your action of choice.
#{
Choice currentPoint = ViewData["currentChoice"] as Choice;
<h2>#currentPoint.text</h2>
}
Change
Try this
as you are using ASP.NET core so your anchor tag should be like this
<a asp-controller="YourControllerName" asp-action="Change" class="btn btn-primary" onClick="changeChoice()">Change</a>
add JS
<script type="text/javascript">
$('document').ready(function ()
{
function changeChoice()
{
$.ajax(
{
url: '/YourControllerName/Change
type: 'GET',
success: function (response) {
alert('Successfully Updated'),
location.reload()
},
});
}
});
</script>

access/iterate over a C# list in jQuery

i am trying to make an image gallery with pictures fading in and out. I already have that part covered, but so far im hard coding the image url's in my .aspx page. I don't want this, i need it to be dynamic.
<script type="text/javascript">
$(function()
{ var img = $("img.x");
$(img).hide().eq(0).show();
var cnt = img.length
setInterval(imgRotate, 5000);
function imgRotate() {
$(img).eq((img.length++) % cnt).fadeOut("slow",
function() {
$(img).eq((img.length) % cnt).fadeIn("slow");
});
}
});
</script>
<body>
<form id="form1" runat="server">
<div>
<img class="x" alt="Image1" src="Desert.jpg"/>
<img class="x" alt="Image1" src="Lighthouse.jpg"/>
</div>
</form>
this makes the images fade in and out, which is good, but as you can see, i've hardcoded the images in this example. I can't use this for my application.
What i want to do is the following:
i want to pass a List<string> (codebehind) to the jQuery script that will just iterate over the list and replace the source url of the image.
i just want to do something like this in the jQuery script (pseudo-code):
int counter = 0;
var img = ListFromCodeBehind[counter];
//do some fading stuff
count++;
i've tried using <%=%> server tags, and so forth but to no avail. I've read lots of things but they all seem overly complicated for what i'm trying to achieve..
Why is everybody forcing you to use AJAX? There is no need to load image list in separate HTTP request. I assume your code comes from some aspx page. Therefore you can provide a public method in this Pages's class (lets call it GetImages()) that returns a string that looks like JavaScript array. I.e.
public string GetImages()
{
return "['Desert.jpg', 'Lighthouse.jpg']";
}
Then in you JavaScript code (that is placed in this Page's aspx file as well) you can call public method of Page's class with classic ASP syntax:
int counter = 0;
var ListFromCodeBehind = <%= this.GetImages() %>;
var img = ListFromCodeBehind[counter];
//do some fading stuff
count++;
which will finally print:
var ListFromCodeBehind = ['Desert.jpg', 'Lighthouse.jpg'];
and this is the result I believe you expect.
You can add a Web Method into your aspx page (code behind) that can be called by AJAX.
Your code behind method will return a string that contains the URL to the images, in a JSON format (so that JQuery knows how to iterate though it out of the box).
Have a look at this thread to have an idea of how to create a web method in an aspx code behind file. I'd do it via asp.net MVC though...much more straightforward
Calling an ASP.NET server side method via jQuery
//Controller
[HttpGet]
public JsonResult GetImageURLS()
{
var urls = GetUrls();
return Json(new { urls = urls }, JsonRequest.AllowGet);
}
//js file
$.ajax({ url : '/GetImageURLS/', success : function(e) { if (e && e.urls) {
var $images = $(".images");
for (var i in e.urls) {
$images.append('<img src="' + i.url + '" class="x" ' + ' alt="' + i.alt + '" /> ';
}
});
//html
<div class="images">
</div>
Try this for initial load of the images. Then call your function on them after the images are populated.
You can use AJAX and call a webservice in your Javascript to return your image list as follows:
function LoadImages() {
var url;
url = "WebServices/wsImages.asmx/GetImageList"
$.ajax({
type: "POST",
url: url,
contentType: "application/json; charset=utf-8",
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(textStatus);
},
success: function (response) {
var imgList = response.d;
//Loop through image list etc.
}
});
}

Redirecting to another page in ASP.NET MVC using JavaScript/jQuery

I want to redirect from one page to another page in ASP.NET MVC 3.0 using JavaScript/jQuery/Ajax. On button click event I have written JavaScript code like below.
function foo(id)
{
$.post('/Branch/Details/' + id);
}
My controller code is like this:
public ViewResult Details(Guid id)
{
Branch branch = db.Branches.Single(b => b.Id == id);
return View(branch);
}
When I click on a button it is calling the Details action inside BranchController, but it doesn't return to the Details view.
I didn't get any error or exception. It's showing status 200 OK in Firebug. What is wrong in my code and how can I redirect to the Details view page?
You are not subscribing to any success callback in your $.post AJAX call. Meaning that the request is executed, but you do nothing with the results. If you want to do something useful with the results, try:
$.post('/Branch/Details/' + id, function(result) {
// Do something with the result like for example inject it into
// some placeholder and update the DOM.
// This obviously assumes that your controller action returns
// a partial view otherwise you will break your markup
});
On the other hand if you want to redirect, you absolutely do not need AJAX. You use AJAX only when you want to stay on the same page and update only a portion of it.
So if you only wanted to redirect the browser:
function foo(id) {
window.location.href = '/Branch/Details/' + id;
}
As a side note:
You should never be hardcoding urls like this. You should always be using url helpers when dealing with urls in an ASP.NET MVC application. So:
function foo(id) {
var url = '#Url.Action("Details", "Branch", new { id = "__id__" })';
window.location.href = url.replace('__id__', id);
}
This could be done by using a hidden variable in the view and then using that variable to post from the JavaScript code.
Here is my code in the view
#Html.Hidden("RedirectTo", Url.Action("ActionName", "ControllerName"));
Now you can use this in the JavaScript file as:
var url = $("#RedirectTo").val();
location.href = url;
It worked like a charm fro me. I hope it helps you too.
You can use:
window.location.href = '/Branch/Details/' + id;
But your Ajax code is incomplete without success or error functions.
// in the HTML code I used some razor
#Html.Hidden("RedirectTo", Url.Action("Action", "Controller"));
// now down in the script I do this
<script type="text/javascript">
var url = $("#RedirectTo").val();
$(document).ready(function () {
$.ajax({
dataType: 'json',
type: 'POST',
url: '/Controller/Action',
success: function (result) {
if (result.UserFriendlyErrMsg === 'Some Message') {
// display a prompt
alert("Message: " + result.UserFriendlyErrMsg);
// redirect us to the new page
location.href = url;
}
$('#friendlyMsg').html(result.UserFriendlyErrMsg);
}
});
</script>
<script type="text/javascript">
function lnkLogout_Confirm()
{
var bResponse = confirm('Are you sure you want to exit?');
if (bResponse === true) {
////console.log("lnkLogout_Confirm clciked.");
var url = '#Url.Action("Login", "Login")';
window.location.href = url;
}
return bResponse;
}
</script>
check the code below this will be helpful for you:
<script type="text/javascript">
window.opener.location.href = '#Url.Action("Action", "EventstController")', window.close();
</script>

Asp.net MVC populate a list box with JQuery?

I have a list of Payees in a drop down box on my form. I would like to populate a different drop down, based on the selected item of the Payee drop down, without post backs and all that.
So, I created a method in my controller that does the work:
private JsonResult GetCategories(int payeeId)
{
List<CategoryDto> cats = Services.CategoryServices.GetCategoriesByPayeeId(payeeId);
List<SelectListItem> items = new List<SelectListItem>();
foreach(var cat in cats)
{
items.Add(new SelectListItem {Text = cat.Description, Value = cat.CategoryId.ToString()});
}
return Json(items);
}
Now, I am unsure what to add to my view to get this to work.
At the moment, all I have is this:
<% using (Html.BeginForm())
{%>
<p>
<%=Html.DropDownList("SelectedAccountId", Model.Accounts, "Select One..", null) %>
</p>
<p>
<%=Html.DropDownList("SelectedPayeeId", Model.Payees, "Select One...", null) %>
</p>
<input type="submit" value="Save" />
<%
}%>
they populate fine... so when the user selects the SelectedPayeeId drop down, it should then populate a new (Yet to be created?) drop down which holds categories, based on the SelectedPayeeId.
So, I think I need to create a JQuery function (Never done JQuery.. so not even sure where it goes) which monitors the Payee drop down for an onChange event? And then call the method I created above. Does this sound right, and if so, can you guide me in how to achieve this?
Your reasoning so far is totally sound. First you are going to want to include the jquery library in your View / Master. You can download a copy of jquery from http://jquery.com/. Add the file to you project and include a <script src="/path/to/jquery.js"> to the <head> of your document. You are going to want to add another dropdown to your View (and probably another property to your model). We'll call this 'SelectedCategoryId:'
<%=Html.DropDownList("SelectedCategoryId", null, "Select One...", new { style = "display:none;"}) %>
We've set the style of this Drop Down to not be visible initially because there is nothing to select inside of it. We'll show it later after we generate some content for it. Now, somewhere on your page you will want to include a <script> block that will look something like this:
$(document).ready(function() { $('#SelectedPayeeId').change(function() {
$.ajax({
type: 'POST',
url: urlToYourControllerAction,
data: { payeeId: $(this).val() },
success: function(data) {
var markup = '';
for (var x = 0; x < data.length; x++ ) {
markup += '<option value="' + data[x].Value + '">'+data[x].Text+'</option>';
}
$('#SelectedCategoryId').html(markup).show();
}
}); }); });
This code binds the anonymous function written above to the DOM element with the ID of 'SelectedPayeeId' (in this case your dropdown). The function performs an AJAX call to the url of your method. When it receives the results of the request (your JSON you returned) we iterate over the array and build a string of the html we want to inject into our document. Finally we insert the html into the 'SelectedCategoryId' element, and change the style of the element so it is visible to the user.
Note that I haven't run this code, but it should be (almost) what you need. jQuery's documentation is available at http://docs.jquery.com/Main_Page and the functions I used above are referenced here:
.ready()
.change()
jQuery.ajax()
.html()
.show()
You'd need to make the GetCategories as a public method as it would correspond to an action handler in your controller.
Your jquery code can look like:
<script type="text/javascript">
$(function() {
$('#SelectedPayeeId').change(function() {
$.get('<%= Url.Action("GetCategories", "YourControllerName") %>',
{payeeId: $(this).val()},
function(data) {
populateSelectWith($("#Category"), data);
});
});
//Place populateSelectWith method here
});
</script>
The populateSelectWith can fill your dropdown with data like:
function populateSelectWith($select, data) {
$select.html('');
$select.append($('<option></option>').val('').html("MYDEFAULT VALUE"));
for (var index = 0; index < data.length; index++) {
var option = data[index];
$select.append($('<option></option>').html(option));
}
}
I have not tested this code, but I am hoping it runs okay.
You can find syntax for the jquery ajax get here
Since you are not posting any data to the server, you can might as well decorate your controller action with a [HttpGet] attribute

Categories