Answered by:
Popup Form Causes main View Form Malfunction

Question
-
User-1641868886 posted
I have a view "CreateNewRecord" that contains a form with post action. One of the elements is a dropdownlist of "Vendors". If the user does not see his choice, he can press a button "AddNewVendor" to add a vendor using a jQuery popup dialog, this is a second form with post method. This popup has an ajax post method and a "success" method that a) serializes the form through the "AddNewVendor" controller, b) shows a "notify" flag onscreen, c) closes the popup, and d) appends the ddl to auto-fill the ddl control with the new choice.
ALL THIS WORKS, except when I use the popup, and then try to complete the primary form, "CreateNewRecord". I notice in debugging that the primary form DOES NOT send its results to the "CreateNewRecord" controller. HOWEVER, if I DO NOT use the popup, and instead simply choose an existing choice in the "Vendor" ddl, then the primary form "CreateNewRecord" operates normally through its controller action, and creates a new record.
Here is the primary ("CreateNewRecord") form (A), its controller (B), the razor view for the popup "AddNewVendor" (C), its controller (D), and the jQuery for the popup (E).
(A) Razor for "CreateNewRecord":
@model Groc_Site_Web.Models.GrocBillsModel @using (Html.BeginForm("CreateNewRecord", "GrocBills", FormMethod.Post)) { @Html.HiddenFor(m => m.Groc_Id) ...several inputs with labels, validators in their own divs... <div class="inline-flex"> @Html.DropDownList("Vend_Id", new SelectList(string.Empty, "Value", "Text"), "- - Select Vendor - -", new { @class = "form-control" }) <a class="btn btn-warning" style="margin-left:30px; " onclick="Vend_PopupForm('@Url.Action("AddOrEdit", "Vendors")')" id="VendAddLink"><i class="fa fa-plus"></i> Add New Vendor</a> </div> ...some more inputs with labels, validators... <input type="submit" style="margin-left:5px;margin-bottom:20px;" name="SubmitBtn" value="Finish" />
(B) Controller action for "CreateNewRecord":
public ActionResult CreateNewRecord(GrocBillsModel gro) { DynamicParameters param = new DynamicParameters(); var userName = User.Identity.GetUserName(); param.Add("@Groc_Id", groc.Groc_Id); param.Add("@UserName", UserName); param.Add("@Sku", groc.Sku); param.Add("@Vend_Id", groc.Vend_Id); param.Add("@Cashier", groc.Cashier); param.Add("@DateOfSale", groc.DateOfSale); param.Add("@Price", groc.Price); param.Add("@NetPrice", groc.NetPrice); param.Add("@Whol_Id", groc.Whol_Id); DataAccess.ExecuteWithoutReturn("spGrocBills_CreateNewRecord", param); return RedirectToAction("Index", "GrocBills"); }
(C) PartialView razor for "AddNewVendor":
@model Groc_Site_Web.Models.VendorsViewModel @using (Html.BeginForm("AddOrEdit", "Vendors", FormMethod.Post, new { onsubmit = "return SubmitVend_PopupForm(this)" })) { @Html.AntiForgeryToken() <div class="form-horizontal"> @Html.HiddenFor(model => model.Vend_Id) @Html.EditorFor(model => model.VendorName, new { htmlAttributes = new { @class = "form-control" } }) @Html.EditorFor(model => model.Address, new { htmlAttributes = new { @class = "form-control" } }) @Html.EditorFor(model => model.City, new { htmlAttributes = new { @class = "form-control" } }) @if (ViewBag.StatesList != null) { @Html.DropDownListFor(m => m.State, ViewBag.StatesList as SelectList, "- - Select State - -", new { @class = "form-control" }) } @Html.EditorFor(model => model.ZipCode, new { htmlAttributes = new { @class = "form-control" } }) <input id="VendSend" type="submit" value="Save" class="btn btn-default" /> }
(D) Controller for "AddNewVendor":
[HttpPost] public ActionResult AddOrEdit(VendorsViewModel Vend) { DynamicParameters param = new DynamicParameters(); param.Add("@Vend_Id", Vend.Vend_Id); param.Add("@VendorName", Vend.VendorName); param.Add("@Address", Vend.Address); param.Add("@City", Vend.City); param.Add("@State", Vend.State); param.Add("@ZipCode", Vend.ZipCode); DataAccess.ExecuteWithoutReturn("spVendors_AddOrEdit", param); return Json(new { success = true, message = "Vendor Added Successfully." }, JsonRequestBehavior.AllowGet); }
(E) JQuery for handling the "AddNewVendor" popupForm:
function SubmitVend_PopupForm(form) { $.validator.unobtrusive.parse(form); if ($(form).valid()) { $.ajax({ type: "POST", url: form.action, data: $(form).serialize(), dataType: "json", success: function (data) { if (data.success) { Popup.dialog('close'); $("#Vend_Id").append( $("<option></option>") .val($("#VendorName").html()) .html($("#VendorName").val()) .prop("selected", true)); $.notify(data.message, { globalPosition: "top center", width: 300, className: "success" }) } } }); } return false; }
IS there anything I'm not seeing that is preventing the primary form from submitting after use of the popup? Thanks for looking.
RC
Saturday, April 4, 2020 10:20 PM
Answers
-
User-17257777 posted
Hi ReidMelSam,
When you submit a form, the selected value in the select list is passed to the background. So if you want to get the Vendor_Id, you should set the select option value.
return Json(new { success = true, message = "Vendor Added Successfully.", option = Vend.VendorName, optionvalue= Vend.Vend_Id }, JsonRequestBehavior.AllowGet);
Render the select list like this to set its text and value.
$("#Vend_Id").append($("<option selected=true value="+ data.optionvalue +">" + data.option + "</option>"))
Now, when you submit, you can get the data.optionvalue(Vend_Id) in the controller, but the data.option(VendorName) will not be submit because it is just a text used to display the select option. To get it, you can define a hidden input field in the form.
Best Regards,
Jiadong Meng
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Wednesday, April 8, 2020 2:30 AM
All replies
-
User-474980206 posted
looks like you are not passing back the new vendor id for the dropdown. you don't really explain the value column of the dropdown.
Saturday, April 4, 2020 11:24 PM -
User-1641868886 posted
Thanks for looking and responding Bruce...hope you and yours are well!
I was worried about that issue of the Vend_Id.
Okay, I'm a lot closer. I revised as below:
$("#Vend_Id").append( $("<option></option>") .val($("#Vend_Id").val()) .val($("#VendorName").html()) .prop("selected", true)
...now the only outstanding item is that when I return to the primary "AddNewRecord" form, the highlighted statement making the new option the "selected" option is not working. Before the revision, the "VendorName" did appear in the ddl box, but now that I've solved the REAL problem, it doesn't appear. Been trying several versions, no luck yet.
Thanks for any suggestions.
RC
Saturday, April 4, 2020 11:53 PM -
User-17257777 posted
Hi ReidMelSam,
It seems that the Dom $("#VendorName") is unavaible after closing the popup. But, I think you can return the VendorName to your success function.
return Json(new { success = true, message = "Vendor Added Successfully.", option = Vend.VendorName }, JsonRequestBehavior.AllowGet);
And then, you can add it to the select option.
$("#Vend_Id").append($("<option selected=true>" + data.option + "</option>"))
Best Regards,
Jiadong Meng
Monday, April 6, 2020 7:09 AM -
User-1641868886 posted
Thanks for the suggestion. This and several other variations did not work. This last detail is a brain-teaser for sure. When I used your version, I once again got the "VendorName" to auto-fill to the dropdownlist, but then I was back to the original problem, the new "Vend_Id" was NOT supplied to the original form's ("CreateNewRecord") controller, so that form would not post.
I tried several other versions:
option = Vend.VendorName option = Vend.Vend_Id option = Vend etc... $("#Vend_Id").append($("<option selected=true>" + data.option + "</option>")) $("#Vend_Id").append($("<option selected=true>" + data.Vend_Id + "</option>")) $("#Vend_Id").append($("<option selected=true>" + data.VendorName + "</option>"))
I also tried several iterations of my original script WITHOUT revising the controller "success" stmt:
$("#Vend_Id").append( $("<option></option>") .val($("#Vend_Id").val()) .val($("#VendorName").html()) .prop("selected", true)); ...or: $("#Vend_Id").append( $("<option></option>") .val($("#Vend_Id").val()) .val($("#VendorName").html()) .attr("selected", true)); ...or: $("#Vend_Id").append( $("<option selected=true></option>") .val($("#Vend_Id").val()) .val($("#VendorName").html()));
None of these works. The important thing is that at least with the first of these (highlighted in green) I can continue with the original form ("CreateNewRecord") and it will post, as long as I choose the newly created "VendorName" in the ddl. BUT, I really need to resolve having the new "VendorName" auto-fill as the choice.
Thanks again for looking. Bruce...any ideas: .prop("selected", true) is SUPPOSED to work. I keep putting it in different places, thinking this is merely a syntax issue.
RC
Monday, April 6, 2020 7:55 PM -
User-1641868886 posted
Here is the latest version of the "append" of my "success" function from submitting "Vend_PopupForm" which creates a new "Vendor":
$("#Vend_Id").append($("<option selected=true>" + data.option + "</option>"));
The idea is to designate the new "Vendor" as the selected choice in the dropdownlist on the primary form, "CreateNewRecord" and send the newly-create "Vend_Id" to the controller for "CreateNewRecord". The Vendor "AddOrEdit" controller action contains this command to declare the "data.option":
return Json(new { success = true, message = "Vendor Added Successfully.", option = Vend.VendorName }, JsonRequestBehavior.AllowGet);
What is currently happening is that 1) the new "VendorName" appears in the ddl, but 2) the controller action for "CreateNewRecord" shows "0" when I hit the breakpoint for "Vend_Id". I thought there may be a problem with the stored procedure to add a new Vendor, so I made this alteration to try to get the new Vend_Id "on the fly":
OUTPUT Inserted.Vend_Id
...and on executing, the result window for the stored proc gives me the correct new "Vend_Id".
It seems likely that I do not yet have the right syntax in the script to get BOTH the new "VendorName" and "Vend_Id" to the "CreateNewRecord" form. Please suggest a revision or an idea of what I'm missing. Thanks much.
RC
Tuesday, April 7, 2020 5:37 PM -
User-17257777 posted
Hi ReidMelSam,
When you submit a form, the selected value in the select list is passed to the background. So if you want to get the Vendor_Id, you should set the select option value.
return Json(new { success = true, message = "Vendor Added Successfully.", option = Vend.VendorName, optionvalue= Vend.Vend_Id }, JsonRequestBehavior.AllowGet);
Render the select list like this to set its text and value.
$("#Vend_Id").append($("<option selected=true value="+ data.optionvalue +">" + data.option + "</option>"))
Now, when you submit, you can get the data.optionvalue(Vend_Id) in the controller, but the data.option(VendorName) will not be submit because it is just a text used to display the select option. To get it, you can define a hidden input field in the form.
Best Regards,
Jiadong Meng
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Wednesday, April 8, 2020 2:30 AM -
User-1641868886 posted
Thanks again for the suggestion. I have two issues: 1) The Json result STILL shows "Vend_Id = 0" so I am not outputting the id of the new row of "Vendor" and 2) the "option" statement in the "success" function clearly deals with what shows in the ddl selector box, because when I formatted according to your suggested, what I got was "0Bob's Pack n Sak" with '0' representing the "optionvalue" of the new "Vend_Id" which is unfortunately returning zero instead of the new row id.
Below is my current controller parameter for "Vend_Id" to show how I'm attempting to capture the output of the new "Vend_Id" as well as my stored procedure to attempt at outputting the "Vend_Id". Something in the stored proc. or the controller parameter, or both, obviously needs to be fixed. Not sure how, although I've been researching various syntax to arrive at this.
//controller parameter param.Add("@Vend_Id", Vend.Vend_Id, direction:ParameterDirection.Output); //stored proc. PROCEDURE [dbo].[spVendors_AddOrEdit] @VendorName nvarchar(100), @Address nvarchar(100), @City nvarchar(100), @State char(10), @ZipCode nvarchar(20), @Vend_Id int Output As IF @Vend_Id = 0 INSERT INTO Vendors(VendorName, Address, City, State, ZipCode, MetrosId) OUTPUT INSERTED.Vend_Id VALUES (@VendorName, @Address, @City, @State, @ZipCode, (SELECT MetroZips.MetrosId FROM MetroZips WHERE MetroZips.ZipCode=@ZipCode)) Else UPDATE Vendors SET VendorName=@VendorName, Address=@Address, City=@City, State=@State, ZipCode=@ZipCode WHERE Vend_Id = @Vend_Id
As to the two green-highlighted parts dealing with "Output" I'm not sure I need both of these, or if one or the other is not proper syntax to achieve what I'm trying to get to. I have fairly good sql knowledge but need a little help. I DID try to place a "SELECT SCOPE_IDENTITY()" at the end of the "INSERT" statement for the new (IF Vend_Id = 0) record, but using the "SCOPE_IDENTITY()" gave me a syntax error at the "Else" line for the Update (I do want to keep "AddOrUpdate" together).
Thanks again anyone who has an idea. I think I'm close, just need to know how to output this new id, so that the Json result has access to it.
RC
Wednesday, April 8, 2020 3:32 PM