While working on my product hit tracking system, I had the idea of color coding my results based on the URL they were referred from. Once I got started, I realized that it was easier than I thought. The solution is pretty straightforward, but I assume that it will help someone out who is looking for a way to manipulate data based on string content.
Basically, before you bind your data to your datagrid/gridview/datagridview, cycle through all your records in search of a string. For instance, I searched for “google”, “yahoo”, and “msn.com” and subsequently surrounded that data with a respective “<span class=”google”>” or yahoo or msn. The code is easy:
Dim dv As DataView = GetData(SQL) 'populate your dataview however you do it
Dim row As DataRowView
Dim i As Integer
Dim cols As Integer = dv.Table.Columns.Count 'get the number of columns in your dataview
For Each row In dv
For i = 0 To cols - 1 'go through each cell and color code as necessary
If InStr(row(i).ToString, "google") Then 'search for the term "google"
row(i) = "<span class='google'>" & row(i) & "</span>"
ElseIf InStr(row(i).ToString, "yahoo") Then 'search for the term "yahoo"
row(i) = "<span class='yahoo'>" & row(i) & "</span>"
ElseIf InStr(row(i).ToString, "msn.com") Then 'search for the term "msn.com"
row(i) = "<span class='msn'>" & row(i) & "</span>"
Then in your CSS stylesheet you define classes for .google, .yahoo, and .msn. Easy! This technique can be applied to anything you want to do with the string value of each cell in your data set.
Anyone have a cool algorithm that does something similar to this? Please share!
Today I was trying to use this technique, but hit a snag because my datasource was bound to a Generics list (ie, List(of T)), so I found another way to do it. It’s possible to use the
RowDataBound event to iterate through the rows and cells to find what you need. Here’s an example that works for me:
Protected Sub gvExisting_RowDataBound(ByVal sender As System.Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) '8 is where inventory is kept, "stock" is the header text If e.Row.Cells(8).Text <> "0" And e.Row.Cells(8).Text <> "Stock" Then Dim str As String = "<span>" & e.Row.Cells(8).Text & "</span>" e.Row.Cells(8).Text = str End If End Sub
Solution: Kludge, and non-working kludge at that.
I’ve been searching for a good tutorial on how to make text images on the fly, and I’ve found some that are decent, but I’m looking for a way to really mess with the orientation of the letters. For instance, if I want to put the letters in an arch, is there a way to do that? I’m building an application that will allow users to preview a design they create, but I want to give them some sort of ability to modify the shape of the text, without the whole project getting way too complex. Any ideas?
Solution: There’s GOTTA be one. I just haven’t found it yet.
Ever wondered how to add a timer to your ASP.NET application? Well, yeah, you guessed correctly again: so freaking easy. Two steps to adding a timer:
- Put the timer control on your page inside your <contenttemplate> tags.
- Set the Interval property of the timer to whatever span of time you want between partial-page post-backs (in milliseconds, ie: 1000 = 1 second)
That was too easy, you say. Okay, you want to do more? How about adding one timer to control multiple UpdatePanels? To do this, you will use a technique from my second post in this series about triggers. First, follow the steps above, except put your timer elsewhere on the page outside of your UpdatePanel. Next:
- In the UpdatePanels you want controlled by your timer, add an <asyncpostbacktrigger> to your <triggers> section, and specify the Timer control in the ID attribute (ie: <asyncpostbacktrigger id=”myTimerControl” />)
- Next, in that same trigger tag, add the attribute “eventname” and put in “Tick” as the value (ie: <asyncpostbacktrigger id=”myTimerControl” eventname=”Tick” />)
- Sit back and watch as all your UpdatePanels automatically update themselves.
If you really want to blow your mind, try adding several timers to your page that refresh at different intervals and linking them up to different UpdatePanels.
Seriously, so freaking easy, Microsoft. What happened to the days of making things challenging? KIDDING! KIDDING! Oh man, I’m sorry guys, I blew it for all of us.
EDIT: Remember, you can alter the behavior of the Timer control programmatically as well. For instance, to turn off the timer, you can create a button or checkbox or something that does: myTimer.Enabled = False. To alter the interval: myTimer.Interval = 60000 (or whatever).
As you might be able to tell by my previous posts, I’ve started looking into ways to AJAX parts of my site. I realized, though, that I wouldn’t be able to do this on a global level with a form that encompasses the whole page and then use UpdatePanels wherever I need them because both Google and PayPal require their own, non-runat=”server” forms. So far I’ve been unsuccessful in my attempts to get a PayPal/Google Checkout form to submit to their respective sites when they’re enclosed by a runat=”server” form.
Anyone have any ideas on how to do this?
Status: Solved (9/28/07)!
Solution: See this post.
Recall (in my first post, see link above) how I mentioned you had to add a ScriptManager to your form in order for ASP.NET AJAX to function. Well, if you’re not adding your own scripts to the site, that’s all you need to do with it. However, if you would like to add your own scripts, doing so is ridiculously easy.
To add custom scripting, within your <asp:scriptmanager></asp:scriptmanager> tags, simply add the following:
<asp:scriptreference path=”~/scriptFolder/yourScript.js” />
You guessed it. That’s it.
Ok, not entirely it, but mostly. If you want, you can also add these two lines to your scripts to notify the client side ASP.NET AJAX framework when the script is finished loading:
if (typeof(Sys) !== ‘undefined’)
I’ve tried it without these lines and had no problem running my scripts, but if you are having problems, maybe adding these lines may help.
My last post highlighted how easy it is to implement asynchronous postbacks using ASP.NET and AJAX but didn’t go into much depth. Here I’m going to explain a little bit more (at least so far as I’ve learned!) about triggers. You most likely have these on your site already and just don’t know it (or do). Any time someone presses a button or selects something from a dropdown that automatically posts back, that’s a trigger. Typically, this performs a full page post back, reloads your page, and performs the designated code for that trigger. In ASP.NET/AJAX, you can decide whether or not you want to trigger a full page refresh or a partial page refresh simply by designating a trigger.
Between your <asp:updatepanel> tags and outside your <contenttemplate> tags, create a <triggers> tag. Inside this tag, you have the option to create two types of tags: <asp:postbacktrigger controlid=”yourControl” /> and <asp:asyncpostbacktrigger controlid=”yourControl” eventname=”yourEvent” />. If you don’t supply either of these, your update panel automatically assumes that all controls within it are the latter. However, sometimes you need to designate a control to do a full page postback. For instance, file uploading won’t work using AJAX (unless you use some crazy IFrame methods), so you will have to set whichever button you use to submit your file to trigger a full page postback (<triggers><asp:postbacktrigger controlid=”yourFileUploadControl” /></trigger> <contenttemplate>…</contenttemplate>).
If you have any other ASP.NET AJAX tips, please post them here!
The easiest way to create an AJAX-enabled .NET site is to first download ASP.NET AJAX (it’s free). After you’ve got it installed, in your VS2005, go to Create New Project > (Web) > ASP.NET AJAX-Enabled Web Application and create your project. Yep, that’s it.
Oh, how do you use it? Well, Microsoft has introduced a concept called UpdatePanels which delineate what content is getting “AJAXed.” But before you do anything, you have to add a “ScriptManager” control right under your <form runat=”server”> tag. If you use templates or master pages, you can usually just add this there and not worry about it. Anyways, after you’ve added your script manager, go ahead and pick a section of your page you want to update without refreshing the whole page. When you’ve done this, wrap that section in a <asp:UpdatePanel id=”yourID” runat=”server”></asp:UpdatePanel> tag. This tells the server which section you wish to update “asynchronously”, meaning separate from the rest of the page.
After you’ve surrounded the section with your update panel, you’ll need to include just one more tag before you’re good to go: <ContentTemplate></ContentTemplate>. This goes after the opening <asp:UpdatePanel> tag and below the respective closing tag with all your content between it. The reason you need this is because there are more advanced features and tags you can include within your update panel that aren’t in your content, but they aren’t necessary for just starting out.
And that’s it! Go ahead and hit your pagination or sort button inside that section and see what happens. Pretty sick, huh?
If you have an existing application that isn’t AJAX-ready and you want to make it so, there are a few more steps you need to take in the preparation stage, but implementation is, of course, the same. I can go into it if someone posts here that they want me to (I just did it with my site! Really simple).
Has anyone had any problems with .NET/AJAX implementation?
Ever gotten an error when you click submit when you enter some HTML in your form? Want users to be able to submit HTML tags? Not only is it possible, it’s easy! Somewhere in your page directive (i.e., where it says <%@ Page) on your .aspx page, simply include the attribute: validateRequest=”False”.
Yeah, that’s it.
EDIT: Be sure to check the comments by Eric on this post on how you can do this more securely! Also, for a more complete explanation, check his post on XSS Attacks.
Does anyone know how to use more than one login page using forms authentication and Web.Config? I’m sure it’s possible, but I don’t want to mess too much with my Web.Config file and screw my whole site up. I suppose I can just create a workaround on my current login page by parsing the URL that the user is coming from, but I’d like to know how to use another login page if I really really needed to.
Solution: none yet.