Web: Textbox value attribute not the same as value in textbox - asp.net-mvc-3

I am using Visual Studio 2010 updated to the latest version and the MVC3 framework updated to the latest version. I am also using jquery 1.5.1 but this issue does not appear to be jquery related.
I have the following main page:
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/jqueryui/1.7.2/themes/base/jquery-ui.css" type="text/css" />
<link href="#Url.Content("~/Content/UserMaintainance.css")" rel="stylesheet" type="text/css" />
<script src="#Url.Content("~/Scripts/UserMaintainance.js")" type="text/javascript"></script>
#model TourSystem2.Models.UserMaintainanceViewModel
#{
ViewBag.Title = "UserMaintainance";
}
#Model.Debug
<h2>User Maintainance</h2>
<div id = "EditUser"></div>
<table>
<tr id="1">
<td><button type="button" class = "deleteButton"></button></td>
<td><button type="button" class = "editButton"></button></td>
<td>John </td>
<td>john </td>
<td>A</td>
<td>1234 </td>
<td></td>
//snipped some unrelated form generation of user information showing
<tr id = "0">
<td colspan = "7"><button type = "button" id = "addButton">Add New User</button></td>
</tr>
</table>
In the java script for this form, I do the following for the addButton:
$(function () {
$(':button.editButton, :button#addButton').click(function () {
var myData = $(this).parent().parent().attr("id");
$.post("/Admin/EditUser", { UserID: myData },
function (data) {
$('#EditUser').html(data);
$('#EditUser').dialog({
modal: true,
width: 400,
resizable: false,
buttons: {
"Save": function () {
$(this).dialog("close");
},
"Cancel": function () {
$(this).dialog("close");
}
}
});
}); //end post
});
The partial page /Admin/EditUser looks like this:
#model TourSystem2.Models.UserEditViewModel
<link href="/Content/UserEdit.css" rel="stylesheet" type="text/css" />
#Html.HiddenFor(Model => Model.UserInfo.iUserID)
<table id="useredit">
<tr>
<td>#Html.LabelFor(Model => Model.UserInfo.cLoginName, "Login Name")</td>
<td>#Html.TextBoxFor(Model => Model.UserInfo.cLoginName)</td>
</tr>
//Snip more fields
</table>
My controller code for EditUser looks like:
public ActionResult EditUser(int UserID)
{
UserEditViewModel myUser = new UserEditViewModel();
if (UserID == 0)
{
myUser.UserInfo.iUserID = 0;
return PartialView("UserEdit", myUser);
}
else if (myUser.Load(UserID))
{
return PartialView("UserEdit", myUser);
}
else
{
return Json("Broken: " + myUser.Debug);
}
}
My intention is that upon clicking save, I will do another AJAX post to pass the information back to the server.
So far, everything is working pretty well except the value attribute of the textbox does not change even though the text in the box has changed. If I click on edit, the data files out correctly on the editUser partial page... but any changes are not reflected in the value.
Using firebug, I can visually see that value does not change for any textbox I have on the screen. During the "save user" post, only the original value is returned and not the modified value.
Did I miss something very basic?
*EDIT 1***
I am trying to do the following in my SaveButton event:
"Save": function () {
var myUser =
{
iUserID: ('#UserInfo_iUserID').val,
cLoginName: ('#UserInfo_cLoginName').val,
};
$.ajax({
type: "POST",
url: "/admin/SaveUser",
data: myUser,
success: function (bNum) {
alert("returned" + bNum);
}
});
I am getting old results for the cLoginName: ('#UserInfo_cLoginName').val
This happens before the second POST.

That's a common gotcha when you try to modify values in a POST action that are contained in the ModelState and rendering the same view. You will need to remove the value from model state before changing it or HTML helpers (such as HiddenFor) will use the POSTed value when binding:
ModelState.Remove("UserInfo.iUserID");
myUser.UserInfo.iUserID = 0;
return PartialView("UserEdit", myUser);
Verify by debugging that ModelState contains a value called UserInfo.iUserID.
UPDATE:
It seems that the wrong syntax is used to retrieve the values:
('#UserInfo_iUserID').val
instead of:
$('#UserInfo_iUserID').val()

I had the same issue as Darrin described below
See Updating value provider prior to TryUpdateModel
The helpers exhibit this behavior because they assume if you are redisplaying data after a post there should be a validation failure otherwise you would be redirecting to a get action as part of the MVC PRG (post redirect get)pattern
I believe your issue though is different as was pointed out below.

Related

Jquery ajax form submit that contains files

I have a very long form that contains files attachment:
this is how my form looks like:
The form will be submitted to this action:
[HttpPost]
public ActionResult AddReceivingConfirm(DTOreceiving entry,IEnumerable<HttpPostedFileBase> fileUpload)
{
return PartialView();
}
through ajax call which is:
$(document).on('click', 'input[type="submit"].genericSubmit', function () { //generic function for ajax submit of ANY FORMS t
if (!$("form#ValidateForm").valid()) {
return false;
};
var frmData = $('.genericForm').serialize();
var frmUrl = $('.genericForm').attr('action');
$.ajax({
type: 'post',
url: frmUrl,
data: frmData,
success: function (e) {
$('#target').html(e);
}
});
return false;
});
everything is binding perfectly except the IEnumerable<HttpPostedFileBase>which always results to null,
the file part of my form is done like this:
<tr>
<td>Attachment #1: </td>
<td colspan="3">
<input id="file1" type="file" name="fileUpload" />
</td>
</tr>
<tr>
<td>Attachment #2: </td>
<td colspan="3">
<input id="file2" type="file" name="fileUpload" />
</td>
</tr>
<tr>
<td>Attachment #3: </td>
<td colspan="3">
<input id="file3 "type="file" name="fileUpload" />
</td>
</tr>
I have tried the brackets version and etc but it won't bind.
After an hour of researching, i've read that it's not possible(?) )to do file posting conventionally through the use of Ajax unless iframe. I am not sure of what my action will be, i kinda want to avoid using plugin so i wanna know if there is some "hacky" ways to access the files directly from my form?
this is my form:
using (Html.BeginForm("AddReceivingConfirm", "Wms", FormMethod.Post, new { id = "ValidateForm", #class = "genericForm" , enctype="multipart/form-data"}))
Unfortunately the jQuery serialize() method will not include input file elements. So your files are not going to be included in the serialized value.
What you should be doing is creating a FormData object, append the files to that. You need to append the form field values as well to this same FormData object. You may simply loop through all the input field and add it. Also, in the ajax call, you need to specify processData and contentType property values to false.
$(document).on('click', 'input[type="submit"].genericSubmit', function(e) {
e.preventDefault(); // prevent the default submit behavior.
var fdata = new FormData();
$('input[name="fileUpload"]').each(function(a, b) {
var fileInput = $('input[name="fileUpload"]')[a];
if (fileInput.files.length > 0) {
var file = fileInput.files[0];
fdata.append("fileUpload", file);
}
});
// You can update the jquery selector to use a css class if you want
$("input[type='text'").each(function(x, y) {
fdata.append($(y).attr("name"), $(y).val());
});
var frmUrl = $('.genericForm').attr('action');
$.ajax({
type: 'post',
url: frmUrl,
data: fdata,
processData: false,
contentType: false,
success: function(e) {
$('#target').html(e);
}
});
});
Seems like your $.ajax needs contentType: false to prevent a bad content-type header from being inserted.
Also, if I am reading the docs ( https://api.jquery.com/serialize/ ) correctly .serialize skips file inputs...
This answer also seems helpful How can I upload files asynchronously?

Jquery Accordion Validation Not working when rendering Partial View through $.ajax call

Hi friends,I am working on MVC 4 Razor and I am stuck in a situation
where Employee Personal Details form is to be filled in
steps(wizard)..for which i used jquery accordion control..for every
step i put an accordion..The html in each accordion section is
rendered from partial view through ajax call on every click of
respective accordion (i.e. <h3></h3> tag)..
On page load first/top accordion is active by default. My problem is
to restrict the user to click on next accordion until he/she fills the
presently active accordion correctly..
Here is my full code:
View:
#model XXX.ViewModels.PersonalDetailsViewModel
#{
ViewBag.Title = "PersonalDetails";
Layout = "~/Views/Shared/Template.cshtml";
}
#using (Html.BeginForm("Lifestyle", "Apply", FormMethod.Post, new { id = "personalDetailForm" }))
{
<div class="centerdiv margin_top20">
<div class="row">
#Html.ValidationSummary(true, "Please Correct the following errors:")
</div>
<div style="width: 1000px;">
<div id="Personalaccordion" class="acordion_div" style="padding: 10px; float: left;">
<h3 class="acordion_div_h3" onclick="javascript:PersonalModule.GetRenderingView('Apply/GetBasicDetailsView','personalDetailForm','BasicDetailsDiv');">
<p>
Basic Details<span id="BasicDetailsDivExp"></span>
</p>
</h3>
<div id="BasicDetailsDiv">
</div>
<h3 class="acordion_div_h3" onclick="javascript:PersonalModule.GetRenderingView('Apply/GetPersonalAddressView','personalDetailForm','PersonalAddressDiv');">
<p>
Address<span id="PersonalAddressDivExp"></span></p>
</h3>
<div id="PersonalAddressDiv">
</div>
</div>
<ul id="conlitue_ul" style="margin-top: 20px;">
<li style="margin-left: 140px;">
<input type="submit" class="compareBtn float_lt" value="Continue Buying >" id="continue" /></li>
</ul>
</div>
</div>
}
#Scripts.Render("~/bundles/PersonalDetails")
<script type="text/javascript">
PersonalModule.GetRenderingView('Apply/GetBasicDetailsView', '', 'BasicDetailsDiv');
</script>
My Controller:
public ActionResult PersonalDetails(int leadId)
{
var personalDetailsViewModel = LeadHelper.GetPersonalDetails(leadId);
return View(personalDetailsViewModel);
}
public ActionResult GetBasicDetailsView(PersonalDetailsViewModel personalDetailsViewModel)
{
if (personalDetailsViewModel.BasicDetails == null)
{
ModelInitializerHelper.InitilaizeBasicDetailsVModel(personalDetailsViewModel);
}
ModelInitializerHelper.InitializeBasicLookup(personalDetailsViewModel);
return PartialView("Personal/BasicDetails", personalDetailsViewModel);
}
public ActionResult GetPersonalAddressView(PersonalDetailsViewModel personalDetailsViewModel)
{
if (personalDetailsViewModel.PersonalAddressDetails == null)
{
ModelInitializerHelper.IntializePersonalAddressVModel(personalDetailsViewModel);
}
ModelInitializerHelper.InitializePersonalAddressLookup(personalDetailsViewModel);
return PartialView("Personal/PersonalAddress", personalDetailsViewModel);
}
My JS :
var PersonalModule = {
GetRenderingView: function (url, formId, containerID) {
var applicationurl = ApplicationRoot + '/' + url;
var objects = $('#BasicDetailsDivExp , #PersonalAddressDivExp' );
viewDivID = containerID;
GetAccordionView(applicationurl, formId, objects, containerID, 'accordion_plus', 'accordion_minus');
}
}
GetAccordionView: function (url, formId, objects, containerID, accordion_plus, accordion_minus) {
var formObjectData = null;
if (formId != undefined) {
formObjectData = $("#" + formId).serialize();
}
var renderView = function (data) {
$('#' + containerID).innerHtml = data;
}
ExpandAccordion(objects, containerID, accordion_plus, accordion_minus);
DoServerRequest(url, formObjectData, renderView);
}
ExpandAccordion: function (objects, spanIconID, accordion_plus, accordion_minus) {
var Objects = objects;
Objects.removeClass(accordion_minus);
Objects.addClass(accordion_plus);
$('#' + spanIconID + 'Exp').removeClass(accordion_plus).addClass(accordion_minus);
if (Browser.ie7) {
Objects.css("margin-top", "-22px");
}
}
DoServerRequest: function (url, data, funSuccess) {
$.ajax({
type: "POST",
url: url,
data: data,
async: false,
dataType: "json",
success: funSuccess,
error: function (errorResponse) {
if (errorResponse.readyState == 4 && errorResponse.status == 200) {
renderCurrentView(errorResponse.responseText)
}
else {
alert(errorResponse.responseText);
}
}
});
}
Please somebody help..I have heard lots of good thing about this forum
and this is my first Question...Thanks in advance..
I have removed my jquery validation attempt as it made the code
garbage thing Now I dont know what to write and where to write
If you are trying to validate data that has been added to form via Ajax after page load then you will need to use the rules method and add rules for these new elements. Jquery Validate has no way of knowing about them otherwise.
Example
Once you have loaded your new content via Ajax you need to find each element and add the necessary rules to them.
$('#yourDiv').find(".newElements").rules("add", {
required: true,
messages: {
required: "Bacon is required"
}
});
If you are using unobtrusive validate you may need to add your new elements to that also. See this SO question for more details.
Validating the Form
To check if the fields are valid, you will need to validate the form on click. This can be done using .validate(). You can then check if the form validated using .valid()
Example
$('#yourForm').validate();
if(!$('#yourForm').valid()) {
alert('Bacon is required');
}

JQuery Load using MVC3 #Url.Action does not pass parameters properly

I noticed that doing #Url.Action("myAction", new { param1 = 123, param2 = 456}) provides me with an invalid URL Home/myAction?param1=123&param2=456.
I am attempting to do
$("#myAjaxDiv").load(url);
But only param1 is getting populated in the action method.
When I remove the & and make it just & then it works, but doing a string replace is super hacky.
url = url.replace("&", "&");
Am I missing something here?
EDIT: Per request I'm including some of my sample app. (you can create a new MVC app and just add these quickly and see for yourself)
Controller:
public ActionResult AjaxTest(int? year, int? month)
{
ViewBag.Message = string.Format("Year: {0}, Month: {1}", year.HasValue ? year.ToString() : "no year", month.HasValue ? month.ToString() : "no month");
return PartialView("AjaxTest");
}
AjaxTest View:
#ViewBag.Message
Index View:
<script>
$(function () {
var url="";
$("#noParams").click(function () {
url = "Home/AjaxTest";
$("#ajaxy").load(url)
$("#url").text(url);
});
$("#yearParam").click(function () {
url = "Home/AjaxTest?year=2012";
$("#ajaxy").load(url)
$("#url").text(url);
});
$("#yearAndMonthParam").click(function () {
url = "Home/AjaxTest?year=2012&month=10";
$("#ajaxy").load(url)
$("#url").text(url);
});
$("#generated").click(function () {
url = "#(Url.Action("AjaxTest", new { year=2012, month=10}))";
$("#ajaxy").load(url);
$("#url").text(url);
});
});
</script>
<a id="noParams" href="#">No Params</a> <br />
<a id="yearParam" href="#">Year Param</a> <br />
<a id="yearAndMonthParam" href="#">Year and Month Param</a> <br />
<a id="generated" href="#">Generated</a> <br />
<div id="ajaxy">
</div>
<div>
URL: <span id="url"></span>
</div>
By default every content (which is not IHtmlString) emitted using a # block is automatically HTML encoded by Razor (see this Razor intro article Html Encoding section)
The Url.Action returns just a plain string so thats why the & gets encoded.
Use the Html.Raw if you don't want the encodeing:
url = "#(Html.Raw(Url.Action("AjaxTest", new { year=2012, month=10})))";
You can build the url in this way also.
var url = "#Url.Action("AjaxTest","YourControllerName")?year=2012&month=10";
$("#ajaxy").load(url);

How to POST to database through URL

I'm writing a web application in Spring/Hibernate that handles basic voting functionality. I want to have a link to /vote/{gameId} which will add that vote to the database for that specific ID. I'm really at a loss as for how to accomplish this though. Here's what I've tried in my controller:
#RequestMapping(value="/vote/{gameId}", method = RequestMethod.POST)
public String addVote(#PathVariable("gameId")
Integer gameId) {
Vote vote = new Vote();
vote.setGameId(gameId);
voteService.addVote(vote);
return "redirect:/games/wanted.html";
}
Here's where the link shows up in a jsp:
<c:if test="${!empty games}">
<table>
<tr>
<th>Game Title</th>
<th>Votes</th>
<th> </th>
</tr>
<c:forEach items="${games}" var="game">
<tr>
<td><c:out value="${game.title}"/></td>
<td>Placeholder</td>
<td>Vote!</td>
</tr>
</c:forEach>
</table>
</c:if>
When I try this though I just get a 404 error. Any insight would be great.
This is how you make a post call with plain Javascript:
var url = "vote";
var params = "id=1";
http.open("POST", url, true);
//Send the proper header information along with the request
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http.setRequestHeader("Content-length", params.length);
http.setRequestHeader("Connection", "close");
http.onreadystatechange = function() {//Call a function when the state changes.
if(http.readyState == 4 && http.status == 200) {
alert(http.responseText);
}
}
http.send(params);
You need to call this in the onclick of your link.
On the other hand it is a lot easier if, for example, you use the jQuery Javascript library:
For your particular case it would be something like:
$.post("vote", { id: "1" } );
Or the full jQuery answer (remember to replace #linkid with the id of you tag):
$(document).ready(function() { //this runs on page load
// Handler for .ready() called.
$('#linkid').click(function(event) { //this finds your <a> and sets the onclick, you can also search by css class by type of tag
$.post("vote", { id: "1" } );
return false; //this is important so that the link is not followed
});
});

Partial view in MVC3 Razor view Engine

I have an view in MVC3 Razor view engine like following image. Now i want to Confirm Connection Action Output show under this link text not New page. How can i done this work?
Please explain with example code.
My View Like this :
#model ESimSol.BusinessObjects.COA_ChartsOfAccount
#{
ViewBag.Title = "Dynamic Account Head Configure";
}
<h2>Dynamic Account Head Configure</h2>
<table border="0">
<tr>
<td> Select an Server Connection </td>
<td style="width:5px">:</td>
<td>#Html.DropDownListFor(m => m.DBConnections, Model.DBConnections.Select(x => new SelectListItem() { Text = x.ConnectionName, Value = x.DBConnectionID.ToString()}))</td>
</tr>
<tr>
<td> </td>
<td style="width:5px"></td>
<td>#Html.ActionLink("Confirm Connection", "ConformConnection")</td>
</tr>
</table>
AND My Controller action Like following :
public ActionResult ConfirmConnection()
{
return PartialView();
}
I'm a big fan of using jquery and ajax for this kind of thing ...
http://api.jquery.com/jQuery.ajax/
If you are following the typical MVC model then you can add an action link to the page using something like ...
#Html.ActionLink("controller", "action", args);
but I would go for the ajax driven approach ...
<script type="text/javascript">
var ajaxBaseUrl = '#Url.Action("yourController", "ConformConnection", new { args })';
$(link).click(function () {
var currentElement = $(this);
$.ajax({
url: ajaxBaseUrl,
data: { any other queryString stuff u want to pass },
type: 'POST',
success: function (data) {
// action to take when the ajax call comes back
}
});
});
});
</script>
First move your markup to a partial view. After that define an action method that renders your partial view.
[ChildActionOnly]
public ActionResult ConfirmConnection(COA_ChartsOfAccount model)
{
return PartialView("MyPartialView", model);
}
ChildActionOnly attribute makes sure this action method cannot be called by a HTTP request.
Then you can display it whenever you want using Html.Action method.
#Html.Action("ConfirmConnection", "MyController", new { model = Model })
Ignore passing the model as a parameter if it doesn't change by the page you display it. You can retrieve it in your action method.

Resources