Ajax and PHP Web Developer Blog http://www.blaineehrhart.com Magento, Book Reviews, and Web Development Tips Tue, 04 Feb 2014 01:33:21 +0000 en-US hourly 1 http://wordpress.org/?v=3.8.3 Export Tables with and without Data http://www.blaineehrhart.com/blog/export-tables-with-and-without-data http://www.blaineehrhart.com/blog/export-tables-with-and-without-data#comments Fri, 13 Jan 2012 21:38:58 +0000 http://www.blaineehrhart.com/?p=511 Mysqldump does not export tables with data and without data at the same time. It does however support exporting the two sets of data separately.

My problem was that I needed to find a way to exclude certain tables’ data because they contained information that was not important to the dump. I did not want to exclude the tables completely because I wanted the truncated tables in the dump. The solution was to make two dumps and combine them into one dump.

The first dump we use the ignore-table parameter to exclude tables that we do not want data for.

mysqldump -u USERNAME -p DATABASE_NAME --ignore-table=DATABASE_NAME.TABLE_NAME > quick_dump.sql

The second dump makes use of the no-data and tables parameters. The no-data parameter specifies that the dump should not include any table data. The tables parameter limits the dump to the tables you supply. The final special thing we use here is “>> quick_dump.sql” to concatenate the two dumps together.

mysqldump -u USERNAME -p DATABASE_NAME --no-data --tables TABLE_NAME >> quick_dump.sql
]]>
http://www.blaineehrhart.com/blog/export-tables-with-and-without-data/feed/ 0
SQL Reference ID Naming http://www.blaineehrhart.com/blog/sql-reference-id-naming http://www.blaineehrhart.com/blog/sql-reference-id-naming#comments Thu, 28 Jul 2011 09:51:34 +0000 http://www.blaineehrhart.com/?p=489 Readable code is important when you are working with others. If you plan to work with others on projects it is good to learn the appropriate way to do things. In some cases there are many appropriate ways to do one thing but it also important to consider the readability.

For instance, some people write their tables primary id name as ID, id, or table_name_id. While people may argue about the appropriate way to do it, all of these are correct as long it is constant throughout the project.

The problem I see developers running into is naming reference table IDs. This can cause confusion for other developers. The appropriate way to reference another table’s ID is to include the table full table name. You never know when you are going to have similar table names that will cause confusion for another developer.

Here are some example reference IDs and the tables that they would link to the IDs from.
user_id is from the user table.
user_group_id is from the user_group table.
client_group_id is from the client_group table.

Here is an example of where another programmer might have trouble easily understanding your database. If you have a database with several tables including user, client_group, and user_group. And the user table references the user_group table with a column named group_id. Another programmer may assume that group_id is actually referencing the id from the client_group table.

]]>
http://www.blaineehrhart.com/blog/sql-reference-id-naming/feed/ 0
Dojo.xhr form submit button value http://www.blaineehrhart.com/blog/dojo-xhr-form-submit-button-value http://www.blaineehrhart.com/blog/dojo-xhr-form-submit-button-value#comments Fri, 24 Jun 2011 06:42:55 +0000 http://www.blaineehrhart.com/?p=500 When using the dojo.xhr methods to submit a form, the value of the submit button is not sent with the the other parameters. To solve this all we have to do is get the target that submitted the form and attach it to the content parameter of the xhr method you are using.

var formConnect = dojo.connect(dojo.byId('myForm'), "onsubmit", function(event) {
    event.preventDefault();
// Important part
    var content = new Object();
    var target = (event.explicitOriginalTarget)?event.explicitOriginalTarget:null;
    if (target != null && dojo.attr(target, 'name') != null && dojo.attr(target, 'value') != null && (target.tagName == 'BUTTON' || target.tagName == 'SUBMIT')) {
        content[dojo.attr(target, 'name')] = dojo.attr(target, 'value');
    }
    var xhrArgs = {
        form: dojo.byId('myForm'),
// Other important part
        content: content
    }
    var deferred = dojo.xhrPost(xhrArgs);
});
]]>
http://www.blaineehrhart.com/blog/dojo-xhr-form-submit-button-value/feed/ 0
How to Freelance for a Living http://www.blaineehrhart.com/blog/how-to-freelance-for-a-living http://www.blaineehrhart.com/blog/how-to-freelance-for-a-living#comments Sun, 22 May 2011 17:37:56 +0000 http://www.blaineehrhart.com/?p=481 Freelancing has many perks such as choosing your vacation days, working the hours you want, and you get paid what you want. It also has its downsides such as money flow, lack of social interaction, and finding motivation to work from home. This article is going to talk about how to work as a freelance developer for a living.]]> Freelancing has many perks such as choosing your vacation days, working the hours you want, and you getting paid what you want. It also has its downsides such as money flow, lack of social interaction, and finding motivation to work from home. This article is going to talk about how to work as a freelance developer for a living.

Getting Started

Experience + Skill + Location = Worth

How much are you worth? This varies depending on your experience, skill, and location. Ask some locals of your skill level what they charge for their services and start there. You can also undercut their prices and offer to do work for them. This way they can make a profit and you have a source of income. In my field I have seen freelancers charge $15-$300 an hour. Do not ask clients how much you should charge. Not only does this show your inexperience, but makes them feel like you are not worth what they are paying you.

Where do you find clients? Contacting development and design firms or other freelancers is a great place to start because many of them need “part-time” freelancers. The majority of my business is from word of mouth. By keeping clients satisfied they tell others about me. About 5% is from business cards that I give out to people who are interested. I have about 100 of 250 cards from two years of business. Finally, 5% of my business is from this website. I do not compete directly with the thousands of other web development websites. Instead I refer clients who want to see my portfolio and resume. I compete for local clients because people prefer someone they can meet. The blog and other content on my site are to help other programmers and introduce them into the world of web development.

What about invoices and taxes? FreshBooks handles tracking time on projects, business expenses, and invoicing clients. I use timerSync with FreshBooks to make time tracking even easier. I have both a business checking and savings accounts. I use the checking account to pay for business related expenses and use the savings account for taxes. Once a month I review the checking account history and categorize my expenses in Freshbooks. My categories include: lease, utility, travel, service, invoice, supplies, fees, depreciating assets, and software. These are grouped to make my taxes easier to file at the end of the year. Here are a few things I write off as expenses: Miles driven and meals when meeting with clients, a percentage of my home utilities and rent that I use for my office, hosting, domains, cell phone, and office furniture. If you buy it for use in your business you can usually write it off. Check with a tax adviser if you have questions.

A fellow freelancer, Dan Decort, recommends getting a Certified Public Accountant. He says “They are worth every penny and do wonderful job at saving me money on taxes”.

Put 25% away for taxes, make sure the ratio is appropriate for your tax bracket

A CPA will manage all of your money and handle your taxes. I don’t have a CPA out of personal choice, it is possible however that in the future I might get one. I am responsible enough to put 25% of all my income into business savings and not touch it until after taxes are paid. I use TurboTax to do my personal and business taxes. I setup a LLC and have a prepared W9 in case a client requests it. The W9 is the appropriate form for contractor work. It basically states that you are paying the taxes on the money that the client gives you.

What projects do you like to work on? At first you may not get much of a choice of what you work on but as business gets moving you will get more of a choice. You should always strive to take projects that will challenge you but not overwhelm you. It is important that your client thinks you are the smartest programmer in the world.

Keeping things moving

What about financial stability? Find a steady client or two (development firm or another freelancer) who can pay your cost of living. If your cost of living is $1,500 a month and your rate is $50 an hour, your client should consistently buy 40 hours per month. Where is the extra $500 going? Taxes. Do not forget about taxes. You may have to give them a discount on your rate to get them to spend the amount you need. Any other clients you can get are extra money. Try to save 6 months of your minimum living expenses in a savings account to use if you lose clients.

How do I keep my sanity? Working from home is challenging. It is nothing like working in an office with people, phones, and lunches. Instead you have silence, radio, and YouTube. It can and will drive you crazy unless you enjoy silence or radio. However if you have this urge to be around people one solution is to voice chat other freelancers. The conversation is usually small talk because we are working, but it is knowing that they are there helps me a great deal.

What do I do in my downtime? If you need more work start looking for new clients. Try craigslist, other job offer websites, and freelancing websites. If you are expecting clients with work in the near future try learning something new that you would not feel comfortable doing for a client. You can also write a blog to help others with problems you may have had or something you feel very knowledgeable on and can teach it with your own twist. Everyone learns differently, so your perspective may help.

Earn a raise by maintaining a lot of work. Then raise prices to lower work.

What happens when I have too much work? Clients start emailing you about the same job. You are sleep deprived (I’ve been up for 27 hours as of now). You are on the programmers diet, meaning, if nothing is within reach you forget to notice you have not not eaten in the past 12 hours. If you find yourself working for more than 40 hours a week on a constant basis and you have enough clients, raise your prices. I raised my prices by $15 and lost no clients. Try not to do this often, you just gave yourself a well deserved raise. At this point you can either find a freelancer to take on the extra work and make some money off of them. Or you can decline work of clients that have another freelancer to go to. To grow you must find, teach, and trust other freelancers to work with you.

Final Tips

Keep a good relationship with your clients. If you need to end a relationship, keep it as civil as possible for future business and referrals. Quote high and beat your quotes, it will make your client feel like they are getting a deal. If you have a client that is trying to price gouge your work do not put up with this. Explain that your rate is the standard for the quality of work they are receiving. If they feel they can get a better deal some were else tell them to go for it. I find it best to have hourly fees with detailed quotes so the project does not lose you money. If you have to have a flat price on a project, bid high and detail the work that will be done for the price.

If you have questions feel free to hit up the comments below or contact me.

]]>
http://www.blaineehrhart.com/blog/how-to-freelance-for-a-living/feed/ 0
Utah Metal Works http://www.blaineehrhart.com/portfolio/utah-metal-works http://www.blaineehrhart.com/portfolio/utah-metal-works#comments Wed, 09 Feb 2011 17:34:15 +0000 http://www.blaineehrhart.com/?p=391 Todd Anderson designed a stunning website. I used CSS sprites to keep the size of the site down and fast loading. While a lot of the text is in a graphic, CSS and HTML is hiding the text so it is still very accessible and SEO friendly. The site has a control panel to update metal prices and I also skinned a WordPress blog for the site.

]]>
http://www.blaineehrhart.com/portfolio/utah-metal-works/feed/ 0
PHP Recursive Regex Pattern http://www.blaineehrhart.com/blog/php-recursive-regex-pattern http://www.blaineehrhart.com/blog/php-recursive-regex-pattern#comments Wed, 05 Jan 2011 22:06:46 +0000 http://www.blaineehrhart.com/?p=411 Recently I had a client that needed their emails formatted with headers. Bender (my contact form class) did not easily support this. I needed the ability to parse a string and split it up into an array based on square brackets. And have the ability to do this at infinitely deep levels. I also wanted it to be very flexible and forgiving, since other people use bender and they may accidentally do something different.

In my regular expression, I only look for a very select few characters and the rest get thrown out. This allows the user to use characters that are not a-z, 0-9, or underscores to separate the values in the string. New lines will also work to separate the values. I’ve also added indentation in my example to make easier to read, this does not affect the parser’s ability to separate the values. If the user wanted they could put this on a single line and separate the values by commas or another character.

This is the example input:

$string = '
personal_information[
	first_name
	last_name
	email
	private_information[
		birth_day
		mothers_name
		fathers_name
	]
	previous_employers[
		company_1[
			company_1_name
			company_1_start_date
			company_1_position
		]
		company_2[
			company_2_name
			company_2_start_date
			company_2_position
		]
	]
]
how_did_you_find_us
comments
';

The output is a multidimensional array that is built by a recursive function and a recursive regular expression.

function parseInput ($string) {
	$array = array();
	// The pattern searches for string[*] recursively finding the appropriate closing and opening brackets
	// It does this by the use of ?R which makes it a recursive regular expression
	$pattern = "/([\*a-zA-Z0-9_]+)(?:\[((?:[^\[\]]+|(?R))*)\])?/";
	preg_match_all($pattern, $string, $matches, PREG_OFFSET_CAPTURE);
	// $matches[0] is the value and children: value[children]
	// $matches[1] is the value
	// $matches[2] is the children if they exist
	$countMatches = count($matches[0]);
	// loop through the matches
	for ($i = 0; $i < $countMatches; $i++) {
		// Check if the value has children
		if ($matches[2][$i][0]) {
			$array[] = array(
				'header' => $matches[1][$i][0],
				'children' => parseInput($matches[2][$i][0],true)
			);
		} else {
			$array[] = array('name' => $matches[1][$i][0]);
		}
	}
	return $array;
}
// Parse and print the $string
print_r(parseInput($string));

Here is a working example which shows the input text and output array. And here is the source code of the example.

]]>
http://www.blaineehrhart.com/blog/php-recursive-regex-pattern/feed/ 0
Redirect Index to Folder with Htaccess http://www.blaineehrhart.com/blog/redirect-index-to-folder-with-htaccess http://www.blaineehrhart.com/blog/redirect-index-to-folder-with-htaccess#comments Tue, 16 Nov 2010 18:29:40 +0000 http://www.blaineehrhart.com/?p=384 I usually would not post an article about how daft I can be, but this one deserves noting. I have the htaccess remove index.php and index.html from the url and redirect the index to the folder. This caused caused my $_POST variable to go missing. I thought it was WordPress going haywire but I was wrong.

What was really happening is that my form was pointed to index.php and it would redirect to a url without index.php and well redirects do not save $_POST values. Solution, do not write your form to post to index.php.

For those that are looking for the RewriteRule to remove the index:

RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /([^/]+/)*index\.(htm(l)?|php)\ HTTP/
RewriteRule ^(([^/]+/)*)index\.(htm(l)?|php)$ http://www\.blaineehrhart\.com/$1 [R=301,L]
]]>
http://www.blaineehrhart.com/blog/redirect-index-to-folder-with-htaccess/feed/ 1
Design Choice: PHP and Joomla http://www.blaineehrhart.com/blog/design-choice-php-and-joomla http://www.blaineehrhart.com/blog/design-choice-php-and-joomla#comments Fri, 29 Oct 2010 18:02:47 +0000 http://www.blaineehrhart.com/?p=400 Guest author, Kirsten Ramsburg, has written us an article about Joomla’s current state, ease of use, and hosting with people who make installing Joomla a breeze.

Joomla is a content management system based on the programming language PHP that allows users to create fully functional websites and manage them via a user-friendly interface panel. The interface panels are generally designed and maintained by specific Joomla providers. Partly because Joomla is an open-source program, installation can be extremely difficult for individuals who are not familiar with programming languages, requiring the assistance of an expert programmer. Originally released in 2005, Joomla has since undergone several updates to increase its operation speed and its ability to offer users specifically designed degrees of control. Getting Joomla web hosting can help ease the install because they install Joomla for you.

If you are working with Joomla, be sure to get PHP hosting as Joomla is PHP based. PHP is a bare-bones experience without the user friendliness or rapid adaptability of Joomla. PHP hosting can provide the functionality of a content management system (as it does when integrated with Joomla), but it is recommended for those individuals who write code on a daily basis. PHP 5, instead of PHP 4, should be used in conjunction with Joomla.

Updates for Joomla

Merchant Services

Joomla’s merchant package allows intermediate users to organize multiple-item shopping carts with a minimum of hassle. The shopping cart is pre-installed and pre-configured. The control panel is designed for intermediate to advanced users. Extensive experience with PHP 5 is recommended.

Automatic Twitter/Facebook Updates

Joomla can be configured to send automatic updates about newly posted articles or shopping items via RSS feed to major social networking sites. The control panel encourages intermediate users to create nuanced commands which allow for the dispersal of specific updates across a wide variety of internet sites.

More Sophisticated Access Control List

In version 1.6, Joomla assigns complete functionality to the so-called super user, while giving the administrator, manager, author, editor, publisher, registered users and the public access to different aspects of the software. While a manager has access to most of the tools of the editor and the publisher, for example, the manager does not have access to installation procedures. Editors, likewise, have a sharply defined role as set by the super user, who is the only Joomla user who has access to all panels, modes, and settings.

Article Manager

This increased specificity helps to create a more fluid and productive system, where individual users are able to take charge of those items which require their immediate attention without becoming distracted by options that either do not apply to them, or will only lead to more work for other users. This simplification extends to individual task based areas, such as the implementation of articles on the site. With different levels of control, from the global approach to the administrative level to the individual tab level, editing and implementing an article is quickly broken down into discrete tasks. Permissions can be quickly set and denied depending on the needs of the application.

Faster Overall Implementation

The changes to Joomla ultimately impact how quickly a website can post new content, alter it, or change the look of a major part of the display. In essence, the major changes to Joomla are refinements of its overall structural capability, which leads to cleaner executions of basic tasks, and less duplication and confusion of individual user responsibilities. The code structure of PHP allows for the creation of programming that inserts, protects and files information and corresponding actions in multiple databases simultaneously. Functionally, Joomla has not diminished its power but rather distilled that power in more discretely defined areas.

Kirsten Ramsburg is a senior writer for a web hosting services review company, WebHostingSearch.com.

]]>
http://www.blaineehrhart.com/blog/design-choice-php-and-joomla/feed/ 1
Custom Email Forms With PHP http://www.blaineehrhart.com/blog/custom-php-email-forms http://www.blaineehrhart.com/blog/custom-php-email-forms#comments Mon, 18 Oct 2010 10:08:01 +0000 http://www.blaineehrhart.com/?p=353 Looking for an easy way to create a custom contact form? Bender is a PHP class that also comes with a default contact form. From there you can customize the fields, styling, and input validation. Here is a guide to creating custom contact forms with Bender.

First, you are probably wondering what it looks like and how it handles. Here is an example and source of a custom form with file support. Get started by downloading the latest Bender with or without the PHP Website File Structure.

Bender’s Features

  • Simple input validation
    Is the field required or not.
  • Ability to add more input validation
    Bender allows you to easily add more validation yourself by letting you access the error array which halts the email from being sent and throws and error to the user. I’ll show you an example of this below.
  • Emails multiple people
  • Multiple types of input
    • Text inputs
    • Text areas
    • Dropdown / Select
    • Check box
    • Radio
    • Files
  • Automatic propagation of all inputs (except for files) on failure to submit
  • Simple or Akismet Captcha or neither
    Some clients prefer a simpler captcha to make sure their customers do not get frustrated filling out the forms. I found that even a very simple captcha thwarts most robots.
  • Easy customization of text
    The form and the error and success messages are easy to customize
  • Easy to understand
    The default contact.php script has everything a basic contact form needs.

Customizing Bender

Bender comes with a default form which details the configuration so even if you are not very good with PHP you can still customize it to fit your needs.

// Include the bender class so we can use it to send the email
include('benderClass.php');
$contactForm = new ContactForm();
 
// To: Email you are sending the form to. If you want more than one then seperate emails by commas
$contactForm->to = 'test@test.com';
 
// Subject: Subject of the email
#$contactForm->subject = 'Email from '.$contactForm->url;

// Input: Form input values seperate by commas, no spaces, required fields have * in front. Order by how you want them to show up in the email
// name and email are used when sending out email. If you change name or email then you also need to change benderClass.php
$contactForm->input = 'name,*email,phone,reason_of_contact,attachment,*comments';
 
// Human Code aka Simple Captcha: User must type in humancode to submit form unless ReCaptcha is enabled or humancode is empty
$contactForm->humancode = 'code55';
 
// Humant: Input name for he simple captcha
// Sometime it helps to change this if you are getting spam. Otherwise use akismet
#$contactForm->humant = 'iamhuman';

// ReCaptcha! If this info is not empty or fails form will default to Simple Captcha
// Get a key from http://recaptcha.net/api/getkey
$contactForm->publickey = '';
$contactForm->privatekey = '';
 
// freshsubmit: is a basic security feature. It helps so someone can't refresh the success page or accidentally submit twice
// freshsubmit is enabled by default when you have session_start before output and your server supports sessions
#$contactForm->freshsubmit = false;

// url: is used in the default subject and default success message
#$contactForm->url = $_SERVER['HTTP_HOST'];

// formpage: is used by the form and is sent in the email
#$contactForm->formpage = $_SERVER['REQUEST_URI'];

// Example input validation
#if ($_POST['name'] != 'Blaine') { $contactForm->error[] = 'You are not Blaine'; }

// Checks form for errors if none exist, it sends the email.
$contactForm->send();

Send to different people based on an input

if ($_GET['reply_by'] == 'email') {
 $contactForm->to = 'test@test.com';
} elseif ($_GET['reply_by'] == 'phone') {
 $contactForm->to = 'anothertest@test.com';
} else {
// Did you know you can send texts via email?
 $contactForm->to = '8015553333@<strong>vtext.com</strong>';
}

Because this form sends email, and you can send a SMS text via email, you can send SMS texts with this form. Although you might want to trim up the email sent in the benderClass.php.

Changing required inputs based on an input

if ($_GET['submit'] == 'Please Respond') {
 $contactForm->input = '*name,*email,*phone,*comments';
} elseif ($_GET['submit'] == 'No Response Needed') {
 $contactForm->input = 'name,*email,phone,*comments';
} else {
 $contactForm->input = '*name,*email,phone,*comments';
}

Contact form that sends an image

// Here we are doing some minor verification to make sure the file is an image and under a certain size. If it is not, we throw an error.
foreach ($_FILES as $key => $image) {
 if (!empty($image['tmp_name']) && !(($image["type"] == "image/gif") || ($image["type"] == "image/jpeg") || ($image["type"] == "image/pjpeg")) || !($image["size"] < 2000000)) {
 $contactForm->error[] = 'There was an error uploading: '.ucfirst(str_replace('_',' ',$key));
 }
}
<!-- enctype="multipart/form-data" on the form element must be set if you are sending files -->
<form action="<?php echo $contactForm->formpage; ?>#contactForm" method="post" enctype="multipart/form-data">
 <p>
 <label>Image</label>
<!-- this input type of file allows the user to upload a single file to the email -->
 <input type="file" name="image" />
 </p>
 </form>

Radio boxes and Check boxes

Radio and check boxes use the same function of getCheckedValue so we only need one example.

<h3>Type of Service</h3>
<p>
<!--
We want the user to be able to click the text next to the radio or check box to select the the value.
To do this we add an id to each radio box and on the label we add a for="idOfRadioBox" and this sets activates the setting.
-->
 <input type="radio" <?php echo $contactForm->getCheckedValue('type_of_service','Drop-off at Shop') ?>> <label>Drop-off at Shop</label><br />
 <input type="radio" <?php echo $contactForm->getCheckedValue('type_of_service','Mobile Service') ?>> <label>Mobile Service (We'll come to you)</label>
</p>

An extra dash of HTML

In the above example there is an easier way for letting the users tick the radio boxes. In fact it works on every field in a form. If you ever want the text that describes the input (the label) to be clickable to let you tick, check, or put your cursor in the field there is an easy way to do this. Add a UNIQUE id for each input and for=”idOfInput” to your label.

<h3>Type of Service</h3>
<p>
<!--
We want the user to be able to click the text next to the radio or check box to select the the value.
To do this we add an id to each radio box and on the label we add a for="idOfRadioBox" and this sets activates the setting.
-->
 <input type="radio" id="checkboxDropoff"<?php echo $contactForm->getCheckedValue('type_of_service','Drop-off at Shop') ?>> <label for="checkboxDropoff">Drop-off at Shop</label><br />
 <input type="radio" id="checkboxMobile"<?php echo $contactForm->getCheckedValue('type_of_service','Mobile Service') ?>> <label for="checkboxMobile">Mobile Service (We'll come to you)</label>
</p>

Download the latest Bender with or without the  PHP Website File Structure.

]]>
http://www.blaineehrhart.com/blog/custom-php-email-forms/feed/ 2
Ajax Drag and Drop List Ordering http://www.blaineehrhart.com/blog/ajax-drag-and-drop-list-ordering http://www.blaineehrhart.com/blog/ajax-drag-and-drop-list-ordering#comments Wed, 18 Aug 2010 04:10:04 +0000 http://www.blaineehrhart.com/?p=316 This tutorial is going to provide information on an easy way to create drag and drop ordering of data. This can be categories, lists, projects, whatever data you have. In this example we are working with re-arranging files. For this we are going to need to add a field to MySQL, add Dojo to your script, and of course some PHP to manipulate it all.

The Database

First, modify your database table to have an order column. Make the type an int and with a default of null. You must also have an ID or some other unique field that will let you update the fields individually. I will assume you already have one.

ALTER  TABLE  `file`  ADD  `order` INT(11) NULL ;

The Javascript

Then we need to add our JavaScript to the <head> of the page. What this is going to do is load Dojo from a CDN and then attach an onDndDrop event to the HTML code that we are going to write. The event will detect an item being dropped and then submit the form without refreshing the page.

<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.7.1/dojo/dojo.js" djConfig="isDebug: true, parseOnLoad: true"></script>
<script type="text/javascript">
dojo.require("dojo.parser");
dojo.require("dojo.dnd.Source");
dojo.addOnLoad(function(){
 dojo.connect(dragAndDropList,"onDndDrop",function(e){updateList()});
});
function updateList() {
 var xhrArgs = {
 form:dojo.byId('dragAndDropForm'),
 handleAs: "text",
 preventCache: true
 }
 var deferred = dojo.xhrPost(xhrArgs);
}
</script>

Displaying The Data in Order

You will want to use a query similar to this if you have new data entering your table after your organize the data. This works because the default value of order is NULL and the query creates a temporary alias column called isnull. The temporary isnull column will detect if order is set to null which allows us to order by isnull to separate unorganized items from organized items. We then order by order to arrange all the ordered items.

<?php
$sql = "SELECT `name`, `id`, `order`, IF(`order` IS NULL or `order`='', 1, 0) AS `isnull` FROM `file` ORDER BY `isnull` ASC, `order` ASC";
$result = mysql_query($sql);
?>

HTML Code for Drag and Drop and From

There are a few very key elements in this form. The dojoType and class=”dojoDndItem” are required to have Dojo add drag and drop to the page. The data-dojo-id is required to create a global JavaScript variable of the Drag and Drop source. You are not required to use UL and LI but you must have a wrapper and inner elements. You will also notice a hidden input which sends the order of the items discretely to update-order.php.

<form action="update-order.php" method="post" name="dragAndDropForm" id="dragAndDropForm">
<ul dojoType="dojo.dnd.Source" data-dojo-id="dragAndDropList">
<?php
while($row = mysql_fetch_assoc($result)){
 echo '<li class="dojoDndItem">';
 echo '<input type="hidden" name="order[]" value="'.$row['id'].'" />';
 echo '<a href="/download.php?id='.$row['id'].'">'.$row['name'].'</a>';
 echo '</li>';
}
?>
</ul>
</form>

Submitting the form to update-order.php

This script gets run every time the user drops an item. The form submits POST values called order[] which PHP interprets as an array. The script then just runs a loop on the array and updates the list. Obviously you are going to want to insure the data incoming is secure and you have connected to the database.

$i = 1;
foreach ($_POST['order'] as $id) {
 $id = intval($id);
 if (!empty($id)) {
  mysql_query('UPDATE `file` SET `order`="'.$i.'" WHERE `id`="' .$id.'"');
  $i++;
 }
}

Styling the Drag and Drop “hover thingy” Avatar:

Lastly- you may want to style the drag and drop actions and avatar without including the Dojo CSS files.

.dojoDndItemSelected, .dojoDndItemAnchor { background:#252525; }
.dojoDndItemOver { background:#333; }
table.dojoDndAvatar { -moz-border-radius: 0; border: 1px solid #ccc; border-collapse: collapse; background-color: #fff; font-size: 75%; color: black; }
.dojoDndAvatar td { border: none; }
.dojoDndAvatar tr { border: none; }
.dojoDndAvatarHeader td { height: 20px; padding: 0 0 0 21px; }
.dojoDndAvatarItem td { padding: 2px; }
.dojoDndMove .dojoDndAvatarHeader, .dojoDndCopy .dojoDndAvatarHeader { background-color: #f58383; }
.dojoDndMove .dojoDndAvatarCanDrop .dojoDndAvatarHeader, .dojoDndCopy .dojoDndAvatarCanDrop .dojoDndAvatarHeader { background-color: #97e68d; }
]]>
http://www.blaineehrhart.com/blog/ajax-drag-and-drop-list-ordering/feed/ 7