I need to pass a parameter to a partial view but I'm not finding how.
So basically my problem is: I need to call RenameFileAndFolder from a different view and then bring the user to the Index controller page but passing a path to the _fileTable.
Controller:
public ActionResult Index(){...}
public ActionResult _fileTable(string path){...} //partial view
[HttpPost]
public ActionResult RenameFileAndFolder(string path, string newName){...}
View:
function RenameFileFolder() {
//(...)
$.ajax({
type: "Post",
url: '#Url.Action("RenameFileAndFolder", "ManageFiles")',
data: { path: '#(currentPath)', newName: inputName },
dataType: "json",
traditional: true,
success: function (data) {
document.getElementById("inputNewName").value = "";
//Here how can I say: "go to the index page with the path="X" on the partial view"?
//currently I am doing this but it does not allow me to pass a parameter
window.location.assign("Index");
})
}
The partial view is called within the view:
<div id="tabelaDiv">
#{
Html.RenderAction("_fileTable", Model);
}
</div>
EDIT:
My situation in more detail:
So, I am on the View beta with partial view omega within it. Then I go to View alpha and call function RenameFileFolder() with an ajax query, and, if success, I want to be able to go again to View Beta and pass a parameter to the partial view omega.
Simply write this to send parameters to ActionMethod
<div id="tabelaDiv">
#Html.Action("_fileTable",new{path= "your path"} )
</div>
You could try storing the new filepath in a Session variable and then accessing it in your view. This will save you trouble of trying to pass the variable between your views.
[HttpPost]
public ActionResult RenameFileAndFolder(string path, string newName)
{
//code to get new file path
//set session variable
Session["path"] = "<filepath>";
//return your ActionResult;
}
Once you have stored the variable, you can access the session variable in your view by using:
#Session["path"]
It really depends on how long you would like this data to persist for. This variable will persist throughout the users entire session, so if you want to reset it you would need to do so explicitly Session["path"] = null. However, if you only want it to persist long enough to render a single partial view, it may be better to use one of the other methods for persisting data such as ViewData:
https://www.codeproject.com/Articles/576514/AplusBeginner-splusTutorialplusonplusVariousplus
Related
I have the following URL.Action in my cshtml:
<a href="#Url.Action("ShowStudent", "Student", new { studentCode = item.StudentCode, newPrivateStudent = Model.PrivateStudent })">
<i class="icon-arrow-right"></i>
</a>
The action in my controller is:
public ActionResult ShowCShowStudentlient(studentCode studentCode , PrivateStudentModel newPrivateStudent )
{ *some actions*}
When the action is hit in the controller the newPrivateStudent is set as null.
Any idea why?
The newPrivateStudent properties are set as hidden in the cshtml.
First, you should look at this #Url.Action helper:
#Url.Action("ShowStudent", "Student", new { studentCode = item.StudentCode, newPrivateStudent = Model.PrivateStudent })
The helper above will generate URL with query string like the following example (already tested):
...
As you see at the last parameter (newPrivateStudent), instead of adding contents of the complex object, the helper implicitly calls ToString() which returns fully-qualified name of that object (and subsequently newPrivateStudent has null value in action method). Hence, the proper way to do so is using AJAX callback to post corresponding key together with model contents to controller action and sends back its response as partial view to target DOM element.
Here is an example for sending model contents inside a form with AJAX postback (assumed using HTML helpers to generate input elements):
$('#triggerElementId').click(function () {
// this example sets string parameter as hardcoded string
// change it to actual value by jQuery selector with val() or text() function
var sCode = "XXX";
var modelData = $('form').serialize();
// or serializeArray() if you want to push additional data
// if model contents should left unchanged, use 'var modelData = #Html.Raw(Json.Encode(Model.PrivateStudent))'
$.ajax({
type: 'POST',
url: '#Url.Action("ShowStudent", "Student")',
data: { studentCode: sCode, newPrivateStudent: modelData },
success: function (result) {
$('#targetResultElement').html(result);
},
error: function (xhr, status, error) {
// error handling
}
});
});
Then setting controller action to retrieve key & serialized model contents as in example below:
[HttpPost]
public ActionResult ShowStudent(string studentCode, PrivateStudentModel newPrivateStudent)
{
// some actions
return PartialView("_ShowStudent", viewModelName); // mention partial view & viewmodel name here
}
I request a ajax call from the View Index.cshtml to an action method in HomeController.cs and get json data that I use in Index.cshtml.
Another View Display.cshtml is called using Url.Action() from different anchor tags in Index.cshtml.Depending on the anchor tag clicked, the data will be displayed in Display.cshtml.
Now I have a requirement where the same json(used in Index.cshtml) is needed in Display.cshtml.
Please let me know the best way to pass the json data with minimal calls to server & data storage on client side.
Thank you.
Ajax call in Index.cshtml
$(document).ready(function () {
$.getJSON("#Url.Action("GetJsonData", "Home")", function (json) { ... }
Anchor tag in Index.cshtml
<a href="#Url.Action("Display", "Home", new { Name = "Test" })">
Call Display.cshtml in HomeController.cs
public ActionResult Display(string Name)
{
ViewBag.Name = Name;
return View();
}
I'm working on an asp-mvc application and facing the following issue:
I have a model with simple properties plus one property which is a list of my custom object, and I render the Ienumerable property as mentioned here:
Passing IEnumerable property of model to controller post action- ASP MVC
In my view, I have a button that is supposed to add items to the ienumerable property of my model. Of Course, I don't want to lose already inserted data, so I need to pass the model to the corresponding action.
I've noticed that the model os transferred entirely only upon post. So, I did something like:
$(".addButton").click(function (event) {
event.preventDefault();
$("#FilterForm").submit();
#{ Session["fromAddFullItem"] = "true";}
return false;
});
And then in my controller, I do something like:
public ActionResult Index(FilterModel model)
{
if (Session["fromAddFullItem"].ToString() == "true")
{
Session["fromAddFullItem"] = "false";
return AddBlankItemTemplate(model);
}
I've read that assigning session in js is not recommended, but also tried TempData, and there the data was always null.
My problem is that Session["fromAddFullItem"] is always true, even when I come from another button. If I put breakpoint in addbtn click in line- Session["fromAddFullItem"] = "false";, and press the other button, I see that for some odd reason the mentioned breakpoint is hit, even though I haven't pressed the add button.
Any help? Maybe there is another way to achieve what I want. Currently, no matter which button I press (which posts the form), it comes as Session["fromAddFullItem"] = "false" and goes to action AddBlankItemTemplate. Thanks.
EDIT - AJAX POST
$(".addButton").click(function(event) {
event.preventDefault();
var modelData = JSON.stringify(window.Model);
$.ajax({
url: '#Url.Action("AddBlankItemTemplate")',
type: 'POST',
dataType: 'json',
data: modelData,
contentType: 'application/json; charset=utf-8',
});
return false;
});
and controller
public ActionResult AddBlankItemTemplate(string modelData)
EDIT 2:
$(".addButton").click(function (event) {
event.preventDefault();
$.ajax({
url: '#Url.Action("AddBlankItemTemplate")',
data: $("#FilterForm").serialize()
}).success(function(partialView) {
$('DetailsTemplates').append(partialView);
});
});
and Controller:
public ActionResult AddBlankItemTemplate(FilterModel model)
The line #{ Session["fromAddFullItem"] = "true";} is Razor code and will be run on page rendering and load regardless of where you put it in the page.
It's not client side code so won't wait for your js code to run. If you're trying to synchronise state between js and MVC have you looked into angularjs which could simplify these actions.
I have a following form:
Edit is some partial view _Edit with separate view model called EditVM.
Search is a partial view _Search split between two another partial models - filter (_SearchFilter) and search results (_SearchResults). All those views share one view model SearchVM.
Finally I'm trying to make an UpdateVM which represents what's on the picture. It contains EditVM and SearchVM instances.
My problem is loosing information about the UpdateVM.
First I'm calling get action Update.
[HttpGet]
public virtual ActionResult Update()
{
var model = new UpdateVM();
var searchVM = new SearchVM();
model.searchVM = searchVM;
var editVM = new EditVM();
model.editVM = editVM;
return View(model);
}
View looks like that:
#model UpdateVM
#Html.Partial(MVC.Shared.Views._Search, Model.searchVM)
#Html.Partial(MVC.Shared.Views._Edit, Model.editVM)
Problem begins with searching on the filter. As you can see to the _Search partial view only a SearchVM is passed. I want Search to be generic, shared between the views, so I can't pass to it the UpdateVM.
Filter view _SearchFilter looks as follows:
#using (Html.BeginForm(Model.SearchButtonAction, Model.SearchButtonController, FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="frm_row">
#Html.TextBoxFor(model => model.Query)
<input type="submit" value="Search" />
</div>
}
The problem is that post action is getting SearchVM instance, moreover with only Query field set. Is it possible at all to split whole view shown on the picture only between two actions, get and post, with UpdateVM? Is it possible to don't loose the information already stored in the models (search has some settings, for example mode small or big)?
Or maybe there's other way to implement mentioned view in a robust way? Maybe I'm trying to do it not in the MVC style?
You don't want to load your partial views into the main view. you want them to be dynamically loaded based on the search parameters. To do this use an ajax call
$(document).on('click', '.btnSearch', function(){
$.ajax({
url: '#Url.Action("Search", "Controller")',
type: 'post',
cache: false,
async: true,
data: { id: $("#Query").val() },
success: function(result){
$(".divSearch").html(result);
}
});
});
your controller would look like this
public PartialViewResult Search(int id){
var Model = //populate the model based on the selected id
return PartialView("_partialName", Model);
}
and change your search button to
<input type="button" value="Search" class="btnSearch" />
you don't want to submit the form so you want a button instead of a submit and you need to add a class to the button that your script can trigger off of for the click event. Let me know if you have any questions.
I would like to pass a javascript variable in a #Url.Action method as a route parameter.
I like to pass the screenmode javascript variable as a route parameter to my action method.
I have a view model with ScreenMode enum property and based on it i
should call a action in Ajax. I also need to pass a javascript
variable as a parameter for route.
This is what i tried and got compilation error.
The name 'screenMode' does not exist in the current context
$("#role-detail-form").submit(function (e) {
if ($(this).valid()) {
var screenMode = 0;
#{
if (Model.ScreenMode == UI.ViewModel.ScreenMode.New)
{
<text>
screenMode =2;
</text>
}
}
$.post('#Url.Action("SaveRoleDetail", new { mode=screenMode})',
$(this).serialize(), function (data) {
$("#role-detail").html(data);
$.validator.unobtrusive.parse($("#role-detail"));
});
}
e.preventDefault();
});
My Action is
public ActionResult SaveRoleDetail(RoleModel viewModel, ScreenMode screenMode)
{
}
You'd have to split that out and build the query string yourself, in order to incorporate the Javascript variable.
Something like this is what you need:
$.post('#(Url.Action("SaveRoleDetail"))?screenMode=' + screenMode)
EDIT: Although probably best practice, you should store the ScreenMode variable in your Model, then put a HiddenFor in your view for it. Then, whenever you change the value in Javascript, simply update the value of the hidden input, that way your action method only needs to take the view model as a parameter. If you are posting the form in JavaScript and you can call $("#form").serialize() to send all the data back within your post call.
Also it's possible to create a place holder and then replace it:
var url = '#Url.Action("GetOrderDetails", "Home", new { id = "js-id" })'
.replace("js-id", encodeURIComponent(rowId));
If you use T4MVC and jQuery, you can call the ActionResult doing the following:
In the controller:
public ActionResult SaveRoleDetail(RoleModel viewModel, ScreenMode screenMode)
{
}
In the view:
$.post("#Url.Action(MVC.Home.SaveRoleDetail())", { viewModel: param1, screenMode: param2) }, function (data) {
//Do Work
});
Access your route values (perhaps in html.HiddenFor). Values from JavaScript and Build your URL without #Url.Action. Use the URL to post.