2.9 Features Vote Results

Earlier this month, over 3500 of you responded to our survey asking you to help us prioritize some of the media features that had been suggested for the 2.9 release. While the exact features for 2.9 have not been hammered out yet, as we continue to match up developers with features, we wanted to share the survey results and let you know what we’re thinking in terms of approach.

First, the results. The first question, and the only one that was mandatory, asked what single media feature you would choose to include in version 2.9. The top vote-getter was standalone editable photo albums (as opposed to the current per-post gallery) at 17.5%, followed closely by easier embeds for videos and other third-party content at 16.5%. Next came basic image editing (such as rotating, cropping and resizing) at 13.7%, and post thumbnails (image teasers for posts featured on the home page) at 12.9%. The rest of the features each took less than ten percent of the vote. The full list came in like this:

Results of question 1

The second question was optional (3406 people answered it), and asked you to rate each feature on a scale going from top priority down to definitely not for implementation priority. Results here were in line with the results from the first question, with most features rated as nice to have more often than anything else. The features that scored the highest in question 1 were more likely to have earned higher votes in the Top Priority column, but no feature was ranked as a Top Priority more often than it was ranked as a Nice to Have (though Media Albums, Easier Embeds and Post Thumbnails came close). The complete tabulations are shown in the chart below.

Results for question 2

Question three was getting at the same thing, but in a more granular fashion, asking you to rank the eleven features in order of priority to you. As only one feature could be assigned to each position, this prevented people from assigning the same priority to multiple features, and we wondered if it would alter the results. Though some features got more recognition in this question, the overall rankings were still in line with the results from question 1. Here are the exact votes per feature/per position:

Results for question 3

The fourth question asked for your preferences regarding including new media features in core, bundling them as plugins with the core download, or developing them as plugins but not bundling them with the core download. This vote was more interesting to watch. As the notice for the voting went first to the development community, then to the user community, it was possible to see a shift in the voting. Earlier in the voting cycle, there were more votes for bundling ‘core plugins’ for the advanced media features, while later votes skewed heavily toward just putting the features in core. This vote shows, I think, one of the differences between developer and user perspectives. While developers are heavily interested in keeping the core code lean and relying on plugins for advanced functionality, many users would prefer features they want to be included in core rather than being a separate plugin. The final tally on this question was 56.2% for including features in core, 38.1% for bundled plugins, and 5.7% for non-bundled plugins. The actual numbers:

Results for question 4

Clearly this issue deserves more discussion, and the concept of how we move toward a system of canonical plugins and/or core “packages” intended for different use cases (CMS, photoblog, portfolio, etc) will be a big topic in the months ahead.

So where does that leave us regarding features coming down the road? When the vote closed, the results were discussed in the #wordpress-dev IRC chat to divvy up feature development.

The top-voted feature, standalone photo albums, is being worked on as a Google Summer of Code project by Rudolf Lai, under the mentorship of WordPress Lead Developer Mark Jaquith. The “pencils down” date for GSOC is in less than two weeks, at which point we’ll be assessing the state of Rudolf’s project. Hopefully, we’ll be able to incorporate it with 2.9 development, do some testing, amend the code and/or UI as needed, and have this launch with the 2.9 release (in core or as plugin TBD). Undoubtedly, additional functionality will be contributed by core contributors who have also been working on media plugins.

Easier embeds, the second most popular feature, is being looked at in a couple of ways. One, more shortcodes for third-party services. Work on this has already begun. In addition, Viper007Bond, of Viper’s Video Quicktags plugin fame, has taken on the task of working on a way to improve the embed experience in core. We’re not sure quite how this will work yet, but stay tuned.

Adding some basic editing functions like 90-degree rotation, cropping and resizing was considered an obvious winner in the dev chat, and as several plugins handle this functionality, we’re hopeful it will be included soon.

Post thumbnails are being handled by Mark Jaquith, who has created this functionality before, with an assist from Scribu, who has a similar plugin in the repository.

Lower ranked features aren’t off the radar, but may take lower priority than some other (non-media) features we have in the works. One of my favorite 2.9 features is in trunk now, and changes the way we delete content. Goodbye, annoying popup asking me if I’m sure I want to delete a comment/post/etc. Hello, fast and quiet removal into a trash can, from which the content can be retrieved if it was deleted by accident. Think Gmail style. We’re also hoping to work on improving page management, though that has a number of technical issues that may cause it to be a 3.0 feature instead.

As always, you can keep track of development progress in a number of ways:
1. Keep track of Trac. Contribute a patch, test a patch, just read through tickets if you have some time to kill, whatever. There are over 500 tickets against the 2.9 milestone currently. Patches and testing can help us get that number down.

2. Follow Trac commits on Twitter. Don’t want to get involved in the nitty gritty, just want to see what’s getting committed? Follow wpdevel on Twitter and you’ll get core commit updates in your stream.

3. See what’s on the dev agenda. Each week for the IRC dev chat, there’s an agenda, created based on developer suggestions posted at wpdevel.wordpress.com. This blog also contains discussions about specific development issues.

4. Join the dev chat. The day changed this week, to accommodate European schedules. Chats are now held for one hour each week on Thursday at 21:00 UTC. That’s 5pm NYC, 2pm in California, etc. Chats are in the #wordpress-dev room at irc.freenode.com.

5. Watch this blog. If you’re not a developer and prefer to stick to major announcements, the occasional survey to help decide a feature, and security notices, just keep doing what you’re doing. Reading this blog will get you all of these things.

Thanks again for your help in prioritizing features for version 2.9, hopefully coming toward the end of the year to a server near you!

Ajaxed Sliding Shopping Cart With jQuery

With this 5th & last post of the "WRD E-Commerce Week" we will be modifying "our Ajaxed shopping cart" to create a one which is very ideal for designs with limited spaces.

The shopping cart will:

  • be hidden at the top of the page that can be displayed with a show/hide link
  • open when an item is added to the basket & auto-close
  • require a manual "hide" click if opened manually
  • enable us to delete products

Ajaxed Sliding Shopping Cart

Ajaxed Sliding Shopping Cart With jQuery DemoAjaxed Sliding Shopping Cart With jQuery Download

The HTML

For The Sliding Basket:

<div id="slidingTopWrap">
	<div id="slidingTopContent">
		<div id="basketWrap">
			<div id="basketTitleWrap">
				Your Basket <span id="notificationsLoader"></span>
			</div>
			<div id="basketItemsWrap">
				<ul>
				<li></li>
				<?php getBasket(); ?>
				</ul>
			</div>
		</div>
	</div>
	<div id="slidingTopFooter">
		<div id="slidingTopFooterLeft">
			<img src="images/arrow-down.png" alt="Show Basket" /> <a href="no-js.htm" onclick="return false;" id="slidingTopTrigger">Show Basket</a>
		</div>
	</div>
</div>

The Highlights

  • the div slidingTopWrap is positioned absolutely with top: 0 CSS value to stick to the top of the page
  • the div slidingTopContent is hided via JavaScript when the page loads & it is actually the part which slides
  • the div basketWrap, nothing unusual, wraps the contents of the basket

The JavaScript (jQuery)

Manual Show/Hide Part

$("#slidingTopContent").hide();

$("#slidingTopTrigger").live("click", function(event) {
	$("#slidingTopContent").slideToggle("slow", function(){
		if ($("#slidingTopContent").is(":visible")) {
			$("#slidingTopFooterLeft").html('<img src="images/arrow-up.png" alt="Hide Basket" /> <a href="no-js.htm" onclick="return false;" id="slidingTopTrigger">Hide Basket</a>');
		} else {
			$("#slidingTopFooterLeft").html('<img src="images/arrow-down.png" alt="Show Basket" /> <a href="no-js.htm" onclick="return false;" id="slidingTopTrigger">Show Basket</a>');
		}
	});
}); 

The Highlights:

  • we have $("#slidingTopContent").hide(); in the beginning to hide the div in the initial load
  • when the #slidingTopTrigger is clicked, we use the slideToggle function to show/hide the #slidingTopContent. To understand whether it is open or not, we have an if then else clause as if ($("#slidingTopContent").is(":visible")) {
    • if the #slidingTopContent is visible, we insert the "hide HTML"
    • if the #slidingTopContent is not visible, we insert the "show HTML"
  • you’ll see that we used the $("#slidingTopTrigger").live("click", function(event) { rather than a standard click function. The reason is adding the new created HTMLs to the DOM

Adding Products

$(".productPriceWrapRight a img").click(function() {
	var productIDValSplitter 	= (this.id).split("_");
	var productIDVal 			= productIDValSplitter[1];

	if ($("#slidingTopContent").is(":visible")) {

		$("#notificationsLoader").html('<img src="images/loader.gif">');

		$.ajax({
		type: "POST",
		url: "inc/functions.php",
		data: { productID: productIDVal, action: "addToBasket"},
		success: function(theResponse) {

		if( $("#productID_" + productIDVal).length > 0){
			$("#productID_" + productIDVal).animate({ opacity: 0 }, 500);
			$("#productID_" + productIDVal).before(theResponse).remove();
			$("#productID_" + productIDVal).animate({ opacity: 0 }, 500);
			$("#productID_" + productIDVal).animate({ opacity: 1 }, 500);
			$("#notificationsLoader").empty();

		} else {
			$("#basketItemsWrap li:first").before(theResponse);
			$("#basketItemsWrap li:first").hide();
			$("#basketItemsWrap li:first").show("slow");
			$("#notificationsLoader").empty();
		}

		}
		}); 

	} else {

		$("#slidingTopContent").slideToggle("slow", function(){		

			$("#slidingTopFooterLeft").html('<img src="images/arrow-up.png" alt="Hide Basket" /> <a href="aaa.htm" onclick="return false;" id="slidingTopTrigger">Hide Basket</a>');
			$("#notificationsLoader").html('<img src="images/loader.gif">');

			$.ajax({
			type: "POST",
			url: "inc/functions.php",
			data: { productID: productIDVal, action: "addToBasket"},
			success: function(theResponse) {

			if( $("#productID_" + productIDVal).length > 0){
				$("#productID_" + productIDVal).animate({ opacity: 0 }, 500);
				$("#productID_" + productIDVal).before(theResponse).remove();
				$("#productID_" + productIDVal).animate({ opacity: 0 }, 500);
				$("#productID_" + productIDVal).animate({ opacity: 1 }, 500);
				$("#notificationsLoader").empty();

			} else {
				$("#basketItemsWrap li:first").before(theResponse);
				$("#basketItemsWrap li:first").hide();
				$("#basketItemsWrap li:first").show("slow");
				$("#notificationsLoader").empty();
			}

			}
			}); 

			$("#slidingTopTrigger").fadeTo(4000, 1, function(){
				$("#slidingTopContent").slideToggle("slow", function(){
					$("#slidingTopFooterLeft").html('<img src="images/arrow-down.png" alt="Show Basket" /> <a href="aaa.htm" onclick="return false;" id="slidingTopTrigger">Show Basket</a>');
				});

			});

		});
	}

});

The Highlights:

As "how-to" on sending the Ajax query & fading animations are described in the previous post, we won’t repeating the same info here & focus on the effects.

  • we again run the same if-then-else clause
    • if the #slidingTopContent is open send an Ajax query to functions.php and add-the-products to basket
    • if the #slidingTopContent is closed:
      • slideToggle the div
      • insert the "hide HTML" to #slidingTopFooterLeft"
      • send an Ajax query to functions.php and add-the-products to basket
      • wait for x seconds: $("#slidingTopTrigger").fadeTo(4000, 1, function(){
      • slideToggle the div
      • insert the "show HTML" to #slidingTopFooterLeft"

P.S. To make the example work on your side, you should be creating a new database with the jBasket.sql file inside the download package & configure the database connection information inside “inc/db.php” file.

Special Downloads:
Ajaxed Add-To-Basket Scenarios With jQuery And PHP
Free Admin Template For Web Applications
jQuery Dynamic Drag’n Drop
ScheduledTweets

Advertisements:
SSLmatic – Cheap SSL Certificates (from $19.99/year)
Dreamhost $50 Discount Code: WRD
Follow WebResourcesDepot At Twitter And Get More Resources!

Tags: ,

Related posts

13 Tips For A Better E-Commerce Website

E-commerce has its own dynamics when compared to the standard shopping experiences. It:

  • is faster
  • requires collection of data
  • includes shipping more frequently
  • has different ways of supporting users
  • & more..

E-Commerce Tips

If the product sold is not something unique, then it probably exists in 100s of other e-commerce websites. So, to differentiate your stores from others, here are 13 tips for a better e-commerce website:

 

Software


1.- Use A Well-Tested Software

Many websites / applications can handle the risk of "developing while online". E-commerce is not one of them, at least the core parts.

You may be using a ready-to-go software or built a new one from scratch. In both cases, test how it works very well on every level: browsing, cart functions, payments. and make sure they work. A bug in payments or a product that can’t be added to basket will not only result in un-completed sales but also lost future customers and bad word-of-mouth.

2.- Have Scenarios In Case An Unexpected Thing Occurs

E-commerce has its own risks like:

  • communication problems with payment processors
  • hosting / server problems

In such situations, rather than offering the customers a buggy usage, you must be able to take an action with a "click" & display friendly notifications like: "for a short time we can’t accept credit card payments, we can let you know when it will be available or you can use these payment methods".

Simply, show the customer you’re aware of the problem and have an alternative solution.

 

Presentation


3.- Adding To Cart Without Registering

Sign-InForcing users to "register first then start shopping" is probably one of the best ways to lose them. Many users who add products to their shopping carts are still not sure to buy them. They want to see what the sum will be, if there will be shipping fees, etc.

Rather than placing barriers in front of them from the beginning, easing the ways to explore the website/products and collecting any information when needed is much better.

And, don’t forget, there is always a risk in losing a customer who didn’t pay yet.

4.- Reaching To The Product With Less Clicks

There are multiple ways to help users reach the products with less clicks:

  • well-planned categories where sub-categories can be viewed just by hovering them
  • ability to narrow products by price, product features (like screen sizes for monitors), brands, etc.
  • an easily reachable product search form

5.- There Is Never "Too Detailed Products"

In contrast to the famous and funny Microsoft Re-Designs the Ipod Packaging video, providing as many details as you can on a product is a great thing.

You can always make this uncomplicated by presenting the basic information as a standard and having a "detailed information" as an option.

6.- More And High-Quality Photos

CameraSeeing is believing. As users won’t be able to touch the products, the more photos provided is the easier they decide if that is the product they need.

And, always use high-quality images as it will be perceived as "sloppy" if otherwise.

7.- Show Related, Alternative And Complimentary Products Better

A widely seen mistake in e-commerce websites is showing both the alternative and related products all mixed up. But they are not the same thing and will be confusing to the customer as well.

If you’re about to purchase a camera:

  • an other camera
  • the dock that is built specially built for that camera
  • case for cameras

are all different stuff and a better presentation will be displaying them under their own titles.

8.- Use SSL In Every Page When Collecting Critical Data

When collecting information such as:

  • registration forms
  • editing account details
  • credit card details

make sure you switch the website to the SSL URLs as it is measure of security and shows that you pay attention to your data.

P.S. Check SSLmatic.com for RapidSSL, Geotrust and Verisign certificates with much cheaper prices.

 

Order Processing


9.- Notify Users On Every Level

With the good ones, many people also have bad experiences with e-commerce specially on the delivery part.

Due to the nature of e-commerce no or few stock is kept and a sold product can not be delivered because it does not exist anymore or delivered later than expected. Also, specially for international orders, payments need to be approved manually. To sum up, there are various things that may go wrong from the users point of view.

So, it is a "must" to notify users on every level like:

  • when the payment is approved
  • a delay occured
  • when the product is shipped

10.- If Something Goes Wrong, Contact With Phone Besides E-mail

PhoneLike mentioned above, things can go wrong. The product may be no longer available, the system didn’t write the "shipping address to the database" & more.

In a such position, contacting the customer is a must but e-mail is mostly not enough. A customer, who doesn’t check e-mails frequently, waiting the product to be delivered yesterday but have a notification in the inbox saying "there is a problem with the order" is not a good experience.

Using phone or SMS is a better choice to make sure customer knows what’s going on.

 

Support


11.- Detailed Knowledgebase

Whether the website is a fresh one or not, a knowledgebase covering the most required titles is a must. These can be the "shipping & handling" & "refund policy" in the beginning.

A detailed knowledgebase shows that there are procedures within the company & is a sign of trust.

12.- Provide Live Chat Support

E-commerce customers generally require a help instantly & online as they are about to buy a product, their sessions may expire, etc.

Live chat support, which exists on every page with a clear link or image is a great way to meet this need. And, it is better on the administration side as you can already see "in which page the customer is", "what browser, OS they use", "their country/city", etc.

Also, every chat can be recorded for reporting & analysis. Besides the paid ones, there are various free live chat softwares which can be found in WebResourcesDepot’s "Customer Support"category.

13.- Do Your Best To Prevent Support Calls But Have A Phone Number

Thinking that "this is an e-commerce website" and no phone support is needed is mostly not true. At the end, it is a business & from the perception of users, a business requires a phone number.

But, do your best to prevent support calls coming in like the options mentioned above as telephone is a time killer and there is always a risk that no enough number support personels exist at a given time.

 

Have your tips / experiences? Please share them.

Special Downloads:
Ajaxed Add-To-Basket Scenarios With jQuery And PHP
Free Admin Template For Web Applications
jQuery Dynamic Drag’n Drop
ScheduledTweets

Advertisements:
SSLmatic – Cheap SSL Certificates (from $19.99/year)
Dreamhost $50 Discount Code: WRD
Follow WebResourcesDepot At Twitter And Get More Resources!

Tags: , ,

Related posts

The WordPress 2.0.x Legacy Branch is Deprecated

The WordPress team had initially committed to maintaining the WordPress 2.0.x legacy branch until 2010. Unfortunately, we bit off more than we could chew—the 2.0.x branch is now retired and deprecated, a few months shy of 2010.

Many of the security improvements to the new versions of WordPress in the last couple of years were complete reworks of how various systems were handled. Porting those changes to the 2.0.x branch would have been a monumental task and could have introduced instability or new bugs. We had to make hard decisions between stability and merging in the latest security enhancements. Additionally, far fewer people stayed on the 2.0.x branch than we anticipated. I take that as a testament to the new features in WordPress and perhaps even more the features offered by plugins, many of which don’t support older versions of WordPress!

I’m disappointed that we weren’t able to keep the branch maintained until 2010, but since one of the big reasons for that failure was the massive scope of our security improvements for the newer versions of WordPress, 2.0.x doesn’t die in vain!

Fly-To-Basket Effect With jQuery

In this 3rd day of the "WRD E-Commerce Week", we will be adding a chic fly-to-basket effect to our previously created Ajaxed shopping cart using jQuery.

Rather than the complete HTML structure & PHP code that adds/removes the products, we’ll be focusing on the details related with  the effect.

Fly To Basket With jQuery

To findout the details of the complete HTML structure & PHP code, please check our post: Creating A Slick Ajaxed Add-To-Basket With jQuery And PHP. And, a full working example can be found in the download package.

Fly-To-Basket Effect With jQuery DemoFly-To-Basket Effect With jQuery Download

The HTML

HTML For The Product’s Wrapper:

<div class="productWrap">
	<div class="productImageWrap">
		<img src="images/product1.jpg" alt="Product1" />
	</div>
	<div class="productNameWrap">
		Krups Coffee Maker
	</div>
	<div class="productPriceWrap">
		<div class="productPriceWrapLeft">
			$95
		</div>
		<div class="productPriceWrapRight">
			<a href="inc/functions.php?action=addToBasket&productID=1" onClick="return false;">
				<img src="images/add-to-basket.gif" alt="Add To Basket" width="111" height="32" id="featuredProduct_1" />
			</a>
		</div>
	</div>
</div>

The part we’ll focus is the contents inside <div class="productPriceWrapRight"> which wraps the "add-to-basket" button.

The Highlights:

  • a link with onClick="return false; value which means it won’t be active if JavaScript is active (to make the script unobtrusive)
  • add-to-basket image has an unique ID: id="featuredProduct_1" which we’ll use to understand the button of which product is clicked

HTML For The Basket:

<div id="basketWrap">
	<div id="basketTitleWrap">
		Your Basket <span id="notificationsLoader"></span>
	</div>
	<div id="basketItemsWrap">
		<ul>
		<li></li>
		<?php getBasket(); ?>
		</ul>
	</div>
</div>

The Highlights:

  • we have an empty <span> with id="notificationsLoader" to show a loading image
  • we keep an empty div to be able to insert any data before/after them
  • we call a PHP function: <?php getBasket(); ?> to get the basket data when the page is first loaded.

The JavaScript (jQuery)

$("#basketItemsWrap li:first").hide();

$(".productPriceWrapRight a img").click(function() {
	var productIDValSplitter 	= (this.id).split("_");
	var productIDVal 			= productIDValSplitter[1];

	var productX 		= $("#productImageWrapID_" + productIDVal).offset().left;
	var productY 		= $("#productImageWrapID_" + productIDVal).offset().top;

	if( $("#productID_" + productIDVal).length > 0){
		var basketX 		= $("#productID_" + productIDVal).offset().left;
		var basketY 		= $("#productID_" + productIDVal).offset().top;
	} else {
		var basketX 		= $("#basketTitleWrap").offset().left;
		var basketY 		= $("#basketTitleWrap").offset().top;
	}

	var gotoX 			= basketX - productX;
	var gotoY 			= basketY - productY;

	var newImageWidth 	= $("#productImageWrapID_" + productIDVal).width() / 3;
	var newImageHeight	= $("#productImageWrapID_" + productIDVal).height() / 3;

	$("#productImageWrapID_" + productIDVal + " img")
	.clone()
	.prependTo("#productImageWrapID_" + productIDVal)
	.css({'position' : 'absolute'})
	.animate({opacity: 0.4}, 100 )
	.animate({opacity: 0.1, marginLeft: gotoX, marginTop: gotoY, width: newImageWidth, height: newImageHeight}, 1200, function() {
																																																																												$(this).remove();

		$("#notificationsLoader").html('<img src="images/loader.gif">');

		$.ajax({
		type: "POST",
		url: "inc/functions.php",
		data: { productID: productIDVal, action: "addToBasket"},
		success: function(theResponse) {

		if( $("#productID_" + productIDVal).length > 0){
			$("#productID_" + productIDVal).animate({ opacity: 0 }, 500);
			$("#productID_" + productIDVal).before(theResponse).remove();
			$("#productID_" + productIDVal).animate({ opacity: 0 }, 500);
			$("#productID_" + productIDVal).animate({ opacity: 1 }, 500);
			$("#notificationsLoader").empty();

		} else {
			$("#basketItemsWrap li:first").before(theResponse);
			$("#basketItemsWrap li:first").hide();
			$("#basketItemsWrap li:first").show("slow");
			$("#notificationsLoader").empty();
		}

		}
		});  

	});

});

Highlights:

  • splitting the ID of the clicked "add-to-basket" image which is "featuredProduct_1" from the "_" character & get the databaseID of the product
  • using jQuery’s offset, we get the current x-y position of the product
  • run a "if-then-else" clause which:
    • if that product is already in the basket: if( $("#productID_" + productIDVal).length > 0){ (if an element with that ID exists in the basket), if exists, then we get the x-y positions of that element using "offset" again, so we can target that element while flying our product
    • if that product isn’t in the basket: then we get the x-y positions of a static element in the basket HTMl area (#basketTitleWrap in our case)
  • very important: we create 2 variables; gotoX & gotoY by subtracting the element in the basket’s position from the product’s position. And we get the distance product needs to animate (fly) in x’s & y’s
  • again create 2 variables named newImageWidth & newImageHeight which are x times (3 in our case) smaller the size of our product’s image. This is used to create a resizing effect while flying the product to the basket
  • and, let’s fly the product: targeting the product image to be flied; $("#productImageWrapID_" + productIDVal + " img"). We clone it with jQuery’s clone, place inside the same element where the original image exists with prependTo & set it’s position to absolute. The next thing, we decrease its opacity so it starts in a little transparent look before the animation. And, we fly it by mentioning the marginLeft & marginTop values we calculated. At the same time, we make it more transparent & resize it. Also, we set the duration of the animation (1200 in our case).
  • As a callback function (after the animation ends), we remove the cloned image from the DOM, show the Ajax loader & post a query to our PHP page. That’s all.

P.S. To make the example work on your side, you should be creating a new database with the jBasket.sql file inside the download package & configure the database connection information inside “inc/db.php” file.

Special Downloads:
Ajaxed Add-To-Basket Scenarios With jQuery And PHP
Free Admin Template For Web Applications
jQuery Dynamic Drag’n Drop
ScheduledTweets

Advertisements:
SSLmatic – Cheap SSL Certificates (from $19.99/year)
Dreamhost $50 Discount Code: WRD
Follow WebResourcesDepot At Twitter And Get More Resources!

Tags: ,

Related posts

iGoogle-Like Start Pages For Intranets: Picok

Picok (personal information cockpit) is an open source, multi-user script where users can create their own iGoogle-like start pages.

It is ideal for intranets as an admin account can pre-define the available components like feed addresses & users can select items from that list.

iGoogle-Like Script

Similar to iGoogle, the items can be:

  • drag’n dropped
  • minimized
  • configured

The script has integration support for Lotus Notes, Doodle, Wikipedia, Google Maps & more. Also, users can create post-it notes.

Picok offers a multi-language interface & can be extended by writing custom portlets.

It is built with PHP (Zend Framework), YUI & supports MySQL, Microsoft SQL Server, IBM Lotus Notes.

Special Downloads:
Ajaxed Add-To-Basket Scenarios With jQuery And PHP
Free Admin Template For Web Applications
jQuery Dynamic Drag’n Drop
ScheduledTweets

Advertisements:
SSLmatic – Cheap SSL Certificates (from $19.99/year)
Dreamhost $50 Discount Code: WRD
Follow WebResourcesDepot At Twitter And Get More Resources!

Tags: , , ,

Related posts

E-Commerce Icons Collection

Using icons in e-commerce websites is almost a standard as users generally search for a shopping cart icon to view the items in the basket or credit card icons to findout if such a payment option exists.

With this 2nd post of E-Commerce Week, here is a collection of free e-commerce icons that you can use in your projects.

WebResourcesDepot E-Commerce Icons (Vectors Included)

E-Commerce Icons

The free e-commerce icon set is created exclusively for WebResourcesDepot by the talented team at IconShock (like promised).

The set comes with 5 icons both in PNG & AI (Illustrator) files so, if wanted, they can be resized or modified easily.

Click here to download WebResourcesDepot E-Commerce Icons!.

Vector Shopping Cart Icons

Vector Shopping Cart Icons

The set has 12 icons in vector formats: AI, EPS, PDF & XAR.

Shopping Cart Icon

Shopping Cart Icon

A single & detailed icon which comes in ICO, ICNS & PNG formats with 16*16px, 32*32px, 48*48px & 128*128px sizes.

Glossy E-Commerce Icons

Glossy E-Commerce Icons

32 glossy icons in PNG format & 32*32px size.

Basket Icons

Basket Icons

2 huge basket icons with emtpy/full scenarios in PNG format & 128*128px, 256*256px, 512*512px sizes.

Tango-Styled Shopping Cart

Shopping Cart

This is an icon in PNG format.

Christmas Shopping Basket

Christmas Shopping Basket

1 icon that comes in both PNG & ICO formats. PNG formats are in 32*32px, 48*48px, 64*64px, 128*128px, 256*256px sizes.

Cart Icon

Cart Icon

1 icon in PNG, ICO & ICNS formats. PNG format comes in 16*16px, 24*24px, 32*32px, 48*48px, 64*64px, 128*128px sizes.

Full Shopping Cart Icon

Full Shopping Cart Icon

The icon is in PNG format & 512*512px size.

Chalkwork Payments

Payment Icons

The set includes 21 original icons and 105 variations. They are available in 3 sizes and 6 file formats: transparent PNG, TIF, GIF, BMP, Windows ICO and Mac ICNS.

Credit Cards Icon Set

Credit Card Icons

20 icons in GIF format with sizes: 50px*30px or 30px*30px.

Credit Card Logos & Images

Credit Card Logos

A collection of credit card logos, related images & variations.

3D Credit Card Icons

3D Credit Card Icons

Six 3D icons in GIF, JPG, PNG, ICO & Mac ICNS formats. They are sized 48*48px & 72*72px.

Special Downloads:
Ajaxed Add-To-Basket Scenarios With jQuery And PHP
Free Admin Template For Web Applications
jQuery Dynamic Drag’n Drop
ScheduledTweets

Advertisements:
SSLmatic – Cheap SSL Certificates (from $19.99/year)
Dreamhost $50 Discount Code: WRD
Follow WebResourcesDepot At Twitter And Get More Resources!

Tags: , , , , ,

Related posts

Open Source Job Board Application: JoobsBox

JoobsBox is an open source job board application which is built with PHP (Zend Framework) & MySQL.

No membership is required to add new job listings & they can be posted under pre-defined categories.

It comes with a plugin system which makes it possible to extend the application easily. There are already several plugins like iPhone plugin or the Twitter plugin (auto-posts the listings to Twitter).

JoobsBox

The application offers an admin panel where all the categories, listings, plugins & other variables can be controlled.

JoobsBox is multilingual & themeable. The project is currently in alpha stage, not mature but promising.

Special Downloads:
Ajaxed Add-To-Basket Scenarios With jQuery And PHP
Free Admin Template For Web Applications
jQuery Dynamic Drag’n Drop
ScheduledTweets

Advertisements:
SSLmatic – Cheap SSL Certificates (from $19.99/year)
Dreamhost $50 Discount Code: WRD
Follow WebResourcesDepot At Twitter And Get More Resources!

Tags: ,

Related posts

Creating A Slick Ajaxed Add-To-Basket With jQuery And PHP

It is a clear fact that Ajaxed interfaces, if not overused, eases using websites so much.

For an e-commerce website, this can mean a better shopping experience for customers where they can concentrate more on the products which may result in better sales.

jQuery Ajax Shopping Cart

This is a detailed tutorial which shows creating an unobtrusive Ajaxed shopping cart using jQuery & PHP and can guide you to Ajaxify any e-commerce software you may already be using or coding.

The main functions of the cart will be adding/removing items to the basket without the need of refreshing the page & displaying the actions with effects.

Other Add-To-Basket Tutorials Built on This Example:

To try the demo or download the script:

Slick Add-To-Basket With jQuery And PHP DemoSlick Add-To-Basket With jQuery And PHP Download

The HTML

Rather than the formatting of the page, as you can design it however you prefer, we’ll be focusing on the vital parts which does all the tricks.

HTML For The Product’s Wrapper:

<div class="productWrap">
	<div class="productImageWrap">
		<img src="images/product1.jpg" alt="Product1" />
	</div>
	<div class="productNameWrap">
		Krups Coffee Maker
	</div>
	<div class="productPriceWrap">
		<div class="productPriceWrapLeft">
			$95
		</div>
		<div class="productPriceWrapRight">
			<a href="inc/functions.php?action=addToBasket&productID=1" onClick="return false;">
				<img src="images/add-to-basket.gif" alt="Add To Basket" width="111" height="32" id="featuredProduct_1" />
			</a>
		</div>
	</div>
</div>

The part we’ll focus is the contents inside <div class="productPriceWrapRight"> which wraps the "add-to-basket" button.

The Highlights:

  • a link with onClick="return false; value which means it won’t be active if JavaScript is active (to make the script unobtrusive)
  • add-to-basket image has an unique ID: id="featuredProduct_1" which we’ll use to understand the button of which product is clicked

HTML For The Basket:

<div id="basketWrap">
	<div id="basketTitleWrap">
		Your Basket <span id="notificationsLoader"></span>
	</div>
	<div id="basketItemsWrap">
		<ul>
		<li></li>
		<?php getBasket(); ?>
		</ul>
	</div>
</div>

The Highlights:

  • we have an empty <span> with id="notificationsLoader" to show a loading image
  • we keep an empty div to be able to insert any data before/after them
  • we call a PHP function: <?php getBasket(); ?> to get the basket data when the page is first loaded.

The JavaScript (jQuery)

We have 2 main jQuery functions:

Function For Adding To Basket:

$(".productPriceWrapRight a img").click(function() {
	var productIDValSplitter 	= (this.id).split("_");
	var productIDVal 			= productIDValSplitter[1];

	$("#notificationsLoader").html('<img src="images/loader.gif">');

	$.ajax({
	type: "POST",
	url: "inc/functions.php",
	data: { productID: productIDVal, action: "addToBasket"},
	success: function(theResponse) {

		if( $("#productID_" + productIDVal).length > 0){
			$("#productID_" + productIDVal).animate({ opacity: 0 }, 500, function() {
				$("#productID_" + productIDVal).before(theResponse).remove();
			});
			$("#productID_" + productIDVal).animate({ opacity: 0 }, 500);
			$("#productID_" + productIDVal).animate({ opacity: 1 }, 500);
			$("#notificationsLoader").empty();
		} else {
			$("#basketItemsWrap li:first").before(theResponse);
			$("#basketItemsWrap li:first").hide();
			$("#basketItemsWrap li:first").show("slow");
			$("#notificationsLoader").empty();
		}

	}
	});  

});

The Highlights:

  • splitting the ID of the clicked "add-to-basket" image which is "featuredProduct_1" from the "_" character & get the databaseID of the product (1)
  • inserting the loader.gifimage inside the element with id="notificationsLoader"
  • posting a data with Ajax to our functions.php fil which handles all the server-side jobs. 2 data are posted: productID and the action to be done which is addToBasket
  • There are 2 possibilities when the data is posted, the items may already be inside the basket or it may be a new item. So, we have an if clause: if( $("#productID_" + productIDVal).length > 0){ which checks if an element with ID: productID1 (1 is a variable) exists in the page
    •  if it exist:
      • we change the opacity of that object to 0 (make it invisible)
      • load the new <li>product info</li> response that comes from the functions.php
      • remove the original <li>product info</li> object whose opacity was 0
      • and play with the new <li>product info</li> object’s opacity to create a blinking effect
      • empty the contents inside id="notificationsLoader" to stop the loading animation
    • if it does not exist:
      • we insert the response from the functions.php before the first hidden <li> and hide it
      • then use jQuery’s show function to display it with an effect
      • empty the contents inside id="notificationsLoader" to stop the loading animation

Function For Removing From Basket:

$("#basketItemsWrap li img").live("click", function(event) { 

	var productIDValSplitter 	= (this.id).split("_");
	var productIDVal 			= productIDValSplitter[1];	

	$("#notificationsLoader").html('<img src="images/loader.gif">');

	$.ajax({
	type: "POST",
	url: "inc/functions.php",
	data: { productID: productIDVal, action: "deleteFromBasket"},
	success: function(theResponse) {

		$("#productID_" + productIDVal).hide("slow",  function() {$(this).remove();});
		$("#notificationsLoader").empty();

	}
	});  

});

The Highlights:

  • As the objects are inserted to basket via Ajax, the new HTML items inside the basket are normally not loaded to the DOM and we can’t reach them via JavaScript. jQuery offers an event named "live" (starting from jQuery 1.3) which loads the new created items to the DOM. So we used this event.
  • All other tasks are similar to adding an item, we splitted the HTML element from the "_" character and got the productID to be deleted and sent it to functions.php via Ajax.

The Database

We have used a MySQL database in this example with 2 tables:

Products:

Add To Basket Products Table

Baskets (for keeping the shopping cart of every different session)

Add To Basket Sessions Table

The PHP

There is nothing complicated on the PHP part.

Handle The Variables:

session_start();
$sessionID = $_COOKIE['PHPSESSID'];

if($_POST['action'] != '' || $_GET['action'] != '') {
	if($_POST['action'] == '')
	{
		$action 	= $_GET['action'];
		$productID	= $_GET['productID'];
		$noJavaScript = 1;
	} else {
		$action 	= $_POST['action'];
		$productID	= $_POST['productID'];
		$noJavaScript = 0;
	}
}

The Highlights:

  • we create a session variable so every different user will have their own baskets
  • understand if the request comes from a POST (Ajax) or GET (JS disabled) request and get the action & productID variables
  • if it is a GET request we change the value of a variable named $noJavaScript to 1

PHP For Add To Basket:

if ($action == "addToBasket"){

	$productInBasket 	= 0;
	$productTotalPrice	= 0;

	$query  = "SELECT * FROM products WHERE productID = " . $productID;
	$result = mysql_query($query);
	$row = mysql_fetch_array( $result );

	$productPrice 		= $row['productPrice'];
	$productName		= $row['productName'];	

	$query = "INSERT INTO baskets (productID, productPrice, basketSession) VALUES ('$productID', '$productPrice', '$sessionID')";
	mysql_query($query) or die('Error, insert query failed');	

	$query  = "SELECT * FROM baskets WHERE productID = " . $productID . " AND basketSession = '" . $sessionID . "'";
	$result = mysql_query($query) or die(mysql_error());;

	while($row = mysql_fetch_array($result, MYSQL_ASSOC))
	{
		$totalItems 	= $totalItems + 1;
		$productTotalPrice 	= $productTotalPrice + $row['productPrice'];
	}

	if ($noJavaScript == 1) {
		header("Location: ../index.php");
	} else {
		echo ('<li id="productID_' . $productID . '"><a href="inc/functions.php?action=deleteFromBasket&productID=' . $productID . '" onClick="return false;"><img src="images/delete.png" id="deleteProductID_' . $productID . '"></a> ' . $productName . '(' . $totalItems . ' items) - $' . $productTotalPrice . '</li>');
	}

}

The Highlights:

  • we insert the product to the database. If $noJavaScript to 1 we redirect to the index.php else we create a <li> element including the product’s details & echo it so we can insert it via jQuery.

PHP For Delete From Basket:

if ($action == "deleteFromBasket"){

	$query = "DELETE FROM baskets WHERE productID = " . $productID . " AND basketSession = '" . $sessionID . "'";
	mysql_query($query) or die('Error, delete query failed');

	if ($noJavaScript == 1) {
		header("Location: ../index.php");
	}
}

The Highlights:

  • we delete the product to the database. If $noJavaScript to 1 we redirect to the index.php

PHP For Getting The Basket (For Initial Load)

Like mentioned before, we create a function to get the basket’s current situation, so it can be loaded in the initial loading of the page.

function getBasket(){

	session_start();
	$sessionID = $_COOKIE['PHPSESSID'];

	$query  = "SELECT * FROM baskets WHERE basketSession = '" . $sessionID . "' GROUP BY productID ORDER By basketID DESC";
	$result = mysql_query($query);
	//echo $query;

	while($row = mysql_fetch_array($result, MYSQL_ASSOC))
	{

		$query2  = "SELECT * FROM products WHERE productID = " . $row['productID'];
		$result2 = mysql_query($query2);
		$row2 = mysql_fetch_array( $result2 );

		$productID	 		= $row2['productID'];
		$productPrice 		= $row2['productPrice'];
		$productName		= $row2['productName'];	

		$query2  = "SELECT COUNT(*) AS totalItems FROM baskets WHERE basketSession = '" . $sessionID . "' AND productID = " . $productID;
		$result2 = mysql_query($query2);
		$row2 = mysql_fetch_array( $result2 );
		$totalItems = $row2['totalItems'];
		$basketText = $basketText . '<li id="productID_' . $productID . '"><a href=inc/functions.php?action=deleteFromBasket&productID=' . $productID . ' onClick="return false;"><img src="images/delete.png" id="deleteProductID_' . $productID . '"></a> ' . $productName . '(' . $totalItems . ' items) - $' . ($totalItems * $productPrice) . '</li>';

	}
	echo $basketText;
}

The Highlights:

  • This is a standard PHP function which creates the HTML for the items in the basket with a loop

And, the Ajaxed basket built with jQuery & PHP is ready-to-use.

P.S. To make the example work on your side, you should be creating a new database with the jBasket.sql file inside the download package & configure the database connection information inside “inc/db.php” file.

Special Downloads:
Ajaxed Add-To-Basket Scenarios With jQuery And PHP
Free Admin Template For Web Applications
jQuery Dynamic Drag’n Drop
ScheduledTweets

Advertisements:
SSLmatic - Cheap SSL Certificates (from $19.99/year)
Dreamhost $50 Discount Code: WRD
Follow WebResourcesDepot At Twitter And Get More Resources!

Tags: , ,

Related posts

Free Live Support Software: LiveZilla

LiveZilla is a very impressive, mature & free live support software which enables you to provide live chat support on any website.

It is managed via a desktop-based (Windows OS) application & a web-based management is in the roadmap.

A chat can be initiated by a visitor clicking the "chat" button or pro-actively by the admin starting a chat without the visitor asks for it.

LiveZilla Free Live Support Software

With the help of canned messages, it is possible to give quick answers to predefined questions. Users can be pushed to an URL wanted which is great for guiding them.

If there are no admins when there is a chat request, visitors can leave an offline message.

The software offers real-time visitor monitoring like seeing which pages they are currently browsing & their browser, OS, geolocation details.

LiveZilla also comes with webcam support for personalized chats and increased customer retention.

It requires only PHP to run as data is kept file-based.

Special Downloads:
Ajaxed Add-To-Basket Scenarios With jQuery And PHP
Free Admin Template For Web Applications
jQuery Dynamic Drag’n Drop
ScheduledTweets

Advertisements:
SSLmatic - Cheap SSL Certificates (from $19.99/year)
Dreamhost $50 Discount Code: WRD
Follow WebResourcesDepot At Twitter And Get More Resources!

Tags:

Related posts