Version Description
Download this release
Release Info
Developer | Ajay |
Plugin | Contextual Related Posts |
Version | 1.2 |
Comparing to | |
See all releases |
Code changes from version 1.1.1 to 1.2
- admin.inc.php +87 -3
- contextual-related-posts.php +44 -23
- readme.txt +15 -3
- wick/sample_data.js.php +31 -0
- wick/wick.css +51 -0
- wick/wick.js +492 -0
- wick/wick_sample.html +85 -0
admin.inc.php
CHANGED
@@ -2,6 +2,16 @@
|
|
2 |
/**********************************************************************
|
3 |
* Admin Page *
|
4 |
*********************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
function crp_options() {
|
6 |
|
7 |
global $wpdb;
|
@@ -12,10 +22,23 @@ function crp_options() {
|
|
12 |
if($_POST['crp_save']){
|
13 |
$crp_settings[title] = ($_POST['title']);
|
14 |
$crp_settings[limit] = ($_POST['limit']);
|
|
|
15 |
$crp_settings[add_to_content] = (($_POST['add_to_content']) ? true : false);
|
|
|
16 |
$crp_settings[add_to_feed] = (($_POST['add_to_feed']) ? true : false);
|
17 |
$crp_settings[match_content] = (($_POST['match_content']) ? true : false);
|
|
|
|
|
|
|
18 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
19 |
update_option('ald_crp_settings', $crp_settings);
|
20 |
|
21 |
$str = '<div id="message" class="updated fade"><p>'. __('Options saved successfully.','ald_crp_plugin') .'</p></div>';
|
@@ -49,7 +72,7 @@ function crp_options() {
|
|
49 |
(<a href="http://ajaydsouza.com/donate/"><?php _e('Some reasons why you should.','ald_crp_plugin'); ?></a>)</p>
|
50 |
</fieldset>
|
51 |
</div>
|
52 |
-
<form method="post" id="crp_options" name="crp_options" style="border: #ccc 1px solid; padding: 10px">
|
53 |
<fieldset class="options">
|
54 |
<legend>
|
55 |
<h3>
|
@@ -68,10 +91,41 @@ function crp_options() {
|
|
68 |
<input type="textbox" name="title" id="title" value="<?php echo stripslashes($crp_settings[title]); ?>">
|
69 |
</label>
|
70 |
</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
71 |
<p>
|
72 |
<label>
|
73 |
<input type="checkbox" name="add_to_content" id="add_to_content" <?php if ($crp_settings[add_to_content]) echo 'checked="checked"' ?> />
|
74 |
-
<?php _e('Add related posts to the post content on single
|
|
|
|
|
|
|
|
|
|
|
|
|
75 |
</label>
|
76 |
</p>
|
77 |
<p>
|
@@ -86,6 +140,12 @@ function crp_options() {
|
|
86 |
<?php _e('Find related posts based on content as well as title. If unchecked, only posts titles are used. (I recommend using a caching plugin if you enable this)','ald_crp_plugin'); ?>
|
87 |
</label>
|
88 |
</p>
|
|
|
|
|
|
|
|
|
|
|
|
|
89 |
<p>
|
90 |
<input type="submit" name="crp_save" id="crp_save" value="Save Options" style="border:#00CC00 1px solid" />
|
91 |
<input name="crp_default" type="submit" id="crp_default" value="Default Options" style="border:#FF0000 1px solid" onclick="if (!confirm('<?php _e('Do you want to set options to Default? If you don\'t have a copy of the username, please hit Cancel and copy it first.','ald_crp_plugin'); ?>')) return false;" />
|
@@ -116,8 +176,32 @@ function crp_adminmenu() {
|
|
116 |
add_options_page(__("Related Posts", 'myald_crp_plugin'), __("Related Posts", 'myald_crp_plugin'), 9, 'crp_options', 'crp_options');
|
117 |
}
|
118 |
}
|
|
|
119 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
120 |
|
121 |
-
add_action('admin_menu', 'crp_adminmenu');
|
122 |
|
123 |
?>
|
2 |
/**********************************************************************
|
3 |
* Admin Page *
|
4 |
*********************************************************************/
|
5 |
+
// Pre-2.6 compatibility
|
6 |
+
if ( !defined('WP_CONTENT_URL') )
|
7 |
+
define( 'WP_CONTENT_URL', get_option('siteurl') . '/wp-content');
|
8 |
+
if ( !defined('WP_CONTENT_DIR') )
|
9 |
+
define( 'WP_CONTENT_DIR', ABSPATH . 'wp-content' );
|
10 |
+
// Guess the location
|
11 |
+
$crp_path = WP_CONTENT_DIR.'/plugins/'.plugin_basename(dirname(__FILE__));
|
12 |
+
$crp_url = WP_CONTENT_URL.'/plugins/'.plugin_basename(dirname(__FILE__));
|
13 |
+
|
14 |
+
|
15 |
function crp_options() {
|
16 |
|
17 |
global $wpdb;
|
22 |
if($_POST['crp_save']){
|
23 |
$crp_settings[title] = ($_POST['title']);
|
24 |
$crp_settings[limit] = ($_POST['limit']);
|
25 |
+
$crp_settings[exclude_cat_slugs] = ($_POST['exclude_cat_slugs']);
|
26 |
$crp_settings[add_to_content] = (($_POST['add_to_content']) ? true : false);
|
27 |
+
$crp_settings[add_to_page] = (($_POST['add_to_page']) ? true : false);
|
28 |
$crp_settings[add_to_feed] = (($_POST['add_to_feed']) ? true : false);
|
29 |
$crp_settings[match_content] = (($_POST['match_content']) ? true : false);
|
30 |
+
$crp_settings[exclude_pages] = (($_POST['exclude_pages']) ? true : false);
|
31 |
+
$crp_settings[blank_output] = (($_POST['blank_output'] == 'blank' ) ? true : false);
|
32 |
+
|
33 |
|
34 |
+
$exclude_categories_slugs = explode(", ",$crp_settings[exclude_cat_slugs]);
|
35 |
+
|
36 |
+
$exclude_categories = '';
|
37 |
+
foreach ($exclude_categories_slugs as $exclude_categories_slug) {
|
38 |
+
$exclude_categories .= get_category_by_slug($exclude_categories_slug)->term_id . ',';
|
39 |
+
}
|
40 |
+
$crp_settings[exclude_categories] = substr($exclude_categories, 0, -2);
|
41 |
+
|
42 |
update_option('ald_crp_settings', $crp_settings);
|
43 |
|
44 |
$str = '<div id="message" class="updated fade"><p>'. __('Options saved successfully.','ald_crp_plugin') .'</p></div>';
|
72 |
(<a href="http://ajaydsouza.com/donate/"><?php _e('Some reasons why you should.','ald_crp_plugin'); ?></a>)</p>
|
73 |
</fieldset>
|
74 |
</div>
|
75 |
+
<form method="post" id="crp_options" name="crp_options" style="border: #ccc 1px solid; padding: 10px" onsubmit="return checkForm()">
|
76 |
<fieldset class="options">
|
77 |
<legend>
|
78 |
<h3>
|
91 |
<input type="textbox" name="title" id="title" value="<?php echo stripslashes($crp_settings[title]); ?>">
|
92 |
</label>
|
93 |
</p>
|
94 |
+
<p><?php _e('Exclude Categories: ','ald_crp_plugin'); ?></p>
|
95 |
+
<div style="position:relative;text-align:left">
|
96 |
+
<table id="MYCUSTOMFLOATER" class="myCustomFloater" style="position:absolute;top:50px;left:0;background-color:#cecece;display:none;visibility:hidden">
|
97 |
+
<tr><td><!--
|
98 |
+
please see: http://chrisholland.blogspot.com/2004/09/geekstuff-css-display-inline-block.html
|
99 |
+
to explain why i'm using a table here.
|
100 |
+
You could replace the table/tr/td with a DIV, but you'd have to specify it's width and height
|
101 |
+
-->
|
102 |
+
<div class="myCustomFloaterContent">
|
103 |
+
you should never be seeing this
|
104 |
+
</div>
|
105 |
+
</td></tr>
|
106 |
+
</table>
|
107 |
+
<textarea class="wickEnabled:MYCUSTOMFLOATER" cols="50" rows="3" wrap="virtual" name="exclude_cat_slugs"><?php echo stripslashes($crp_settings[exclude_cat_slugs]); ?></textarea>
|
108 |
+
</div>
|
109 |
+
<p><?php _e('When there are no posts, what should be shown?','ald_crp_plugin'); ?><br />
|
110 |
+
<label>
|
111 |
+
<input type="radio" name="blank_output" value="blank" id="blank_output_0" <?php if ($crp_settings['blank_output']) echo 'checked="checked"' ?> />
|
112 |
+
<?php _e('Blank Output','ald_crp_plugin'); ?></label>
|
113 |
+
<br />
|
114 |
+
<label>
|
115 |
+
<input type="radio" name="blank_output" value="noposts" id="blank_output_1" <?php if (!$crp_settings['blank_output']) echo 'checked="checked"' ?> />
|
116 |
+
<?php _e('Display "No Related Posts"','ald_crp_plugin'); ?></label>
|
117 |
+
<br />
|
118 |
+
</p>
|
119 |
<p>
|
120 |
<label>
|
121 |
<input type="checkbox" name="add_to_content" id="add_to_content" <?php if ($crp_settings[add_to_content]) echo 'checked="checked"' ?> />
|
122 |
+
<?php _e('Add related posts to the post content on single posts. <br />If you choose to disable this, please add <code><?php if(function_exists(\'echo_ald_crp\')) echo_ald_crp(); ?></code> to your template file where you want it displayed','ald_crp_plugin'); ?>
|
123 |
+
</label>
|
124 |
+
</p>
|
125 |
+
<p>
|
126 |
+
<label>
|
127 |
+
<input type="checkbox" name="add_to_page" id="add_to_page" <?php if ($crp_settings[add_to_page]) echo 'checked="checked"' ?> />
|
128 |
+
<?php _e('Add related posts to pages. <br />If you choose to disable this, please add <code><?php if(function_exists(\'echo_ald_crp\')) echo_ald_crp(); ?></code> to your template file where you want it displayed','ald_crp_plugin'); ?>
|
129 |
</label>
|
130 |
</p>
|
131 |
<p>
|
140 |
<?php _e('Find related posts based on content as well as title. If unchecked, only posts titles are used. (I recommend using a caching plugin if you enable this)','ald_crp_plugin'); ?>
|
141 |
</label>
|
142 |
</p>
|
143 |
+
<p>
|
144 |
+
<label>
|
145 |
+
<input type="checkbox" name="exclude_pages" id="exclude_pages" <?php if ($crp_settings[exclude_pages]) echo 'checked="checked"' ?> />
|
146 |
+
<?php _e('Exclude Pages in Related Posts','ald_crp_plugin'); ?>
|
147 |
+
</label>
|
148 |
+
</p>
|
149 |
<p>
|
150 |
<input type="submit" name="crp_save" id="crp_save" value="Save Options" style="border:#00CC00 1px solid" />
|
151 |
<input name="crp_default" type="submit" id="crp_default" value="Default Options" style="border:#FF0000 1px solid" onclick="if (!confirm('<?php _e('Do you want to set options to Default? If you don\'t have a copy of the username, please hit Cancel and copy it first.','ald_crp_plugin'); ?>')) return false;" />
|
176 |
add_options_page(__("Related Posts", 'myald_crp_plugin'), __("Related Posts", 'myald_crp_plugin'), 9, 'crp_options', 'crp_options');
|
177 |
}
|
178 |
}
|
179 |
+
add_action('admin_menu', 'crp_adminmenu');
|
180 |
|
181 |
+
function crp_adminhead() {
|
182 |
+
global $crp_url;
|
183 |
+
|
184 |
+
?>
|
185 |
+
<link rel="stylesheet" type="text/css" href="<?php echo $crp_url ?>/wick/wick.css" />
|
186 |
+
<script type="text/javascript" language="JavaScript">
|
187 |
+
function checkForm() {
|
188 |
+
answer = true;
|
189 |
+
if (siw && siw.selectingSomething)
|
190 |
+
answer = false;
|
191 |
+
return answer;
|
192 |
+
}//
|
193 |
+
</script>
|
194 |
+
<?php }
|
195 |
+
add_action('admin_head', 'crp_adminhead');
|
196 |
+
|
197 |
+
function crp_adminfoot() {
|
198 |
+
global $crp_url;
|
199 |
+
|
200 |
+
?>
|
201 |
+
<script type="text/javascript" src="<?php echo $crp_url ?>/wick/sample_data.js.php"></script>
|
202 |
+
<script type="text/javascript" src="<?php echo $crp_url ?>/wick/wick.js"></script>
|
203 |
+
<?php }
|
204 |
+
add_action('admin_footer', 'crp_adminfoot');
|
205 |
|
|
|
206 |
|
207 |
?>
|
contextual-related-posts.php
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
<?php
|
2 |
/*
|
3 |
Plugin Name: Contextual Related Posts
|
4 |
-
Version: 1.
|
5 |
Plugin URI: http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/
|
6 |
Description: Show user defined number of contextually related posts. Based on the plugin by <a href="http://weblogtoolscollection.com">Mark Ghosh</a>. <a href="options-general.php?page=crp_options">Configure...</a>
|
7 |
Author: Ajay D'Souza
|
@@ -22,9 +22,10 @@ define('ALD_crp_DIR', dirname(__FILE__));
|
|
22 |
********************************************************************/
|
23 |
function ald_crp() {
|
24 |
global $wpdb, $post, $single;
|
25 |
-
|
26 |
$crp_settings = crp_read_options();
|
27 |
$limit = $crp_settings['limit'];
|
|
|
28 |
|
29 |
// Make sure the post is not from the future
|
30 |
$time_difference = get_settings('gmt_offset');
|
@@ -37,35 +38,48 @@ function ald_crp() {
|
|
37 |
$stuff = addslashes($post->post_title);
|
38 |
}
|
39 |
|
40 |
-
$sql = "SELECT ID,post_title,
|
41 |
. "MATCH(post_title,post_content) AGAINST ('$stuff') AS score "
|
42 |
-
. "FROM $
|
43 |
. "MATCH (post_title,post_content) AGAINST ('$stuff') "
|
44 |
. "AND post_date <= '$now' "
|
45 |
. "AND post_status = 'publish' "
|
46 |
-
. "AND id != $post->ID "
|
47 |
-
|
48 |
-
|
|
|
49 |
$search_counter = 0;
|
50 |
$searches = $wpdb->get_results($sql);
|
51 |
|
52 |
-
$output = '<div id="crp_related">'
|
53 |
|
54 |
if($searches){
|
|
|
55 |
$output .= '<ul>';
|
56 |
foreach($searches as $search) {
|
|
|
|
|
57 |
$title = trim(stripslashes($search->post_title));
|
58 |
-
|
59 |
-
|
60 |
-
}
|
61 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
62 |
} //end of foreach loop
|
63 |
$output .= '</ul>';
|
64 |
}else{
|
65 |
-
$output .= '<p>'.__('No related posts found').'</p>';
|
66 |
}
|
67 |
-
|
68 |
-
|
|
|
|
|
|
|
69 |
|
70 |
return $output;
|
71 |
}
|
@@ -76,11 +90,13 @@ function ald_crp_content($content) {
|
|
76 |
$crp_settings = crp_read_options();
|
77 |
$output = ald_crp();
|
78 |
|
79 |
-
if((
|
|
|
|
|
80 |
return $content.$output;
|
81 |
-
|
82 |
return $content.$output;
|
83 |
-
|
84 |
return $content;
|
85 |
}
|
86 |
}
|
@@ -93,14 +109,19 @@ function echo_ald_crp() {
|
|
93 |
|
94 |
// Default Options
|
95 |
function crp_default_options() {
|
96 |
-
$title = __('<
|
97 |
|
98 |
$crp_settings = Array (
|
99 |
-
title => $title,
|
100 |
-
add_to_content => true, // Add related posts to content (only on single
|
|
|
101 |
add_to_feed => true, // Add related posts to feed
|
102 |
-
limit => '5',
|
103 |
-
match_content =>
|
|
|
|
|
|
|
|
|
104 |
);
|
105 |
return $crp_settings;
|
106 |
}
|
1 |
<?php
|
2 |
/*
|
3 |
Plugin Name: Contextual Related Posts
|
4 |
+
Version: 1.2
|
5 |
Plugin URI: http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/
|
6 |
Description: Show user defined number of contextually related posts. Based on the plugin by <a href="http://weblogtoolscollection.com">Mark Ghosh</a>. <a href="options-general.php?page=crp_options">Configure...</a>
|
7 |
Author: Ajay D'Souza
|
22 |
********************************************************************/
|
23 |
function ald_crp() {
|
24 |
global $wpdb, $post, $single;
|
25 |
+
|
26 |
$crp_settings = crp_read_options();
|
27 |
$limit = $crp_settings['limit'];
|
28 |
+
$exclude_categories = explode(',',$crp_settings['exclude_categories']);
|
29 |
|
30 |
// Make sure the post is not from the future
|
31 |
$time_difference = get_settings('gmt_offset');
|
38 |
$stuff = addslashes($post->post_title);
|
39 |
}
|
40 |
|
41 |
+
$sql = "SELECT DISTINCT ID,post_title,post_date,"
|
42 |
. "MATCH(post_title,post_content) AGAINST ('$stuff') AS score "
|
43 |
+
. "FROM $wpdb->posts WHERE "
|
44 |
. "MATCH (post_title,post_content) AGAINST ('$stuff') "
|
45 |
. "AND post_date <= '$now' "
|
46 |
. "AND post_status = 'publish' "
|
47 |
+
. "AND id != $post->ID ";
|
48 |
+
if ($crp_settings['exclude_pages']) $sql .= "AND post_type = 'post' ";
|
49 |
+
$sql .= "ORDER BY score DESC ";
|
50 |
+
|
51 |
$search_counter = 0;
|
52 |
$searches = $wpdb->get_results($sql);
|
53 |
|
54 |
+
$output = '<div id="crp_related">';
|
55 |
|
56 |
if($searches){
|
57 |
+
$output .= $crp_settings['title'];
|
58 |
$output .= '<ul>';
|
59 |
foreach($searches as $search) {
|
60 |
+
$categorys = get_the_category($search->ID); //Fetch categories of the plugin
|
61 |
+
$p_in_c = false;
|
62 |
$title = trim(stripslashes($search->post_title));
|
63 |
+
foreach ($categorys as $cat) {
|
64 |
+
if (!$p_in_c) $p_in_c = (in_array($cat->cat_ID, $exclude_categories)) ? true : false;
|
65 |
+
}
|
66 |
+
|
67 |
+
if (!$p_in_c) {
|
68 |
+
if ($search_counter <= $limit) {
|
69 |
+
$output .= '<li><a href="'.get_permalink($search->ID).'" rel="bookmark">'.$title.'</a></li>';
|
70 |
+
$search_counter++;
|
71 |
+
} //end of search_counter loop
|
72 |
+
}
|
73 |
} //end of foreach loop
|
74 |
$output .= '</ul>';
|
75 |
}else{
|
76 |
+
$output .= (($_POST['blank_output']) ? '' : '<p>'.__('No related posts found','ald_crp_plugin').'</p>');
|
77 |
}
|
78 |
+
if ((strpos($output, '<li>')) === false) {
|
79 |
+
$output = '<div id="crp_related">';
|
80 |
+
$output .= (($_POST['blank_output']) ? '' : '<p>'.__('No related posts found','ald_crp_plugin').'</p>');
|
81 |
+
}
|
82 |
+
$output .= '</div>';
|
83 |
|
84 |
return $output;
|
85 |
}
|
90 |
$crp_settings = crp_read_options();
|
91 |
$output = ald_crp();
|
92 |
|
93 |
+
if((is_single())&&($crp_settings['add_to_content'])) {
|
94 |
+
return $content.$output;
|
95 |
+
} elseif((is_page())&&($crp_settings['add_to_page'])) {
|
96 |
return $content.$output;
|
97 |
+
} elseif((is_feed())&&($crp_settings['add_to_feed'])) {
|
98 |
return $content.$output;
|
99 |
+
} else {
|
100 |
return $content;
|
101 |
}
|
102 |
}
|
109 |
|
110 |
// Default Options
|
111 |
function crp_default_options() {
|
112 |
+
$title = __('<h3>Related Posts:</h3>');
|
113 |
|
114 |
$crp_settings = Array (
|
115 |
+
title => $title, // Add before the content
|
116 |
+
add_to_content => true, // Add related posts to content (only on single posts)
|
117 |
+
add_to_page => false, // Add related posts to content (only on single pages)
|
118 |
add_to_feed => true, // Add related posts to feed
|
119 |
+
limit => '5', // How many posts to display?
|
120 |
+
match_content => true, // Match against post content as well as title
|
121 |
+
exclude_pages => true, // Exclude Pages
|
122 |
+
blank_output => true, // Match against post tags as well as title
|
123 |
+
exclude_categories => '', // Exclude these categories
|
124 |
+
exclude_cat_slugs => '', // Exclude these categories
|
125 |
);
|
126 |
return $crp_settings;
|
127 |
}
|
readme.txt
CHANGED
@@ -3,15 +3,21 @@ Tags: related posts, similar posts
|
|
3 |
Contributors: Ajay D'Souza, Mark Ghosh
|
4 |
Donate link: http://ajaydsouza.com/donate/
|
5 |
Stable tag: trunk
|
6 |
-
Requires at least:
|
7 |
Tested up to: 2.7
|
8 |
|
9 |
|
10 |
Show user defined number of contextually related posts
|
11 |
|
|
|
12 |
== Description ==
|
13 |
|
14 |
-
Display a list of contextually related posts for the current post.
|
|
|
|
|
|
|
|
|
|
|
15 |
|
16 |
== Installation ==
|
17 |
|
@@ -26,6 +32,12 @@ Display a list of contextually related posts for the current post. You can selec
|
|
26 |
|
27 |
== Changelog ==
|
28 |
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
* 1.1 - Fixed MySQL index key conflicts by using a more unique index key name.
|
30 |
* 1.0.1 - Release
|
31 |
|
@@ -34,7 +46,7 @@ Display a list of contextually related posts for the current post. You can selec
|
|
34 |
|
35 |
= What are the requirements for this plugin? =
|
36 |
|
37 |
-
WordPress 2.
|
38 |
|
39 |
|
40 |
= Can I customize what is displayed? =
|
3 |
Contributors: Ajay D'Souza, Mark Ghosh
|
4 |
Donate link: http://ajaydsouza.com/donate/
|
5 |
Stable tag: trunk
|
6 |
+
Requires at least: 2.5
|
7 |
Tested up to: 2.7
|
8 |
|
9 |
|
10 |
Show user defined number of contextually related posts
|
11 |
|
12 |
+
|
13 |
== Description ==
|
14 |
|
15 |
+
Display a list of contextually related posts for the current post.
|
16 |
+
|
17 |
+
You can select the number of posts to display and if you want to automatically display the related posts in your content / feed.
|
18 |
+
|
19 |
+
Now, you can choose to exclude posts from certain categories as well as exclude pages.
|
20 |
+
|
21 |
|
22 |
== Installation ==
|
23 |
|
32 |
|
33 |
== Changelog ==
|
34 |
|
35 |
+
* 1.2
|
36 |
+
- Option to blank output in case nothing is found
|
37 |
+
- Exclude posts from certain categories
|
38 |
+
- Exclude pages
|
39 |
+
- Option to choose if you want related posts to be displayed on pages
|
40 |
+
* 1.1.1 - Now you can optionally choose if you want to use the post content to search for related posts
|
41 |
* 1.1 - Fixed MySQL index key conflicts by using a more unique index key name.
|
42 |
* 1.0.1 - Release
|
43 |
|
46 |
|
47 |
= What are the requirements for this plugin? =
|
48 |
|
49 |
+
WordPress 2.5 or above
|
50 |
|
51 |
|
52 |
= Can I customize what is displayed? =
|
wick/sample_data.js.php
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
//"sample_data.js.php" List of categories
|
3 |
+
Header("content-type: application/x-javascript");
|
4 |
+
|
5 |
+
if (!function_exists('add_action')) {
|
6 |
+
$wp_root = '../../../..';
|
7 |
+
if (file_exists($wp_root.'/wp-load.php')) {
|
8 |
+
require_once($wp_root.'/wp-load.php');
|
9 |
+
} else {
|
10 |
+
require_once($wp_root.'/wp-config.php');
|
11 |
+
}
|
12 |
+
}
|
13 |
+
|
14 |
+
// Ajax Increment Counter
|
15 |
+
wick_data();
|
16 |
+
function wick_data() {
|
17 |
+
global $wpdb;
|
18 |
+
|
19 |
+
$categories = get_categories('hide_empty=0');
|
20 |
+
$str = 'collection = [';
|
21 |
+
foreach ($categories as $cat) {
|
22 |
+
$str .= "'".$cat->slug."',";
|
23 |
+
}
|
24 |
+
$str = substr($str, 0, -1); // Remove trailing comma
|
25 |
+
$str .= '];';
|
26 |
+
|
27 |
+
echo $str;
|
28 |
+
}
|
29 |
+
|
30 |
+
|
31 |
+
?>
|
wick/wick.css
ADDED
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*
|
2 |
+
WICK: Web Input Completion Kit
|
3 |
+
http://wick.sourceforge.net/
|
4 |
+
Copyright (c) 2004, Christopher T. Holland,
|
5 |
+
All rights reserved.
|
6 |
+
|
7 |
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
8 |
+
|
9 |
+
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
10 |
+
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
11 |
+
Neither the name of the Christopher T. Holland, nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
12 |
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
13 |
+
|
14 |
+
*/
|
15 |
+
|
16 |
+
.floater {
|
17 |
+
position:absolute;
|
18 |
+
z-index:2;
|
19 |
+
bottom:0;
|
20 |
+
right:0;
|
21 |
+
display:none;
|
22 |
+
padding:0;
|
23 |
+
}
|
24 |
+
|
25 |
+
.floater td {
|
26 |
+
font-family: Gill, Helvetica, sans-serif;
|
27 |
+
background-color:white;
|
28 |
+
border:1px inset #979797;
|
29 |
+
color:black;
|
30 |
+
}
|
31 |
+
|
32 |
+
.matchedSmartInputItem {
|
33 |
+
font-size:0.8em;
|
34 |
+
padding: 5px 10px 1px 5px;
|
35 |
+
margin:0;
|
36 |
+
cursor:pointer;
|
37 |
+
}
|
38 |
+
|
39 |
+
.selectedSmartInputItem {
|
40 |
+
color:white;
|
41 |
+
background-color:#3875D7;
|
42 |
+
}
|
43 |
+
|
44 |
+
#smartInputResults {
|
45 |
+
padding:0;margin:0;
|
46 |
+
}
|
47 |
+
|
48 |
+
.siwCredit {
|
49 |
+
margin:0;padding:0;margin-top:10px;font-size:0.7em;color:black;
|
50 |
+
}
|
51 |
+
|
wick/wick.js
ADDED
@@ -0,0 +1,492 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
/*
|
2 |
+
WICK: Web Input Completion Kit
|
3 |
+
http://wick.sourceforge.net/
|
4 |
+
Copyright (c) 2004, Christopher T. Holland
|
5 |
+
All rights reserved.
|
6 |
+
|
7 |
+
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
|
8 |
+
|
9 |
+
Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
|
10 |
+
Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
11 |
+
Neither the name of the Christopher T. Holland, nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
12 |
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
13 |
+
|
14 |
+
*/
|
15 |
+
/* start dhtml building blocks */
|
16 |
+
function freezeEvent(e) {
|
17 |
+
if (e.preventDefault) e.preventDefault();
|
18 |
+
e.returnValue = false;
|
19 |
+
e.cancelBubble = true;
|
20 |
+
if (e.stopPropagation) e.stopPropagation();
|
21 |
+
return false;
|
22 |
+
}//freezeEvent
|
23 |
+
|
24 |
+
function isWithinNode(e,i,c,t,obj) {
|
25 |
+
answer = false;
|
26 |
+
te = e;
|
27 |
+
while(te && !answer) {
|
28 |
+
if ((te.id && (te.id == i)) || (te.className && (te.className == i+"Class"))
|
29 |
+
|| (!t && c && te.className && (te.className == c))
|
30 |
+
|| (!t && c && te.className && (te.className.indexOf(c) != -1))
|
31 |
+
|| (t && te.tagName && (te.tagName.toLowerCase() == t))
|
32 |
+
|| (obj && (te == obj))
|
33 |
+
) {
|
34 |
+
answer = te;
|
35 |
+
} else {
|
36 |
+
te = te.parentNode;
|
37 |
+
}
|
38 |
+
}
|
39 |
+
return te;
|
40 |
+
}//isWithinNode
|
41 |
+
|
42 |
+
function getEvent(event) {
|
43 |
+
return (event ? event : window.event);
|
44 |
+
}//getEvent()
|
45 |
+
|
46 |
+
function getEventElement(e) {
|
47 |
+
return (e.srcElement ? e.srcElement: (e.target ? e.target : e.currentTarget));
|
48 |
+
}//getEventElement()
|
49 |
+
|
50 |
+
function findElementPosX(obj) {
|
51 |
+
curleft = 0;
|
52 |
+
if (obj.offsetParent) {
|
53 |
+
while (obj.offsetParent) {
|
54 |
+
curleft += obj.offsetLeft;
|
55 |
+
obj = obj.offsetParent;
|
56 |
+
}
|
57 |
+
}//if offsetParent exists
|
58 |
+
else if (obj.x)
|
59 |
+
curleft += obj.x
|
60 |
+
return curleft;
|
61 |
+
}//findElementPosX
|
62 |
+
|
63 |
+
function findElementPosY(obj) {
|
64 |
+
curtop = 0;
|
65 |
+
if (obj.offsetParent) {
|
66 |
+
while (obj.offsetParent) {
|
67 |
+
curtop += obj.offsetTop;
|
68 |
+
obj = obj.offsetParent;
|
69 |
+
}
|
70 |
+
}//if offsetParent exists
|
71 |
+
else if (obj.y)
|
72 |
+
curtop += obj.y
|
73 |
+
return curtop;
|
74 |
+
}//findElementPosY
|
75 |
+
|
76 |
+
/* end dhtml building blocks */
|
77 |
+
|
78 |
+
function handleKeyPress(event) {
|
79 |
+
e = getEvent(event);
|
80 |
+
eL = getEventElement(e);
|
81 |
+
|
82 |
+
upEl = isWithinNode(eL,null,"wickEnabled",null,null);
|
83 |
+
|
84 |
+
kc = e["keyCode"];
|
85 |
+
|
86 |
+
if (siw && ((kc == 13) || (kc == 9))) {
|
87 |
+
siw.selectingSomething = true;
|
88 |
+
if (siw.isSafari) siw.inputBox.blur(); //hack to "wake up" safari
|
89 |
+
siw.inputBox.focus();
|
90 |
+
siw.inputBox.value = siw.inputBox.value.replace(/[ \r\n\t\f\s]+$/gi,' ');
|
91 |
+
hideSmartInputFloater();
|
92 |
+
} else if (upEl && (kc != 38) && (kc != 40) && (kc != 37) && (kc != 39) && (kc != 13) && (kc != 27)) {
|
93 |
+
if (!siw || (siw && !siw.selectingSomething)) {
|
94 |
+
processSmartInput(upEl);
|
95 |
+
}
|
96 |
+
} else if (siw && siw.inputBox) {
|
97 |
+
siw.inputBox.focus(); //kinda part of the hack.
|
98 |
+
}
|
99 |
+
|
100 |
+
}//handleKeyPress()
|
101 |
+
|
102 |
+
|
103 |
+
function handleKeyDown(event) {
|
104 |
+
e = getEvent(event);
|
105 |
+
eL = getEventElement(e);
|
106 |
+
|
107 |
+
if (siw && (kc = e["keyCode"])) {
|
108 |
+
if (kc == 40) {
|
109 |
+
siw.selectingSomething = true;
|
110 |
+
freezeEvent(e);
|
111 |
+
if (siw.isGecko) siw.inputBox.blur(); /* Gecko hack */
|
112 |
+
selectNextSmartInputMatchItem();
|
113 |
+
} else if (kc == 38) {
|
114 |
+
siw.selectingSomething = true;
|
115 |
+
freezeEvent(e);
|
116 |
+
if (siw.isGecko) siw.inputBox.blur();
|
117 |
+
selectPreviousSmartInputMatchItem();
|
118 |
+
} else if ((kc == 13) || (kc == 9)) {
|
119 |
+
siw.selectingSomething = true;
|
120 |
+
activateCurrentSmartInputMatch();
|
121 |
+
freezeEvent(e);
|
122 |
+
} else if (kc == 27) {
|
123 |
+
hideSmartInputFloater();
|
124 |
+
freezeEvent(e);
|
125 |
+
} else {
|
126 |
+
siw.selectingSomething = false;
|
127 |
+
}
|
128 |
+
}
|
129 |
+
|
130 |
+
}//handleKeyDown()
|
131 |
+
|
132 |
+
function handleFocus(event) {
|
133 |
+
e = getEvent(event);
|
134 |
+
eL = getEventElement(e);
|
135 |
+
if (focEl = isWithinNode(eL,null,"wickEnabled",null,null)) {
|
136 |
+
if (!siw || (siw && !siw.selectingSomething)) processSmartInput(focEl);
|
137 |
+
}
|
138 |
+
}//handleFocus()
|
139 |
+
|
140 |
+
function handleBlur(event) {
|
141 |
+
e = getEvent(event);
|
142 |
+
eL = getEventElement(e);
|
143 |
+
if (blurEl = isWithinNode(eL,null,"wickEnabled",null,null)) {
|
144 |
+
if (siw && !siw.selectingSomething) hideSmartInputFloater();
|
145 |
+
}
|
146 |
+
}//handleBlur()
|
147 |
+
|
148 |
+
function handleClick(event) {
|
149 |
+
e2 = getEvent(event);
|
150 |
+
eL2 = getEventElement(e2);
|
151 |
+
if (siw && siw.selectingSomething) {
|
152 |
+
selectFromMouseClick();
|
153 |
+
}
|
154 |
+
}//handleClick()
|
155 |
+
|
156 |
+
function handleMouseOver(event) {
|
157 |
+
e = getEvent(event);
|
158 |
+
eL = getEventElement(e);
|
159 |
+
if (siw && (mEl = isWithinNode(eL,null,"matchedSmartInputItem",null,null))) {
|
160 |
+
siw.selectingSomething = true;
|
161 |
+
selectFromMouseOver(mEl);
|
162 |
+
} else if (isWithinNode(eL,null,"siwCredit",null,null)) {
|
163 |
+
siw.selectingSomething = true;
|
164 |
+
}else if (siw) {
|
165 |
+
siw.selectingSomething = false;
|
166 |
+
}
|
167 |
+
}//handleMouseOver
|
168 |
+
|
169 |
+
function showSmartInputFloater() {
|
170 |
+
if (!siw.floater.style.display || (siw.floater.style.display=="none")) {
|
171 |
+
if (!siw.customFloater) {
|
172 |
+
x = findElementPosX(siw.inputBox);
|
173 |
+
y = findElementPosY(siw.inputBox) + siw.inputBox.offsetHeight;
|
174 |
+
//hack: browser-specific adjustments.
|
175 |
+
if (!siw.isGecko && !siw.isWinIE) x += 8;
|
176 |
+
if (!siw.isGecko && !siw.isWinIE) y += 10;
|
177 |
+
siw.floater.style.left = x;
|
178 |
+
siw.floater.style.top = y;
|
179 |
+
} else {
|
180 |
+
//you may
|
181 |
+
//do additional things for your custom floater
|
182 |
+
//beyond setting display and visibility
|
183 |
+
}
|
184 |
+
siw.floater.style.display="block";
|
185 |
+
siw.floater.style.visibility="visible";
|
186 |
+
}
|
187 |
+
}//showSmartInputFloater()
|
188 |
+
|
189 |
+
function hideSmartInputFloater() {
|
190 |
+
if (siw) {
|
191 |
+
siw.floater.style.display="none";
|
192 |
+
siw.floater.style.visibility="hidden";
|
193 |
+
siw = null;
|
194 |
+
}//siw exists
|
195 |
+
}//hideSmartInputFloater
|
196 |
+
|
197 |
+
function processSmartInput(inputBox) {
|
198 |
+
if (!siw) siw = new smartInputWindow();
|
199 |
+
siw.inputBox = inputBox;
|
200 |
+
|
201 |
+
classData = inputBox.className.split(" ");
|
202 |
+
siwDirectives = null;
|
203 |
+
for (i=0;(!siwDirectives && classData[i]);i++) {
|
204 |
+
if (classData[i].indexOf("wickEnabled") != -1)
|
205 |
+
siwDirectives = classData[i];
|
206 |
+
}
|
207 |
+
|
208 |
+
if (siwDirectives && (siwDirectives.indexOf(":") != -1)) {
|
209 |
+
siw.customFloater = true;
|
210 |
+
newFloaterId = siwDirectives.split(":")[1];
|
211 |
+
siw.floater = document.getElementById(newFloaterId);
|
212 |
+
siw.floaterContent = siw.floater.getElementsByTagName("div")[0];
|
213 |
+
}
|
214 |
+
|
215 |
+
|
216 |
+
setSmartInputData();
|
217 |
+
if (siw.matchCollection && (siw.matchCollection.length > 0)) selectSmartInputMatchItem(0);
|
218 |
+
content = getSmartInputBoxContent();
|
219 |
+
if (content) {
|
220 |
+
modifySmartInputBoxContent(content);
|
221 |
+
showSmartInputFloater();
|
222 |
+
} else hideSmartInputFloater();
|
223 |
+
}//processSmartInput()
|
224 |
+
|
225 |
+
function smartInputMatch(cleanValue, value) {
|
226 |
+
this.cleanValue = cleanValue;
|
227 |
+
this.value = value;
|
228 |
+
this.isSelected = false;
|
229 |
+
}//smartInputMatch
|
230 |
+
|
231 |
+
function simplify(s) {
|
232 |
+
return s.toLowerCase().replace(/^[ \s\f\t\n\r]+/,'').replace(/[ \s\f\t\n\r]+$/,'');
|
233 |
+
//.replace(/[�,�,�,�,\u00E9,\u00E8,\u00EA,\u00EB]/gi,"e").replace(/[�,�,\u00E0,\u00E2]/gi,"a").
|
234 |
+
}//simplify
|
235 |
+
|
236 |
+
function getUserInputToMatch(s) {
|
237 |
+
a = s;
|
238 |
+
fields = s.split(",");
|
239 |
+
if (fields.length > 0) a = fields[fields.length - 1];
|
240 |
+
return a;
|
241 |
+
}//getUserInputToMatch
|
242 |
+
|
243 |
+
function getUserInputBase() {
|
244 |
+
s = siw.inputBox.value;
|
245 |
+
a = s;
|
246 |
+
if ((lastComma = s.lastIndexOf(",")) != -1) {
|
247 |
+
a = a.replace(/^(.*\,[ \r\n\t\f\s]*).*$/i,'$1');
|
248 |
+
}
|
249 |
+
else
|
250 |
+
a = "";
|
251 |
+
return a;
|
252 |
+
}//getUserInputBase()
|
253 |
+
|
254 |
+
function runMatchingLogic(userInput, standalone) {
|
255 |
+
userInput = simplify(userInput);
|
256 |
+
uifc = userInput.charAt(0).toLowerCase();
|
257 |
+
if (uifc == '"') uifc = (n = userInput.charAt(1)) ? n.toLowerCase() : "z";
|
258 |
+
if (standalone) userInput = uifc;
|
259 |
+
if (siw) siw.matchCollection = new Array();
|
260 |
+
pointerToCollectionToUse = collection;
|
261 |
+
if (siw && siw.revisedCollection && (siw.revisedCollection.length > 0) && siw.lastUserInput && (userInput.indexOf(siw.lastUserInput) == 0)) {
|
262 |
+
pointerToCollectionToUse = siw.revisedCollection;
|
263 |
+
} else if (collectionIndex[userInput] && (collectionIndex[userInput].length > 0)) {
|
264 |
+
pointerToCollectionToUse = collectionIndex[userInput];
|
265 |
+
} else if (collectionIndex[uifc] && (collectionIndex[uifc].length > 0)) {
|
266 |
+
pointerToCollectionToUse = collectionIndex[uifc];
|
267 |
+
} else if (siw && (userInput.length == 1) && (!collectionIndex[uifc])) {
|
268 |
+
siw.buildIndex = true;
|
269 |
+
} else if (siw) {
|
270 |
+
siw.buildIndex = false;
|
271 |
+
}
|
272 |
+
|
273 |
+
tempCollection = new Array();
|
274 |
+
|
275 |
+
re1m = new RegExp("^([ \"\>\<\-]*)("+userInput+")","i");
|
276 |
+
re2m = new RegExp("([ \"\>\<\-]+)("+userInput+")","i");
|
277 |
+
re1 = new RegExp("^([ \"\}\{\-]*)("+userInput+")","gi");
|
278 |
+
re2 = new RegExp("([ \"\}\{\-]+)("+userInput+")","gi");
|
279 |
+
|
280 |
+
for (i=0,j=0;(i<pointerToCollectionToUse.length);i++) {
|
281 |
+
displayMatches = ((!standalone) && (j < siw.MAX_MATCHES));
|
282 |
+
entry = pointerToCollectionToUse[i];
|
283 |
+
mEntry = simplify(entry);
|
284 |
+
if (!standalone && (mEntry.indexOf(userInput) == 0)) {
|
285 |
+
userInput = userInput.replace(/\>/gi,'\\}').replace(/\< ?/gi,'\\{');
|
286 |
+
re = new RegExp("(" + userInput + ")","i");
|
287 |
+
if (displayMatches) {
|
288 |
+
siw.matchCollection[j] = new smartInputMatch(entry, mEntry.replace(/\>/gi,'}').replace(/\< ?/gi,'{').replace(re,"<b>$1</b>"));
|
289 |
+
}
|
290 |
+
tempCollection[j] = entry;
|
291 |
+
j++;
|
292 |
+
} else if (mEntry.match(re1m) || mEntry.match(re2m)) {
|
293 |
+
if (!standalone && displayMatches) {
|
294 |
+
siw.matchCollection[j] = new smartInputMatch(entry, mEntry.replace(/\>/gi,'}').replace(/\</gi,'{').replace(re1,"$1<b>$2</b>").replace(re2,"$1<b>$2</b>"));
|
295 |
+
}
|
296 |
+
tempCollection[j] = entry;
|
297 |
+
j++;
|
298 |
+
}
|
299 |
+
}//loop thru collection
|
300 |
+
if (siw) {
|
301 |
+
siw.lastUserInput = userInput;
|
302 |
+
siw.revisedCollection = tempCollection.join(",").split(",");
|
303 |
+
collectionIndex[userInput] = tempCollection.join(",").split(",");
|
304 |
+
}
|
305 |
+
if (standalone || siw.buildIndex) {
|
306 |
+
collectionIndex[uifc] = tempCollection.join(",").split(",");
|
307 |
+
if (siw) siw.buildIndex = false;
|
308 |
+
}
|
309 |
+
}//runMatchingLogic
|
310 |
+
|
311 |
+
function setSmartInputData() {
|
312 |
+
if (siw) {
|
313 |
+
orgUserInput = siw.inputBox.value;
|
314 |
+
orgUserInput = getUserInputToMatch(orgUserInput);
|
315 |
+
userInput = orgUserInput.toLowerCase().replace(/[\r\n\t\f\s]+/gi,' ').replace(/^ +/gi,'').replace(/ +$/gi,'').replace(/ +/gi,' ').replace(/\\/gi,'').replace(/\[/gi,'').replace(/\(/gi,'').replace(/\./gi,'\.').replace(/\?/gi,'');
|
316 |
+
if (userInput && (userInput != "") && (userInput != '"')) {
|
317 |
+
runMatchingLogic(userInput);
|
318 |
+
}//if userinput not blank and is meaningful
|
319 |
+
else {
|
320 |
+
siw.matchCollection = null;
|
321 |
+
}
|
322 |
+
}//siw exists ... uhmkaaayyyyy
|
323 |
+
}//setSmartInputData
|
324 |
+
|
325 |
+
function getSmartInputBoxContent() {
|
326 |
+
a = null;
|
327 |
+
if (siw && siw.matchCollection && (siw.matchCollection.length > 0)) {
|
328 |
+
a = '';
|
329 |
+
for (i = 0;i < siw.matchCollection.length; i++) {
|
330 |
+
selectedString = siw.matchCollection[i].isSelected ? ' selectedSmartInputItem' : '';
|
331 |
+
a += '<p class="matchedSmartInputItem' + selectedString + '">' + siw.matchCollection[i].value.replace(/\{ */gi,"<").replace(/\} */gi,">") + '</p>';
|
332 |
+
}//
|
333 |
+
}//siw exists
|
334 |
+
return a;
|
335 |
+
}//getSmartInputBoxContent
|
336 |
+
|
337 |
+
function modifySmartInputBoxContent(content) {
|
338 |
+
//todo: remove credits 'cuz no one gives a shit ;] - done
|
339 |
+
siw.floaterContent.innerHTML = '<div id="smartInputResults">' + content + (siw.showCredit ? ('<p class="siwCredit">Powered By: <a target="PhrawgBlog" href="http://chrisholland.blogspot.com/?from=smartinput&ref='+escape(location.href)+'">Chris Holland</a></p>') : '') +'</div>';
|
340 |
+
siw.matchListDisplay = document.getElementById("smartInputResults");
|
341 |
+
}//modifySmartInputBoxContent()
|
342 |
+
|
343 |
+
function selectFromMouseOver(o) {
|
344 |
+
currentIndex = getCurrentlySelectedSmartInputItem();
|
345 |
+
if (currentIndex != null) deSelectSmartInputMatchItem(currentIndex);
|
346 |
+
newIndex = getIndexFromElement(o);
|
347 |
+
selectSmartInputMatchItem(newIndex);
|
348 |
+
modifySmartInputBoxContent(getSmartInputBoxContent());
|
349 |
+
}//selectFromMouseOver
|
350 |
+
|
351 |
+
function selectFromMouseClick() {
|
352 |
+
activateCurrentSmartInputMatch();
|
353 |
+
siw.inputBox.focus();
|
354 |
+
hideSmartInputFloater();
|
355 |
+
}//selectFromMouseClick
|
356 |
+
|
357 |
+
function getIndexFromElement(o) {
|
358 |
+
index = 0;
|
359 |
+
while(o = o.previousSibling) {
|
360 |
+
index++;
|
361 |
+
}//
|
362 |
+
return index;
|
363 |
+
}//getIndexFromElement
|
364 |
+
|
365 |
+
function getCurrentlySelectedSmartInputItem() {
|
366 |
+
answer = null;
|
367 |
+
for (i = 0; ((i < siw.matchCollection.length) && !answer) ; i++) {
|
368 |
+
if (siw.matchCollection[i].isSelected)
|
369 |
+
answer = i;
|
370 |
+
}//
|
371 |
+
return answer;
|
372 |
+
}//getCurrentlySelectedSmartInputItem
|
373 |
+
|
374 |
+
function selectSmartInputMatchItem(index) {
|
375 |
+
siw.matchCollection[index].isSelected = true;
|
376 |
+
}//selectSmartInputMatchItem()
|
377 |
+
|
378 |
+
function deSelectSmartInputMatchItem(index) {
|
379 |
+
siw.matchCollection[index].isSelected = false;
|
380 |
+
}//deSelectSmartInputMatchItem()
|
381 |
+
|
382 |
+
function selectNextSmartInputMatchItem() {
|
383 |
+
currentIndex = getCurrentlySelectedSmartInputItem();
|
384 |
+
if (currentIndex != null) {
|
385 |
+
deSelectSmartInputMatchItem(currentIndex);
|
386 |
+
if ((currentIndex + 1) < siw.matchCollection.length)
|
387 |
+
selectSmartInputMatchItem(currentIndex + 1);
|
388 |
+
else
|
389 |
+
selectSmartInputMatchItem(0);
|
390 |
+
} else {
|
391 |
+
selectSmartInputMatchItem(0);
|
392 |
+
}
|
393 |
+
modifySmartInputBoxContent(getSmartInputBoxContent());
|
394 |
+
}//selectNextSmartInputMatchItem
|
395 |
+
|
396 |
+
function selectPreviousSmartInputMatchItem() {
|
397 |
+
currentIndex = getCurrentlySelectedSmartInputItem();
|
398 |
+
if (currentIndex != null) {
|
399 |
+
deSelectSmartInputMatchItem(currentIndex);
|
400 |
+
if ((currentIndex - 1) >= 0)
|
401 |
+
selectSmartInputMatchItem(currentIndex - 1);
|
402 |
+
else
|
403 |
+
selectSmartInputMatchItem(siw.matchCollection.length - 1);
|
404 |
+
} else {
|
405 |
+
selectSmartInputMatchItem(siw.matchCollection.length - 1);
|
406 |
+
}
|
407 |
+
modifySmartInputBoxContent(getSmartInputBoxContent());
|
408 |
+
}//selectPreviousSmartInputMatchItem
|
409 |
+
|
410 |
+
function activateCurrentSmartInputMatch() {
|
411 |
+
baseValue = getUserInputBase();
|
412 |
+
if ((selIndex = getCurrentlySelectedSmartInputItem()) != null) {
|
413 |
+
addedValue = siw.matchCollection[selIndex].cleanValue;
|
414 |
+
theString = (baseValue ? baseValue : "") + addedValue + ", ";
|
415 |
+
siw.inputBox.value = theString;
|
416 |
+
runMatchingLogic(addedValue, true);
|
417 |
+
}
|
418 |
+
}//activateCurrentSmartInputMatch
|
419 |
+
|
420 |
+
function smartInputWindow () {
|
421 |
+
this.customFloater = false;
|
422 |
+
this.floater = document.getElementById("smartInputFloater");
|
423 |
+
this.floaterContent = document.getElementById("smartInputFloaterContent");
|
424 |
+
this.selectedSmartInputItem = null;
|
425 |
+
this.MAX_MATCHES = 15;
|
426 |
+
this.isGecko = (navigator.userAgent.indexOf("Gecko/200") != -1);
|
427 |
+
this.isSafari = (navigator.userAgent.indexOf("Safari") != -1);
|
428 |
+
this.isWinIE = ((navigator.userAgent.indexOf("Win") != -1 ) && (navigator.userAgent.indexOf("MSIE") != -1 ));
|
429 |
+
this.showCredit = false;
|
430 |
+
}//smartInputWindow Object
|
431 |
+
|
432 |
+
function registerSmartInputListeners() {
|
433 |
+
inputs = document.getElementsByTagName("input");
|
434 |
+
texts = document.getElementsByTagName("textarea");
|
435 |
+
allinputs = new Array();
|
436 |
+
z = 0;
|
437 |
+
y = 0;
|
438 |
+
while(inputs[z]) {
|
439 |
+
allinputs[z] = inputs[z];
|
440 |
+
z++;
|
441 |
+
}//
|
442 |
+
while(texts[y]) {
|
443 |
+
allinputs[z] = texts[y];
|
444 |
+
z++;
|
445 |
+
y++;
|
446 |
+
}//
|
447 |
+
|
448 |
+
for (i=0; i < allinputs.length;i++) {
|
449 |
+
if ((c = allinputs[i].className) && (c == "wickEnabled")) {
|
450 |
+
allinputs[i].setAttribute("autocomplete","OFF");
|
451 |
+
allinputs[i].onfocus = handleFocus;
|
452 |
+
allinputs[i].onblur = handleBlur;
|
453 |
+
allinputs[i].onkeydown = handleKeyDown;
|
454 |
+
allinputs[i].onkeyup = handleKeyPress;
|
455 |
+
}
|
456 |
+
}//loop thru inputs
|
457 |
+
}//registerSmartInputListeners
|
458 |
+
|
459 |
+
siw = null;
|
460 |
+
|
461 |
+
if (document.addEventListener) {
|
462 |
+
document.addEventListener("keydown", handleKeyDown, false);
|
463 |
+
document.addEventListener("keyup", handleKeyPress, false);
|
464 |
+
document.addEventListener("mouseup", handleClick, false);
|
465 |
+
document.addEventListener("mouseover", handleMouseOver, false);
|
466 |
+
} else {
|
467 |
+
document.onkeydown = handleKeyDown;
|
468 |
+
document.onkeyup = handleKeyPress;
|
469 |
+
document.onmouseup = handleClick;
|
470 |
+
document.onmouseover = handleMouseOver;
|
471 |
+
}
|
472 |
+
|
473 |
+
registerSmartInputListeners();
|
474 |
+
|
475 |
+
document.write (
|
476 |
+
'<table id="smartInputFloater" class="floater" cellpadding="0" cellspacing="0"><tr><td id="smartInputFloaterContent" nowrap="nowrap">'
|
477 |
+
+'<\/td><\/tr><\/table>'
|
478 |
+
);
|
479 |
+
|
480 |
+
//note: instruct users to the fact that no commas should be present in entries.
|
481 |
+
//it would make things insanely messy.
|
482 |
+
//this is why i'm filtering commas here:
|
483 |
+
for (x=0;x<collection.length;x++) {
|
484 |
+
collection[x] = collection[x].replace(/\,/gi,'');
|
485 |
+
}//
|
486 |
+
|
487 |
+
collectionIndex = new Array();
|
488 |
+
|
489 |
+
ds = "";
|
490 |
+
function debug(s) {
|
491 |
+
ds += ( s + "\n");
|
492 |
+
}
|
wick/wick_sample.html
ADDED
@@ -0,0 +1,85 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<html>
|
2 |
+
<head><title>WICK Testing Ground</title>
|
3 |
+
|
4 |
+
<!-- WICK STEP 1: INSERT CSS -->
|
5 |
+
<link rel="stylesheet" type="text/css" href="./wick.css" />
|
6 |
+
|
7 |
+
</head>
|
8 |
+
<body>
|
9 |
+
<script type="text/javascript" language="JavaScript">
|
10 |
+
function checkForm() {
|
11 |
+
answer = true;
|
12 |
+
if (siw && siw.selectingSomething)
|
13 |
+
answer = false;
|
14 |
+
return answer;
|
15 |
+
}//
|
16 |
+
</script>
|
17 |
+
<center>
|
18 |
+
<p>
|
19 |
+
Welcome to the very unpolished WICK testing ground.
|
20 |
+
A view source on this document should give you most information you need
|
21 |
+
to make WICK work on your site, as i'm still working on more formal documentation
|
22 |
+
that'll also include integration suggestions to make this work as fast as possible with
|
23 |
+
large amounts of data.
|
24 |
+
<br/><br/>
|
25 |
+
Be sure to enter multiple e-mail addresses in each field, type a few characters, hit the delete key,
|
26 |
+
use your keyboard's up and down arrows, hit return or tab to select an item, use your mouse to hover and click,
|
27 |
+
deleting from a current item back into the preceding item, and basically poke around mercilessly.
|
28 |
+
<br /><br />
|
29 |
+
<div id="wickStatus">
|
30 |
+
Loading ... please hold!
|
31 |
+
</div>
|
32 |
+
<br /><br />
|
33 |
+
<form onsubmit="return checkForm()"> <!-- WICK STEP 5: this prevents form from being submitted right-away if a user hits RETURN to select an address -->
|
34 |
+
My First Box:<br />
|
35 |
+
<input class="wickEnabled" type="text" size="50" /><br />
|
36 |
+
My Second Box:<br />
|
37 |
+
<textarea class="wickEnabled" cols="50" rows="3" wrap="virtual"></textarea>
|
38 |
+
<!-- WICK STEP 4: ADD "wickEnabled" attribute to input
|
39 |
+
that'll receive autocompletion using data stored in the "collection" array defined in STEP 2 -->
|
40 |
+
<br />
|
41 |
+
My Third Box:<br />
|
42 |
+
<textarea class="wickEnabled" cols="50" rows="3" wrap="virtual"></textarea>
|
43 |
+
<br /> <br />
|
44 |
+
My Fourth Box with developer-built floater USING TABLE: SHRINKS TO CONTENTS:<br />
|
45 |
+
<div style="position:relative;text-align:left">
|
46 |
+
<table id="MYCUSTOMFLOATER" class="myCustomFloater" style="position:absolute;top:50px;left:0;background-color:#cecece;display:none;visibility:hidden">
|
47 |
+
<tr><td><!--
|
48 |
+
please see: http://chrisholland.blogspot.com/2004/09/geekstuff-css-display-inline-block.html
|
49 |
+
to explain why i'm using a table here.
|
50 |
+
You could replace the table/tr/td with a DIV, but you'd have to specify it's width and height
|
51 |
+
-->
|
52 |
+
<div class="myCustomFloaterContent">
|
53 |
+
you should never be seeing this
|
54 |
+
</div>
|
55 |
+
</td></tr>
|
56 |
+
</table>
|
57 |
+
<textarea class="wickEnabled:MYCUSTOMFLOATER" cols="50" rows="3" wrap="virtual"></textarea>
|
58 |
+
</div>
|
59 |
+
<br />
|
60 |
+
some content lah lah lah
|
61 |
+
<br />
|
62 |
+
<!--
|
63 |
+
My Fourth Box with developer-built floater USING DIV: FIXED WIDTH/HEIGHT:<br />
|
64 |
+
<div style="position:relative;text-align:left">
|
65 |
+
<div id="MYCUSTOMFLOATER_TWO" class="myCustomFloater" style="position:absolute;top:50px;left:0;background-color:#cecece;width:300px;height:400px;display:none;visibility:hidden">
|
66 |
+
<div class="myCustomFloaterContent">
|
67 |
+
you should never be seeing this
|
68 |
+
</div>
|
69 |
+
</div>
|
70 |
+
<textarea class="wickEnabled:MYCUSTOMFLOATER_TWO" cols="50" rows="3" wrap="virtual"></textarea>
|
71 |
+
</div>
|
72 |
+
-->
|
73 |
+
<br />
|
74 |
+
My Fifth Box:<br />
|
75 |
+
<input class="wickEnabled" type="text" size="50" /><br />
|
76 |
+
</form>
|
77 |
+
</p>
|
78 |
+
</center>
|
79 |
+
<script type="text/javascript" language="JavaScript" src="./sample_data.js.php"></script> <!-- WICK STEP 2: DEFINE COLLECTION ARRAY THAT HOLDS DATA -->
|
80 |
+
<script type="text/javascript" language="JavaScript" src="./wick.js"></script> <!-- WICK STEP 3: INSERT WICK LOGIC -->
|
81 |
+
<script>
|
82 |
+
document.getElementById("wickStatus").innerHTML = '<a target="_blank" href="./sample_data.js.php">Loaded <b>' + collection.length + '</b> Sample Addresses</a>';
|
83 |
+
</script>
|
84 |
+
</body>
|
85 |
+
</html>
|