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

[img
  • http://tozainetwork.net/tutorial_img/  ajax_form_01.png[/img]

    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[i];
    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.