How to pass viewData back to the controller from partial view? - html

I have a main view using several partial Views.
Each of these partials use a different model and have post action.
My problem is I need one property from my main view's model to be used in one of my partials.
The partial view which I need to pass this property view is the last stage in the process.
The application reaches a partial view that contains a switch statement , based on the status on the item being queried, decides which partial will be rendered.
I have the property passing that far and even have it included in the Renderaction for the partial but I don't know how to retrieve it in the controller, PartialViewResult.
In the main view:
#{Html.RenderPartial("StatusForm", Model.HeadingDataModel.Status, new ViewDataDictionary { { "PurchaseOrderNumber", Model.AccordionModel.LtsSpecific.PurchaseOrderNumber } });}
PurchaseOrderNumber is what I'm after. The value gets passed to the next stage:
#{
var obj = ViewData["PurchaseOrderNumber"];
}
And within the same view:
Html.RenderAction("FinishedCalibrationForm", obj);
How can I retreive this in my controller ?? The following is not correct I know, but you get the idea.
public PartialViewResult FinishedCalibrationForm( string obj)
All help is appreciated.

Calling Html.RenderAction or Html.Action is largely the same as Url.Action. There's many different overloads, but essentially, the first parameter is the action name, the second parameter is going to be either the controller name or an anonymous object of route values, and the third parameter will be an anonymous object of route values if the second parameter was used for the controller name.
Anyways, whatever you pass in the route values will be used to find and call the associated action, which includes parameters for the action. So, for your example:
Html.RenderAction("FinishedCalibrationForm", new { obj = obj })
Would properly pass obj into your action method. As you have it now, it's going to interpret the value of obj as the controller name the action is within, which is obviously not correct.

Related

Displaying data based on type of user authentication

So I am have made a laravel authentication application that can log in/register users based on a type and depending on a type they can see different information in this case data tables. I used the laratrust package to do this and works well, but if I want to make this with a vue component that will show the data using some special data grid how would go about doing it as the controller which I am using where the data is collected but is also the place where the view which the user will see depending on the type of user is also checked. So, how will I send the json data to the vue component and what other things do I need to consider.
Here is the controller in laravel:
class DashboardController extends Controller
{
public function index()
{
if(Auth::user()->hasRole('user')){
$posts = DB::select('select * from office');
return view('userdash',['posts'=>$posts]);
}elseif(Auth::user()->hasRole('administrator')){
$posts = Post::all();
return view('administratordash',['posts'=>$posts]);
}elseif(Auth::user()->hasRole('admin')){
$people = DB::select('select * from office');
$posts = Post::all();
return view('dashboard',['posts'=>$posts,'people'=>$people]);
}
}
}
One of the things I tried was
return response(view('userdash',array('posts'=>$posts)),200,['Content-Type' => 'application/json']);
This way I can just send the json data and then render it in the view component. But I am not sure if it is working as I get back a bunch of html and some of the data in the database but not all of it. Also not sure how this can be passed to the view component. Maybe as a prop but not sure.
Any and all help and suggestions are appreciated.
As you are responding from the controller with different views, you can just check for any variables sent with the wiew in your view and once your variables are at your disposal in the view yo can serialize them using $myVar=$myVariable->toJson() if they are laravel collections or json_encode($myVariable) if they are simple arrays.
Then you can
<my-component :data ={{$myVar}}/>

Difference Between Razor View taking a IEnumerable<Model> vs Model?

I have seen some people write #model IEnumerable<WebApplication1.Models.Weight> at the top of their view and some write #model WebApplication1.Models.Weight
I wanted to know the difference between both.Like when to use what?
A razor view which takes an IEnumerable<Entity> as a Model means that a collection of objects (e.g. view models, or entities) is passed as the Model to the page by the controller. e.g.
#model IEnumerable<MyNamespace.Entity>
would match a Controller action such as
[HttpGet]
public ActionResult SearchByName(string startsWith)
{
var entities = Db.Entities
.Where(e => e.StartsWith(startsWith))
.ToList();
return View(entities);
}
So that the view will have access to multiple Entity objects (e.g. the page in question might be an Index or Search result page, where the entries could be listed in tabular fashion with a foreach)
In contrast, a razor view which takes a single object as a Model is just showing the one object, e.g.
#model MyNamespace.Entity
Would be used from a controller action such as
[HttpGet]
public ActionResult Details(int id)
{
var entity = Db.Entities.Find(id);
if (entity == null)
return HttpNotFound();
return View(entity);
}
Means that the view has a single Entity model subject, e.g. the page might be showing the details of one Entity object, or allowing update, or insertion of just one Entity.
The corresponding Model instance object available to the page will be the according type of the #model.
One other point to note is that IEnumerable also expresses immutability, i.e. the View should read the collection, but may not e.g. Add or Delete entities from it (i.e. it is good practice to leave the scaffolded IEnumerable and not change this to e.g. IList or ICollection).

MVC, How to read rendered HTML in a controller?

Maybe it´s a strange question, but imagine this:
//We all know that View is a method...
public ActionResult Something()
{
return View("index");
}
But what if I step before this method to perform some stats
public ActionResult Something()
{
return PerformStats(View("index"));
}
I will have a private method like this:
private ActionResult PerformStats(ViewResult viewResult)
{
//THIS IS WHAT I WANT TO ACCHIEVE:
//*********************************
var contentSent = viewResult.InnerHtml.Lengh; <<-- I wish!
return viewResult;
}
And latter, what i want to do, is to save that ammount of content sent to the client.
It doesn´t matter if it is the exactly quantity of html, even if I get the .count() of a json it will do the trick.
Is any way to know the rendered content on the controller?
Thanks!
OnActionExecuting: Called before action method executes. You can put stats related logic in there.
http://msdn.microsoft.com/en-us/library/system.web.mvc.iactionfilter.onactionexecuting(v=vs.98).aspx
OnActionExecuted: Called after action method executed.
http://msdn.microsoft.com/en-us/library/system.web.mvc.iactionfilter.onactionexecuted(v=vs.98).aspx
Within these methods you can access ActionExecuting and ActionExecutedContext
If you want to get a size of rendered HTML (partial or complete view), then you probably need to:
Find the view that you want to render
Store it in the string builder
Get its length
There is a question that explains how to render view as a string within the action method: In MVC3 Razor, how do I get the html of a rendered view inside an action?

TYPO3. Passing objects as arguments in FLUID View Helpers

In the following code booksis a list of book object containing certain properties. And by clicking on the title, it goes to an action display
Fluid template is
<f:for each="books" as="book">
<f:link.action action="display" arguments="{book: book}"> {book.title} </f:link.action>
</f:for>
In controller
public function displayAction(){
print_r($this->request->getArguments());
}
The value of book here is not being set. [book] => null. I try printing the class of it, it still gives me null.
It works fine when I send the arguments as book.title instead of the entire object
What am I missing here? Is this the right way to pass objects as arguments ?
EDIT:
Initially I tried this way.
public function displayAction(\TYPO3\MyExt\Domain\Model\Book $book) {}
But this gives me
Exception while property mapping at property path "":No converter found which can be used to convert from "string" to "TYPO3\MyExt\Domain\Model\Book"
The class Book is something which I created manually and is not registered under extension builder.
You could try it with a parameter for the action:
public function myAction(Tx_MyExt_Domain_Model_Book $book) {
$this->view->assignMultiple(array(
'title' => $book->getTitle(),
'label' => $book->getLabel(),
'content' => $book->getContent()
));
}
EDIT: I updated the example.
Update:
It works with book.title because it's just a string. When you want a complete book object it needs to be found in some storage. A database e.g.. Hence that means you need a model and a repository. Also an entry in the tca and the tables files. Better create your Models with the extension builder, it's much easier and safer for the beginning.

Return Multiple Collections for use in an MVC4 asp.net View page

I understand how to return a single collection (List<>) from a controller by returning View({mylist}); then referencing that with razor syntax #Model etc. inside the view page. In my case, I have several different collections I want to use separately on the page. I understand that I can make "the mother of all collections collection" and simply include the collections inside another collection (and return that one), but I'm wondering if there is some way in MVC4 that allows me to handle this situation more gracefully.
Thanks and Happy New Year!
You should create a view model. That is a regular class that will hold all the collection or properties you need in your view.
Check this post: http://msdn.microsoft.com/en-us/vs2010trainingcourse_aspnetmvc3fundamentals_topic7.aspx
You can make use of ViewBag for every collection in controller and use those ViewBag variables View
In controller
public ActionResult HotelDetails(List<HotelDetailsModel> model)
{
ViewBag.HotelDetails = model;
return View();
}
and in View
#{
List<HotelDetailsModel> hotels = (List<HotelDetailsModel>)ViewBag.SearchResultsModel;
if (hotels.Count > 0)
{
foreach (HotelDetailsModel item in hotels)
{
}
}
}