possible to “catch” a javascript-variable to put it into php

Archived from the Xataface Users forum.

Markus — Tue May 15, 2007 7:32 am

Hello df-users, hello steve,

i wonder wether it could be possible to “catch” a javascript variable and use it in a php-function. The Thing is, i tested your little Happy Birthday - Alert JavaScript i found somewhere here. I changed it a little bit to get an id out. When doing so and combining with a select in fields.ini and a valuelist i got an alert with the id of the corresponding record onchange of my select field.

In order to have dynamic valuelists could i somehow get this id into a php-function? I know, there could not be dynamic valuelists, i read it somewhere. But if i could kind of translate this JavaScript variable into php, maybe it works?

I want to accomplish the following: Given i have two tables linked with a foreign_key ID one the source one the destination table. Each record in the source table has some related records in the destination table. In my new record form where i have two selects i want to select one value in the first select and then the second select should display only the related values.

Normally i can not get this until something is saved in my db, i know. But would it be possible using either the above mentioned javascipt-variable or doing some other javascript action with an widget:attsnchange of the first select? I tried a little but could no achieve something.

Right now i am still using 0.6.13r4 instead of 0.7 version.

Thank you for your help, hopefully you understand, what i mean

Markus


shannah — Tue May 15, 2007 11:58 am

Ok.. I think I see what you mean.

Let me recap so that I can make sure that I understand.

On your form you have:

[Select_list_A]
widget:type=select
vocabulary=valuelist_1

[Select_list_B]
widget:type=select
vocabulary=valuelist_2

And you want the values in valuelist_2 to depend on the value chosen for Select_list_A?

If this is the case, then there is a bit of stickiness you have to deal with.Ê If feasible and possible, I would make valuelist_2 contain all of the possible values that Select_list_B can take on.Ê Then just use javascript to filter them.

This can still be a bit tricky.Ê I have done a few maneuvres like this one before… I’ll see if I can track down some examples.

Dataface 0.7 has some features to make it easy to do this with checkboxes, but I haven’t gotten around to adding the “simple” way of doing it to select lists.Ê One of the coming versions will allow you to do this 100% in the ini file, but it may be a few months before this gets added and released.

-Steve


Markus — Wed May 16, 2007 3:37 am

Thank you for your hints. My application is structured like you write. All possible values that select_list_B can take on are in there.

The values from select_list_A are from list_event_group table which is related to the table list_event_type.

TABLE list_event_group has the structure:

l_gid (int, auto increment)
type_group (varchar)

Table list_event_type has

l_tid (int, auto increment)
L_GID (int, relation to Table A)
type (varchar)

Every type_group in Table A has some related types in Table B

I do something like

[list_event_group]
__sql__ = “select l_gid, type_group from list_event_group”

[list_event_type]
__sql__ = “select l_tid, L_GID, type from list_event_type”

in my valuelists.ini of a THIRD TABLE called events and has L_GID, L_TID as foreign keys.

But this gets all the data in Select_list_B instead of only the related ones.

And I can not use a $l_gid in the valuelists.ini like
__sql__ = “select l_tid, L_GID, type from list_event_type WHERE L_GID=$l_gid”

This because there is no l_gid submitted when jumping from SELECT A to SELECT B, right?
This l_gid variable I have to get somehow with javascript.

Am i right until here?

The problem ist the javascript filter because i am not really deep into javascript. So if you could find an example I can learn from would be great.

Maybe there are other solutions with version 0.71 I have installed now. You mentioned checkboxes. This would be an opportunity instead of select A maybe because there are only 5 values in there.

Thank you for your patience once more

Markus


Markus — Thu May 24, 2007 11:59 am

Ok.. I think I see what you mean.

Let me recap so that I can make sure that I understand.

On your form you have:

[Select_list_A]
widget:type=select
vocabulary=valuelist_1

[Select_list_B]
widget:type=select
vocabulary=valuelist_2

And you want the values in valuelist_2 to depend on the value chosen for Select_list_A?

If this is the case, then there is a bit of stickiness you have to deal with. If feasible and possible, I would make valuelist_2 contain all of the possible values that Select_list_B can take on. Then just use javascript to filter them.

This can still be a bit tricky. I have done a few maneuvres like this one before… I’ll see if I can track down some examples.

Dataface 0.7 has some features to make it easy to do this with checkboxes, but I haven’t gotten around to adding the “simple” way of doing it to select lists. One of the coming versions will allow you to do this 100% in the ini file, but it may be a few months before this gets added and released.

-Steve

Hello Steve,

I think I am a little further now but how i said before I am not a JavaScript - Enthusiast Please refer to my last posting in this thread also.

OK. I can pass the JavaScript-Variable to the URL with a little trick when opening a new browser-window and after that read it out with php which I don’t want because it is ugly.

I still have my two selects, values in select two depending on choosen values in select one.

I have a Javascript-Function in javascript.js which reads out the ID of the value in select one and puts it into a link.

The Link is http://www.mydomain.de/path/to/my/app/index.php?-action=new&-table=event&type_group=2 where type_group is the JavaScript Variable.

When I select a value from select one where i have the widget:attsnchange = “myJavascriptFunction(this.value);” in my fields.ini the Link will open in a new blank browser-window.

If I click on the Link now, which brings me back to my form, the selected value in select one is not selected anymore BUT select two shows only the values dependent on my selection in select one.
This because I have a function in the ApplicationDelegate of this table which reads out the type_group var from the URL and processes it further in a php-query.

Better than before but not perfect so far…

How can I -maybe with using actions.ini and javascript.js - files ??? for this single table- avoid that a new blank window is opened between focussing select one and select two.

I can feel there must be a solution but did not manage to find it til now.
Maybe there are other JavaScript or AJAX-specialized users here to help me out.

Thank you for all hints.

Markus


shannah — Thu May 24, 2007 12:17 pm

Hi Markus,

How do you determine which options should be available in the 2nd select?Ê Do you have a naming convention for the values, or is it based on related values?Ê Here’s what I generally do:
The valuelist for the 2nd select list is *big* - it holds all possible values that that 2nd field can take regardless of what is selected in the first field.
I write an onchange event handler and attach it to the first select list.Ê This handler goes through the options in the second select list and hides the values that shouldn’t be shown based on what is selected in the first list.ÊÊ If you let me know how you are determining which options in the 2nd list should be selected, I can go into some more details about how to approach this.
-Steve


Markus — Fri May 25, 2007 3:00 am

Hi Markus,

How do you determine which options should be available in the 2nd select? Do you have a naming convention for the values, or is it based on related values? Here’s what I generally do:
The valuelist for the 2nd select list is *big* - it holds all possible values that that 2nd field can take regardless of what is selected in the first field.
I write an onchange event handler and attach it to the first select list. This handler goes through the options in the second select list and hides the values that shouldn’t be shown based on what is selected in the first list. If you let me know how you are determining which options in the 2nd list should be selected, I can go into some more details about how to approach this.
-Steve

Hi Steve,

Oh. I thought I had already explained (in my last but second posting). I’ll try to make it a little bit clearer. I have the so called type_group in the first select. I have the type in second select. Both valuelists come from SQL-queries of two related tables as shown above in my other posting. Each type_group has related types by a foreign key in the second valuelist. If the user selects a value (type_group) in the first (an onchange event handler is already in the fields.ini) only the relates values (type) should show up in the second. The first one should remain the selected value.

How to hide the non-related values in the second valuelist then?

Thank you for your help

Markus


shannah — Fri May 25, 2007 12:46 pm

Here’s an AJAX solution:

create a custom action named get_types as follows:

Add a file named get_types.php into your actions directory with the following contents:

php<br /class actions_get_types {
ÊÊÊ function handle(&$params){
ÊÊÊÊÊÊÊ if ( isset($_REQUEST[‘type_group’]) ){
ÊÊÊÊÊÊÊÊÊÊÊ $sql = “select type_id, type_name from types where type_group=’“.addslashes($_REQUEST[‘type_group’]).”’”;
ÊÊÊÊÊÊÊ } else {
ÊÊÊÊÊÊÊÊÊÊÊ $sql = “select type_id, type_name from types”;
ÊÊÊÊÊÊÊ }
ÊÊÊÊÊÊÊ $res = mysql_query($sql, df_db());
ÊÊÊÊÊÊÊ if ( !$res ) trigger_error(mysql_error(df_db()), E_USER_ERROR);
ÊÊÊÊÊÊÊ header(‘Content-type: text/javascript’);
ÊÊÊÊÊÊÊ echo ‘[’;
ÊÊÊÊÊÊÊ $values = array();
ÊÊÊÊÊÊÊ while ( $row = mysql_fetch_assoc($res) ){
ÊÊÊÊÊÊÊÊÊÊÊ $values[] =Ê “{id:’”.$row[‘type_id’].”’, name: ‘“.addslashes($row[‘type_name’]).”’}”;
ÊÊÊÊÊÊÊ }
ÊÊÊÊÊÊÊ echo implode(‘,’,$values);
ÊÊÊÊÊÊÊ echo ‘]’;
ÊÊÊÊÊÊÊ exit;
ÊÊÊ }
}

?> Ê

What this does is returns the values for a given type group in JSON format (which javascript can read very easily).

Then in javascript you could do something like:

var types_http = getHTTPObject();

/**
Ê* updateTypesList
Ê* This function is to be assigned in the onchange handler for the group types select list.
Ê*/

function updateTypesList(type_groups_select){
ÊÊÊ // type_groups_select is a reference to the type_groups select list
ÊÊÊ var selectedGroup = type_groups_select.options[group_list.selectedIndex].value;
Ê Ê var url = DATAFACE_SITE_HREF +’?-action=get_types&type_group=’.escape(selectedGroup);
Ê Ê types_http.open(“GET”, url);
Ê Ê types_http.onreadystatechange =Ê handleUpdateTypesList;
ÊÊÊÊÊÊÊ // Assign the handleUpdateTypesList function as a handler to be called when the HTTP object receives a response from the server
ÊÊÊ types_http.group_list = type_groups_select;
ÊÊÊÊÊÊÊ // Save a reference to the group types select list in the http object so that it can be accessed from the handleUpdateTypesList function
ÊÊÊ types_http.send(null);
}

/**
Ê* handleUpdateTypesList
Ê* This function is called when a response is received from the HTTP object after we request the types for a particular group.
Ê*/
function handleUpdateTypesList(){
ÊÊÊ if ( types_http.readystate == 4 ){
ÊÊÊÊÊÊÊ // We have successfully obtained the response from the server
ÊÊÊÊÊÊÊ var options = eval(‘(‘ + types_http.responseText +’)’);
ÊÊÊÊÊÊÊ // we now have the options that we will use to fill the 2nd select list as an array
ÊÊÊÊÊÊÊ // now let’s get out select list and refill it
ÊÊÊÊÊÊÊ var types_list = types_http.group_list.form.elements[‘type_id’];
ÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊÊ // We obtain a reference to the type_id select list (let’s assume that the field is named type_id.. if not, then change this).
ÊÊÊÊÊÊÊÊÊÊÊ // Clear the existing options in the types list.
ÊÊÊÊÊÊÊ for ( var i=0; iÊÊÊÊÊÊÊÊÊÊÊ types_list.options[i] = new Option(options[i][‘name’], options[i][‘id’]);
ÊÊÊÊÊÊÊ }
ÊÊÊ }

}

Finally you can add the following to your fields.ini file for the type_groups field:
[type_groups]
widget:attsnchange=”updateTypesList(this):”

Now this code has not been tested, and I undoubtedly have the names of fields wrong,Ê - so you will need to work with it a bit to make it work.. but this is the general strategy to take.

References:

http://www.javascriptkit.com/javatutors/selectcontent.shtml
http://www.developer.com/lang/jscript/article.php/3596836

Best regards

Steve


Markus — Fri May 25, 2007 1:48 pm

Hi Steve,

thanks a lot for your work and the references I had a short look on. I cannot test it right now because I will go on holiday for the weekend early tomorrow but I am eager to try it when I am back. I will give you a response then.

By the way let me thank you for developing this great framework. I was thinking of testing seagull or tried dadabik before but I think dataface is the one I should use now and in future. I am nearly convinced of it. It is a little bit a pity that the community here is still very small but I hope it will grow very soon. On the long run you should not be the only one answering most of the questions by yourself. On the other hand it is really familiar here and I also like it this way

Have a nice weekend

Markus


Markus — Tue May 29, 2007 6:43 am

Here’s an AJAX solution:

create a custom action named get_types as follows:

Add a file named get_types.php into your actions directory with the following contents:

php<br /class actions_get_types {
function handle(&$params){
if ( isset($_REQUEST[‘type_group’]) ){
$sql = “select type_id, type_name from types where type_group=’“.addslashes($_REQUEST[‘type_group’]).”’”;
} else {
$sql = “select type_id, type_name from types”;
}
$res = mysql_query($sql, df_db());
if ( !$res ) trigger_error(mysql_error(df_db()), E_USER_ERROR);
header(‘Content-type: text/javascript’);
echo ‘[’;
$values = array();
while ( $row = mysql_fetch_assoc($res) ){
$values[] = “{id:’”.$row[‘type_id’].”’, name: ‘“.addslashes($row[‘type_name’]).”’}”;
}
echo implode(‘,’,$values);
echo ‘]’;
exit;
}
}

?>

What this does is returns the values for a given type group in JSON format (which javascript can read very easily).

Then in javascript you could do something like:

var types_http = getHTTPObject();

/**
* updateTypesList
* This function is to be assigned in the onchange handler for the group types select list.
*/

function updateTypesList(type_groups_select){
// type_groups_select is a reference to the type_groups select list
var selectedGroup = type_groups_select.options[group_list.selectedIndex].value;
var url = DATAFACE_SITE_HREF +’?-action=get_types&type_group=’.escape(selectedGroup);
types_http.open(“GET”, url);
types_http.onreadystatechange = handleUpdateTypesList;
// Assign the handleUpdateTypesList function as a handler to be called when the HTTP object receives a response from the server
types_http.group_list = type_groups_select;
// Save a reference to the group types select list in the http object so that it can be accessed from the handleUpdateTypesList function
types_http.send(null);
}

/**
* handleUpdateTypesList
* This function is called when a response is received from the HTTP object after we request the types for a particular group.
*/
function handleUpdateTypesList(){
if ( types_http.readystate == 4 ){
// We have successfully obtained the response from the server
var options = eval(‘(‘ + types_http.responseText +’)’);
// we now have the options that we will use to fill the 2nd select list as an array
// now let’s get out select list and refill it
var types_list = types_http.group_list.form.elements[‘type_id’];
// We obtain a reference to the type_id select list (let’s assume that the field is named type_id.. if not, then change this).
// Clear the existing options in the types list.
for ( var i=0; i types_list.options[i] = new Option(options[i][‘name’], options[i][‘id’]);
}
}

}

Finally you can add the following to your fields.ini file for the type_groups field:
[type_groups]
widget:atts” title=”Surprised” />nchange=”updateTypesList(this):”

Now this code has not been tested, and I undoubtedly have the names of fields wrong, - so you will need to work with it a bit to make it work.. but this is the general strategy to take.

References:

[http://www.javascriptkit.com/javatutors/selectcontent.shtml](http://www.javascriptkit.com/javatutors/selectcontent.shtml)
[http://www.developer.com/lang/jscript/article.php/3596836](http://www.developer.com/lang/jscript/article.php/3596836)

Best regards

Steve

Hi Steve,

now I am testing with your suggestions. To verify that I am doing everything right I will give you a nearly complete overview about the things I have done so far.

In my app I have the tables:

list_event_group

l_gid (int,8) NOT NULL, auto increment PRIMARY KEY
type_group (varchar,30) NULL

list_event_type

l_tid (int,8) NOT NULL, auto increment PRIMARY KEY
L_GID (int,8) NULL
type (varchar,256) NULL

event

eid (int,8) NOT NULL, auto increment PRIMARY KEY
L_GID (int,8) NOT NULL
L_TID (int,8) NOT NULL
more fields…

Currently I am working with the table event

valuelists.ini

[list_event_group]
__sql__ = “select l_gid, type_group from list_event_group”

[list_event_type]
__sql__ = “select l_tid, L_GID, type from list_event_type”

fields.ini

other fields…

[L_GID]
widget:label = “Ereignisgruppen ID”
widget:description = “Die Ereignisgruppen ID des Ereignisses”
widget:type = “select”
vocabulary = “list_event_group”
widget:attsnchange=”updateTypesList(this);”
actions = “get_types”

[L_TID]
widget:label = “Ereignistyp ID”
widget:description = “Die Ereignistyp ID des Ereignisses”
widget:type = “select”
vocabulary = “list_event_type”

other fields…

relationships.ini

other relationship…

[list_event_group]
list_event_group.l_gid = “$L_GID”

[list_event_type]
list_event_type.l_tid = “$L_TID”

Now I took your code like above and did the following in the http://path/to/my/app/actions Directory

I made a get_types.php and changed the field-names corresponding to my field-names:

php<br /class actions_get_types {
function handle(&$params){
if ( isset($_REQUEST[‘L_GID’]) ){
$sql = “select l_tid, type from list_event_type where L_GID=’“.addslashes($_REQUEST[‘L_GID’]).”’”;
} else {
$sql = “select L_tid, type from list_event_type”;
}
$res = mysql_query($sql, df_db());
if ( !$res ) trigger_error(mysql_error(df_db()), E_USER_ERROR);
header(‘Content-type: text/javascript’);
echo ‘[’;
$values = array();
while ( $row = mysql_fetch_assoc($res) ){
$values[] = “{l_tid:’”.$row[‘l_tid’].”’, type: ‘“.addslashes($row[‘type’]).”’}”;
}
echo implode(‘,’,$values);
echo ‘]’;
exit;
}
}

?>

In the http://path/to/my/app/javascripts.ini I have the following:

var types_http = getHTTPObject();

/**
* updateTypesList
* This function is to be assigned in the onchange handler for the group types select list.
*/

function updateTypesList(list_event_group_select){
// list_event_groups_select is a reference to the list_event_group select list
var selectedGroup = list_event_groups_select.options[list_event_group.selectedIndex].value;
var url = DATAFACE_SITE_HREF +’?-action=get_types&type_group=’.escape(selectedGroup);
types_http.open(“GET”, url);
types_http.onreadystatechange = handleUpdateTypesList;
// Assign the handleUpdateTypesList function as a handler to be called when the HTTP object receives a response from the server
types_http.list_event_group = list_event_groups_select;
// Save a reference to the list_event_groups select list in the http object so that it can be accessed from the handleUpdateTypesList function
types_http.send(null);
}

/**
* handleUpdateTypesList
* This function is called when a response is received from the HTTP object after we request the types for a particular group.
*/
function handleUpdateTypesList(){
if ( types_http.readystate == 4 ){
// We have successfully obtained the response from the server
var options = eval(‘(‘ + types_http.responseText +’)’);
// we now have the options that we will use to fill the 2nd select list as an array
// now let’s get out select list and refill it
var list_event_type = types_http.list_event_group.form.elements[‘l_tid’];
// We obtain a reference to the type_id select list (the field is named l_tid so I changed it).
// Clear the existing options in the types list.
for ( var i=0; i list_event_type.options[i] = new Option(options[i][‘type’], options[i][‘l_tid’]);
}
}

}

When doing all this, whats happening is:

In my application new record form I choose the list_event_group select and select an item.

The list_event_type select then stays empty and in my IE status bar I get a JavaScript-Error whose details say: list_event_group ist undefiniert (“is undefined” in english, I suppose).

Where did I go wrong here?

Thank you again


shannah — Tue May 29, 2007 8:54 am

It may be objecting to adding the list_event_group member variable to the types_http object.Ê Another way to accomplish this is to create a global variable called list_event group and then replace all references to types_http.list_event_group to just list_event_group.

e.g.:Ê

After
var types_http = getHTTPObject();
add
var list_event_group = null;
And then replace all references to types_http.list_event_group to just list_event_group
-Steve


Markus — Tue May 29, 2007 9:06 am

Hi Steve,

some more questions occured, when I tried your code:

FIRST:

function updateTypesList(type_groups_select){
// type_groups_select is a reference to the type_groups select list

Does that mean, that I have to replace “type_groups_select” with the name of my table which is “list_event_group” and name the function updateTypesList(list_event_groups_select) ?
Does the plural or the _select within the brakes mean anything according to naming conventions in DF?

Or do I have to replace “type_groups_select” through the name of my select widget in fields.ini which is L_GID and write updateTypesList(L_GID)?

I have tried a little, but still could not get anything out of my list_event_type select field.

SECOND:

When I look into the error-console of firefox browser it says GetHTTPObject() is not defined.

Maybe this can help you to find something wrong

Best regards

Markus


Markus — Tue May 29, 2007 9:08 am

Hi Steve,

some more questions occured, when I tried your code:


Markus — Tue May 29, 2007 9:35 am

It may be objecting to adding the list_event_group member variable to the types_http object. Another way to accomplish this is to create a global variable called list_event group and then replace all references to types_http.list_event_group to just list_event_group.

e.g.:

After
var types_http = getHTTPObject();
add
var list_event_group = null;
And then replace all references to types_http.list_event_group to just list_event_group
-Steve

My code in javascript.js now:

//FUNKTIONEN ANGEPASST
var types_http = getHTTPObject();
var list_event_group = null;

/**
* updateTypesList
* This function is to be assigned in the onchange handler for the group types select list.
*/

function updateTypesList(list_event_groups_select){
// list_event_group_select is a reference to the list_event_group select list
var selectedGroup = list_event_groups_select.options[list_event_group.selectedIndex].value;
var url = DATAFACE_SITE_HREF +’?-action=get_types&list_event_group=’.escape(selectedGroup);
types_http.open(“GET”, url);
types_http.onreadystatechange = handleUpdateTypesList;
// Assign the handleUpdateTypesList function as a handler to be called when the HTTP object receives a response from the server
list_event_group = list_event_groups_select;
// Save a reference to the group types select list in the http object so that it can be accessed from the handleUpdateTypesList function
types_http.send(null);
}

/**
* handleUpdateTypesList
* This function is called when a response is received from the HTTP object after we request the types for a particular group.
*/
function handleUpdateTypesList(){
if ( types_http.readystate == 4 ){
// We have successfully obtained the response from the server
var options = eval(‘(‘ + types_http.responseText +’)’);
// we now have the options that we will use to fill the 2nd select list as an array
// now let’s get out select list and refill it
var list_event_type = types_http.list_event_group.form.elements[‘l_tid’];
// We obtain a reference to the type_id select list (let’s assume that the field is named type_id.. if not, then change this).
// Clear the existing options in the types list.
for ( var i=0; i list_event_type.options[i] = new Option(options[i][‘type’], options[i][‘l_tid’]);
}
}

}

and error-console of firefox goes:

getHTTPObject() is not defined

list_event_group has no properties

Any idea?

Markus


shannah — Wed May 30, 2007 10:02 am

The getHTTPObject() function is defined in the js/ajax.js file in the dataface installation folder.ÊÊ Most likely it hasn’t been loaded yet in your document.Ê If you change the following:

var types_http = getHTTPObject();

var list_event_group = null;

to

require(DATAFACE_SITE_URL+’/js/ajax.js’);
var types_http = null;
var list_event_group = null;

And then add the following to the updateTypesList() function:

if ( types_http == null ) types_http = getHTTPObject();

That should give the function time to be loaded before it is called.

The second error (list_event_group has no properties) is coming up because you haven’t changed the types_http.list_event_group to just list_event_group in the handler function.

-Steve


Markus — Wed May 30, 2007 10:52 am

The getHTTPObject() function is defined in the js/ajax.js file in the dataface installation folder. Most likely it hasn’t been loaded yet in your document. If you change the following:

var types_http = getHTTPObject();

var list_event_group = null;

to

require(DATAFACE_SITE_URL+’/js/ajax.js’);
var types_http = null;
var list_event_group = null;

And then add the following to the updateTypesList() function:

if ( types_http == null ) types_http = getHTTPObject();

That should give the function time to be loaded before it is called.

The second error (list_event_group has no properties) is coming up because you haven’t changed the types_http.list_event_group to just list_event_group in the handler function.

-Steve

Hi Steve,

I changed the code to:

//FUNKTIONEN ANGEPASST
require(DATAFACE_SITE_URL+’/js/ajax.js’);
var types_http = null;
var list_event_group = null;

/**
* updateTypesList
* This function is to be assigned in the onchange handler for the group types select list.
*/

function updateTypesList(list_event_groups_select){
if ( types_http == null ) types_http = getHTTPObject();
// list_event_group_select is a reference to the list_event_group select list
var selectedGroup = list_event_groups_select.options[list_event_group.selectedIndex].value;
var url = DATAFACE_SITE_HREF +’?-action=get_types&list_event_group=’.escape(selectedGroup);
types_http.open(“GET”, url);
types_http.onreadystatechange = handleUpdateTypesList;
// Assign the handleUpdateTypesList function as a handler to be called when the HTTP object receives a response from the server
list_event_group = list_event_groups_select;
// Save a reference to the group types select list in the http object so that it can be accessed from the handleUpdateTypesList function
types_http.send(null);
}

/**
* handleUpdateTypesList
* This function is called when a response is received from the HTTP object after we request the types for a particular group.
*/
function handleUpdateTypesList(){
if ( types_http.readystate == 4 ){
// We have successfully obtained the response from the server
var options = eval(‘(‘ + types_http.responseText +’)’);
// we now have the options that we will use to fill the 2nd select list as an array
// now let’s get out select list and refill it
var list_event_type = list_event_group.form.elements[‘l_tid’];
// We obtain a reference to the type_id select list (let’s assume that the field is named type_id.. if not, then change this).
// Clear the existing options in the types list.
for ( var i=0; i list_event_type.options[i] = new Option(options[i][‘type’], options[i][‘l_tid’]);
}
}

}

as you said. The first error does not occur any longer. Thank you for your help. But the second one “list_event_group has no properties” is still there.

And I would like to know wether the naming in function updateTypesList, which means(list_event_groups_select) follows special naming conventions in DF? Especially the Plural and the _select. Or am I free to name it somehow. See similar question in my last but second posting.

Thank you

Markus


Markus — Tue May 29, 2007 9:06 am

Hi Steve,

some more questions occured, when I tried your code:

FIRST:

function updateTypesList(type_groups_select){
// type_groups_select is a reference to the type_groups select list

Does that mean, that I have to replace “type_groups_select” with the name of my table which is “list_event_group” and name the function updateTypesList(list_event_groups_select) ?
Does the plural or the _select within the brakes mean anything according to naming conventions in DF?

Or do I have to replace “type_groups_select” through the name of my select widget in fields.ini which is L_GID and write updateTypesList(L_GID)?

I have tried a little, but still could not get anything out of my list_event_type select field.

SECOND:

When I look into the error-console of firefox browser it says GetHTTPObject() is not defined.

Maybe this can help you to find something wrong

Best regards

Markus


Markus — Tue May 29, 2007 9:08 am

Hi Steve,

some more questions occured, when I tried your code:


Markus — Tue May 29, 2007 9:35 am

It may be objecting to adding the list_event_group member variable to the types_http object. Another way to accomplish this is to create a global variable called list_event group and then replace all references to types_http.list_event_group to just list_event_group.

e.g.:

After
var types_http = getHTTPObject();
add
var list_event_group = null;
And then replace all references to types_http.list_event_group to just list_event_group
-Steve

My code in javascript.js now:

//FUNKTIONEN ANGEPASST
var types_http = getHTTPObject();
var list_event_group = null;

/**
* updateTypesList
* This function is to be assigned in the onchange handler for the group types select list.
*/

function updateTypesList(list_event_groups_select){
// list_event_group_select is a reference to the list_event_group select list
var selectedGroup = list_event_groups_select.options[list_event_group.selectedIndex].value;
var url = DATAFACE_SITE_HREF +’?-action=get_types&list_event_group=’.escape(selectedGroup);
types_http.open(“GET”, url);
types_http.onreadystatechange = handleUpdateTypesList;
// Assign the handleUpdateTypesList function as a handler to be called when the HTTP object receives a response from the server
list_event_group = list_event_groups_select;
// Save a reference to the group types select list in the http object so that it can be accessed from the handleUpdateTypesList function
types_http.send(null);
}

/**
* handleUpdateTypesList
* This function is called when a response is received from the HTTP object after we request the types for a particular group.
*/
function handleUpdateTypesList(){
if ( types_http.readystate == 4 ){
// We have successfully obtained the response from the server
var options = eval(‘(‘ + types_http.responseText +’)’);
// we now have the options that we will use to fill the 2nd select list as an array
// now let’s get out select list and refill it
var list_event_type = types_http.list_event_group.form.elements[‘l_tid’];
// We obtain a reference to the type_id select list (let’s assume that the field is named type_id.. if not, then change this).
// Clear the existing options in the types list.
for ( var i=0; i list_event_type.options[i] = new Option(options[i][‘type’], options[i][‘l_tid’]);
}
}

}

and error-console of firefox goes:

getHTTPObject() is not defined

list_event_group has no properties

Any idea?

Markus


shannah — Wed May 30, 2007 10:02 am

The getHTTPObject() function is defined in the js/ajax.js file in the dataface installation folder.ÊÊ Most likely it hasn’t been loaded yet in your document.Ê If you change the following:

var types_http = getHTTPObject();

var list_event_group = null;

to

require(DATAFACE_SITE_URL+’/js/ajax.js’);
var types_http = null;
var list_event_group = null;

And then add the following to the updateTypesList() function:

if ( types_http == null ) types_http = getHTTPObject();

That should give the function time to be loaded before it is called.

The second error (list_event_group has no properties) is coming up because you haven’t changed the types_http.list_event_group to just list_event_group in the handler function.

-Steve


Markus — Wed May 30, 2007 10:52 am

The getHTTPObject() function is defined in the js/ajax.js file in the dataface installation folder. Most likely it hasn’t been loaded yet in your document. If you change the following:

var types_http = getHTTPObject();

var list_event_group = null;

to

require(DATAFACE_SITE_URL+’/js/ajax.js’);
var types_http = null;
var list_event_group = null;

And then add the following to the updateTypesList() function:

if ( types_http == null ) types_http = getHTTPObject();

That should give the function time to be loaded before it is called.

The second error (list_event_group has no properties) is coming up because you haven’t changed the types_http.list_event_group to just list_event_group in the handler function.

-Steve

Hi Steve,

I changed the code to:

//FUNKTIONEN ANGEPASST
require(DATAFACE_SITE_URL+’/js/ajax.js’);
var types_http = null;
var list_event_group = null;

/**
* updateTypesList
* This function is to be assigned in the onchange handler for the group types select list.
*/

function updateTypesList(list_event_groups_select){
if ( types_http == null ) types_http = getHTTPObject();
// list_event_group_select is a reference to the list_event_group select list
var selectedGroup = list_event_groups_select.options[list_event_group.selectedIndex].value;
var url = DATAFACE_SITE_HREF +’?-action=get_types&list_event_group=’.escape(selectedGroup);
types_http.open(“GET”, url);
types_http.onreadystatechange = handleUpdateTypesList;
// Assign the handleUpdateTypesList function as a handler to be called when the HTTP object receives a response from the server
list_event_group = list_event_groups_select;
// Save a reference to the group types select list in the http object so that it can be accessed from the handleUpdateTypesList function
types_http.send(null);
}

/**
* handleUpdateTypesList
* This function is called when a response is received from the HTTP object after we request the types for a particular group.
*/
function handleUpdateTypesList(){
if ( types_http.readystate == 4 ){
// We have successfully obtained the response from the server
var options = eval(‘(‘ + types_http.responseText +’)’);
// we now have the options that we will use to fill the 2nd select list as an array
// now let’s get out select list and refill it
var list_event_type = list_event_group.form.elements[‘l_tid’];
// We obtain a reference to the type_id select list (let’s assume that the field is named type_id.. if not, then change this).
// Clear the existing options in the types list.
for ( var i=0; i list_event_type.options[i] = new Option(options[i][‘type’], options[i][‘l_tid’]);
}
}

}

as you said. The first error does not occur any longer. Thank you for your help. But the second one “list_event_group has no properties” is still there.

And I would like to know wether the naming in function updateTypesList, which means(list_event_groups_select) follows special naming conventions in DF? Especially the Plural and the _select. Or am I free to name it somehow. See similar question in my last but second posting.

Thank you

Markus


shannah — Wed May 30, 2007 11:20 am

Hi Markus,

None of the variables here are following any naming conventions.Ê You are free to change them as you like.

A couple of tips.Ê XXX has no properties, generally means that the variable is null or not initialized.Ê Generally this means that we have made a mistake somewhere when we thought we had initialized it.

The list_event_group variable should have been initialized in the updateTypesList function when we set it to list_event_groups_select (which should be a reference to the first select list).

What i usually do in these cases is start inserting alert() functions in various places to see what values my variables have (this is like a poor-man’s debugger).

e.g.Ê In the updateTypesList() function, try calling alert(list_event_groups_select), and see what it says (it will pop up a javascript alert).ÊÊ Try this in various places to see where we are losing it.

-Steve


Markus — Wed May 30, 2007 11:33 am

Thanks again for your tips, Steve. The alert-thing sounds pretty similar to what I know from echo in php. I will try and give you response when I am through with it. Seems that I will have to learn some JavaScript right now

Markus


shannah — Wed May 30, 2007 11:50 am

Thanks for being a pioneer here.Ê I have thought about trying to add this sort of functionality simply using the fields.ini file, but I want to make sure that I do it right in a generic sort of way.. may be a few releases from now.

-Steve


Markus — Fri Jun 01, 2007 5:29 am

Hi steve,

My updateTypesList function again:

require(DATAFACE_SITE_URL+’/js/ajax.js’);
var types_http = null;
var type_group = null;

/**
* updateTypesList
* This function is to be assigned in the onchange handler for the group types select list.
*/

function updateTypesList(type_groups_select){

// type_groups_select is a reference to the type_groups select list
var selectedGroup = type_groups_select.options[type_group.selectedIndex].value;
var url = DATAFACE_SITE_HREF +’?-action=get_types&type_group=’.escape(selectedGroup);
types_http.open(“GET”, url);
types_http.onreadystatechange = handleUpdateTypesList;
// Assign the handleUpdateTypesList function as a handler to be called when the HTTP object receives a response from the server
type_group = type_groups_select;
// Save a reference to the group types select list in the http object so that it can be accessed from the handleUpdateTypesList function
types_http.send(null);
}

I found out that already in the first line:
var selectedGroup = type_groups_select.options[type_group.selectedIndex].value;

my firefox error-console tells me that type_group has no properties. I can do an alert(“” +type_group+ “”) above this line and get null which is defined above and so it works.

If I put the same alert after this line nothing will be returned when changing the select. Even if I put alert(“Hello”) there, nothing happens. It seems to me that this line has a mistake in it but could not figure out where it might be. I suppose, this line should return the Index of my value, right? Cause there are 5 values, it should return either 1,2,3,4 or 5. But it does not.

It also seems that the script stops here because I never get a changed URL when selecting something from my type_groups select. The URL stays like http://pathtomyapp/index.php?-action=new&-table=event
It is somehow frustrating.

Again also the relevant part of my fields.ini of table event:

[L_GID]
widget:label = “Ereignisgruppen ID”
widget:description = “Die Ereignisgruppen ID des Ereignisses”
widget:type = “select”
vocabulary = “list_event_group”
widget:attsnchange=”updateTypesList(this);”

[L_TID]
widget:label = “Ereignistyp ID”
widget:description = “Die Ereignistyp ID des Ereignisses”
widget:type = “select”
vocabulary = “list_event_type”

My valuelists.ini

[list_event_group]
__sql__ = “select l_gid, type_group from list_event_group”

[list_event_type]
__sql__ = “select l_tid, L_GID, type from list_event_type”

My relationships.ini

[list_event_group]
list_event_group.l_gid = “$L_GID”

[list_event_type]
list_event_type.l_tid = “$L_TID”

My get_types.php

Is this all correct so far? Do you have another idea, what could be wrong?

Thank you

Markus


shannah — Fri Jun 01, 2007 3:22 pm

Here is one mistake:

var selectedGroup = type_groups_select.options[type_group.selectedIndex].value;

This should be

var selectedGroup = type_groups_select.options[type_groups_select.selectedIndex].value;


Markus — Sun Jun 03, 2007 8:12 am

Here is one mistake:

var selectedGroup = type_groups_select.options[type_group.selectedIndex].value;

This should be

var selectedGroup = type_groups_select.options[type_groups_select.selectedIndex].value;

Hi steve,

thank you again. Let me resume what I have done so far by posting the code of updateTypesList again. I put some comments into the code to show, what is happening.

require(DATAFACE_SITE_URL+’/js/ajax.js’);
var types_http = null;
var type_group = null;

/**
* updateTypesList
* This function is to be assigned in the onchange handler for the group types select list.
*/

function updateTypesList(type_groups_select){
// type_groups_select is a reference to the type_groups select list

var selectedGroup = type_groups_select.options[type_groups_select.selectedIndex].value;

alert (“” +selectedGroup+ “”); // works fine, shows me the right ID of the selected value; for example 2

var url = DATAFACE_SITE_HREF +’?-action=get_types&type_group=’+selectedGroup;

alert (“” +url+ “”); // shows me the url which is: /dataface/plone_javascript_variables.js.php?-action=get_types&type_group=2 ;

alert (“” +types_http+ “”); // shows me null

types_http.open(“GET” url); // does not work until now

types_http.onreadystatechange = handleUpdateTypesList;
// Assign the handleUpdateTypesList function as a handler to be called when the HTTP object receives a response from the server
type_group = type_groups_select;
// Save a reference to the group types select list in the http object so that it can be accessed from the handleUpdateTypesList function
types_http.send(null);
}

After I have closed all the alerts I get an error in firefox error-console: types_http has no properties

I wonder why the DATAFACE_SITE_HREF gives back /dataface/plone_javascript_variables.js.php and if this could be right?

There is no /dataface directory within my app because I have all the dataface files one step up the hierarchy on the server like:

server_root/dataface
server_root/pathtomyapp

Should I better have my application directory within the dataface directory?

So I would like to ask if this URL is right and why the types_http has no properties. I think I am not so far from a solution of my problem now but I am not enough into DF to do it on my own.

Possibly you are not working on sundays which I don’t do normally too. But I really want to find the solution and understand what is happening in my DF-application. Maybe you can help me a little more. Could be tomorrow of course

greets

Markus


shannah — Sun Jun 03, 2007 5:20 pm

Hi Markus,

This readout makes sense.Ê First some responses to specific questions:
Q: “I wonder why the DATAFACE_SITE_HREF gives back /dataface/plone_javascript_variables.js.php and if this could be right?”
A: Ahh.. Yes.. This looks like a little bug in Dataface.Ê I have updated my current source base to fix this bug.Ê You can fix it in your version by opening the file: Dataface/templates/Dataface_Main_Template.html.Ê At around Line 51, there some HTML like:

Add a couple of lines so that it becomes:

This should produce the correct url.
Q: “Should I better have my application directory within the dataface directory?”
A: No.. My preference is to do it the way you are currently doing it:Ê with separate directories for dataface and your application.

The reason for the error: “types_http has no properties” is because you have removed the code that was there before to set the types_http variable to an HTTP object:
if ( types_http == null ) types_http = getHTTPObject();

I also notice a typo from the code that I made to include the ajax.js file.Ê It is currently :
require(DATAFACE_SITE_URL+’/js/ajax.js’);

It should be
require(DATAFACE_URL+’/js/ajax.js’);

Best regards
Steve


Markus — Mon Jun 04, 2007 4:08 am

Dear steve,

thank you again for your explanations and changes. I made all the changes to Dataface_Main_Template.html and in my javascript.js I have now:

require(DATAFACE_URL+’/js/ajax.js’);

var types_http = null;
var type_group = null;

/**
* updateTypesList
* This function is to be assigned in the onchange handler for the group types select list.
*/

function updateTypesList(type_groups_select){
// type_groups_select is a reference to the type_groups select list

if ( types_http == null ) types_http = getHTTPObject();

var selectedGroup = type_groups_select.options[type_groups_select.selectedIndex].value;

alert (“” +selectedGroup+ “”); //shows the Index of selectedGroup, for example 2

var url = DATAFACE_SITE_HREF +’?-action=get_types&type_group=’+selectedGroup;

alert (“” +url+ “”); // shows the url, which is: /dataface/plone_javascript_variables.js.php?-action=get_types&type_group=2 ;

alert (“” +types_http+ “”); // firefox shows [object XMLHttpRequest] ie shows [object]

types_http.open(“GET”, url);

types_http.onreadystatechange = handleUpdateTypesList;
// Assign the handleUpdateTypesList function as a handler to be called when the HTTP object receives a response from the server

type_group = type_groups_select;
// Save a reference to the group types select list in the http object so that it can be accessed from the handleUpdateTypesList function

types_http.send(null);
}

/**
* handleUpdateTypesList
* This function is called when a response is received from the HTTP object after we request the types for a particular group.
*/
function handleUpdateTypesList(){
if ( types_http.readystate == 4 ){
// We have successfully obtained the response from the server
if ( types_http == null ) types_http = getHTTPObject();
var options = eval(‘(‘ + types_http.responseText +’)’);
// we now have the options that we will use to fill the 2nd select list as an array
// now let’s get out select list and refill it
var types_list = type_group.form.elements[‘type_group’];
// We obtain a reference to the type_id select list (let’s assume that the field is named type_id.. if not, then change this).
// Clear the existing options in the types list.
for ( var i=0; i types_list.options[i] = new Option(options[i][‘type’], options[i][‘l_tid’]);
}
}

}

See my comments in updateTypesList function above. I don’t get any errors from firefox now but still the url does not change and the second select remains empty (please select…)

My current get_types.php is like follows (I leave the php-questionmarks)

class actions_get_types {
function handle(&$params){
if ( isset($_REQUEST[‘type_group’]) ){
$sql = “select l_tid, L_GID, type from list_event_type where L_GID=’“.addslashes($_REQUEST[‘type_group’]).”’”;
} else {
$sql = “select l_tid, L_GID, type from list_event_type”;
}
$res = mysql_query($sql, df_db());
if ( !$res ) trigger_error(mysql_error(df_db()), E_USER_ERROR);
header(‘Content-type: text/javascript’);
echo ‘[’;
$values = array();
while ( $row = mysql_fetch_assoc($res) ){
$values[] = “{l_tid:’”.$row[‘l_tid’].”’, type: ‘“.addslashes($row[‘type’]).”’}”;
}
echo implode(‘,’,$values);
echo ‘]’;
exit;
}

}

Obviously there must be something wrong with the following line in updateTypesList:

types_http.open(“GET”, url);

because it is not executed, right? I am not sure about what I can put here as an alert to check what’s happening. Maybe you know?
Please have a close look at my get_types.php if this is right. Especially I am not sure about these lines:

if ( isset($_REQUEST[‘type_group’]) ){
$sql = “select l_tid, L_GID, type from list_event_type where L_GID=’“.addslashes($_REQUEST[‘type_group’]).”’”;

and

while ( $row = mysql_fetch_assoc($res) ){
$values[] = “{l_tid:’”.$row[‘l_tid’].”’, type: ‘“.addslashes($row[‘type’]).”’}”;

Can you give me some hints again?

Markus


shannah — Mon Jun 04, 2007 8:07 am

OK.. next phase of problem solving: getting AJAX to work.ÊÊ Check a couple of things:

  1. Put some alerts in the handleUpdateTypesList function to at least see if it ever gets called.

  2. If handleUpdateTypesList is getting called, then you want to take a look at the response text.Ê (e.g. alert(types_http.responseText).

  3. If handleUpdateTypesList is NOT getting called, then you’ll want to take a look at the url that is being sent to types_http.open().Ê Copy and paste this URL directly into your web browser and see what it gives you…Ê this url should result in the output of your custom action.

Best regards

Steve


Markus — Mon Jun 04, 2007 9:07 am

OK.. next phase of problem solving: getting AJAX to work. Check a couple of things:

  1. Put some alerts in the handleUpdateTypesList function to at least see if it ever gets called.

  2. If handleUpdateTypesList is getting called, then you want to take a look at the response text. (e.g. alert(types_http.responseText).

  3. If handleUpdateTypesList is NOT getting called, then you’ll want to take a look at the url that is being sent to types_http.open(). Copy and paste this URL directly into your web browser and see what it gives you… this url should result in the output of your custom action.

Best regards

Steve

Hi steve,

I tried the alerts in handleUpdateTypesList function and they won’t run.

I gave the url /dataface/plone_javascript_variables.js.php?-action=get_types&type_group=2 directly into the browser and it calls the plone_javascript_variables.js.php

The output is

// Global Plone variables that need to be accessible to the Javascripts

//portal_url = ‘http://localhost/~shannah/lesson_plans’;
portal_url = ‘/dataface’;
DATAFACE_URL = portal_url;
DATAFACE_SITE_URL = ‘/dataface’;
DATAFACE_SITE_HREF = ‘/dataface/plone_javascript_variables.js.php’;

How can I get to my custom action?

Markus


Markus — Sun Jun 03, 2007 8:12 am

Here is one mistake:

var selectedGroup = type_groups_select.options[type_group.selectedIndex].value;

This should be

var selectedGroup = type_groups_select.options[type_groups_select.selectedIndex].value;

Hi steve,

thank you again. Let me resume what I have done so far by posting the code of updateTypesList again. I put some comments into the code to show, what is happening.

require(DATAFACE_SITE_URL+’/js/ajax.js’);
var types_http = null;
var type_group = null;

/**
* updateTypesList
* This function is to be assigned in the onchange handler for the group types select list.
*/

function updateTypesList(type_groups_select){
// type_groups_select is a reference to the type_groups select list

var selectedGroup = type_groups_select.options[type_groups_select.selectedIndex].value;

alert (“” +selectedGroup+ “”); // works fine, shows me the right ID of the selected value; for example 2

var url = DATAFACE_SITE_HREF +’?-action=get_types&type_group=’+selectedGroup;

alert (“” +url+ “”); // shows me the url which is: /dataface/plone_javascript_variables.js.php?-action=get_types&type_group=2 ;

alert (“” +types_http+ “”); // shows me null

types_http.open(“GET” url); // does not work until now

types_http.onreadystatechange = handleUpdateTypesList;
// Assign the handleUpdateTypesList function as a handler to be called when the HTTP object receives a response from the server
type_group = type_groups_select;
// Save a reference to the group types select list in the http object so that it can be accessed from the handleUpdateTypesList function
types_http.send(null);
}

After I have closed all the alerts I get an error in firefox error-console: types_http has no properties

I wonder why the DATAFACE_SITE_HREF gives back /dataface/plone_javascript_variables.js.php and if this could be right?

There is no /dataface directory within my app because I have all the dataface files one step up the hierarchy on the server like:

server_root/dataface
server_root/pathtomyapp

Should I better have my application directory within the dataface directory?

So I would like to ask if this URL is right and why the types_http has no properties. I think I am not so far from a solution of my problem now but I am not enough into DF to do it on my own.

Possibly you are not working on sundays which I don’t do normally too. But I really want to find the solution and understand what is happening in my DF-application. Maybe you can help me a little more. Could be tomorrow of course

greets

Markus


shannah — Sun Jun 03, 2007 5:20 pm

Hi Markus,

This readout makes sense.Ê First some responses to specific questions:
Q: “I wonder why the DATAFACE_SITE_HREF gives back /dataface/plone_javascript_variables.js.php and if this could be right?”
A: Ahh.. Yes.. This looks like a little bug in Dataface.Ê I have updated my current source base to fix this bug.Ê You can fix it in your version by opening the file: Dataface/templates/Dataface_Main_Template.html.Ê At around Line 51, there some HTML like:

Add a couple of lines so that it becomes:

This should produce the correct url.
Q: “Should I better have my application directory within the dataface directory?”
A: No.. My preference is to do it the way you are currently doing it:Ê with separate directories for dataface and your application.

The reason for the error: “types_http has no properties” is because you have removed the code that was there before to set the types_http variable to an HTTP object:
if ( types_http == null ) types_http = getHTTPObject();

I also notice a typo from the code that I made to include the ajax.js file.Ê It is currently :
require(DATAFACE_SITE_URL+’/js/ajax.js’);

It should be
require(DATAFACE_URL+’/js/ajax.js’);

Best regards
Steve


Markus — Mon Jun 04, 2007 4:08 am

Dear steve,

thank you again for your explanations and changes. I made all the changes to Dataface_Main_Template.html and in my javascript.js I have now:

require(DATAFACE_URL+’/js/ajax.js’);

var types_http = null;
var type_group = null;

/**
* updateTypesList
* This function is to be assigned in the onchange handler for the group types select list.
*/

function updateTypesList(type_groups_select){
// type_groups_select is a reference to the type_groups select list

if ( types_http == null ) types_http = getHTTPObject();

var selectedGroup = type_groups_select.options[type_groups_select.selectedIndex].value;

alert (“” +selectedGroup+ “”); //shows the Index of selectedGroup, for example 2

var url = DATAFACE_SITE_HREF +’?-action=get_types&type_group=’+selectedGroup;

alert (“” +url+ “”); // shows the url, which is: /dataface/plone_javascript_variables.js.php?-action=get_types&type_group=2 ;

alert (“” +types_http+ “”); // firefox shows [object XMLHttpRequest] ie shows [object]

types_http.open(“GET”, url);

types_http.onreadystatechange = handleUpdateTypesList;
// Assign the handleUpdateTypesList function as a handler to be called when the HTTP object receives a response from the server

type_group = type_groups_select;
// Save a reference to the group types select list in the http object so that it can be accessed from the handleUpdateTypesList function

types_http.send(null);
}

/**
* handleUpdateTypesList
* This function is called when a response is received from the HTTP object after we request the types for a particular group.
*/
function handleUpdateTypesList(){
if ( types_http.readystate == 4 ){
// We have successfully obtained the response from the server
if ( types_http == null ) types_http = getHTTPObject();
var options = eval(‘(‘ + types_http.responseText +’)’);
// we now have the options that we will use to fill the 2nd select list as an array
// now let’s get out select list and refill it
var types_list = type_group.form.elements[‘type_group’];
// We obtain a reference to the type_id select list (let’s assume that the field is named type_id.. if not, then change this).
// Clear the existing options in the types list.
for ( var i=0; i types_list.options[i] = new Option(options[i][‘type’], options[i][‘l_tid’]);
}
}

}

See my comments in updateTypesList function above. I don’t get any errors from firefox now but still the url does not change and the second select remains empty (please select…)

My current get_types.php is like follows (I leave the php-questionmarks)

class actions_get_types {
function handle(&$params){
if ( isset($_REQUEST[‘type_group’]) ){
$sql = “select l_tid, L_GID, type from list_event_type where L_GID=’“.addslashes($_REQUEST[‘type_group’]).”’”;
} else {
$sql = “select l_tid, L_GID, type from list_event_type”;
}
$res = mysql_query($sql, df_db());
if ( !$res ) trigger_error(mysql_error(df_db()), E_USER_ERROR);
header(‘Content-type: text/javascript’);
echo ‘[’;
$values = array();
while ( $row = mysql_fetch_assoc($res) ){
$values[] = “{l_tid:’”.$row[‘l_tid’].”’, type: ‘“.addslashes($row[‘type’]).”’}”;
}
echo implode(‘,’,$values);
echo ‘]’;
exit;
}

}

Obviously there must be something wrong with the following line in updateTypesList:

types_http.open(“GET”, url);

because it is not executed, right? I am not sure about what I can put here as an alert to check what’s happening. Maybe you know?
Please have a close look at my get_types.php if this is right. Especially I am not sure about these lines:

if ( isset($_REQUEST[‘type_group’]) ){
$sql = “select l_tid, L_GID, type from list_event_type where L_GID=’“.addslashes($_REQUEST[‘type_group’]).”’”;

and

while ( $row = mysql_fetch_assoc($res) ){
$values[] = “{l_tid:’”.$row[‘l_tid’].”’, type: ‘“.addslashes($row[‘type’]).”’}”;

Can you give me some hints again?

Markus


shannah — Mon Jun 04, 2007 8:07 am

OK.. next phase of problem solving: getting AJAX to work.ÊÊ Check a couple of things:

  1. Put some alerts in the handleUpdateTypesList function to at least see if it ever gets called.

  2. If handleUpdateTypesList is getting called, then you want to take a look at the response text.Ê (e.g. alert(types_http.responseText).

  3. If handleUpdateTypesList is NOT getting called, then you’ll want to take a look at the url that is being sent to types_http.open().Ê Copy and paste this URL directly into your web browser and see what it gives you…Ê this url should result in the output of your custom action.

Best regards

Steve


Markus — Mon Jun 04, 2007 9:07 am

OK.. next phase of problem solving: getting AJAX to work. Check a couple of things:

  1. Put some alerts in the handleUpdateTypesList function to at least see if it ever gets called.

  2. If handleUpdateTypesList is getting called, then you want to take a look at the response text. (e.g. alert(types_http.responseText).

  3. If handleUpdateTypesList is NOT getting called, then you’ll want to take a look at the url that is being sent to types_http.open(). Copy and paste this URL directly into your web browser and see what it gives you… this url should result in the output of your custom action.

Best regards

Steve

Hi steve,

I tried the alerts in handleUpdateTypesList function and they won’t run.

I gave the url /dataface/plone_javascript_variables.js.php?-action=get_types&type_group=2 directly into the browser and it calls the plone_javascript_variables.js.php

The output is

// Global Plone variables that need to be accessible to the Javascripts

//portal_url = ‘http://localhost/~shannah/lesson_plans’;
portal_url = ‘/dataface’;
DATAFACE_URL = portal_url;
DATAFACE_SITE_URL = ‘/dataface’;
DATAFACE_SITE_HREF = ‘/dataface/plone_javascript_variables.js.php’;

How can I get to my custom action?

Markus


shannah — Mon Jun 04, 2007 9:21 am

Ok.. for some reason it’s not picking up the new values for DATAFACE_SITE_HREF that you put into the dataface template…. for the sake of getting this working, just hard code the url for now.

i.e. swap DATAFACE_SITE_HREF with just ‘index.php’

Your custom action should be accessed by index.php?-action=get_types&type_group=%selectedGroup%Ê (where %selectedGroup% is the id of the group whose options you want to get.

-Steve


Markus — Mon Jun 04, 2007 10:25 am

Ok.. for some reason it’s not picking up the new values for DATAFACE_SITE_HREF that you put into the dataface template…. for the sake of getting this working, just hard code the url for now.

i.e. swap DATAFACE_SITE_HREF with just ‘index.php’

Your custom action should be accessed by index.php?-action=get_types&type_group=%selectedGroup% (where %selectedGroup% is the id of the group whose options you want to get.

-Steve

It is quite persistent. Now it gives me index is not defined

Any idea?

Markus


shannah — Mon Jun 04, 2007 10:57 am

Hi Markus,

Without a line number/source code it is difficult or impossibleÊ for me to speculate as to the source of this error.


Markus — Mon Jun 04, 2007 1:50 pm

Hi Markus,

Without a line number/source code it is difficult or impossible for me to speculate as to the source of this error.

Hi Steve,

sorry, i just changed the line you said. I marked it OLD and NEW inside the comment of code. Now my javascript.js is:

require(DATAFACE_URL+’/js/ajax.js’);

var types_http = null;
var type_group = null;

/**
* updateTypesList
* This function is to be assigned in the onchange handler for the group types select list.
*/

function updateTypesList(type_groups_select){
// type_groups_select is a reference to the type_groups select list

if ( types_http == null ) types_http = getHTTPObject();

var selectedGroup = type_groups_select.options[type_groups_select.selectedIndex].value;

alert (“” +selectedGroup+ “”); //shows the Index of selectedGroup, for example 2

//var url = DATAFACE_SITE_HREF +’?-action=get_types&type_group=’+selectedGroup; // OLD
var url = index.php +’?-action=get_types&type_group=’+selectedGroup; // NEW

alert (“” +url+ “”); // shows the url, which is: /dataface/plone_javascript_variables.js.php?-action=get_types&type_group=2 ;

alert (“” +types_http+ “”); // shows [objekt XMLHttpRequest]

types_http.open(“GET”, url);

types_http.onreadystatechange = handleUpdateTypesList;
// Assign the handleUpdateTypesList function as a handler to be called when the HTTP object receives a response from the server
type_group = type_groups_select;
// Save a reference to the group types select list in the http object so that it can be accessed from the handleUpdateTypesList function
types_http.send(null);
}

/**
* handleUpdateTypesList
* This function is called when a response is received from the HTTP object after we request the types for a particular group.
*/
function handleUpdateTypesList(){
if ( types_http.readystate == 4 ){
alert (“Hello”);
// We have successfully obtained the response from the server
if ( types_http == null ) types_http = getHTTPObject();

alert (“” +types_http.responseText+ “”);

var options = eval(‘(‘ + types_http.responseText +’)’);

// we now have the options that we will use to fill the 2nd select list as an array
// now let’s get out select list and refill it
var types_list = type_group.form.elements[‘type_group’];
// We obtain a reference to the type_id select list (let’s assume that the field is named type_id.. if not, then change this).
// Clear the existing options in the types list.
for ( var i=0; i types_list.options[i] = new Option(options[i][‘type’], options[i][‘l_tid’]);
}
}

}

I get an error “index is not defined” in my firefox error-console. Do I have a syntax-error somewhere?

Thanks

Markus


shannah — Mon Jun 04, 2007 1:55 pm

Yes.Ê index.php is a string so it has to be inside quotes.Ê Right now javascript is treating it like a variable.

i.e. It thinks that you are referring to variable named ‘index’ which is an object that has a member variable ‘php’… so it is complaining that the ‘index’ variable has no index ‘php’.

If that makes sense.
Best regards
Steve


Markus — Mon Jun 04, 2007 3:40 pm

Yes. index.php is a string so it has to be inside quotes. Right now javascript is treating it like a variable.

i.e. It thinks that you are referring to variable named ‘index’ which is an object that has a member variable ‘php’… so it is complaining that the ‘index’ variable has no index ‘php’.

If that makes sense.
Best regards
Steve

OK. I changed it again and now it is:

require(DATAFACE_URL+’/js/ajax.js’);

var types_http = null;
var type_group = null;

/**
* updateTypesList
* This function is to be assigned in the onchange handler for the group types select list.
*/

function updateTypesList(type_groups_select){
// type_groups_select is a reference to the type_groups select list

if ( types_http == null ) types_http = getHTTPObject();

var selectedGroup = type_groups_select.options[type_groups_select.selectedIndex].value;

alert (“” +selectedGroup+ “”); //shows the Index of selectedGroup, for example 2

//var url = DATAFACE_SITE_HREF +’?-action=get_types&type_group=’+selectedGroup;
var url = ‘index.php?-action=get_types&type_group=’+selectedGroup;

alert (“” +url+ “”); // shows the url, which is now: index.php?-action=get_types&type_group=2

alert (“” +types_http+ “”); // shows [objekt XMLHttpRequest]

types_http.open(“GET”, url);

types_http.onreadystatechange = handleUpdateTypesList;
// Assign the handleUpdateTypesList function as a handler to be called when the HTTP object receives a response from the server
type_group = type_groups_select;
// Save a reference to the group types select list in the http object so that it can be accessed from the handleUpdateTypesList function
types_http.send(null);
}

/**
* handleUpdateTypesList
* This function is called when a response is received from the HTTP object after we request the types for a particular group.
*/
function handleUpdateTypesList(){
if ( types_http.readystate == 4 ){
alert (“Hello”);
// We have successfully obtained the response from the server
if ( types_http == null ) types_http = getHTTPObject();

alert (“” +types_http.responseText+ “”);

var options = eval(‘(‘ + types_http.responseText +’)’);

// we now have the options that we will use to fill the 2nd select list as an array
// now let’s get out select list and refill it
var types_list = type_group.form.elements[‘type_group’];
// We obtain a reference to the type_id select list (let’s assume that the field is named type_id.. if not, then change this).
// Clear the existing options in the types list.
for ( var i=0; i types_list.options[i] = new Option(options[i][‘type’], options[i][‘l_tid’]);
}
}

}

The line
alert (“” +url+ “”); // shows the url, which is now: index.php?-action=get_types&type_group=2
is correct now, I think.

No errors in firefox but no results either. Second select remains (Please select…) No alerts of function handleUpdateTypesList show up.

I am too tired now to think about it. I will try and test again tomorrow.

Markus


Markus — Tue Jun 05, 2007 6:47 am

Hi steve,

In my javascript.js I now have:

require(DATAFACE_URL+’/js/ajax.js’);

var types_http = null;
var type_group = null;

/**
* updateTypesList
* This function is to be assigned in the onchange handler for the group types select list.
*/

function updateTypesList(type_groups_select){
// type_groups_select is a reference to the type_groups select list

if ( types_http == null ) types_http = getHTTPObject();

var selectedGroup = type_groups_select.options[type_groups_select.selectedIndex].value;

alert (“” +selectedGroup+ “”); //shows the Index of selectedGroup, for example 2

var url = ‘index.php?-action=get_types&type_group=’+selectedGroup;

alert (“” +url+ “”); // shows the url, which is now: index.php?-action=get_types&type_group=2

alert (“” +types_http+ “”); // shows [objekt XMLHttpRequest]

types_http.open(“GET”, url); // SEEMS NOT TO WORK

types_http.onreadystatechange = handleUpdateTypesList;
// Assign the handleUpdateTypesList function as a handler to be called when the HTTP object receives a response from the server
type_group = type_groups_select;
// Save a reference to the group types select list in the http object so that it can be accessed from the handleUpdateTypesList function
types_http.send(null);
}

/**
* handleUpdateTypesList
* This function is called when a response is received from the HTTP object after we request the types for a particular group.
*/
function handleUpdateTypesList(){
if ( types_http.readystate == 4 ){
alert (“Hello”);
// We have successfully obtained the response from the server
if ( types_http == null ) types_http = getHTTPObject();

alert (“” +types_http.responseText+ “”);

var options = eval(‘(‘ + types_http.responseText +’)’);

// we now have the options that we will use to fill the 2nd select list as an array
// now let’s get out select list and refill it
var types_list = type_group.form.elements[‘type_group’];
// We obtain a reference to the type_id select list (let’s assume that the field is named type_id.. if not, then change this).
// Clear the existing options in the types list.
for ( var i=0; i
types_list.options[i] = new Option(options[i][‘type’], options[i][‘l_tid’]);
}
}

}

When I copy the url index.php?-action=get_types&type_group=2 directly into the browser I get an array back which is like

[{l_tid:’7’, type: ‘UmrŸstkonzept’},{l_tid:’8’, type: ‘Sonderkomponenten’},{l_tid:’9’, type: ‘Bedienungskomfort’},{l_tid:’10’, type: ‘Anpassungen und Verbesserungen’}]

These are the values I want to have in my second select when preselected type_group 2 in first select. This means, my get_types.php should be ok. right?

Only the url does not change when doing the select in the form. Second select remains (Please select..) and no action is called.

We could not be so far from the solution now. What is still wrong here?

Markus


shannah — Tue Jun 05, 2007 9:52 am

A couple of things we can add for completeness.Ê

  1. Add the third parameter to the open() method to explicitly state that we are doing an asynchronous call.

e.g.

types_http.open(“GET”, url, true);

  1. Add more alert statements in the handleUpdate…() function .. even before the first ‘if’ statement, so you will know for sure if the handler is being called.

  2. Change the way the the handleUpdateTypesList() function is defined, so it is explicitly assigned to a variable.

e.g. instead of

function handleUpdateTypesList(){

we have

var handleUpdateTypesList = function(){

Javascript can be pesky…


Markus — Tue Jun 05, 2007 10:35 am

A couple of things we can add for completeness.

  1. Add the third parameter to the open() method to explicitly state that we are doing an asynchronous call.

e.g.

types_http.open(“GET”, url, true);

  1. Add more alert statements in the handleUpdate…() function .. even before the first ‘if’ statement, so you will know for sure if the handler is being called.

  2. Change the way the the handleUpdateTypesList() function is defined, so it is explicitly assigned to a variable.

e.g. instead of

function handleUpdateTypesList(){

we have

var handleUpdateTypesList = function(){

Javascript can be pesky…

Thank you again, Steve.

I now have changed the code like this:

//ORIGINAL-FUNKTIONEN
require(DATAFACE_URL+’/js/ajax.js’);

var types_http = null;
var type_group = null;

/**
* updateTypesList
* This function is to be assigned in the onchange handler for the group types select list.
*/

function updateTypesList(type_groups_select){
// type_groups_select is a reference to the type_groups select list

if ( types_http == null ) types_http = getHTTPObject();

var selectedGroup = type_groups_select.options[type_groups_select.selectedIndex].value;

alert (“” +selectedGroup+ “”); //shows the Index of selectedGroup, for example 2

//var url = DATAFACE_SITE_HREF +’?-action=get_types&type_group=’+selectedGroup;
var url = ‘index.php?-action=get_types&type_group=’+selectedGroup;

alert (“” +url+ “”); // shows the url, which is now: index.php?-action=get_types&type_group=2 ;

alert (“” +types_http+ “”); // shows [objekt XMLHttpRequest]

types_http.open(“GET”, url, true);

types_http.onreadystatechange = handleUpdateTypesList;
// Assign the handleUpdateTypesList function as a handler to be called when the HTTP object receives a response from the server
type_group = type_groups_select;
// Save a reference to the group types select list in the http object so that it can be accessed from the handleUpdateTypesList function
types_http.send(null);
}

/**
* handleUpdateTypesList
* This function is called when a response is received from the HTTP object after we request the types for a particular group.
*/
//function handleUpdateTypesList(){
var handleUpdateTypesList = function(){
alert (“Hello 1”);
if ( types_http.readystate == 4 ){
alert (“Hello 2”);
// We have successfully obtained the response from the server
if ( types_http == null ) types_http = getHTTPObject();

alert (“” +types_http.responseText+ “”);

var options = eval(‘(‘ + types_http.responseText +’)’);

// we now have the options that we will use to fill the 2nd select list as an array
// now let’s get out select list and refill it
var types_list = type_group.form.elements[‘type_group’];
// We obtain a reference to the type_id select list (let’s assume that the field is named type_id.. if not, then change this).
// Clear the existing options in the types list.
for ( var i=0; i types_list.options[i] = new Option(options[i][‘type’], options[i][‘l_tid’]);
}
}

}

Now we have to deal with the handleUpdateTypesList - Thing i suppose. It is kind of funny what happens but there is always a reason why, right?

When I choose some value in the first select all my alerts show up until the first alert (“Hello 1”); in handleUpdateTypesList.

This one shows up 4 times and then nothing more happens. No alert (“Hello 2”); or alert (“” +types_http.responseText+ “”); ever shows up.

Second selelect remains empty (Please select…). Does that mean that the if ( types_http.readystate == 4 ){ condition returns false?
We do not obtain a server response. What to try next?

Best regards

Markus


shannah — Tue Jun 05, 2007 10:41 am

I really hate to swear… but… SHIT!

I’m sorry I put you through this.. the problem is

if ( types_http.readystate == 4 ){

should be

if ( types_http.readyState == 4 ){

(Note the capital ‘S’).

That should fix the issue – or at least get us to the next step of debugging.

Reference: http://www.w3schools.com/xml/xml_http.asp

-Steve


Markus — Mon Jun 04, 2007 3:40 pm

Yes. index.php is a string so it has to be inside quotes. Right now javascript is treating it like a variable.

i.e. It thinks that you are referring to variable named ‘index’ which is an object that has a member variable ‘php’… so it is complaining that the ‘index’ variable has no index ‘php’.

If that makes sense.
Best regards
Steve

OK. I changed it again and now it is:

require(DATAFACE_URL+’/js/ajax.js’);

var types_http = null;
var type_group = null;

/**
* updateTypesList
* This function is to be assigned in the onchange handler for the group types select list.
*/

function updateTypesList(type_groups_select){
// type_groups_select is a reference to the type_groups select list

if ( types_http == null ) types_http = getHTTPObject();

var selectedGroup = type_groups_select.options[type_groups_select.selectedIndex].value;

alert (“” +selectedGroup+ “”); //shows the Index of selectedGroup, for example 2

//var url = DATAFACE_SITE_HREF +’?-action=get_types&type_group=’+selectedGroup;
var url = ‘index.php?-action=get_types&type_group=’+selectedGroup;

alert (“” +url+ “”); // shows the url, which is now: index.php?-action=get_types&type_group=2

alert (“” +types_http+ “”); // shows [objekt XMLHttpRequest]

types_http.open(“GET”, url);

types_http.onreadystatechange = handleUpdateTypesList;
// Assign the handleUpdateTypesList function as a handler to be called when the HTTP object receives a response from the server
type_group = type_groups_select;
// Save a reference to the group types select list in the http object so that it can be accessed from the handleUpdateTypesList function
types_http.send(null);
}

/**
* handleUpdateTypesList
* This function is called when a response is received from the HTTP object after we request the types for a particular group.
*/
function handleUpdateTypesList(){
if ( types_http.readystate == 4 ){
alert (“Hello”);
// We have successfully obtained the response from the server
if ( types_http == null ) types_http = getHTTPObject();

alert (“” +types_http.responseText+ “”);

var options = eval(‘(‘ + types_http.responseText +’)’);

// we now have the options that we will use to fill the 2nd select list as an array
// now let’s get out select list and refill it
var types_list = type_group.form.elements[‘type_group’];
// We obtain a reference to the type_id select list (let’s assume that the field is named type_id.. if not, then change this).
// Clear the existing options in the types list.
for ( var i=0; i types_list.options[i] = new Option(options[i][‘type’], options[i][‘l_tid’]);
}
}

}

The line
alert (“” +url+ “”); // shows the url, which is now: index.php?-action=get_types&type_group=2
is correct now, I think.

No errors in firefox but no results either. Second select remains (Please select…) No alerts of function handleUpdateTypesList show up.

I am too tired now to think about it. I will try and test again tomorrow.

Markus


Markus — Tue Jun 05, 2007 6:47 am

Hi steve,

In my javascript.js I now have:

require(DATAFACE_URL+’/js/ajax.js’);

var types_http = null;
var type_group = null;

/**
* updateTypesList
* This function is to be assigned in the onchange handler for the group types select list.
*/

function updateTypesList(type_groups_select){
// type_groups_select is a reference to the type_groups select list

if ( types_http == null ) types_http = getHTTPObject();

var selectedGroup = type_groups_select.options[type_groups_select.selectedIndex].value;

alert (“” +selectedGroup+ “”); //shows the Index of selectedGroup, for example 2

var url = ‘index.php?-action=get_types&type_group=’+selectedGroup;

alert (“” +url+ “”); // shows the url, which is now: index.php?-action=get_types&type_group=2

alert (“” +types_http+ “”); // shows [objekt XMLHttpRequest]

types_http.open(“GET”, url); // SEEMS NOT TO WORK

types_http.onreadystatechange = handleUpdateTypesList;
// Assign the handleUpdateTypesList function as a handler to be called when the HTTP object receives a response from the server
type_group = type_groups_select;
// Save a reference to the group types select list in the http object so that it can be accessed from the handleUpdateTypesList function
types_http.send(null);
}

/**
* handleUpdateTypesList
* This function is called when a response is received from the HTTP object after we request the types for a particular group.
*/
function handleUpdateTypesList(){
if ( types_http.readystate == 4 ){
alert (“Hello”);
// We have successfully obtained the response from the server
if ( types_http == null ) types_http = getHTTPObject();

alert (“” +types_http.responseText+ “”);

var options = eval(‘(‘ + types_http.responseText +’)’);

// we now have the options that we will use to fill the 2nd select list as an array
// now let’s get out select list and refill it
var types_list = type_group.form.elements[‘type_group’];
// We obtain a reference to the type_id select list (let’s assume that the field is named type_id.. if not, then change this).
// Clear the existing options in the types list.
for ( var i=0; i
types_list.options[i] = new Option(options[i][‘type’], options[i][‘l_tid’]);
}
}

}

When I copy the url index.php?-action=get_types&type_group=2 directly into the browser I get an array back which is like

[{l_tid:’7’, type: ‘UmrŸstkonzept’},{l_tid:’8’, type: ‘Sonderkomponenten’},{l_tid:’9’, type: ‘Bedienungskomfort’},{l_tid:’10’, type: ‘Anpassungen und Verbesserungen’}]

These are the values I want to have in my second select when preselected type_group 2 in first select. This means, my get_types.php should be ok. right?

Only the url does not change when doing the select in the form. Second select remains (Please select..) and no action is called.

We could not be so far from the solution now. What is still wrong here?

Markus


shannah — Tue Jun 05, 2007 9:52 am

A couple of things we can add for completeness.Ê

  1. Add the third parameter to the open() method to explicitly state that we are doing an asynchronous call.

e.g.

types_http.open(“GET”, url, true);

  1. Add more alert statements in the handleUpdate…() function .. even before the first ‘if’ statement, so you will know for sure if the handler is being called.

  2. Change the way the the handleUpdateTypesList() function is defined, so it is explicitly assigned to a variable.

e.g. instead of

function handleUpdateTypesList(){

we have

var handleUpdateTypesList = function(){

Javascript can be pesky…


Markus — Tue Jun 05, 2007 10:35 am

A couple of things we can add for completeness.

  1. Add the third parameter to the open() method to explicitly state that we are doing an asynchronous call.

e.g.

types_http.open(“GET”, url, true);

  1. Add more alert statements in the handleUpdate…() function .. even before the first ‘if’ statement, so you will know for sure if the handler is being called.

  2. Change the way the the handleUpdateTypesList() function is defined, so it is explicitly assigned to a variable.

e.g. instead of

function handleUpdateTypesList(){

we have

var handleUpdateTypesList = function(){

Javascript can be pesky…

Thank you again, Steve.

I now have changed the code like this:

//ORIGINAL-FUNKTIONEN
require(DATAFACE_URL+’/js/ajax.js’);

var types_http = null;
var type_group = null;

/**
* updateTypesList
* This function is to be assigned in the onchange handler for the group types select list.
*/

function updateTypesList(type_groups_select){
// type_groups_select is a reference to the type_groups select list

if ( types_http == null ) types_http = getHTTPObject();

var selectedGroup = type_groups_select.options[type_groups_select.selectedIndex].value;

alert (“” +selectedGroup+ “”); //shows the Index of selectedGroup, for example 2

//var url = DATAFACE_SITE_HREF +’?-action=get_types&type_group=’+selectedGroup;
var url = ‘index.php?-action=get_types&type_group=’+selectedGroup;

alert (“” +url+ “”); // shows the url, which is now: index.php?-action=get_types&type_group=2 ;

alert (“” +types_http+ “”); // shows [objekt XMLHttpRequest]

types_http.open(“GET”, url, true);

types_http.onreadystatechange = handleUpdateTypesList;
// Assign the handleUpdateTypesList function as a handler to be called when the HTTP object receives a response from the server
type_group = type_groups_select;
// Save a reference to the group types select list in the http object so that it can be accessed from the handleUpdateTypesList function
types_http.send(null);
}

/**
* handleUpdateTypesList
* This function is called when a response is received from the HTTP object after we request the types for a particular group.
*/
//function handleUpdateTypesList(){
var handleUpdateTypesList = function(){
alert (“Hello 1”);
if ( types_http.readystate == 4 ){
alert (“Hello 2”);
// We have successfully obtained the response from the server
if ( types_http == null ) types_http = getHTTPObject();

alert (“” +types_http.responseText+ “”);

var options = eval(‘(‘ + types_http.responseText +’)’);

// we now have the options that we will use to fill the 2nd select list as an array
// now let’s get out select list and refill it
var types_list = type_group.form.elements[‘type_group’];
// We obtain a reference to the type_id select list (let’s assume that the field is named type_id.. if not, then change this).
// Clear the existing options in the types list.
for ( var i=0; i types_list.options[i] = new Option(options[i][‘type’], options[i][‘l_tid’]);
}
}

}

Now we have to deal with the handleUpdateTypesList - Thing i suppose. It is kind of funny what happens but there is always a reason why, right?

When I choose some value in the first select all my alerts show up until the first alert (“Hello 1”); in handleUpdateTypesList.

This one shows up 4 times and then nothing more happens. No alert (“Hello 2”); or alert (“” +types_http.responseText+ “”); ever shows up.

Second selelect remains empty (Please select…). Does that mean that the if ( types_http.readystate == 4 ){ condition returns false?
We do not obtain a server response. What to try next?

Best regards

Markus


shannah — Tue Jun 05, 2007 10:41 am

I really hate to swear… but… SHIT!

I’m sorry I put you through this.. the problem is

if ( types_http.readystate == 4 ){

should be

if ( types_http.readyState == 4 ){

(Note the capital ‘S’).

That should fix the issue – or at least get us to the next step of debugging.

Reference: http://www.w3schools.com/xml/xml_http.asp

-Steve


Markus — Tue Jun 05, 2007 10:54 am

I really hate to swear… but… SHIT!

I’m sorry I put you through this.. the problem is

if ( types_http.readystate == 4 ){

should be

if ( types_http.readyState == 4 ){

(Note the capital ‘S’).

That should fix the issue – or at least get us to the next step of debugging.

Reference: [http://www.w3schools.com/xml/xml_http.asp](http://www.w3schools.com/xml/xml_http.asp)

-Steve

Wow it’s going on, now we have the following:

/**
* handleUpdateTypesList
* This function is called when a response is received from the HTTP object after we request the types for a particular group.
*/
//function handleUpdateTypesList(){
var handleUpdateTypesList = function(){
alert (“Hello 1”);
if ( types_http.readyState == 4 ){
alert (“Hello 2”);
// We have successfully obtained the response from the server
if ( types_http == null ) types_http = getHTTPObject();

alert (“” +types_http.responseText+ “”);

var options = eval(‘(‘ + types_http.responseText +’)’);

// we now have the options that we will use to fill the 2nd select list as an array
// now let’s get out select list and refill it
var types_list = type_group.form.elements[‘type_group’];
// We obtain a reference to the type_id select list (let’s assume that the field is named type_id.. if not, then change this).
// Clear the existing options in the types list.
for ( var i=0; i types_list.options[i] = new Option(options[i][‘type’], options[i][‘l_tid’]);
}
}

}

Same than before, but…

alert (“Hello 2”); shows up

alert (“” +types_http.responseText+ “”); gives me the array with the right values inside the alert.

Than nothing more is happening.

Some more Ideas or typos in there?

Markus


shannah — Tue Jun 05, 2007 11:08 am

Same strategy as you used to get this far… find out what is in the variables.Ê May sure that types_list is actually holding a reference to the 2nd select list.

The line:

var types_list = type_group.form.elements[‘type_group’];

seems to indicate that it is actually referring to the first select list.

etc…

Find out what is in the variables.


Markus — Wed Jun 06, 2007 4:50 am

Same strategy as you used to get this far… find out what is in the variables. May sure that types_list is actually holding a reference to the 2nd select list.

The line:

var types_list = type_group.form.elements[‘type_group’];

seems to indicate that it is actually referring to the first select list.

etc…

Find out what is in the variables.

Hoooooray, it works! Thanks very much for all your patience. Seems you are not only a good programmer but a very patient teacher too. And I think I understood at least a little bit of this JavaScript sources.

My last code of handleUpdateTypesList function is:

/**
* handleUpdateTypesList
* This function is called when a response is received from the HTTP object after we request the types for a particular group.
*/
//function handleUpdateTypesList(){
var handleUpdateTypesList = function(){

if ( types_http.readyState == 4 ){
// We have successfully obtained the response from the server

if ( types_http == null ) types_http = getHTTPObject();

//alert (“” +types_http.responseText+ “”); // gives out an array of keys and values

var options = eval(‘(‘ + types_http.responseText +’)’);
// we now have the options that we will use to fill the 2nd select list as an arrays
// now let’s get out select list and refill it

var types_list = type_group.form.elements[‘L_TID’]; //Loads right values into L_TID select
// We obtain a reference to the L_TID select list.
// Clear the existing options in the types list.
for ( var i=0; i types_list.options[i] = new Option(options[i][‘type’], options[i][‘l_tid’]);
}
}

}

If you are working on things like this to make them a feature in one of the next releases remember we had this line in updatesTypesList function where we skipped

var url = DATAFACE_SITE_HREF +’?-action=get_types&type_group=’+selectedGroup;

and put in the static

var url = ‘index.php?-action=get_types&type_group=’+selectedGroup;

Would be nice to have it dynamic in the future. For me and for now I think it works fine with the static code.

And one little problem I have left. I can not really understand but it has to do with german special characters in my database values.
There are special characters in valuelist one as well as in valuelist two. The ones in the first select got displayed right, the ones in the second select got displayed wrong e.g. with a question mark instead of the special character. Why is it different and could I put something in my code to avoid this?

Many many thanks again for this. I have a few more questions but on other subjects so I will start a new thread for them.

Markus


shannah — Wed Jun 06, 2007 9:58 am

For the weird characters, this is because the output is returned in UTF-8 but we forgot to tell that to javascript.

You can remedy this by adding the following to the beginning of your get_types action:

$app =& Dataface_Application::getInstance();

header(‘Content-type: text/javascript; charset=’.$app->_conf[‘oe’]);

$app->_conf[‘oe’] stores the output encoding for the application which is probably UTF-8 right now. This should fix the issue.

In any case I’m glad to hear it’s all working for you. Javascript can be very painful and frustrating at times, but it is satisfying when it starts working. If you are inclined, perhaps you could write a short “how-to” about your experiences here to help users who want to achieve the same thing.

Best regards

Steve


Markus — Thu Jun 07, 2007 2:49 am

For the weird characters, this is because the output is returned in UTF-8 but we forgot to tell that to javascript.

You can remedy this by adding the following to the beginning of your get_types action:


Markus — Thu Jun 07, 2007 2:59 am

I hope this will work now. Here is the missing code from the last posting:

xml version="1.0" encoding="ISO-8859-1"?  

http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
http://www.w3.org/1999/xhtml" xml:lang="de" lang="de">  
	  
			

shannah — Thu Jun 07, 2007 10:05 am

Hi Markus,
You just need to enable unicode in your application: http://framework.weblite.ca/documentation/how-to/unicode

Although if unicode is not already enabled, then this may not be what is causing the characters to turn up funny.

-Steve


Markus — Thu Jun 07, 2007 1:15 pm

Hi steve,

i put that two lines in my conf.ini but i got the same source like above which means encoding is ISO-8859-1

What could it be then?

Kind regards

Markus

xml version="1.0" encoding="ISO-8859-1"?  

http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
http://www.w3.org/1999/xhtml" xml:lang="de" lang="de">  
	  
								

shannah — Thu Jun 07, 2007 1:57 pm

Did you put it at the beginning of your conf.ini file or somewhere later on?Ê It has to go at the very beginning.

-Steve


Markus — Fri Jun 08, 2007 9:14 am

Hi Steve,
yes I put it at the very beginning and I tried something else.
I changed my Dataface_Main_Template.html in the two lines where $ENV.APPLICATION.oe is:
{if !$ENV.APPLICATION_OBJECT->main_content_only}xml version=”1.0” encoding=”{$ENV.APPLICATION.oe}”?
Êto {if !$ENV.APPLICATION_OBJECT->main_content_only}xml version=”1.0” encoding=”UTF-8”?
and

to
but when I load it on the server and reload my page I get still ISO-8859-1 in both places in my source code.
It seems that none of both trials lead to success. Is there some server-cache I have to empty before or is the problem somewhere else?
Kind regards
Markus


Markus — Thu Jun 07, 2007 2:59 am

I hope this will work now. Here is the missing code from the last posting:

xml version="1.0" encoding="ISO-8859-1"?  

http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
http://www.w3.org/1999/xhtml" xml:lang="de" lang="de">  
	  
			

shannah — Thu Jun 07, 2007 10:05 am

Hi Markus,
You just need to enable unicode in your application: http://framework.weblite.ca/documentation/how-to/unicode

Although if unicode is not already enabled, then this may not be what is causing the characters to turn up funny.

-Steve


Markus — Thu Jun 07, 2007 1:15 pm

Hi steve,

i put that two lines in my conf.ini but i got the same source like above which means encoding is ISO-8859-1

What could it be then?

Kind regards

Markus

xml version="1.0" encoding="ISO-8859-1"?  

http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
http://www.w3.org/1999/xhtml" xml:lang="de" lang="de">  
	  
								

shannah — Thu Jun 07, 2007 1:57 pm

Did you put it at the beginning of your conf.ini file or somewhere later on?Ê It has to go at the very beginning.

-Steve


Markus — Fri Jun 08, 2007 9:14 am

Hi Steve,
yes I put it at the very beginning and I tried something else.
I changed my Dataface_Main_Template.html in the two lines where $ENV.APPLICATION.oe is:
{if !$ENV.APPLICATION_OBJECT->main_content_only}xml version=”1.0” encoding=”{$ENV.APPLICATION.oe}”?
Êto {if !$ENV.APPLICATION_OBJECT->main_content_only}xml version=”1.0” encoding=”UTF-8”?
and

to
but when I load it on the server and reload my page I get still ISO-8859-1 in both places in my source code.
It seems that none of both trials lead to success. Is there some server-cache I have to empty before or is the problem somewhere else?
Kind regards
Markus


shannah — Fri Jun 08, 2007 9:33 am

Have you overridden you Dataface_Main_Template.html file at all in your application’s templates directory?Ê That would override any changes you make to the Dataface template files.

There is something fishy going on with that install, but it is difficult for me to diagnose from this vantage point.

If at all possible it is best to not make any changes to any of the files in the dataface directory because it will become more difficult for you to upgrade later on.Ê Best to use conf.ini file where possible.

And I guess another thing to confirm that we are talking about the same conf.ini file.Ê You are changing the conf.ini file in your application’s directory and not the one in the dataface directory right?

-Steve


Markus — Mon Jun 11, 2007 5:22 am

Hi Steve,
You are right, I copied some files from the Dataface templates directory to my application templates directory and made some
changes there. I thought this would override the original files in dataface/Dataface/templates.
I do not make any changes in files of dataface/Dataface/templates directory.
How about the templates_c directory in my application. Isn’t that a kind of cache where my real templates for the application
come from? There are all the same templates as in the templates directory but named something like
%%08^08F^08FE976E%%Dataface_Main_Template.html.php
OK. I searched the forum and found http://framework.weblite.ca/forum/dataface-users/141833807/23945652/?searchterm=templates_c
and http://framework.weblite.ca/forum/dataface-users/127/2/?searchterm=templates_c
How does it exactly work? What happens when I delete everything but the folders in templates_c. I think that has to do with
my problems. I want the Dataface_Main_Template.html IN MY APPs templates folder to be the one which is used. And when I change it I want the
changed one there to be used and not the %%08^08F^08FE976E%%Dataface_Main_Template.html.php in templates_c.
I think this should be another thread. Maybe I should open one next time.
Now on my main problem with the odd special chars:
I changed my conf.ini in my app not the one in dataface directory. And I changed my Dataface_Main_Template.html in my
application back to the former state, that means I took out the static UTF-8 encoding and made it {ENV.APPLICATION.oe} again.
Nevertheless my special chars come out as ? in my app.
What more can I do?
Markus


shannah — Mon Jun 11, 2007 9:16 am

Are all special chars coming out as ? or just the ones from the 2nd select list?

This is how dataface works for encodings:

1.Ê If you are using only one language, then Dataface will try to use ISO-8859-1 encoding (Latin-1).Ê If you have more than one language in your app, then it will always use UTF-8.Ê You can override the encoding by setting the io and oe parameters in the conf.ini file.Ê This will add a meta tag to the main template to indicate that it should use UTF-8.Ê If you are not using the Main template for the output in an action, then you should explicitly output an HTTP header to state the character set.

See dataface/actions/ajax_view_record_details.php for an example of this.Ê Note the line:

header(‘Content-type: text/html; charset=’.$app->_conf[‘oe’]);

This is important.

For javascript like your custom action is returning, you’ll want to use text/javascript instead of text/html .

-Steve


Markus — Mon Jun 11, 2007 10:26 am

Hi Steve,
just the special chars from 2nd select list come out as ?
I have at the very beginning of my conf.ini
oe=UTF-8
ie=UTF-8
I have my cutom action like this:
$app =& Dataface_Application::getInstance();
header(‘Content-type: text/javascript; charset=’.$app->_conf[‘oe’]);
//$app->_conf[‘oe’] stores the output encoding for the application which is probably UTF-8 right now
// Dient der Ausgabe von Sonderzeichen in UTF-8 Codierung
// actions_get_types sucht die zugehšrigen typen einer gewŠhlten typgruppe
class actions_get_types {
ÊÊÊ function handle(&$params){
ÊÊÊÊÊÊÊ if ( isset($_REQUEST[‘type_group’]) ){
ÊÊÊÊÊÊÊÊÊÊÊ $sql = “select l_tid, L_GID, type from list_event_type where L_GID=’“.addslashes($_REQUEST[‘type_group’]).”’”;
ÊÊÊÊÊÊÊ } else {
ÊÊÊÊÊÊÊÊÊÊÊ $sql = “select l_tid, L_GID, type from list_event_type”;
ÊÊÊÊÊÊÊ }
ÊÊÊÊÊÊÊ $res = mysql_query($sql, df_db());
ÊÊÊÊÊÊÊ if ( !$res ) trigger_error(mysql_error(df_db()), E_USER_ERROR);
ÊÊÊÊÊÊÊ header(‘Content-type: text/javascript’);
ÊÊÊÊÊÊÊ echo ‘[’;
ÊÊÊÊÊÊÊ $values = array();
ÊÊÊÊÊÊÊ while ( $row = mysql_fetch_assoc($res) ){
ÊÊÊÊÊÊÊÊÊÊÊ $values[] =Ê “{l_tid:’”.$row[‘l_tid’].”’, type: ‘“.addslashes($row[‘type’]).”’}”;
ÊÊÊÊÊÊÊ }
ÊÊÊÊÊÊÊ echo implode(‘,’,$values);
ÊÊÊÊÊÊÊ echo ‘]’;
ÊÊÊÊÊÊÊ exit;
ÊÊÊ }
ÊÊÊ
}
Nevertheless I do not get the right chars. And when I look into the source of my html, it is still:

xml version="1.0" encoding="ISO-8859-1"?  

http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">  
and in the head

Somehow frustrating I think. I t seems as if nothing ever changes.
Markus


shannah — Mon Jun 11, 2007 3:33 pm

Hi Markus,
A couple of things.Ê There are 2 separate things to be looking at… best to keep them separate so that things don’t get confusing.

  1. The get_types action.
  2. The HTML source.
    Since most of your HTML source looks OK, it is best to leave that alone.Ê Just focus on the get_types action.Ê (i.e. REmove all of the encoding stuff you added at the beginning of the conf.ini file).
    Now for the get_types action, this is the problem:
    Your header() function should be where the second header() function is called.Ê (Notice that you have 2 of them - the 2nd one is in the correct place, the first one is not.Ê You just need to change the 2nd one so that it looks like the first one - if that makes any sense.Ê e.g.
    class actions_get_types {
    ÊÊÊ function handle(&$params){
    ÊÊÊÊÊÊÊ if ( isset($_REQUEST[‘type_group’]) ){
    ÊÊÊÊÊÊÊÊÊÊÊ $sql = “select l_tid, L_GID, type from list_event_type where L_GID=’“.addslashes($_REQUEST[‘type_group’]).”’”;
    ÊÊÊÊÊÊÊ } else {
    ÊÊÊÊÊÊÊÊÊÊÊ $sql = “select l_tid, L_GID, type from list_event_type”;
    ÊÊÊÊÊÊÊ }
    ÊÊÊÊÊÊÊ $res = mysql_query($sql, df_db());
    ÊÊÊÊÊÊÊ if ( !$res ) trigger_error(mysql_error(df_db()), E_USER_ERROR);
    ÊÊÊÊÊÊÊ $app =& Dataface_Application::getInstance();
    ÊÊÊÊÊÊÊ header(‘Content-type: text/javascript; charset=’.$app->_conf[‘oe’]);
    ÊÊÊÊÊÊÊ echo ‘[’;
    ÊÊÊÊÊÊÊ $values = array();
    ÊÊÊÊÊÊÊ while ( $row = mysql_fetch_assoc($res) ){
    ÊÊÊÊÊÊÊÊÊÊÊ $values[] =Ê “{l_tid:’”.$row[‘l_tid’].”’, type: ‘“.addslashes($row[‘type’]).”’}”;
    ÊÊÊÊÊÊÊ }
    ÊÊÊÊÊÊÊ echo implode(‘,’,$values);
    ÊÊÊÊÊÊÊ echo ‘]’;
    ÊÊÊÊÊÊÊ exit;
    ÊÊÊ }
    ÊÊÊ
    }

Markus — Tue Jun 12, 2007 1:23 am

Hi Steve,

Thank you for that. I did not really regognize the double code. Now it works great and all of the special chars are written correctly. I hope we can close this thread now.

I have in mind the “How to” but still not enough spare time now.

Markus


shannah — Tue Jun 12, 2007 12:49 pm

Phew… this thread really exposes some klunkiness in the Ploneboard forum.Ê Having to always click on “Page 2” is kind of a pain..Ê it was a long one.

Glad to hear it’s working now.Ê

Best regards

Steve


Markus — Tue Jun 12, 2007 1:23 am

Hi Steve,

Thank you for that. I did not really regognize the double code. Now it works great and all of the special chars are written correctly. I hope we can close this thread now.

I have in mind the “How to” but still not enough spare time now.

Markus


shannah — Tue Jun 12, 2007 12:49 pm

Phew… this thread really exposes some klunkiness in the Ploneboard forum.Ê Having to always click on “Page 2” is kind of a pain..Ê it was a long one.

Glad to hear it’s working now.Ê

Best regards

Steve