MVC 4 partial view causes page to become unresponsive on submit - c#

Situation: In my C#/MVC 4 solution I am employing a view with a partial view within. The view is a form with a submit button. The partial view is with a div that is hidden, but can be displayed if the checkbox is selected.
Issue: If the partial view is hidden, the submit works normally. If the partial view is not hidden the submit causes the page to become unresponsive, if one waits the 3 plus minutes or so the submit eventually works as expected.
The code is below. Thank you in advance for your consideration. I am a novice developer, therefore all comments, suggestions and critiques are welcome.
Code:
Model
namespace MyModels
{
public class MainModel
{
public SelectListItem Things { get; set;}
public IEnumerable<OtherModel> MoreThings { get; set;}
}
}
View
//named MyView
#model MyModels.MainModel
#using MyModels
#if (Model != null){
using (Html.BeginForm("MyViewName", "MyControllerName", FormMethod.Post, new { id = "view-form" }))
{
#Html.LabelFor(model => model.things)
#Html.DropDownList("", (Selectist)ViewBag.things)
#Html.ValidationMessageFor(model => model.field1)
#Html.CheckBoxWithLabel("aNameAttribute", Model.valueAttribute.ToString(), "anIdAttribute", Model.valueAtttribue ==1, "aLabel", "a_Toggle_Class")
<div class="treeview" style="display: none;">
<fieldset>
<legend>Title</legend>
//view causing issues replaces the div below
<div id="replacedDiv"></div>
</fieldset>
</div>
<p>
<input type="submit" value="Submit" />
</p>
}
}
<script type="text/javascript">
$(document).ready(function () {
$.ajax({
url: "/MyController/MyPartialView",
contentType: "application/html; charset=utf-8",
cache: "false",
type: "GET",
datatype: "html"
})
.success(function (result) {
$('#replacedDiv").html(result);
})
});
</script>
Partial View
//named _MyPartialView
#model MyModels.MainModel
#using MyModels
#foreach (var moreThings in ViewBag.moreThings)
{
<div id="replacedDiv">
<label>
<input type="checkbox" id=#moreThings.id value=#moreThings.name />#moreThings.name </label>
</div>
}
Controller
namespace Main.Controllers
{
public class MyController
{
[HttpGet]
public ActionResult Index(MainModel model)
{
return View(model);
}
public ActionResult MyView()
{
var model = new MainModel();
return View(model);
}
public ActionResult MyPartialView(MainModel model)
{
<OtherModel> moreThings = BLotherModel.GetMoreThings();
ViewBag.moreThings = moreThings;
return PartialView("_MyPartialView", promotion);
}
[HttpPost]
public ActionResult MyView(FormCollection collection)
{
MainModel model = new MainModel();
return SaveModel(model);
}
}
}

In your ajax you are using:
$('#replacedDiv").html(result);
But your partial view contains <div id="replacedDiv"> that are generated in a loop
replace your partial view code with :
#foreach (var moreThings in ViewBag.moreThings)
{
<label>#moreThings.name </label>
<input type="checkbox" id=#moreThings.id value=#moreThings.name />
}
and it should be OK

Related

Working with multiple partial views

Good day
I am working with 7 partial views on my index page.
Index.cshtml (code section that creates the partial views in their own tabs)
#model project1.Models.MasterModel
<div class="tab-content col-lg-9 col-md-9 col-sm-9 col-xs-9" style="margin-bottom:110px;">
<div id="partial1" class="tab-pane fade in active">
#Html.Partial("partial1", Model)
</div>
<div id="partial2" class="tab-pane fade in">
#Html.Partial("partial2", Model)
</div>
<div id="partial3" class="tab-pane fade in">
#Html.Partial("partial3", Model)
</div>
<div id="partial4" class="tab-pane fade in">
#Html.Partial("partial4", Model.Owners)
</div>
<div id="partial5" class="tab-pane fade in">
#Html.Partial("partial5", Model)
</div>
<div id="partial6" class="tab-pane fade in">
#Html.Partial("partial6", Model)
</div>
<div id="partial7" class="tab-pane fade in">
#Html.Partial("partial7", Model)
</div>
On partial1 I have a submit button that should populate the other partial views with the information that is submitted on the first partial view.
My Model consist of 7 models (one for each partial view)
MasterModel.cs
public class MasterModel
{
public DisplayPartial1 view1 {get;set;}
public DisplayPartial2 view2 {get;set;}
public DisplayPartial3 view3 {get;set;}
public DisplayPartial4 view4 {get;set;}
public DisplayPartial5 view5 {get;set;}
public DisplayPartial6 view6 {get;set;}
public DisplayPartial7 view7 {get;set;}
}
In my controller's Index Action result I create a new instance of the MasterModel and then I create new instances for all the sub models and return to the Index view.
MainController.cs
// Global variable used and returned by all partial views
MasterModel main = new MasterModel();
public ActionResult Index()
{
MasterModel master = new MasterModel();
master.view1 = new DisplayPartial1 ();
master.view2 = new DisplayPartial2 ();
master.view3 = new DisplayPartial3 ();
master.view4 = new DisplayPartial4 ();
master.view5 = new DisplayPartial5 ();
master.view6 = new DisplayPartial6 ();
master.view7 = new DisplayPartial7 ();
return View(master);
}
public ActionResult MyPartial1()
{
return PartialView("MyPartial1", master);
}
[HttpPost]
public ActionResult MyPartial1(MasterModel model, string submitButton)
{
if(submitButton == "GetInfo")
{
/*Process input values*/
//wcf service return data
main.view1.id = serviceObject.Id;
...
main.view4.name = serviceObject.Name;
...
}
return PartialView("MyPartial1", master);
}
When MyPartial1 is returned then the other 6 partial view do not update with the assigned information until I do a submit call with a java script that looks like the following:
<script type="text/javascript">
$(document).ready(function () {
$('#input1').change(function () {
$('form').submit();
});
$('#input2').change(function () {
$('form').submit();
});
});
</script>
An Example Partial view (all the partial views work on the same principals)
#model OperatorLicense.Models.MasterModel
#using (Ajax.BeginForm("MyPartial1", "Operator", null, new AjaxOptions
{
UpdateTargetId = "MyPartial1",
InsertionMode = InsertionMode.Replace,
HttpMethod = "Post"
}, new { id = "MyPartial1" }))
{
#Html.TextBoxFor(model => model.view1.SerialNumber, new { id="SerialNumber", #class = "form-control", placeholder = Html.DisplayNameFor(n => n.view1.SerialNumber) })
...
}
Is there a way to refresh the other partial views when the MyPartial1 partial view has returned so that the assaigned values can be displayed on the required partial view?
You can use OnSuccess or OnComplete property of AjaxOptions class.
#using (Ajax.BeginForm("MyPartial1", "Operator", null, new AjaxOptions
{
UpdateTargetId = "MyPartial1",
InsertionMode = InsertionMode.Replace,
HttpMethod = "Post",
OnSuccess="partial1Success"
}, new { id = "MyPartial1" }))
{
#Html.TextBoxFor(model => model.view1.SerialNumber, new { id="SerialNumber", #class = "form-control", placeholder = Html.DisplayNameFor(n => n.view1.SerialNumber) })
...
}
define partial1Success method in javascript
<script type="text/javascript">
function partial1Success(){
// write your other partial view refresh logic here
}
</script>
partial1Success method called after from submit successfully.

Sending a phrase (variable) from searcher (from view) to controller, asp.net mvc

I'm trying to create searcher in asp.net. I'm so green about it. I'm trying to create in view and send to controller variable, which has text written in searcher. In that moment, I have smth like that -->
My question is, where and how create and send variable and give her data written in searcher?
Layout
form class="navbar-form navbar-left" role="search">
#using (Html.BeginForm("Index", "Searcher", FormMethod.Post, new { phrase = "abc" }))
{
<div class="form-group">
<input type="text" class="form-control" placeholder="Wpisz frazę...">
</div>
<button type="submit" class="btn btn-default">#Html.ActionLink("Szukaj", "Index", "Searcher")</button>
}
</form>
Controller
public class SearcherController : ApplicationController
{
[HttpGet]
public ActionResult Index(string message)
{
ViewBag.phrase = message;
getCurrentUser();
return View();
}
}
View
#{
ViewBag.Title = "Index";
}
<h2>Index</h2>
<ul>
<li>#ViewBag.message</li>
</ul>
You're missing a key part of MVC -> the Model.
Let's create one first:
public class SearchModel
{
public string Criteria { get; set; }
}
Then let's update your "Layout" view (don't know why you had a form in a form?):
#model SearchModel
#using (Html.BeginForm("Index", "Searcher", FormMethod.Post, new { phrase = "abc" }))
{
<div class="form-group">
#Html.EditorFor(m => m.Criteria)
</div>
<button type="submit" class="btn btn-default">#Html.ActionLink("Szukaj", "Index", "Searcher")</button>
}
Then your action that serves that view:
[HttpGet]
public ActionResult Index()
{
return View(new SearchModel());
}
Then your post method would be:
[HttpPost]
public ActionResult Index(SearchModel model)
{
ViewBag.phrase = model.Criteria;
getCurrentUser();
return View();
}

Partial View to Add Data

So here, I need to add comment for video in one view.
I have the main view code like this that displaying video and comment for that video.
<!-- language: C# -->
#model AzureMediaPortal.ViewModels.ViewModelWatch
#{
ViewBag.Title = "Watch";
}
<div id="videoPlayer">
</div>
<h2>#Html.DisplayFor(model => model.media.Title)</h2>
<h3> By #Html.DisplayFor(model => model.media.UserId) at #Html.DisplayFor(model => model.media.UploadDate) </h3>
#Html.HiddenFor(model => model.media.Id)
#Html.HiddenFor(model => model.media.AssetId)
#Html.HiddenFor(model => model.media.FileUrl, new { id = "fileUrl" })
<div class="display-label" style="font-weight:bold">
#Html.DisplayNameFor(model => model.media.Description)
</div>
<div class="display-field">
#Html.DisplayFor(model => model.media.Description)
</div>
<br />
<div class="display-label" style="font-weight:bold">
#Html.DisplayName("Category")
</div>
<div class="display-field">
#Html.DisplayFor(model => model.media.Category.CategoryName)
</div>
<h3>Comments</h3>
#foreach (var item in Model.comment)
{
<div class="display-label" style="font-weight:bold">
#item.UserId
</div>
<div class="display-field">
#item.Content
</div>
}
#Html.Partial("Post",new AzureMediaPortal.ViewModels.ViewModelWatch())
#section Scripts {
<script src="~/Scripts/playerframework.min.js"></script>
<script src="~/Scripts/media-player.js"></script>
#Scripts.Render("~/bundles/jqueryval")
<script type="text/javascript">
mediaPlayer.initFunction("videoPlayer", $("#fileUrl").val());
</script>
}
and this the partial view
#model AzureMediaPortal.ViewModels.ViewModelWatch
#{
ViewBag.Title = "Post";
}
<h2>Add Comment</h2>
#Html.HiddenFor(model => model.cmnt.MediaElement.Id)
#using (Html.BeginForm("Post","Home",FormMethod.Post)) {
#Html.AntiForgeryToken()
#Html.ValidationSummary(true)
<fieldset>
<legend>Add Comment</legend>
<div class="editor-label" style="font-weight:bold">
#Context.User.Identity.Name
</div>
<div class="editor-field">
#Html.TextAreaFor(model => model.cmnt.Content)
#Html.ValidationMessageFor(model => model.cmnt.Content)
</div>
<p>
<input type="submit" value="Post" />
</p>
</fieldset>
}
#section Scripts {
#Scripts.Render("~/bundles/jqueryval")
}
this is my ViewModel
public class ViewModelWatch
{
public MediaElement media { get; set; }
public List<Comment> comment { get; set; }
public Comment cmnt { get; set; }
}
and this is my controller
public ActionResult Watch(int id)
{
ViewModelWatch vm = new ViewModelWatch();
vm.media = _repository.GetMedia(id);
vm.comment = _repository.GetMediaComment(id);
return View(vm);
}
public ActionResult Post()
{
return View();
}
[HttpPost]
public ActionResult Post(Comment comment, int id)
{
if (ModelState.IsValid)
{
comment.UserId = User.Identity.Name;
comment.MediaElement.Id = id;
db.Comments.Add(comment);
db.SaveChanges();
return RedirectToAction("Watch");
}
return View();
}
I need to pass data from partial view and save it to database include the media.Id to know that comment inserted for the video.
Thanks so muchhh
putting scripts on a partial view is generally bad practice. Script gets inserted into the middle of the view. For saving information from a partial view I use ajax calls. To do that add a class to your post button
<input type="button" class="btnSubmit" value="Post" />
then in your script on the main page
$(document).on('click', '.btnSubmit', function(){
$.ajax({
url: '#Url.Action("Action", "Controller")',
cache: false,
async: true,
data: {
//put the data that you want to save from the partial here
id: $('#hiddenID').val(),
content: $('#Content').val()
},
success: function (_result) {
//can add something here like an alert, close a popup something along those lines
}
});
});
just make sure the inputs on your controller match exactly the names that you have defined here
[HttpPost]
public ActionResult Action(int id, string content){
//database call to save the fields
//see here for an example of returning json http://stackoverflow.com/questions/1482034/extjs-how-to-return-json-success-w-data-using-asp-net-mvc
return Json(json);
}
I would suggest using #Html.Action and get the create form from there. Also, once the comments are stored you can redirect to the parent action. That should automatically update the comments list.
But that would be a bad idea.
Rather you can put get your comments by calling action from ajax ($.ajax) and use pure.js to replace the older ones with the new comment list.

Not able to run another function for another button inside same view

I have got the two buttons in the same view one is working with the data to show in a label in another view and I have written the function for the button2 (adding another value), when I click on the button2 its not showing the data in view ..... rather it's giving error like this ... http:404 Resource not found error
and this is the view
#model MvcSampleApplication.Models.products
#{
ViewBag.Title = "Valuesadd";
}
<h2>Valuesadd</h2>
#using (Html.BeginForm("SubmitValue","EnterValue",FormMethod.Post))
{
<div>
<fieldset>
<legend>Enter Textbox Value</legend>
<div class ="editor-label">
#Html.LabelFor(m => m.EnteredValue)
</div>
<div class="editor-field">
#Html.TextBoxFor(m=>m.EnteredValue)
</div>
<p>
<input type="submit" value="Submit1" />
</p>
</fieldset>
</div>
}
#using (Html.BeginForm("SubmitValue2","EnterValue",FormMethod.Post))
{
<p>
<input type="submit" value="Submit2" />
</p>
}
and this is the controller for
namespace MvcSampleApplication.Controllers
{
public class EnterValueController : Controller
{
[HttpPost]
public ActionResult SubmitValue(MvcSampleApplication.Models.products model)
{
TempData["logindata"] = model.EnteredValue;
return RedirectToAction("submittedvalues" , "SubmitValue2");
// how can we redirect to another view when the button is clicked in one view
}
public ActionResult submittedvalues()
{
var model = new MvcSampleApplication.Models.category();
string data = TempData["logindata"] != null ? TempData["logindata"].ToString() : "";
model.lablvalue = data;
return View(model);
}
// action for second button click
public ActionResult submittedvalues2()
{
var model = new MvcSampleApplication.Models.category();
string data = TempData["logindata"] != null ? TempData["logindata"].ToString() : "";
model.lablvalue = "HIIII"+data;
return View(model);
}
}
}
would you pls suggest any idea ..
Many thanks...
Your form action and action in the controller are not named the same. Also you don't have a HttpPostfor it
#using (Html.BeginForm("SubmitValue2","EnterValue",FormMethod.Post))
{
}
//add this
[HttpPost]
public ActionResult submittedvalues2()
{
var model = SOMETHING;
return View("submittedvalues", model);
}
or
[HttpPost]
public ActionResult submittedvalues2()
{
//Do your post actions and redirect to action
return RedirectToAction("submittedvalues");
}
SubmitValue2 in the form should be submittedvalues2, and add a HttpPost attribute on it

Load two controllers in the same view

I'm developing an mvc 4 application and I'm just about done. I have two controllers are there.
public ActionResult Index()
{
return View(new Resources());
}
public ActionResult ResourceDetails(int id = 1)
{
ResourceItems re = new Resources().GetResDetails(id);
return View(re);
}
ResourceDetails is a partial viewpage .it contains
#model ....Models.ResourceItems
<div>
#Html.Raw(#Model.Res_Details)
</div>
and index page contains
#model IEnumerable<.....Models.ResourceItems>
<ul id="res">
#foreach(var Item in Model)
{
<a href="~/Resources/ResourceDetails/#Item.Id" ><li>#Item.Res_NA</li></a>
}
</ul>
<div id="rescontent">
</div>
I want load the partial page in to the div "rescontent" based on Id. Defaultly Id is 1. how it possible
You could use AJAX:
#model IEnumerable<Puthencruz.Rotary.Club.Models.ResourceItems>
<ul id="res">
#foreach(var item in Model)
{
<li>
#Html.ActionLink(
item.Res_NA,
"ResourceDetails",
"Resources",
new { id = item.Id },
new { #class = "detail" }
)
</li>
}
</ul>
<div id="rescontent">
</div>
and then in a separate javascript file you could use jQuery to subscribe to the .click event of the anchors and send an AJAX request to the Details controller action sending the current item id and then render the results in the #rescontent div:
$(function() {
$('.detail').click(function() {
$('#rescontent').load(this.href);
return false;
});
});
Also from your controller action make sure you are returning a partial view:
public ActionResult ResourceDetails(int id = 1)
{
ResourceItems re = new Resources().GetResDetails(id);
return PartialView(re);
}

Categories

Resources