asp.net mvc get value from Html.TextBoxFor() - javascript

I'm new to MVC(Asp.net) as well as JavaScript. sorry for this primary question.
<body>
<div>
<%--<% Html.BeginForm(); %>--%>
<table>
<tr>
<td><%:Html.LabelFor(t=> t.CustomerID) %></td>
<td><%:Html.TextBoxFor(t => t.CustomerID, new { ID = "txtCustomerID" })%></td>
</tr>
<tr>
<td><%:Html.LabelFor(t=> t.CustomerName) %></td>
<td><%:Html.TextBoxFor(t => t.CustomerName, new { ID = "txtCustomerName" })%></td>
</tr>
<tr>
<td>
<input type="submit" value="Submit" onclick="CheckName()" />
</td>
</tr>
</table>
<%--<% Html.EndForm(); %>--%>
</div>
</body>
I need to get t.CustomerName value using JavaScript. I tried as below and it gives me errors.
<head runat="server">
<script type="text/javascript">
function CheckName() {
var value = document.getElementById('<%=t.CustomerName%>').value;
alert(value);
}
function SubmitData() {
var obj = {};
obj.CustomerID = $("#txtCustomerID").val();
obj.CustomerName = $("#txtCustomerName").val();
$.ajax({
url: "CreateNewRetailCustomer?jsonObject=" + JSON.stringify(obj),
type: 'POST',
contentType: 'application/json; charset=utf-8',
dataType: 'json',
success: function (result) {
if (result.status == "successful") {
document.location.href = '../';
}
}
});
}
</script>
<title>Create Wholesale Customer</title>
</head>
i wrote my controller coding as below :
public ActionResult CreateRetailCustomer()
{
return View();
}
[HttpPost]
public ActionResult CreateRetailCustomer(RetailCustomer retCust)
{
new CustomerService.CustomerServiceClient().SaveRetailCustomer(retCust);
return RedirectToAction("Index");
}
[HttpPost]
public JsonResult CreateRetailCustomer(string jsonObject)
{
var retailCustomer = new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize<Models.RetailCustomer>(jsonObject);
new CustomerService.CustomerServiceClient().SaveRetailCustomer(retailCustomer);
return Json(new { status = "successful" }, JsonRequestBehavior.AllowGet);
}
[HttpGet]
public JsonResult GetCustomerList()
{
var custlist = new CustomerService.CustomerServiceClient().GetCustomer().Select(m => new { CustomerId = m.CustomerId, CustomerName = m.CustomerName});
return Json(custlist, JsonRequestBehavior.AllowGet);
}
error:
An error occurred during the compilation of a resource required to
service this request. Please review the following specific error
details and modify your source code appropriately.
I searched and I found similar question asp.net mvc get value from Html.textbox() here. but it doesn't discussed about how to get value from Html.TextBoxFor so how can I do this?

var value = document.getElementById('<%=t.CustomerName%>').value;
This line is causing the error. ASP.NET MVC doesn't generate random client side ids like in Web Forms. They will be the same property name in your model. This line is what you are looking for:
var value = document.getElementById('CustomerName').value;
Also HTML helpers like TextBoxFor() take some delegates as a parameter. t variable you are trying to use is meaningful in the context of a lambda expression(a short way to create delagates and expressions). If you want to reach a model property, use Model variable.

A clean way to get the ID is to use IdFor(). This allows hierarchical IDs to be resolved and avoids hardcoding the string name for the property into your code.
function CheckName() {
var value = document.getElementById('<%:Html.IdFor(t => t.CustomerName) %>').value;
alert(value);
}

Related

ASP CORE JSON OBJECT NULL or COUNT 0

I'm trying to send a list of values from View to Controller. I tried a lot of solutions from the Internet but haven't succeeded.
My View HTML Table list of Data send to controller via JSON but the list is empty even when I use JSON.stringify
Heres my code
JavaScript:
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>
<script type="text/javascript" src="http://ajax.cdnjs.com/ajax/libs/json2/20110223/json2.js"></script>
<script type="text/javascript">
$("body").on("click", "#btnSave", function () {
//Loop through the Table rows and build a JSON array.
var customers = new Array();
$("#tblCustomers TBODY TR").each(function () {
var row = $(this);
var customer = {};
//skill.skill_name = row.find("TD").eq(0).html();
customer.CNIC = row.find("TD").eq(1).html();
customers.push(customer);
});
console.log(customers);
console.log(JSON.stringify(customers));
//Send the JSON array to Controller using AJAX.
$.ajax({
type: "POST",
//traditional: true,
url: "/Admin/Reconcile/Customers",
contentType: "application/json; charset=utf-8",
data: JSON.stringify(customers),
dataType: "json",
success: function (r) {
alert(r + " record(s) inserted.");
location.reload();
}
});
});
</script>
Controller Action:
public JsonResult Customers(List<String> customers)
{
}
Firstly,you need to create a model like this:
public class Customer {
public string CNIC { get; set; }
}
Then since you pass json type data in ajax,you need to use [FromBody] in action:
public JsonResult Customers([FromBody]List<Customer> customers)
{
}
You are sending an array of objects, so for the model binder to work you should accept a List of SomeModel, where SomeModel should have a property CNIC. Check the documentation here https://learn.microsoft.com/en-us/aspnet/web-api/overview/formats-and-model-binding/parameter-binding-in-aspnet-web-api on how objects are binded.
So you are sending this:
[
{
"CNIC":"somevalue",
"CNIC":"somevalue"
}
]
And you are trying to bind it to a List of string and it will not happen. Try binding it with List of SomeModel:
public class SomeModel
{
public string CNIC { get; set; }
}
Also try this attribute [IgnoreAntiforgeryToken] above your action. If it works then, you should be sending the antiforgery token with the post request.

How to return a JsonResult to Razor Page?

I'm new to ASP.net and Razor Pages. In the codes below, I'm trying to fill the District dropdownlist with values based on the State dropdownlist. Here's what I've got so far:
View:
<script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8/jquery-ui.min.js"></script>
<script language="javascirpt" type="text/javascript">
function GetDist(_stateId) {
var procemessage = "<option value='0'> Please wait...</option>";
$("#select-state").html(procemessage).show();
var url = "/Info/GetDistById/";
$.ajax({
url: url,
data: { stateid: _stateId },
cache: false,
type: "POST",
success: function (data) {
var markup = "<option value='0'>Quận/Huyện</option>";
for (var x = 0; x < data.length; x++) {
markup += "<option value=" + data[x].Value + ">" + data[x].Text + "</option>";
}
$("#select-state").html(markup).show();
},
error: function (reponse) {
alert("error : " + reponse);
}
});
}
</script>
<div class="col-md-offset-0 col-md-2">
<select class="form-control" id="select-state" onchange = "javascript:GetDist(this.value);">
#foreach (var state in Model.tbState)
{
<option value=#state.StateId>#state.Statename</option>
}
</select>
</div>
<div class="col-md-1 ">Quận/Huyện: </div>
<div class="col-md-offset-0 col-md-2">
<select class="form-control" id="select-dist">
#foreach (var dist in Model.tbDistrict)
{
<option value=#dist.DistrictId>#dist.Districtname</option>
}
</select>
</div>
On my cshtml.cs file I have this code. I did use System.Web.Helpers at the beginning of the code:
public IActionResult GetDistById(int stateid)
{
List<TbDistrict> list = new List<TbDistrict>();
foreach (var q in tbDistrict)
{
if (q.StateId == stateid)
list.Add(q);
}
SelectList selectlist = new SelectList(list, "", "", 0);
JsonResult result = Json(selectlist);
return result;
}
I found out that the Json() method only works with the Controller class in MVC, not a Razor PageModel class, so it gives error CS0103 "The name 'Json' does not exist in the current context". Is there a way to make it work?
There are multiple issues.
For return json, you need to try the suggestion from #poke by using return new JsonResult like
public IActionResult OnGetDistById(int stateid)
{
return new JsonResult(new Product { Id = stateid, Name = "Tom" });
}
For action method in PageModel, its name should follow the suggestion from #Prakash by using OnGetDistById
For client side, its request url should be https://localhost:44358/index?handler=distbyid&stateid=2 with specicying the handler and querystring stateid
Anyway, if you prefer request url like /Info/GetDistById/, you need to implement web api in your razor project instead of PageModel.
You could follow:
Add ValuesController in your project like
[Route("api/[controller]")]
public class ValuesController : Controller
{
// GET: api/<controller>
[HttpGet]
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
}
Configure route in Startup.cs
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller=Home}/{action=Index}/{id?}");
});
ASP Pages has usual OnGet and OnPost methods. If you need any additional calls to the same page via Ajax, then you will have to follow the OnGet* and OnPost* convention.
In the example you have given, you need to name the method as OnPostDistById and in the Javascript you need have the URL as "/Info/DistById". Had that been a HTTP Get call, the method name would have been OnGetDistById and the URL would remain the same.
See here for more info.

How to Display data in tables in View in MVC...Ajax and Json?

I am new to MVC. Started learning 2 months back...Here is my Doubt.
I know two approaches to display data in View of MVC(displaying data using Tables) but I am confused which one to use.
Requirement : View should display data from Database using Tables in View.
Approach 1: Fetch data from Database in Controller then fill Model and pass it to View.Loop through Model build Table and Data and Display data.
Approach 2: Define a Table in View.When user clicks button to display data in View, in js(Javascript File) make an ajax call to Controller to get data from Database and build the Table data(using html) in js(Javascript File) and append to the Table in the View.
Code for Approach 1 (this is just example to convey my doubt exactly):
public class TableInfo
{
public string FileName { get; set; }
public string Date { get; set; } //you might want to change this to DateTime
possibly?
public string Info { get; set; }
}
List<TableInfo> tables = dtTemplates.Rows.AsEnumerable()
.Select(t => new TableInfo
{
FileName = row["FileName"],
Date = row["Date"],
Time = row["Time"],
Info = row["Info"]
})
.ToList();
close_Connection();
return View(tables);
#model List<TableInfo>
if (Model.Count > 0)
{
<table>
<tr>
<td>File Name</td>
<td>Date</td>
<td>Time</td>
<td>Info</td>
</tr>
#foreach (TableInfo item in Model)
{
<tr>
<td>#item.FileName</td>
<td>#item.Date</td>
<td>#item.Time</td>
<td>#item.Info</td>
</tr>
}
</table>
}
Code for Approach 2(Below code is from .js(JavaScript) file):
controlSystem = {
GetContactRequests: function (view) {
$.ajax({
type: 'POST',
url: baseUrl + "ControlSystemAdmin/GetContactRequests",
data: JSON.stringify({ 'stateFilter': view }),
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function (data) {
if (data) {
$.each(data, function (index, res) {
var items = controlSystem.PopulateControlRequest(res.Data);
$("table.control-system tr:last").after(items);
$("div.high").tooltip({ content: tooltip });
});
}
},
error: function (x, status, error) {
Common.UI.HandleExceptions(x);
}
});
},
PopulateControlRequest: function (shiftLifts) {
var list = [];
if (shiftLifts) {
list.push('<tr id=' + shiftLifts.TaskID + '>');
var qTime = controlSystem.ProcessTime(shiftLifts.QTime);
list.push('<td><time>' + qTime.date + " " + qTime.time + '</time></td>');
list.push('<td><div><span>' + ((shiftLifts.AssignedOperator) ? shiftLifts.AssignedOperator : '-') + '</span></div></td>');
list.push('<td><div>');
list.push('</div></td>');
list.push('</tr>');
}
return list.length > 0 ? list.join('') : list;
},
Both approaches will do the Job but
1.Which is the best Approach to use? and why?
2.Which is recommended way to do?
3.In Jquery we can build the table fast so browser will be more responsive(which is Approach 2).If we build the table in View(Approach 1) browser may be less responsive so Is Approach 2 better than Approach 1?
4.What are the advantages of one over the other?
5.Please give me detailed explanation,recommend approach,pros and cons of each approach.
Thanks in advance for your help.

Showing Popup Windows with MVC, JavaScript

I have a simple create form in MVC 4 and would like two submit functions: (1) Create and (2) Create & Print. Create is a normal Create action and works perfectly. Create & Print should save the object and then launch a popup browser window with data from the newly saved object. The original window needs to refresh to a blank Create form ready for another record.
What is the best way to approach this?
Below is an example that works in practice however I have the ID hardcoded in. Ideally, this ID will dynamically inherit from the object that was just saved and link there. Is JavaScript the best idea here or should (can) I launch the popup from the Controller?
<input type="submit" value="Create" />
<input type="submit"
value="Create & Print"
onclick="window.open('Print/f1ad6330-2978-4ea9-9116-65f861412260'
, 'PRINT'
, 'height=200,width=200');" />
Best option is to create another action which returns string (last-insert-id), post data to it through ajax and get last-insert-id back in javascript then you can use it to open new window.
Now suppose this is new controller action:
[HttpPost]
public string CreateAndPrint(Object obj)
{
// Save data here / insert record here
if (Request.IsAjaxRequest())
{
// Now get last insert id
string lastInsertId = db.GetLastInsertId; // get last insert id from database
return lastInsertId;
}
}
Have a javascript function to post the data:
<script type="text/javascript">
function creteAndPrint() {
$.ajax(
{
url : "CreateAndPrint",
type: "POST",
data : $("#from1").serialize(),
success:function(data)
{
var lastInsId = data; // you will get last insert id here.
var secWin = window.open('Print/'+lastInsId
, 'PRINT'
, 'height=200,width=200');
secWin.focus();
}
});
}
</script>
And call this function only on create & print button:
<input type="submit" value="Create & Print" onclick="creteAndPrint();" />
Hope it works for you. Thank you.
Here I am editing my answer after your comment :)
Yes! you can call the same Create action for achieving the same which I explained above. But for that you have to make some changes in the your Create action:
public string Create(Object obj)
{
// Save data here / insert record here
if (Request.IsAjaxRequest())
{
// Now get last insert id
string lastInsertId = db.GetLastInsertId; // get last insert id from database
return PartialView("_Create", lastInsertId);
}
return View();
}
Notice that when you call this action through AJAX it will return a partial view, which return just LAST_INSERT_ID as string. You just have create one simple partial view _Create to print last-insert-id.
Partial view will have only two lines:
#model string
#Model
This will print the last-inst-id which we have passed from controller action.
I ended up bypassing the form's default submit call to the Create method and just created two new methods. It's not ideal, but it works.
SOLUTION
Form:
#using (Html.BeginForm("Dummy", "Count", FormMethod.Post, new { id = "form1" }))
{
// My Form
// Note the Dummy controller which will just fall through and do nothing
}
Form Submit:
<input type="submit" value="Create & Print" onclick="createAndPrint();" />
<input type="submit" value="Create" onclick="createWithoutPrinting();" />
JavaScript:
<script type="text/javascript">
function createAndPrint() {
$.ajax(
{
url: "CreateAndPrint",
type: "POST",
data: $("#form1").serialize(),
success: function (data) {
var lastInsId = data; // you will get last insert id here.
var secWin = window.open('Print/' + lastInsId
, 'PRINT'
, 'height=450,width=230');
secWin.focus();
}
});
}
</script>
<script type="text/javascript">
function createWithoutPrinting() {
$.ajax(
{
url: "Create",
type: "POST",
data: $("#form1").serialize()
});
}
</script>
Controller:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Dummy(Count count)
{
return RedirectToAction("Create");
}
[HttpPost]
public string CreateAndPrint(Count count)
{
SaveCount(count);
if (Request.IsAjaxRequest())
{
// Now get last insert id
string lastInsertId = count.Id.ToString();
return lastInsertId;
}
return "";
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Count count)
{
SaveCount(count);
if (Request.IsAjaxRequest())
{
// Now get last insert id
string lastInsertId = count.Id.ToString();
return PartialView("_Create", lastInsertId);
}
return RedirectToAction("Create");
}

ASP.NET MVC4 Refresh view after adding a comment

I am writing ASP.NET web application. I am using views generated by Visual Studio (Create/Delete/Details/Edit/Index). In my application I have Articles which can be commented by logged users. Everything works fine (adding comment and viewing it), but to view newly added comment I have to manually refresh page.
Structure of Article/Details View looks like:
#if (Request.IsAuthenticated)
{
using (Ajax.BeginForm("Create", "Comment", new { articleId = Model._article.ArticleId }, new AjaxOptions
{
HttpMethod = "post",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "myDisplayID"
}))
{
#Html.ValidationSummary(true)
<fieldset>
<h4>Dodaj komentarz</h4>
<p>
#Html.TextArea("komentarz", new { #class = "form-control" })
</p>
<p>
<input type="submit" value="Dodaj" class="btn btn-primary btn-large" />
</p>
</fieldset>
}
}
else
{
<p>
Zaloguj się aby dodać komentarz.
</p>
}
<hr />
<div id="myDisplayID">
#Html.Partial("_Comment", Model._comment)
</div>
EDIT
Comment/Create GET method
public ActionResult Create(int articleId)
{
var komentarz = new Comment();
komentarz.ArticleId = articleId;
return View(komentarz);
}
Comment/Create POST
[HttpPost]
public ActionResult Create(Comment comment, string komentarz, int articleId)
{
if (komentarz != String.Empty)
{
if (ModelState.IsValid)
{
comment.UserId = (int)WebSecurity.GetUserId(User.Identity.Name);
comment.Content = komentarz;
comment.ArticleId = articleId;
db.Comments.Add(comment);
db.SaveChanges();
}
}
ArticleViewModel widok = new ArticleViewModel();
widok._comment = (from b in db.Comments where b.ArticleId == articleId select b).ToList();
return PartialView("_Comment", widok._comment);
}
Article/Details GET method
public ActionResult Details(int id = 0)
{
ArticleViewModel widok = new ArticleViewModel();
widok._comment = (from b in db.Comments where b.ArticleId == id select b).ToList();
widok._article = (from t in db.Articles where t.ArticleId == id select t).FirstOrDefault();
if (Request.IsAjaxRequest())
{
return PartialView("_Comment", widok._comment);
}
if (widok == null)
{
return HttpNotFound();
}
return View(widok);
}
If you are to use Ajax.BeginFrom like you have shown. (but with some modifications)
using (Ajax.BeginForm(new AjaxOptions {
HttpMethod= "get",
InsertionMode=InsertionMode.Replace,
UpdateTargetId = "myDisplayID"
}))
, there are 3 things you need.
your comment section should be in a partial view and strongly type it (for your solution it might be a list of comments)
you should check if the request is ajax within the Action, using 'Request.IsAjaxRequest()'
if it's an ajax request, then you should return a partial view not the view.
.
public ActionResult Details()
{
//what ever the data retrieve code you have
return View(alldata);
}
[HttpPost]
public ActionResult Create(Comment comment, string komentarz)
{
if (komentarz != String.Empty)
{
if (ModelState.IsValid)
{
comment.UserId = (int)WebSecurity.GetUserId(User.Identity.Name);
comment.Content = komentarz;
db.Comments.Add(comment);
db.SaveChanges();
}
}
ArticleViewModel widok = new ArticleViewModel();
widok._comment = (from b in db.Comments where b.ArticleId == id select b).ToList();
return PartialView("_Comments",widok._comment);
}
submit comment - view
using (Ajax.BeginForm("Create", new AjaxOptions
{
HttpMethod = "POST",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "myDisplayID"
}))
{
#Html.ValidationSummary(true)
<fieldset>
<h4>Dodaj komentarz</h4>
<p>
#Html.TextArea("komentarz", new { #class = "form-control" })
</p>
<p>
<input type="submit" value="Dodaj" class="btn btn-primary btn-large" />
</p>
</fieldset>
}
in your view
instead of
<h4>Comments</h4>
<table>
// table with comments for this article
</table>
put
<div id="myDisplayID">
#Html.Partial("_Comments", Model.Comments)
</div>
_Comments partial view
#model IEnumerable<Comments>
<h4>Comments</h4>
<table>
// table with comments for this article
</table>
I think doing it this way will improve the user experience if you also happen to add new comments using ajax
You can refresh in javascript with window.location.href=window.location.href. Reload posts the data again.
Best option to do this send a post request with an ajax Call, like this:
var comment = $("#txtComment).val(); // change this id with your textarea id
var id = #Model._article.ArticleId;
$.ajax({
url: "/Comment/Create",
type: "POST",
dataType: "json",
data: JSON.stringify({ content: comment, articleId: id }),
contentType: "application/json; charset=utf-8",
success: function (data) {
// if you returning all your comment use this
$("table").html(data.allContent);
// or if you return just a row with this comment
$("table").prepend(data.Comment);
}
I assume your Action method like this:
[HttpPost]
public ActionResult Create(string content,int articleId)
{
...
return Json(new { allContent = comments }); // just for example
}
Problem solved with changing
return View()
in POST Create Action to
ControllerContext.HttpContext.Response.Redirect(ControllerContext.HttpContext.Re​quest.Url.ToString());
without any Partial Views, AJAX and Jquery
Try this :
return RedirectToAction("Index", "Comments");
or however your controller is called. But..
The best solution for me is to add comment asynchronously with jquery ajax. Comment/Create should return html as response (partialview), and you should replace old table with new one.
$.ajax({
url: "Comments/Create",
data: {comment : "bla bla", articleId : 1},
success: function (response) {
if (response == 'True') {
$('table').html(response);
}
}
});
Check some jquery ajax tutorials, it's very useful for such things. You can also use javascript when you are firing the action, which will prepare some html code with another row, and append it to table. Both of these ways are very nice, because you are not forced to reload the page.

Categories