I am having a problem using client side validation in combination with Data Annotations.
The project is using ASP.NET Framework 4.5, a Web Application with the MVP pattern and jQuery Ajax calls to dynamically load user controls.
This is the (stripped) user control which contains the input element that needs to be validated:
<form id="insertArtist" class="form-horizontal">
<fieldset>
<legend>Add new artist</legend>
<div class="control-group">
<label class="control-label" for="name">Name</label>
<div class="controls">
<asp:TextBox runat="server" ID="name" ClientIDMode="Static" CssClass="input-medium"></asp:TextBox>
<ml:DataAnnotationValidator runat="server" ID="davName" ControlToValidate="name" EnableClientScript="true" PropertyToValidate="Name" SourceTypeName="Music.Library.Domain.Models.Artist, Music.Library.Domain">
</ml:DataAnnotationValidator>
</div>
<div class="form-actions">
<button id="save" class="btn btn-primary" name="submit" type="submit">Save</button>
<button id="cancel" class="btn">Cancel</button>
</div>
</div>
</form>
This user control get's dynamically loaded using the following ajax call:
$('#add').click(function () {
$.ajax({
url: "/Artist/Manage/Insert.ascx.axd",
type: "POST",
dataType: "html",
success: function (obj) {
$('#body_artist').html($(obj));
}
});
});
This is the jquery executed when a user clicks save:
$('#save').click(function (event) {
event.preventDefault();
$.ajax({
url: "/artist/add.axd",
type: "POST",
dataType: "html",
cache: false,
async: true,
data: 'Ajax=true&' + $('#insertArtist').serialize(),
beforeSend: function (jqXHR, settings) {
$('#loading').show();
},
success: function (data) {
if (data == "succes") {
showNotification('succes', 'Succesfully added artist');
} else {
showNotification('error', 'Error while adding artist: ' + data);
}
},
error: function (jqXHR, textStatus, errorThrown) {
showNotification('error', 'Error while adding artist: ' + data);
},
complete: function () {
$('#loading').hide();
}
});
});
Now, since there is no trigger from an asp.net control the custom data annotation validator will not validate.
I've tried validating using Javascript, using the Page_ClientValidate(), ValidateEnable() and Validate() methods. Unfortunately when trying this I keep getting the same error over and over:
Page_ClientValidate is not defined
Same story for the other methods.
I'm at wits end here.
Is it because the UserControl is dynamically loaded that these client validation methods do not work? I've set EnableClientScript to true.
Or does anyone have another idea on how to implement this? I'd really like to use the Data Annotations.
Thanks in advance!
It can be a solution
http://xhalent.wordpress.com/2011/01/24/applying-unobtrusive-validation-to-dynamic-content/
Especially, it is a dublicate of this question Unobtrusive validation not working on dynamically-added partial view which also refers to XHalent blog
Related
I'm having an issue with a dropdown list using Knockout. I'm fairly new to this. The scenario is that when I edit some data, I call a Web Api to return some information in JSON. The JSON is then mapped and displayed for an end user to edit if they wish to. I have two dropdown lists (manufacturers and ranges). The manufacturer dropdown list gets populated and set to the correct value which is returned. The issue is that the second dropdown list gets populated but does not get set to the correct value. Instead it remains at the default "select" value. Would someone be able to explain why this happens or point me in the right direction?
My code is as follows. I have trimmed it down but can provide any further code if need be. Many thanks.
JS
/// <reference path="../knockout/knockout-3.4.0.debug.js" />
/// <reference path="../jquery/jquery.min.js" />
var deal = function () {
var self = this;
// These are the initial options
self.ManufacturerOptions = ko.observableArray();
self.VehicleManufacturerId = ko.observable();
self.RangeOptions = ko.observableArray();
self.VehicleRangeId = ko.observable();
var Deals = {
ManufacturerOptions: self.ManufacturerOptions,
VehicleManufacturerId: self.VehicleManufacturerId,
RangeOptions: self.RangeOptions,
VehicleRangeId: self.VehicleRangeId,
};
self.Deal = ko.observable();
self.Deals = ko.observableArray();
RetrieveDeals();
GetManufacturers();
self.EditData = function (Deal) {
GetManufacturers();
GetRanges(Deal.VehicleManufacturerId);
self.Deal(Deal);
};
function GetManufacturers() {
$.ajax({
url: 'http://localhost:47633/api/Vehicle/GetManufacturers',
type: 'get',
crossDomain: true,
dataType: 'json',
contentType: "application/json; charset=utf-8",
success: function (dataReturned) {
self.ManufacturerOptions(dataReturned);
}
});
}
function GetRanges(manufacturerId) {
$.ajax({
url: 'http://localhost:47633/api/Vehicle/GetRanges?manufacturerCode=' + manufacturerId,
type: 'get',
crossDomain: true,
dataType: 'json',
contentType: "application/json; charset=utf-8",
success: function (dataReturned) {
self.RangeOptions(dataReturned);
}
});
}
};
$(document).ready(function () {
ko.applyBindings(new deal());
});
ASCX Control
<%# Control Language="C#" AutoEventWireup="true" CodeBehind="Home.ascx.cs" Inherits="Desktop.Controls.DealBook.Home" %>
<h1>DealBook</h1>
<div data-bind="if: Deal">
<div>
<h2>Update Deal</h2>
</div>
<div>
<p>Manufacturer: <select id="Manufacturer" data-bind="options: ManufacturerOptions, optionsCaption: 'Select Manufacturer', optionsValue: 'cman_code', optionsText: 'cman_name', value: Deal().VehicleManufacturerId, event: { change: manufacturerChanged}"></select></p>
<p>Range: <select id="Range" data-bind="options: RangeOptions, optionsCaption: 'Select Range', optionsValue: 'cran_code', optionsText: 'cran_name', value: Deal().VehicleRangeId, event: { change: rangeChanged }"></select></p>
</div>
<input type="button" id="btnUpdateData" class="btn btn-primary" value="Update Deal" data-bind="click: UpdateData" />
<input type="button" id="btnCancel" class="btn btn-primary" value="Cancel" data-bind="click: Cancel" />
UPDATE
I believe the issue is that my code is trying to update the dropdown list to the selected value before the options are returned from the Web API. Any thoughts on how I can bind the value to the deal once the options are returned?
Fixed by using Jquery promises to defer method calls until complete.
I now call $.when(GetRanges(Deal.VehicleManufacturerId)).then(function () { self.Deal(Deal) }); instead of
GetRanges(Deal.VehicleManufacturerId);
self.Deal(Deal);
In MVC 4, I have a textbox with Autocomplete functionality in a partial view And i am using this partial view in two views,view 1 and View 2.In View 1 ,it is working fine, as view 1 does not have any postback, while in View 2, i have a submit button causing postback,and after this postback,the partial is shown on the screen or else it is hidden.The Autocomplete here is not working.
$("#txtProduct").autocomplete({
source: function (request, response) {
$.ajax({
type: "POST",
data: { term: request.term },
datatype: JSON,
url: 'UploadEligibilityCodes/GetAllMatchingProducts',
success: function (data) {
response($.map(data, function (value, key) {
return {
label: value.ProductName.concat("(", value.ProductId, ")"),
value: value.ProductName,
pid: value.ProductId
};
}))
}
});
},
select: function (event, ui) {
$('#hdnProductIdSearch').val(ui.item.pid);
}
});
This is the code of my text box defined in Partial view named SearchFilters.cshtml and View 2 which uses this partial view as follows.
#using (Html.BeginForm( "Validate","UploadEligibilityCodes",FormMethod.Post, new {id="UploadForm" , enctype = "multipart/form-data" }))
{
<div class="col-sm-1 form-group">
<button type="submit" class="SIMPLDocumentUploadSave" id="importbtn" value="Import" style="width: 100px"> Import</button>
</div>
}
<div class="col-sm-12 form-group SIMPLAdvancedFilterOptions">
#Html.Partial("SearchFilters")
</div>
I saw some examples using Sys.WebForms.PageRequestManager in ASP.Net, but the same i am not able to apply it html of mvc application.Please help :)
Can you replace your submit button with regular one and call submit() on form manually with jQuery? This can help you with postback issue
I have a webpage where many section of the page gets loaded using jQueryAjax after intial load. Now I need to download the web page completey using C#. It should be downloaded once all the ajax call completes.
I tried many ways to do that but didnot get through. Can sombody suggest the best way to handle that?
I have my MVC view like this
#{
ViewBag.Title = "My Page";
}
<div id="Banner" class="divMain" style="height: 92px;" style="margin-left: 0.3em">
</div>
<div style="float:left; width:99.6%">
<div id="StockPriceCharts" class="div_Chart" style="margin-top:0.1em;margin-left:-0.1em">
</div>
<div id="Rating" class="divMain_48" style="margin-left: 0.3em; min-height:140px">
<div class="ControlHeader">
Entity Details</div>
<div id="dvEntity" >
</div>
</div>
<div id="FilMeetings" class="divMain_48" style="float:left;">
<div class="ControlHeader">
MEETINGS
</div>
<div id="dvMeeting" style="height: 119px;" class="loading">
</div>
</div>
</div>
<span>
<input id="IdHidden" type="hidden" value="#ViewBag.SymbolId"/>
</span>
<script type="text/javascript">
$.ajaxSetup({ cache: false });
// For Entity Detail
$.ajax({
url: '/HomePage/Entity Detail/' + $('#IdHidden').val(),
contentType: 'application/html; charset=utf-8',
type: 'GET',
dataType: 'html',
data: { symbolId: document.getElementById("IdHidden").value }
})
.success(function (result) {
$('#dvEntity').html(result);
})
.error(function (xhr, status) {
$('#dvEntity').html('<div style="height:40px;" class="loading">Failed to load Entities</div>');
});
$.ajax({
url: '/HomePage/GetMEETINGSs/' + $('#IdHidden').val(),
contentType: 'application/html; charset=utf-8',
type: 'GET',
dataType: 'html',
data: { symbolId: document.getElementById("IdHidden").value }
})
.success(function (result) {
$('#dvMeeting').html(result);
})
.error(function (xhr, status) {
$('#dvMeeting').html('<div style="height:40px;" class="loading">Failed to load Business description</div>');
});
</script>
I have removed some part and put dummy value for brevity. But I have similar more section that are getting loaded via AJAX and there are some static content as well. When I download it ajax section is not getting loaded.
If I understand you right, after page loaded you're loading data with ajax and rendering it with JavaScript.
If so, you have to implement data rendering in Razor way (If you're using ASP.NET MVC). Each section should have own partial view. Create a new View and put Partials in it.
public ViewResult Index()
{
var api = new YouWebApiController();
var sectionData_1 = api.GetSectionData_1();
var sectionData_2 = api.GetSectionData_2();
var sectionData_3 = api.GetSectionData_3();
ViewBag.SectionData_1 = sectionData_1;
ViewBag.SectionData_2 = sectionData_2;
ViewBag.SectionData_3 = sectionData_3;
return new View();
}
In your view:
<body>
#Html.RenderPartial("SectionPartial_1", ViewBag.SectionData_1);
#Html.RenderPartial("SectionPartial_2", ViewBag.SectionData_2);
#Html.RenderPartial("SectionPartial_3", ViewBag.SectionData_3);
</body>
#{
var db = Database.Open("CMS");
//retrieving the username of the user from the session
var session_username = Session["session_username"];
//get the details of the user from the database
var getuserdetailscommand = "SELECT * from student where student_username = #0";
var getuserdetailsdata = db.Query(getuserdetailscommand, session_username);
var statusfirstname = "";
var statuslastname = "";
var statusavatar = "";
foreach(var row in getuserdetailsdata){
statusfirstname = row.student_firstname;
statuslastname = row.student_lastname;
statusavatar = row.student_avatar;
}
//on submit execute the following queries
if(IsPost){
if(Request["button"] == "sharestatus"){
//retrieve the data from the form input fields
var statusbody = Request.Form["statusbody"];
var statususername = session_username;
//insert the status for the username into the database
var insertcommand = "INSERT into status(status_body, status_date, status_username, status_firstname, status_lastname, status_avatar) VALUES (#0, #1, #2, #3, #4, #5)";
db.Execute(insertcommand, statusbody, DateTime.Now, session_username, statusfirstname, statuslastname, statusavatar);
}
}
}
<script type="text/javascript" src="http://code.jquery.com/jquery-1.7.2.min.js"></script>
<script type="text/javascript">
function get() {
$.post('statusupdateform.cshtml', { name: form.name.value }
}
</script>
<form class="status-form" role="form" action="" enctype="multipart/form-data" method="post" name="form">
<div class="form-body">
<div class="form-group">
<textarea class="form-control" placeholder="What's on your mind?" name="statusbody"></textarea>
</div>
</div>
<div class="form-footer">
<div class="pull-right actions">
<button class="btn btn-primary" name="button" value="sharestatus" onclick="event.preventDefault();get();return false;">Share</button>
</div>
</div>
</form>
This is the code in my cshtml file. I want to submit the form using ajax so that the whole page doesn't get refreshed everytime a user submits anything.
The C# code necessary to run the form is also provided in the code.
Any help how can I submit the for using ajax?
Thank you!
Use Javascript or JQuery for this.
E.g. add script tag with link to jquery code file and then use $.get or $.post to make ajax call.
You should remove
method="post"
From the form as this will make the full page submit. Also you can find more information on how to do this in the Jquery documentation.
See the bottom of this link for an example:
http://api.jquery.com/jquery.post/
Use This to perform your operations
$.ajax
({
url: " URL",
data: "{ 'name' : 'DATA'}",
dataType: "json",
type: "POST",
contentType: "application/json; charset=utf-8",
async: true,
dataFilter: function (data) { return data; },
success: function (data)
{
alert(data);
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert("error");
}
});
<script type="text/javascript">
$('#btnregister').click(function () {
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "fetchusers.asmx/RegUsers",
data: "{ username: '" + $("#txtuser").val() + "name: '" + $("#txtname").val() + "'}",
dataType: "json",
success: function (data) {
alert("Successfully register");
$("#btnregclose").click();
}
});
});
</script>
<div id="registration">
<fieldset>
<legend>Registration Form</legend>
<input id="txtuser" type="text" placeholder="Username" /><br />
<input id="txtname" type="text" placeholder="Name" /><br />
<input id="txtpass" type="password" placeholder="password" /><br />
<input id="txtconfirmpass" type="password" placeholder="confirm password" /><br />
<input id="btnregister" type="button" value="Register" />
<input id="btnregclose" type="button" value="close" />
</fieldset>
</div>
[WebMethod]
public string RegUsers(string username, string name)
{
string response = username + name;
return response;
}
I'm a beginner in Ajax Jquery and I'm doing exercise to improve my knowledge about it. My problem is when I click #btnregister it's not working. I think there's a problem in the parameters I passed on the ajax but I don't know what is it.
try this :
$(document).ready(function () {
$('#btnregister').click(function () {
var obj = { username: $("#txtuser").val(), name: $("#txtname").val() };
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "fetchusers.asmx/RegUsers",
data: JSON.stringify(obj),
dataType: "json",
success: function (data) {
alert("Successfully register");
$("#btnregclose").click();
}
});
});
});
this worked in my local enviroment.
Instead of trying to build the string by concatination it might be easier to do something like this:
$.ajax(url, {
data: JSON.stringify({
username: $("#txtuser").val(),
name: $("#txtname).val()
})
});
It will prevent typos/problems that might occur if you have say, a comma, in one of your fields. Note though, that ie7 and lower will require you to include a file called json2.js (github).
Edit:
Also, try executing your web service manually (just browse to the url, use a poster, etc). It is entirely possible you are getting a 404, or a server error.
Edit part 2: A good way to debug ajax issues in firefox is to use ctrl-shift-k to open the web console. Make sure "Net" is enabled and that "Log Request and Response Bodies" is checked in its dropdown. This way you can see the requests going out and coming back. If you dont see one then its an issue with your javascript, not the ajax.
Another Edit:
Also, I see your click event isnt in a $(document).ready(function() {}); It could be that you are attaching the click event before the button is rendered. Therefore the event isnt attached and your not even executing the ajax code.
use this syntax....
data: "{ 'username': '" + $("#txtuser").val() + "', 'name': '" + $("#txtname").val() + "'}",
The code in the question is right it needs simple solution. Go to yourwebservice.asmx.cs file and uncomment the following line given at class level this will resolve the issue of calling this webservice from jQuery or Ajax.
[System.Web.Script.Services.ScriptService]