How to pass a list from Controller to View? - c#

This is what I've tried:
In Controller:
public ActionResult Detail()
{
List<string> list = new List<String>();
return View(list);
}
In View of Detail:
#model dynamic
<!-- some HTML -->
<script>
#Model.add(document.getElementById("input_box").value);
</script>
Problem is, intelli-sense is not detecting that the passed in object is a List so #Model.add doesn't work.
My goal is to pass a list into the view so I can gather data from user inputs, and then use that list of data in my controller. Any ideas?

The current problem can be solved by using a statically typed model:
#model List<string>
<!-- some HTML -->
<script>
#Model.Add(document.getElementById("input_box").value);
</script>
However, you'll quickly hit another wall when the compiler complains that it doesn't know what document is. That's because the Razor view is rendered on the server side, but document is an object provided by the browser on the client side. You simply can't dynamically add elements to this server-side list from the client. You'll need to encode your list somehow for the client to be able to read, say in a JavaScript array. Then dynamically modify the list on the client side, perhaps using the JavaScript .push method. And then post this back to the controller in a separate action.

It's not going to be that simple.
Firstly, the Razor statement you used
#Model.add(document.getElementById("input_box").value);
is not a valid C# statement. It will cause an exception when you try to open the page, because the Model type you're using (List<T>) does not have a method called add (though it has Add), and further because that javascript is not valid Razor code either :)
Secondly, you seem to be confused about how the server-client interaction works.
You need to carefully think about how what you want to do can be realized--
For you to be able to get information from the client (the user's browser), you first need to render the page, send it to the client, let the user (or whatever) enter the information, and then get them to send it back to a Controller action. At the moment your page is not even rendering, so you couldn't hope to get data from anyone.
This can still be solved in numerous ways, one of which is to use Html.BeginForm(...) to create a simple form and have an input element and a submit button somewhere in there.
If you can get the user to submit the data back to you, you can then do whatever you like with the data in the previously mentioned Controller action.

Okay, solved it by creating a global array in the JavaScript of the View, then passing it to a Controller function as a parameter with Ajax.

Related

How can I respond to events on a page in an ASP.NET MVC app that need to access data within the View?

In my ASP.NET MVC project, I need to dynamically manipulate some html elements when the user makes a couple of selections. I assume this needs to be done in code-behind C# (as opposed to in jquery), because how I respond is using data that is retrieved from a SQL Server database and is part of the View (I don't think jQuery would/could know about this MVC/.NET-specific data).
Specifically, when a user clicks a checkbox on the page, provided a selection has been made from an html-select element, my code needs to spring into action to populate other elements on the page.
The View (.cshtml) is getting the data in a Razor code block like so:
#model WebAppRptScheduler.Models.HomeModel
#using System.Data
#{
DataTable dtUnitReportPairEmailVals = Model.UnitReportPairEmailVals DataTable;
var unitRptPairEmailVals = from x in dtUnitReportPairEmailVals.AsEnumerable()
select new
{
emailAddr = x.Field<string>("EmailAddr")
};
This data comes from the Controller:
DataTable UnitReportPairEmailValsDT = new DataTable();
UnitReportPairEmailValsDT = SQL.ExecuteSQLReturnDataTable(SQL.UnitReportPairEmailQuery, CommandType.Text, null);
model.UnitReportPairEmailVals = UnitReportPairEmailValsDT;
Does this (event handling) code belong in the Controller? If so, how is the method declared/decorated so that there is a connection between it and the html elements whose events it needs to monitor?
This is what needs to happen:
User selects an option from an html select
User clicks a checkbox
The code determines that both an option has been selected, and a checkbox checked; it then uses the data to populate other controls, something like this:
#if (unitRptPairEmailVals.Count > 0)
{
email1.Text = unitRptPairEmailVals[0];
}
#if (unitRptPairEmailVals.Count > 1)
{
email2.Text = unitRptPairEmailVals[1];
}
#if (unitRptPairEmailVals.Count > 2)
{
email3.Text = unitRptPairEmailVals[2];
}
The above would populate the text/value of these html inputs:
<label class="margin4horizontal">Email 1</label><input type="text" name="email1" id="email1" />
<label class="margin4horizontal">Email 2</label><input type="text" name="email2" id="email2" />
<label class="margin4horizontal">Email 3</label><input type="text" name="email3" id="email3" />
BTW, if I'm barking up the wrong tree, or am even in the wrong forest altogether, please let me know what the preferred approach is.
UPDATE
Once I pieced together several different answers to this and related questions, I wrote up a tip on how to do this here.
Update: I was answering on mobile last night, and here is a clearer edit and some sample code...
Asp.net MVC has controllers, which contain actions. When you navigation to a URL (HTTP GET), ASP.net translates this via routes into a specific controller action to invoke, then the result of that action is sent back to the browser as plain HTML.
Also when you submit a form (HTTP POST) to specific URL it translates to invoking a controller action via routes. and a ModelBinder will read the body of that HTTP POST and converts it into your Model class. Unlike the classic web forms that used ViewState to track page controls, state, and events.
What you want to achieve can be done in 2 different ways...
Using JavaScript and JQuery. You can issue an Ajax request (GET, POST, etc) to a URL that exists in your ASP.net MVC routes table to execute an action and the results will be returned back to your JavaScript without navigating to another page.
Posting an HTML Form back to the server will allow ASP.net MVC to read the new/changed values in your HTML controls and pass those new values to the controller action, which in turn can render the same view again with the new values and behaviour.

using ajax to post to server of a partial view form

I am new at using ajax, I have to add the form data onto a post so that it can be added to the server. but the tricky part is that the form data is a partial view on a dialog box. i would like to know how i would be able to use ajax in order to get a hold of this data so that it can be put back on to a database.
make a function on click of a button in the dilog box
Then un that function use $.Post({"Controller/Action", {Parameter List}})
where PArameter List will contain the values of controls Like
Parameter1=document.getelementbyid('Textbox1').value;
so on ....
and make a action method in controller using [HTTPPost]
you can check syntax from here
http://www.codeproject.com/Articles/426765/post-and-get-in-MVC-Razor-JQuery
Please Click the answer as useful if it serves your problem.

Display form in pop up

i have two cshtml page one which has the link the makes the popup appear, and another with just the form data and would like to know how i would be able to display the form on the popup, as i am using MVC, to create the form, the plage which has link on is in the ~/views/client/index.cshtml while thr form is ~/views/fb/CreateOrEidt.cshtml the colller is called "FB" and the methos to call is edit, it take the parameter Id
I have tried #hmtl.renderpartial, #html.renderaction, #hmtl.partial, #html.action,
I have also tied these method with a { after the # and the end, doesnt give me a error bust still doesn't display information
The error which i get is razor canot convert type object to void
It's a little unclear what you're trying to achieve but from the error you've mentioned when calling Html.RenderAction you need to call using something like:
#{
Html.RenderAction("ACTIONNAME");
}
Calling the other methods against an action view won't work.
If you're trying to display a view inside a popup though you want to be careful that you don't end up including your layout page etc as this is potentially not the look you're going for..!
The pattern I generally implement for things like this is to simply partial out the form bit that I need to reuse and call renderpartial to display this where I need it. This renders just the html I'm after then and not the whole view (+ layout(s)).

ASP .NET MVC partial views and routing

I have an MVC view that contains a number of partial views. These partial views are populated using partial requests so the controller for the view itself doesn't pass any data to them. Is it possible to reload the data in one of those partial views if an action was triggered in another? For example, one partial view has a jqGrid and I want to refresh the data in another partial view when a user selects a new row in this grid.
Is there a code example for this scenario (in C#) that I can look at to see what am I doing wrong? I am using ajax calls to trigger a new request but non of the partial views are refreshed so I am not sure if the issue is with the routing, the controller, or if this even possible at all!
Thanks!
If your partial view action returns a ViewResult, the response contains an HTML chunk. However, an Ajax call does not automatically insert the result into the DOM, as the result can be in any number of formats and/or might need additional processing before the DOM is updated. So, in order to get your partial view refreshed, you need to take the result of the Ajax call and insert it in the right place in the DOM tree.
jQuery has a nifty load() method, that will encapsulate this process for you. It'll make the Ajax call, take the result and replace the inner HTML of the selected element. You can even pass it your own function to be executed before it inserts it in the DOM tree, if you need to transform the result in any way.
Side note: jQuery.load() strips scripts returned in the result. It does retain them for execution in certain sceanrios, but it does not even execute them in other scenarios. So, if your partial view contains scripts, you might consider updating the DOM tree yourself.
All that this has nothing to do with your C# code, which runs on the server side.
However, you do have the ability to make your action a little bit smarter by checking if the request is plain HTML, so the result will be rendered by the browser directly, or if it's an Ajax call and the result will be processed by your script before getting in the DOM. This check is done using the Request extension method IsAjaxRequest.

How can I set a variable in my pages javascript based on my controller action in ASP.NET MVC?

So, I have a page that looks like the following:
alt text http://img704.imageshack.us/img704/5973/croppercapture3.png
This is my basic messaging inbox. I have 2 pages right now, Inbox and Sent (there will eventually be others). These both share the same View, and just have 2 different actions to populate the appropriate data.
The elements on the right-hand side (the message list) is a partial view which has its data populated based on my two controller actions Inbox(int? page) and Sent(int? Page).
So, I have one view "MessageView" and one partial view "MessageList" shared between Inbox/Sent.
However, I now have to get those arrow buttons ("<" ">") working using Ajax. I know how to use jQueries ajax calls well enough, and I know how to render the result of the action call (which returns a partial view).
The problem comes from the fact that the javascript that makes these pagination ajax calls needs to know two things:
What the current page is (whether it be /messages/inbox or /messages/sent)
What the current page is (specified in the query string, ie /messages/inbox?page=2).
Without knowing which page I'm on (Inbox or Sent), it wont know which url to make the ajax call on. Should it make the postback to /messages/inbox or to /messages/sent?
If I wasn't making these messages load with Ajax it would be as simple as loading the appropriate url into the link tags for the "<" and the ">" buttons. But I can't, because part of my requirements states that it must load the messages below without visibly refreshing to a new page.
In JavaScript you can check window.location.pathname to see the pathname section of the current’s page’s URL.
window.location.search gives you the query string.
When the user clicks the Inbox or Sent buttons, you need to rewrite the URLs in your arrows so that they point to the right place.

Categories

Resources