Updating controls via JQuery from inside an UpdatePanel

Recently we encountered an issue when we were trying (unsuccessfully) to update a link outside an Ajax UpdatePanel using jQuery.
We wrote the change events and we noticed that they only fired once and no more. Clicking on the tickbox proved to be futile. Not even 317 clicks seemed to work.
original

After a bit of research, we found out that the Update Panels only subscribe to the page load event once and afterwards they drop the events, unless you rebind them once more.
To rebind them, you need to call the PageRequestManager and connect to the endRequest method.

var prm = Sys.WebForms.PageRequestManager.getInstance();
prm.add_endRequest(function () {…});

$('#ctl00_ContentPlaceHolder1_chkLinkedSuppliers').on('change', function () {
        if ($('#ctl00_ContentPlaceHolder1_lnkAuditReport2').length > 0)
        {
            var href = $('#ctl00_ContentPlaceHolder1_lnkAuditReport2').attr("href");
            ///Reports/AuditReport2.aspx?ID=21074&ShowAll=0&ShowAllSystems=0&ShowAllCompanies=0&ShowAllLinked=1
            href = href.replace("&ShowAllLinked=1","").replace("&ShowAllLinked=0","");
            if($(this).is(":checked")) {
                href = href + "&ShowAllLinked=1";
            }else{
                href = href + "&ShowAllLinked=0";
            }

            $('#ctl00_ContentPlaceHolder1_lnkAuditReport2').attr("href", href);
        }

    });

    var prm = Sys.WebForms.PageRequestManager.getInstance();

    prm.add_endRequest(function () {
        // re-bind your jQuery events here

        $('#ctl00_ContentPlaceHolder1_chkLinkedSuppliers').on('change', function () {
            if ($('#ctl00_ContentPlaceHolder1_lnkAuditReport2').length > 0) {
                var href = $('#ctl00_ContentPlaceHolder1_lnkAuditReport2').attr("href");
                ///Reports/AuditReport2.aspx?ID=21074&ShowAll=0&ShowAllSystems=0&ShowAllCompanies=0&ShowAllLinked=1
                href = href.replace("&ShowAllLinked=1", "").replace("&ShowAllLinked=0", "");
                if ($(this).is(":checked")) {
                    href = href + "&ShowAllLinked=1";
                } else {
                    href = href + "&ShowAllLinked=0";
                }

                $('#ctl00_ContentPlaceHolder1_lnkAuditReport2').attr("href", href);
            }

        });

It worked like a charm!

"text/javascript">
    function BindControlEvents() {
        //jQuery is wrapped in BindEvents function so it can be re-bound after each callback.
        //Your code would replace the following line:
            $('#').limit('100', '#charsLeft_Instructions');
    }

    //Initial bind
    $(document).ready(function () {
        BindControlEvents();
    });

    //Re-bind for callbacks
    var prm = Sys.WebForms.PageRequestManager.getInstance();

    prm.add_endRequest(function() {
        BindControlEvents();
    });

Advertisements

Are photoshop-like blend modes possible in HTML5?

If you’re a user of our design applications such as Photoshop and Illustrator, you know how you can create very cool effects with blend modes. An Amazon search returns many books and a Google search on ‘photoshop blending tutorial’ returns more than 200,000 results. This points to a very widely known and used feature.

Adobe: http://blogs.adobe.com/webplatform/2012/04/04/bringing-blending-to-the-web/

Capture

To be able to blend to images together like Photoshop does, we will need to use the HTML5 canvas feature. The images are loaded dynamically using Javascript.

The easy way to blend two images together can be summarized into

// Might be an 'offscreen' canvas
var over  = someCanvas.getContext('2d');
var under = anotherCanvas.getContext('2d');

over.blendOnto( under, 'screen', {destX:30,destY:15} );

The full example is featured below:

The HTML

Blending mode
Opacity
</div> <canvas id="canvas2" width="300" height="300"></canvas> </section> <section class="result"> <canvas id="result" width="300" height="300"></canvas> </section> </div>

The Javascript Code

At first we define the blending modes:

var blendingModes = {
	normal: function(a, b) {
		return a;
	},

	lighten: function(a, b) {
		return (b > a) ? b : a;
	},

	darken: function(a, b) {
		return (b > a) ? a : b;
	},

	multiply: function(a, b) {
		return (a * b) / 255;
	},

	average: function(a, b) {
		return (a + b) / 2;
	},

	add: function(a, b) {
		return Math.min(255, a + b);
	},

	substract: function(a, b) {
		return (a + b < 255) ? 0 : a + b - 255; 	}, 	difference: function(a, b) { 		return Math.abs(a - b); 	}, 	negation: function(a, b) { 		return 255 - Math.abs(255 - a - b); 	}, 	screen: function(a, b) { 		return 255 - (((255 - a) * (255 - b)) >> 8);
	},

	exclusion: function(a, b) {
		return a + b - 2 * a * b / 255;
	},

	overlay: function(a, b) {
		return b < 128
			? (2 * a * b / 255)
			: (255 - 2 * (255 - a) * (255 - b) / 255);
	},

	softLight: function(a, b) {
		return b < 128 			? (2 * ((a >> 1) + 64)) * (b / 255)
			: 255 - (2 * (255 - (( a >> 1) + 64)) * (255 - b) / 255);
	},

	hardLight: function(a, b) {
		return blendingModes.overlay(b, a);
	},

	colorDodge: function(a, b) {
		return b == 255 ? b : Math.min(255, ((a << 8 ) / (255 - b)));
	},

	colorBurn: function(a, b) {
		return b == 0 ? b : Math.max(0, (255 - ((255 - a) << 8 ) / b));
	},

	linearDodge: function(a, b) {
		return blendingModes.add(a, b);
	},

	linearBurn: function(a, b) {
		return blendingModes.substract(a, b);
	},

	linearLight: function(a, b) {
		return b < 128
			? blendingModes.linearBurn(a, 2 * b)
			: blendingModes.linearDodge(a, (2 * (b - 128)));
	},

	vividLight: function(a, b) {
		return b < 128
			? blendingModes.colorBurn(a, 2 * b)
			: blendingModes.colorDodge(a, (2 * (b - 128)));
	},

	pinLight: function(a, b) {
		return b < 128
			? blendingModes.darken(a, 2 * b)
			: blendingModes.lighten(a, (2 * (b - 128)));
	},

	hardMix: function(a, b) {
		return blendingModes.vividLight(a, b) < 128 ? 0 : 255;
	},

	reflect: function(a, b) {
		return b == 255 ? b : Math.min(255, (a * a / (255 - b)));
	},

	glow: function(a, b) {
		return blendingModes.reflect(b, a);
	},

	phoenix: function(a, b) {
		return Math.min(a, b) - Math.max(a, b) + 255;
	}
};

The Blending Code

/** @type CanvasRenderingContext2D */
var ctx1 = null;

/** @type CanvasRenderingContext2D */
var ctx2 = null;

/** @type CanvasRenderingContext2D */
var ctx3 = null;

/** Current blending mode */
var mode = 'normal';

/** Current blending opacity */
var alpha = 1;

var totalImages = 2;
var img1 = new Image;
var img2 = new Image;

img1.onload = img2.onload = imageReady;

function imageReady() {
	if (--totalImages == 0) {
		setupScene();
	}
}

function setupScene() {
	ctx1 = document.getElementById('canvas1').getContext('2d');
	ctx2 = document.getElementById('canvas2').getContext('2d');
	ctx3 = document.getElementById('result').getContext('2d');

	drawImage(img1, ctx1);
	drawImage(img2, ctx2);
	drawImage(img1, ctx3);
}

/**
 * Draw image on specified canvas context
 * @param {Image} img
 * @param {CanvasRenderingContext2D} ctx
 */
function drawImage(img, ctx) {
	ctx.canvas.width = img.width;
	ctx.canvas.height = img.height;
	ctx.drawImage(img, 0, 0);
	updateScene();
}

function updateScene() {
	// create rect for smallest image
	var width =  Math.min(ctx1.canvas.width, ctx2.canvas.width);
	var height = Math.min(ctx1.canvas.height, ctx2.canvas.height);

	var imageData1 = ctx1.getImageData(0, 0, width, height);
	var imageData2 = ctx2.getImageData(0, 0, width, height);

	/** @type Array */
	var pixels1 = imageData1.data;
	/** @type Array */
	var pixels2 = imageData2.data;

	var r, g, b, oR, oG, oB, alpha1 = 1 - alpha;

	var blendingMode = blendingModes[mode];

	// blend images
	for (var i = 0, il = pixels1.length; i < il; i += 4) {
		oR = pixels1[i];
		oG = pixels1[i + 1];
		oB = pixels1[i + 2];

		// calculate blended color
		r = blendingMode(pixels2[i], oR);
		g = blendingMode(pixels2[i + 1], oG);
		b = blendingMode(pixels2[i + 2], oB);

		// alpha compositing
		pixels1[i] =     r * alpha + oR * alpha1;
		pixels1[i + 1] = g * alpha + oG * alpha1;
		pixels1[i + 2] = b * alpha + oB * alpha1;
	}

	ctx3.putImageData(imageData1, 0, 0);
}

/**
 * @param {String} name
 */
function humanizeName(name) {
	return name.charAt(0).toUpperCase() + name.substring(1).replace(/[A-Z]/g, function(s) {
		return ' ' + s.toLowerCase();
	});
}

$(function() {
	// setup page:

	// fill blending mode select box
	var options = [];
	for (var name in blendingModes) if (blendingModes.hasOwnProperty(name)) {
		options.push('' + humanizeName(name) + '');
	}

	$('select[name=blending]').html(options.join('')).change(function() {
		mode = $(this).val();
		if (!totalImages)
			updateScene();
	});

	$('input[name=opacity]').bind('change keyup keypress', function() {
		var value = parseInt($(this).val(), 10);
		if ($(this).data('prev-value') != value) {
			$(this).data('prev-value', value);
			alpha = Math.min(1, Math.max(0, value / 100));

			if (!totalImages)
				updateScene();
		}
	}).val(Math.floor(alpha * 100));

	// load images
	img1.src = 'image1.jpg';
	img2.src = 'image2.jpg';
});

The CSS

body {
			padding: 40px 10px;
			font-family: arial, sans-serif;
			font-size: 12px;
		}

		.blending-demo {
			margin-top: 5em;
			white-space: nowrap;
		}

		section {
			position: relative;
			display: inline-block;
		}

		section:after {
			font-weight: bold;
			font-size: 60px;
			position:absolute;
			top: 50%;
			margin-left: 0.15em;
			left: 100%;
			margin-top: -0.6em;
			line-height: 1.2;
		}

		.image1, .image2 {
			margin-right: 4em;
		}

		.image1:after {
			content: '+';
		}

		.image2:after {
			content: '=';
		}

		.controls {
			position: absolute;
			bottom: 100%;
			padding-bottom: 1em;
		}

		select[name=blending] {
			margin-bottom: 1em;
		}

		label {
			display: inline-block;
			line-height: 1.5;
			vertical-align: middle;
			margin-right: 1em;
			width: 7em;
		}

		input[name=opacity] {
			vertical-align: middle;
		}

The Result

http://media.chikuyonok.ru/canvas-blending/

Call SOAP-XML Web Services With jQuery Ajax

if you would like to call a webservice which returns an XML format, why not have a read at this article:
http://openlandscape.net/2009/09/25/call-soap-xm-web-services-with-jquery-ajax/

function CallClientIDWebService() {
            var URL = "https://test.NJ.samole.com/apps/Service/SampleService/NRK/Employees";
            jQuery.ajax({
                type: "POST",
                url: URL,
                dataType: "xml",
                contentType: "application/xml; charset=utf-8",
                success: function (data) {
                    //edata = $(data).find("string").text();
                    debugger;
                    alert(data);
                }
            })
        }

Customize ajax loading image in jQuery mobile

In jQuery mobile v 1.0, to change defalt styling of ajax loading and search bar icon customize following default css.

Customize ajax loading image using css
.ui-loader .ui-icon {
background-color: transparent;
}

.ui-loader-default {
opacity: 1;
}

.ui-icon-loading {
background: url(YOUR URL) no-repeat;
}

Customize search bar icon using css
.ui-icon-search, .ui-icon-searchfield:after {
background-position: 0px 100%;
}

.ui-icon, .ui-icon-searchfield:after {
background: url(YOUR URL) no-repeat;
border-radius: 9px 9px 9px 9px;
background-size: 16px 16px;
}

.ui-icon-searchfield:after
{
opacity:1;
}

 

How to create a JSON POST request from a GET method

Let’s say you find a security hole in your system from old developers – leaving one of your webservices exposed:

http://mywebservice/MyService.asmx/SendEmail?Username=1234&Password=1224!&EmailFrom=no-reply@carra-lucia-ltd.co.uk&EmailTo=carra_lucia@hotmail.com&Subject=MySubject&Message=Dear%20Administrator,test%20mail%20here

Now how would you transform this into a POST string with JSON?


  var myURL = "http://mywebservice/MyService.asmx/SendEmail";
        var dataToUse = $.parseJSON('{"Username": "1234","Password":"1224!","EmailFrom":"no-reply@carra-lucia-ltd.co.uk","EmailTo":"carra_lucia@hotmail.com","Subject":"MySubject","Message":"' + msg + '"}');
        $.ajax({
            type: "POST",
            url: myURL,
            contentType: "application/json; charset=utf-8",
            dataType: "jsonp",
            data: dataToUse,
            crossDomain: true,
            success: function (response) {
                //email was sent
                alert("Email has been sent successfully!");
            },
            error: function (jqXHR, error, errorThrown) {
                if (jqXHR.status && jqXHR.status == 400) {
                    alert(jqXHR.responseText);
                } else {
                    alert("Something went wrong. We could not send your email.");
                }
            }
        });

MySubject

Using jQuery ajax to call asmx webservice methods

One imprtant distinction is what I mean by a JSON object and JSON format.  A JSON object is an object that can be used by javascript

var o = {data: 'value'};
alert (o.data); // this works as o is an object

JSON format is simply a literal string that can be turned into a JSON object if we parse it

var f = "{data: 'value'}";
alert (f.data); // this won't work as f is just a string and string doesn't have a data property

The following code calls a webservice that has three different SayHello functions.

[WebMethod]
public string SayHello(string firstName, string lastName)
{
    return "Hello " + firstName + " " + lastName;
}

[WebMethod]
public string SayHelloJson(string firstName, string lastName)
{
    var data = new { Greeting = "Hello", Name = firstName + " " + lastName };

    // We are using an anonymous object above, but we could use a typed one too (SayHello class is defined below)
    // SayHello data = new SayHello { Greeting = "Hello", Name = firstName + " " + lastName };

    System.Web.Script.Serialization.JavaScriptSerializer js = new System.Web.Script.Serialization.JavaScriptSerializer();

    return js.Serialize(data);
}

[WebMethod]
public SayHello SayHelloObject(string firstName, string lastName)
{
    SayHello o = new SayHello();
    o.Greeting = "Hello";
    o.Name = firstName + " " + lastName;

    return o;
}

“SayHello” returns a string

“SayHelloJson” returns a string that is an object in JSON format

“SayHelloObject” returns an object.  The SayHello class is here

public class SayHello
{
    public string Greeting { get; set; }
    public string Name { get; set; }
}

I have added the comments inline on the code, but the examples cover calling all three types of webservice method, and they also cover getting simple text back and getting JSON objects back, and also sending parameters in form encoded formats and also JSON formats.

Enjoy

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="test.aspx.cs" Inherits="WebTest.ajax.test" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
        http://../Scripts/jquery-1.4.1.js
</head>
<body>
    <form id="form1" runat="server">
    

Example A

Example B

Example C

Example D

Example E
/* SayHello returns a string SayHelloJson returns a string that is an object in JSON format SayHelloObject returns an object [WebMethod] public string SayHello(string firstName, string lastName) { return "Hello " + firstName + " " + lastName; } [WebMethod] public string SayHelloJson(string firstName, string lastName) { var data = new { Greeting = "Hello", Name = firstName + " " + lastName }; // We are using an anonymous object above, but we could use a typed one too (SayHello class is defined below) // SayHello data = new SayHello { Greeting = "Hello", Name = firstName + " " + lastName }; System.Web.Script.Serialization.JavaScriptSerializer js = new System.Web.Script.Serialization.JavaScriptSerializer(); return js.Serialize(data); } [WebMethod] public SayHello SayHelloObject(string firstName, string lastName) { SayHello o = new SayHello(); o.Greeting = "Hello"; o.Name = firstName + " " + lastName; return o; } public class SayHello { public string Greeting { get; set; } public string Name { get; set; } } */ $(document).ready(function () { // SayHello returns a string we want to display. Examples A, B and C show how you get the data in native // format (xml wrapped) as well as in JSON format. Also how to send the parameters in form-encoded format, // JSON format and also JSON objects. To get JSON back you need to send the params in JSON format. // Example A - call a function that returns a string. // Params are sent as form-encoded, data that comes back is text $.ajax({ type: "POST", url: "MyWebService.asmx/SayHello", data: "firstName=Aidy&lastName=F", // the data in form-encoded format, ie as it would appear on a querystring //contentType: "application/x-www-form-urlencoded; charset=UTF-8", // if you are using form encoding, this is default so you don't need to supply it dataType: "text", // the data type we want back, so text. The data will come wrapped in xml success: function (data) { $("#searchresultsA").html(data); // show the string that was returned, this will be the data inside the xml wrapper } }); // Example B - call a function that returns a string. // Params are sent in JSON format, data that comes back is JSON $.ajax({ type: "POST", url: "MyWebService.asmx/SayHello", data: "{firstName:'Aidy', lastName:'F'}", // the data in JSON format. Note it is *not* a JSON object, is is a literal string in JSON format contentType: "application/json; charset=utf-8", // we are sending in JSON format so we need to specify this dataType: "json", // the data type we want back. The data will come back in JSON format success: function (data) { $("#searchresultsB").html(data.d); // it's a quirk, but the JSON data comes back in a property called "d"; {"d":"Hello Aidy F"} } }); // Example C - call a function that returns a string. // Params are sent as a JSON object, data that comes back is text $.ajax({ type: "POST", url: "MyWebService.asmx/SayHello", data: { firstName: 'Aidy', lastName: 'F' }, // here we are specifing the data as a JSON object, not a string in JSON format // this will be converted into a form encoded format by jQuery // even though data is a JSON object, jQuery will convert it to "firstName=Aidy&lastName=F" so it *is* form encoded contentType: "application/x-www-form-urlencoded; charset=UTF-8", dataType: "text", // the data type we want back, so text. The data will come wrapped in xml success: function (data) { $("#searchresultsC").html(data); // show the data inside the xml wrapper } }); // SayHelloJson returns a .net object that has been converted into JSON format. So the method still return a // string, but that string is an object in JSON format. It is basically an object within an object. We still // get the "d" property back as in Example B, but "d" is an object represented in JSON format itself. // Example D - call a function that returns a string that is an object in JSON format. // Params are sent in JSON format, data that comes back is a string that represents an object in JSON format $.ajax({ type: "POST", url: "MyWebService.asmx/SayHelloJson", data: "{ firstName: 'Aidy', lastName: 'F' }", contentType: "application/json; charset=utf-8", dataType: "json", success: function (data) { var myData = JSON.parse(data.d); // data.d is a JSON formatted string, to turn it into a JSON object // we use JSON.parse // now that myData is a JSON object we can access its properties like normal $("#searchresultsD").html(myData.Greeting + " " + myData.Name); } }); // SayHelloObject returns a typed .net object. The difference between this and Example D is that in Example D // the "d" property is an object in JSON format so we need to parse it to make it a JSON object. Here the // "d" property is already an actual JSON object so no need to parse it. // Example E - call a function that returns an object. .net will serialise the object as JSON for us. // Params are sent in JSON format, data that comes back is a JSON object $.ajax({ type: "POST", url: "MyWebService.asmx/SayHelloObject", data: "{ firstName: 'Aidy', lastName: 'F' }", contentType: "application/json; charset=utf-8", dataType: "json", success: function (data) { var myData = data.d; // data.d is a JSON object that represents out SayHello class. // As it is already a JSON object we can just start using it $("#searchresultsE").html(myData.Greeting + " " + myData.Name); } }); }); </form> </body> </html>

.NET Webservice still returning XML instead of Json

I was trying to call a webservice method through the jquery ajax metod and guess what: I was always getting an xml response

$.ajax(
{
type: “POST”,
url: http://localhost:50080/ElearningWebApplication/ChatWebService.asmx/InserMessage,
data: “{}”,
contentType: “application/json; charset=utf-8”,
dataType: “json”,
crossDomain: true,
success: function (response) {
//email was sent
alert(“Email has been sent successfully!”);
},
error: function (jqXHR, error, errorThrown) {
if (jqXHR.status && jqXHR.status == 400) {
alert(jqXHR.responseText);
} else {
alert(“Something went wrong. We could not send your email.”);
}
}

}

);

 I included the correct attributes to both the service and the method

[WebService(Namespace = http://www.action.gr/&#8221;)]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
[System.Web.Script.Services.ScriptService]
public class ChatWebService : System.Web.Services.WebService
{
[WebMethod]
[ScriptMethod(ResponseFormat = ResponseFormat.Json)]

          public string InsertMessage(string text, int roomID, int userID, string color, int toUserID)
{
…..
}
}

<configuration>
    <system.web>
        <compilation debug="true" targetFramework="4.0" />
    </system.web>
    <system.webServer>
        <handlers>
            <add name="ScriptHandlerFactory"
                 verb="*" path="*.asmx"
                 type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
                 resourceType="Unspecified" />
        </handlers>
    </system.webServer>
</configuration>

Final Checklist

  1. Did you specify type: “POST” in the ajax request? A security feature of ASP.NET web services that are JSON serialized through the ASP.NET AJAX extensions is that they must be requested in a specific way. This is an important deterrent against your services being used in XSS attacks.
  2. Did you specify contentType: “application/json; charset=utf-8” in the ajax request?
  3. Did you specify dataType: “json”in the ajax request?
  4. Does your .asmx web service include the [ScriptService]` attribute?
  5. Does your web method include the [ScriptMethod(ResponseFormat = ResponseFormat.Json)] attribute? (My code works even without this attribute, but a lot of articles say that it is required)
  6. Have you added the ScriptHandlerFactory to the web.config file in ?
  7. Have you removed all handlers from the the web.config file in in ?