Render Partial View in Correct Location - c#

Trying to:
Place a partial view within a telerik tabstrip.
Problem:
The view is being displayed above the tab strip instead of within the first tab.
What I have tried:
If I use RenderPage instead of RenderAction then the view correctly appears inside the tabstrip however then the controller does not get called or load the model for the gridview.
Code so far:
Partial View:
#model IEnumerable<MyModel>
#{
ViewBag.Title = "Index";
}
#*My code to load a GridView*#
View containing tab strip:
#{
ViewBag.Title = "MyView";
}
#(Html.Kendo().TabStrip()
.Name("tabstrip")
.Items(tabstrip =>
{
tabstrip.Add().Text("Index")
.Selected(true)
.Content(#<text>
#{Html.RenderAction("Index", "MyController");}
</text>);
tabstrip.Add().Text("Index2")
.Content(#<text>
</text>);
})
)

The Content configuration method of a Kendo UI TabStrip should be used for "static" content. By static I mean code that you already have/know. For loading partial views it is best to use the LoadContentFrom configuration method. This method requires a valid URL of an existing Action, which returns the targeted partial view:
#(Html.Kendo().TabStrip()
.Name("tabstrip")
.Items(tabstrip =>
{
tabstrip.Add().Text("Index")
.Selected(true)
.LoadContentFrom(Html.Action("Index", "MyController"));
tabstrip.Add().Text("Index2")
.Content(#<text>
</text>);
})
)

Related

ASP.NET MVC Render Partial on Dropdown List Value Change

I'm trying to render a partial view dynamically when the user selects a value from the dropdown list. I've gotten quite far but can't figure out this last bit.
Here's the View/Quiz/AddQuestion.cshtml file
#model quizAppCodeFirst.ViewModels.QuestionTypes
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div>
Type #Html.DropDownList("QuestionTypes", ViewData["QuestionTypes"] as SelectList, new { #class = "form-control" })
<div id="partialPlaceHolder"> </div>
</div>
}
<script type="text/javascript" src="~/Scripts/jquery-3.3.1.min.js"></script>
<script type="Text/javascript">
$(function(){
$("#QuestionTypes").change(function(){
var stateId=$(this).val();
$("#partialPlaceHolder").load("#Url.Action("MyAction", "Quiz")/MCQ");
});
});
</script>
In the QuizController.cs, this is the MyAction method that renders the partials
public ActionResult MyAction(string id)
{
Type t = Type.GetType("quizAppCodeFirst.Quiz" + id);
return PartialView(viewName, t);
}
Till now, I've succeeded in rendering the partial view, but when I click the button inside the partial, it reloads the javascript / MyAction method.
Edit: To make it clear, I have main view which is View/Quiz/AddQuestions.cshtml and within it I am calling a partial view which is View/MCQ/AddMCQ.cshtml when the user selects MCQ from the dropdown list. The partial view (AddMCQ) loads perfectly fine and displays a form to add an MCQ with a Create button, but when I click the Create button, instead of calling the MCQController.cs/AddMCQ function, it calls the QuizController.cs/MyAction function. I can add the code for AddMCQ.cshtml but I feel like it's unnecessary since it works fine on its own.

Nested Partial View

On our website the client can add different items into the footer columns, ie a text box. We wanted to be able to keep the code for these different items in one partial view, as the items are used in other areas of the site and want to keep code duplication to a minimum.
I was wondering if it possible to nest a Partial View within a foreach statement and then pass an if statement based on the parent foreach.
I have the following code in a partial view called Three_Column_Footer:
#inherits Umbraco.Web.Mvc.UmbracoTemplatePage
#{
var root = Model.Content.Site();
var thefooter = root.FirstChild("footer").Children();
}
<footer class="footer color-main">
<div class="container">
<div class="row">
#foreach(var foot in thefooter){
var childcol = foot.Children;
<div class="col-6">
#foreach(var item in childcol){
#Html.Partial("Footers/FooterStubs", item)
}
</div>
}
</div>
</div>
</footer>
I need someway of getting the above foreach to be recognised in the Partial called FooterStubs. Can this be done with an #inherits Umbraco.Web.Mvc.UmbracoViewPage<IPublishedContent> or a Model.GetPropertyValue<IEnumerable<IPublishedContent>> - if so how?
Thanks!
The Partial method has an overload that accepts additionalViewData. You can utilize this to provide any additional context you need the partial to have:
#Html.Partial("Footers/FooterStubs", item, new ViewDataDictionary(ViewData)
{
{ "foot": foot }
});
Then in your partial:
#{
var foot = ViewData["foot"] as YourFootClass;
}
I'm not sure what info you actually need in the partial, but you can essentially add whatever you like in this way. Just bear in mind that ViewData is a dynamic dictionary, so you'll have to type whatever you get out of it.

mvc paging inside an html form

I'm trying to create paging inside html form.
How do I make each page button change the model's CurrentPage property?
I'm new to MVC, so bear with me please.
I have a list of reports that I need to display in a view named Search. I made a model for that (ReportViewModel), and another model that holds a list of those, named SearchViewModel. In SearchViewModel I have some other variables like SearchName, SearchDate, CurrentPage, PageCount, PageSize, etc. The goal is to do paging and searching in one action named Search in ReportsController.
Now, I would like to keep that action simple by giving that function only SearchViewModel instance as a parameter, so that inside I use all variables of that model. Doing that, I won't have to type parameter names twice (once in SearchViewModel and once as parameters in Search action). I will not need that search function elsewhere, so it's ok for it to not have any parameters other than SearchViewModel instance.
So, very loosely, it looks something like this:
ReportsController.cs
public class ReportsController : Controller
{
public ActionResult Search(SearchViewModel model)
{
if (!ModelState.IsValid)
return View(model);
// do search magic here
return View(model)
}
}
Search.cshtml
#model ISFinReports.Models.SearchViewModel
#{
ViewBag.Title = "List";
Layout = "~/Views/_masterLayout.cshtml";
}
<link href="~/CSS/Search.css" rel="stylesheet" />
<script src="~/Scripts/Search.js"></script>
#using (Html.BeginForm("Search", "Reports", FormMethod.Get))
{
<div id="divSearchBar">
// add #Html.DropDownListFor, #Html.TextBoxFor and submit button here
</div>
<div id="divReportsTable">
<table id="tblReports">
#if (Model.Reports != null)
{
foreach (var r in Model.Reports)
{
// add tr, td of all reports in report list
}
}
</table>
</div>
<div style="text-align:center">
#for (int i = 0; i < Model.PageCount; i++)
{
#Html.ActionLink(i.ToString(), "Search", "Reports", new { CurrentPage = i });
// or
// <input type="submit" value="#i" onClick="meybe something like this?" />
}
Current Page #Html.EditorFor(q => q.CurrentPage), of total #Model.PageCount pages
</div>
}
I know that I can simply type twice all the data I need to flow between controller and view, once in model and once as Search action parameters, but that's extactly what I'm trying not to do. Currently I have a textbox for editing the current page, and it works, because it's created via #Html.EditorFor, but I'd like to have multiple buttons for each page.
I could maybe create a hidden field in that form, and create a javascript function that'll find that hidden field by id, and change it's value, and then call whatever the submit button onClick function is. BUT, is there a better/shorter/more-MVC way to implement that?

Return a razor view into an Iframe

I create a small form and give the link to my customer so he include the view in one IFRAME in his page and show ok.
When user submit the IFRAME form instead of redraw inside the IFRAME take the whole page.
...
ViewBag.result = "Form send correctly";
return View();
What should I use instead return View(); ?
I think the problem is not on the controller. It is on your View. You could try set a name for the elements iframe and target your form to post on this element, for sample:
<iframe src="#Url.Action("ActionName", "ControllerName")" name="foo"></iframe>
and in your View inside the iFrame
#using(Html.BeginForm("Action", "Controller", FormMethod.Post, new { target = "foo" })
{
..
}
I guess your problem is, It shows the layout which you do not want to be shown in the iFrame.
You can disable the layout in the razor view
#{
Layout = null;
}
If you remove the layout from the page, you will loose all the JS and CSS you loaded via the Layout file. In that case, you may use a minimalistic Layout which still has reference to your required CSS/JS files.
#{
Layout = "~/Views/Shared/MyMiniLayout.cshtml;
}
You can customize the MyMiniLayout the way you want.
You may show another view once the form submit is completed instead of showing the same view.
[HttpPost]
public ActionResult Register(string name)
{
// to do :Do something with posted data
return RedirectToAction("FormSubmitted");
}
public ActionResult FormSubmitted()
{
return View();
}
You can put whatever markup you want to show to user in the FormSubmitted view.
#{
Layout = null;
}
<h2>Submitted successfully</h2>

Rendering a partial view in MVC with Javascript

I've got an asp.net MVC website that consists of a topbar and a main area.
Via a js function, I want to be able to retrieve new data from my Controller and display these data in the main area of my website, but without re-rendering the topbar area.
How do I do this?
Here is what I got:
I put the topbar and all related scripts in the _layout.cshtml, scripts related to the mainview go to Display.cshtml and the data itself which I want to display go inside Partial_ChartView.cshtml
The partial view that should display my chart data is loaded inside Display.cshtml like this:
#model MobileReports.Models.ReportViewModel
#{
ViewBag.Title = "Display";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#{Html.RenderPartial("Partial_ChartView");}
The partial view Partial:ChartView.cshtml looks like this:
#model MobileReports.Models.ReportViewModel
<div id="chartContainer">#Model.Chart</div>
The corresponding controller contains this code:
public ActionResult Display(Guid? id)
{
ReportViewModel viewModel = new ReportViewModel();
Guid validId = (Guid)id;
viewModel.Chart = GetChart(guid);
viewModel.ChartData = GetData(guid);
return PartialView(viewModel);
}
When I open the page at ../Report/Display , the page seems to get rendered correctly.
Now I want to add a script that calls Display(id) with a certain value. Then I want to re-render only the main area (inside div #chartContainer) to display the new data which should now be in the model.
How do I do this?
Create a new method that returns a partial view containing only the data you need
public ActionResult Chart(GUID id)
{
.....
return PartialView(someModel);
}
then use jquery .load to replace the contents of your div
$('#chartContainer').load('#Url.Action("Chart", "Report")', { id: YourGUIDValue });

Categories

Resources