Friday, June 12, 2009

WRAP Encourages Kerbside Recycling

Amazing News:

This week WRAP has launched a report which outlines why co-mingled recycling streams are less effective than source segregation of materials in terms of both cost and quality output.

In a leaflet entitled 'Choosing The Right Recycling Collection System' WRAP outlined their opinion:

"kerbside sort systems offer reliable material quality and lower net costs for council taxpayers. They are also capable of capturing the same volume of material as co-mingled schemes."

"Because of our priority for quality materials as a way to improve resource efficiency, WRAP believes that kerbside sort collections should be preferred where they are practical and should be in the majority of local authority areas."


I'm delighted that WRAP has taken this stance as the lead body on developing and improving materials' recycling infrastructure and systems in the UK. Their latest report adds to the body of evidence supporting kerbside sort collection systems. At EMERGE we have known for a long time that source separated collection schemes such the ones we run for councils and for businesses in Greater Manchester produce a far higher quality of material with a massively reduced risk of contamination, as well as engaging people fare more effectively in the process of managing the waste they generate.

More information about how kerbside sort schemes work for councils can be found at the Campaign for Real Recycling website and hopefully this report will be taken into consideration by other councils when they decide how to implement and improve their own recycling schemes.

Onwards & upwards!

Lucy.

Dynamically register UpdatePanel Trigger

Two approaches can be used to register the UpdatePanel Trigger:

1. At code behind, we can use UpdatePanel.Triggers.Add to add a dynamic trigger.

AsyncPostBackTrigger Trigger1 = new AsyncPostBackTrigger();
Trigger1.ControlID = "Control UniqueID"; //it's UniquelID
Trigger1.EventName = "Click";
UpdatePanel1.Triggers.Add(Trigger1);


That's the way always popular to do when we go with UpdatePanel.


2. Sometimes, we need use client-side approach to register Triggers on the fly that will be more firsthand and more convenient.

Check the following Script code:

Sys.WebForms.PageRequestManager.getInstance()._updateControls(["t"+updatepanelid],
[AsyncPostBackTriggers1_ID, AsyncPostBackTriggers2_ID], [PostBackTriggers1_ID, PostBackTriggers2_ID], 90);// Here ID is UniqueID.


The above code can register the control as the trigger of UpdatePanel. That is real what the Ajax framework is doing. When you check the source code of ajax-enable page, you can find this kind of code.

Let's research this method step on step:
1.This method is to register AsyncPostBackTrigger and PostBackTrigger on client.
2.In the first parameter, it is composted by "t"/"f" and UpdatePanel ID. "t"/"f" means if ChildrenAsTriggers is true or false.
3.In the second parameter, it is an array list of asyncpostback triggers' Unique ID.
3.In the third parameter, it is an array list of postback triggers' Unique ID.
4.In the last parameter, it is the timeout attribute.

--------------------------------------------------------------------------------------

You can choose one of these two approaches to achieve registering Trigger dynamically. However, with this approach, we can get some interesting purpose. Please check the following sample.


I have a DropdownList inside UpdatePanel with Button. When I select the first item, Button will be as PostBack Trigger and do full postback. When I select the second item, Button will be as AsyncPostBack Trigger and do partial postback. So I can do validation to decide to do as PostBack Trigger or AsyncPostBack Trigger dynamically.

<script type="text/javascript">


function check() {
var button1 = '<%=Button1.UniqueID %>';
var dropDownList1 = $get('<%=DropDownList1.UniqueID %>');
var updatePanel = '<%= UpdatePanel1.UniqueID %>';
if (dropDownList1.selectedIndex == 0)
Sys.WebForms.PageRequestManager.getInstance()._updateControls(["t" + updatePanel], [], [button1], 90); //PostBack

else
Sys.WebForms.PageRequestManager.getInstance()._updateControls(["t" + updatePanel], [button1], [], 90); //AsyncPostBack

}
</script>

<body>

<form id="form1" runat="server">
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:DropDownList ID="DropDownList1" runat="server">
<asp:ListItem>do PostBack</asp:ListItem>
<asp:ListItem>do asyncPostBack</asp:ListItem>
</asp:DropDownList>
<%=DateTime.Now %>
<asp:Button ID="Button1" runat="server" Text="Button" OnClientClick="check();" />
</ContentTemplate>
</asp:UpdatePanel>
</form>
</body>

Wednesday, June 10, 2009

Keep the TextBox Focus inside UpdatePanel

At this time, let's talk about the old issue -- UpdatePanel Focus problem
Assuming that you have a TextBox inside UpdatePanel, when you set an Ajax Timer for this UpdatePanel or set TextChanged event of TextBox in order to make the TextBox do postback, you will find it losts focus from TextBox after you type something and do postback.
For instance, please check the following sample:

<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:TextBox ID="TextBox1" runat="server" OnTextChanged="TextBox1_TextChanged"

AutoPostBack="true"></asp:TextBox>
<asp:Label runat="server" Text="" ID="Label1"></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>



protected void TextBox1_TextChanged(object sender, EventArgs e)
{
Label1.Text="you inputed " + TextBox1.Text;
//ScriptManager1.SetFocus(TextBox1);

}


In above sample, TextBox will lost focus after you press enter and doing postback.

As a solution, We can use ScriptManager1.SetFocus(TextBox1) to focus the Textbox1 again after postback. As a result, it gets the focus, but the cursor in TextBox is changed and initialized(It goes to the first charactor location, instead of keeping to the current location).

To resolve this problem so that it can keep the current location in Textbox after postback, we can use the following JavaScript to set the location in TextBox manually.


function setfocus() {
var txb = $get("<%=TextBox1.ClientID%>");
var t = txb.createTextRange();
t.collapse(true);

t.moveStart("character", txb.value.length);
t.select();

}


In addition, we need use JavaScript to store the current location in TextBox before postback and set it back after postback. See the entire sample as below.


<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
</asp:ScriptManager>
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:TextBox ID="TextBox1" runat="server" OnTextChanged="TextBox1_TextChanged"

AutoPostBack="true"></asp:TextBox>
<asp:Label runat="server" Text="" ID="Label1"></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form>
</body>

<script type="text/javascript">
var currentCaret;
function getCaret(textbox) {
var textbox = $get("<%=TextBox1.ClientID%>");
var control = document.activeElement;
textbox.focus();
var rang = document.selection.createRange();
rang.setEndPoint("StartToStart", textbox.createTextRange());
return rang.text.length;
}


function setfocus() {
var txb = $get("<%=TextBox1.ClientID%>");
var t = txb.createTextRange();
t.collapse(true);

t.moveStart("character", currentCaret);
t.select();

}

Sys.WebForms.PageRequestManager.getInstance().add_beginRequest(
function(sender, e) {
currentCaret = getCaret($get("<%=TextBox1.ClientID%>"));

});
Sys.WebForms.PageRequestManager.getInstance().add_endRequest(
function(sender, e) {

setfocus();
});

</script>



protected void TextBox1_TextChanged(object sender, EventArgs e)
{
Label1.Text = "you inputed " + TextBox1.Text;

}


Following this sample, it will store the current cursor loacation in TextBox in beginRequest event, and set it back in endRequest event. In this way, it will achieve keeping the current location in TextBox.

(It's also working if you use an Ajax Timer inside UpdatePanel.)