Knockoutjs couldn't go to RedirectToAction view - asp.net-mvc

I have a simple login controller:
public ActionResult Login()
{
return View();
}
[HttpPost]
public ActionResult Login(string userName, string passWord)
{
if (ModelState.IsValid)
{
var employee =
db.Employees.FirstOrDefault(x => x.EmployeeNo == userName && x.Password == passWord && x.StatId == 1);
if (employee != null)
{
return RedirectToAction("Index");
}
}
return View();
}
public ActionResult Index()
{
return View(db.Employees.ToList());
}
This is my view which is bound to a knockoutjs file:
#model SimpleLogin.Models.Employee
#{
ViewBag.Title = "Login";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>Login</h2>
<span>User</span> <span data-bind="text: userName"></span> <br/>
<span>Password</span> <span data-bind="text: passWord"></span>
<div>
<table>
<tr>
<td>
<input type="text" name="txtUserName" placeholder="User Name" data-bind="value: userName" /></td>
</tr>
<tr>
<td>
<input type="password" name="txtPassword" placeholder="Password" data-bind="value: passWord"/></td>
</tr>
</table>
<button data-bind="click: logUser">Login</button>
</div>
#section Scripts
{
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/knockout")
#Scripts.Render("~/Knocks/LoginVm.js")
}
this is my knockout LoginVm.js
$(function() {
ko.applyBindings(LoginVm);
});
var LoginVm = {
userName: ko.observable(''),
passWord: ko.observable(''),
logUser: function() {
var self = this;
$.ajax({
url: '/Company/Login',
type: 'post',
dataType: 'json',
data: ko.toJSON(self),
contentType: 'application/json',
success: function(data) {
//window.location.href = '/Company/Index'; //I tried putting an alert here but doesn't work. why?
}
});
}
};
When I ran the app, I put a break point in the "if (ModelState.IsValid)" of the controller. It worked fine. It even executed the "return RedirectToAction("Index")" but the problem is, the page stays in the Login View and never loaded the Index view. Why? What did I do wrong?
I also put this:
bundles.Add(new ScriptBundle("~/bundles/knockout").Include(
"~/Scripts/knockout-2.1.0.js",
"~/Scripts/knockout-2.1.0.debug.js"));
in the BundleConfig.cs
I'm not used to js, it really confuses me. I know there are more than 2 errors in what I did.
this is my class
public class Employee{
public int EmployeeId {get; set;}
public string UserName {get; set}
public string Password {get; set;}
}

You can't return View to an ajax request. You should change it to:
public ActionResult Login(string userName, string passWord)
{
if (ModelState.IsValid)
{
var employee =
db.Employees.FirstOrDefault(x => x.EmployeeNo == userName && x.Password == passWord && x.StatId == 1);
if (employee != null)
{
return Json(true);
}
}
return Json(false);
}
Then in your js:
$.ajax({
url: '/Company/Login',
type: 'post',
dataType: 'json',
data: ko.toJSON(self),
contentType: 'application/json',
success: function(data) {
if(data) {
window.location.href = '#Url.Action("Index", "Company")';
}
}
});
But there is no need to use knockout here. You can simply do a regular form Submit and Redirect by return RedirectToAction("Index", "Company") in the controller.

Related

Couldn't Load the data on Dropdown menu using Asp.net Mvc Json

i am creating a simple inventory control system using Asp.net Mvc Json.when i am tring to load the category data.category Data is not loaded to the Dropdown menu. code which i tried so far i attached below along with the screen shot image.
enter image description here
Form design
<div class="card-action">
<div class="form-group">
<label class="form-label">Category</label>
<select class="form-control" id="category" name="category"
placeholder="Category" required>
<option value="">Please Select</option>
</select>
</div>
</div>
Jquery
getCategory();
function getCategory() {
$.ajax({
type: 'GET',
url: '/product/Getcategory',
dataType: 'JSON',
success: function (data) {
console.log(data);
for (var i = 0; i < data.length; i++) {
$('#category').append($("<option/>", {
value: data[i].id,
text: data[i].cat_name,
}));
}
},
error: function (xhr, status, error) {
alert(xhr.responseText);
}
});
}
Controller
public class ProductController : Controller
{
aspoEntities db = new aspoEntities();
// GET: /Product/
public ActionResult Index()
{
return View();
}
public ActionResult Getcategory()
{
using (aspoEntities db = new aspoEntities())
{
var category = db.categories.ToList();
return Json(new { data = category }, JsonRequestBehavior.AllowGet);
}
}
}
Change your controller to
public class ProductController : Controller
{
// GET: /Product/
public ActionResult Index()
{
return View();
}
public ActionResult Getcategory()
{
aspoEntities db = new aspoEntities()
var category = db.categories.ToList();
return Json(category, JsonRequestBehavior.AllowGet);
}
}
It seems your db context has been disposed before the json is being serialized.
Try to inject the db context to your controller and get rid of the using statement.
Or move your return statement outside the using block.

How to Get HTML drop down list value from View to controller in MVC?

Small help required
1) I have created an html Dropdown in MVC view like this
<select name="Associateddl" id="Associateddl"></select>
2)I am appending the options to the dropdownlist using Jquery Ajax like
$.ajax({
type: 'POST',
contentType: "application/json; charset=utf-8",
url: 'customservice.asmx/getallmember',
dataType: 'JSON',
success: function (response) {
var getData = JSON.parse(response.d);
console.log(getData.length);
if (getData.length > 0) {
$("#msg").hide();
$.each(getData, function (i, item) {
var optiontext = "";
optiontext = "<option value='" + item.Aid + "'>" + item.AMail + "</option>";
$("#Associateddl").append(optiontext);
});
}
else {
$("#msg").append("<p style='color:red'><b>Currently there are no members ,Please Add !!</b></p>");
}
},
error: function (err) {
//alert(err);
}
});
3)Now i want to retrive the dropdown selected value to controller from View.
My Model:
public class Event
{
[DisplayName("Event Name")]
[Required(ErrorMessage ="Event Name is Mandatory...")]
public string Eventname { get; set; }
[DisplayName("Event Year")]
[Required(ErrorMessage ="Enter the Year...")]
public int Year { get; set; }
[DisplayName("Associate ID")]
[Required(ErrorMessage ="Associate ID is required...")]
public string Associateddl { get; set; }
}
My Controller:
[HttpPost]
public ActionResult Index(Event eve)
{
string ename = eve.Eventname;
int eyr = eve.Year;
string eassociate = eve.Associateddl; //Here i want to retrive the dropdownselected Value
return View();
}
Please help me to get the Html dropdown seleted value to Controller from View.
Here is an example on how you can see the value of the ddl in the controller. I will get you an ASP.NET Fiddle you can click on that will host the solution.
web service
[System.Web.Script.Services.ScriptService]
public class Service1 : System.Web.Services.WebService
{
[WebMethod]
public string getallmember()
{
var drop2 = new List<SelectListItem>();
SelectListItem sli1 = new SelectListItem { Text = "MoreOptions1", Value = "1" };
SelectListItem sli2 = new SelectListItem { Text = "MoreOptions2", Value = "2" };
drop2.Add(sli1);
drop2.Add(sli2);
//GET NewtonSoft
var json = JsonConvert.SerializeObject(drop2);
return json;
}
Controller
public class HomeController : Controller
{
[HttpPost]
public ActionResult Tut118(string Associateddl)
{
//put breakpoint here
return View();
}
public ActionResult Tut118()
{
return View();
}
View
#{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Tut118</title>
<script src="~/Scripts/jquery-1.12.4.min.js"></script>
<script type="text/javascript">
$(function () {
$("#theButton").click(function () {
$.ajax({
type: "Post",
url: "customservice.asmx/getallmember",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (response) {
$("#Associateddl").empty();
var theData = JSON.parse(response.d);
$.each(theData, function (i, anObj) {
$("#Associateddl").append($('<option>').text(anObj.Text).attr('value', anObj.Value));
});
}
,
error: function (request, status, error) {
alert(error);
}
});
})
})
</script>
</head>
<body>
<div>
#using (Html.BeginForm())
{
<input type="button" id="theButton" value="click to get ddl" />
<select name="Associateddl" id="Associateddl"></select>
<input type="submit" value="click after selecting ddl" />
}
</div>
</body>
</html>

Unable to pass Id from listbox items in mvc 5

I've coded for multiple values that resides inside listbox on button click. I have used autocomplete textbox to get the required value along with its id. Then i managed to add those values inside the listbox. Now what i want is to pass id's against those values in listbox instead of names. Below is my code that I'm running.
StudentBatch.cs
public string studentId { get; set; }
public string StudentName { get; set; }
public List<string> selectedids { get; set; }
public List<string> names { get; set; }
public List<string> SelectedNames { get; set; }
Create.cshtml
#using (Html.BeginForm("Create", "Student", FormMethod.Post))
{
<div class="form-group">
<div class="col-md-12">
#Html.EditorFor(model => model.StudentName, new { id = "StudentName" })
<input type="button" value="Add Text" id="addtypevalue" />
<div id="typevaluelist"></div>
</div>
</div>
<div id="new" style="display:none;">
<div class="typevalue">
<input type="text" name="typevalue" />
<button type="button" class="delete">Delete</button>
</div>
</div>
<div id="hiddensq">
</div>
for (int i = 0; i < Model.names.Count; i++)
{
#Html.Hidden("UserValues", Model.names[i]);
}
#Html.ListBoxFor(m => m.SelectedNames, new SelectList(Model.names))
<div id="partialDiv">
#{
Html.RenderPartial("GetListBox", Model);
}
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
}
<script type="text/javascript">
$(document).ready(function () {
$("#StudentName").autocomplete({
//autocomplete: {
// delay: 0,
// minLength: 1,
source: function (request, response)
{
$.ajax({
url: "/Student/CreateStudent",
type: "POST",
dataType: "json",
data: { Prefix: request.term },
success: function(data) {
try {
response($.map(data,
function (item)
{
return { label: item.FirstName, id: item.Id };
}));
} catch (err) {
}
}
});
},
messages:
{
noResults: "jhh", results: "jhjh"
}
});
});
</script>
<script>
$(function () {
$('#addtypevalue').click(function (e) {
var name = $("#StudentName").val();
alert(name);
$('#SelectedNames').
append($("<option></option>").
attr("value", name).
text(name));
$('#hiddensq').append("<input name='UserValues' type='hidden' value='"+ name +"'/>");
});
});
</script>
StudentController.cs
public ActionResult Create()
{
Context.Student student = new Context.Student();
Models.StudentBatch studBatch = new Models.StudentBatch();
studBatch.names = new List<string>();
studBatch.names.Add("Add Student Names");
studBatch.BatchNumberList = student.getBatchList();
return View(studBatch);
}
[HttpPost]
public JsonResult CreateStudent(string Prefix)
{
CreateUser user = new CreateUser();
string stdid = "f14570f0-e7a1-4c22-bf69-60ffbeb7e432";
var StudentList1 = user.GetAllUsers().ToList().Where(u => u.FirstName.Contains(Prefix) && u.usertypeid == stdid);
var StudentList = user.GetAllUsers().ToList();
var searchlist = (from student in StudentList1
where student.FirstName.Contains(Prefix)
select student).ToList();
return Json(StudentList1, JsonRequestBehavior.AllowGet);
}
// POST: Student/Create
[HttpPost]
public ActionResult Create(Models.StudentBatch student, IEnumerable<string> UserValues)
{
try
{
// TODO: Add insert logic here
return RedirectToAction("Index");
}
catch
{
return View();
}
}
If I understood correctly the problem here is passing multiple IDs from a listbox to a POST? One possible way is to assign viewbag like thus in your controller:
ViewBag.StudentList = new SelectList(db.StudentBatch, "studentId", "StudentName");
I use entities to access my models, I think you have a little bit different approach but the point is to give a collection to the Selectlist. Then you specify the data value field and the data text field.
Then in your view, note that it's not ListBoxFor, as it's dynamic:
#Html.ListBox("StudentList", null)
Then finally to be able to receive the values in the POST add the following parameter to your action and you should be able to iterate through it:
string[] StudentList
Finally managed to get the related from the listbox. I followed the instruction mentioned in a particular question. That's how i did.
$("#StudentName").autocomplete({
source: function (request, response) {
$.ajax({
cache: false,
// async: false, NEVER do this
url: '#Url.Action("CreateStudent", "Student")', // don't hard code your url's
data: { Prefix: request.term }, // change
dataType: "json",
type: "POST",
// contentType: "application/json; charset=utf-8", delete
success: function (data) {
response($.map(data, function (item) {
return {
label: item.label,
id: item.id
}
}));
}
})
},select: function(event, ui) {
$.ajax({
cache: false,
type: "POST",
url: '#Url.Action("GetDetails", "Student")',
data: { id: ui.item.id },
success: function (data) {
var name = $("#StudentName").val();
$('#SelectedNames').
append($("<option></option>").
attr("value", ui.item.id).
text(name));
$('#hiddensq').append("<input name='UserValues' type='hidden' value='" + ui.item.id + "'/>");
}
});
}
});
</script>
and in the controller class
[HttpPost]
public JsonResult GetDetails(string id)
{
ViewBag.Value = id;
return Json(ViewBag.Value, JsonRequestBehavior.AllowGet);
}

How can i prevent User click the button to submit form if specify field is not valid?

I have a jquery function to check valid data on UsernameTextbox in my View. I want to prevent User click on the Register button until this field valid.
Disable button is it the best method? I just want when the value is not valid, user click on button just focus to the UsernameTextbox filed?
Update Code:
Here is my Model :
[Required]
[Remote("CheckUsername", "Account", ErrorMessage = "Username already exits.")]
public string Username { get; set; }
and Controller with GET method:
[HttpGet]
public JsonResult CheckUsername(string userName)
{
var user = IUserRepo.GetUserByUrName(userName);
bool isValid = true;
if (user!=null)
{
isValid = false;
}
return Json(isValid, JsonRequestBehavior.AllowGet);
}
and in my View :
#using (Ajax.BeginForm("Register","Account",new {area = "Area"},null))
{
#Html.ValidationSummary(true)
<table>
<tbody>
<tr>
<td class="info_label">Tên đăng nhập</td>
<td>#Html.EditorFor(m => m.User.Username)
</td>
<td class="check_user">#Html.ValidationMessageFor(m => m.User.Username)</td>
</tr>
<tr> ........
Why no error message appear? And i want to valid intermediately when user fill data or leave textbox like this site http://yame.vn/TaiKhoan/DangKy.
Note : The below mentioned suggestion is only for MVC3 and above
Luffy, you can remove the Ajax Call to check UserName existence
How can we do that ?
Model
public class UserModel
{
// Remote validation is new in MVC3. Although this will also generate AJAX
// call but, you don't need to explicitly type the code for Ajax call to
// check the User Existence. Remote Validation will take care of it.
[Required]
[Remote("CheckUsername", "Account", ErrorMessage = "User Already Exist")]
public string UserName { get; set; }
}
Controller
[HttpGet]
public JsonResult CheckUsername(string MyProp)
{
// Your Validation to check user goes here
bool isValid = true;
return Json(isValid, JsonRequestBehavior.AllowGet);
//Note - This will be called whenever you post the form.
//This function will execute on priority, after then the Index
//Post Action Method.
}
[HttpGet]
public ActionResult Index()
{
return View();
}
[HttpPost]
public ActionResult Index(UserModel model)
{
// This action method will execute if the UserName does not exists
// in the DataBase
return View(model);
}
View
#using (Ajax.BeginForm("Action", "Controller", new { area = "Area" }, null))
{
#Html.TextBoxFor(i => i.UserName);
<input type="submit" name="Submit" value="Submit" />
// Whenever you submit the form, the control will go directly to
// CheckUsername function. In case the UserName doesn't exists only
// then the Post action method will be executed.
}
Scripts
<script src="jquery-1.7.1.min.js" type="text/javascript"></script>
<script src="jquery.validate.min.js" type="text/javascript"></script>
<script src="jquery.validate.unobtrusive.min.js" type="text/javascript"></script>
Try this
function CheckUserNameExits() {
$("#User_Username").on("blur", function () {
$("#User_Username").addClass("thinking");
var username = $("#User_Username").val();
if (username == "") {
$(".check_user").html("Ba?n chua nhâ?p tên dang nhâ?p.");
$("#User_Username").removeClass("thinking");
$("#User_Username").removeClass("approved");
$("#User_Username").addClass("denied");
$("#User_Username").focus();
$("#User_Username").select();
return false;
}
$.ajax({
url: "/Account/CheckUsername",
data: { userName: username },
dataType: "json",
type: "POST",
error: function () {
return false;
},
success: function (data) {
if (data) {
$("#User_Username").removeClass("thinking");
$("#User_Username").removeClass("denied");
$("#User_Username").addClass("approved");
$(".check_user").html("");
//$("#createuser").prop("disabled", false);
return true;
}
else {
$("#User_Username").removeClass("thinking");
$("#User_Username").removeClass("approved");
$("#User_Username").addClass("denied");
$(".check_user").html("Tên dang nhâ?p da~ duo?c du`ng, vui lo`ng cho?n tên kha´c.");
$("#User_Username").focus();
$("#User_Username").select();
//$("#createuser").prop("disabled", true);
return false;
}
}
});
});
}
function CheckValidate()
{
if (!CheckUserNameExits()){
return false;
}
return true;
}
<input id="createuser" type="submit" value="Ðang ky´ ta`i khoa?n" onclick="return CheckValidate();" />
May be it would be better to use jQuert enable/disable button method.
Fistly button is disable:
$(document).ready(function(){
$( ".register" ).button("disabled");
});
Than, if your function return true, enable button
function CheckUserNameExits() {
//*If your function is success
$( ".register" ).button( "enable" );
})

How do I Show/Hide partial view based on result I get from service call using jQuery AJAX in MVC4?

I want to have a page where I can enter loan number then I will call a WCF get service to see if a loan number is valid. If loan# is valid, I want to show loan related data (partial view) on the same page.
Here is my main View:
#model LoanStatus.Web.Models.Validate
#{
ViewBag.Title = "Validate";
}
#section Scripts {
#Scripts.Render("~/bundles/jquery")
#Scripts.Render("~/bundles/jqueryval")
#Scripts.Render("~/bundles/jqueryui")
}
<script type="text/javascript">
jQuery(function ($) {
$("#txtssn").mask("9999");
});
function validateRequest() {
var $form = $('form');
if ($form.valid()) {
$.support.cors = true;
var lnkey = $('#txtlnkey').val();
$.ajax({
type: "GET",
url: "http://localhost:54662/Service1/ValidateRequest/" + encodeURIComponent(lnkey),
contentType: "application/json; charset=utf-8",
dataType: "json", //jsonp?
success: function (response) {
$('#Result').html('Loading....');
if (response.ValidateRequestResult.toString().toUpperCase() == 'TRUE') {
alert('validated');
} else {
alert('cannot validated' + response.ValidateRequestResult.toString().toUpperCase());
//$("#Result").hide();
}
$('#Result').html(response.ValidateRequestResult);
//alert(response.ValidateRequestResult.toString());
},
error: function (errormsg) {
alert("ERROR! \n" + JSON.stringify(errormsg));
}
});
//
} else {
$('#Result').html('Input Validation failed');
}
}
</script>
#using (Html.BeginForm()) {
<fieldset>
<legend>Log in Form</legend>
<ol>
<li>
#Html.LabelFor(m => m.LoanKey, new{})
#Html.TextBoxFor(m => m.LoanKey, new { #id = "txtlnkey" })
#Html.ValidationMessageFor(m => m.LoanKey)
</li>
</ol>
<input type="button" value="Get Status" onclick="javascript:validateRequest();" />
</fieldset>
}
<div id="Result">
#if (ViewBag.Validated)
{
#Html.Action("GetLoanInfo");
}
</div>
Below is my controller:
namespace LoanStatus.Web.Controllers
{
public class ValidateController : Controller
{
//
// GET: /Validate/
[HttpGet]
public ActionResult Index()
{
var model = new Validate() {LoanKey = "", Last4Ssn = ""};
ViewBag.Validated = false;
return View(model);
}
[HttpPost]
public ActionResult Index(Validate model, bool validated)
{
// do login stuff
ViewBag.Loankey = model.LoanKey;
ViewBag.Validated = true;
return View(model);
}
public ActionResult GetLoanInfo() // SHOWs Search REsult
{
return PartialView("_LoanInfoPartial", ViewBag.Loankey);
}
}
}
I want to have '#Html.Action("GetLoanInfo");' rendered only if jQuery AJAX service call returns TRUE (Where I have alert('validated'). I am not sure how to do that. My issue can be resolved if I can set value to ViewBag.Validated in success:function(). But based on what I read, it cannot be set in jQuery.
I tried $("#Result").hide(); and $("#Result").show(); but it did not work. Please help.
Can you try with this:
In your function validateRequest() ajax success, at the place where you are showing alert('validated'); use this and try:
$('#Result').load('#Url.Action("GetLoanInfo", "Validate")');
In your view make Result div empty
<div id="Result"> </div>
Tell me if it helps.

Resources