Close Popup Windows MVC Controller - c#

I have a popup window opened when clicked a link on screen, the view that has the link is _DetailsSurvey. After clicking the link pop up window opens with the content of _EditSurvey view. At the end of _EditSurvey, I have button
<input type="submit" value="Save" />
I am using Ajax option and after button click I insert a row into Survey table if the modelstate is valid.
#using (Ajax.BeginForm("SubmitSurvey", "Blog", null, new AjaxOptions
{
UpdateTargetId = "context",
InsertionMode = System.Web.Mvc.Ajax.InsertionMode.Replace,
HttpMethod = "Post",
Url = "/Home/SubmitSurvey"
},
new { surveyItem = #Model }))
What i want to do is if the modelstate is valid after returning from SubmitSurvey method I want the pop up window to be closed.I use the following method to achieve this but it does not work.
Employee employee;
if (ModelState.IsValid)
{
int employeeId = surveyItem.EmployeeId;
int trainingId = surveyItem.TrainingId;
employee = _work.EmployeeRepository.GetSet().
FirstOrDefault(a => a.Id == employeeId);
var training = _work.TrainingRepository.GetSet().Where(a => a.EmployeeId == employeeId && a.Id == trainingId).ToList().ElementAt(0);
training.Survey = surveyItem.survey;
training.SurveyId = surveyItem.survey.Id;
/* _work.SurveyRepository.Add(surveyItem.survey);
_work.SurveyRepository.Save();*/
_work.TrainingRepository.UpdateAndSave(training);
_work.TrainingRepository.Save();
}
else
{
return PartialView("_EditSurvey", surveyItem);
}
return JavaScript("window.close()");
I create my popup links as follows
<tr>
<td class="view_detail_label">
Eğitim Adı
</td>
<td>
#Html.ActionLink(
training.Name.Name,
"AddSurvey",
new {
employeeId = Model.Id,
trainingId = training.Id
},
new {
#class = "addSurvey"
}
)
<div class="result" style="display:none;"></div>
</td>
</tr>
The called ajax code is as follows:
$(document).ready(function () {
$('.addSurvey').click(function () {
$.ajax({
url: this.href,
type: 'GET',
cache: false,
context: this,
success: function (result) {
$(this).next('.result').html(result).dialog({
autoOpen: true,
title: 'Anket',
width: 500,
height: 'auto',
modal: true
});
}
});
return false;
});
});
In my pop up view I am using previously shown Ajax BeginForm and below that I have the table where user inputs values of the survey. At the end I have the submit button.
<table id="context">
<tr>
<td>
<div class="editor-label">
#Html.LabelFor(model => model.survey.Context)
</div>
</td>
<td>
<div class="editor-field">
#Html.EditorFor(model => model.survey.Context)
#Html.ValidationMessageFor(model => model.survey.Context)
</div>
</td>
</tr>
<tr>
<td>
<input type="submit" value="Kaydet" />
</td>
</tr>
I show validation message next to each field if there is any problem with the provided input. If the model was valid I want to do either close the popup window.

It's a very bad idea to open a popup window for many reasons I won't explain here. I spend a very long time to find a solution I could consider as perfect (for me).
In my case, I prepare the view as a partial one (without html, header and body). Just the necessary items do create my functionality in a div.
Then I request my partial view using an ajax query after what I feed a div with my partial view string and I apply the JQuery dialog method to the div for my view to be displayed as a floating dialog box and I bind the OK button to an ajax post to send data to the server.
If you want to have the unobstrusive validation to works, you must parse the form with the validator.
I invite you to have a look to my framework, everything you need is available.
https://myprettycms.codeplex.com/SourceControl/latest#461106

Related

Delete btn in MVC.net

I might need an extra set of eyes but my delete btn is not working it does return a message but after clicking yes or ok it doesn't remove the data i wanted to delete basically nothing happens, I think I have an issue with the inventory.Id part. thank you, and i know this is not a good question for other users but i appreciate the help.
<tbody>
#foreach (var inventory in Model)
{
<tr>
<td>#Html.ActionLink(inventory.PartNumber, "Edit", "Inventory", new
{ id = inventory.Id }, null)</td>
<td>#inventory.PinNumber</td>
<td>#inventory.PartQuantity </td>
<td>#inventory.PartPrice </td>
<td>#inventory.PartDescrption</td>
<td> <button data-inventory-id="#inventory.Id" class="btn-link js-delete">Delete</button> </td>
</tr>
}
</tbody>
</table>
#section scripts
{
<script>
$(document).ready(function ()
{
$("#inventories").DataTable();
$("#inventories .js-delete").on("click", function () {
var button = $(this);
if (confirm("Are you sure you want to delete this Part Number?")) {
$.ajax({
url: "/inventory/" + button.attr("data-inventory-id"),
method: "DELETE",
success: function () {
button.parents("tr").remove();
}
});
}
});
});
</script>
}
this is my Controller for the Delete Action:
[HttpDelete]
public void DeleteInventory(int id)
{
var inventoryInDb = _context.Inventory.SingleOrDefault(c => c.Id == id);
_context.Inventory.Remove(inventoryInDb);
_context.SaveChanges();
}
I don't have an API in the Tutorial i am following He has an API but I didn't create one. I am trying to get around that.
Thank you.
How about using POST instead of DELETE as your ajax method? Or simply using the $.post method.
https://www.w3schools.com/jquery/ajax_post.asp
Most likely you did not create a DELETE method in your back-end API. To find out for sure, open Chrome's developer tools (making sure you're on the console tab) and then click your button. You will see an error message that says "Method DELETE is not found" or something similar.
If it says "method is not allowed" then that has to do with permissions (the user clicking the button does not have permission to access that API).
In controller:
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
Inventory inventory = _context.Inventory.Find(id);
if (inventory == null)
{
return HttpNotFound();
}
return View(inventory);
}
in index add delete btn, this is an ajax call to the delete btn its used with dataTables to render data faster..
{
"render": function (data, type, row, meta) {
return '<a class="btn btn-danger"
href ="#Url.Action("Delete", "Inventory")/' + row.Id + '">Delete</a>';
}
create a Delete view:
#model InventoryTracker.Models.Inventory //this has to be re-named to your naming
convention.
#using (Html.BeginForm())
{
#Html.AntiForgeryToken()
<div class="form-actions no-color">
<input type="submit" value="Delete" class="btn btn-primary" />
#Html.ActionLink("Cancel", "Index", null, new { #class = "btn btn-primary" })
</div>
}
}

how to upload a file using jquery + c#

I'm having issues trying to upload a docx file. First, when I click on "Choose File", the prompt opens up but the page reloads going to CheckInController/CheckIn url ( I thought that what you add in the Html.BeginForm is where your controller and method go when you click on submit ). Second thing is how do I know that the contents of the document are being sent to the server and not just the name or id?
https://jsfiddle.net/w6adx6za/1/
<div class="session-filter">
#using (Html.BeginForm("CheckIn", "CheckInController", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="select-filter-title"><strong>Select File</strong></div>
<table>
<tr>
<td><input name="fileResume" id="hiddenFileResume" type="file" value="" /><input type="submit" onclick="tested()"/></td>
</tr>
</table>
}
</div>
function tested(){
$.ajax({
cache: false,
type: "POST",
url: "/SummaryStatementProcessing/CheckInSummaryStatement",
data: data
});
}
public ActionResult CheckIn(HttpPostedFileBase fileResume){
//work in here
}
I don't need the page to go anywhere ( because this is actually in a dialog so it can close on submit, but currently it's reloading the page at the url above ). Currently I can't even get to the controller to check...
To do what you require, the easiest method is to send a FormData object in the request. However, you should ideally be hooking to the submit event of the form, not the click of the submit button, to stop the page redirecting.
You'll need to set the processData and contentType properties to false in the request. Also, the Action name does not appear to match your URL. You can fix that by using #Url.Action. The Action also needs the [HttpPost] attribute as that's the HTTP verb you're using in the AJAX request.
With all that said, try this:
<div class="session-filter">
#using (Html.BeginForm("CheckIn", "CheckInController", FormMethod.Post, new { enctype = "multipart/form-data" }))
{
<div class="select-filter-title"><strong>Select File</strong></div>
<table>
<tr>
<td>
<input name="fileResume" id="hiddenFileResume" type="file" value="" />
<input type="submit" />
</td>
</tr>
</table>
}
</div>
$('.session-filter form').submit(function(e) {
e.preventDefault();
$.ajax({
cache: false,
type: "POST",
url: '#Url.Action("CheckIn", "SummaryStatementProcessing")',
data: new FormData(this),
processData: false,
contentType: false,
});
}
[HttpPost]
public ActionResult CheckIn(HttpPostedFileBase fileResume)
{
// work in here
}
With the above code in place, you should then be able to work with the HttpPostedFileBase class in the Action.

Rendering a Partial View on button click in a div C# MVC 5

I have been following the answers on here but can't seem to get it to work. I think it's firing my function and calling my controller but it isn't rendering my partial view. Any help would be awesome.
Controller
public ActionResult Detail(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
User_Accounts user_accounts = db.User_Accounts.Find(id);
if (user_accounts == null)
{
return HttpNotFound();
}
return PartialView("_Detail", user_accounts);
}
HTML
<h2>Index</h2>
<div class="container left">
<div class="panel-default panelbox" style="position:static">
#*<p>
#Html.ActionLink("Create New", "Create")*#
#using (Html.BeginForm("Index", "Users", FormMethod.Get))
{
<p>
Type: #Html.DropDownList("userType", "All")
</p>
<p>
Last Name: #Html.TextBox("SearchString")
</p>
}
</div>
<div class="panel panel-default left">
<div class="panel-heading">
<label style="text-align:center">
User
</label>
</div>
<div class="table-responsive">
<table id="UserTable" class="table-bordered table leftPanel table-condensed">
#foreach (var item in Model)
{
<tr>
<td>
<button data-url='#Html.Action("Detail", "Users", new { id = item.user_id_IN })' id="js-reload-details">#Html.DisplayFor(modelItem => item.DisplayName)</button>
#*#Html.ActionLink(item.DisplayName, "Detail", new { id = item.user_id_IN }, new { onclick = "renderPartial();" })*#
</td>
</tr>
}
</table>
</div>
</div>
</div>
<div>
<label>Details</label>
<div id="detailsDiv"></div>
</div>
Script
<script>
$('.js-reload-details').click(function (evt) {
var $detailDiv = $('#detailsDiv'),
url = $(this).data('url');
$.get(url, function (data) {
$detailsDiv.replaceWith(data);
});
});
</script>
Let me know if you need anything else.
You cant use data-url='#Html.Action("Detail", "Users", new { id = item.user_id_IN })' in your button to generate a url. #Html.Action() is a method which calls you controller. What would be happening is that for each item in your model you would be hitting the Detail method of UsersController (performance must of been awful if you had a lot of items :) ).
Since you appear to need only the one url (/Users/Detail) I suggest you just store the ID in data to minimize the html generated. As noted in the other answers you also need to use a class name for the button to prevent invalid html, and I also suggest using type="button" because the default (depending on the browser) may be "submit" (you don't have a form so does not matter in this case, but its good practice to get into). There is also no real need to use #Html.DisplayFor() unless your using a custom DisplayTemplate or have a [DisplayFormat] attribute on the property.
Change the html to
<button type="button" data-id="#item.user_id_IN" class="js-reload-details">#item.DisplayName</button>
and the script to
var url = '#Url.Action("Detail", "Users");
$('.js-reload-details').click(function() {
$.get(url, { id: $(this).data('id') }, function (data) {
$('#detailsDiv').html(data);
});
});
Note you do not want to use replaceWith() in your case. .replaceWith() would replace the actual div <div id="detailsDiv"></div> with the html your method returned, so the next time a user clicked on this or any other button, the method would be called, but <div id="detailsDiv"></div> no longer exists and nothing would happen.
$('#detailsDiv').html('Hello world');
renders
<div id="detailsDiv">Hello world</div>
but
$('#detailsDiv').replaceWith('Hello world');
renders
Hello world
The id of your button id="js-reload-details"
Mistake this code is repeated in a foreach loop. which will cause multiple id's of the same name on your HTML page.
Your click event is on : '.js-reload-details'. which is a class:
so make your code like this:
#foreach (var item in Model)
{
<tr>
<td>
<button data-url='#Html.Action("Detail", "Users", new { id = item.user_id_IN })' class="js-reload-details">
#Html.DisplayFor(modelItem => item.DisplayName)
</button>
</td>
</tr>
}
One error I noticed in your jQuery is that you have $detailsDiv.replaceWith(data);
It should be $detailDiv according to your code: var detailDiv = $('#detailsDiv'); instead of $detailsDiv
<script>
$(document).ready(function(){
$('.js-reload-details').click(function (evt) {
evt.stopPropagation();
var detailDiv = $('#detailsDiv');
// TRY using the attr function:
var url = $(this).attr("data-url");
$.get(url, function (data) {
detailDiv.html(data);
});
});
});
</script>
UPDATE:
<script>
$(document).ready(function(){
$('.js-reload-details').click(function (evt) {
evt.stopPropagation();
var detailDiv = $('#detailsDiv');
// TRY using the attr function:
var url = $(this).attr("data-url");
$.get(url).success(function(result) {
detailDiv.html(result);
});
});
</script>
It's a good practice we use unique id's for our HTML elements. Since the following statement is going to be executed mulitple times
<button data-url='#Html.Action("Detail", "Users", new { id = item.user_id_IN })' id="js-reload-details">#Html.DisplayFor(modelItem => item.DisplayName)</button>
You will have multiple buttons with the same id. Instead of doing so, you could use a class.
<button data-url='#Html.Action("Detail", "Users", new { id = item.user_id_IN })' #class="js-reload-details">#Html.DisplayFor(modelItem => item.DisplayName)</button>
Then you have to correct your script:
// Now we bound the click event in all the elements that contain
// the .js-reload-details class
$('.js-reload-details').click(function (evt) {
var $detailDiv = $('#detailsDiv');
// Here was your the error
var url = $(this).attr("data-url");
$.get(url, function (data) {
$detailsDiv.replaceWith(data);
});
});

Refresh the view from JQuery ajax call

I am having a cshml view in which i am calling another view in a div as follows
<div class="family_name" id="DisplayPartilView">
<div class="content_part content_part2">
<h1 class="family_nameStyle">Additional Contacts <button id="AddEmergencyContact" jid="#ViewData["offerId"].ToString()" class="btn highlight" data-dismiss="modal" >
+</button></h1>
<h6> </h6>
<div id="listChildContactAuthorisationsCI" class="table_form">
<table style="width: 640px;" id="CIAuthtable">
<tr>
<td>Contact Name</td>
<td title="This contact is authorised to drop off and collect this child.">Collection</td>
<td title="This contact is an emergency contact for the child.">Emergency</td>
<td title="This contact can authorise the child to participate in centre excursions.">Excursion</td>
<td title="This contact can authorised the administering of medication to the child.">Medical</td>
</tr>
#if (Model.ChildContactAuthorisations != null)
{
#Html.EditorFor(x => x.ChildContactAuthorisations)
}
</table>
</div>
</div>
</div>
This view is shared among other view and so it is in Shared/Editor Template folder.
I am using the ajax from another page (addcontact) as follows
$.ajax({
data: $.parseJSON('{"Id" : "' + EntityId + '"}'),
type: 'POST',
url: '#(Url.Action("GetAdditionalContacts", "QkEnrolment"))',
success: function (result) {
alert(result.outerHTML);
$('div#listChildContactAuthorisationsCI').html(result);
},
error: function () {
alert('Error');
}
});
The control is going to the controller following controller function after adding a contact
public ActionResult GetAdditionalContacts(int Id)
{
Id = Convert.ToInt32(TempData["offerId"]);
User user = DependencyResolver.Current.GetService<ICrud<User>>().Where(x => x.Username == WebSiteContext.Current.UserId).FirstOrDefault();
var offer = _offerRepo.Get(Id);
var child = _childRepo.Get(offer.Child.Id);
var childStubContactAuthorisations = child.GetContactAuthorisations().ToList();
List<Section_ChildContactAuthorisation> ChildContactAuthorisations1 = GetAggregateChildContactAuthorisations(user, childStubContactAuthorisations);
TempData["offerId"] = Id;
return Json(ChildContactAuthorisations1, JsonRequestBehavior.AllowGet);
}
But i want to update the view with the model(which contains newly added contact) return from this above controller function. But the view is not updating.
Can anybody please help me in this
Thanks,
Vidya
Now you are setting json as html in your $('div#listChildContactAuthorisationsCI') you will have to iterate through the returned json and create appropriate html from those values and then add these to your $('div#listChildContactAuthorisationsCI').html(data)
Example:
data = '';
for(i=0;i<result.length;i++) {
data += '<li>' + result.whateverIsInhere + '</li>';
}
If you don't know what's in your json use Console.Log(result) then use the developer tools (F12 in chrome) and see what's inside.

Form default value not wanted after ajax submission

I have this script, what it intends to do is: in a view with a list of contacts, each one with a edit link whenever you click on one of these links it displays an edit form in a partial view (there's only one div in the parent view for holding it) just below the clicked contact, for that it does a get ajax call to the server and gets the information for that contact. After submitting, via ajax as well, it refreshes the list.
Everything seems to work fine, but if I edit a contact, after the list being refreshed I try to open again the form on the same contact and the information is the same as it was before being edited. Although debugging I see the list for the server is correct (and so is the display in the list, it's only wrong in the form)
Thing is that in chrome developer tool I can see the form with some "default values" set to the previous stuff. I didn't know about them till now and I don't know how to get rid of them, because to my understanding I'm making a get call to the server, anyway I have tried this
document.getElementById("editForm").reset();
with no luck.
Thanks
The script
(function ($) {
var editContainer = $(document.getElementById('editContainer'));
$('#editContainer').on('submit', '#editForm', ajaxEditCall);
$('a.edit').on("click", displayEditForm);
function displayEditForm(e) {
var clickedElement = $(this).parent(),
url = editContainer.data('amp-edit-url');
$.get(url, {
id: parseInt(this.id, 10)
}, function (result) {
editContainer.html(result);
$.validator.unobtrusive.parse(editContainer);
// Display edit form just below the "item" clicked
if (editContainer.is(":visible")) {
editContainer.slideToggle(300, function () {
editContainer.appendTo(clickedElement);
editContainer.slideToggle(300);
});
} else {
editContainer.appendTo(clickedElement);
editContainer.slideToggle(300);
}
}, "html");
e.preventDefault();
}
function ajaxEditCall(e) {
e.preventDefault();
//if ($('#editForm').valid()) {
var list = $(document.getElementById('list'));
$.ajax({
url: this.action,
type: this.method,
data: $(this).serialize(),
success: function (result) {
if (result.passedValidation == true) {
$.get(result.action, function (partial) {
document.getElementById("editForm").reset();
list.html(partial);
$('a.edit').on("click", displayEditForm);
$('#editForm').slideUp(300);
setTimeout(function () {
list.effect("highlight", {}, 3000);
}, 1000);
});
} else {
$(document).scrollTop(0);
editContainer.html(result);
$.validator.unobtrusive.parse('#editForm');
}
}
});
//} return false;
}
}(jQuery));
And the view in case is relevant
#model ContactListViewModel
#{
ViewBag.Title = " My Contacts";
}
<div id="myContacts">
<h2>My Contacts</h2>
<div id="editContainer" data-amp-edit-url="#Url.Action("Edit", "Contacts")" class="initiallyHidden"></div>
<div id="list">
#{ Html.RenderPartial("_ContactList", Model); }
</div>
<div id="dialog" data-amp-del-url="#Url.Action("Delete", "Contacts")" title="Confirmation Required">
<p>Are you sure you want to delete this Contact?</p>
</div>
</div>
#section Foot
{
<script src="~/Scripts/AMPContacts.js"></script>
<script src="~/Scripts/conditional-validation.js"></script>
<script src="~/Scripts/Placeholders.min.js"></script>
}
Well that's obviously the parent view, the partial one is just a bunch of fields, I remove most of them to avoid increase the already long post
#model AddContactViewModel
#using (Html.BeginForm("Edit", "Contacts", FormMethod.Post, new { #id = "editForm", #class = "addTab" }))
{
#Html.ValidationSummary(true, "Please correct the errors and try again.")
#Html.HiddenFor(m => m.Id)
#Html.HiddenFor(m => m.OwnedItemId)
#Html.HiddenFor(m => m.AddressId)
<div id="editContactDetails">
<div>
#Html.DisplayFor(m => m.PlanName)
</div>
<div>
#Html.DropDownListFor(m => m.Title, Model.TitleList, "Title")
</div>
<div>
#Html.EditorFor(m => m.FirstName, new { #id="editFirstName", data_placeholders_focus = "false", placeholder = ViewData.ModelMetadata.Watermark })
#Html.ValidationMessageFor(m => m.FirstName)
</div>
// And so on....
<div class="addDEC">
<input class="addDECButton" type="submit" value="Save" />
</div>
}
I ran into this problem with a site I was working on. You'll need to disable your ajax caching:
//Disbable cache for all jQuery AJAX requests
$.ajaxSetup({ cache: false });
That will do it for all ajax calls, so you may only want to do that on certain pages, depending on your usage.

Categories

Resources