mvc view insert into wrong "DOM" telerik window - asp.net-mvc-3

Apologies in advance if this becomes a very long question...
Background Info
I have an MVC 3 application, using Telerik components and this particular issue is specific (I think) to the Window() component.
From my main view (Index.cshtml) I executing an ajax request to return a partial view which is what I am populating the contents of my window with. This is the jquery which is executing the request:
var url = '#Url.Action("GetAddPart", "Jobs")';
var window = $("#Window").data("tWindow");
var data = $("#indexForm").serialize();
window.ajaxRequest(url, data);
window.center().open();
the controller action is:
[HttpGet]
public ActionResult GetAddPart(MDTCompletedJobM model)
{
// show the AddPart window
//TryUpdateModel<MDTCompletedJobM>(model);
model.ActionTakenList = ActionTakenList;
model.ProblemTypes = ActualProblemList;
var addPartM = new MDTAddPartM() { CompletedJobM = model };
return PartialView(string.Concat(ViewDefaultUrl, "AddPart.cshtml"), addPartM);
}
this opens my window hunky dory.
in my partial view i have a form with two or three fields and an "Add", "Cancel button. For the sake of brevity I'll just show what I think are the relevant parts of the partial view, but i can produce the entire view if need be:
<div id="resultDiv">
#using (Html.BeginForm("AddPart", "Jobs", FormMethod.Post, new { id = "addPartForm", name = "addPartForm" }))
{
** layout components removed from here **
<input type="button" value="Add" class="t-button" id="btnAdd"/>
<input type="button" value="Cancel" class="t-button" id="btnCancel"/>
<p />
<div id="progressdiv">
</div>
}
</div>
is the "top level" tag in the partial view.
my jquery to handle the Cancel button is:
$("#btnCancel").click(function () {
var window = $("#Window").data("tWindow");
window.close();
});
In my main view, I have a submit button, which when completed effectively reders the main view "disabled" or displays errors. The action for this submit button returns the main view:
Controller's action snippet:
if (ViewData["DoPayJobWarningStr"] == null)
return RedirectToAction("GetAutoDispatchJob", new { autoDispatchJob = model.JobReferenceNumber});
else
return View(string.Concat(ViewDefaultUrl, "Index.cshtml"), tmpModel);
My actual problem
For a specific example I am using, I am expecting ViewData["DoPayJobWarningStr"] NOT to be null, there the return View(...) will be executed.
if I execute this action (for the submit button) without opening the window, my view returns correctly and the page is updated to show the warning message. However, if I open the window first then execute the submit button, the View isn't updated on the page, but seems to be placed into the Window's html. ie, if I hit the submit button (nothing happens), then click on the button which opens the Telerik window, I briefly see the View returned by the submit Action being shown before it's updated with what the Partial View should contain. I don't understand at all how or why the returned View is being placed there?
Things I've tried:
Commenting out the ajax request (window.ajaxRequest(url, data);) fixes the issue (even though I obviously have a blank partial view to look at).
Not making the Partial View a "Form" doesnt' work
No matter how I "close" the window, the view is still placed within there. eg clicking the x in the top right hand corner
Using Firebug, the HTML after the submit button is clicked is not updated.
Rather than using "window.ajaxRequest(url, data)", i've also tried (with the same result):
$.ajax({
type: "GET",
cache: false,
url: url,
data: $("#indexForm").serialize(),
success: function (data) {
var window = $("#Window").data("tWindow");
window.content(data);
window.center().open();
$("#progress").html('')
},
error: function (e) {
alert(e.Message);
}
});
Is it all possible to determine what I am doing wrong? Is it the ajax request? Only assuming that because removing it fixes the issue, but there might be more to it than that.
Thanks and of course if you need more info, ask :)
Thanks
EDIT
After suggestions from 3nigma, this is what I've updated to (still no luck)...
Telerik window definition:
#{Html.Telerik().Window()
.Name("Window")
.Title("Add Part")
.Draggable(true)
.Modal(true)
.Width(400)
.Visible(false)
.Height(270)
.ClientEvents(e => e.OnOpen("onWindowOpen"))
.Render();
}
jquery function which is an OnClick event for a button:
function AddBtnClicked() {
$("#Window").data('tWindow').center().open();
}
the onWindowOpen event:
function onWindowOpen(e) {
//e.preventDefault();
var data = #Html.Raw(Json.Encode(Model));
var d2 = $.toJSON(data);
$.ajax({
type: 'GET',
url: '#Url.Action("GetAddPart", "Jobs")',
data: d2,
contentType: 'application/json',
success: function (data) {
var window = $("#Window").data("tWindow");
window.content(data);
$("#progress").html('');
},
error: function (xhtr, e, e2) {
alert(e +'\n' + xhtr.responseText);
}
});
};

OK.
Issue was related to this line in the Partial View:
<script src="#Url.Content("~/Scripts/ValidationJScript.js")" type="text/javascript"></script>
As soon as I took that out, it all works. Not sure why that was causing the issue - I don't think it had been previously been loaded but maybe it had which was causing the problem.
Thanks to 3nigma for your thoughts, nonetheless!

Related

How to present partial view in jQuery dialog without navigating to another page

I have two controllers, A and B. A is responsible for representing some data in a grid view. Assume I have a button called "ShowInfo" which brings additional info about the selected record. And to retrieve the info about the selected record is the job of controller B.
The info is so little that it'd take just a tiny place in the corner if I navigate to another view. So I thought I'd rather bring that info inside a jQuery dialog without navigating to anywhere. But I'm a bit confused as to how to do it.
Here's the action method in controller B that is responsible for providing that info in a partial view.
public class BController:Controller{
public ActionResult GetInfo(int recordID){
RecordInfo info=RecordsRepository.GetRecordInfoById(recordID);
return PartialView(viewName:"RecordInfo",model:info);
}
}
I don't know, maybe the action method needs to different. Maybe I should return JSON instead of Partial view, but anyway, how do I do that?
You can use the jquery .get or .load methods. For example, to replace the contents of <div id="SomeElement"></div> with the partial view returned by GetInfo()
$('#ShowInfo').click(function() {
var url = '#Url.Action("GetInfo", "B")';
var ID = someValue; // the value to pass to the GetInfo method
$.get(url, { recordID: ID }, function(data) {
$('#someElement').html(data);
});
});
You can use Jquery ajax to achieve this.
Wrtire jquery ajax on the view page and call the partial view action from ajax.
receive the result in html format and replace it in the dialog box.
Put following code on main view page(ShowInfo button page)
$(document).ready(function(){
$("#ShowInfo").on("click",function(){ ///give id to showinfo button and attr data-id is record id
var id=$(this).attr("data-id");
$.ajax({
type: "POST",
url: "B/GetInfo",
data: JSON.stringify({ recordID: id }),
dataType: "html",
success: function (html)
{
////put the html response in dialog box
}
});
})
});

Jquery Mobile submit button not working after page refresh

I have a single page mark-up with popup divs that contain forms that the user can use to update his/her account information. After form submission the popup closes and the page refreshes showing the updated information that is located within a li (this seems to be working). The problem is, if the user goes back and tries to update again the button within the popup is not submitting.
Thanks in advance for any suggestions!!!
Javascript
$('#updateadmin').click(function() {
var admin = $('#adminform').serializeArray();
/*alert(admin);*/
$.ajax({
type: "POST",
url: 'adminupdate.php',
data: admin,
success: function(data) {
if(data=="success") {
$('#admindiv').popup('close');
$.mobile.changePage('companyinfo.php', {
allowSamePageTransition: true,
transition: 'none',
reloadPage: true,
changeHash: false
});
} else {
$('#adminupdatestatus').html(data).css({color: "red"}).fadeIn(1000);
}
}
});
return false;
});
It sounds like the #updateadmin link/button is located on the page that gets reloaded, if this is the case then you should delegate your event handler so it affects matching elements in the DOM for all time, not just when the code runs.
You would change this:
$('#updateadmin').click(function() {
to this:
$(document).on("click", "#updateadmin", function() {
This works because you're now attaching the event handler to the document element which always exists. When events reach the document element they are checked to see if the element on which they originally fired matches the selector we put as the second argument for .on().
Documentation for .on(): http://api.jquery.com/on

MVC Action getting called twice?

I am using Asp.Net MVC3, for a project.
In one of the page, I am using MS Charts. In View I have a Image which shows the chart as follows:
<img src="#Url.Action("RenderCharts", "Home", new
{
XAxisColor = ViewBag.XAxisColor,
YAxisColor = ViewBag.YAxisColor,
})" alt="Charts" runat="server" />
I have 2 CheckBoxes, which is used to change Chart Axes Colors. When the checkbox is clicked, page is submitted and checkbox status is stored and based on that Chart is rendered:
bool XAxisColor = (#ViewBag.XAxisColor) ?? true;
bool YAxisColor = #ViewBag.YAxisColor ?? false;
#Html.CheckBox("chkXAxisColor", XAxisColor, new { #Id = "chkXAxisColor",
onClick = "this.form.submit();" })
X Axis Color
#Html.CheckBox("chkYAxisColor", YAxisColor, new { #Id = "chkScatter",
onClick = "this.form.submit();" })
Y Axis Color
When first time the page is loaded, RenderCharts() Action gets called and Chart is rendered.
But when i Click any of the CheckBox, RenderCharts() Action gets called twice.
I could not understand this issue. I have created a sample Application which can be downloaded from here https://www.dropbox.com/s/ig8gi3xh4cx245j/MVC_Test.zip
Any help would be appreciated. Thanks in advance.
This appears to be something to do with Internet Explorer. Using your sample application, everything works fine in both Google Chrome and Firefox, but when using IE9, there are two Action requests on a postback.
Using the F12 developer tools on the network tab, it shows an initial request to RenderCharts which appeared to be aborted:
The (aborted) line in the middle is, I suspect, the additional request you're seeing. Why this happens, I don't know!
Finally got the answer. The problem was
runat="server"
in the Img tag.
Removing runat fixed the issue.
I can eliminate the IE issue in the following manner by simply using a bit of JQuery instead. A few possible advantages...
It eliminates the cross-browser issue.
It is an unobtrusive approach (not mixing javascript and HTML in the view).
You can update the image via ajax.
Create a new file in the scripts folder (e.g. "chart.js") which will simply attach an anonymous function to the the click events of your checkboxes from the document ready function. You would obviously need to include the script reference in your page as well:
$(document).ready(function () {
// Attach a function to the click event of both checkboxes
$("#chkXAxisColor,#chkScatter").click(function () {
// Make an ajax request and send the current checkbox values.
$.ajax({
url: "/Home/RenderCharts",
type: "GET",
cache: false,
data: {
XAxisColor: $("#chkXAxisColor").attr("checked"),
YAxisColor: $("#chkScatter").attr("checked")
},
success: function (result) {
alert(result);
$("#chart").attr("src", result);
}
});
});
});
Best of all, you get to eliminate the javascript from your view :)
...
<div style="margin: 2px 0 2px 0">
#Html.CheckBox("chkXAxisColor", XAxisColor, new { #Id = "chkXAxisColor" })
X Axis Color
#Html.CheckBox("chkYAxisColor", YAxisColor, new { #Id = "chkScatter" })
Y Axis Color
</div>
...
This is of course a very basic example which does eliminate the IE issue but you could get fancier from there in terms of how you update the image + show a loading gif, etc with only a few more lines.
Hopefully it is a workable solution for you!

Edit pop up box for a grid design

I am writing a MVC3 project. Right now I have a table which has column with Data as actionLinks as:
<td style="color: Black; background-color: Bisque; text-align: center; width: 410px">
#Html.ActionLink(#item.LookUp_NameString, "EditPartial", "Capitation", new { id = item.CAPITATION_RATE_ID }, new { #class = "actionLink" })
</td>
EditPartial as the name suggests is a partial view, which I need to be opened as a pop-up menu so that user can edit the details of the object, save it and we can come back to original page.
I have tried the render partial, but can't get it to pass the id value dynamically.
This is for edit functionality of my grid. What will be the best way to implement this?
If you want to open the result of EditPartial Action method in a model popup, you need some model popup code for that.
jQuery UI is one option. http://jqueryui.com/demos/dialog/
1) Include jQuery UI reference in your page,
2) Add the below script to your page which will convert your normal link to a model popup
<script type="text/javascript">
$(function(){
$(".actionLink").click(function (e) {
var url = this.href;
var dialog = $("#dialog");
if ($("#dialog").length == 0) {
dialog = $('<div id="dialog" style="display:hidden"></div>').appendTo('body');
}
dialog.load(
url,
{}, // omit this param object to issue a GET request instead a POST request, otherwise you may provide post parameters within the object
function (responseText, textStatus, XMLHttpRequest) {
dialog.dialog({
close: function (event, ui) {
dialog.remove();
},
modal: true,
width: 460, resizable: false
});
}
);
return false;
});
});
</script>
From your action result, you can return whatever markup you want to show in the Model popup. Mostly you will be returning a View. If you want to show a partial View,If it is an ajax request and show the normal view if it is a normal request, you can check the Request.IsAjaxRequest method to do that.
public ActionResult EditPartial(int id)
{
CustomerViewModel objCustomer=GetCustomer(id);
if(Request.IsAjaxRequest())
{
return View("Partial/Edit",objCustomer);
}
return View(objCustomer);
}
Assuming you have 2 views present to show your normal page and partial page (for model popup)
I prefer to name my action method as Edit instead of EditPartial, because it is handling both requests (ajax and normal)

I need help using jquery to post info from Pop Up to an MVC 3 Controller action

So I have a view that allows users to Approve or Reject items listed on the page. When approved, I simply use the #Ajax.ActionLink to post to the appropriate controller action. When the user Rejects an item, the user is required to enter a reason for the rejection. I'm found code on the internet that gave me a popup dialog and added a textbox and OK/Cancel buttons. I can capture the input from the user and show it in an alert, but now I need to complete it and I'm not sure how.
1st - I need add functionality to pass to my jquery link handler, the ID associated with the Item being rejected.
2nd - I need a way to call my Controller Action from the jquery.
Here is the code I have up to this point.
My link is simply an 'a' tag. I can't see to post the code for this without removing the <>
a href="#dialog" name="modal" Reject a
My script handles this here
$(document).ready(function () {
//select all the a tag with name equal to modal
$('a[name=modal]').click(function (e) {
//Cancel the link behavior
e.preventDefault();
//Get the A tag
var id = $(this).attr('href');
//Get the screen height and width
var maskHeight = $(document).height();
var maskWidth = $(window).width();
//Set heigth and width to mask to fill up the whole screen
$('#mask').css({ 'width': maskWidth, 'height': maskHeight });
//transition effect
$('#mask').fadeIn(1000);
$('#mask').fadeTo("slow", 0.8);
//Get the window height and width
var winH = $(window).height();
var winW = $(window).width();
//Set the popup window to center
$(id).css('top', winH / 2 - $(id).height() / 2);
$(id).css('left', winW / 2 - $(id).width() / 2);
//transition effect
$(id).val('');
$(id).fadeIn(2000);
});
Here is my pop up dialog and the mask that grays out the screen when the dialog is opened.
<div id="boxes">
<div id="dialog" class="window">
Enter the reason for rejection:</br>
<textarea class="multiline" id="rejectreason" rows="10" cols="20"></textarea><br/>
<div style="margin-left: 120px"><input type="button" value="OK" class="ok" style="width:70px"/> <input type="button" value="Cancel" style="width:70px" class="close"/>
</div>
</div>
<!-- Mask to cover the whole screen -->
<div id="mask"></div>
</div>
It could be that I'm going about this completely wrong, but it's all I could find on line and pieced it all together from there. As this is my first experience with jquery and MVC, I'm struggling a bit here. Any help would be greatly appreciated.
Thanks
UPDATE
OK, so I added a data-id attribute to my link that allows me to get the ID of the link clicked. I tested it using this code and it works.
var iD = $(this).attr('data-id');
I now need to pass this value to my dialog so I can then retrieve it again when the OK button on the dialog is clicked. I can set a hidden field on the page if necessary and retrieve it from there.
Here is some code to get you on the right path...
jQuery Ajax:
$(document).ready(function () {
$("#InputButtonId").click(function () {
$.ajax({
url: '#Url.Action("SomeAction", "Controller")',
type: 'POST',
data: { id: $("#hidden").val(), reason: $("#rejectreason").html },
dataType: "json",
beforeSend: function () {
},
success: function (result) {
// Do action if success
},
error: function (result) {
// Do action if error
}
});
return false;
});
});
And the controller action:
[HttpPost]
public JsonResult SomeAction(string id, string reason)
{
//Perform Actions
return Json(new
{
value1 = value1,
value2 = value2
}, JsonRequestBehavior.AllowGet);
}
Hope this helps.

Resources