Pure javascript ajax call asp.net webmethod - asp.net

I would not like to call asp.net server side code with jquery $.ajax .
So I have written a pure javascript ajax file .But when I call webmethod,this do not work.
Can anyony help me out how correct this? THANK you very much .
ajax.js:
var ajax = {
_params: null,
_callback: null,
_xhr: null,
_createXHR: function () {
if (window.ActiveXObject) {
_xhr = new ActiveXObject("Microsoft.XMLHTTP"); //IE
}
else if (window.XMLHttpRequest) {
_xhr = new XMLHttpRequest(); //FireFox,Chrome et.
}
},
_ajaxcallback: function () {
if (_xhr.readyState == 4) {
if (_xhr.status == 200) {
_callback.call(this, _xhr.responseText)
}
}
},
_changeParams: function () {
var args = arguments[0];
var s = "";
for (var i in args) {
s += "&" + i + "=" + args[i];
}
_params = s;
},
get: function (url, params, callback) {
_callback = callback;
ajax._createXHR();
ajax._changeParams(params);
if (null != _xhr) {
_xhr.open('get', url + '?' + _params, true);
_xhr.onreadystatechange = ajax._ajaxcallback;
_xhr.send();
}
},
post: function (url, params, callback) {
_callback = callback;
ajax._createXHR();
ajax._changeParams(params);
if (null != _xhr) {
_xhr.open('post', url, true);
_xhr.onreadystatechange = ajax._ajaxcallback;
_xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
_xhr.send(_params);
}
}
}
WebForm1.aspx
<head runat="server">
<title></title>
<script src="ajax.js" type="text/javascript"></script>
<script type="text/javascript">
function ajaxtest() {
var uid = document.getElementById("txtuid").value;
var pwd = document.getElementById("txtpwd").value;
ajax.post("WebForm1.aspx/GetModel", "{ 'uid':" + uid + ", 'pwd':" + pwd + " }", function (data) {
alert(data);
});
}
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<input type="text" id="txtuid" value="eeee" />
<input type="text" value="222" id="txtpwd" onblur="ajaxtest()"/>
WebForm1.cs:
[WebMethod]
public static string GetModel(string uid,string pwd)
{
return "1";
}

In your markup you need to have a ScriptManager with EnablePageMethods set to true. Doing this will ensure you can call the methods you have marked up with [WebMethod].
In your JavaScript you can then call your method like this: PageMethods.GetModel("userName", "password", OnSuccessMethod, OnFailureMethod); - you won't need any of the ActiveXObject/XmlHttpRequest stuff if you do it this way, which keeps things much simpler.

Use AJAX.PRO from Michael Schwarz --> http://www.ajaxpro.info/

Related

How should I encode a form value I send with XMLHttpRequest [duplicate]

I'd like to send some data using an XMLHttpRequest in JavaScript.
Say I have the following form in HTML:
<form name="inputform" action="somewhere" method="post">
<input type="hidden" value="person" name="user">
<input type="hidden" value="password" name="pwd">
<input type="hidden" value="place" name="organization">
<input type="hidden" value="key" name="requiredkey">
</form>
How can I write the equivalent using an XMLHttpRequest in JavaScript?
The code below demonstrates on how to do this.
var http = new XMLHttpRequest();
var url = 'get_data.php';
var params = 'orem=ipsum&name=binny';
http.open('POST', url, true);
//Send the proper header information along with the request
http.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
http.onreadystatechange = function() {//Call a function when the state changes.
if(http.readyState == 4 && http.status == 200) {
alert(http.responseText);
}
}
http.send(params);
In case you have/create an object you can turn it into params using the following code, i.e:
var params = new Object();
params.myparam1 = myval1;
params.myparam2 = myval2;
// Turn the data object into an array of URL-encoded key/value pairs.
let urlEncodedData = "", urlEncodedDataPairs = [], name;
for( name in params ) {
urlEncodedDataPairs.push(encodeURIComponent(name)+'='+encodeURIComponent(params[name]));
}
var xhr = new XMLHttpRequest();
xhr.open('POST', 'somewhere', true);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.onload = function () {
// do something to response
console.log(this.responseText);
};
xhr.send('user=person&pwd=password&organization=place&requiredkey=key');
Or if you can count on browser support you could use FormData:
var data = new FormData();
data.append('user', 'person');
data.append('pwd', 'password');
data.append('organization', 'place');
data.append('requiredkey', 'key');
var xhr = new XMLHttpRequest();
xhr.open('POST', 'somewhere', true);
xhr.onload = function () {
// do something to response
console.log(this.responseText);
};
xhr.send(data);
Use modern JavaScript!
I'd suggest looking into fetch. It is the ES5 equivalent and uses Promises. It is much more readable and easily customizable.
const url = "http://example.com";
fetch(url, {
method : "POST",
body: new FormData(document.getElementById("inputform")),
// -- or --
// body : JSON.stringify({
// user : document.getElementById('user').value,
// ...
// })
}).then(
response => response.text() // .json(), etc.
// same as function(response) {return response.text();}
).then(
html => console.log(html)
);
In Node.js, you'll need to import fetch using:
const fetch = require("node-fetch");
If you want to use it synchronously (doesn't work in top scope):
const json = await fetch(url, optionalOptions)
.then(response => response.json()) // .text(), etc.
.catch((e) => {});
More Info:
Mozilla Documentation
Can I Use (96% Nov 2020)
David Walsh Tutorial
Here is a complete solution with application-json:
// Input values will be grabbed by ID
<input id="loginEmail" type="text" name="email" placeholder="Email">
<input id="loginPassword" type="password" name="password" placeholder="Password">
// return stops normal action and runs login()
<button onclick="return login()">Submit</button>
<script>
function login() {
// Form fields, see IDs above
const params = {
email: document.querySelector('#loginEmail').value,
password: document.querySelector('#loginPassword').value
}
const http = new XMLHttpRequest()
http.open('POST', '/login')
http.setRequestHeader('Content-type', 'application/json')
http.send(JSON.stringify(params)) // Make sure to stringify
http.onload = function() {
// Do whatever with response
alert(http.responseText)
}
}
</script>
Ensure that your Backend API can parse JSON.
For example, in Express JS:
import bodyParser from 'body-parser'
app.use(bodyParser.json())
Minimal use of FormData to submit an AJAX request
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge, chrome=1"/>
<script>
"use strict";
function submitForm(oFormElement)
{
var xhr = new XMLHttpRequest();
xhr.onload = function(){ alert (xhr.responseText); } // success case
xhr.onerror = function(){ alert (xhr.responseText); } // failure case
xhr.open (oFormElement.method, oFormElement.action, true);
xhr.send (new FormData (oFormElement));
return false;
}
</script>
</head>
<body>
<form method="post" action="somewhere" onsubmit="return submitForm(this);">
<input type="hidden" value="person" name="user" />
<input type="hidden" value="password" name="pwd" />
<input type="hidden" value="place" name="organization" />
<input type="hidden" value="key" name="requiredkey" />
<input type="submit" value="post request"/>
</form>
</body>
</html>
Remarks
This does not fully answer the OP question because it requires the user to click in order to submit the request. But this may be useful to people searching for this kind of simple solution.
This example is very simple and does not support the GET method. If you are interesting by more sophisticated examples, please have a look at the excellent MDN documentation. See also similar answer about XMLHttpRequest to Post HTML Form.
Limitation of this solution: As pointed out by Justin Blank and Thomas Munk (see their comments), FormData is not supported by IE9 and lower, and default browser on Android 2.3.
NO PLUGINS NEEDED!
Select the below code and drag that into in BOOKMARK BAR (if you don't see it, enable from Browser Settings), then EDIT that link :
javascript:var my_params = prompt("Enter your parameters", "var1=aaaa&var2=bbbbb"); var Target_LINK = prompt("Enter destination", location.href); function post(path, params) { var xForm = document.createElement("form"); xForm.setAttribute("method", "post"); xForm.setAttribute("action", path); for (var key in params) { if (params.hasOwnProperty(key)) { var hiddenField = document.createElement("input"); hiddenField.setAttribute("name", key); hiddenField.setAttribute("value", params[key]); xForm.appendChild(hiddenField); } } var xhr = new XMLHttpRequest(); xhr.onload = function () { alert(xhr.responseText); }; xhr.open(xForm.method, xForm.action, true); xhr.send(new FormData(xForm)); return false; } parsed_params = {}; my_params.split("&").forEach(function (item) { var s = item.split("="), k = s[0], v = s[1]; parsed_params[k] = v; }); post(Target_LINK, parsed_params); void(0);
That's all! Now you can visit any website, and click that button in BOOKMARK BAR!
NOTE:
The above method sends data using XMLHttpRequest method, so, you have to be on the same domain while triggering the script. That's why I prefer sending data with a simulated FORM SUBMITTING, which can send the code to any domain - here is code for that:
javascript:var my_params=prompt("Enter your parameters","var1=aaaa&var2=bbbbb"); var Target_LINK=prompt("Enter destination", location.href); function post(path, params) { var xForm= document.createElement("form"); xForm.setAttribute("method", "post"); xForm.setAttribute("action", path); xForm.setAttribute("target", "_blank"); for(var key in params) { if(params.hasOwnProperty(key)) { var hiddenField = document.createElement("input"); hiddenField.setAttribute("name", key); hiddenField.setAttribute("value", params[key]); xForm.appendChild(hiddenField); } } document.body.appendChild(xForm); xForm.submit(); } parsed_params={}; my_params.split("&").forEach(function(item) {var s = item.split("="), k=s[0], v=s[1]; parsed_params[k] = v;}); post(Target_LINK, parsed_params); void(0);
I have faced similar problem, using the same post and and this link I have resolved my issue.
var http = new XMLHttpRequest();
var url = "MY_URL.Com/login.aspx";
var params = 'eid=' +userEmailId+'&pwd='+userPwd
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);// all browser wont support Refused to set unsafe header "Content-Length"
//http.setRequestHeader("Connection", "close");//Refused to set unsafe header "Connection"
// Call a function when the state
http.onreadystatechange = function() {
if(http.readyState == 4 && http.status == 200) {
alert(http.responseText);
}
}
http.send(params);
This link has completed information.
Try to use json object instead of formdata. below is the code working for me. formdata doesnot work for me either, hence I came up with this solution.
var jdata = new Object();
jdata.level = levelVal; // level is key and levelVal is value
var xhttp = new XMLHttpRequest();
xhttp.open("POST", "http://MyURL", true);
xhttp.setRequestHeader('Content-Type', 'application/json');
xhttp.send(JSON.stringify(jdata));
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
console.log(this.responseText);
}
}
There's some duplicates that touch on this, and nobody really expounds on it. I'll borrow the accepted answer example to illustrate
http.open('POST', url, true);
http.send('lorem=ipsum&name=binny');
I oversimplified this (I use http.onload(function() {}) instead of that answer's older methodology) for the sake of illustration. If you use this as-is, you'll find your server is probably interpreting the POST body as a string and not actual key=value parameters (i.e. PHP won't show any $_POST variables). You must pass the form header in to get that, and do that before http.send()
http.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
If you're using JSON and not URL-encoded data, pass application/json instead
var util = {
getAttribute: function (dom, attr) {
if (dom.getAttribute !== undefined) {
return dom.getAttribute(attr);
} else if (dom[attr] !== undefined) {
return dom[attr];
} else {
return null;
}
},
addEvent: function (obj, evtName, func) {
//Primero revisar attributos si existe o no.
if (obj.addEventListener) {
obj.addEventListener(evtName, func, false);
} else if (obj.attachEvent) {
obj.attachEvent(evtName, func);
} else {
if (this.getAttribute("on" + evtName) !== undefined) {
obj["on" + evtName] = func;
} else {
obj[evtName] = func;
}
}
},
removeEvent: function (obj, evtName, func) {
if (obj.removeEventListener) {
obj.removeEventListener(evtName, func, false);
} else if (obj.detachEvent) {
obj.detachEvent(evtName, func);
} else {
if (this.getAttribute("on" + evtName) !== undefined) {
obj["on" + evtName] = null;
} else {
obj[evtName] = null;
}
}
},
getAjaxObject: function () {
var xhttp = null;
//XDomainRequest
if ("XMLHttpRequest" in window) {
xhttp = new XMLHttpRequest();
} else {
// code for IE6, IE5
xhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
return xhttp;
}
};
//START CODE HERE.
var xhr = util.getAjaxObject();
var isUpload = (xhr && ('upload' in xhr) && ('onprogress' in xhr.upload));
if (isUpload) {
util.addEvent(xhr, "progress", xhrEvt.onProgress());
util.addEvent(xhr, "loadstart", xhrEvt.onLoadStart);
util.addEvent(xhr, "abort", xhrEvt.onAbort);
}
util.addEvent(xhr, "readystatechange", xhrEvt.ajaxOnReadyState);
var xhrEvt = {
onProgress: function (e) {
if (e.lengthComputable) {
//Loaded bytes.
var cLoaded = e.loaded;
}
},
onLoadStart: function () {
},
onAbort: function () {
},
onReadyState: function () {
var state = xhr.readyState;
var httpStatus = xhr.status;
if (state === 4 && httpStatus === 200) {
//Completed success.
var data = xhr.responseText;
}
}
};
//CONTINUE YOUR CODE HERE.
xhr.open('POST', 'mypage.php', true);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
if ('FormData' in window) {
var formData = new FormData();
formData.append("user", "aaaaa");
formData.append("pass", "bbbbb");
xhr.send(formData);
} else {
xhr.send("?user=aaaaa&pass=bbbbb");
}
This helped me as I wanted to use only xmlHttpRequest and post an object as form data:
function sendData(data) {
var XHR = new XMLHttpRequest();
var FD = new FormData();
// Push our data into our FormData object
for(name in data) {
FD.append(name, data[name]);
}
// Set up our request
XHR.open('POST', 'https://example.com/cors.php');
// Send our FormData object; HTTP headers are set automatically
XHR.send(FD);
}
https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Sending_forms_through_JavaScript
Short & modern
You can catch form input values using FormData and send them by fetch
fetch(form.action, {method:'post', body: new FormData(form)});
function send() {
let form = document.forms['inputform'];
fetch(form.action, {method:'post', body: new FormData(form)});
}
<form name="inputform" action="somewhere" method="post">
<input value="person" name="user">
<input type="hidden" value="password" name="pwd">
<input value="place" name="organization">
<input type="hidden" value="key" name="requiredkey">
</form>
<!-- I remove type="hidden" for some inputs above only for show them --><br>
Look: chrome console>network and click <button onclick="send()">send</button>
Just for feature readers finding this question. I found that the accepted answer works fine as long as you have a given path, but if you leave it blank it will fail in IE. Here is what I came up with:
function post(path, data, callback) {
"use strict";
var request = new XMLHttpRequest();
if (path === "") {
path = "/";
}
request.open('POST', path, true);
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
request.onload = function (d) {
callback(d.currentTarget.response);
};
request.send(serialize(data));
}
You can you it like so:
post("", {orem: ipsum, name: binny}, function (response) {
console.log(respone);
})

How import file Excel to multiple tables in DB using asp.net and angularJS?

I have developed an application, and in this application I want to import file Excel to multiple table in my DB, and since i am a beginner in angularJS and .NET, I work with .net web api and angularjs, and I develop a function, it works when I import the data into a singe table, but the problem how to import the data into 3 table in DB !!! . and the 3 tables are linked to each other (in my exemple code there 2 table Candidature and Candidat). My question is: how to import Excel file to multiple table in DB and thank's. ( i work with asp.net web API and angularJS )
controller.cs:
/////
[Route("api/Candidature/SaveData")]
[HttpPost]
[ResponseType(typeof(Candidat))]
public IHttpActionResult SaveData(List<Candidature> Candidatures, List<Candidat> candidat)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
foreach (var data in Candidatures)
{
db.Candidature.Add(data);
}
db.SaveChanges();
foreach (var data in candidat)
{
db.Candidat.Add(data);
}
db.SaveChanges();
return StatusCode(HttpStatusCode.OK);
////
service.js:
SaveData: {
method: 'POST' ,
url: serviceBase + 'Candidature/SaveData',
isArray: true,
headers: {
'Content-Type' : 'application/json'
}
},
CandidatureCtrl.js :
$scope.Importation = function (data) {
$scope.SelectedFileForUpload = null;
$scope.UploadFile = function (files) {
$scope.$apply(function () { //I have used $scope.$apply because I will call this function from File input type control which is not supported 2 way binding
$scope.Message = "";
$scope.SelectedFileForUpload = files[0];
})
};
//Parse Excel Data
$scope.ParseExcelDataAndSave = function () {
var file = $scope.SelectedFileForUpload;
if (file) {
var reader = new FileReader();
reader.onload = function (e) {
var data = e.target.result;
//XLSX from js-xlsx library , which I will add in page view page
var workbook = XLSX.read(e.target.result, { type: 'binary', cellDates:true, cellStyles:true });
var sheetName = workbook.SheetNames[0];
var excelData = XLSX.utils.sheet_to_row_object_array(workbook.Sheets[sheetName]);
if (excelData.length > 0) {
//Save data
Candidature.SaveData(excelData).then(function (data) {
if (data.status) {
$scope.Message = excelData.length + " record inserted";
}
else {
$scope.Message = "Failed";
}
}, function (error) {
$scope.Message = "Error";
});
// Candidature.SaveDatacandidature(excelData).then(function (data) {
// if (data.status) {
// $scope.Message = excelData.length + " record inserted";
// }
// else {
// $scope.Message = "Failed";
// }
// }, function (error) {
// $scope.Message = "Error";
// });
// $scope.SaveData(excelData);
}
else {
$scope.Message = "No data found";
}
}
reader.onerror = function (ex) {
console.log(ex);
}
reader.readAsBinaryString(file);
}
};
var dialogOpts = {
backdrop: 'static',
keyboard: false,
scope: $scope,
size: 'lg',
templateUrl: 'views/candidature/Importation.html',
controller: ['$scope', '$uibModalInstance','$sce',
function ($scope, $uibModalInstance, $sce) {
$scope.cancel = function () {
$uibModalInstance.dismiss('cancel');
};
}
]
};
$uibModal.open(dialogOpts);
};
Importation.html :
<!DOCTYPE html>
<html>
<head>
<meta name="viewport" content="width=device-width" />
<title>Index</title>
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/xlsx/0.8.1/xlsx.full.min.js"></script>
<script src="http://oss.sheetjs.com/js-xlsx/jszip.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.6.1/angular.min.js"></script>
<!--<script src="app/views/candidature/candidatureCtrl.js"></script>-->
</head>
<body ng-app="agu">
<div ng-controller="candidatureCtrl" class="container" style="margin-top:50px;">
<div class="form-inline">
<input type="file" name="file" class="form-control"
onchange="angular.element(this).scope().UploadFile(this.files)"/>
<input type="button" value="Import" class="btn btn-success" ng-disabled="!SelectedFileForUpload"
ng-click="ParseExcelDataAndSave()" />
<br/>
<span style="color:red">
{{Message}}
</span>
</div>
</div>
</body>
</html>
In your web api, you are expecting two arrays for Candidatures and candidat.
But from your controller you are passing only one array of data excelData.
So when it comes to api it doesn't execute this code,
foreach (var data in candidat)
{
db.Candidat.Add(data);
}
Because candidat is either null or undefined. So it can't go through the loop which the below code is never executed.
db.Candidat.Add(data);

How do I track SignalR Connection State?

I was pointed to this GITHub sample code by David Fowler himself to track SignalR users and states. I have implemented all of it and it works great except I can't figure out the displaying of Hub connection state changes. I have this which doesn't seem to work. Does anyone know why?
!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
<style>
#state {
width: 20px;
height: 50px;
}
</style>
</head>
<body>
<h3 id="msg"></h3>
<div id="state"></div>
<script src="../Scripts/jquery-1.10.2.min.js"></script>
<script src="../Scripts/jquery.signalR-2.0.2.min.js"></script>
<script src="signalr/hubs"></script>
<script>
$(function () {
var userTracking = $.connection.alphaHub;
// Need at least one callback for events to be raised on the hub
userTracking.client.void = function () { };
$.connection.logging = true;
$.connection.hub.stateChanged(function (change) {
if (change.newState === $.signalR.connectionState.connected) {
$('#state').css('background-color', 'green');
} else if (change.newState === $.signalR.connectionState.reconnecting) {
$('#state').css('background-color', 'yellow');
} else if (change.newState === $.signalR.connectionState.disconnected) {
$('#state').css('background-color', 'red');
}
});
$.connection.hub.disconnected(function () {
setTimeout(function () {
$.connection.hub.start();
}, 1000);
});
});
</script>
</body>
</html>
My Hub is shown partially here:
public class AlphaHub : Hub
{
public override async Task OnConnected()
{
try
{
var name = Context.User.Identity.Name;
using (savitasEntities2 entities = new savitasEntities2())
{
var user = entities.SUsers
.Include(u => u.SConnections)
.SingleOrDefault(u => u.UserName == name);
if (user == null)
{
user = new SUser
{
UserName = name,
SConnections = new List<SConnection>()
};
entities.SUsers.Add(user);
}
user.SConnections.Add(new SConnection
{
ConnectionID = Context.ConnectionId,
UserAgent = Context.Request.Headers["User-Agent"],
LastActivity = DateTimeOffset.UtcNow
});
// entities.SaveChanges();
await entities.SaveChangesAsync();
}
}
public override async Task OnDisconnected()
{
try
{
using (savitasEntities2 db = new savitasEntities2())
{
var connection = await db.SConnections.FindAsync(Context.ConnectionId);
db.SConnections.Remove(connection);
await db.SaveChangesAsync();
}
}
catch (Exception ex)
{
c.LogError(ex.Message, "AlphaHub.cs" + " - " + this.GetType().FullName + "." + System.Reflection.MethodBase.GetCurrentMethod().Name);
}
}
Looks like your hubs can't be found.
Change:
<script src="signalr/hubs"></script>
to:
<script src="~/signalr/hubs"></script>

Trying to use a jquery-ui combobox in asp.net webforms

I'm trying to use the jqueryUI combobox into my asp.net 3.5 webforms application. I've added a dropdownlist and modified it style with jquery. The problem i got is when i try to execute the postback the dropdown normally does when it selected item it's changed. The combobox doesn't change it's value and I'm getting the error that _dopostback is not defined in my firebug error console. I've been reading about this here and in and in in the asp.net forums, and found some answers that told me that should give a try to the GetPostBackEventReference method, but still nothing has happened. Below is the code, thanks.
<script type="text/javascript">
(function ($) {
$.widget("ui.combobox", {
_create: function () {
var input,
self = this,
select = this.element.hide(),
selected = select.children(":selected"),
value = selected.val() ? selected.text() : "",
wrapper = $("<span>")
.addClass("ui-combobox")
.insertAfter(select);
input = $("<input>")
.appendTo(wrapper)
.val(value)
.addClass("ui-state-default")
.autocomplete({
delay: 0,
minLength: 0,
source: function (request, response) {
var matcher = new RegExp($.ui.autocomplete.escapeRegex(request.term), "i");
response(select.children("option").map(function () {
var text = $(this).text();
if (this.value && (!request.term || matcher.test(text)))
return {
label: text.replace(
new RegExp(
"(?![^&;]+;)(?!<[^<>]*)(" +
$.ui.autocomplete.escapeRegex(request.term) +
")(?![^<>]*>)(?![^&;]+;)", "gi"
), "<strong>$1</strong>"),
value: text,
option: this
};
}));
},
select: function (event, ui) {
ui.item.option.selected = true;
self._trigger("selected", event, {
item: ui.item.option
});
_doPostBack('<%= ddlModalities.UniqueID %>', "");
},
change: function (event, ui) {
if (!ui.item) {
var matcher = new RegExp("^" + $.ui.autocomplete.escapeRegex($(this).val()) + "$", "i"),
valid = false;
select.children("option").each(function () {
if ($(this).text().match(matcher)) {
this.selected = valid = true;
$(select).change();
return false;
}
});
if (!valid) {
// remove invalid value, as it didn't match anything
$(this).val("");
select.val("");
input.data("autocomplete").term = "";
return false;
}
}
}
})
.addClass("ui-widget ui-widget-content ui-corner-left");
input.data("autocomplete")._renderItem = function (ul, item) {
return $("<li></li>")
.data("item.autocomplete", item)
.append("<a>" + item.label + "</a>")
.appendTo(ul);
};
$("<a>")
.attr("tabIndex", -1)
.attr("title", "Show All Items")
.appendTo(wrapper)
.button({
icons: {
primary: "ui-icon-triangle-1-s"
},
text: false
})
.removeClass("ui-corner-all")
.addClass("ui-corner-right ui-button-icon")
.click(function () {
// close if already visible
if (input.autocomplete("widget").is(":visible")) {
input.autocomplete("close");
return;
}
// work around a bug (likely same cause as #5265)
$(this).blur();
// pass empty string as value to search for, displaying all results
input.autocomplete("search", "");
input.focus();
});
},
destroy: function () {
this.wrapper.remove();
this.element.show();
$.Widget.prototype.destroy.call(this);
}
});
})(jQuery);
$(function () {
$("#<%=ddlModalities.ClientID %>").combobox();
});
</script>
<div class="ui-widget">
<asp:DropDownList runat="server" ID="ddlModalities" Width="150px" AutoPostBack="True"
DataSourceID="odsModalitiesNoWorklist" DataTextField="Ae" DataValueField="Id"
CssClass="ddlStandardWidth" OnDataBound="ddlModalities_DataBound" OnSelectedIndexChanged="ddlModalities_SelectedIndexChanged" />
</div>
It looks like you're calling "_doPostBack". However, the ASP.NET-generated function is "__doPostBack" - there are two "_" characters at the beginning, not just one. That could be the cause of your "function not defined" error.

jQuery and ASP.NET Custom Validator

I'm trying to learn jQuery and it occurred to me that existing JS in some of my sites could be replaced with just a few lines of jQuery code. In the following code, I'm trying to set the value of a custom validator by making an AJAX call. The first block of code does not work as it should, whereas the second block works fine. The whole "if it ain't broke don't fix it" answer isn't helpful, I really want to learn jQuery. For the record, I've placed alerts in the code and they both return the exact same result, just one is setting the args and the other is not for some reason.
Why does this code NOT work:
function CheckForUserName(sender, args)
{
args.IsValid = true;
var url = "/somepage.aspx";
MakeCall(url, function(txt) {
if (txt == "false") {
args.IsValid = false;
}
});
}
function MakeCall(url,callback) {
$.ajax({
url: url,
dataType: "text",
success: callback
});
}
This code DOES work:
function CheckForUserName(sender, args)
{
args.IsValid = true;
var call = MakeCall();
if (call == "false")
{
args.IsValid = false;
}
}
function MakeCall()
{
var xmlHttp;
var validation=true;
xmlHttp=GetXmlHttpObject();
if (xmlHttp==null)
{
alert ("Your browser does not support AJAX!");
return;
}
var url="/somepage.aspx";
xmlHttp.onreadystatechange=function ()
{
if (xmlHttp.readyState==4)
{
if (xmlHttp.status==200)
{
return xmlHttp.responseText;
}
else
{
alert(xmlHttp.status);
}
}
};
xmlHttp.open("GET",url,false);
xmlHttp.send(null);
return xmlHttp.responseText;
}
function GetXmlHttpObject()
{
var xmlHttp=null;
try
{
// Firefox, Opera 8.0+, Safari
xmlHttp=new XMLHttpRequest();
}
catch (e)
{
// Internet Explorer
try
{
xmlHttp=new ActiveXObject("Msxml2.XMLHTTP");
}
catch (e)
{
xmlHttp=new ActiveXObject("Microsoft.XMLHTTP");
}
}
return xmlHttp;
}
In order to make it work, you need to specify the async option as false:
function MakeCall(url,callback) {
$.ajax({
async: false,
url: url,
dataType: "text",
success: callback
});
}
This works fyi.. ignore my custom javascript namespace functions, but you should get the concept.
<script type="text/javascript">
function VerifyCustomerNumber(s, a) {
var r = ProcessCustomerNumber(a.Value);
a.IsValid = r;
}
function ProcessCustomerNumber(n) {
var u = '/Services/WebServices/Customer.asmx/CountByCustomerNumber';
var d = '{"Number": "' + n + '"}';
$j.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: u,
cache: false,
async: false,
data: d,
dataType: "json",
success: function(r) {
var v = Data.JS.Ajax.ParseJSON(r);
return v;
}
});
}
</script>
Just for the record. Having a custom validator that allows AJAX calls is possible, but is a litle complicated. Here is an article about the issue.
Basically, one must do these things:
Say "Invalid!" immediately.
Show a "processing..." message instead of your "invalid" message.
Start your long-runing process, AKA your AJAX request.
As soon as your request ends, replace the ClientValidationFunction for a dummy function.
Reset the original message.
Update the validation state.
Reset the original validation function but only when the validated control changes.
Here is the final function that accomplishes the task (taken from the article):
//Create our respond functions...
var Respond_True = function (sender, args) { args.IsValid = true; };
var Respond_False = function (sender, args) { args.IsValid = false; };
function AjaxValidator(sender, args, ajaxSettings){
args.IsValid = false;
//This is a reference to our validator control
var $sender = $(sender);
//Save the original message, color and validation function to restore them later.
var originalMessage = $sender.text();
var originalColor = $sender.css("color");
var originalFunction = sender.clientvalidationfunction;
var validatedControl = $("#" + sender.controltovalidate);
//Change the error message for a friendlier one.
$sender.text("Checking...").css({ color: "black" });
var setRespondFunction = function (respondFunction) {
sender.clientvalidationfunction = respondFunction;
//Reconstitute original styles.
$sender.text(originalMessage).css({ color: originalColor });
//Re-validate our control
ValidatorValidate(sender, null, null);
ValidatorUpdateIsValid();
var onChange = function(){
//Reset the original validation function
sender.clientvalidationfunction = originalFunction;
//Re-validate to ensure the original validation function gets called
ValidatorValidate(sender, null, null);
ValidatorUpdateIsValid();
//Ensure the validation function is called just once.
validatedControl.unbind("change", onChange);
};
validatedControl.on("change", onChange);
}
var originalSuccessFunction = ajaxSettings.success;
//Start the AJAX call..
$.ajax($.extend(ajaxSettings, {
success: function(data){
setRespondFunction(originalSuccessFunction(data) ? "Respond_True" : "Respond_False");
}
}));
}
And here is a sample usage:
function MyJavascriptValidationFunctionName(sender, args){
AjaxValidator(sender, args, {
url: ...,
type: ...,
data: ...,
success: function(data){
return /*True or false*/;
}
});
}

Resources