Skip to content

Commit

Permalink
gallery-2012.06.13-20-30 mzgupta gallery-multivalue-input
Browse files Browse the repository at this point in the history
  • Loading branch information
YUI Builder committed Jun 13, 2012
1 parent e96d117 commit 118f0d9
Show file tree
Hide file tree
Showing 7 changed files with 469 additions and 0 deletions.
@@ -0,0 +1 @@
/*Nothing to write */
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -0,0 +1,61 @@
.yui3-skin-sam .yui3-multivalueinput-content{
background-color: white;
padding-left: 2px;
border: 1px solid #BDC7D8;
font: 11px "Lucida Grande","Verdana";
width:300px;
}


.yui3-skin-sam ul.yui3-multivalueinput-ul{
height: auto !important;
margin:0 !important;
padding: 4px 5px 0px 5px;
overflow: hidden;
}

.yui3-skin-sam li.yui3-multivalueinput-list{
float: left;
list-style-type: none;
margin: 0 5px 4px 0;
white-space: nowrap;

}

.yui3-skin-sam li.yui3-multivalueinput-listitem{
position: relative;
background: none repeat scroll 0 0 #DEE7F8;
border: 1px solid #CAD8F3;
padding: 1px 5px 2px 5px;
-moz-border-radius: 6px 6px 6px 6px;
-webkit-border-radius: 6px 6px 6px 6px;
-o-border-radius: 6px 6px 6px 6px;
padding-right: 15px;
}

.yui3-skin-sam li.yui3-multivalueinput-pendingdelete{
background-color: #4173CC !important;
}

.yui3-skin-sam li.yui3-multivalueinput-list a{
background: url("close.gif") repeat scroll 0 0 transparent;
display: block;
font-size: 1px;
height: 7px;
position: absolute;
right: 4px;
top: 4px;
width: 7px;
}
.yui3-skin-sam li.yui3-multivalueinput-list a:hover{
background-position: 7px 50%;
}

.yui3-skin-sam input.yui3-multivalueinput-input {
border: 0;
outline: 0;
margin: 0;
}
.yui3-skin-sam .yui3-multivalueinput-border {
border:1px solid #4D90FE;
}
7 changes: 7 additions & 0 deletions src/gallery-multivalue-input/build.properties
@@ -0,0 +1,7 @@
# Multivalue Input Build Properties

builddir=../../../builder/componentbuild
component=gallery-multivalue-input
component.jsfiles=multivalue-input.js
component.requires=plugin,substitute,node
component.skinnable=true
6 changes: 6 additions & 0 deletions src/gallery-multivalue-input/build.xml
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project name="MultiValueInput Plugin" default="local">
<description>An alternative of conventional multiselect input control, allows user to select multiple values in more user friendly way</description>
<property file="build.properties" />
<import file="${builddir}/3.x/bootstrap.xml" />
</project>
311 changes: 311 additions & 0 deletions src/gallery-multivalue-input/js/multivalue-input.js
@@ -0,0 +1,311 @@
"use strict";
/**********************************************************************
* Plugin which allows user select multiple value, it replaces the traditional ugly
* multi select input control
* @module gallery-multivalue-input
* @author MaYanK(mzgupta)
*/

/**
*
* @class QueryBuilder
* @extends Widget
* @constructor
* @param config {Object} Widget configuration
*/
function MultiValueInput(config) {
MultiValueInput.superclass.constructor.apply(this, arguments);
}


//Any frequently used shortcuts
var Lang = Y.Lang,
MVI = "multivalueinput",
getCN = Y.ClassNameManager.getClassName,
DIVCONTENT = getCN(MVI, "content"),
LIST = getCN(MVI, "list"),
LIST_ITEM = getCN(MVI,"listitem"),
UL = getCN(MVI, "ul"),
INPUT = getCN(MVI, "input"),
Node = Y.Node;





/*
* Required NAME static field, to identify the Widget class and
* used as an event prefix, to generate class names etc. (set to the
* class name in camel case).
*/
MultiValueInput.NAME = "multiValueInput";

//Name space of plugin in case host want to access the plugin
MultiValueInput.NS = "mvi";
/*
* The attribute configuration for the widget. This defines the core user facing state of the widget
*/
MultiValueInput.ATTRS = {
/*
* Array of values selected
* @attribute values
* @type {array}
*
* */
values : {
value : [],
validator: function(val) {
return Lang.isArray(val);
}
},
/*
* Placeholder for inputbox
* @attribute placeholder
* @type {String}
*
* */
placeholder : {
value : "type here"
}
};

/* Templates for any markup for multivalue input includes {} tokens, which are replaced through Y.substitute */

MultiValueInput.DIV_TEMPLATE = "<div class={div_class}></div>";

//UL tag contain list of values
MultiValueInput.VALUE_HOLDER_TEMPLATE = "<ul class={ul_class}></ul>";

//LI tag contain item values
MultiValueInput.LI_TEMPLATE = "<li class={list_class}>{item}</li>";

//markup for input control
MultiValueInput.INPUT_TEMPLATE = "<input type='text' placeholder={placeholder} class={input_class}></input>";

//Markup for remove icon
MultiValueInput.ITEM_REMOVE = "<a href='javascript:void(0)'>,</a>";

/* MultiValueInput extends the base Widget class */
Y.extend(MultiValueInput, Y.Plugin.Base,
{

initializer : function() {
var values = this.get("values"),placeholder=this.get("placeholder");
this._host = this.get("host");
this._host.set("placeholder",placeholder);

//Create Container div that contains list of values
this._divContent = this._createDivNode();
this._host.insert(this._divContent, "before");

//Create un order List
this._ul = this._createULNode();

if (values) {
for(var i=0;i<values.length;i++){
this._ul.appendChild(this._createListNode(values[i], true));
}
Y.log("List Initialized:"+this.get("values"),"info","MultiValueInput.initializer");
}
this._host.addClass(INPUT);
this._inputWrapper = this._createListNode("");
this._inputWrapper.appendChild(this._host);
this._ul.appendChild(this._inputWrapper);


this._divContent.appendChild(this._ul);

// Event Biniding

if (this._host.ac) {
//If host has autocomplete plugged
this._host.ac.after("select", this._appendItem, this);
} else {
this._host.after("change", this._appendItem, this);
}

this._host.after("blur", function() {
this._host.set("value", "");
this._divContent.removeClass("yui3-multivalueinput-border");
},this);

this._host.after("focus", function() {
this._host.set("value", "");
this._divContent.addClass("yui3-multivalueinput-border");
},this);

this._host.on("keydown", this._keyDownHandler, this);


},
destructor : function() {
},

/**
* Generate Markup for UL tag
* @method _keyDownHandler
* @protected
* @param {Event}
*/

_keyDownHandler:function(/* Event */ e){
var allList,lastItem, lastItemIndex;
if(e.keyCode !== 8){
return;
}
allList=this._ul.get("children");
lastItemIndex=allList.size()-2;
lastItem=allList.item(lastItemIndex);
if(!this._host.get("value")){
if(this._pendingDelete){
this._removeItem(lastItem, lastItemIndex);
this._pendingDelete = false;
}
else{
lastItem.addClass("yui3-multivalueinput-pendingdelete");
this._pendingDelete = true;
}
}
},

/**
* Generate Markup for UL tag
* @method _createULNode
* @protected
* @return {Node}
*/

_createULNode : function() {
return Node.create(Y.substitute(
MultiValueInput.VALUE_HOLDER_TEMPLATE, {
ul_class : UL
}));
},

/**
* Generate Markup for list tag
* @method _createListNode
* @protected
* @param index {int} the section index
* @return {Node}
*/

_createListNode : function(
/* String */ item,
/* boolean */ isListItem)
{
var listNode, anchorNode;
if (isListItem) {
anchorNode = Node.create(Y
.substitute(MultiValueInput.ITEM_REMOVE));
listNode = Node.create(Y.substitute(
MultiValueInput.LI_TEMPLATE, {
item : item,
list_class : LIST
}));
listNode.appendChild(anchorNode);
anchorNode.on("click", Y.bind(this._removeItem, this,
listNode));
listNode.addClass(LIST_ITEM);
} else {
listNode = Node.create(Y.substitute(
MultiValueInput.LI_TEMPLATE, {
item : item,
list_class : LIST
}));
}
return listNode;
},

/**
* Generate Markup for div tag
* @method _createDivNode
* @protected
* @return {Node}
*/

_createDivNode : function() {
return Node.create(Y.substitute(MultiValueInput.DIV_TEMPLATE, {
div_class : DIVCONTENT
}));
},

/**
* Get the index of remove item
* @method _getListIndex
* @protected
* @param {Node}
* @return {index}
*/

_getListIndex : function(listNode) {
var allList=this._ul.get("children"),size=allList.size();
for(var i=0;i<size;i++){
if(listNode.compareTo(allList.item(i))){
return i;
}
}
return -1;
},

/**
* add the item in to the list
* @method _appendItem
* @protected
* @return
*/

_appendItem : function() {
var val = this._host.get("value");
this._inputWrapper.insert(this._createListNode(val, true), "before");
this._addValue(val);
this._host.set("value", "");
},

/**
* remove the item from the list
* @method _removeItem
* @protected
* @param {Node}
* @return
*/

_removeItem : function(/* Node */selectedListNode, /* int */ idx) {
var index = idx || this._getListIndex(selectedListNode);
this._host.focus();
selectedListNode.get("parentNode")
.removeChild(selectedListNode);
this._removeValue(index);
},

/**
* Add value to value list
* @method _addValue
* @protected
* @return
*/

_addValue : function(val) {
var values = this.get("values");
values.push(val);
Y.log(val+" added to the List:"+this.get("values"),"info","MultiValueInput._addValue");
},

/**
* remove value from value list
* @method _removeValue
* @protected
* @param {index}
* @return
*/

_removeValue : function(/* int */ index) {
var values = this.get("values"), val = values[index];
values.splice(index,1);
Y.log(val+" removed from the List:"+this.get("values"),"info","MultiValueInput._removeValue");
}


});

Y.MultiValueInput = MultiValueInput;

0 comments on commit 118f0d9

Please sign in to comment.