PDA

View Full Version : [CLOSED] Button change Title and fireEvent in behind code



cwolcott
Jan 19, 2015, 5:13 AM
I can change the title of a Button by:



YearOption.Text = "Year: " + gYearOption;


How can I get the Button listener ChangeText to fire? I tried:



YearOption.FireEvent("textchange");


but nothing happens.

Daniil
Jan 19, 2015, 6:33 AM
Hi Chris,

I would expect it should fire even without a .FireEvent() call as that happens in the sample below.

Example

<%@ Page Language="C#" %>

<script runat="server">
protected void ChangeText(object sender, DirectEventArgs e)
{
(sender as Ext.Net.Button).Text = "New Text, seconds - " + DateTime.Now.Second;
}
</script>

<!DOCTYPE html>

<html>
<head runat="server">
<title>Ext.NET v2 Example</title>
</head>
<body>
<form runat="server">
<ext:ResourceManager runat="server" />

<ext:Button runat="server" Text="Change Text" OnDirectClick="ChangeText">
<Listeners>
<TextChange Handler="alert('The text has been changed to: ' + newText);" />
</Listeners>
</ext:Button>
</form>
</body>
</html>

cwolcott
Jan 19, 2015, 8:06 PM
Agreed. Trying to track down what is causing the change of the button text on the server side not to fire the TextChange listener.

cwolcott
Jan 20, 2015, 2:10 AM
OK, please close the thread. I am embarrassed. My problem was when I was pressing F5 to refresh the screen, my button title was not being formatted correctly. And why ...? Because i did not have a Render event.

When the dashboard is initially created it is hidden and a login dialog is first shown. After you login the dashboard is shown and thus the buttons title is changed based on the user logged in and colorized appropriately. I then changed the code a little bit and pressed F5 and now the button wasn't colorized appropriately, Why ...? Because it didn't have a render listener.

Everything works correctly now. Here is an example.



<%@ Page Language="C#" %>

<script runat="server">

protected void Page_Load(object sender, EventArgs e)
{
if (!X.IsAjaxRequest)
YearOption.Text = "Year: All";
}
protected void Doit(object sender, DirectEventArgs e)
{
YearOption.Text = "Year: 2015";
}
</script>

<!DOCTYPE html>

<html>
<head runat="server">
<title>Ext.NET v2 Example</title>
</head>
<body>
<form runat="server">
<ext:ResourceManager runat="server" />

<ext:ButtonGroup ID="BtnGrp" runat="server">
<HtmlBin>
<script type="text/javascript">
var yearSelection = function (menu, item) {
menu.up('button').setText('Year:' + item.text);
};

var renderBtnTitle = function (button) {
colorizeBtnTitle(button, undefined, button.getText())
}

var colorizeBtnTitle = function (button, oldTitle, newTitle) {
if (newTitle == undefined) return;
var valueColor = "black";

var i = newTitle.indexOf(":");
var prefix = newTitle.substr(0, i).trim();
var value = newTitle.substr(i + 1, newTitle.length).trim();
if (value != "All") valueColor = "firebrick";

button.suspendEvents(false);
button.setText(prefix + ': <b><font color="' + valueColor + '">' + value + '</font></b>');
button.resumeEvents();
}
</script>
</HtmlBin>
<Items>
<ext:Button ID="YearOption" runat="server" Text="Year: ??" Icon="Calendar">
<Menu>
<ext:Menu ID="YearOptionMn" runat="server" Title="Year" TitleAlign="Center">
<Items>
<ext:MenuItem runat="server" Text="2015" />
<ext:MenuItem runat="server" Text="2014" />
<ext:MenuSeparator runat="server" />
<ext:MenuItem runat="server" Text="All" />
</Items>
<Listeners>
<Click Fn="yearSelection" />
</Listeners>
</ext:Menu>
</Menu>
<Listeners>
<Render Fn="renderBtnTitle" />
<TextChange Fn="colorizeBtnTitle" />
</Listeners>
</ext:Button>

<ext:Button runat="server" Text="DoIt">
<DirectEvents>
<Click OnEvent="Doit" />
</DirectEvents>
</ext:Button>
</Items>
</ext:ButtonGroup>
</form>
</body>
</html>

cwolcott
Jan 20, 2015, 2:41 AM
In the sample I changed the ext:Button to ext:CycleButton which makes more sense and stops be hardcoding the prepended text "Year:" in various places.



<%@ Page Language="C#" %>

<script runat="server">

protected void Page_Load(object sender, EventArgs e)
{
if (!X.IsAjaxRequest)
YAll.Checked = true;
}
protected void Doit(object sender, DirectEventArgs e)
{
Y2015.Checked = true;
}
</script>

<!DOCTYPE html>

<html>
<head runat="server">
<title>Ext.NET v2 Example</title>
</head>
<body>
<form runat="server">
<ext:ResourceManager runat="server" />

<ext:ButtonGroup ID="BtnGrp" runat="server">
<HtmlBin>
<script type="text/javascript">
var renderBtnTitle = function (button) {
colorizeBtnTitle(button, button.getActiveItem())
}

var colorizeBtnTitle = function (button, item) {
var valueColor = "black";

if (item.text != "All") valueColor = "firebrick";
debugger;
button.suspendEvents(false);
button.setText(button.prependText + '<b><font color="' + valueColor + '">' + item.text + '</font></b>');
button.resumeEvents();
}
</script>
</HtmlBin>
<Items>
<ext:CycleButton ID="YearOption" runat="server" PrependText="Option Year: " ShowText="true"
Icon="Calendar">
<Menu>
<ext:Menu ID="YearOptionMn" runat="server" Title="Year" TitleAlign="Center">
<Items>
<ext:CheckMenuItem ID="Y2015" runat="server" Text="2015" />
<ext:CheckMenuItem ID="Y2014" runat="server" Text="2014" />
<ext:MenuSeparator runat="server" />
<ext:CheckMenuItem ID="YAll" runat="server" Text="All" Checked="true" />
</Items>
</ext:Menu>
</Menu>
<Listeners>
<Render Fn="renderBtnTitle" />
<Change Fn="colorizeBtnTitle" />
</Listeners>
</ext:CycleButton>

<ext:Button runat="server" Text="DoIt">
<DirectEvents>
<Click OnEvent="Doit" />
</DirectEvents>
</ext:Button>
</Items>
</ext:ButtonGroup>
</form>
</body>
</html>

cwolcott
Jan 20, 2015, 2:46 AM
I thought I would need to suspend and resume events in the colorizeBtnTitle function, but it looks like I can remove them without any issues.

Daniil
Jan 20, 2015, 6:06 AM
Yes, it looks like the suspendEvents and resumeEvents might be removed safely.

Thank you for sharing the code samples.

Just a few small tips.

1. I would try to use a BeforeRender handler instead of Render.

<BeforeRender Fn="renderBtnTitle" />

The sense is to do as much as possible before rendering. For example, in this case if you apply a new text to already rendered element it deals with a DOM to update the text inside a rendered HTML element. Otherwise, if you do it before rendering, the only thing happens that a new text is applied to a JavaScript property that is used on rendering. Well, sure, it doesn't speed up anything in your test case, but it is just some rule to adhere - avoid DOM operations if possible.

2. You may like to to use Ext.String.format.
http://docs.sencha.com/extjs/4.2.1/#!/api/Ext.String-method-format

This

button.setText(button.prependText + '<b><font color="' + valueColor + '">' + item.text + '</font></b>');
could be revised to

button.setText(Ext.String.format('{0}<b><font color="{1}">{2}</font></b>', button.prependText, valueColor, item.text));


3. Personally, I would avoid using a <font> tag. It is now treated as obsolete.
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/font

You could use a span

button.setText(Ext.String.format('{0}<span style="color:{1}; font-weight: bold;">{2}<span>', button.prependText, valueColor, item.text));

I would also recommend you to define CSS classes instead of hardcoding styles.