Showing posts with label Web Design. Show all posts
Showing posts with label Web Design. Show all posts

Sunday, January 11, 2015

Andy's CSS Best Practices



While a lot of languages have pretty well defined sets of best practices, CSS seems to fluctuate on a monthly basis. Is the cascade good or bad this week? Am I trying to be modular, or trying to have a few selectors as possible? Are classes good or bad? If you search in Google for "CSS Best Practices", you'll numerous articles explaining why "X Method" is the "RIGHT WAY". Problem is, that a lot of times these different methods contradict. The most sane article I've read on the topic in a long time was by Chris Coyier over on CSS-Tricks, entitled, "CSS: Just Try and Do A Good Job". He brought up a lot of these issues, and reached the conclusion that as long as you are trying to keep things logical and easy to read, then you're on the right track. Don't be lazy, do what makes sense, etc. Inspired by this, I'd like to share my set of CSS Best Practices ... the method to my madness, if you will.

Use One Stylesheet


As tempting as it is to split up stylesheets, I try to avoid this for performance issues. In this, as with everything, there are other opinions, but I prefer to avoid multiple files being downloaded.

Attach Styles to Elements (Not Classes or IDs)


This is the main point. With the rise of HTML5, we have a lot more elements to play with. I like to attach my styles directly to the elements, and then use classes as modifiers. I try to avoid using IDs at all (for styles). Example:

<article>
  <h2>Header</h2>
  <p>Content goes here.</p>
  <p class="highlighted">Content goes here.</p>
</article>


h2 {styles here...}
span {styles here...}
span.highlight {modified styles}


My styles are attached to the h2 and span elements, while the class is used solely as a modifier. I never use classes by themselves, and I almost never use IDs. As with any rule, there are exceptions. The website logo, for example, I might identify with #logo, since it's unique on the entire site.

Nesting Is Okay


If I have a span inside an article that behaves in one way, plus a span in the footer which behaves differently, I'll use:

article span {styles here...}
footer span {styles here...}


Rather than give them classes. Many people say that we should try to avoid over specificity, and that nesting is entirely bad. I agree that we should try to minimize specificity, but we only have a limited number of elements to work with so there's going to be some. I do sometimes get around the element limit by "cheating though", which leads me to my next point:

Custom Elements (The "Bad" Way)


HTML5 gives us an official way to make custom elements. It's clunky because they have to have two words separated by a dash. Plus browser compatibility sucks. But here's the thing. As long as we are just talking container elements, I can name it anything I want to. I just have to make sure to define it with "display:block" in the CSS. I can have , or , or . This opens up everything, and the code starts to look Very nice. Plus it works all browsers. It's officially a bad idea, but so what? It works and it makes your HTML and CSS look really nice. Example:

<person>
  <h3>
    <display>John Smith</display>
    <edit></edit>
    <cancel></cancel>
  </h3>
  <span class="editable">
    <display>(555)-555-5555</display>
    edit></edit>
    cancel></cancel>
  </span>
  <span>
    display>johnsmith@email.com</display>
    edit></edit>
    <cancel></cancel>
  </span>
</person>


person {Styles here...}
person display {Styles here...}
person edit {Styles here...}
person cancel {Styles here...}


Person, Display, Edit, and Cancel are all fake elements. But in this example (taken from a web app I'm currently building) they allow for code which is much easier on the eyes. Take a look at the same structure without custom elements.

<div>
  <h3>
    <div>John Smith</div>
    <button class="edit"></button>
    <button class="cancel"></button>
  </h3>
  <span class="editable">
    <div>(555)-555-5555</div>
    <button class="edit"></button>
    <button class="cancel"></button>
  </span>
  <span>
    div>johnsmith@email.com</div>
    button class="edit"></button>
    button class="cancel"></button>
  </span>
</div>


div.person {Styles here...}
div.person h3 div {Styles here...}
div.person span div {Styles here...}
div.person button.edit {Styles here...}
div.person button.cancel {Styles here...}


The HTML is longer and we have to add another line of CSS, or add more classes.

Summary


As stated above, there is no one right answer here for how to structure your CSS. my method is to use custom elements, apply styles to elements, use classes as modifiers, and avoid IDs. What about you? Let me know in the comments what you think.

Wednesday, September 10, 2014

Text in SVG: 3nd Attempt (Size Reduction)

Several days ago I wrote about finally solving the text in SVG problem. The key was to pick an open-source font, obtain the woff and svg font files, convert those files into base64 data streams, and plop the whole thing inside the actual SVG itself. And it works!

Problem is, I overlooked the file size. My original PNG logo file is 20KB. The new SVG is 400KB. That's 2000% increase in size! And completely unacceptable to me. I set out to find ways to decrease the size.

My first find was the tspan element. This is an element, similar to HTML's span, which can be embedded in a text element. Instead of having a new text element for every enlarged letter, I can just wrapper those letters in a tspan element and use CSS to apply the font. This helps in rendering time, but unfortunately doesn't significantly change the file size (409KB to 408KB).

I then tried removing whitespace. It screwed up the file and didn't really save space.

My final idea was to look at the cause of the large size. The current SVG had both an SVG and WOFF font file embedded. Looking at the font size, it turns out that the SVG font files were huge. 120ish KB each, for the two fonts I'm using. And an SVG font is readable if one opens it in a text editor. It's kind of odd to look at, but I found a pattern, and I found saw each letter and typical character. I simply removed all characters that I'm not using for the logo. Doing this for both fonts and reencoding in base64 netted me a huge size reduction. The SVG logo is now down from 408KB to 120KB. That is still far larger than 20KB, but it's a gain I can live with given the sharpness benefits of SVG.

This does mean that if the text ever changes in the logo, I'm going to have to go back to my original font files and add or subtract certain characters. But the text is a company name, meaning it won't change often. I've texted in Chrome and Firefox on Android, along with Chrome, IE11, and Firefox on Windows. Take a look at the 408KG and 120KB versions below:

SVG 408KB:

SVG 120KB:

Monday, September 8, 2014

Text in SVG: 2nd Attempt

Last week I attempted to convert a complex logo involving text into SVG, and failed. This was due to the fact that the logo in question used Palatino Tinotype, which is a font that seems to be completely safe because it's installed on all Windows and OSX machines. However, this is actually not an open source font, and Android phones don't come with it. The logo ended up using the default serif font for Android, which messed up the spacing and looks quite terrible.

Additionally, Chrome on Android doesn't support the CSS selector "first-letter", which I had been using to increase font sizes. I have since been able to address both of these problems. I split the "text" elements so that all first letters of increased size were in their own wrapper, which I applied a class to. Increasing the font size using this class works on all browsers. The font issue was more complex. The owner of the logo declined to pay $165 to buy Palatino Linotype, so I had to find a free alternative. After searching for a while, I came across TeX Gyre Pagella. This is a free font, and it looks extremely similar to Palatino Linotype. And so without further ado, I present the final product along with original PNG for comparison:

SVG:

Original PNG:



EDIT:

It turns out at at the time I posted this, I was STILL missing something. When SVG files are embedded, they can't have any external dependencies. This includes referencing fonts. I therefore had to convert the fonts to a data URI stream. To be entirely honest I have no idea how it works, except in concept. It takes the entire file, converts it into a special text language, and I insert that text blog into the spot that I'd put the font address. I found a very nice tool, which let me upload the font files.

One issue I now see is that the SVG file is much larger. We are talking 400KB instead of 5 or 10. This somewhat destroys a large advantage of SVG in the first place, which is the smaller file format. However, it retains the perfect sharpness at all sizes, which is worth it. I've edited the file which is previewing above, so it should look great on all devices, finally. If it doesn't on whatever you are viewing it in, please let me know!

EDIT 2:

Turns out that IE9-11 screws up the SVG if it is resized. This is because IE requires an extra attribute on the SVG element, called "viewbox". Since my SVG width is 1220 and height is 200, I have to add this: viewbox="0 0 1220 200". More information here.

Wednesday, August 6, 2014

Creating SVG with CodePen.io

Over the past few days, I've been exploring the SVG image format, and I converted my own logo, with great results. I decided to try my hand at a more complex logo, and I decided that instead of typing, saving, and refreshing the browser, I'd use Codepen.io. I chose this testbed over my normal JSFiddle.net testbed due to it's live updating capability.

I'll go into detail another time about the new logo, but suffice to say I got it working. To test in a webpage, I really wanted to just take the codepen that I'd created and embed it. They have a nifty feature where you can write JS or CSS in one 'pen, and embed the whole 'pen into another. Turns out this wonderful recursion doesn't work with inline SVGs though. It would be a great feature to have, though, I think. Apparently the creators of CodePen agree (and are also VERY timely with feature request responses. The ability to embed inline SVG 'pens into another 'pen is now on the feature shortlist!

Monday, August 4, 2014

SVG vs PNG Logo Results

Earlier today I wrote about the method I used to convert my website logo from a scalar PNG to a vector SVG file. I wanted to share the results with you.I opened the site up in Firefox, and then CTRL+ zoomed in as far as possible. Then I screenshot'd a before and after:

Scalar PNG Logo:




Scalar PNG Logo:




Another nice feature is a size reduction of the image file. I went from 604B to 294B, which is a better than 50% reduction! Granted, both files are incredible tiny, but I've tested with a more complex logo and the reduction is even better, down from 2340B to 704B.

Friday, July 18, 2014

WordPress Media Selector - Mobile

WordPress 4.0 is coming along quite nicely, with Beta 2 being due soon. One area I'm very excited about is a makeover of the mobile version of the Media Selector. This is the popup that lets users insert media (pictures, video, etc) into posts. On the phone is currently looks very broken, so there's a big push right now to give it an overhaul. This is what you'd see on a phone right now, with WordPress 3.9:



As you can see, everything is squished because of how narrow the screen on a phone is. To address the problem, two major changes have been made. If the sidebar is removed, and the options a the top are changed from text links to a dropdown menu, everything gets a lot nicer. Throw in some CSS to make sure all the images are in a nice looking grid, and suddenly you have this:



Two changes can make a huge difference in the usability. I'm very excited about this change, along with everything else that is coming down the pipeline regarding media. WP just keeps getting better.

Friday, July 11, 2014

WordPress Plugin Update

A while back, I wrote about an idea for a plugin that I was going to try and write. It would add a folder system to WordPress's media capabilities. As I later explained, this was somewhat beyond my abilities at that point. I have since, however, written two separate plugins, which are currently up on the WordPress repository.

Admin Classic Borders


In WP 3.8, the admin backend of WordPress was completely redesigned. Taking queues from Windows 8, WP was made "cleaner", which means flatter and with less borders. Overall I think it looks good, but I like borders between items. I think borders make a site or app easier to use by cleanly dividing items.



To address what I perceive as shortcomings with the new design, I wrote some custom CSS to re-add borders, along with a few other things. Admin Classic Borders is simply a plugin wrapper for that CSS, along with a settings page to let users customize.



It's currently has a 5-star rating an almost 1000 downloads, which I think says quite a bit for my school of design thought. My second plugin, Featured Galleries, is a little more in-depth, so I'll discuss it in a separate post.

Saturday, August 3, 2013

WordPress Plugin

I recently finished work on IndyGreekFest.org (Old Site), and am in my reflective period that follows every project. One issue that I ran into with this site is the organization of images on the site.

Several sections of the website are basically image galleries; food, media, etc. It would be nice if I could upload images into folders and organize them by the page in which they are embedded. Unfortunately, with WordPress, this isn't possible.

WordPress started as a simple blog software, and while it's doing an admirable job slowly transforming itself into a full CMS, it's not there yet. The way it handles images is a prime example of this. Currently, there is a single media folder, in which all uploaded images go. WordPress each month, a new folders is made by wordpress inside the media folder. All images uploaded that month go in there. Additionally, when viewing the images, there is a single list of images. One can't view folders.

It would be nice to fix this. I have sketched out several user interfaces which would incorporate folders. A real fix would require updating the core, though, which I'm not really prepared to do. A plugin, however, I think is within my current capabilities. A plugin will not be able to full accomplish my goals, but it will let me start. So tonight, I am going to write a simple Hello World plugin to teach myself the basics. Having created several themes in the past, it shouldn't be too difficult.

From there, I can start figuring out how to go about adding folders to WordPress.

Tuesday, June 4, 2013

Wordpress and the Rise of Vector Image Fonts

As a Wordpress developer (ironic, I realize, since this blog is hosted on Blogger), one thing I follow pretty closely is the Wordpress Make UI blog. An overhaul of the WP backend has been cooking for several months now, and one aspect of that overhaul is a change in the way icons are displayed. Currently, WP uses PNG rastor icons, but the new backend will likely use vector icons in the format of a font. Confused yet? Let me give you some background info.

Images come in two types: Raster and Vector. Most images you see on the internet are Raster. JPGs, PNGs, GIFs, all of these are Raster images, which means that they are static. You can think of them as a giant grid, with each point, or pixel, having a specifically set color. When all these points are put close enough together, you can't tell that it's square points. But when images are zoomed in, they look blocky. Vector images don't consist of set points. They use lines and formulas and things that I don't fully understand. The end product is an image that will look sharp no matter how far it is zoomed in and out.

Wordpress is switching from Raster to Vector, because Vector images look better when zoomed in (when using a Retina display, for example). They are also going one step further and using a font, instead of image files. Fonts have used Vector images for a long time. Each character is a small image with a transparent background. It's certainly possible to place custom images yourself. I found a very interesting article on the reasoning behind switching to icon fonts, rather than using icon image files, which I've added a link to here.

The Era of Symbol Fonts

Thursday, May 23, 2013

Storing and Retreiving Dates - PHP

I had a bit of free time over the past week, and I started working on the final section I promised to convert to CMS for the CESAC website. This section involves the annual career fair, and to save down on the number of variables I looked for static relationships. The first thing that jumped out at me were dates.

For each career fair, there are four dates that need to be dealt with. Early registration, company info sessions, career fair, and post-fair interviews. The nice thing about these is that the latter three have a static relationship. The info sessions are always the day before the fair, and the interviews are the day after. Really then, only two dates need to be stored. This does pose an additional challenge of finding the next day and previous day of a specified date, but it's worth it to cut the inputs down by half. Less to store, less code, and less chance for user screw up.

The question then became, how do I best store the dates to save space and use the most efficient code in conversion for display. In previous sections of the CESAC website I'd stored dates as three separate numbers. Example:

September 18th, 2013 becomes: month = 9, date = 18, year = 2013

Not elegant, because one needs three inputs instead of 1, and three columns in the SQL table instead of 1.

I started looking for a better way and found a few ideas, none of which I really liked. I considered an idea of creating a single large number which would then be converted mathematically into the final three numbers. These three would then be converted using PHP date() function into the final display form. Example:

September 18th, 2013 becomes: date = 09182019


I still didn't like this, because it required some complicated mathematical code, plus a second step of the date() function. I finally gave up on storing as a number, and looked into characters. Storing as:

September 18th, 2013 = date = '9-18-2013'

This might be able to plug directly into date(), saving time. In the process of testing I discovered that if the input format was changed into '2013-9-18' (which makes more sense from a logical perspective), it could indeed be placed directly into date(), saving considerable time. Success for step 1!

This left me with the issue of figuring out how to get the next/previous day. I was hoping to avoid doing some custom function writing. It would require an array of the max days in each month, to figure out if the next day was actually the 1st. Plus a math function to figure out leap years. I was saved from this by the internet, and I found that the php function strtotime() could do it for me!

  $previousDay= date("F dS, Y",strtotime($specifiedDate." -1 day"));

The outputs into the correct format, and does the math for me, no matter what is the specified date. the final code, after pulling the raw data with a query, ends up being:

  $displayDateInfo = date("F dS, Y",strtotime($dateCF." -1 day"));
  $displayDateCF = date("F dS, Y",strtotime($dateCF));
  $displayDateInt = date("F dS, Y",strtotime($dateCF." +1 day"));
  $displayDateReg = date("F dS, Y",strtotime($dateReg));

Clean, concise, and with half the columns used up for storage.

Monday, October 15, 2012

Dynamic CSS

So for a long while I've wanted to be able to dynamically update CSS. This is especially useful in creating a dynamic Wordpress theme framework. I've finally figured out a way to do so, and it's really simple. There are three steps.



Step 1:

First, rename your CSS file from '.css' to '.css.php'.

style.css

style.css.php



Step 2:

Next, (and this might be obvious), update the link in your HTML file from ...

... to ...




Step 3:

At the top of your CSS document, insert this:
<?php
    header("Content-type: text/css; charset: UTF-8");
?>



And now you can put in whatever CSS you want statically, plus insert PHP variables the same as you'd do with HTML.

Static:
body {
    background-color:rgb(200,230,255);
    margin:0;
    padding:0;
}

Semi-Static
body {
    background-color:<?php echo 'rgb(200,230,255)'; ?>;
    margin:0;
    padding:0;
}

Dynamic
body {
    background-color:<?php echo bg_color_light; ?>;
    margin:0;
    padding:0;
}
 

Thursday, September 20, 2012

Catstache's First Website!

Catstache Design, LLC finished it's first website yesterday. While it would have taken all of a week or two had I been working full time, it ended up taking nearly a month. Productivity really takes a hit when 3/4s of one's time is suddenly involved in going to classes and working on homework.

Anyway it's a simple WordPress site, with custom home, contact, and portfolio page templates. I did have to fork a plugin that added a page widget, but overall it wasn't too complex. You can check it out at:

www.dggraphicsigns.com

The most complex part was figuring out how to install WordPress on a Network Solutions hosting package. There were several tutorials, all of which were out of date. Didn't help that their control panel is pretty terribly designed. But in the end it got figured out.

We're starting on our next project already. The initial design work was completed over the summer but it got delayed. And someday I need to find time to actually build out own site. Someday ...
 

Monday, August 13, 2012

No I'm Not Dead

Yeah it's been almost three weeks, but don't worry, I'm still around. Life has just gotten really busy (Work, getting ready for school, a new g/f). But it's been fun. Catstache is on it's way, we're halfway through designing and building our first website. (Which I'll talk about more later).

The main topic of this post is about online presence. My own specifically. My full name is Andrew Z Mercer. So how do I go about starting a personal website about myself? I could choose andrewzmercer.com. That's a bit long. andrewmercer.com, andymercer.com, azmercer, amercer.com. So many to choose from. Plus, several are already taken.

The best bet is to wait until there's a good deal on cheap domain names, and then grab them all, and have 'em auto forward to the one I want to use primarily. So I'd pick andrewmercer.com. Then if someone goes to andymercer.com, they land on my website at andrewmercer.com.

The biggest problem is as mentioned above, the best ones are already taken. But hardly used well. AndyMercer.com for example is a single page in dedication to another Andy Mercer, who died in '08. AndrewMercer.com is a blank white page. The latter especially, isn't really being used. The key then, is just grab what is available now, and then over the next few years be watchful and when something pops up, grab it too. URLs are pretty cheap to maintain.
 

Tuesday, July 24, 2012

Remove Query From URL Using PHP

I had some free time the past two days, so I've been working on finishing up the the CESAC members area. While I had the Add New Members functionality complete, adding the Edit Existing Member was more interesting.

Given that it's both A, an obscure small site, and B, already password protected, I'm not putting all that much effort into security. Mostly I'm trying to idiot proof it rather than prevent a determined hacker. As such, on pages that should only be accessed in pattern, I'm just grabbing the referrer and validating it against what the previous page should be.

This is fine, until you get start using a single edit page to edit any member. This involves using a query in the URL, the ?ID=somenumber. And this plays hells with my validation. So what is the best way to remove the query? I googled and found a few answers, but all of them use complex filtering, or splitting the URL into pieces and then rebuilding. And since it's rebuilding, the parts that you should include have to be defined. This limits what type of URL you can use without throwing an error.

Instead of building, I'd rather subtract. I'd rather remove the query and leave everything else the same. To this end, the code below solves the problem quite nicely.

$referer = $_SERVER['HTTP_REFERER'];

  $url = parse_url($referer);

  $referer = str_replace('?'.$url['query'],'',$referer);


First we grab the initial full URL. We then break it into an array. And finally, we replace the query with nothing, essentially subtracting it.
 

Monday, July 9, 2012

Misc Updates

Been nearly 2 weeks since I last touched this blog. You might notice a new name though. No longer do you have to type in .blogspot between the name and .com. 1and1 was having a weekend special, URLs for $0.99, so I picked up thephilosophicalgeek.com. A small thing, but it makes me happy.

Catstache is finally fully official as well, we now have an operating agreement and a bank account, so we can finally start our first project. Additionally I've been picking up some work for TKOSEO, which has been nice. It'll be my first legit paycheck since December.

In other news, I mentioned several weeks ago that I was going out. And while things haven't been perfect, she hasn't told me to jump in a lake yet, so that's good! I'm going to see the new Spiderman movie with her later this week; I'm looking forward to it.

I'm going to try to start posting some things about Wordpress here soon. The stuff I've been doing for TKOSEO has been theme building from scratch, which has involved a lot of backend work. I've learned more about Wordpress in the past two weeks than any time before combined, and my first theme has a custom backend menu page that can change all sorts of options.

Hopefully I'll have time to start writing up some of the basics here. There are many advanced tutorials on the internet. But very few basic ones; everyone assumes the reader is familiar with Wordpress development.

Anyway, hopefully we won't have any more 2 week gaps here. Depends on time, as does everything.
 

Thursday, May 31, 2012

Installing Wordpress on WAMP

As I mentioned recently, I set up a server environment on my local computer using WAMP. Today I installed a fresh copy of Wordpress, so that I could play around with some realty listings plugins. Unfortunately I couldn't even get through the setup without something going wrong.

After Wordpress was installed, I created a test page, and then changed the URL linking over to use names. IE, the post's URL would be localhost/testpage/, instead of localhost/post=001. I clicked to view it, and I got a 404 error. Imagine my surprise, given that this is a pretty common change.

It took me a while to track down, but I finally found the answer and solution online. Turns out that WAMP's default Apache installation has a setting that prevents things I don't really understand from happening, which in turn prevents Wordpress from working correctly. A.N.M. Saiful over at Checkmate had the solution, which was to go into the Apache config file and mess with some settings.

Not being a server guy, I really have no idea what it means, but Wordpress now works on my localhost server, so I consider it to be a success.
 

Saturday, May 26, 2012

Web Development on Windows

As I've mentioned before, I've gotten spoiled as a Purdue student. Since we're provided with webspace on a root server that we can map to Windows as a networked drive, I can just edit files in a seemingly local folder. It makes for easy updating.

Since I'm no longer at Purdue, I have to use a VPN to gain access to this networked drive. This still works, but it's incredibly slow. Think 2KB/s speed. Slow to the point of being really unusable. Really the only way I've been able to do thinks is by creating mirrored folders locally, updating the local files, and then starting a sync and letting it run for a while, while I go do something else.

Additionally, my local machine isn't a web server, meaning that PHP files don't work. The browser will open them and display whatever HTML there is, but it will also display the PHP as the actual PHP code.

So today in the couple hours I have before heading out to a meeting, I've decided to set up a PHP web development environment. The other tech guy who was going to be working with me on KollegeKareer had mentioned it was easy if I found the right thing, and after looking around I think I've got what he was talking about. WAMP Server, standing for Windows/Apache/MySQL/PHP. I'm installing now, and we'll see if it works.

UPDATE:
Well after cleaning two hurdles, I have gotten it all working. WAMP comes with no instructions unfortunately. And from Googling, it seems that a LOT of people had both problems I had. The first is that Windows machines come with a server that's already running, from Microsoft. You either have to disable it, or change it to a different port. I found a Youtube video that explained changing the ports so that both can run together. Then I started getting an 403 Access Denied error. Turns out that WAMP comes with an Apache installation that is locked down. You have to go in and find a config file to unlock it.

That said, it's working now! w00t.
 

Thursday, May 17, 2012

Ruby on Rails

For many years I've had HTML in my toolbox. Several years ago I added CSS. Last summer I tackled Javascript/jQuery, mySQL, and PHP. Over the past year I've been polishing up my knowledge of these tools and practicing with them. Now however, it's time to add more to the toolbox. More being, Ruby on Rails.

Ruby on Rails in a website framework, similar to PHP, but much more scalable, and so better for larger projects. It uses the Model/View/Controller programming ideal, which forces designers to separate elements of a web application (site) into different parts. When something goes wrong, it's easy to find the error because everything is in a specific place for it's functionality.

I've spent the past two days reading up on all this. There's a lot to take in, because it's not just Rails (Ruby on Rails), it's also Ruby itself, the programming languages that Rails is built with, plus Git, Github, re-learning the Command Prompt (or Terminal if one is on a Mac), etc. I found a nice long tutorial, so that's been helpful. It's as long as a book though, so it's taking time.

I spent many hours yesterday just trying to get a working development environment set up on my computer. Turns out most people who do this do it on a Linux/Unix machine or on a Mac. Only recently have people been trying to push to make it easier on Windows, and there's a nice installer package now, which is very recent.

I'm doing this of course, because Rails is what we're building KollegeKareer in, and it seems that that is what I'll be doing for the summer. Probably. If I ever get a contract to sign.
 

Thursday, May 10, 2012

New Code View

I've been working for the past day on integrating jQuery and user defined javascript functions, and finally figured out what I was trying to finish. Coming here to show off the results, I realized that I'm quite tired of scripts/HTML/CSS looking terrible. So I've finally gotten around to adding a special view for code, using the open-source Syntax Highlighter. Great code, and very useful as you can see below.

So on to what I was showing off. In the members section of the CESAC website, I'm building up a set of tools that will allow future webmasters to edit the site without touching code. The current section I'm working on is the members database. One tool in that section is an Add New page. On that page, one item is an HTML textarea, for the member's description. Since the description field in the SQL database is limited to 1000 characters, I don't want people putting more than 1000 characters into the textbox. I also wanted to give them a live updating monitor of how many characters they have typed.

I gave the textarea a class of 'new_description', and the monitor 'new_description_monitor'. Below is my initial script.

$(document).ready(function(){

  if      ($(".new_description").val().length < 1)    { $(".new_description_monitor").css("color","black"); }

  else if ($(".new_description").val().length < 1001) { $(".new_description_monitor").css("color","green"); }

  else                                  { $(".new_description_monitor").css("color","red"); }

  $(".new_description_monitor").text( $(".new_description").val().length + "/1000" );

  $(text).keypress(function(event) {

    window.setTimeout(function(){

      if      ($(".new_description").val().length < 1)    { $(".new_description_monitor").css("color","black"); }

      else if ($(".new_description").val().length < 1001) { $(".new_description_monitor").css("color","green"); }

      else                                  { $(".new_description_monitor").css("color","red"); }

      $(".new_description_monitor").text( $(".new_description").val().length + "/1000" );

    }, 0);

  });
  
});
It works perfectly. It annoyed me though, because I'm using the same code twice, once on pageload, and once each type a key is typed. I wanted to be able to type out the function once, then just reference it twice. So I dove into it, went through about 10 iterations, stopped by the jQuery forums for some help, and finally arrived at what you see below.
$(document).ready(function() {

  $("textarea").each(function(){ update_monitor('.' + $(this).attr('class')); });

  $("textarea").keypress(function(event) {

    var text = '.' + $(this).attr('class');

    window.setTimeout(function() { update_monitor(text);},0);

  });

});

function update_monitor(text)
{
  var value = $(text).val().length;

  var colour = (value < 1 ? 'black' : (value < 1001 ? 'green' : 'red'));

  $(text + '_monitor').text(value + '/1000').css('color', colour);
}

The function is declared and separated entirely from the main code. Additionally, this script will handle infinite textarea/monitors on a single page, as long as the monitor has a classname that is the classname of the linked textarea plus '_monitor'.
 

Sunday, May 6, 2012

HTML Textbox Form - Character Limit

Last semester CESAC moved our registration system for the Career Fair to an online version run by Purdue Conferences. There were issues.

One big one was that the company description box said it was limited to 400 words. In reality, it was limited to 300 characters. Which is way too small. So we're working with Conferences to try and fix that.

Meanwhile I'm working on automating the member database for the Council so that the next webmaster has less code to touch. I've got the List page done, the quickedits working, and I'm almost finished building the New Member page. One feature of the page will be a text box for inputting a description for the member.

I decided, one thing that would be useful would be a live updating ticker on the side of the box, giving the user an up to date character number, so they know how much more can be added. Up to date to the point of every keystroke.

How to do this though, is the question. I googled to see if anyone else had built one, and couldn't find anything. So I just started working on my own from scratch. The first thing was how to grab the value of characters. The second would be how to update the page. And the third would be how to trigger those events on each keystroke.

First part was easy enough, it's just .val().length, added to the text box. The second part was also easy, I used .text, which replaces just the inside text of an element without having the replace the entire thing. The third was tricky though.

I considered using .keydown, but that triggers on any key, not just value keys, and if you press and hold down a key, it only triggers once, not each time the letter/number is added to the box. .keypress though, ended up being exactly what I was looking for. The final code was remarkably simple for what it does.

$(document).ready(function(){

    $(".new_description").keypress(function(event) {

        window.setTimeout(function(){ $(".new_textlength").text( $(".new_description").val().length + "/1000" ); }, 1);

    });

});

Note there is a setTimeout in there as well. I tried it without that, but the number updated before registering the changed value of characters, so it would be one off. The setTimeout fixed the problem.