Welcome Guest, Not a member yet? Register   Sign In
jquery autocomplete
#1

[eluser]Gorazd Reichman[/eluser]
Hello,

This is my first post on this forum. I have been using CI for a while now.
It is great but I miss some ajax functionality. As I have read on this forum we can expect some sort ajax/JQuery support in the near future but I needed a solution right now, so I wrote simple JQuery autocomplete libraray for use in CI.

Library:
Code:
<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class JQuery {

    var $el_Num;
    var $AjaxDelay ;
    var $AjaxBaseUrl ;
    var $AjaxMinChars ;
    var $scripts ;

    function JQuery()
    {
        $this->CI =& get_instance();
        $this->el_Num = array() ;
        $this->AjaxDelay = 500 ;
        $this->AjaxMinChars = 3 ;
        $this->AjaxBaseUrl = "" ;
        $this->scripts = array() ;
        $this->CI->load->helper('form') ;
    }
    
    function setAjaxDelay($delay)
    {
        $this->AjaxDelay = $delay ;
    }
    
    function setAjaxMinChars($chars)
    {
        $this->AjaxMinChars = $chars ;
    }
    
    function setAjaxBaseUrl($url)
    {
        $this->AjaxBaseUrl = $url ;
    }
    
    function loadJScript($src)
    {
        $this->scripts[] = $src ;
    }
    
    function JScript()
    {
        $output = "" ;
        foreach ($this->scripts as $script)
        {
            $output .= '[removed][removed]' ;
        }
        $output .= '[removed]' ;
        $output .= 'var autocomplete_baseurl = "'.$this->AjaxBaseUrl.'" ;' ;
        $output .= 'var autocomplete_delay = '.$this->AjaxDelay.' ;' ;
        $output .= 'var autocomplete_minchars = '.$this->AjaxMinChars.' ;' ;
        $output .= '[removed]' ;
        return $output ;
    }
    
    function form_autocomplete($ajaxFunction, $hidden = FALSE, $data = '', $value = '', $extra = '')
    {
        if (!array_key_exists($ajaxFunction,$this->el_Num)) $this->el_Num[$ajaxFunction] = 0 ;
        $this->el_Num[$ajaxFunction]++ ;
        $output = form_input($data,$value,'class="autocomplete" id="'.$ajaxFunction.'_'.$this->el_Num[$ajaxFunction].'" '.$extra) ;
        if ($hidden)
        {
            $output .= form_hidden("hidden".$ajaxFunction.'_'.$this->el_Num[$ajaxFunction]) ;
        }
        return $output ;
    }
        
}
// end of class
#2

[eluser]Gorazd Reichman[/eluser]
This libraray requires at least:
JQuery.js
and jquery.myautocomplete.js

You can get jquery on the net
and myautocomplete.js is here
Code:
var t = false ;
var autocomplete_baseurl = "http://192.168.3.6/intranet/index.php/rma/Ajax" ;
var autocomplete_delay = 300 ;
var autocomplete_minchars = 3 ;

$(window).load(function() {
    Autocomplete = function (id)
    {
        if (id.match('_') != -1) //split name and number
        {
            var myId = new String(id) ;
            var IdSplit=myId.split('_',2) ;
            elType = IdSplit[0] ;
        } else
        {
            var elType = id ;
        }
        var SearchStr = $("#"+id).val() ;
        var NumChars = SearchStr.length ;
        if (NumChars >= autocomplete_minchars)
        {
            var postdata = "search=" + SearchStr ;
            $.ajax({
                url: autocomplete_baseurl+elType ,
                type: "POST",
                data: postdata ,
                success: function(html) {
                    if (html != "empty")
                    {
                        var position = $("#"+id).offset() ;
                        $("#"+id).attr('auto','on') ;
                        $("#result").css('top',position.top+22) ;
                        $("#result").css('left',position.left) ;
                        $(".combosel").attr('fokus','off') ;
                        $("#result").stop(true,true) ;
                        $("#result").fadeOut(100,
                            function () {
                                $(".combosel").empty() ;
                                $(".combosel").append(html) ;
                                $("#result").fadeIn(400) ;
                            } ) ;
                    }
                }  
            }) ;
        }
        else
        {
            $("#result").css({'display':'none'}) ;
        }
    } ;
    
    $(".autocomplete").bind('keyup',function(event) {

        var id = $(this).attr('id') ;
        clearTimeout(t) ;  
        $(".combosel").attr('parent',id) ; //set dropdown box parent attr to element id
        if (event.which == 40) //check if user want to go down to dropdown
        {
            event.preventDefault() ;
            $(".combosel").attr('fokus','on') ;
            $(this).blur() ; //blur input box
            $(".combosel").focus() ;   //set focus to dropdown
        } else
        {
            t=setTimeout("Autocomplete('"+id+"');",autocomplete_delay) ; //start autocomplete
        }
    });
    
    $(".combosel").bind('blur',function(){
        $(this).attr('fokus','off') ;
        if ($("#"+$(this).attr('parent')).attr('fokus') == 'off') $("#result").css({'display':'none'}) ;
    }) ;
    
    $(".combosel").bind('focus',function(){
        $(this).attr('fokus','on') ;
    }) ;
    
    $(".autocomplete").bind('focus', function() {
        $(this).attr('fokus','on') ;
    });
    
    $(".combosel").bind('click keyup',function(e) {
        if ((e.which != 13) && (e.type == "keyup")) return ; //check if Enter was pressed
        e.preventDefault() ;
        var selection = $(".combosel :selected").text() ;  //get selected value
        if ($(".combosel :selected").val() == undefined) return ; //if nothing is selected exit
        var elementid = $(".combosel").attr('parent') ; //set parent id
        
        $("#"+elementid).val(selection) ;
        $("#"+elementid).attr('auto','off') ;  //autocomplete input is closed
        $('#result').attr('parent','none') ;
        $('#result').css({'display':'none'}) ;
        $("#"+elementid).focus() ;
        
    } ) ;
    
    $(".autocomplete").bind('blur',function(e) {

        $(this).attr('fokus','off') ;
        
        if (($(this).attr('auto') == 'on') && ($(".combosel").attr('fokus') == 'off'))
        {
            $(".combosel").click() ;
            $(this).attr('auto','off') ;
            $('#result').attr('parent','none') ;
            $('#result').css({'display':'none'}) ;
        }
    }) ;  
}) ;
#3

[eluser]Gorazd Reichman[/eluser]
You can use it like this:

Controller:
Code:
<?php
class Rma extends Controller {

    function Rma()
    {
        parent::Controller();  
        $this->load->model('Rmamodel','',TRUE) ;
        $this->load->library('JQuery') ;
        $this->base = $this->config->item('base_url');
    }
    
    function index()
    {
        $this->jquery->setAjaxBaseUrl($this->base.'index.php/rma/Ajax') ;
        $this->jquery->loadJScript($this->base.'jscript/jquery.js') ;
        $this->jquery->loadJScript($this->base.'jscript/jquery.myautocomplete.js') ;
        $this->load->view('jquery_test',$data);
    }
    
    function AjaxPartners()
    {
        echo $this->Rmamodel->get_partners($this->input->post('search'),FALSE) ;
    }

In the model you must have function like this:
Code:
function get_products($name, $description=TRUE)
    {
        $this->db->like('pnaziv',$name) ;
        $this->db->or_like('pnaziv2',$name) ;
        $this->db->order_by('pnaziv') ;
        $result = $this->db->get('vasco_products') ;
        if ($result->num_rows() > 0)
        {
            $output = '<ul>' ;
            if (!$description) $output = '';//'<select size="10" id="combosel" style="width: 220; border-style: none">' ;
            foreach ($result->result() as $product)
            {
                if ($description)
                {
                    $output .= '<li><strong>'.$product->pnaziv.'</strong><br>' ;
                    $output .= $product->pnaziv2.'</li>' ;
                } else
                {
                    $naziv = trim ($product->pnaziv) ;      
                    $output .= '<option value="'.$naziv.'">'.$naziv.'</option>' ;
                }
            }
            if ($description) $output .= '</ul>' ;
            else $output .= '';//'</select>' ;
            return $output ;      
        } else
        {
            return "empty" ;
        }
    }

and in the View:
Code:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
&lt;html&gt;
&lt;head&gt;
&lt;meta http-equiv="Cache-Control" content="no-cache"&gt;
&lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8"&gt;
&lt;meta http-equiv="content-language" content="sl-SI"&gt;
&lt;title&gt;JQuery_test&lt;/title&gt;
&lt;?=$this->jquery->JScript()?&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;?=$this->jquery->form_autocomplete('Partners', true)?&gt;<br/>
&lt;?=$this->jquery->form_autocomplete('Partners', true)?&gt;<br/>
&lt;?=$this->jquery->form_autocomplete('Partners', true)?&gt;<br/>

<div id="result" style="position:absolute; display:none;">
<select size="10" class="combosel" style="width: 220px; ">
</select>
</div>

&lt;/body&gt;
&lt;/html&gt;
#4

[eluser]BoogieK[/eluser]
There is a plugin for jQuery called "jQuery autocomplete" or AjaxComplete and is for CI too. You have instruction there how to use it creating the controller, the model and the view. If know jQuery a little bit you can improve for your work. I use the jQeury autocomplete but I had a problem on the binding events. I solved it with a "rough" method but it`s ok now.
#5

[eluser]Colin Williams[/eluser]
CI's role is to handle certain requests to your server. Ajax is just a means of requesting the server. CI can handle Ajax. From CI, you can serve a chunk of HTML for a client side script to inject into a page. From CI, you can serve a well-formed XML file, which a client side script could parse. From CI, you could serve a JSON file, which, again, a client side script could parse. So yes, CI "supports" Ajax.

If I were going to implement auto-complete within an app, it would look something like this in the controller method that the JS hits via Ajax

Code:
function list_x_json($str = '')
{
   // Search for "x_objects" where title is like $str
   $this->load->model('x_object');
   $x_array = $this->x_object->get_matches(array('title' => $str), 10); // (object to match, limit)

   // Return json encoded array. Okay if it's blank
   print json_encode($x_array);
}
#6

[eluser]Gorazd Reichman[/eluser]
[quote author="BoogieK" date="1232816891"]There is a plugin for jQuery called "jQuery autocomplete" or AjaxComplete and is for CI too. You have instruction there how to use it creating the controller, the model and the view. If know jQuery a little bit you can improve for your work. I use the jQeury autocomplete but I had a problem on the binding events. I solved it with a "rough" method but it`s ok now.[/quote]

Do you mean http://www.dyve.net/jquery/?autocomplete ?
I looked at it but it seemed a litle big (13k).My main goal was to write small js that would enable me to simplify writing CI library that would not require user to have any js knowledge to include autocomplete input fields in CI.
#7

[eluser]Gorazd Reichman[/eluser]
Colin I know that CI can handle server side role with ease, but I wanted to simplify writing CI code to incorporate this functionality without js knowledge. I agree that I should probably return JSON or XML, but right now I was focused on getting usable results from my js script.
#8

[eluser]Colin Williams[/eluser]
Quote:Colin I know that CI can handle server side role with ease
I thought my three-line function looked pretty easy. My main point was that it doesn't need to be so hard. You also said, "I have been using CI for a while now. It is great but I miss some ajax functionality." I had to correct you.




Theme © iAndrew 2016 - Forum software by © MyBB