Toggling images with Jquery and CSS can be useful for a number of different things. I recently used it in a project to help filter search results. Where by a user would click a link, the image would grey itself out, and the records that related to said image would become hidden.
The first part of that, is getting the image to grey itself out, without the need to create a separate image for each “state” the image is in. I referred to them simply as “on” and “off” and created CSS rules for them accordingly.
.icon-Program32_on {
background-image: url('../images/32/graduated-icon-32.png');
}
.icon-Program32_off {
background-image: url('../images/32/graduated-icon-32.png');
opacity:0.4;
filter:alpha(opacity=40);
}
As you can see, i have to classes, and I add the property “opacity: 0.4″ and filter: alpha(opactiy=40). Next, the HTML was simple enough:
<ul id="right_panel_filter_results" class="sticklr">
<li>
<a href="#" id="Program" class="icon-Program32 tgl"></a>
</li>
</ul>
Then came the JQuery JavaScript, now it would be easy enough to bind these based on ID, but that’s not really the goal here. See, I might want to reuse this JavaScript for other buttons or links too. I solved this issue by adding the class “tgl” to the link here. From there, I decided that HTML element I make with the class of tgl, will be able to be clicked, and get “greyed out”. The javascript is fairly straightforward now too:
$(".tglbtn").click(function(event) {
$("#" + event.target.id).toggleClass("icon-" + event.target.id + "32 icon-" + event.target.id + "32_off");
});
So, the actual syntax of this is pretty easy, $(id).toggleClass(class1 class2) And that’s it. Now, from inside of that function you will notice that I can also do just about anything else I’m wanting too with the element (the event sent me it’s ID!).
That’s all for today. I hope to get a little further into the .each function as another way to do this sometime at a later date.
Creating forms with ExtJS is extremely easy, no more hand coding HTML, and then assigning Javascript to it, it’s all handled with ExtJS now, it makes getting the look and feel of a form right even easier. Now I’d be remiss if I didn’t at least suggest the great product that is Ext Designer. It’s a great product that makes this process even easier, but for the sole developer out there, who (like me) generally codes with no profit coming in from it, it doesn’t do anything you can’t do by hand, it just makes it a bit easier.
On to the form then, here we’re going to create a simple form with multiple fields, and with validation checking on it. To make things simple (for me), this form will pop up in a window.
I’m going to separate this out into two files (much like Ext Designer does) so that the display is separated from functions, and I will admit that it does seem to make things much easier.
So, the first file that contains the form and the window itself.
MyWindowUi = Ext.extend(Ext.Window, {
title: 'My Window',
width: 765,
height: 544,
id: 'my-new-window',
initComponent: function() {
this.items = [
{
xtype: 'form',
title: '',
width: 751,
height: 513,
id: 'my-new-form',
items: [
{
xtype: 'fieldset',
title: '',
height: 474,
items: [
{
xtype: 'textfield',
fieldLabel: 'Text Field',
anchor: '100%',
id: 'textfield'
},
{
xtype: 'datefield',
fieldLabel: 'Date Field',
id: 'datefield',
anchor: '100%'
},
{
xtype: 'timefield',
fieldLabel: 'Time Field',
id: 'timefield',
anchor: '100%'
},
{
xtype: 'numberfield',
fieldLabel: 'Number Field',
id: 'numberfield',
anchor: '100%'
},
{
xtype: 'trigger',
fieldLabel: 'Trigger Field',
id: 'triggerfield',
anchor: '100%'
},
{
xtype: 'combo',
fieldLabel: 'Combo Field',
id: 'combofield',
anchor: '100%'
},
{
xtype: 'radio',
fieldLabel: 'Radio Field',
boxLabel: 'BoxLabel',
id: 'radiofield',
anchor: '100%'
},
{
xtype: 'checkbox',
fieldLabel: 'Checkbox Field',
boxLabel: 'BoxLabel',
id: 'checkbox',
anchor: '100%'
},
{
xtype: 'sliderfield',
value: 40,
fieldLabel: 'Slider Field',
id: 'sliderfield',
anchor: '100%'
},
{
xtype: 'textarea',
anchor: '100%',
id: 'textarea',
fieldLabel: 'Text Area'
},
{
xtype: 'htmleditor',
anchor: '100%',
height: 150,
id: 'htmleditor',
fieldLabel: 'HTML Area'
}
]
}
],
fbar: {
xtype: 'toolbar',
items: [
{
xtype: 'button',
text: 'Cancel',
id: 'new-form-cancel-button'
},
{
xtype: 'button',
text: 'Submit',
id: 'new-form-submit-button'
}
]
}
}
];
MyWindowUi.superclass.initComponent.call(this);
}
});
The most important thing I can tell you to make the future easier for you, is try and give everything you think you might ever use a unique id. Also, note that you can put all kinds of wonderful things on each field or button, to see what you can do, check out the ExtJS API. (Expand the “forms” box on the left hand side, then expand fields, and select a field you wish to learn more about!)
Part 2, the second part of the form, will be up soon.
I’ve been using ExtJS since 2.2 and if you haven’t checked it out yet, please do now. Take a look at their site over at Sencha. Make sure you go into the ExtJS 4 section and check out the Demo’s and Samples to see all the javascript goodness that is their framework.
I’m going to write quite a few posts now going over some of the concepts that I use most with ExtJS 4, from writing forms to validation to saving and retrieving that information via PHP and JsonData. I will however, start with the more simple concepts like creating forms and try my best to explain how they work.
Fair warning here though. There might be (and probably are) “better” ways to accomplish what it is exactly that you’re doing. I’m a self taught kinda guy, and that means while my methods that I use might not be the best, they do work. If you have an easier / more efficient way of doing things please post it in the comments, I’ll be sure to give you credit!
I would also like to note that I am in no way affiliated with Sencha.
Had an issue a while back involving the processing of huge txt / csv files, and the solution that had always been used was “split the file into pieces of 1000 lines and run them one at a time”. When your file has 23,000 lines, that’s kind of a pain. Seeing as this is evidentely something that happens once every few months, I went ahead and wrote a little app.
It’s pretty simple really, you select a file, and tell it how many lines you want per returned file. It leaves the original file unharmed (just in case). You can download the application here: File Splitter.
** Note ** I’ve only actually tried this with .csv and .txt files. If you try this with an excel file, I will be amazed if doesn’t corrupt every file it pushes out. (Of course, you could always save your excel file as a csv).
Sorry for the delay in posting a new article. I’ve recently started learning Ruby and most of my time has been dedicated to that. Once I get a better handle on things, I will hopefully be posting some Ruby on Rails posts for everyone to look over!
In my few dealings with C#, I’ve come across the need to store data in a file outside of the properties in my application. The easiest way I’ve found to do this is to create an XML file with the data in it. I ended up creating a C# class that pulls that data into a DataTable, and then spits it back into the file when I’m done with it. I use a custom error catching class, (which I’ll get around to posting eventually), so make sure that you catch and handle your errors correctly.
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Data.SqlClient;
using System.Xml.Serialization;
using System.Xml;
using System.IO;
namespace someNamespace
{
class XML_Control
{
public DataTable read_XML(String xml_file, String res_string)
{
DataSet ds_Set = new DataSet();
ds_Set.ReadXml(xml_file);
return ds_Set.Tables[res_string];
}
public Boolean write_XML(DataTable dt, String xml_file)
{
try
{
StreamWriter xmldoc = new StreamWriter(xml_file, false);
dt.WriteXml(xmldoc);
xmldoc.Close();
}
catch (Exception e)
{
return false;
}
return true;
}
public Boolean checkForXML(string xml_file)
{
if (File.Exists(xml_file))
{
return true;
}
else
{
return false;
}
}
public Boolean deleteXMLFile(string xml_file)
{
if (File.Exists(xml_file))
{
try
{
File_Control f = new File_Control();
f.deleteFile(xml_file);
}
catch (Exception e)
{
return false;
}
return true;
}
return true;
}
}
}
I recently got to do a bit more work with C#, automating more office processes. This time I actually wrote a script to navigate around a website and check stuff out, fill out and submit forms, and on down the line, completely automated. Here is some of the major code that I used to do the trick. As always, comment if you have any questions, have any suggestions, or find any mistakes!
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using SHDocVw;
using System.Windows.Forms;
using mshtml;
using System.IO;
using System.ComponentModel;
namespace some_namespace
{
class Web_Control
{
public InternetExplorer IE = new InternetExplorer();
public string csvpath;
public string letterpath;
public string username;
public string password;
public HTMLDocument myDoc = new HTMLDocument();
public void launchIE(string sURL)
{
IE.ClientToWindow(10, 10);
object oEmpty = String.Empty;
object oURL = sURL;
IE.Visible = true;
IE.Navigate2(ref oURL, ref oEmpty, ref oEmpty, ref oEmpty, ref oEmpty);
pause(4000);
}
public void loadDocument(String username, String password, String url)
{
this.launchIE(url);
myDoc = (HTMLDocument)IE.Document;
int maxwait = 10000;
try
{
//Make sure it is loaded and ready
for (int count = 0; count < maxwait; count++)
{
if (IE.ReadyState == SHDocVw.tagREADYSTATE.READYSTATE_COMPLETE)
break;
}
if (IE.ReadyState == SHDocVw.tagREADYSTATE.READYSTATE_COMPLETE)
{
fillInField("userid", username);
fillInField("pwd", password);
submitForm("login");
}
pause(4000);
}
catch
{
//Dont forget to catch your errors!
}
}
public void uncheck(String fieldID)
{
if (myDoc.getElementById(fieldID).getAttribute("checked") == true)
{
myDoc.getElementById(fieldID).click();
}
}
public void check(string fieldID)
{
if (myDoc.getElementById(fieldID).getAttribute("checked") == false)
{
myDoc.getElementById(fieldID).click();
}
}
public void navigateTo(String url)
{
object oEmpty = String.Empty;
object oURL = url;
IE.Visible = true;
IE.Navigate2(ref oURL, ref oEmpty, ref oEmpty, ref oEmpty, ref oEmpty);
}
public void pause(int t)
{
System.Threading.Thread.Sleep(t);
}
public void clickButton(string bttnID)
{
HTMLInputButtonElement btn = (HTMLInputButtonElement)myDoc.all.item(bttnID, 0);
btn.click();
}
public void fillInField(string fieldID, string val)
{
HTMLInputElement otxtbox = (HTMLInputElement)myDoc.all.item(fieldID, 0);
otxtbox.value = val;
}
public void submitForm(string formID)
{
HTMLFormElement frm = (HTMLFormElement)myDoc.all.item(formID, 0);
frm.submit();
}
public void clickAnchor(string anchorID)
{
HTMLAnchorElement a = (HTMLAnchorElement)myDoc.anchors.item(anchorID, 0);
a.click();
}
public void resync()
{
myDoc = (HTMLDocument)IE.Document;
myDoc.recalc();
}
}
}
If you’ve ever used PHP on a load balanced website, you’ve probably felt the pain that sessions can cause. A while back, I ended up writing session data to a mySQL database to make it easier to keep sessions across servers.
The mySQL table is pretty simple, just session_id, data_key, session_data, session_expiration. A sample row would look something like: JK3342920, username, David, 2011-04-24 14:00:00. The code I’m about to post uses a DBAL called Creole, which I believe is dead now, but still works great.
<?php
/**
* Session_Class.php
*
* Class controls all Session Information and needs to be included anywhere that
* you wish to use sessions
*
* @author David Singleton <david.dsingleton@gmail.com>
* @version 2.0
* @package SiteWide
*/
require_once 'Database/Query_Class.php';
class Session {
/**
* Session ID is the ID of the Session that is created, it is currently
* stored in a cookie
* @access protected
*/
protected $SessionID;
/**
* Construct method called up class call. Will create a new session if one
* does not already exist.
*/
public function __construct() {
if(!isset($_SESSION))
{
session_start();
}
$this->SessionID = session_id();
}
/**
* SetSesVar will set a session variable based on the paramaters specified.
*
* @access public
* @param string $VarName The Name of the Variable
* @param mixed $VarValue The Value you wish to set it as(Can be any type)
* @return bool
*/
public function SetSesVar($VarName, $VarValue) {
$VarName = strtolower($VarName);
$in = new Query('prodnet');
$q = $in->getConString();
$newtime = date("Y-m-d H:i:s");
if($this->ValidVar($VarName)) {
//udpate rather than insert
$stmt = $q->prepareStatement('update sessions set session_data = ? where sessiDBAL called on_id = ? and data_key = ?');
$stmt->setString(1, $VarValue);
$stmt->setString(2, $this->SessionID);
$stmt->setString(3, $VarName);
}
else {
$stmt = $q->prepareStatement('insert into sessions (session_id, data_key, session_data, session_expiration) VALUES (?,?,?,?)');
$stmt->setString(1, $this->SessionID);
$stmt->setString(2, $VarName);
$stmt->setString(3, $VarValue);
$Newdte = date("Y-m-d H:i:s", strtotime($newtime . ' +1 day'));
$stmt->setString(4, $Newdte);
}
try {
$stmt->executeUpdate();
}
catch(SQLException $sqle) {
echo $sqle;
return false;
}
return true;
}
/**
* DelSesVar will delete a Session variable
*
* @access public
* @param string $VarName the Name of the variable to delete
* @return bool
*/
public function DelSesVar($VarName) {
$VarName = strtolower($VarName);
$in = new Query('prodnet');
$q = $in->getConString();
$newtime = date("Y-m-d H:i:s");
$stmt = $q->prepareStatement('delete from sessions where session_id = ? and data_key = ?');
$stmt->setString(1, $this->SessionID);
$stmt->setString(2, $VarName);
try {
$stmt->executeUpdate();
}
catch(SQLException $sqle) {
echo $sqle;
return false;
}
return true;
}
/**
* Prints a list of all session Variables
*
* @access public
*/
public function printSesVars() {
$in = new Query('prodnet');
$q = $in->getConString();
$result = $q->executeQuery('select * from sessions where session_id = "' . $this->SessionID . '"');
while($result->next()) {
echo $result->getString('data_key') . " : " . $result->getString('session_data') . "<br>";
}
}
/**
* Function to tell if variable is set to blank or is not set(is var valid)
*
* @access public
* @param string $VarName The Name of the variable to check
* @return mixed
*/
public function ValidVar($VarName) {
$VarName = strtolower($VarName);
$in = new Query('prodnet');
$q = $in->getConString();
$result = $q->executeQuery('select session_data from sessions where session_id = "' . $this->SessionID . '" and data_key = "' . $VarName . '"');
while($result->next()) {
$val = $result->getString('session_data');
}
if(!isset($val) || $val == "")
{
return false;
}
else
{
return true;
}
}
/**
* Function returns the value of a given variable
*
* @access public
* @param string $VarName The Name of the variable you wish to retrieve
* @return mixed
*/
public function ReturnVar($VarName) {
$VarName = strtolower($VarName);
$in = new Query('prodnet');
$q = $in->getConString();
$result = $q->executeQuery('select session_data from sessions where session_id = "' . $this->SessionID . '" and data_key = "' . $VarName . '"');
while($result->next()) {
$val = $result->getString('session_data');
}
if(!isset($val) || $val == "")
{
return false;
}
else
{
return $val;
}
}
/**
* Function to delete all session variables
*
* @access public
* @return bool
*/
public function DelAllSesVars() {
$VarName = strtolower($VarName);
$in = new Query('prodnet');
$q = $in->getConString();
$newtime = date("Y-m-d H:i:s");
$stmt = $q->prepareStatement('delete from sessions where session_id = ?');
$stmt->setString(1, $this->SessionID);
try {
$stmt->executeUpdate();
}
catch(SQLException $sqle) {
echo $sqle;
return false;
}
return true;
}
}
?>
Have you ever had to Merge a CSV file into a Microsoft Word Template for Mailings? Microsoft provided this wonderful little tool called mail merge, and it works great, given the CSV file is small enough and you have enough patience. The problem is it takes a while, and worse is that generally speaking, this type of thing isn’t something most people will do once and forget, most jobs will require for a user to do this often for customer notifications or marketing programs.
Having one such assignment handed to me, and not wanting to spend 1-2 hours every day doing this task over and over again, I came up with a C# application that will merge and print the document for me. I’ve included the code that actually does the merging.
Feel free to comment with any questions you have.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Collections;
using System.Data;
using Microsoft.Office.Interop.Word;
using WORD = Microsoft.Office.Interop.Word;
namespace someNamespace
{
class MSWord_Manipulation
{
public System.Data.DataTable csvDataTable = new System.Data.DataTable();
public void runFile(String tempPath, String csvPath, String savePath, String csvFileName)
{
Object oMissing = System.Reflection.Missing.Value;
Object oTrue = true;
Object oFalse = false;
String hasTemp = "true";
String oTemplate = "";
oTemplate = tempPath;
object _oTemplate = oTemplate;
WORD.Application oWord = new WORD.Application();
WORD.Document oWordDoc = new Document();
object sectionBreak = WORD.WdBreakType.wdSectionBreakNextPage;
WORD.WdMailMergeDestination saveit = WdMailMergeDestination.wdSendToNewDocument;
oWordDoc = oWord.Documents.Add(ref _oTemplate, ref oMissing, ref oMissing, ref oMissing);
oWordDoc.MailMerge.OpenDataSource(csvPath, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing);
oWordDoc.MailMerge.Destination = saveit;
oWordDoc.MailMerge.Execute(ref oTrue);
int wizState = oWordDoc.MailMerge.WizardState;
oWordDoc.Saved = true;
oWordDoc.Close(ref oFalse, ref oMissing, ref oMissing);
oWord.Visible = true;
System.Text.StringBuilder savename = new System.Text.StringBuilder();
savename.Append(savePath);
savename.Append(csvFileName);
savename = savename.Replace(".CSV", ".DOC");
object _savename = (object)savename.ToString();
oWord.ActiveDocument.SaveAs(ref _savename, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref oMissing);
//Set up the printer stuff
object Range = WORD.WdPrintOutRange.wdPrintAllDocument;
object Copies = 1;
object PageType = WORD.WdPrintOutPages.wdPrintAllPages;
object PrintZoomColumn = 1;
object PrintZoomRow = 1;
oWord.ActiveDocument.PrintOut(ref oTrue, ref oMissing, ref Range, ref oMissing, ref oMissing, ref oMissing, ref oMissing, ref Copies, ref oMissing, ref PageType, ref oFalse, ref oTrue, ref oMissing, ref oFalse, ref PrintZoomColumn, ref PrintZoomRow, ref oMissing, ref oMissing);
while (oWord.BackgroundPrintingStatus > 0)
{
System.Threading.Thread.Sleep(250);
}
oWord.ActiveDocument.Close(ref oMissing, ref oMissing, ref oMissing);
oWord.Quit(ref oFalse, ref oMissing, ref oMissing);
}
public static System.Data.DataTable csvToDataTable(string file, bool isRowOneHeader)
{
String[] csvData = File.ReadAllLines(file);
System.Data.DataTable csvDataTable = new System.Data.DataTable();
if (csvData.Length == 0)
{
throw new Exception("csv File Appears to be Empty");
}
String[] headings = csvData[0].Split(',');
int index = 0;
if (isRowOneHeader)
{
index = 1;
for (int i = 0; i < headings.Length; i++)
{
headings[i] = headings[i].Replace(" ", "_");
char trm = '"';
headings[i] = headings[i].TrimStart(trm);
headings[i] = headings[i].TrimEnd(trm);
headings[i] = headings[i].Replace("\"", "");
csvDataTable.Columns.Add(headings[i], typeof(string));
}
}
else
{
for (int i = 0; i < headings.Length; i++)
{
csvDataTable.Columns.Add("col" + (i + 1).ToString(), typeof(string));
}
}
for (int i = index; i < csvData.Length; i++)
{
DataRow row = csvDataTable.NewRow();
for (int j = 0; j < headings.Length; j++)
{
String valu = csvData[i].Replace("\",\"", "~");
char trm = '"';
String val = valu.Split('~')[j];
val = val.TrimStart(trm);
val = val.TrimEnd(trm);
row[j] = val;
}
csvDataTable.Rows.Add(row);
}
return csvDataTable;
}
}
}
Well, after a dispute with my hosting company, who wanted to charge me over a year of my hosting costs to restore my old site, I’ve decided to just start from scratch. Over the next week I will be working to get everything back up and going, although I fear I will not be able to duplicate my old posts, so if you’ve gotten here through a google search looking for something specific, I’m sorry. Leave a comment about what you were looking for and I’ll see what I can do for you.
Thanks!