19 May 2016 (revised 12 Nov 2019): wsurveyButtonToText.js documentation
Click on button to copy (or remove) a value from a list of textboxes
Useage:
buttonsToText(buttonClass,textClass,options)
where
buttonClass: a class used for each of the clickable "buttons"
textClass : a class used for "textbox" -- where "textbox" can be an or other field with a value element, or a simple container (such as )
options: optional. an object containing options.
Typically, there are several buttons and several textboxes (often, there are more buttons than textboxes)
What does this do:
When a button is clicked, its value (or the value of its 'useValue' attribute) is copied to the first "empty" textbox.
Thus: what is copied to the text box can be, but does NOT have to be, the value of the button!
If the value has already been copied to a textbox, clear it. Note that the useValue IS used -- so if you have two buttons (with different values),
they do the same thing (so clicking either one will clear the box with that useValue).
Or, you can copy to a to a "selected" textbox (see the options below for the details). In which case adding, and removing, is under user control
Thus, clicking a button will toggle the prescence of its value in the set of textboxes
Typically, a are used as "textboxes" -- but
basically anything can be used as "buttons"; and anything can be used as "textboxes".
Note that a click handler is assigned to each element with a buttonClass class.
These buttonClass elements can be fields (such as "radio" or "checkbox"), , , etc. So long as a click event can be assigned!
The fields in options:
collapse (default=1).
1 when removing (toggling off) a value, collapse the list (so there will be no internal empty textboxes)
0 just remove (don't collapse)
atEnd (default =0).
1 when copying a value, always place at end of textboxes. This is irreleveant if collapse=1
0 when copying, place in first empty textbox.
Note: if collapse =0, atEnd can have odd effects. In particular, if you have removed an item that is "in the middle" -- with
choices before and after it, then that text box will remain empty.
overwriteFinal (default=0)
1 when copying a value, and there are no spots free -- overwrite last spot
0 when copying a value, and there are no spots free -- do nothing
This is useful if there is only one "text" row. In that case, pressing buttons auto-fills this single row.
And if this is a "hidden" field, the user won't see "redundant" information (the coloring of the button is sufficient)
bySpot (default=0);
0 Use collapse and atEnd to determine what textbox to use
1 Use "most recently selected" text box. Thus, the same box will be modified if you click on a succession of buttons
(so prior choices are overwritten).
This allows the end user to fill in a specific set of text boxes in whatever order. It also allows the same
choice to be used multiple times.
If bySpot=1, the collapse, atEnd, and overwriteFinal are ignored.
Alternative: if bySpot='classname' -- the class is used to highlight the currently chosen "spot".
Note: if bySpot!=1, then buttons will NOT be highlighted when they are "selected" or "de-selected". The idea is that the user may wish to
select the same button multiple times (to be used in different text boxes), hence button highlighting might be confusing.
dragAndDrop (default=0). Ignored if bySpot=0
If 1, enable "drag and drop" -- mouse down a button, 'drag' to a Search on text box, and then release.
If a string, the string is the id of an element that is the parent container of the button and text elements.
If not specified (if dragAndDrop=1), a move is not cancelled on a button release. You have to reclick on a button
That is: if dragAndDrop=1,
a) click on a button and move the mouse off the button without releasing
b) Release mouse when off the button, move to a Text box, and click again.
Or, don't ever release, move to a text box, and then release.
Either action simulates a click on the text box, and then a click on the button.
During this move, the mouse cursor looks like a normal mouse cursor
c) This can stay active forever!
If you want to cancel this assignation; and return to the normal bySpot "click on text box, and then click on button"
mode -- you have to click on any of the buttons.
In contrast, if dragAndDrop="id_of_parent", then
a) click on a button and do NOT release
b) move to a Text box, and then release.
This simulates a click on the text box, and then a click on the button.
During this move, the mouse cursor is a "closed hand"
c) If you release anywhere else in this "id_of_parent" container, the move is cancelled
d) If you go outside of this "id_of_parent" container, you revert to dragAndDrop=1 performance.
Note: dragAndDrop uses two CSSclasses to highlight :
buttonsToText_buttonSelect : highlight the button currently being dragged (or selected)
buttonsToText_textSelect : highlight the text box that would be selected (if you released the mouse button)
If these don't exist, default values are used
onClass (default=none)
After adding this button's value to a textbox add this class to the button (and remove offColor class).
This is ignored if bySpot=0
It is meant to indicate which buttons have been "selected" -- to help the user keep track.
offClass (default=none)
After removing this button's value from a textbox, add this class to the button (and remove onColor class)
This is ignored if bySpot=0
It is meant to indicate which buttons have been "de-selected" (after being selected) -- to help the user keep track.
If you don't want to highlight deselections, use the same class used in the buttons (so the background of "never selected" and "de-selected" is the same).
clear1 (default='clear')
If clicked button has value (or useValue attribute) of this option (say, 'clear'), then erase value of last textbox.
This is ignored if bySpot!=0 (since there is no "last textbox")
Note:, when bySpot=0, you can also clear a chosen text fielfield by deselcting its corresponding button. Hence, clear1 is sort of deprecated.
clearAll (default='clearAll')
If clicked button has value (or useValue attribute) set by clearAll, then erase all textbox values
doCall (default='')
If not '', an attribute name.
If specified, (i.e.; 'doCall':'call') the value of this attribute (in the clicked button) is checked.
If it exists, its value should be the name of a function (specified as a string).
Example:
After buttonsToText does its thing, this function is called with the jquery object of the textbox that was modified, and a flag of what was done.
In the example: if doCall='call' is specified, then the myFuncUse button will be called (assuming myFuncUse is an existing function)
The function is called using afunc(textButtonObject,flagValue) (flagValue is set, clear, or clearall)
Flag values are: 'set', 'clear', 'clearAll'
'clearAll' is special: it is only used on a clearAll.
If 'clearAll', then the first argument in an array of jquery objects (all the text buttons).
Notes:
* the function is called using afunc(textButtonObject,flagValue) (flagValue is set, clear, or clearall)
where the "textObject" is a jQuery object of the text field selected (NOT the button clicked).
* to pass information specific to a "seleted textbox": you can use attributes in the textButtons -- the afunc can then read them using textBottonObject.attr(myAttribute)
* for clearAll, the jQuery containter of ALL the textObjects is sent (rather than just a single "selected" text box.
* The textButtonObject will contain the recent changes.
keyAutoFill (default=0)
If 1, then "auto fill" of text fields is supported. This means
* The user enters something (via keyboard) in one of the "text boxes"
* If it matchs (exact or abbreviation) one of the "values" of the "buttons", then
* When the user hits Enter, the matching button is "clicked" -- so the value (or the useValue) is written to the text box
Note: if there is more than one match, the first is used. However, an exact match is always used (even if it isn't first)
* If there is no match, an Enter does nothing
The user can always click out side of the text box (without hitting Enter).
If that happens, the text is as is. No attempt is made to check if the entered value matches what a button would of produced!
This will NOT work if the text field has a 'readonly' attribute
Thus:
a) text boxes are NOT readonly, keyAutoFill=0
allow the user to enter anything. Or he can click a button to fill the text box with the button's assigned value (or its useValue)
b) not readonly, keyAutoFill=1
The user can enter anything
... if it matches a button value, and he hits enter: the button's value (or useValue) is 'auto filled' into the text box
... if it does NOT match a button value, and he hits enter ... nothing happens (no auto-fill occurs).
Or, if he clicks outside the text box (without hitting enter), nothing happens -- the entered value is retain in the text box.
Or he can click a button!
c) readonly, keyAutoFill does not matter
The user can click a button to fill in a textbox (but can not enter with the keyboard)
In a sense,
(c) is safest -- you know what the user can enter. But it isn't very flexible
(b) is friendly, but a creative (or recalcitrant) user could enter something odd
(a) is simple and flexible, but it is easy to enter something odd.
Alternative: keyAutoFill=funcName
Auto fill occurs, but when enter is hit the funcName is called -- BEFORE autofill complete.
the call is: funcName(this,suggestedValue)
Note that funcname can find the current value with $(this).val(). And, funcname can read attributes of the text box.
Funcname should return:
0 : do nothing: text does not change, button "click" does not occur
1 : continue: a "click" on the button corresponding to the "suggested" value occurs (which will automatically change the text box value)
If there is NO button (if there is no match), this is the same as 0
2 : auto-complete: change text to the auto-complete value, but do NOT "click" on the corresponding button
If there is NO match, this clears the text box (same as 3)
3 : Clear the text, and do nothing
Anything else is interpreted as '0'
Notes:
* funcname can also switch focus, say by triggering another button.
For example: if the current box is empty, that can signal "submit a form"
* Funcname could (by using $(this).val('something new')) change the value of the text.
Be careful: a subsequent Enter may not do what the user expects!
Hint #1 :
To create a list of buttons used to choose a single value (with the value not directly displayed):
a) Create your page with just one element with the textClass class
b) That element should be
c) Create several buttonClass elements
d) Set opts={'bySpot':0,'overwriteFinal':0,'onClass':'thisChosenClass'}
buttonsToText('myTextClass','myButtonClass',opts)
e) On submit or whatever, check the findMeLater element for the msotly recently clicked buttone ("0" if none clicked)
Hint #2:
To go to another field (say, another text box) after a text field has been filled by a button
a) Insert a call="checkStuff" attribute in your buttons (and have a doCall="call" in the options.
b) In your text boxes, have a 'nextStep' attribute pointing to the id of the text-box to go to.
For example
What is your favorite animal: Why:
c) The function ...
function checkStuff(telement,iaction) {
var v1=telement.attr('nextStep');
$('#'+v1).focus();
}