...

View Full Version : How to pass new value to hidden input



sfraise
12-01-2010, 06:48 PM
I'm working on an autocomplete script and have it working close to what I need, however I have an issues.

I need to be able to pass a new value to the hidden field input, as it is now only selected values from the auto suggestions get's passed. I'm guessing I need to create some type of onchange or onclick event to do it but I'm not 100% sure how to go about it correctly. My first thought here is I should add a small + icon when clicked will add the new value.

Here's the script I'm using:


/*
* jQuery Plugin: Tokenizing Autocomplete Text Entry
* Version 1.1
*
* Copyright (c) 2009 James Smith (http://loopj.com)
* Licensed jointly under the GPL and MIT licenses,
* choose which one suits your project best!
*
*/

(function($) {

$.fn.tokenInput = function (url, options) {
var settings = $.extend({
url: url,
hintText: "Type in a search term",
noResultsText: "No results",
searchingText: "Searching...",
searchDelay: 300,
minChars: 1,
tokenLimit: null,
jsonContainer: null,
method: "GET",
contentType: "json",
queryParam: "q",
onResult: null
}, options);

settings.classes = $.extend({
tokenList: "token-input-list",
token: "token-input-token",
tokenDelete: "token-input-delete-token",
selectedToken: "token-input-selected-token",
highlightedToken: "token-input-highlighted-token",
dropdown: "token-input-dropdown",
dropdownItem: "token-input-dropdown-item",
dropdownItem2: "token-input-dropdown-item2",
selectedDropdownItem: "token-input-selected-dropdown-item",
inputToken: "token-input-input-token"
}, options.classes);

return this.each(function () {
var list = new $.TokenList(this, settings);
});
};

$.TokenList = function (input, settings) {
//
// Variables
//

// Input box position "enum"
var POSITION = {
BEFORE: 0,
AFTER: 1,
END: 2
};

// Keys "enum"
var KEY = {
BACKSPACE: 8,
TAB: 9,
RETURN: 13,
ESC: 27,
LEFT: 37,
UP: 38,
RIGHT: 39,
DOWN: 40,
COMMA: 188
};

// Save the tokens
var saved_tokens = [];

// Keep track of the number of tokens in the list
var token_count = 0;

// Basic cache to save on db hits
var cache = new $.TokenList.Cache();

// Keep track of the timeout
var timeout;

// Create a new text input an attach keyup events
var input_box = $("<input type=\"text\">")
.css({
outline: "none"
})
.focus(function () {
if (settings.tokenLimit == null || settings.tokenLimit != token_count) {
show_dropdown_hint();
}
})
.blur(function () {
hide_dropdown();
})
.keydown(function (event) {
var previous_token;
var next_token;

switch(event.keyCode) {
case KEY.LEFT:
case KEY.RIGHT:
case KEY.UP:
case KEY.DOWN:
if(!$(this).val()) {
previous_token = input_token.prev();
next_token = input_token.next();

if((previous_token.length && previous_token.get(0) === selected_token) || (next_token.length && next_token.get(0) === selected_token)) {
// Check if there is a previous/next token and it is selected
if(event.keyCode == KEY.LEFT || event.keyCode == KEY.UP) {
deselect_token($(selected_token), POSITION.BEFORE);
} else {
deselect_token($(selected_token), POSITION.AFTER);
}
} else if((event.keyCode == KEY.LEFT || event.keyCode == KEY.UP) && previous_token.length) {
// We are moving left, select the previous token if it exists
select_token($(previous_token.get(0)));
} else if((event.keyCode == KEY.RIGHT || event.keyCode == KEY.DOWN) && next_token.length) {
// We are moving right, select the next token if it exists
select_token($(next_token.get(0)));
}
} else {
var dropdown_item = null;

if(event.keyCode == KEY.DOWN || event.keyCode == KEY.RIGHT) {
dropdown_item = $(selected_dropdown_item).next();
} else {
dropdown_item = $(selected_dropdown_item).prev();
}

if(dropdown_item.length) {
select_dropdown_item(dropdown_item);
}
return false;
}
break;

case KEY.BACKSPACE:
previous_token = input_token.prev();

if(!$(this).val().length) {
if(selected_token) {
delete_token($(selected_token));
} else if(previous_token.length) {
select_token($(previous_token.get(0)));
}

return false;
} else if($(this).val().length == 1) {
hide_dropdown();
} else {
// set a timeout just long enough to let this function finish.
setTimeout(function(){do_search(false);}, 5);
}
break;

case KEY.TAB:
case KEY.RETURN:
case KEY.COMMA:
if(selected_dropdown_item) {
add_token($(selected_dropdown_item));
return false;
}
break;

case KEY.ESC:
hide_dropdown();
return true;

default:
if(is_printable_character(event.keyCode)) {
// set a timeout just long enough to let this function finish.
setTimeout(function(){do_search(false);}, 5);
}
break;
}
});

// Keep a reference to the original input box
var hidden_input = $(input)
.hide()
.focus(function () {
input_box.focus();
})
.blur(function () {
input_box.blur();
});

// Keep a reference to the selected token and dropdown item
var selected_token = null;
var selected_dropdown_item = null;

// The list to store the token items in
var token_list = $("<ul />")
.addClass(settings.classes.tokenList)
.insertAfter(hidden_input)
.click(function (event) {
var li = get_element_from_event(event, "li");
if(li && li.get(0) != input_token.get(0)) {
toggle_select_token(li);
return false;
} else {
input_box.focus();

if(selected_token) {
deselect_token($(selected_token), POSITION.END);
}
}
})
.mouseover(function (event) {
var li = get_element_from_event(event, "li");
if(li && selected_token !== this) {
li.addClass(settings.classes.highlightedToken);
}
})
.mouseout(function (event) {
var li = get_element_from_event(event, "li");
if(li && selected_token !== this) {
li.removeClass(settings.classes.highlightedToken);
}
})
.mousedown(function (event) {
// Stop user selecting text on tokens
var li = get_element_from_event(event, "li");
if(li){
return false;
}
});


// The list to store the dropdown items in
var dropdown = $("<div>")
.addClass(settings.classes.dropdown)
.insertAfter(token_list)
.hide();

// The token holding the input box
var input_token = $("<li />")
.addClass(settings.classes.inputToken)
.appendTo(token_list)
.append(input_box);

init_list();

//
// Functions
//


// Pre-populate list if items exist
function init_list () {
li_data = settings.prePopulate;
if(li_data && li_data.length) {
for(var i in li_data) {
var this_token = $("<li><p>"+li_data[i].cb_activities+"</p> </li>")
.addClass(settings.classes.token)
.insertBefore(input_token);

$("<span>x</span>")
.addClass(settings.classes.tokenDelete)
.appendTo(this_token)
.click(function () {
delete_token($(this).parent());
return false;
});

$.data(this_token.get(0), "tokeninput", {"cb_activities": li_data[i].cb_activities});

// Clear input box and make sure it keeps focus
input_box
.val("")
.focus();

// Don't show the help dropdown, they've got the idea
hide_dropdown();

// Save this token id
var id_string = li_data[i].cb_activities + ","
hidden_input.val(hidden_input.val() + id_string);
}
}
}

function is_printable_character(keycode) {
if((keycode >= 48 && keycode <= 90) || // 0-1a-z
(keycode >= 96 && keycode <= 111) || // numpad 0-9 + - / * .
(keycode >= 186 && keycode <= 192) || // ; = , - . / ^
(keycode >= 219 && keycode <= 222) // ( \ ) '
) {
return true;
} else {
return false;
}
}

// Get an element of a particular type from an event (click/mouseover etc)
function get_element_from_event (event, element_type) {
var target = $(event.target);
var element = null;

if(target.is(element_type)) {
element = target;
} else if(target.parent(element_type).length) {
element = target.parent(element_type+":first");
}

return element;
}

// Inner function to a token to the list
function insert_token(value) {
var this_token = $("<li><p>"+ value +"</p> </li>")
.addClass(settings.classes.token)
.insertBefore(input_token);

// The 'delete token' button
$("<span>x</span>")
.addClass(settings.classes.tokenDelete)
.appendTo(this_token)
.click(function () {
delete_token($(this).parent());
return false;
});

$.data(this_token.get(0), "tokeninput", {"cb_activities": value});

return this_token;
}

// Add a token to the token list based on user input
function add_token (item) {
var li_data = $.data(item.get(0), "tokeninput");
var this_token = insert_token(li_data.cb_activities);

// Clear input box and make sure it keeps focus
input_box
.val("")
.focus();

// Don't show the help dropdown, they've got the idea
hide_dropdown();

// Save this token id
var id_string = li_data.cb_activities + ","
hidden_input.val(hidden_input.val() + id_string);

token_count++;

if(settings.tokenLimit != null && settings.tokenLimit >= token_count) {
input_box.hide();
hide_dropdown();
}
}

// Select a token in the token list
function select_token (token) {
token.addClass(settings.classes.selectedToken);
selected_token = token.get(0);

// Hide input box
input_box.val("");

// Hide dropdown if it is visible (eg if we clicked to select token)
hide_dropdown();
}

// Deselect a token in the token list
function deselect_token (token, position) {
token.removeClass(settings.classes.selectedToken);
selected_token = null;

if(position == POSITION.BEFORE) {
input_token.insertBefore(token);
} else if(position == POSITION.AFTER) {
input_token.insertAfter(token);
} else {
input_token.appendTo(token_list);
}

// Show the input box and give it focus again
input_box.focus();
}

// Toggle selection of a token in the token list
function toggle_select_token (token) {
if(selected_token == token.get(0)) {
deselect_token(token, POSITION.END);
} else {
if(selected_token) {
deselect_token($(selected_token), POSITION.END);
}
select_token(token);
}
}

// Delete a token from the token list
function delete_token (token) {
// Remove the id from the saved list
var token_data = $.data(token.get(0), "tokeninput");

// Delete the token
token.remove();
selected_token = null;

// Show the input box and give it focus again
input_box.focus();

// Delete this token's id from hidden input
var str = hidden_input.val()
var start = str.indexOf(token_data.cb_activities+",");
var end = str.indexOf(",", start) + 1;

if(end >= str.length) {
hidden_input.val(str.slice(0, start));
} else {
hidden_input.val(str.slice(0, start) + str.slice(end, str.length));
}

token_count--;

if (settings.tokenLimit != null) {
input_box
.show()
.val("")
.focus();
}
}

// Hide and clear the results dropdown
function hide_dropdown () {
dropdown.hide().empty();
selected_dropdown_item = null;
}

function show_dropdown_searching () {
dropdown
.html("<p>"+settings.searchingText+"</p>")
.show();
}

function show_dropdown_hint () {
dropdown
.html("<p>"+settings.hintText+"</p>")
.show();
}

// Highlight the query part of the search term
function highlight_term(value, term) {
return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + term + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "<b>$1</b>");
}

// Populate the results dropdown with some results
function populate_dropdown (query, results) {
if(results.length) {
dropdown.empty();
var dropdown_ul = $("<ul>")
.appendTo(dropdown)
.mouseover(function (event) {
select_dropdown_item(get_element_from_event(event, "li"));
})
.mousedown(function (event) {
add_token(get_element_from_event(event, "li"));
return false;
})
.hide();

for(var i in results) {
if (results.hasOwnProperty(i)) {
var this_li = $("<li>"+highlight_term(results[i].cb_activities, query)+"</li>")
.appendTo(dropdown_ul);

if(i%2) {
this_li.addClass(settings.classes.dropdownItem);
} else {
this_li.addClass(settings.classes.dropdownItem2);
}

if(i == 0) {
select_dropdown_item(this_li);
}

$.data(this_li.get(0), "tokeninput", {"cb_activities": results[i].cb_activities});
}
}

dropdown.show();
dropdown_ul.slideDown("fast");

} else {
dropdown
.html("<p>"+settings.noResultsText+"</p>")
.show();
}
}

// Highlight an item in the results dropdown
function select_dropdown_item (item) {
if(item) {
if(selected_dropdown_item) {
deselect_dropdown_item($(selected_dropdown_item));
}

item.addClass(settings.classes.selectedDropdownItem);
selected_dropdown_item = item.get(0);
}
}

// Remove highlighting from an item in the results dropdown
function deselect_dropdown_item (item) {
item.removeClass(settings.classes.selectedDropdownItem);
selected_dropdown_item = null;
}

// Do a search and show the "searching" dropdown if the input is longer
// than settings.minChars
function do_search(immediate) {
var query = input_box.val().toLowerCase();

if (query && query.length) {
if(selected_token) {
deselect_token($(selected_token), POSITION.AFTER);
}
if (query.length >= settings.minChars) {
show_dropdown_searching();
if (immediate) {
run_search(query);
} else {
clearTimeout(timeout);
timeout = setTimeout(function(){run_search(query);}, settings.searchDelay);
}
} else {
hide_dropdown();
}
}
}

// Do the actual search
function run_search(query) {
var cached_results = cache.get(query);
if(cached_results) {
populate_dropdown(query, cached_results);
} else {
var queryStringDelimiter = settings.url.indexOf("?") < 0 ? "?" : "&";
var callback = function(results) {
if($.isFunction(settings.onResult)) {
results = settings.onResult.call(this, results);
}
cache.add(query, settings.jsonContainer ? results[settings.jsonContainer] : results);
populate_dropdown(query, settings.jsonContainer ? results[settings.jsonContainer] : results);
};

if(settings.method == "POST") {
$.post(settings.url + queryStringDelimiter + settings.queryParam + "=" + query, {}, callback, settings.contentType);
} else {
$.get(settings.url + queryStringDelimiter + settings.queryParam + "=" + query, {}, callback, settings.contentType);
}
}
}
};

// Really basic cache for the results
$.TokenList.Cache = function (options) {
var settings = $.extend({
max_size: 50
}, options);

var data = {};
var size = 0;

var flush = function () {
data = {};
size = 0;
};

this.add = function (query, results) {
if(size > settings.max_size) {
flush();
}

if(!data[query]) {
size++;
}

data[query] = results;
};

this.get = function (query) {
return data[query];
};
};

})(jQuery);

sfraise
12-01-2010, 11:23 PM
This is solved, I ditched the ui version and went with another script.



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum