vegUI.org home of the javascript based window manager and AJAX framework

vegUI Tutorial 13 - The Property Set Widget

written by vegu on 22 Dec, 2006 07:59:16
A live example of this tutorial can be found here.

All image files used in this tutorial can be downloaded here

The property set widget is useful when you need to collect lots of data from the user. A property set is basically a list of properties and every property has a name and a value. The user can click on the value field of a property to input a new value for the chosen property. Currently there are 4 method of input:


  1. Standard Text Input, input is gathered via text field

  2. Checkbox, good for boolean properties where you need to collect a yes or no answer from the user

  3. List, lets the user select the value for the property from a list element

  4. Custom, value is set by a function



Before we dive into this tutorial let me warn you that the property set element is probably the most complex vegUI element there is at the moment, hover considering that vegUI itself is not rocket science we should be able to tackle it together, so follow me! ;)

Why is it such a complex element? Well for one it combines a lot of existing vegUI elements, we need to set up a list template to use for the properties that require list input, we need to build a checkbox element that we can provide to the properties that need boolean input. The property set itself extends - like the list - the content box element.

There is a reason i've waited to do the property set as one of the last basic vegUI tutorials, because now we have already taken a look at all of the required elements in the previous tutorials.

Okay let's create the manager element.

Code: Javascript
Manager = new VegUIManager('Manager');
Manager.set(800,600,0,0);
Manager.T.Css.backgroundColor = '#b2b2b2';
Manager.build(document.body);
;


Creating the content box element



Since the property set element extends the content box element we first create a contentbox. We could assign the properties directly to the property set, but we will also clone the input list element from the same content box later on. I will not explain this stuff as we've done this in the previous tutorials. Most of the code below is taking from the content box tutorial, with some minor changes added.

Code: CSS
.btn_scroll_left_0 { background-image: url(btn_arrow_left_0.gif); }
.btn_scroll_left_1 { background-image: url(btn_arrow_left_1.gif); }
.btn_scroll_right_0 { background-image: url(btn_arrow_right_0.gif); }
.btn_scroll_right_1 { background-image: url(btn_arrow_right_1.gif); }
.btn_scroll_down_0 { background-image: url(btn_arrow_down_0.gif); }
.btn_scroll_down_1 { background-image: url(btn_arrow_down_1.gif); }
.btn_scroll_up_0 { background-image: url(btn_arrow_up_0.gif); }
.btn_scroll_up_1 { background-image: url(btn_arrow_up_1.gif); }
.btn_scroll_drag { background-color: #c8c8c8; }

.scroll_bar { background-color: #838383; }

.cbox_cholder {
border: 1px #838383 solid;
background-color: #fff;
}

.cbox_content {
font: bold 10px Verdana, Arial, Helvetica;
color: #838383;
}

.blank {
}


Code: CSS
/* create content box template */
CBox = Manager.get_new(VUI_CBOX);
CBox.set(200,150,100,100);
CBox.CHolder.T.className = 'cbox_cholder';
CBox.Content.T.className = 'cbox_content';

/* set up y axis scrollbar */

CBox.ScrollY.T.className = 'scroll_bar';
CBox.ScrollY.set('y',null,null,18);
CBox.ScrollY.T.rmarg_nr = -5;
CBox.ScrollY.T.bmarg = 13;

CBox.ScrollY.Btn1.set(0,0,18,18,'btn_scroll_up_0','btn_scroll_up_1');
CBox.ScrollY.Btn2.set(0,0,18,18,'btn_scroll_down_0','btn_scroll_down_1');
CBox.ScrollY.Btn3.set(0,0,18,18,'btn_scroll_drag','btn_scroll_drag');

CBox.ScrollY.Btn3.add_skin('t',18,4,0,0,0,null,null,null,null,'img','btn_drag_y_top.gif');
CBox.ScrollY.Btn3.add_skin('f',18,1,0,4,0,null,3,null,null,'img','btn_drag_y_fill.gif');
CBox.ScrollY.Btn3.add_skin('b',18,4,0,0,0,null,null,null,-1,'img','btn_drag_y_bottom.gif');
CBox.ScrollY.Btn3.add_skin('p',1,1,0,0,'blank',0,0,null,null);

CBox.flags |= VUI_HIDE_SCROLLX;


Make sure not to build this content box element as we will use it only as a template for both our property set and the input list.

The Property Set


Okay now that we have our content box template we can create our property set and clone it from the content box.

Code: Javascript
PropertySet = Manager.get_new(VUI_PROP_SET);
PropertySet.clone(CBox);


Then we set it up by calling its set() or set_propset() method.

Code: Javascript
PropertySet.set(400,400,100,100,50,0,0,0,'pset','pset_name','pset_value',30);

Definition: VegUIPropertySet.set_propset()

The first two arguments are width and height of the property set, argument three and four are it's x and y position. The fifth parameter is the width of the property name column in percent, in our case it will take up 50% of the property set width. Argument six is the fields object, which we skip at the moment as i will explain that later in detail. Paramters seven and eight are x and y position of the input list element, they currently do nothing so we skip them as well by passing them as 0. Argument 9 is the css class to use for the property set table element, argument 10 is the css class to use for the name field and argument 11 is the css class to use for the value field. The last parameter is the row height, if skipped row height will be dynamic.

Let's define those css classes quick before we move on.

Code: CSS
.pset {
border-collapse: collapse;
}

.pset_name {
background-color: #838383;
color: #fff;
padding: 5px;
font: bold 10px Verdana, Arial, Helvetica;
border-bottom: 1px #656565 solid;
}

.pset_value {
background-color: #d8d8d8;
border-bottom: 1px #838383 solid;
color: #000;
font: bold 10px Verdana, Arial, Helvetica;
padding: 5px;
}

The Input List


Okay, as i have stated earlier we will need both a checkbox element and a list element. The list element needs to be defined as a template. Every time an item is added to the property set that has list input selected as input type a list is cloned from the list element we create now. Again most of this code is taken from the list tutorial and will not be explained again here. Most of its properties are taking from the content box element we have created earlier anyways.

Code: CSS
.list_normal {
font: bold 10px Verdana, Arial, Helvetica;
color: #838383;
}

.list_selected {
font: bold 10px Verdana, Arial, Helvetica;
color: #fff;
background-color: #838383;
}

.list_hover {
font: bold 10px Verdana, Arial, Helvetica;
color: #fff;
background-color: #c8c8c8;
}

.list_label {
font: bold 10px Verdana, Arial, Helvetica;
color: #fff;
background-color: #fff;
border: 1px #838383 solid;
}


Code: Javascript
PSetList = Manager.get_new(VUI_LIST);
PSetList.clone(CBox);
PSetList.set(100,100,0,0,16,0);
PSetList.T.mOver = 'list_hover';
PSetList.T.mNormal = 'list_normal';
PSetList.T.mClick = 'list_selected';


Now our property needs to know how to find the list template we just created so it can use it later on. We accomplish that by setting the ListTemplate template property of the property set to the element index of our list template.

Code: Javascript
PropertySet.T.ListTemplate = PSetList.eleIdx;

The Checkbox


Now we need to setup the checkbox element as well. The checkbox will be shown to the user when the toggles the input mode of a property that is of type VUI_PSET_CHECK. Its intended use is to capture a true or false (yes / no) input from the user.

Again most of this code is taken from a previous tutorial: the checkbox tutorial, should you have questions regarding this elements please go back and read again :) However this time we dont need to create a checkbox template but can set the checkbox up directly as it is an existing child of the property set by the name of CbInput

Code: CSS
.btn_check_1 {
background-image: url('btn_cbox_unchecked.gif');
}

.btn_check_2 {
background-image: url('btn_cbox_checked.gif');
}

.checkbox_label {
font: bold 10px Verdana;
color: #383838;
padding-left: 5px;
}


Code: Javascript
PropertySet.CbInput.set(0,0,150,18,'yes/no',0,'btn_check_2','btn_check_1');
PropertySet.CbInput.BtnCheck.set(0,0,18,18);
PropertySet.CbInput.Label.T.className = 'checkbox_label';

The Text Input Field


Okay now that we got the tedious stuff behind us there is a little more setting up we need to do. There is a third input element that needs to be configured a bit. The text input, which is shown to the user when text input is required for a property. The input field in question is a child of the property set by the name of FldInput and all we have to do is set its className template property to our newly defined css class.

Code: CSS
.fldinput {
border: 1px #000 solid;
font: bold 10px Verdana, Arial, Helvetica;
}


Code: Javascript
PropertySet.FldInput.T.className = 'fldinput';

Moving on


Alright time to fill our property set with properties. We do this by creating a fields object. A fields object is a generic javascript object with a certain property structure. Every base property indicates a field, every field has multiple sub properties that define its behavior in the property set. Those sub properties are.

Code: Javascript
field.name => the name of the field
field.value => default value
field.type => input type
field.fill_list => reference to function that fills the list (if list input type)
field.fetch => reference to custom function that sets the value of this field
field.caption => caption of the field


The field name is the name of the field, duh! The field value is the default value that is set when the set is built. The field type is the input type of the field which can be set to one of four types.

Code: Javascript
VUI_PSET_INPUT => text input
VUI_PSET_CHECK => checkbox input
VUI_PSET_LIST => list input
VUI_PSET_CUSTOM => custom function input


The user can set the values of a property by clicking on the value field beside the property name. When clicked the value field will prompt the user with the selected input type. On text input a text input field is shown to the user and any changes the user makes need to be accepted by hitting the enter key on the keyboard. When checkbox input is set a checkbox will be shown to the user that when clicked will set the value of the property to the new state of the checkbox (true or false). On list input a list will be shown, before that list is shown the function stored in the fill_list property of the field will be called to fill the list with the necessary items.

The last input form is custom input. When the user clicks the value field if a property of the custom input type the function stored in the fields fetch property will be executed to set the value.

Confused yet? Dont worry we will go over it step by step.

Lets start by creating a fields object with one field only. This field will be of type text input.

Code: Javascript
PropertySet.T.fields = {
field_1 : {
name : 'field_1',
type : VUI_PSET_INPUT,
value : 'some default value',
caption : 'Field 1'
}
};


If the caption property is skipped then the field name will be shown in the name column of the property.

Lets take a second and build the property set and check it out, to make sure everything is in order :)
Code: Javascript
Manager.build_element(PropertySet);


Your page should look exactly like my example page (link at the top of this tutorial) except for the fact that it only has the first field. Try it out and click the value of the property, if everything is set up correct a text input field should show up and you should be able to enter some text. Verify the changes by hitting enter.

Everything worked? Great lets move on and add fields of the checkbox and list input type.

Code: Javascript
PropertySet.T.fields = {
field_1 : {
name : 'field_1',
type : VUI_PSET_INPUT,
value : 'some default value',
caption : 'Field 1'
},
field_2 : {
name : 'field_2',
type : VUI_PSET_CHECK,
value : false,
caption : 'Is this true?'
},
field_3 : {
name : 'field_3',
type : VUI_PSET_LIST,
fill_list : fill_me,
caption : 'List Selection'
}
};


Before we can check it out we need to define the function that will fill the list with the needed items. As the fill_list property indicates the name of our function will be fill_me :). Make sure you create the function before the fields are created else you will receive an error as field 3 tries to reference a function that does not exist.

Code: Javascript
function fill_me(List) {
List.flush();
var i;
for(i = 0; i < 10; i++)
List.add_item_txt('Item ' + i , i);
}


The List argument holds the actual list element that we need to work with. In other words it holds the list element that will be shown to the user when he is queried for input on the third property in our list. All our function does is clearing the list of any existing elements and re-adding them - sorta inefficient way to handle it but you get the drift.

The custom function


Lets add a last field to our property list, one that makes use of the custom input type. First lets create the function that will set the value, keep in mind this is a pretty simple straight forward example and this can be a really powerful way to set values in the property set.

Our function will be called fetch me and it will increase the value of the fourth field in our property set by one everytime it's value field is clicked.

Code: Javascript
function fetch_me(PSet, fld) {
PSet.dataset_cancel_input(fld.value + 1);
}


The PSet parameter is a reference to the property set element itself and the fld parameter holds a reference to the field that called this function. We call the dataset_cancel_input method to set the new value of the field - it's old value 1.

Okay now lets add our fourth field with the type VUI_PSET_CUSTOM.

Code: Javascript
PropertySet.T.fields = {
field_1 : {
name : 'field_1',
type : VUI_PSET_INPUT,
value : 'some default value',
caption : 'Field 1'
},
field_2 : {
name : 'field_2',
type : VUI_PSET_CHECK,
value : false,
caption : 'Is this true?'
},
field_3 : {
name : 'field_3',
type : VUI_PSET_LIST,
fill_list : fill_me,
caption : 'List Selection'
},
field_4 : {
name : 'field_4',
type : VUI_PSET_CUSTOM,
fetch : fetch_me,
caption : 'Custom Value',
value : 0
}
};


Processing the collected data


In order to be able to process the collected data the vegUI property set widget provides a function called to_xml. It creates an XML string that holds the collected data.

Code: Javascript
alert(PropertySet.to_xml('mydata'));

Definition: VegUIPropertySet.to_xml()

The parameter in this example is the tag name to use for the root element in the xml tree.

Dynamic Rebuilding of the dataset


It is also possible to rebuild the dataset (the property list) with a new fields object even after the property set element has been built. To do so you simply call the dataset_build() method of the property set and pass the new fields object to it.

Code: Javascript
PropertySet.dataset_build(newFieldsObject);

Definition: VegUIPropertySet.dataset_build()

Related Posts


Your Comment

name:*
email-address:

Are you human?



Comments

No comments yet.