Live search MVC - asp.net-mvc

I'm looking for live search for ASP.NET and entity framework. I'm a little bit green with it. I read that it needs to use ajax, but I never used it before and can't get good example. Here is a piece of code, cshtml (part of textbox)
<div class="form-horizontal">
<hr />
<h4>Search for a client: </h4>
<div class="input-group">
<span class="input-group-addon" id="Name">
<span class="glyphicon glyphicon-user" aria-hidden="true"></span>
</span>
#Html.TextBox("Name", "", new { #class = "form-control", placeholder = "Name" })
</div>
<div><h6></h6></div>
<div class="input-group">
<span class="input-group-addon" id="Surname">
<span class="glyphicon glyphicon-user" aria-hidden="true"></span>
</span>
#Html.TextBox("Surname", "", new { #class = "form-control", placeholder = "Surname" })
</div>
<div><h6></h6></div>
<button type="submit" class="btn btn-default" data-toggle="modal" data-target="#infoModal">Search</button>
</div>
this is a part of controller:
public ActionResult Index(string Name, string Surname)
{
var SearchList = from m in db.Klienci
select m;
if (!String.IsNullOrEmpty(Name))
{
SearchList = SearchList.Where(s => s.Name.Contains(Name));
}
if (!String.IsNullOrEmpty(Surname))
{
SearchList = SearchList.Where(s => s.Nazwisko.Contains(Surname));
}
return View(SearchList);
}
So it search for me clients by name and surname, but it refresh full page when it lost focus or after clicking the button. How to solve it, to get live search? after each keystroke search through database? I'm a little bit green, would you Help me?

You can listen to the keyup event on your input element, read the value and send it to the server using ajax. Return the results and in the ajax call's success callback, update the ui with the results.
$(function() {
$("#Name,#SurName").keyup(function(e) {
var n = $("#Name").val();
var sn = $("#SurName").val();
$.get("/Home/Index?Name="+n+"&SurName="+sn,function(r){
//update ui with results
$("#resultsTable").html(r);
});
});
});
The code basically listens to the key up event on the two input textboxes and read the values and send to the /Home/Index action method using jquery get method asynchronously.When the action method returns the response, we update the DOM.
Assuming resultsTable is the Id of the table where we list the results.
Also, since you are returning the partial view result ( without layout headers), you should use return PartialView() instead of return View()
if(Request.IsAjaxRequest())
return PartialView(SearchList);
return View(SearchList);

Here is nice example/tutorial how to use Ajax with ASP.NET MVC
http://www.itorian.com/2013/02/jquery-ajax-get-and-post-calls-to.html
EDITED: 2016-07-20
Example:
$(function () {
$("searchField").keyup(function () {
$.ajax({
type: "POST",
url: "/Controller/Action",
data: data,
datatype: "html",
success: function (data) {
$('#result').html(data);
}
});
});

You have to visit the server to get data from server and without ajax it is not possible. Now the question is how to make ajax call, you can use jQuery js lib to do but I would recommend you to try angular as data binding in angular will fulfill your needs.
Take a look at followings links
Angular Ajax Service -
jQuery Ajax

Related

Showing values from controller in view in asp.net mvc

I have a form, with different input fields, where user can enter their information.
Inside of the form, I have 2 buttons. When user clicks one button called 'Add address', I want to fill up a div with the address. And when user clicks other button called 'Preview', the form is validated and prepared for preview page.
Below is how 'My Adrress' button is defined in Index.cshtml
<button id ="address" class="btn btn-default" onclick="location.href='#Url.Action("populateAddress","Information")?addressID=2222'">
Add Address
</button>
So, when user clicks, Add Address, I want to fill up the address that I am retrieving from database in the div on Index.cshtml. Below is where I want to display the retrieved address:
<div class="row">
<div class="col-md-1"></div>
<div class="col-md-3">
#Html.Label("Address", htmlAttributes: new { #class = "control-label" })
</div>
<div class="col-md-6">
#ViewBag.FeedAddress //Here I want to display my retrieved address
</div>
</div>
So, on button click, I am calling my 'Information' controller method 'populateAddress' and passing the addressID parameter '2222' to it.
Below is how I am defining my 'populateAddress' method in my controller:
public void populateAddress(string addressID = null)
{
var addressDetail = db.Agency.Where(e => e.AddressCode == addressID).ToList();
string AddressRetrieved= "";
string StreetAddress, City, State, Zip = "";
foreach(var detail in addressDetail )
{
StreetAddress = detail.Address;
City = detail.City;
State = detail.State;
Zip = detail.Zip;
AddressRetrieved= StreetAddress + Environment.NewLine + City + ", " + State + " - " + Zip;
}
ViewBag.FeedAddress = AddressRetrieved
}
So, here, my ViewBag is getting filled with my retrieved address.
But, my issue is, after it gets filled with the address, instead of showing it on my Index.cshtml page in the div where I am retrieving back the value from ViewBag, my page is instead getting submitted and showing my validations.
I want that, once user fills up part of the form above 'Add Address' button and clicks 'Add Address' button, my address is retrieved from ViewBag, shown inside the div and user proceed filling up the rest of the form.
I am unable to get this kind of behavior.
Can anyone please help me to achieve that behavior or may be tell what I am missing. Thanks!
EDIT:
Please find Index.cshtml code. The page is long, so I am just adding required code:
// input fields for user
<div class="form-group">
<div class="col-md-2">
#Html.Label("Title", htmlAttributes: new { #class = "control-label" }) </div>
<div class="col-md-6">
#Html.EditorFor((e => e.Title), new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
//Add Address button
<button id ="address" class="btn btn-default" onclick="location.href='#Url.Action("populateAddress","Information")?addressID=2222'">
Add Address
</button>
//section to display retrieved address
<div class="row">
<div class="col-md-1"></div>
<div class="col-md-3">
#Html.Label("Address", htmlAttributes: new { #class = "control-label" })
</div>
<div class="col-md-6">
#ViewBag.FeedAddress //Here I want to display my retrieved address
</div>
</div>
// input fields for user
<div class="form-group">
<div class="col-md-2">
#Html.Label("Description", htmlAttributes: new { #class = "control-label" }) </div>
<div class="col-md-6">
#Html.EditorFor((e => e.Description), new { htmlAttributes = new { #class = "form-control" } })
</div>
</div>
//Preview Button
<div class="form-group">
<div class="col-md-offset-2 col-md-6">
<input type="submit" value="Preview" class="btn btn-default" />
</div>
</div>
In the controller (named mainController for this example):
public JsonResult GetAddress(int addressId)
{
// do whatever to get what you need
// the Address model will need to be JSON serialized
return JSON(Address);
}
In the javascript:
function GetAddress(addressId)
{
$.ajax({
type: "GET",
async: false,
url: "/main/GetAddress?addressId=" + addressId
contentType: "application/json",
context: this,
success: function (data) {
console.log(data);
// do stuff here
},
error: function (error) {
alert("error");
}
});
}
Important routing info:
The url is "/main/GetAddress/" which means it will route to the controller mainController (notice the 'main' part matches) and the function inside the controller is GetAddress. It is a "GET" request so using the url variable is fine.
This is the basic structure of how you do an ajax call with MVC.
Special note: In the controller method you return a JsonResult, NOT an ActionResult! Use ActionResult when you are trying to route through a View and have the Razor engine create the HTML markup. But if you are just returning JSON, use JsonResult.
EDIT:
In case you want to do a POST instead of a GET, here is what it would look like:
In the controller:
public JsonResult PostSomething(MyClass data)
{
// do something with the data -- class is MyClass
var result = ...... // whatever the result is, Null is ok I'd recommend some sort of "successful" reply
return JSON(result);
}
In the javascript:
function SubmitForm()
{
var formData;
// common to use jQuery to get data from form inputs
// use JSON.stringify to serialize the object
var data = JSON.stringify(formData);
// the ajax is almost the same, just add one data: field
$.ajax({
type: "POST",
url: "/main/PostSomething"
contentType: "application/json",
data: data, // the second 'data' is your local variable
success: function(data){
console.log(data);
},
error: function(error){
alert(error)
}
});
}
The 'asynch: false' and 'context: this' from the first example are actually not necessary in either (most of the time).
As with most of programming, there is more than one way to do it. These examples are just simple (but fairly standard) snippets to get you on the right track.

angularJS with MVC call - how to do something other than CRUD?

I've been following web tutorials to try to learn angularJS on a .NET MVC Application. All the tutorials seem to cover getting a list, getting an individual item etc.
What I want to do is allow the user to fill in an email address, I want to verify that email address against the database and return true or false if it existed. I'm then trying to put that value in the scope so I can do something in response to whether its true or false.
I'm using a single page app so this is the login html.
<form name="form" class="form-horizontal">
<div class="control-group" ng-class="{error: form.ValidEmailAddress.$invalid}">
<label class="control-label" for="ValidEmailAddress">Valid Email Address</label>
<div class="controls">
<input type="email" ng-model="item.ValidEmailAddress" id="ValidEmailAddress">
</div>
</div>
<div class="form-actions">
<button ng-click="login()" class="btn btn-primary">
Go!
</button>
<label ng-if="user.isAuthorised">Authorised</label>
<label ng-if="!user.isAuthorised">NotAuthorised</label>
</div>
</form>
In my app.js file I declare a loginCtrl controller when the url was /login so that's all fine. The logic that I'm calling on my button click is this:
var LoginCtrl = function ($scope, $location, $http, AuthorisedUser) {
$scope.login = function() {
var isValidUser = $http.get("/AuthorisedUser/IsValidUser/" + $scope.item.ValidEmailAddress);
$scope.user.isAuthorised = isValidUser;
} };
Which is then calling an MVC AuthorisedUserController class method:
public bool IsValidUser(string id)
{
var list = ((IObjectContextAdapter)db).ObjectContext.CreateObjectSet<ApprovedUser>();
var anyItems = list.Any(u => u.ValidEmailAddress == id);
return anyItems;
}
So it vaguely seemed to be working when I put in a value like "aaa" into the textbox. But as soon I try putting in an email address the value is undefined. Maybe I'm supposed to be doing a post but the only thing I can successfully hit my .NET controller with is by using get.
I'm sure I'm missing fundamental knowledge and potentially tackling this in the wrong way.
In case it helps I've created a module and defined factories like this:
var EventsCalendarApp = angular.module("EventsCalendarApp", ["ngRoute", "ngResource"]).
config(function ($routeProvider) {
$routeProvider.
when('/login', { controller: LoginCtrl, templateUrl: 'login.html', login: true }).
otherwise({ redirectTo: '/' });
});
EventsCalendarApp.factory('AuthorisedUser', function ($resource) {
return $resource('/api/AuthorisedUser/:id', { id: '#id' }, { isValidUser: { method: 'GET' } });
});
One of my questions is - should I be accessing the controller method using the $http object, or is there a way of using my factory declaration so that I can go something like:
AuthorisedUser.IsValidUser($scope.item.validEmailAddress)
I know in the tutorial I was following I could do stuff like:
CalendarEvent.save()
to be able to call a CalendarEventController post method.
What i think is, your get() function will return a promise. and you can't assign promise like this. so better try this approch once. I hope, it'd work. if not please let me know...
here I assume your first,second and third snippet of code works fine...
$http.get("/AuthorisedUser/IsValidUser/" + $scope.item.ValidEmailAddress).success(function (result, status) {
var isValidUser=result;
$scope.user.isAuthorised = isValidUser;
$scope.$apply();
}).error(function (result, status) {
//put some error msg
});

Parameter passed from view to controller not working

I have a very simple view and can't figure out why my textbox value is not passing to my controller. Will the actionlink work for providing the controller the parameter?
#{
ViewBag.Title = "Home Page";
}
#using (Html.BeginForm("LookupEmployee", "Home")) {
<div class="jumbotron">
<h2>Personnel System</h2><br />
<p>ID: <input type="text" id=employeeID name="employeeID" /></p>
#Html.ActionLink("Your Leave Balance", "LeaveBalance", "Home", null, new { #class = "btn btn-primary btn-large" })
</div>
}
<div class="row">
</div>
My HomeController takes the parameter and fills the dataset. I have hard coded a value and verified that this code works:
public class HomeController : Controller
{
public ActionResult Index()
{
return View();
}
public ActionResult LeaveBalance(string employeeID)
{
//ViewBag.Message = "Your application description page.";
if (!String.IsNullOrEmpty(employeeID))
{
DataSet gotData;
LeaveRequestWCF myDataModel = new LeaveRequestWCF();
gotData = myDataModel.GetTheData(Convert.ToInt32(employeeID));
myDataModel.theModelSet = gotData;
return View(myDataModel);
}
return View();
}
}
Any advice? As you can tell, I'm new with MVC and trying to drift away from web forms.
OPTION 1:
You are using Html.ActionLink to post a form, which cannot be done because Html.ActionLinks are rendered as Anchor tags. Anchor tags make GET Requests unless we explicitly handle their JQuery click event. Use a Submit button to post a form for an appropriate controller action. So instead of -
#Html.ActionLink("Your Leave Balance", "LeaveBalance", "Home", null,
new { #class = "btn btn-primary btn-large" })
go for -
<input type="submit" class="SomeClass" value="Submit" />
OPTION 2:
You can also use AJAX POST using JQuery click event for anchor tag to post the form and once you get the result, you can make a client side redirection.
<script src="~/Scripts/jquery-1.10.2.min.js"></script>
<script>
$(document).ready(function() {
$("#solTitle a").click(function() {
var data = {
"Id": $("#TextId").val()
};
$.ajax({
type: "POST",
url: "http://localhost:23133/api/values",
data: JSON.stringify(data),
contentType: "application/json; charset=utf-8",
dataType: "json",
processData: true,
success: function (data, status, jqXHR) {
console.log(data);
console.log(status);
console.log(jqXHR);
alert("success..." + data);
// handle redirection here
},
error: function (xhr) {
alert(xhr.responseText);
}
});
});
});
</script>
ActionLink creates a simple <a href /> on the page, that will send a get request to the server.
You need a submit button instead, so your form gets posted with its form inputs. Use:
<button type="submit">Your Leave Balance</button>

Submitting jquery dialog box using ajax call

I'm attempting to do a search using a jquery ui dialog box, and have the results also appear in a dialog box without any redirection on the actual page. I'm thinking an easy way of doing this is just to create my ui and have a < div id > surrounding the content, then replace the div with a view using an ajax call.
I've gotten the basics of this working, but... I have no clue how to pass the input field parameters to the incoming view/controller! It's currently not using submit() in any shape or form as this causes an unavoidable page redirect afaik.
My dialog contains standard text fields such as:
#Html.HiddenFor(model => model.Id)
<label>Customer Name</label>
#Html.TextBoxFor(m => m.Name, new { #class = "text ui-widget-content ui-corner-all" })
<label>EIN</label>
#Html.TextBoxFor(m => m.Ein, new { #class = "text ui-widget-content ui-corner-all" })
<label>State Tax ID Number</label>
#Html.TextBoxFor(m => m.StateTaxId, new { #class = "text ui-widget-content ui-corner-all" })
I have a placeholder for the dialog div
<div id="dialog-searchResults" title="Search Results" class="hide">
#using (Html.BeginForm("searchResults", "Customers", FormMethod.Post, new { #id = "searchResultForm" }))
{
<div id="SearchContents">a</div>
}
</div>
The ajax call
function InsertDialogDiv(ajaxUrl, divTable) {
var jsonData = {
"id": 0
};
$.ajax({
type: 'POST',
url: BASE_URL + ajaxUrl,
data: JSON.stringify(jsonData),
success: function (data) {
$(divTable).replaceWith(data);
},
error: function (xhr, ajaxOptions, thrownError) {
$(divTable).replaceWith(xhr.responseText);
}
});
}
Where ajaxUrl='Customer/SearchResults' as the path of the view.
Replacing the div in this way does trigger the Customer's controller to hit the SearchResults function, but as I'm not submitting, the model has all null values. How do I get my precious nuggets of information?
TY & Rat's off to ya!
PS: ASP.NET C# MVC4 Razor

JQuery AJAX: Update ViewModel

I have a strongly-typed MVC view that includes a form with an editor that is bound to a view model:
#model ViewModels.CommentView
#using (Ajax.BeginForm("UpdateComments", new AjaxOptions { HttpMethod="POST" }))
{
<fieldset>
<legend>Metadata</legend>
<div>
#Html.HiddenFor(model => model.Id)
<div class="editor-label">
#Html.LabelFor(model => model.Comment)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.Comment)
#Html.ValidationMessageFor(model => model.Comment)
</div>
</div>
<p class="action clear">
<input type="submit" value="Save" />
</p>
</fieldset>
}
When the user clicks on an element in a different part of the view, a JQuery AJAX call retrieves data from the server and updates the control:
<script type="text/javascript">
$(".load-comments").focus(function () {
var Id = $("#Id").val();
var url = "#Url.Action("GetComment")/" + Id;
$.ajax({ url: url, success: DataRetrieved, type: 'POST', dataType: 'json' });
function DataRetrieved(data) {
if (data) {
$("#Comment").val(data.Comment);
}
};
});
</script>
This functionality works as expected: the control content is visually updated. However, the value of the underlying html element is not updated, and when I post the form back to the server, the view model is empty.
How do I set the form controls' value in the JQuery function so that they post back to the server?
How did you set the HTML? ASP.NET default ModelBinder looks for id that are equals object properties to build the model back in the server. Looks like your form HTML doesnot reflect the object. Inspect each element created by Html helper and create each control as the same after comment data comes from the request. Hopes its help you! You can create a custom ModelBinder to Bind your model back in the server, take a look here: Model Biding

Resources