I made a simple form where you write a string, and then print it on another view, but now i have to check the length of the string(using jquery) and print it on a Jquery UI dialog, already looked for some tutorials but im new to this MVC4 ASP .Net so its a little bit confusing to use jquery(which I have to) on this framework.
Here is the view of the form:
#{
ViewBag.Title = "Página principal";
}
<h3>Formulario</h3>
#using (Html.BeginForm())
{
#Html.Label("Escribe lo que quieras")<br />
#Html.TextArea("text")<br />
<button type="submit">Enviar</button>
}
Here is the view where i print the string i got from the first view:
#{
ViewBag.Title = "Hola, Escribiste: ";
}
<hgroup class="title">
<h1>#ViewBag.Title</h1>
<h2>#ViewBag.Message</h2>
</hgroup>
<script type="text/javascript">
var myLength = $("#text").val().length;
</script>
And here is the controller:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
namespace MvcApplication10.Controllers
{
public class HomeController : Controller
{
[HttpGet]
public ActionResult Index()
{
ViewBag.Message = "Modifique esta plantilla para poner en marcha su aplicación ASP.NET MVC.";
return View();
}
[HttpPost]
public ActionResult Index(string text)
{
TempData["Text"] = text;
return RedirectToAction("About", "Home");
}
public ActionResult About()
{
ViewBag.Message = TempData["Text"];
return View();
}
public ActionResult Contact()
{
ViewBag.Message = "Página de contacto.";
return View();
}
}
}
Please help me!
It's important to bear in mind that jQuery (and jQuery UI) are client-side technologies. That code runs in the user's browser. ASP.Net MVC is a server-side technology. That code runs on your server, and creates the HTML and JavaScript that is delivered to the browser.
You seem to be off to a reasonable start. You are outputting JavaScript code that will run in the browser and set the length of the string in a JavaScript variable
var myLength = $("#text").val().length;
Now, you need to add some additional code to create your jQuery UI dialog. You put that JavaScript code in your view as well. ASP.Net will then send that code to the browser as well, where it will run.
Have a look at the examples for jQuery UI dialogs and try to incorporate that into your view
http://jqueryui.com/dialog/
Fundamentally you will have a block of HTML that describes what will appear in the dialog, e.g.:
<div id="dialog" title="Basic dialog">
<p>The length of the string is: <span id='len'>RESULT HERE</span></p>
</div>
and will "convert" that block into the dialog using a call like:
<script>
$(function() {
$( "#dialog" ).dialog();
});
</script>
The only trick now is to update the text in that dialog to show the length of the string. There are many ways to accomplish that. One way is to have an HTML element as a placeholder for that value, and set the text of that element using jQuery:
$('#len').text(myLength);
Related
I changed the Person controller and Home view.
I have 209 people in the database. And that's how it shows me in the Person view.
When I interrupt the code count shows me 0.
View Home:
I also made changes here.
#model Legolandia.Models.Store
#{
ViewBag.Title = "Home Page";
}
<div class="jumbotron">
<div class="row">
#section Scripts {
<script>
// document.ready is fired once the page has loaded in the browser
$(document).ready(function () {
// set the url to get the data from the PersonController
var url = '#Url.Action("GetPersonCount", "Person")';
// use jQuery.getJSON to get our data from the controller
$.getJSON(url, function(data) {
// update the element with the count from the controller
$('#personCount').text(data.count);
});
});
</script>
}
<div id="orange" class="col-md-4">
<a class="change-a" href="/Person/Index">
<div class="change-title">
Person in system: <span id="personCount"></span>
</div>
Controller Person:
I also made changes here.
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Net;
using System.Web;
using System.Web.Mvc;
using Legolandia.Models;
namespace Legolandia.Controllers
{
public class PersonController : Controller
{
private LegolandEntities db = new LegolandEntities();
// GET: Person
public ActionResult Index()
{
var person = db.Person.Include(o => o.xxx);
ViewBag.PersonCount = db.Person.Count();
return View(person.ToList());
}
public ActionResult GetPersonCount()
{
var count = db.Person.Count(); // get count from database
var data = new { count }; // anonymous type
return Json(data); // return serialized Json data
}
Since you need to get data from PersonController and display it in a view of HomeController, I'd suggest using Ajax.
Create a new method in PersonController to return the data you need. This method will return Json data which you can use in the view.
public ActionResult GetPersonCount()
{
var count = db.Person.Count(); // get count from database
var data = new { count }; // anonymous type
return Json(data, JsonRequestBehavior.AllowGet); // return serialized Json data
}
Note: If you're using .Net Core you don't need the JsonRequestBehavior.AllowGet in the Json result.
Now, in Home/Index.cshml you will need to add some JavaScript. I'll actually use jQuery since it makes this task a little easier. Make sure you include jQuery on the page (MVC comes with jQuery included these days).
First, in Home/index.cshtml create a <span> element which will hold the value for PersonCount:
<div class="change-title">
Person in system: <span id="personCount"></span>
</div>
Now, near the bottom of Home/index.cshtml add some script tags:
#section Scripts {
<script>
// document.ready is fired once the page has loaded in the browser
$(document).ready(function () {
// set the url to get the data from the PersonController
var url = '#Url.Action("GetPersonCount", "Person")';
// use jQuery.getJSON to get our data from the controller
$.getJSON(url, function(data) {
// update the element with the count from the controller
$('#personCount').text(data.count);
});
});
</script>
}
Finally, in _Layout.cshtml make sure you put #RenderSection("Scripts", required: false) near the bottom of the page (below #RenderBody()).
Here I have used $.getJSON. It performs an ajax request to Person/GetPersonCount. Then we update the <span> with the person count from the GetPersonCount in PersonController.
Here's the result:
This method worked for me:
ViewBag.PatientCount = (from x in Hasta.TblPatient select x).Count();
In your controller, save count in ViewData:
{
ViewData["Users"] = _userManager.Users.Count();
return View();
}
In your view, retrieve the value:
#Html.ViewData["Users"]
This is the way I was sending my model to an angular controller scope.
c# Controller:
public class AreaMenuController : RootController
{
// GET: Menu
public PartialViewResult Index()
{
var mod = Modules.Instance.ModuleList.FirstOrDefault(m => m.Prefix.Equals(base.GetArea(), StringComparison.CurrentCultureIgnoreCase));
return PartialView("_AreaMenu", mod.ModuleMenus);
}
}
View cshtml:
#using Nuclei.Models
#model IEnumerable<Nuclei.Models.Menu>
<script type="text/javascript">
#{ var serializer = new System.Web.Script.Serialization.JavaScriptSerializer(); }
window.areaMenus = #Html.Raw(serializer.Serialize(Model));
</script>
<script type="text/javascript" src="#Url.Content("~/Scripts/AngularControllers/_AreaMenuController.js")"></script>
<div ng-controller="AreaMenuController as vm" ng-init="vm.initializeController()">
<div id="accordion" ng-class="accordian-menu" style="visibility: visible;">
<ul>
<li ng-repeat="menu in vm.areaMenus">
...
</li>
</ul>
</div>
</div>
Angular Js file:
var NucleiApp = angular.module('NucleiApp');
NucleiApp.controller('AreaMenuController', ['$scope', '$http', '$location', function ($scope, $http, $location) {
"use strict";
var vm = this;
vm.initializeController = function () {
vm.areaMenus = window.areaMenus;
}
}]);
Question 1: Is there a smoother way to send your c# model through to angular other than through global window object?
You can use an $http get from angular, however because this is processed client-side there is always a bit of lag before it gets displayed, because it needs to call the c# controller and get the data. So I'm reserving $http get for updates only.
The other other way I was thinking was to send the view a Json object straight off:
c# controller:
public class AreaMenusController : RootController
{
// GET: Menu
public PartialViewResult Index()
{
return PartialView("_AreaMenu", GetAreaMenus());
}
public JsonResult GetAreaMenus()
{
var mod = Modules.Instance.ModuleList.FirstOrDefault(m => m.Prefix.Equals(base.GetArea(), StringComparison.CurrentCultureIgnoreCase));
return Json(new { areaMenus = mod.ModuleMenus }, JsonRequestBehavior.AllowGet);
}
}
View cshtml:
#using System.Web.Mvc
#model JsonResult
<script type="text/javascript">
window.areaMenus = #Model;
</script>
Question 2: I'm not really sure how to initialize the #model at this point and send it through to the angular file and again, if there is a better option than javascripts global window object... open to suggestions!
We currently do this to bootstrap a set of data that is later updated by a call into a WebAPI.
The reason we do this is we have found cases where the data, when bootstrapped via an API call, was coming back too slowly, which gave a bad experience to our users.
In our razor view:
<html>
<head>
<script>
window.areaMenus = '#Html.Raw(Model.SerializedJsonString)';
</script>
</head>
</html>
Then when our angular app is Run(), we deserialize the data, and use it from there:
var app = angular.module('myApp', ["stuff"])
.run(["menuService", (menuService) => {
// deserialize the json string into my object
var areaMenus = angular.fromJson(window.areaMenus);
// do something with it
menuService.Load(areaMenus);
}]);
This'll get the data available to angular immediately without having to wait for a $http request to complete, which should address your issue.
C# asp.net MVC project: I have my index page with a button in it, I want to press it and update the same page with some results.
Here's some code:
The View: (with a button that calls the getConfig method in the controller)
#{
ViewBag.Title = "Home Page";
}
<form method="get" action="/Home/GetConfig/" >
<input type="submit" value="Get Config WS" />
</form>
<p>
#ViewBag.totalRecords
</p>
The controller:
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Message = "Test webservices";
return View();
}
public void getConfig()
{
string totalRecords = string.Empty;
wsConfig.config_pttClient client = new wsConfig.config_pttClient();
wsConfig.getConfigInput gci = new wsConfig.getConfigInput();
wsConfig.getConfigOutput gco = new wsConfig.getConfigOutput();
gco = client.getConfig(gci);
totalRecords = gco.result.totalRecords.ToString();
ViewBag.totalRecords = totalRecords;
}
I want to press the view's button and show the totalRecords on the same page.
How can I achieve this?
Edit: There might be other solutions, (if you don't mind updating your entire page) but this how I generally do it.
Ok, there are a couple of things that you need to change in order to make it work:
Create a new partial view that contains just the part that you would like to update (and wrap it an element with an id). In this example, let's call it 'Partial_TotalCount'.
This partial view will contain the following code:
<div id="updated">
<p>
#ViewBag.totalRecords
</p>
</div>
Now, change your original view so that it includes the partial view:
#{
ViewBag.Title = "Home Page";
}
<form method="get" action="/Home/GetConfig/" >
<input type="submit" value="Get Config WS" />
</form>
#Html.Partial("Partial_TotalCount", #Model)
Now, update your controller to work with an ajax request. This would make your controller looks like:
public ActionResult Index()
{
ViewBag.Message = "Test webservices";
if (Request.IsAjaxRequest())
{
getconfig();
return PartialView("Partial_TotalCount");
}
return View();
}
Now, you need to be able to submit the page when you click the button. This can be done through javascript:
First your javascript function that will update the contents:
<script type="text/javascript">
function Refresh() {
$.ajax({
url: '/Home/Index',
type: "GET",
dataType: "html",
success: function(data) {
$("#updated").html(data);
},
error: function() { alert('Refreshing error.'); }
});
}
</script>
You just need to add an onclick on your button. And you can remove the form tags from around your form aswell.
Edit: As requested by the questioner, I provide a bit of explanation on the Javascript function itself:
$.ajax means that we are doing an Ajax request. It means that we are doing some asynchronous requests with the server.
Then a couple of parameters are passed:
Url: The url that should be executed. In your example, the code behind the url "Home/GetConfig" get's executed.
Type: The type of submit that you want to do (POST, GET, ...)
dataType: The type we are expecting back from the server.
Success: The piece of javascript that needs to execute when complete. (In this case, update the DIV element with the id "WithCss" with the contents that are received with the url "Home/Getconfig".
Error: A function that is executed when the request failed for some reason.
There are a lot of other parameters you can pass (for example if you need to pass an id, and others.
For more explanation, please look at the original documentation.
Also, consider marking this answer as accepted.
I hope it works.
Try This:
Replace your input button code with the following code :
<input type="submit" id="btnSave" name="BtnSave" value="Get Config WS" />
Then in controller change the whole code for this code:
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Message = "Test webservices";
return View();
}
public ActionResult getConfig()
{
return View();
}
[HttpPost]
public ActionResult getConfig(FormCollection Form)
{
if(Form["BtnSave"]!=null)
{
string totalRecords = string.Empty;
wsConfig.config_pttClient client = new wsConfig.config_pttClient();
wsConfig.getConfigInput gci = new wsConfig.getConfigInput();
wsConfig.getConfigOutput gco = new wsConfig.getConfigOutput();
gco = client.getConfig(gci);
totalRecords = gco.result.totalRecords.ToString();
ViewBag.totalRecords = totalRecords;
}
return View();
}
Hopefully it works...!
Alright, so I have just started with razor mvc4 and I have a little experience with c#. I am currently making a website on which there is a button. my html follows:
<button onclick ="vote1_click" id="VoteButton" value="Vote">Vote</button>
this is in a .cshtml view
I then have a class to handle the vote1_click event. It is in c# and follows:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace MvcApplication1
{
public class voting
{
public void vote1_click(object sender, EventArgs e)
{
}
}
}
I believe that my issue is a fundamental understanding of the razor structure, but could not figure it out on my own.
Any help at all is appreciated, and I will try to not feel too stupid when the answer is simple.
Thanks!
EDIT:
I have been getting an issue where the Add(string name) gives me an error of "not all code paths return a value"
here is the rest of my code as requested:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using System.Data.SqlClient;
namespace WAgermanClub.Controllers
{
public class HomeController : Controller
{
[HttpPost]
public ActionResult Add(string vote)
{
SqlConnection vote1connection = new SqlConnection("user id=userid;" +
"password=validpassword;server=o5z5dpwpzi.database.windows.net;" +
"Trusted_Connection=yes;" +
"database=wagermanclub_votes; " +
"connection timeout=30");
try
{
vote1connection.Open();
}
catch (Exception g)
{
Console.WriteLine(g.ToString());
}
try
{
SqlDataReader myReader = null;
SqlCommand myCommand = new SqlCommand("select * from table", vote1connection);
myReader = myCommand.ExecuteReader();
while (myReader.Read())
{
Console.WriteLine(myReader["Vote1"].ToString());
}
}
catch (Exception i)
{
Console.WriteLine(i.ToString());
}
SqlCommand vote1command = new SqlCommand("INSERT INTO table (Column1, Vote1) " +
"Values (1, 'Vote1' + 1)", vote1connection);
vote1command.ExecuteNonQuery();
try
{
vote1connection.Close();
}
catch (Exception h)
{
Console.WriteLine(h.ToString());
}
}
}
}
And here is my HTML:
#{
ViewBag.Title = "Ideas";
}
#section featured {
<section class="featured">
<div class="content-wrapper">
<hgroup class="title">
<h1>#ViewBag.Title.</h1>
<h2>#ViewBag.Message</h2>
</hgroup>
<p>
</p>
</div>
</section>
}
<body>
<div style="border: solid; max-width: 300px; margin-left: auto; margin-right: auto">
#using(Html.BeginForm())
{
<input type="submit" value="Vote"/>
}
</div>
</body>
Thanks!
You are confused with ASP.NET webforms and MVC. MVC works more in the classic Web (GET-POST form) style. You post a form with values. There is no such click events and event handler in codebehind like what you have in web forms.
So to render your page, you may have an action method like this in your HomeController
public class HomeController : Controller
{
public ActionResult Add()
{
return View();
}
}
So in your Add view(razor file), you need to have some code to render a form tag with input elements. Let's use the Html.Begin form helper method to render the form tag for us.
#using(Html.Beginform())
{
<input type="text" name="name" />
<input type="submit" />
}
This will render a form tag in your markup with action property set as "Home/Add", assuming your GET action method is in HomeController. (Check the view source of the page)
So when user clicks on the submit button it will post the form to the Add action. so make sure you have an action method like this in HomeController to handle the form posting.(The one decorated with HttpPost attribute
[HttpPost]
public ActionResult Add(string name)
{
//do something with the posted values
return RedirectToAction("Success"); // redirecting to another view
}
You may be confusing the webforms model with the asp.net mvc model.
razor is only available for you when using webpages or asp.net mvc.
For asp.net mvc there's not concept of a server method/event as you've defined here.
You'll typically need to define action methods in your controllers which will be responsible for processing whatever forms your are posting.
You may want to check out more on ASP.NET MVC
MVC does not implement the web forms style viewstate and event handlers. So there is no vote1_click. What you would want to do is either
1) Create a JavaScript Post/Get back to the server
or
2) have a form and post back all the form variables back to the server
Here is a pretty good example of beginning MVC: http://www.asp.net/mvc/tutorials/mvc-4/getting-started-with-aspnet-mvc4/intro-to-aspnet-mvc-4
I am used to ASP.NET web forms, and am slowly learning ASP.NET MVC.
My website has a little login form on the homepage. My natural thought is that this login form may be useful in other places, and it is not the primary action of the homepage, so I want to separate it off into a partial view. And because it is related to accounts, I want the login in my AccountController not my HomepageController.
Login form is a pretty basic strongly typed partial view:
#model Models.Account.AccountLogin
<h2>Login Form</h2>
#using (Html.BeginForm("_Login", "Account")) {
#Html.ValidationSummary()
<div>
<span>Email address:</span>
#Html.TextBoxFor(x => x.EmailAddress)
</div>
<div>
<span>Password:</span>
#Html.PasswordFor(x => x.Password)
</div>
<div>
<span>Remember me?</span>
#Html.CheckBoxFor(x => x.RememberMe)
</div>
<input type="submit" value="Log In" />
}
</div>
On the homepage, I have this:
#Html.Action("_Login", "Account")
Finally, in the account controller, this:
[HttpGet]
public PartialViewResult _Login()
{
return PartialView();
}
[HttpPost]
public PartialViewResult _Login(AccountLogin loginDetails)
{
// Do something with this
return PartialView();
}
Now when I load my homepage, it looks OK and contains the form. When I click the Log In button, it takes me to myurl/Account/_Login, which contains the form, but not within the _Layout master page, just basic plain HTML and it doesn't do anything at all when I click Log In.
I am pretty sure that I have just missed some fundamental aspect of what I am supposed to be doing here, can someone please point me in the right direction?
It's because you're returning a partial view, which strips away the master page and just returns the main content. Often actions starting with an underscore are used for partials (e.g. ajaxing in a bit of a page, but not the full page). It sounds like you want a full action, and not a partial, so
[HttpPost]
public ActionResult Login(AccountLogin loginDetails)
{
// Do something with this
return View();
}
The issue here is that you are doing a fullpage postback.
You have two options, really.
Firstly, you can use a full page postback, and then call Html.Partial to display your Partial.
Something like
[HttpGet]
public ActionResult Login()
{
return View();//this typically returns the view found at Account/Index.cshtml
}
And then create a View along the lines of
#{
ViewBag.Title = "Index";
}
<h2>Title</h2>
#Html.Partial("PartialNameGoesHere")
Your partial is then rendered where indicated, but this is done when the page loads (if you look at the generated HTML, it appears exactly as though you had written it inline).
Or you can use jQuery/AJAX to load the partial on demand. Let's say you have a homepage of some description
public ActionResult Home()
{
return View();
}
public ActionResult Login()
{
return PartialView("_Login");
}
Create the view
#{
ViewBag.Title = "Index";
}
<h2>Home</h2>
<div>
<p>Hey welcome to my pretty awesome page!</p>
</div>
Show me the login!
<div id="container">
</div>
You can then load the PartialView into the container div whenever you need it, using some JS.
$(function() {
$('.my-login-link').click(function() {
$.ajax({
url: 'account/login',
success: function(data) {
$('#container').html(data);
}
});
return false;//cancel default action
});
});
In that instance, the page loads as normal without the login part. When the user clicks the link, the Login on the controller Account is called using AJAX/jQuery. This returns the HTML of the PartialView, which you can then add to the page using jQuery in the Success handler.