Pop-up dialog using jQuery issue - asp.net

Hi I have a problem with my page. I have one view page and 2 forms in the same page.
The problem is that I have a main form and another form which is a shown by JQuery. My Problem is when I open the dialog box, submit its form and return the view, the dialog box diappears. I don't know how to return a result which will still show the opened the dialog box.
I need your help on this please!
Below are the codes I used in my application.
.CSTHML Forms
#using (Html.BeginForm("Login2", "Account", FormMethod.Post, new { #id = "loginForm" }))
{
<a id="submitlink" href="#" class="button button-large">Sign In</a>
}
// This is the pop-up dialog box
#using (Html.BeginForm("TroubleSubmit", "Account", FormMethod.Post, new { #id = "troubleSubmitForm" }))
{
<a id="troubleSubmitLink" href="#" class="button">OK</a>
}
JQUERY
$('a#submitlink').click(function () {
$('#loginForm').submit();
});
$('a#troubleSubmitlink').click(function () {
$('#troubleSubmitForm').submit();
});
Below is the code of my controller action to handle the dialog form submit:
public ActionResult SignInTrouble(some parameter...)
{
// some operation and validation here
return View(); // ??? What view will I return? When I return "Login" it will reload the page and close the dialog box.
}
Again, how do I return the View that will still display the dialog box

You're submitting your form in a traditional (non-AJAX) manner so the page will reload. So you'll need to post in an AJAX way.
$("#submitlink").on("click", function () {
var loginForm = $("#loginForm");
$.ajax({
url: loginForm.attr("action"),
type: "post",
data: loginForm.serialize(),
})
.done(function(result) {
// do something with the returned response
});
});
The successful response is handled with .done() but what you return and how you handle the result is up to you. Simplest option is to return a partial view so it's just a html fragment to insert into an existing div container.
.done(function(result) {
$("#someDiv").html(result);
});
I often return JSON with the view rendered as an html string { status: 0, message: "Success", html: "<div>..." }. You could omit the html fragment from the JSON if you just need a simple YES/NO.
public ActionResult SignInTrouble(some parameter...)
{
// some operation and validation here
return Json({
status: 1,
message: "Validation Error"
});
}
Then you get a few more possibilities with your response
.done(function(result) {
var status = result.status;
var message = result.message;
if (status == 0) {
// OK
} else {
// ERROR
}
$("#messageDiv").text(message);
}

It simply due to the page is reloaded, you must use ajax form in this case, so it'll only process the action of ajax form and then return the result to the form without reload the page
#Ajax.BeginForm("TroubleSubmit","Account", new AjaxOptions(){ ...... })

Related

Editing a viewmodel's member via button without submit

I'm using Asp Net Core 3.1 and am working on developing admin controls to approve and delete submitted images that are awaiting approval. The functionality that I am developing and am stuck on is as follows: I have created a grid of images waiting approval (using a loop in razor) and would like to click a button to "approve" that image via the logic I have written in my controller. How would I pass that data to the controller without refreshing the page?
View Model
public class ImageManagerViewModel
{
public List<ListingImages> Images;
public List<Tuple<long, string>> ListingNames;
}
Controller
public class AdminController : Controller
{
public ActionResult ApproveImage(int listingID, long imageID, bool isFeatured)
{
....
}
}
Client-side
#foreach (ListingImages row in Model.Images)
{
....
<div class="d-flex card-footer">
<a a class="btn btn-success btn-space"
href="#Url.Action("ApproveImage", "Admin", new { listingID = row.ListingId, imageID = row.ImageId, isFeatured = false})" role="button">Approve</a>
}
As VDWWD described, you wanna use ajax to achieve this behavior.
I made a quick sample for your code (I didn't have the ability to test it atm though).
Your loop (you can also use hidden input fields to track the ids of every single item):
#foreach (ListingImages row in Model.Images)
{
...
<span class="imageId">#(row.ImageId)</span>
<span class="listingId">#(row.ListingId)</span>
<input type="button" class="btn btn-success approveBtn">Approve</button>
}
JQuery code in the script section:
<script>
$(document).on("click",
".approveBtn",
function () {
var imageId = $(this).closest(".imageId").text();
var listingId = $(this).closest(".listingId").text();
$.ajax({
url: "/Admin/ApproveImage",
type: "POST",
data: {
__RequestVerificationToken: $('input[name=__RequestVerificationToken]').val(),
listingID : listingId,
imageID: imageId,
isFeatured: false
},
timeout: 5000,
success: function(results) {
// result action
},
contentType: "application/x-www-form-urlencoded; charset=utf-8"
})
.fail(function (xhr, textStatus, errorThrown) {
// error handling
});
});
</script>
Hints:
If you use one, include the antiforgery token in the request as shown in the sample.
You can also send the payload as JSON. You then need to edit the content type and use JSON.stringify in the data section to convert the payload.

Razor #Html.ActionLink not getting passed control value correctly

I am new to Razor. I am making good progress on this project but have hit a major road block with something that would seem to be easy. I have read a lot of posts about how to pass the value of a control as a parameter to a controller in order to redirect to a new view. The problem is that I either get the value passed to the controller but can't redirect OR I redirect and the parameter is not passed.
This is my latest attempt. I was hoping to pass the return of GetSelectedEmail to the controller (the value of "selectedEmail"). I can see that the Javascript is getting the correct value and the controller is being called, but the value is always NULL.
#Html.ActionLink("Get Scoring Report...", "History", "Student", null, new { onclick = "return GetSelectedEmail();" });
<select id="selectedEmail" name="align">
#foreach( var s in Model.Students )
{
<option id=#s.Email>#s.Email</option>
}
</select>
function GetSelectedEmail() {
var str = "new {email=" + $("#selectedEmail").val() + "}";
return str;
}
The controller...
public ActionResult History(string email, string sort)
{
string localEmail="";
if ( email == null || email == "" )
localEmail = AccountProfile.CurrentUser.UserName;
...
I have also tried to call the controller with Ajax like below. The controller does get the "selectedEmail" parameter but the page never redirects. I just does nothing. I tried both having the action link with the link parameters or not (show below).
#Html.ActionLink("Get Scoring Report...", "", "", null, new { onclick = "return GetSelectedEmail();" });
<select id="selectedEmail" name="align">
#foreach( var s in Model.Students )
{
<option id=#s.Email>#s.Email</option>
}
</select>
function GetSelectedEmail() {
$.ajax({
url: '/Student/History',
data: { email: $("#selectedEmail").val(), sort: "CaseID" },
type: 'POST',
dataType: 'json',
});
return true;
}
Any ideas?
Your first approach is not actually doing the redirection. ( also it calls a different method, which i am assuming a copy paste mistake)
Your current code is not passing the values because it is a link and when it is clicked, it is supposed to navigate to that url, which is exactly what it is doing.
I just changed the code to use unobtrusive javascript. Replaced the onclick with an id for the link
#Html.ActionLink("Get Scoring Report", "History", "Student", null, new { id="score" });
and when the click happens on this link, read the value of the select element and navigate to the second action method by setting the location.href property value
$(function () {
$("#score").click(function(e) {
e.preventDefault(); // Stop the normal redirection
var url = $(this).attr("href"); //Get the url to action method
url += "?email=" + $("#selectedEmail").val(); //append querystrings
window.location.href = url; // redirect to that url
});
});
For what I needed the solution was simple.
Show Student Scores
<select id="selectedEmail" name="align">
#foreach( var s in Model.Students )
{
<option id="#s.Email">#s.LastName,#s.FirstName</option>
}
</select>
And the Javascript magic...
function GetScoreHistory() {
var emailVal = $('#selectedEmail').find('option:selected').attr('id');
var url = '#Url.Action("History", "Student")';
url += "?email=" + escape(emailVal);
window.location.href = url;
}
The controller was called exactly how I needed it to be called.

Meteor: Most "Meteoric" way to clear form fields

I'm working on an example CRUD application with Meteor.js and am not sure how best to empty out the fields of a form. I need it in two places: when the Submit button is clicked, and when the Cancel button is clicked.
I implemented it this way by creating a utility function called clearFormFields() that just uses jQuery to empty their contents, but it doesn't feel as "Meteoric" as it should; I feel it should be scoped better so it doesn't have a global visibility. What am I doing wrong?
function clearFormFields() {
$("#description").val("");
$("#priority").val("");
}
Template.todoNew.events({
'click #cancel': function(event) {
event.preventDefault();
Session.set('editing', false);
clearFormFields();
},
'submit form': function(event) {
event.preventDefault();
var theDocument = {
description: event.target.description.value,
priority: event.target.priority.value
};
if (Session.get("editing")) {
Meteor.call("updateTodo", theDocument, Session.get('theDocumentId'))
}
else {
Meteor.call("insertTodo", theDocument);
}
Session.set('editing', false);
clearFormFields();
/* Could do this twice but hate the code duplication.
description: event.target.description.value = "";
priority: event.target.priority.value = "";
*/
}
});
You could use the native reset method of the DOM form node ?
"submit form":function(event,template){
event.preventDefault();
// ...
template.find("form").reset();
}
http://www.w3schools.com/jsref/met_form_reset.asp
The DOM object that originated the event can be accessed and reset from through event.target.reset();
"submit form":function(event){
event.preventDefault();
//...
event.target.reset();
}
http://docs.meteor.com/#/full/eventmaps

Index ViewResult not re-rendering after callback from ajax call

I'm trying to callback into my ViewResult Index() controller action from an ajax call to update the page contents based on a dropdown select but my view is not re-updating (re-rendering).
I have set breakpoints and the index() action in the controller is being executed as invoked from the ajax 'get' and the model is being passed off to the view (breakpoints are being hit in the view as well).
View:
#* Contains code to build a webgrid and display data based on the model passed in... *#
#* Contains a couple of dropdowns for filtering *#
#*
Catch the select event from a dropdown and call back into the view to re-update page contents
for filter requests.
*#
<script type="text/javascript">
$("select").multiselect({
click: function (event, ui) {
$.ajax(
{ type: "GET",
url: '#Url.Action("Index","Data")',
data: { FilterRequest: (ui.checked ? 'checked' : 'unchecked') },
success: function () {
alert('hello again');
}
})
}
});
</script>
Controller:
// GET: /Data/
public ViewResult Index(string FilterRequest)
{
IList<DataModel> dataResult;
if (FilterRequest == null)
{ // Not a filter request so just update grid with full contents
dataResult = db.DataObjs.OrderByDescending(x => x.id).ToList();
}
else
{ // Filter request so update grid with filtered data
dataResult = db.DataObjs.Where(/*Build some filtered stuff here*/).OrderByDescending(x => x.id).ToList();
}
// Build some sub totals based on the resultset from above result set to display
// Other business logic number mashing here to display in other grids on the same view
return View(dataResult);
}
You're not doing anything with the response of the $.ajax call.
Something like this:
$.ajax(
{
type: 'GET',
url: '#Url.Action("Index","Data")',
data: { FilterRequest: (ui.checked ? 'checked' : 'unchecked') },
dataType: 'html',
success: function (html) {
$('#somecontainer').html(html);
}
});
Also, you can't return a full view (e.g a HTML page) from your action method - you need to either return a PartialView, or a JsonResult which you can iterate over and manualy bind the contents.
For a partial view, you need something like this:
return PartialView(dataResult);
It all depends on what your trying to re-render. If the HTML you require to re-render is complex, then use a partial view. If it's simply a bunch of data that is to be shoved into an input element (e.g a dropdown list), you should save on the HTTP payload over the wire and use JsonResult.

How to trigger a validation on only Button Click or Input:Submit

I am using Update Panel in my asp page and I am doing JQuery Validation on Asynchronous Postback...
I just want to validate my form on only button clicks or submits...
My problem is..all my buttons are in different formviews and won't load at a time...that's why I am unable to take the button id's and use the click events..here is my code..
Sys.WebForms.PageRequestManager.getInstance().add_initializeRequest(ValidateMyForm);
function ValidateMyForm(sender, args) {
var objPost = args.get_postBackElement();
if (objPost === null || objPost === undefined) return;
if (objPost.id == '<%= ((Button)(formViewinfo.FindControl("btnUpdate"))).ClientID %>') {
$('#pnlerrors').fadeOut('fast');
$('#pnlItemErrors').fadeOut('fast');
var isValid = $('#form1').validate({
errorClass: 'error',
invalidHandler: function (e, validator) {
var errors = validator.numberOfInvalids();
if (errors) {
$('#pnlerrors').html('<p> Please correct the errors </p>').fadeIn('fast');
document.location.href = '#pnlerrors';
}
}, submitHandler: function () {
}
}).form();
if (!isValid) {
CancelPostback(sender, args);
} else {
}
}
//this is for rest of buttons
else {
$('#pnlItemErrors').fadeOut('fast');
$('#pnlerrors').fadeOut('fast');
var isValid = $('#form1').validate({
errorClass: 'error',
invalidHandler: function (e, validator) {
var errors = validator.numberOfInvalids();
if (errors) {
$('#pnlerrors').fadeOut('fast');
document.location.replace('#', '#pnlItemErrors');
$('#pnlItemErrors').html('<p> Please correct the errors </p>').fadeIn('fast');
document.location.href = '#pnlItemErrors';
}
}, submitHandler: function () {
}
}).form();
if (!isValid) {
CancelPostback(sender, args);
} else {
}
}
}
All I want to do is: 2nd time validation on only button submit not for everything...I do get other postbacks on this page and those post backs also gets validated each time (I want to Avoid this)...
I don't know this approach is good or not...I am struggling with this from long time..I really appreciate you help...
On the assumption that you don't want to submit the form when someone presses the enter button, and that you only want to submit the form on pressing a submit button:
$(document).ready(
function(){
$('form').keypress(
function(event){
if (event.keyCode == '13'){
return false;
}
});
$('input:submit').click(
function(){
$(this).closest('form').submit();
});
$('form').submit(
function(){
$('#success').text('form submitted! (Not really...)');
return false;
// Just to stop the error messages
// in this demo.
});
});
There's a JS Fiddle demo, here: http://jsfiddle.net/davidThomas/5PaWz/.
If I'm mistaken in my assumptions, please leave a comment and I'll try to correct myself.
if your problem is just about finding the buttons the need to have validations then
one way of getting around this is to add a class to the buttons that you want to trigger validation, for example :
<asp:button id="btn1" cssclass="Validate"/>
then you can grab all these buttons in JQuery:
var buttons = $('.Validate');
get each button id:
$(buttons).each(function(){
var id = this.id;
});
ohh..god finally found the solution for my problem...First of all my apologizes if my question is not clear....
My validation works on asynchronous post backs...I just want validate my form on button clicks..i do have an asp.net grid view in my page..if i click on paging or something on the grid it fires validation...i want avoid this..
for this what i did is...i am capturing the postback element with the following statement.
var objPost = args.get_postBackElement();
then i am checking for type..
if (objpost.type == 'submit') { do validation }
else { don't }..
this ends my 2days struggle...
thank you very much your support and help...
Try different approach.
Use asp.Net Button with UseSubmitBehavior=true for submission
and use asp.Net Button with UserSubmitBehavior=false for buttons that you don't want them to fire the validation process that. add this following code to your form
function ValidateForm()
{
var errors ="";
if (typeof(Page_ClientValidate) == 'function')
{
if (typeof (Page_ClientValidate) == 'function') { Page_ClientValidate(); }
if (!Page_IsValid)
{
for (i = 0; i < Page_Validators.length; i++) {
var inputControl = document.getElementById(Page_Validators[i].controltovalidate);
if (!Page_Validators[i].isvalid) {
errors = errors + ";" + Page_Validators[i].errormessage;
inputControl.style.border ="solid 2px #FF0000";
}
}
}
return Page_IsValid;
}
return true;
}
$(document).ready(function(){
/*********************************************************************/
///handle form submittion and run validation prior to that
///if a textbox has required field validator, stop form submittion and
/// highlight the text box
/*********************************************************************/
$('#form1').submit(function(){
return ValidateForm();
});

Resources