ASP.Net Core, My google chart won't display - c#

Allright, so the issue I'm having is that my google chart wont display.I am fairly new to working with ASP.NET core applications, and I'm doing a school project.
This is an example that works. I am trying to display data from a list that get it's data from a database, but I don't seem to get it to work.
This hardcoded data works fine:
<html>
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load('current', { 'packages': ['corechart'] });
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Time', 'Data'],
['2004', 1000],
['2005', 1170],
['2006', 660],
['2007', 1030]
]);
var options = {
title: 'Temperature',
curveType: 'function',
legend: { position: 'bottom' }
};
var chart = new google.visualization.LineChart(document.getElementById('curve_chart'));
chart.draw(data, options);
}
</script>
</head>
<body class="container-fluid lead">
<div id="curve_chart" style="width: 900px; height: 500px"></div>
</body>
</html>
But when i try to replace the hardcoded data with a foreach-loop it won't display. The page is just blank. This is my drawChart() with a foreach-loop.
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Time', 'Data'],
#foreach (var item in Model.measurementDataList)
{
<text>['#item.TimeStamp', #item.MeasuredValue],</text>
}
]);
I have displayed some data from the same database in a table. So the method I'm used to fill the list works. This is my method to getting the data from the database:
public List<MeasurementData> GetMeasurementData(string connectionString)
{
List<MeasurementData> measurementDataList = new List<MeasurementData>();
SqlConnection con = new SqlConnection(connectionString);
string sqlQuery = "SELECT Timestamp, MeasuredValue FROM MEASUREDATA";
SqlCommand cmd = new SqlCommand(sqlQuery, con);
con.Open();
SqlDataReader dr = cmd.ExecuteReader();
while (dr.Read())
{
MeasurementData measureParameter = new MeasurementData();
measureParameter.TimeStamp = dr["Timestamp"].ToString();
measureParameter.MeasuredValue = Convert.ToDouble(dr["MeasuredValue"]);
measurementDataList.Add(measureParameter);
}
return measurementDataList;
}
And here's the OnGet().
public void OnGet()
{
SensorConfig sensorConfig = new SensorConfig();
connectionString = _configuration.GetConnectionString("ConnectionString");
measurementDataList = sensorConfig.GetMeasurementData(connectionString);
}
view data source feature:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>MonitorLog - MonitoringApplication</title>
<link rel="stylesheet" href="/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="/css/site.css" />
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container">
<a class="navbar-brand" href="/">MonitoringApplication</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" href="/">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" href="/MonitorLog">Monitor log</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" href="/Privacy">Privacy</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" href="/SensorInformation">About Sensors</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
<html>
<head>
<script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script>
<script type="text/javascript">
google.charts.load('current', { 'packages': ['corechart'] });
google.charts.setOnLoadCallback(drawChart);
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Time', 'Data'],
]);
var options = {
title: 'Temperature',
curveType: 'function',
legend: { position: 'bottom' }
};
var chart = new google.visualization.LineChart(document.getElementById('curve_chart'));
chart.draw(data, options);
}
</script>
</head>
<body class="container-fluid lead">
<div id="curve_chart" style="width: 900px; height: 500px"></div>
</body>
</html>
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
© 2020 - MonitoringApplication - Privacy
</div>
</footer>
<script src="/lib/jquery/dist/jquery.min.js"></script>
<script src="/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="/js/site.js?v=dLGP40S79Xnx6GqUthRF6NWvjvhQ1nOvdVSwaNcgG18"></script>
</body>
</html>

Here comes the mistake:
#foreach (var item in Model.measurementDataList)
{
<text>['#item.TimeStamp', #item.MeasuredValue],</text>
}
Because if you render C# in cshtml directly, ASP.NET Core will HTML encode your script.
To make your app run, consider changing the script to
function drawChart() {
var data = google.visualization.arrayToDataTable([
['Time', 'Data'],
#foreach (var item in Model.measurementDataList)
{
Html.Raw($"['{item.TimeStamp}', {item.MeasuredValue}],")
}
]);
While this may solve your issue, rendering your data with C# to HTML is not a good practice.
I strongly suggest you writing an API that returns your data and you can write pure javascript to get the data.
Like this:
$.get('/api/mychartdata', function(data) {
google.visualization.arrayToDataTable(data);
})
And the data is rendered as JSON from your ASP.NET Core Web API.
If you are not familiar with Web API, please read document here:
https://learn.microsoft.com/en-us/aspnet/core/tutorials/first-web-api?view=aspnetcore-3.1&tabs=visual-studio

Related

jQuery(...).kendoGrid is not a function

I am trying to create a Kendo Grid but I keep getting the same error, saying that the kendoGrid is not a function:
This is my view:
#model IEnumerable<ModelLayer.Models.TableNotificationModel>
#addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
#addTagHelper *, Kendo.Mvc
#using Kendo.Mvc.UI
#{
ViewData["Title"] = "Index";
}
<script src="https://code.jquery.com/jquery-1.12.3.min.js">
window.rootUrl = '#Url.Content("~/")';
</script>
<script src="https://kendo.cdn.telerik.com/2020.2.617/js/kendo.all.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2020.2.617/js/kendo.aspnetmvc.min.js"></script>
<h1>Upload index</h1>
<div>
<h4>Upload file</h4>
<form asp-controller="Upload" asp-action="Upload"
enctype="multipart/form-data" method="post">
<input type="file" name="file" />
<button type="submit" id="btn">Upload</button>
</form>
#if (ViewBag.Message != null)
{
<script>
$(document).ready(function(){
alert('#Html.Raw(ViewBag.Message)');
});
</script>
}
</div>
<div class="clearfix">
#(Html.Kendo().Grid<ModelLayer.Models.TableNotificationModel>()
.Name("notificationGrid")
.Columns(columns =>
{
columns.Bound(c => c.OPERATOR_OBJECTID).Title("ID").Hidden();
columns.Bound(c => c.SETTLEMENT_CODE).Title("settlement code").Width("100px");
columns.Bound(c => c.TECHNOLOGY_CODE).Title("tech code").Width("100px");
columns.Bound(c => c.UPLOAD_SPEED_CLASS_CODE).Title("upload").Width("100px");
columns.Bound(c => c.DOWNLOAD_SPEED_CLASS_CODE).Title("download").Width("100px");
columns.Bound(c => c.DATA_CATEGORY_QOS_CODE).Title("data category").Width("100px");
columns.Bound(c => c.SHAPE).Title("shape").Width("100px");
//columns.Bound(c => c.Message).Title("message").Width("100px");
})
.DataSource(dataSource => dataSource
.Ajax()
.PageSize(20)
.Read(read => read.Action("Upload_Read", "Upload"))
)
)
</div>
I made sure not to have the jQuery script twice, so here's my _Layout.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>#ViewData["Title"] - M20_AEK</title>
<link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.min.css" />
<link rel="stylesheet" href="~/css/site.css" />
</head>
<body>
<header>
<nav class="navbar navbar-expand-sm navbar-toggleable-sm navbar-light bg-white border-bottom box-shadow mb-3">
<div class="container">
<a class="navbar-brand" asp-area="" asp-controller="Home" asp-action="Index">M20_AEK</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target=".navbar-collapse" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="navbar-collapse collapse d-sm-inline-flex flex-sm-row-reverse">
<ul class="navbar-nav flex-grow-1">
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Index">Home</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="CustomerType" asp-action="LoadCustomerType">Customer Type</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="DataCategory" asp-action="LoadDataCategory">Data Category</a>
</li>
<li class="nav-item">
<a class="nav-link text-dark" asp-area="" asp-controller="Upload" asp-action="Index">Upload</a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<div class="container">
<main role="main" class="pb-3">
#RenderBody()
</main>
</div>
<footer class="border-top footer text-muted">
<div class="container">
© 2020 - M20_AEK - <a asp-area="" asp-controller="Home" asp-action="Privacy">Privacy</a>
</div>
</footer>
<script src="~/lib/jquery/dist/jquery.min.js"></script>
<script src="~/lib/bootstrap/dist/js/bootstrap.bundle.min.js"></script>
<script src="~/js/site.js" asp-append-version="true"></script>
#RenderSection("Scripts", required: false)
</body>
</html>
This is my controller:
public ActionResult Upload_Read([DataSourceRequest] DataSourceRequest request)
{
return Json(json_read.ToDataSourceResult(request));
}
I tried placing the Kendo and jQuery scripts in _Layout and that didn't help. I tried different formats for the columns and column menu and fields for the Kendo grid, but it still throws the same error.
What could the issue be?
<script src="https://code.jquery.com/jquery-1.12.3.min.js">
window.rootUrl = '#Url.Content("~/")'; </script>
does not look valid (you normally have src or code inside the tag - not both). I'd suggest removing the src.
I found the solution. If you are using jQuery Office, any version, look for the plugins file attached to your project which contains jQuery code and delete the next line completely:
( !function(e,t){"use strict";"object"==typeof module&&"object"==typeof module.exports?module.exports=e.document?t(e,!0): )
to the end of the line
{return C.$===k&&(C.$=Jt),e&&C.jQuery===k&&(C.jQuery=Qt),k},e||(C.jQuery=C.$=k), k});
Because it will be duplicated in jQuery.js file. This is what is causing the error:

Unable to open the cshtml page

I have developed an application and deployed to cloud. By default index page is loading but once index page is loaded on click on it it will open other page(cshtml page). But i am getting blank page . Please help
Index.cshtml code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Create Invoice Online for Free & Download PDF</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<link rel="stylesheet" type="text/css" href="../Content/bootstrap.css" />
<link rel="stylesheet" type="text/css" href="../Content/bootstrap-responsive.min.css" />
<link rel="stylesheet" type="text/css" href="../Content/quick-invoice.css" />
<script type="text/javascript" src="../Content/jquery.js"></script>
<script type="text/javascript" src="../Content/bootstrap.min.js"></script>
<meta name="google-site-verification" content="FB0t_l2pYlfmLe1hzPyjLXXhDF8Bufut_nDhCP5brrQ" />
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="navbar-inner">
<div class="container">
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</a>
<a class="brand" href="/">Invoices generator</a>
<div class="nav-collapse">
<ul class="nav">
<li class="active"><i class="icon-home icon-white"></i>Home</li>
<li><i class="icon-file icon-white"></i> Invoice Templates</li>
</ul>
</div>
</div>
</div>
</div>
<div class="container layout">
<div class="row">
<div class="span9">
<div class="container-narrow">
<div class="container-narrow jumbotron">
<h1>Shopping Cart Online Invoice Generator</h1>
<p class="lead">Create & Send your invoice without having to register, and download as <strong>PDF, </strong>quickly & easily for free, email your invoice Select an invoice template from our invoices templates list, Save or send your invoice in minutes</p>
<hr /> Create your invoice
<hr />
</div>
</div>
<div class="pop-layouts">
<h4>Invoice Templates</h4>
<ul class="thumbnails">
<li>
<h4>Shopping Cart Invoice Template</h4>
<a class="thumbnail" href="create" title="Shopping Cart Invoice Template">
<img src="../Images/057e7_b4a13_1.jpg" alt="" date-large="../Images/4dad1_733d6_1.png" />
</a>
<div class="caption">
<!--<i class="icon-eye-open icon-white"></i> Preview-->
<i class="icon-plus-sign icon-white"></i> Create
</div>
</li>
</ul>
</div>
</div>
</div>
</div>
<script type="text/javascript">
(function (i, s, o, g, r, a, m) {
i['GoogleAnalyticsObject'] = r; i[r] = i[r] || function () {
(i[r].q = i[r].q || []).push(arguments)
}, i[r].l = 1 * new Date(); a = s.createElement(o),
m = s.getElementsByTagName(o)[0]; a.async = 1; a.src = g; m.parentNode.insertBefore(a, m)
})(window, document, 'script', '//www.google-analytics.com/analytics.js', 'ga');
ga('shopping-cart-invoices', 'UA-47492117-1', 'mybluemix.net');
ga('send', 'pageview');
</script>
</body>
</html>
Startup.cs
using System;
using Microsoft.AspNet.Mvc;
using Microsoft.AspNet.Builder;
using Microsoft.Framework.DependencyInjection;
using Microsoft.AspNet.StaticFiles;
public class Startup
{
public void Configure(IApplicationBuilder app)
{
app.UseServices(services =>
{
services.AddMvc();
});
app.UseFileServer(new FileServerOptions()
{
EnableDirectoryBrowsing = false,
});
app.Use(async (context, next) =>
{
Console.WriteLine(context.Request.Path);
try
{
await next();
}
catch (Exception ex)
{
Console.WriteLine(ex);
}
});
app.UseMvc(routes =>
{
routes.MapRoute(
name: "Default",
template: "{controller=Home}/{action=Index}/{id?}"
);
routes.MapRoute(
name: "CreateInvoice",
template: "{controller=CreateInvoice}/{action=Create}/{id?}"
);
routes.MapRoute(
name: "Preview",
template: "{controller=Preview}/{action=preview}/{id?}"
);
routes.MapRoute(
name: "Thanks",
template: "{controller=Thanks}/{action=Thankyou}/{id?}");
});
}
}
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
}
You should be using
#Html.actionlink("Create", "CreateInvoice")
This will allow you to declare the action and the controller
It also means that you will get build errors if the action or controller do not exist

how to get a confirmation popup to display using jquery and mvc 5?

I am trying to render a jquery popup onto a razor view. I have created a link in my view but when I click it I get a 404 error saying the page can't be found.
I have used jsbin.com so I know the jquery code is correct but clearly I am missing something, I guess I am either incorrectly rendering the javascript or I am trying to put the popup in a wrong file.
Can anyone explain what I have done wrong and why?
partial cshtml: popup
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>jQuery UI Dialog - Modal confirmation</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.1/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.1/jquery-ui.js"></script>
<script>
$(function() {
$("#enableDisable").click(function () {
$( "#dialog-confirm" ).dialog({
resizable: false,
height:220,
width:475,
modal: true,
buttons: {
"OK": function() {
$( this ).dialog( "close" );
},
Cancel: function() {
$( this ).dialog( "close" );
}
}
});
});
});
</script>
</head>
<body>
<a id="Link">
click me
</a>
<div id="dialog-confirm" title="Empty the recycle bin?">
Are you sure you want to change the status of: #ViewBag.UserName
</div>
</body>
</html>
My Razor view requring the popup
#{
ViewBag.Title = "User Details";
}
<h2>User Details</h2>
<p><b>#ViewBag.UserName</b></p>
<table class="table">
<tr>
<th>
Application Name
</th>
<th>
Status
</th>
<th>
</th>
</tr>
#if (ViewBag.ApplicationStatuses.Count > 0)
{
#*Iterating Amadeus model using ViewBag *#
foreach (var item in ViewBag.ApplicationStatuses)
{
<tr>
<td>
#item.Key
</td>
<td>
#item.Value
</td>
<td>
<a href="~/Views/Home/ChangeStatusConfirmation" id="enableDisable">
Change Status
</a>
</td>
<td>
#Html.ActionLink("View Permissions", "Permissions", new { userID = View Bag.UserName, applicationName = item.Key })
</td>
</tr>
}
}
</table>
finally my layout view:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>#ViewBag.Title - Business Security System</title>
#Styles.Render("~/Content/css")
#Scripts.Render("~/bundles/modernizr")
<link rel="stylesheet" href="http://code.jquery.com/ui/1.11.1/themes/smoothness/jquery-ui.css">
<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://code.jquery.com/ui/1.11.1/jquery-ui.js"></script>
</head>
<body>
<div class="navbar navbar-inverse navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
#*#Html.ActionLink("Application name", "Index", "Home", new { area = "" }, new { #class = "navbar-brand" })*#
</div>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>#Html.ActionLink("Home", "Index", "Home")</li>
<li>#Html.ActionLink("MyTeam", "MyTeam", "Home")</li>
<li>#Html.ActionLink("Contact", "Contact", "Home")</li>
</ul>
#*#Html.Partial("_LoginPartial")*#
<p style="color:grey; text-align:right; margin-top:15px">#System.Security.Principal.WindowsIdentity.GetCurrent().Name</p>
</div>
</div>
</div>
<div class="container body-content">
#RenderBody()
<hr />
#*<footer>
<p>© #DateTime.Now.Year - My ASP.NET Application</p>
</footer>*#
</div>
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/bootstrap")
#RenderSection("scripts", required: false)
</body>
</html>
Any assistance will be greatly appreciated.
I ended up using an action link in my view instead of the action tab I used before as shown:
#Html.ActionLink("Change Status", "ChangeStatus", "Home", new { userName = ViewBag.UserName, applicationName = item.Key, currentStatus = item.Value }, new { #class = "enableDisable" })
and instead of having the Jquery code in a seperate file I put the code I needed in the view file and ran it from there.
<div id="dialog-confirm" title="Change Status?">
Are you sure you want to change the status of: #ViewBag.UserName
</div>
#section Scripts {
<link rel="stylesheet" href="http://code.jquery.com/ui/1.11.1/themes/smoothness/jquery-ui.css">
<script src="http://code.jquery.com/ui/1.11.1/jquery-ui.js"></script>
<script type="text/javascript">
$("#dialog-confirm").hide();
$(function () {
$(".enableDisable").click(function () {
$("#dialog-confirm").dialog({
resizable: false,
height: 220,
width: 475,
modal: true,
buttons: {
"OK": function () {
$(this).dialog("close");
window.location.href = "~/Home/ChangeStatus/username/dbname/currentstatus/"
},
Cancel: function () {
$(this).dialog("close");
}
}
});
});
});
</script>
}
This is not the most elegant solution but it works well in the solution I am working in.
href="~/Views/Home/ChangeStatusConfirmation" doesn't seems right.
It should be ~/ControllerName/ActionName. also if you are handling the click event you should not use the href attribute.

Beginner: Autocomplete not working?

I'm trying to create a autocomplete textbox.
This is what I have in view
#model .....
#{
ViewBag.Title = "Create";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#using(Html.BeginForm("Action","Controller"))
{
#Html.TextBoxFor(m=>m.myEmail)
}
#section Scripts{
#Scripts.Render("~/Scripts/jquery-ui-1.10.4.min.js")
<script type="text/javascript">
$(function() {
$("#myEmail").
autocomplete({
source: '/App/Per',
minLength: 1,
}
);
});
</script>
}
When I type lets say s in textbox a request is sent to this method in controller
public JsonResult Person(string term)
{
var persons = FindPersons(term,"bk#hello.com","bk").ToArray();
var fullnameList = persons.Select(person => person.FirstName + " " + person.LastName).ToList();
return Json(fullnameList, JsonRequestBehavior.AllowGet);
}
in browser when I inspect the element in chrome and check the response i get the values, for example
0: "Person1"
1: "Person2"
2: "Person3"
3: "Person4"
Problem
My autocomplete box doesn't fill up with these data. Wasn't i supposed to get a listbox thingy at the bottom of the textbox with above names?
Edit 2: Generated HTML
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Create - My ASP.NET Application</title>
<link href="/Content/bootstrap.css" rel="stylesheet"/>
<link href="/Content/site.css" rel="stylesheet"/>
<script src="/Scripts/modernizr-2.7.1.js"></script>
</head>
<body>
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/">Date Picker</a>
<div class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li>Home</li>
<li>About</li>
<li>Contact</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li>Register</li>
<li>Log in</li>
</ul>
<div class="container body-content">
<link href="/Content/themes/base/minified/jquery-ui.min.css" rel="stylesheet"/>
<h2>Create</h2>
<form action="/App/Cr" method="post"><input id="myEmail" name="myEmail" type="text" value="" /></form>
</div>
<script src="/Scripts/jquery-2.0.3.js"></script>
<script src="/Scripts/bootstrap.js"></script>
<script src="/Scripts/respond.js"></script>
<script src="/Scripts/jquery-ui-1.10.4.min.js"></script>
<script type="text/javascript">
$(function() {
$("#myEmail").
autocomplete({
source: '/App/Per',
minLength: 1,
}
);
});
</script>
Nothing looks particularly off (aside from the CSS link being misplaced). You might want to try formatting your JSON a bit differently, which would also have the effect of answering your last question.
Instead of this:
public JsonResult Person(string term)
{
var persons = FindPersons(term,"bkc#example.com","bk").ToArray();
var fullnameList = persons.Select(person => person.FirstName + " " + person.LastName).ToList();
return Json(fullnameList, JsonRequestBehavior.AllowGet);
}
Try using:
public JsonResult Person(string term)
{
var persons = FindPersons(term,"bk#example.com","bk").ToArray();
return Json(persons.Select(p => new { label = p.FirstName + " " + p.LastName, value = p.Email }), JsonRequestBehavior.AllowGet);
}
This is one of the results the API says the widget will work with: http://api.jqueryui.com/autocomplete/#option-source

Jquery bind events: blur, focus not working in mvc4

I found simple textbox watermark script that I was going to use in my project but I can't understand whats wrong, I tried debugging with Firebug and I can see it going through jquery code only once when page is loaded,after that textbox acts like nothing was binded to its focus or blur and I don't see any breakpoints getting hitted in script, here is whole layout page with script:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>#ViewBag.Title</title>
<link href="#System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/Content/css")" rel="stylesheet" type="text/css" />
<link href="#System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/Content/themes/base/css")" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="#System.Web.Optimization.BundleTable.Bundles.ResolveBundleUrl("~/Scripts/js")"></script>
<style type="text/css">
.water
{
font-family: Tahoma, Arial, sans-serif;
color:gray;
}
</style>
<script type="text/javascript">
$(document).ready(function () {
$(".water").each(function () {
$tb = $(this);
if ($tb.val() != this.title) {
$tb.removeClass("water");
}
});
$(".water").focus(function () {
$tb = $(this);
if ($tb.val() == this.title) {
$tb.val("");
$tb.removeClass("water");
}
});
$(".water").blur(function () {
$tb = $(this);
if ($.trim($tb.val()) == "") {
$tb.val(this.title);
$tb.addClass("water");
}
})
});
</script>
</head>
<body>
<div class="wrapper">
<div id="messageBox" align="center">
</div>
<div class="header">
<div class="header-column">
<h1 id="logo" class="no-border"><img src="../../Content/themes/base/images/ps-logo.png" style="margin-top:10px;" alt="" /></h1>
</div>
<div class="header-column lh50" align="center">
<div>
<input type="text" ID="txtSearch" class="water" title="Search" value="" />
</div>
</div>
<div class="header-column">
<div class="main-menu lh50">
<ul>
<li>
#if(!Request.IsAuthenticated)
{
<a href="Login">Login using
<img alt="Facebook" src="../../Content/themes/base/icons/facebook-icon.png" class="login-icon" />
<img alt="Google" src="../../Content/themes/base/icons/google-icon.png" class="login-icon" />
<img alt="Yahoo" src="../../Content/themes/base/icons/yahoo-icon.png" class="login-icon" />
</a>
<span> or </span>
Register
}
else{
<span>#GetCurrentUsername(this.Context)</span>
Log out
Post
}
</li>
</ul>
</div>
</div>
</div>
<div class="clear">
</div>
#RenderBody()
<div class="push">
</div>
</div>
<div class="footer" align="center">
<ul>
<li>Home</li>
<li>Services</li>
<li>Portfolio</li>
<li><a class="active" href="#">Resources</a></li>
<li>Contact</li>
</ul>
<p>
Copyright © 2012 Domain - All rights reserved</p>
</div>
</body>
</html>
Is there problem in mvc4, my code or something else?
The script works, you just need to ensure that the value of the textbox is the same as the title initially:
<input type="text" ID="txtSearch" class="water" title="Search" value="Search" />
Because that's what you are checking here:
$(".water").each(function () {
$tb = $(this);
if ($tb.val() != this.title) {
$tb.removeClass("water");
}
});
And if the value is different than the title (in your case title="Search" and value="") you remove the water class and nothing will happen later.
You are using the same .water class to describe the set of textboxes that might have watermarks, and also to specifically turn the watermark on and off.
That could get messy, as when you attach the focus and blur events its no longer clear what the .water selector will find because you've already removed it from some textboxes.
Think it should be more like:
$(document).ready(function () {
$(".potentialwater").each(function () {
$tb = $(this);
if ($tb.val() != this.title) {
$tb.removeClass("water");
}
});
$(".potentialwater").focus(function () {
$tb = $(this);
if ($tb.val() == this.title) {
$tb.val("");
$tb.removeClass("water");
}
});
$(".potentialwater").blur(function () {
$tb = $(this);
if ($.trim($tb.val()) == "") {
$tb.val(this.title);
$tb.addClass("water");
}
})
});

Categories

Resources