Buy Now
Sign in

Chronoform 4: A simple AJAX Form with Filter & Paginator

Tozai_X , January 16 2015
Tozai_X
Hi eveybody,
I had to create a simple Form to search users in Joomla by 'username' field. I made it with Choronoforms 4 and decided to write this little tutorial about that.
I hope it is useful for somebody else.

From Choronoforms/Foms Manager Panel click on New.
The name of the form is for me: simple_ajax_form



On Preview Panel insert:

1)textbox ( Start a Multi field row)


2)submit button ( Add to a Multi field row)


3)submit button ( Add to a Multi field row)


4)a container to insert the results of the search: DIV (IMPORTANT: to discover the id of container check the code chronoforms generate on save form. For me and ofr the rest of this tutorial: cf_container_4)

5)a container to insert paginator : DIV (only if we have more than one page to show): the id in my form is cf_container_5



On Events Panel insert:

1)Load CSS to style result.
My code is
/*Results*/
table.users_search
{
width: 100%;
}
table.users_search td
{
text-align: center;
border: 1px solid black;
}
table.users_search td.title1
{
font-size: 110%;
color: #ff6600;
font-weight: bold;
}
table.users_search td.title2
{
font-size: 100%;
color:#008000;
text-decoration: underline;
font-weight: bold;
}
table.users_search td.datas
{
font-size: 100%;
color: #0000ff;
}
/*Paginator*/
table.users_paginator
{
width: 100%;
}
table.users_paginator td
{
text-align: center;
border: 1px solid black;
}
table.users_paginator td.active
{
color: #ff6600;
font-weight: bold;
}
table.users_paginator td.current
{
background-color: #ff6600;
color: #ffffff;
font-weight: bold;
}


2)Load JS to ad event click on buttons (ajax request)

window.addEvent('load', function() {

function show_results(page)
{
var text_filter = document.getElementById("input_user_name").value;
if(text_filter.trim().length < 1)
{
alert("At least one char!") ;
return;
}

var load_req = new Request({
url: 'index.php?option=com_chronoforms&chronoform=simple_ajax_form&event=on_search_button_click&page_n=' + page,
method: 'get',
onRequest: function()
{
document.id('cf_container_4').empty();
document.id('cf_container_4').innerHTML = '<span>Loading...</span>';
document.id('cf_container_5').empty();
},

onSuccess: function(responseText)
{
document.id('cf_container_4').empty();

var response_data = responseText.trim().split("\n");
//N rec in this page
var n_rec_string = response_data[0].trim().split("=");
var i,n_rec = parseInt(n_rec_string[1]);
//N Tot pages
var n_pag_tot_string = response_data[1].trim().split("=");
var n_pag_tot = parseInt(n_pag_tot_string[1]);
// First Page
var n_first_pag_string = response_data[2].trim().split("=");
var n_first_pag = parseInt(n_first_pag_string[1]);
//Previous Page
var n_previous_pag_string = response_data[3].trim().split("=");
var n_previous_pag = parseInt(n_previous_pag_string[1]);
// Actual Page
var n_actual_pag_string = response_data[4].trim().split("=");
var n_actual_pag = parseInt(n_actual_pag_string[1]);
//Next Page
var n_next_pag_string = response_data[5].trim().split("=");
var n_next_pag = parseInt(n_next_pag_string[1]);
//Last Page
var n_last_pag_string = response_data[6].trim().split("=");
var n_last_pag = parseInt(n_last_pag_string[1]);

//Only if i found records
if(n_rec > 0)
{
//Results
var tabel_results = document.createElement('table');
tabel_results.className = "users_search";
//Header
var tr = document.createElement('tr');
tr.innerHTML = "<tr><td class=\"title1\" width=\"100%\">User Name</td></tr>";
tabel_results.appendChild(tr);

for(i = 7; i < n_rec + 7; i++)
{
var tr = document.createElement('tr');
tr.innerHTML = response_data;
tabel_results.appendChild(tr);
}

document.id('cf_container_4').appendChild(tabel_results);
}
else
{
document.id('cf_container_4').innerHTML = '<span>No users found</span>';
}

//Paginator?
//Only if i found records
if(n_pag_tot > 1)
{
var paginator = document.createElement('table');
paginator.className = "users_paginator";

var tr = document.createElement('tr');
tr.innerHTML = "<tr>";

// First Page
tr.innerHTML = tr.innerHTML + "<td width=\"20%\"> <input id=\"id_button_first_pag\" name=\"input_first_pag\" class=\"\" value=\"<<\" type=\"button\" /> </td>";
// Previous Page
tr.innerHTML = tr.innerHTML + "<td width=\"20%\"> <input id=\"id_button_previous_pag\" name=\"input_previous_pag\" class=\"\" value=\"<\" type=\"button\" /> </td>";
// Actual Page
tr.innerHTML = tr.innerHTML + "<td class=\"current\" width=\"20%\"> " + n_actual_pag + "/" + n_pag_tot + " </td>";
// Next Page
tr.innerHTML = tr.innerHTML + "<td width=\"20%\"> <input id=\"id_button_next_pag\" name=\"input_next_pag\" class=\"\" value=\">\" type=\"button\" /> </td>";
// Last Page
tr.innerHTML = tr.innerHTML + "<td width=\"20%\"> <input id=\"id_button_last_pag\" name=\"input_last_pag\" class=\"\" value=\">>\" type=\"button\" /> </td>";

tr.innerHTML = tr.innerHTML + "</tr>";

paginator.appendChild(tr);

document.id('cf_container_5').appendChild(paginator);

//Add avent listener
//First Page Button
if(n_first_pag > 0)
{
document.id('id_button_first_pag').addEvent('click', function()
{
show_results(1);
});
}
else
document.id('id_button_first_pag').disabled = true;
//Previous Page Button
if(n_previous_pag > 0)
{
document.id('id_button_previous_pag').addEvent('click', function()
{
show_results(n_previous_pag);
});
}
else
document.id('id_button_previous_pag').disabled = true;
//Next Page Button
if(n_next_pag > 0)
{
document.id('id_button_next_pag').addEvent('click', function()
{
show_results(n_next_pag);
});
}
else
document.id('id_button_next_pag').disabled = true;
//Last Page Button /*
if(n_last_pag > 0)
{
document.id('id_button_last_pag').addEvent('click', function()
{
show_results(n_last_pag);
});
}
else
document.id('id_button_last_pag').disabled = true;
}

},

onFailure: function()
{
document.id('cf_container_4').empty();
document.id('cf_container_4').innerHTML = '<span>Loading failed!!!</span>';
}
});

load_req.send(document.id('input_user_name').get('name')+'='+document.id('input_user_name').get('value'));
}

document.id('input_submit_search').addEvent('click', function()
{
show_results(1);
});

document.id('input_submit_clear').addEvent('click', function()
{
document.id('input_user_name').value = "";
document.id('cf_container_4').empty();
document.id('cf_container_5').empty();
});
});


3)An event on_search_button_click to query DB and customize format of the results for the ajax.on_success method
<?php
$MAX_RECORD_IN_PAGE = 5;
$Actual_Page = (isset($_GET['page_n'])) ? $_GET['page_n'] : 1;
$LIMIT_string = ' LIMIT ' .($Actual_Page - 1) * $MAX_RECORD_IN_PAGE .',' .$MAX_RECORD_IN_PAGE;

// Get a db connection.
$db = JFactory::getDbo();

// Create a new query object.
$query = $db->getQuery(true);

//Get total record
$query
->select($db->quoteName('username'))
->from($db->quoteName('#__users'))
->where($db->quoteName('username'). ' LIKE \'%'. $form->data['input_user_name'].'%\'');

// Reset the query using our newly populated query object.
$db->setQuery($query);

$db->execute();
$iRecordTotAllPages = $db->getNumRows();
$iTotalPages = (int)($iRecordTotAllPages / $MAX_RECORD_IN_PAGE);
if($iRecordTotAllPages % $MAX_RECORD_IN_PAGE)
{
$iTotalPages++;
}

// Create a new query object.
$query = $db->getQuery(true);

// Get record for the current page
$query
->select($db->quoteName('username'))
->from($db->quoteName('#__users'))
->where($db->quoteName('username'). ' LIKE \'%'. $form->data['input_user_name'].'%\'')
->order($db->quoteName('username'). $LIMIT_string);

// Reset the query using our newly populated query object.
$db->setQuery($query);

// Load the results
$db->execute();
$iRecord = $db->getNumRows();
$rows = $db->loadRowList();
$results = array();

$results[] = "REC_TOT=". $iRecord;
$results[] = "PAG_TOT=". $iTotalPages;
//Paginator?
$results[] = ($Actual_Page <= 1) ? "FIRST_PAG=0" : "FIRST_PAG=1";
$results[] = "PREV_PAG=". ($Actual_Page - 1);
$results[] = "PAG_N=". $Actual_Page;
$results[] = ($Actual_Page < $iTotalPages) ? "NEXT_PAG=". ($Actual_Page + 1) : "NEXT_PAG=0";
$results[] = ($Actual_Page < $iTotalPages) ? "LAST_PAG=". $iTotalPages : "LAST_PAG=0";

if($iRecord > 0 )
{
//Users record
for($i = 0; $i < $iRecord; $i++)
{
$results[] = "<tr><td class=\"datas\" width=\"100%\">" . $rows[$i][0] . "</td></tr>";
}
}

$results = implode("\n", $results);
//Return
echo $results;

//Stop esecuzione
$mainframe =JFactory::getApplication();
$mainframe->close();
?>


As you can see I set the limit of the records on single page to 5 (change as you want)

Change the id of the containers in your JS code to match your id.

If everything right what we have is.





All suggestions to improve it are welcome.
J
jhaviro
Thanks for sharing!!!.

It does not work for me. I am using CFV5 but this should not be a problem.
I changed the URL of Ajax and personalized response IDs, but I always get "No users found" ... I do not have any errors. Can you think why not work?

I was looking for a way to create a page and found your post. I feel very good. I want to implement some more filters and could be very interesting for me.

Sincerely
javierp.
J
jhaviro
YES!! (hello) its work!!... Thank you very much again.
My Error is in URL Request. Only a "5" in "Chronoform" string URL.
great, im happy
J
jhaviro
Hello again.

You can filter the data in various fields?
For example, we make a query with multiple columns

->select($db->quoteName(array('one','two','three','four')))....

Then I want to filter by "one" and "two" with LIKE

->where(.... LIKE \'%'.$form->data['input_field_one'].'%\'', 'AND') // OR
->where(.... LIKE \'%'.$form->data['input_field_two'].'%\'')

I tried this but "load req.send" does not support send array (or do not know)
do what it does eset filtered with a single form field.

I know that all this is possible with CCv5 but should integrate both forms CFv5.

Any help?
Tozai_X
The first idea I have is to put all fileds you want to filter by in a single array.
Convert it in a JSON string a use it like a single parameter in the AJAX request.

On the php server side encode the string into an array and compose your select adding in WHERE CLAUSE different

" field1 LIKE '%". array[1]. "%' AND " . (every time the index of your array is not empty)
" field2 LIKE '%". array[2]. "%' AND " ecc...

The rest of code remain the same.

Hope this help you
J
jhaviro
HI!!

It seems to be working. After converting the JSON string array sends the string in the following format:
["field1 = valuefield1", "field2 = valuefield2" ...] (four fields)
But, now how that chain recovered from php?
I tried to do with json_decode, but do not have the required format and not working.
json_decode need the data ["var1: text", "var2: text2" ....]
How do I get retrieve the string? ... As get access to it, then it is easy to divide in substring.

With (isset ($ _ GET ["? ¿? ¿? ¿? ¿"])) I do not know how to access unnamed variable

Can you think of something ??

(sorry for my bad english) and my short knowledge of ajax, jquery, php, mysql ... etc.
I'm not a programmer, so I try to use CFv5 ... but it has limitations (or my own limitations) and your form is exactly what I need.