ASP.NET MVC Data Feedback through User Controls - c#

In our new product we have a few data entry fields that require you to search for the correct value to place in this field.
When you enter this data entry field I would like to provide a search option via something on the view (perhaps an Ajax implementation) and have it allow searching of the database for the value, but when the result returns I want to keep the existing values in place for other fields not affected by the search.
But I have no idea how to do this with MVC. Does anyone have any suggestions on how this should be done?

Write your data entry page in the
usual way for an ASP.NET MVC view.
Get it working without the Ajax
(e.g., submit works correctly when
you just type in the values, without
auto complete).
Write the prototype for a JavaScript method you'll called when the user performs a certain action (e.g. presses a key inside of a certain control). But this inside a script tag in your aspx page. Unfortunately, stack overflow seems to "sanitize" script tags in my example, so I can't demonstrate that part. But you're JavaScript prototype will look something like this:
function startAutoComplete() {
}
Now hook up the event handlers on the user interface control. You need to call the function you've just prototyped an appropriate event handlers for your application. From your description, it sounds like you might want to use onkeydown, but there are lots of events to choose from. You probably need to handle more than one event, as appropriate for your application.
So far, everything that we've done has been standard aspx and JavaScript. In this step, we'll do the only part of the whole process which is really different for ASP.NET MVC. You need to add an action to your controller which will be called (indirectly) by the JavaScript prototype you've just written. The action should accept appropriate input (e.g., a string representing the text from control, or something like that, as appropriate for your application) and return its results in JSON format. I'm going to show a really simple example here; feel free to substitute more complex code in your real application.
public ActionResult GetSuggestions(string searchText)
{
return Json(new {SearchText = searchText});
}
This example just returns a JavaScript object containing one property, which contains the value passed to the function. Like you said, you can write something more useful for your application.
Now you need to call this function in JavaScript. The URI will look something like:
http://localhost/mycontroller/GetSuggestions?searchText=Foo
It is possible to make Ajax calls without a JavaScript library, but much easier if you use jQuery or some other library which handles cross-browser compatibility issues for you. Since I happen to like jQuery, I'll demonstrate that. Let's update the startAutoComplete method we prototyped earlier:
function startAutoComplete() {
var searchText = $("#myeditorid").text();
$.getJSON("/mycontroller/GetSuggestions?searchText=" + searchText,
null,
autoCompleteResponse);
}
The first line uses jQuery to get the text in the control with the ID myeditorid. We'll pass this to the ASP.NET MVC action as the searchText argument, by appending it as a query string parameter.
The next line, which starts with $.getJSON calls a jQuery function which makes an Ajax call to the URI you specify. We pass an argument, autoCompleteResponse, which is the name of a JavaScript method to be called if the response from the Ajax call is successful. Now we have to write autoCompleteResponse.
function autoCompleteResponse(data) {
if (data.SearchText)
{
$("#myeditorid").text(data.SearchText);
}
}
This says, "If the data returned has a SearchText property, set the text of the control to that value." Again, do whatever is appropriate for your application with the data returned.

Related

MVC - Retain model result for use in ajax method without passing in via JSON?

Long time lurker first time posting, so hey!
TL:DR - how would I keep a value from the original page-loading-controller to the ajax method without passing it in as a json object as part of the ajax request? And I can't use Session[]!
Backstory - I'm working on a filter-search functionality which brings back a big list of objects on the initial page load, generated from a database call and populates Model.FullResults.
In order to filter the results, rather than keep doing more database calls each time a filter is clicked, I'm simply filtering the results via linq in an AJAX method, like so:
var fullResults = #Html.Raw(Json.Encode(Model.FullResults));
var obj = {
//filter tickboxes statuses etc are here
fullResults: fullResults
}
var jqxhr = $.ajax({
//urls etc removed for clarity
data: JSON.stringify(obj),
success: function (response) {
//stuff
}
}
});
Which is all working perfectly fine for small values of Model.FullResults. However, if Model.FullResults is pretty large (i.e. on my main search page), this is a large amount of data to pass across via ajax each time, and the only reason I'm even passing it across this way is just for the plain and simple fact of I don't know how else I can "keep" this data from the original controller action and still have it for use the ajax method.
Storing Model.FullResults in Session was a brief thought, but there's a high probability people will open multiple tabs that hit the same controller, thus making session outdated. Something like Viewdata would be ideal but I can't access that in the ajax method of course.
So how would I keep this value for use in the ajax method? Do I have to resort to doing another database call OR passing it into the ajax method? There must be a way of retaining it somehow?
Thanks in advance you helpful bunch! :)
You can go for memoryCache to save large amount of data. Similer problem was with me where I have to read data from csv file and pass through Web API. Every-time, reading data from text was not a good idea, So I saved data in memory cache and fetching the records from memoryCache to avoid reading from stream. A simple demo is shown on my github account.you can co relate it.
https://github.com/abhee235/SimpleRestfulAPI/tree/master/DataProvider
Note : The project is not optimized for performance point of view. It is just a demo.

Passing a javascript function to ReactJS.NET Server side

I have a pretty basic, but probably complicated question.
I am using ReactJS.net to render react components server side. I have a typeahead component which I use multiple times throughout my site. One of the properties it expects is a javascript filter function.
I don't want to have to create a seperate component for each instance of the typeahead, but would like to pass in a javascript function as a property so that I can reuse the component throughout the site.
For example, to render a component on the server I would do the following. The second parameter is the properties argment
#Html.React("Components.WorkSiteTypeahead", new { filterFn = model.SomeFunction })
Now as ReactJS.net expects native c# objects (string, array, list, etc), I don't see any straight forward way to pass in a Javascript function. Any ideas on how would I go about telling my MVC5 view to render my function not as a string? My first instinct is that there might be some sort of Javascript Raw type I am not aware of, but haven't been able to find it.
As I suspected, at least one way to go about this is to use Newtonsoft's JRAW Type.
#Html.React("Components.WorkSiteTypeahead", new { filterFn = JRaw("function(){//do stuff } "})

Populating Html Helpers route arguments

Is there a way to populate anonymous type properties (route arguments) in Html Helpers like Html.ActionLink or Url.Action with data.
Example.
Create link like this:
Anchor Text
... and populate propertyValue with data extracted from current state of DOM (using Javascript).
I know there's a lot of ways that I can get that logic to work (ex. using form data and passing it to controller) but I'm just curious if a provided scenario is possible.
populate propertyValue with data extracted from current state of DOM (using Javascript)
No.
C# runs on the server, JavaScript runs on the client. You can't use JavaScript on the client to modify code which already ran on the server. You can use JavaScript to modify the markup which gets emitted to the client, and the first step in that would be to examine what that markup actually is. (In this case it looks like you'd be modifying a URL, which may involve some interesting string parsing in the JavaScript code.)
But no, JavaScript can't affect your calls to HTML Helpers.

Converting JavaScript variable to C#

I have a variable in JavaScript and I want to use it as an index reference in my C# code. How do I convert the JavaScript variable into something C# can use? So far this is what I have..
#{
var selectedStockLocation = #Html.Raw(Json.Decode(document.getElementById("cbLocation " + id).value));
var currentLocation = Model.StockLocationBinData[selectedStockLocation];
}
You will have to post the value back with either a full POST or an AJAX call.
You are mixing server and client code there.
You need to use (one of many) methods to post client data back to the controller.
Use jquery to write to a hidden variable in the form is one route, see this answer:
Passing a jQuery value to MVC 3 Razor view html helper
JavaScript runs well after the server-side code has rendered and completed; you cannot use it while rendering the view.. You can, however, store the value in a hidden field, put this hidden field in a form, and process it during a post operation. Or, send it to the server via an AJAX callback.

how does mvc work when index is returned via ajax?

does it reload the entire page or does it have the intelligence to only send the necessary js to update the needed parts of the page that have changed?
if it does the latter that would be a god send, however im probably being dreamful. it probably returns the entire view without any regard, right?
edit: answer seems to be no, everything is returned.
edit added:
do you think it would be difficult to write a framework where mvc compares last html it output to the current html we want to output, and instead of sending the entire html, figure out what has changed and generate js code that will do the updating as compared to previous html? (presuming nothing was manually changed on the client using js)... maybe an idea for a codeplex project? or maybe something like this exists?
Well, it entirely depends on how you do it.
You can return anything you want, when using ajax its common to return your data in JSON. Example:
public ActionResult GetCustomers()
{
if(Request.IsAjaxRequest)
return Json(db.GetCustomers());
return View(db.GetCustomers());
}
This will return all customers Json encoded if the request was made using Ajax.
You can stil return anything you want, if you want to return a view, it's just to
return View(model);
If you dont want to return the layout (master page), just return the MasterPageFile directive from your view.
And no, it does not reload the entire page, that's why it's called Ajax.
Frankly, what happens on the client side is of no concern to MVC. :-) It does not know whether the call was made by the browser engine or the ECMA script.
And since you are asking about Ajax call, the responsibility with dealing with the result falls onto your script (or whatever JS framework you're using).

Categories

Resources