Loading JQuery in Partial View on MVC - c#

I have an ASP.NET MVC C# web application.
In my layout file I have the following ajax call
<li class="PriceModal">
#Ajax.ImageActionLink("/InternalDB/Content/downloadCSV.png", "Pareto", "35px", "35px", "PartialViewPriceCalculator",
"PriceCalculator", new {#Pareto = "active" }, new AjaxOptions
{ UpdateTargetId = "PriceCalculator", InsertionMode = InsertionMode.Replace, HttpMethod = "GET"}, new { #style = "padding-top:30px" })
</li>
When this Ajax link is clicked a bootstrap Modal is loaded and a partial view is load inside the Bootstrap Modal. At this point the Bootstrap modal and the partial view inside are sitting on top of my existing page.
My problems start when I place jQuery code inside the partial View. I have found a way to append the jQuery code (partial) to the DOM with the following code
$('body').on('jQuery event to be placed here(focus,change,mouseenter)', 'class/ID to be Placed here', function (e) {
// jQuery events
});
This will allow me to append to the DOM loaded by my page on the background.
However this has a lot of issues as well. How do I append a jQuery plug in called Chosen to a dropdownlist which is sitting inside my partial view.
I have experimented by putting the jQuery inside the Ajax Options and using the Onsuccess property but this seems to have problems as well.
<li class="PriceModal">
#Ajax.ImageActionLink("/InternalDB/Content/downloadCSV.png", "Pareto", "35px", "35px", "PartialViewPriceCalculator",
"PriceCalculator", new {#Pareto = "active" }, new AjaxOptions
{ UpdateTargetId = "PriceCalculator", InsertionMode = InsertionMode.Replace, HttpMethod = "GET", OnSuccess = "$('.chosen2').chosen({ allow_single_deselect : true })"}, new { #style = "padding-top:30px" })
</li>
Is there a general approach to loading all of the needed jQuery inside a popup partial view or i just need to find hacks for each specific situation?

You can just use the document.ready event to execute JavaScript when your PartialView finishes loading:
<div id="partialViewHere">
</div>
<script type="application/javascript">
$(function() {
// load whatever you need here
};
</script>
I use this on an application to add events to buttons loaded through different PartialViews and it works perfectly.

Related

Is there a "standard MVC" way of mixing Javascript and Razor?

I really dislike page loads, I think they detract from the user experience, so I'm trying to make my web application heavily AJAX-ified.
When the user clicks on "Add new", Javascript generates a form based on a model using Razor, with the following code:
<script type="text/javascript">
var strNewCategoryForm = '<div><i class="glyphicon glyphicon-folder-open rightfolderpadding"></i>#using (Html.BeginForm("AddCategory", "Password", FormMethod.Post, new { #class="newcategoryform", role = "form", id="[1]" })) { #Html.AntiForgeryToken() #Html.PasswordFor(m => m.Category_ParentID, new { type = "hidden", value = "0" }) #Html.PasswordFor(m => m.CategoryName, new { type = "text" }) <span class="btn-group groupalign"><i class="glyphicon glyphicon-save"></i>Save</span> }</div>';
</script>
The code works great, Razor is able to generate the form within the string, so I dont have any issues with making this work.
However, for code readability and ease of development, it's not that great.
I'm still quite new to MVC and razor, so I'm just wondering, is there a better or "MVC/Razor standard" way of doing this, that I don't know about?
Edit:
In case anyone is interested, I've used both bits of Exception's answers:
In the partial view:
#model Secure_Password_Repository.Models.Category
<div><i class="glyphicon glyphicon-folder-open rightfolderpadding"></i> \
#using (Ajax.BeginForm("AddCategory", "Password", new AjaxOptions { HttpMethod="post", OnFailure="" }, new { #class="newcategoryform", role = "form", id="[1]" }))
{
#: \
#Html.AntiForgeryToken() #: \
#Html.HiddenFor(m => m.Category_ParentID, new { value = "0" }) #: \
#Html.TextBoxFor(m => m.CategoryName) #: \
#: <span class="btn-group groupalign"><i class="glyphicon glyphicon-save"></i>Save</span> \
}</div>
In the main view:
<script type="text/javascript">
var strNewCategoryForm = '#Html.Partial("_NewCategoryForm")';
</script>
The "\" at the end of each line in the partial view tell JavaScript that each line is continuation of a string value.
Answer 1 :-
If You are so keen to AJAX-ify your web app then better way is to use Ajax helper in Asp.MVC such as
#Ajax.BeginForm() or #Ajax.ActionLink() and Helpers like #Html.Partial() ,
#Html.RenderPartial() etc. are also handy for asynchronously loading data.
Their Basic Usage(I m taking hypothetical example here) :-
#Ajax.ActionLink("Show",
"Show",
null,
new AjaxOptions { HttpMethod = "GET",
InsertionMode = InsertionMode.Replace,
UpdateTargetId = "dialog_window_id",
OnComplete = "your_js_function();" })
#using (Ajax.BeginForm("Edit", "Cars", new AjaxOptions
{
InsertionMode = InsertionMode.Replace,
HttpMethod = "POST",
OnSuccess = "updateSuccess"
}, new { #id = "updateCarForm" })) { ..... }
Follow this link :- http://www.codeguru.com/csharp/.net/working-with-ajax-helper-in-asp.net-mvc.htm
Above link will be helpful for you to understand building Forms with Ajax Helpers.
and one thing more the way you are building forms with razor syntax in javascript is not at all a good option 'in my opinion'.
Answer 2 :-
A small demo how to build a completely ajax-ified form which donot require any page reload:
#using (Ajax.BeginForm("Index", "Home", null, new AjaxOptions { HttpMethod = "POST", InsertionMode = InsertionMode.Replace, UpdateTargetId = "Mydiv" }, new { #id = "frm" , #style ="width:700px" }))
{
//Your HTML here
}
Make above View a Partial View say 'Index.cshtml' and then return it this way through Controller as :
Public ActionResult Index()
{
return PartialView("Index");
}
Making Partial Views and loading Partial views through Jquery is handy to make unobtrusive forms.
This is more of an HTML-thing than MVC/Razor, as you are essentially asking on how to embed templates into your website. AFAIK html doesn't Support templating out of the box just yet, so you'd Need some JavaScript for that (in your case right now, you're probably using jquery)
Most template engines like knockoutjs, handlebars, etc. (maybe even jquery) support embedding templates similar to this:
<script type="text/html" id="my_template">
<div>
<p>
My template
</p>
</div>
</script>
The browser would not render that html, but a JavaScript library would use it (optionally doing some runtime data-binding) and display it.
Note: you can obviously put the html from that template into a partial view:
_MyTemplate.cshtml:
<div>
<p>
My template
</p>
</div>
View:
<script type="text/html" id="my_template">
#Html.Partial("MyTemplate")
</script>
Most template engines also support loading templates asynchronously, in which case you just render them the partial view alone.
Hope this helps a little.

JQuery function attached to Ajax ActionLink

Quick question.
I have a Ajax.Action link intended to upload the next section of a form asynchronously.
#Ajax.ActionLink("Next" , "matches",null, new AjaxOptions {UpdateTargetId = "placeholder", InsertionMode = InsertionMode.InsertAfter,HttpMethod = "GET"}, new { #class = "button" })
I've applied my "button" class to it, which gives it the appearance of a big button.
I'm looking to attach a JQuery .click event to the above AjaxAction link triggering a function that will hide the previous form. I'm using the JQuery below to do so:
<script>
$(document).ready(function () {
$(this).closest("a.button").click(function () {
$("form.common").hide();
});
});
</script>
This is not working for me. The Ajax.ActionLink works fine, just not the Jquery. Below is rough breakdown of my page.
<form class="common"> (this form needs to hide)
//lots of inputs
<ActionLink class="button>
</form>
<div id="placeholder">
(this is where the new form will be inserted)
</div>
I'm new to C# and JavaScript/JQuery, so I'm hoping someone can point me in the right direction here.
Rather than using any special events with jQuery, you could call a JS method in the beginning of ajax request performed by ajax link.
Add OnBegin property in your link AjaxOptions and assign a JS function into it and do the logic in that JS function
Ajax Link
new AjaxOptions { OnBegin = "OnBegin" ... }
JS
function OnBegin() {
$("form.common").hide();
}
Hope this will help !!
Try to target your element directly instead of using closest. If you can also use the buttons id or assign a more descriptive class.
$("a.action_button").click(function () {
$("form.common").hide();
});

ASP.NET MVC design issue

I have a main view with 2 partial views (a gridview and a callback panel)
This main view receives a IEnumerable<Model> and the panel just receives a Model.
When the view is initially called, the partial view of the panel is filled with an empty model so it is empty.
But I want to re render the panel once I click Edit in my GridView.
How can I achieve this?
I currently have an #Html.ActionLink in the Edit button but its not working since it will create a new view instead of re render the partial view of the panel.
Any clues?
EDIT:
this is my Edit:
Html.ActionLink("Edit", "EditConfig", new { id = DataBinder.Eval(c.DataItem, "QueueMonitorConfigurationsID") })
Function that the edit link calls:
[HttpGet]
public ActionResult EditConfig(int id)
{
StorageConfigurationModel resultForPanel = new StorageConfigurationModel { };
IEnumerable<StorageConfigurationModel> configList = (IEnumerable<StorageConfigurationModel>)Session["ConfigurationList"];
foreach (StorageConfigurationModel configModel in configList)
{
if (configModel.QueueMonitorConfigurationsID == id)
{
resultForPanel = configModel;
break;
}
}
return PartialView("cbpnlNewUpdateConfigs", resultForPanel);
}
Main view containing the partial views:
#model IEnumerable<BPM.Website.Models.StorageConfigurationModel>
#Html.Partial("gvConfigurations", Model)
#Html.Partial("cbpnlNewUpdateConfigs", new BPM.Website.Models.StorageConfigurationModel { QueueMonitorConfigurationsID = -1 })
I currently have an #Html.ActionLink in the Edit button
You could use AJAX. For example you could replace this Html.ActionLink with an Ajax.ActionLink and include the jquery.js and jquery.unobtrusive-ajax.js scripts (in that order) to make it act as an AJAX call. For example:
#Ajax.ActionLink(
"click to edit record",
"Edit",
new { id = item.Id },
new AjaxOptions { UpdateTargetId = "editContainer" }
)
When the link is clicked the Edit controller action will be invoked using an AJAX request and the id of the current item will be passed as parameter. When this AJAX request completes a DOM element with id="editContainer" will be updated with the results of this AJAX call. So your Edit controller action should return a partial view containing the record to be edited.
Solved with an Ajax POST
$.ajax({
type: "POST",
url: url,
data: data,
success: success,
dataType: dataType
});

Reloading Partial View with JQuery

I have a page with a video at the top and a list of videos you can choose from. Currently, clicking a link in the video list will reload the entire page. I need it to only refresh the partial view I have containing the video at the top of the page.
I saw several posts here on SO showing how to reload partial views with JQuery, but couldn't get it to work correctly in my situation. I'm unsure how to pass the correct id of the video along.
Controller:
public ActionResult Videos(int topVideo = 0)
{
VideosModel model = new VideosModel();
model.Videos = StatsVideoService.GetEntityList(new Lookup(TableStatsVideo.IsDeleted, false)).OrderByDescending(x => x.DateCreated).ToList();
if (topVideo == 0)
model.TopVideo = model.Videos.First();
else
{
model.TopVideo = model.Videos.Where(x => x.StatsVideoId == topVideo).FirstOrDefault();
if (model.TopVideo == null)
model.TopVideo = model.Videos.First();
}
return View(model);
}
View:
#model Project.Models.VideosModel
<section class="videos">
<div id="top_video">
#{Html.RenderPartial("StatsVideo", Model.TopVideo);}
</div>
<ul>
#foreach (var item in Model.Videos)
{
<li>
<div class="videoList">
<a href ="#Url.Action("Videos", "Home", new { topVideo = item.StatsVideoId })">
<img src="#Url.Content("~/Content/img/video-ph.png")" />
</a>
<p class="videoTitle">#item.Title</p>
</div>
</li>
}
</ul>
</section>
If there's any more information needed, please let me know.
After several hours of bashing my head against the wall, I got it to work! Just as a reference to anyone else in the future who's viewing this article, here's how I got it to work:
I set the onclick of the link to point to a javascript method, passing in the id of the video as a parameter:
#foreach (var item in Model.Videos)
{
<li>
<div class="videoList">
<a href ="#" onclick="updateTopVideo(#item.StatsVideoId)">
<img src="#Url.Content("~/Content/img/video-ph.png")" />
</a>
<p class="videoTitle">#item.Title</p>
</div>
</li>
}
And then I included this script in the view at the bottom:
<script>
var updateTopVideo = function (itemId) {
var url = '#Url.Content("~/Home/StatsVideo/")';
url = url + itemId;
$.get(url, "", callBack, "html");
};
var callBack = function (response) {
$('#top_video').html(response);
};
</script>
Finally, I added a method to my controller that would return the partial view needed for the video at the top of the screen:
public ActionResult StatsVideo(int Id)
{
IStatsVideo vid = StatsVideoService.GetEntity(new Lookup(TableStatsVideo.StatsVideoId, Id));
if (vid == null)
vid = StatsVideoService.GetEntityList(new Lookup(TableStatsVideo.IsDeleted, false)).OrderByDescending(x => x.DateCreated).FirstOrDefault();
return PartialView(vid);
}
This code should be fairly easy to understand. Basically, the onclick calls the first javascript method, which then calls the controller. The controller builds the partial view and returns it. The first javascript method passes it to the second javascript method which sets the html of the div "top_video" to be the returned partial view.
If anything doesn't make sense, or anyone's having trouble with this in the future, let me know and I'll do my best to offer some help.
I think there may be several confusing and inconsistent elements here.
First, you are returning a full view instead of a partial view. This reloads all containing elements, not just the part that is relevant to your partial view.
Second, you are using Url.Action, which only generates the url. I would recommend using Ajax.ActionLink, which allows you to do fully ajax calls, refreshing the content of your partial div and updating a target div element.
instead of:
<div class="videoList">
<a href ="#Url.Action("Videos", "Home", new { topVideo = item.StatsVideoId })">
<img src="#Url.Content("~/Content/img/video-ph.png")" />
</a>
<p class="videoTitle">#item.Title</p>
</div>
try the more modern solution
<div class="videoList">
#Ajax.ActionLink(
"Videos",
"Home",
"new { topVideo = item.StatsVideoId },
new AjaxOptions {
HttpMethod = "GET",
OnSuccess = "handleSuccess"
}
)
</div>
This way you can be very specific on what you want each link to do, and you can pass along multiple parameters as well as define a callback function. You can also use "UpdateTargetId" in your ajax options to load your newly refreshed partial view into a DOM element.
You can remove the around the image and just store the url generated by the Url.Action in a data-href attribute.
Then you can use the jquery load method to load the data:
$(".videolist>img").click(function () {
$("#content").load($(this).data("href"));
});
I created a fiddle that loads content dynamically here, so you can play with it if you want: http://jsfiddle.net/bTsLV/1/

Dropdownlist box in asp.mvc 2 and jquery [duplicate]

I have a code block in my MVC view as follows:
<%using (Ajax.BeginForm("MyAction", new { action = "MyAction", controller = "Home", id = ViewData["selected"].ToString() }, new AjaxOptions { UpdateTargetId = "Div1" }))
{ %>
<%=Html.DropDownList("ddl", ViewData["MyList"] as SelectList, new { onchange = "this.form.submit()" })%>
<%} %>
I want to set the value of ViewData["selected"] so that i can send it to the desired action.
Can anyone please suggest how can i do this?
thanks!
Instead of using a form, why not use a jQuery onChange event on your drop down?
$(document).ready(function() {
$("#ddl").change(function() {
var strSelected = "";
$("#ddl option:selected").each(function() {
strSelected += $(this)[0].value;
});
var url = "/Home/MyAction/" + strSelected;
$.post(url, function(data) {
// do something if necessary
});
});
});
ViewData is not the place to pass data back to the server side. Values of html input controls within form tag are conveniently available in action method. You can get these values either from various types of action method arguments (model, formcollection etc).
Here is a link to free asp.net mvc ebook tutorial. Is a good resource for asp.net mvc.
Found solution at this post it is just small chnge
Yes, that’s right – only change is replacing:
onchange = “this.form.submit();”
with:
onchange = “$(this.form).submit();”

Categories

Resources