TextField with input buffering as a widget

As I could not find the proper solution for buffering text input and execute a delayed javascript snippet, I came up with my solution:

widget class:




class BufferedTextField extends CWidget

{			

	

	var $name; 

	var $value = ''; 

	var $htmlOptions = array();

	var $onExecuteRequest;

	

	public function run()

	{

		$data['name'] = $this->name;

		$data['value'] = $this->value;

		$data['htmlOptions'] = $this->htmlOptions;

		$data['onExecuteRequest'] = $this->onExecuteRequest;

		

		$this->render("bufferedTextField", $data);

	}	


}



View:




<?php

Yii::app()->clientScript->registerScript('bufferedTextFieldBuffer','


	var onKeyRequestBuffer = {

	

	        bufferText: false,

	        bufferTime: 1000,

	        elem : null,

	        

	        modified : function(elem) {

	        	this.elem = elem;

                setTimeout(\'onKeyRequestBuffer.compareBuffer("\'+ this.elem.val() +\'");\', this.bufferTime);

	        },

	        

	        compareBuffer : function(strText) {

	            if (strText == this.elem.val() && strText != this.bufferText) {

	                this.bufferText = strText;

	                onKeyRequestBuffer.makeRequest();

	            }

	        },	        

	        makeRequest : function() {

        	    '.$onExecuteRequest.'

	        }

	    };

',CClientScript::POS_HEAD);


Yii::app()->clientScript->registerScript('bufferedTextField','

		$("#'.$name.'").keyup(function(event) {

			onKeyRequestBuffer.modified($(this));

		});

',CClientScript::POS_READY);


echo CHtml::textField($name, $value, $htmlOptions);



Example (with ajax):




$this->widget('BufferedTextField', array(

	'name' => "fieldName",

	'onExecuteRequest' => 'jQuery.ajax({

					url: "'.$this->createUrl("yourController/yourAction").'",

					type: "POST",

                                        cache : false,

					data: {"fieldInput" : this.elem.val()},

					success: function(){alert("success");},

				});',

));



The javascript part is adapted from here. The textField fires 1000 ms after the last key up event.

Hi, Sebastian,

I’m doing it like this in a view with a CGridView and a search form:




Yii::app()->clientScript->registerScript('ajax-search', "

$('form').submit(function(){

	$.fn.yiiGridView.update('some-model-grid', {

		data: $(this).serialize()

	});

	return false;

});

var delay = (function(){

	var timer = 0;

	return function(callback, ms){

		clearTimeout(timer);

		timer = setTimeout(callback, ms);

	};

})();

$('#SomeModel_textfield').keyup(function(){

	delay(function(){

		$('form').submit();

	}, 1000);

	return false;

});

$('#SomeModel_combo').change(function(){

	$('form').submit();

	return false;

});

");



In the above #SomeModel_textfield is a text field in the search form and it will fire an ajax search with a delay of 1000 ms.

And #SomeModel_combo is a combobox in the same form and it will fire an ajax search on change.

With a little addition to the gii generated code, they work quite fine and I’m satisfied with the results. :)

I found the tip here : http://stackoverflow.com/questions/1909441/jquery-keyup-delay