$.post not working

Hi,

Can anyone please help me to find why the $.post seems not to be working. I have view form for creating a product. I am trying to have an instant validation when the user inputs the id by checking whether this id does not already exist in the table concerned.

Here is my code for the view form:

[font="Microsoft Sans Serif"][color="#FF0000"]

<div class="form">

<?php Yii::app()->getClientScript()->registerScript(‘checkid’,’$("#thisid").change(function()

{


	&#036;.post(&quot;dupecheck.php&quot;, {thisid: &#036;(this).val()}, function(data) {


		&#036;(&quot;#dupecheck&quot;).html(data); });


}


);');

?>

<?php $form=$this->beginWidget(‘CActiveForm’, array(

'id'=&gt;'roomtype-form',


'enableAjaxValidation'=&gt;true,

)); ?>

&lt;p class=&quot;note&quot;&gt;Fields with &lt;span class=&quot;required&quot;&gt;*&lt;/span&gt; are required.&lt;/p&gt;


&lt;?php echo &#036;form-&gt;errorSummary(&#036;model); ?&gt;


&lt;div class=&quot;row&quot;&gt;


	&lt;?php echo &#036;form-&gt;labelEx(&#036;model,'id'); ?&gt;


	&lt;?php echo &#036;form-&gt;textField(&#036;model,'id',array('size'=&gt;3,'id'=&gt;'thisid','maxlength'=&gt;3)); ?&gt;


	&lt;?php echo &#036;form-&gt;error(&#036;model,'id'); ?&gt;


&lt;/div&gt;


&lt;div id=&quot;dupecheck&quot;&gt;&lt;/div&gt;


&lt;?php echo &#036;form-&gt;labelEx(&#036;model,'description'); ?&gt;


&lt;?php echo &#036;form-&gt;textField(&#036;model,'description',array('size'=&gt;60,'maxlength'=&gt;100)); ?&gt;


&lt;?php echo &#036;form-&gt;error(&#036;model,'description'); ?&gt;&lt;br&gt;


&lt;?php echo &#036;form-&gt;labelEx(&#036;model,'maxnormal'); ?&gt;


&lt;?php echo &#036;form-&gt;textField(&#036;model,'maxnormal',array('size'=&gt;10,'id'=&gt;'maxnor')); ?&gt;


&lt;?php echo &#036;form-&gt;error(&#036;model,'maxnormal'); ?&gt;

<?php echo $form->labelEx($model,‘maxadd’); ?>

&lt;?php echo &#036;form-&gt;textField(&#036;model,'maxadd',array('size'=&gt;10)); ?&gt;


&lt;?php echo &#036;form-&gt;error(&#036;model,'maxadd'); ?&gt;





&lt;div class=&quot;row buttons&quot;&gt;


	&lt;?php echo CHtml::submitButton(&#036;model-&gt;isNewRecord ? 'Create' : 'Save'); ?&gt;


&lt;/div&gt;

<?php $this->endWidget(); ?>

</div><!-- form -->

[/color][/font]

Here is dupecheck.php

[font="Microsoft Sans Serif"][color="#FF0000"]

<?php

$thisid = trim($_POST[‘thisid’]);

$test =Piece::model()->find(“id=’$thisid’”);

if(!empty($test)) {

echo sprintf(&quot;This id &lt;strong&gt;%s&lt;/strong&gt;, exists already.&quot;, &#036;thisid);

} //else {

//echo "Good choice!";

//}

?>[/color][/font]

The dupecheck.php is not even called. It seems that $.post does not work. Any help much appreciated. Thanks.

why dont you make the id auto increment?,

and if you sure you want the id to be given by the user why dont you use Model rules validation

Thanks for the suggestion. But the product ids are given by the users and they use meaningful codes which I must keep. Also, there are other instances where I would need to perform instant validation before submitting the form. The users have been used to work in that way in a previous software and are not willing to change. >:(

so take a look at the link i gave you Model rules validation.

CUniqueValidator validates that the attribute value is unique in the corresponding database table.

So why don’t you use CUniqueValidator

Check also the wiki on Model rules validation amiramir pointed to above.

[b]

[/b]first, starting at point: you dont need to check manually for unique ID, because in most cases if you ignores this field, then your db engine (your db model) will generate a new one: if your ID FIELD is an AUTO INCREMENT,

BUT…if you need to check it manually for reasons i dont understand…then, use this code:

[b]I provide you a full downloadble demo (see attached zip file),

when demo, try as this: [/b]http://<your root here>/test/index.php?r=site/test1

[b]

[/b]

[b]

[/b]

As an example, consider this model:





class YourModel1 extends CActiveRecord 	{

	public $id;

	public $description;

	public $maxnormal;

	public $maxadd;


	public function rules(){

		return array(

			array('id','required'),

			array('description','required'),

			array('maxnormal','safe'),

			array('maxadd','safe'),

		);

	}

}



In your controller, put this two methods:





   	//  this will check your hand-introduced ID

      //


	public function actionAjaxTest1CheckMyId() {

		$jsondata = trim(file_get_contents('php://input'));

		$obj = CJSON::decode($jsondata);

		if (($obj['id'] == 1) || ($obj['id'] == 2) || ($obj['id'] == 3)){

			echo "OK";

		}

		else{

			throw new Exception("<h2 style='color: red;'>Sorry, this demo only accepts this values: 1,2 or 3.  (your submit button must be invisible!)</h2>");

		}

	}


        // this will perform the display of your view, and process the POST

	public function actionTest1() {


		$model = new YourModel1();

		if(isset($_POST['YourModel1'])){

			$model->attributes=$_POST['YourModel1'];

			if($model->validate())

			{

				$this->renderText("Ready to be stored!!");

				return;

			}

		}

		$this->render("test1",array('model'=>$model));

	}

in your view (in my demo: ‘test1.php’)




<div class="form" id='yourform'>

<?php $form=$this->beginWidget('CActiveForm', array(

'id'=>'roomtype-form',

'enableAjaxValidation'=>true,

)); ?>

<p class="note">Fields with <span class="required">*</span> are required.</p>

<?php echo $form->errorSummary($model); ?>

<div class="row">

<?php echo $form->labelEx($model,'id'); ?>

<?php echo $form->textField($model,'id',array('size'=>3,'id'=>'thisid'

	,'maxlength'=>3)); ?>

<?php echo $form->error($model,'id'); ?>

</div>

<div id="dupecheck"></div>

<?php echo $form->labelEx($model,'description'); ?>

<?php echo $form->textField($model,'description',array('size'=>60

	,'maxlength'=>100)); ?>

<?php echo $form->error($model,'description'); ?><br>

<?php echo $form->labelEx($model,'maxnormal'); ?>

<?php echo $form->textField($model,'maxnormal',array('size'=>10

	,'id'=>'maxnor')); ?>

<?php echo $form->error($model,'maxnormal'); ?>

<?php echo $form->labelEx($model,'maxadd'); ?>

<?php echo $form->textField($model,'maxadd',array('size'=>10)); ?>

<?php echo $form->error($model,'maxadd'); ?>


<div class="row buttons">

<?php echo CHtml::submitButton($model->isNewRecord ? 'Create' : 'Save'

,array('id'=>'submit')); ?>  <!-- ************  I ADD THIS FIELD ID MARKER:  ***********-->

</div>

<?php $this->endWidget(); ?>

</div><!-- form -->

<hr/>

<div id='response' style='font-size: 10px; color: blue;'>...</div>

<script>

    /*

        this code checks for change event on your ID field,  then validates it using the provided Ajax action,

        if its value is not:  1 or 2, or 3...then it gets and exception and HIDES the submit button.


        if all is ok, the submit button will be shown.


        ALL other things are managed in Yii's normal way.

    */

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

		var id = $(this).val();

		jQuery.ajax({

    		url: 'index.php?r=site/AjaxTest1CheckMyId',

    		type: 'post',

    		async: false,

    		contentType: "application/json",

    		data: '{ "id" : "'+id+'" }',

    		success: function(data, textStatus, jqXHR){

    				$('#response').html('ID IS OK');

    				$('#submit').show();

    			},

    		error: function(jqXHR, textStatus, errorThrown){

     				$('#response').html(jqXHR.responseText);

     				$('#submit').hide();

    			},

  		});

	});

	$('#submit').hide();

</script>

Thank you very much for the modified code. Will try it and let you know. Like I said in an earlier post, users will define their ids themselves according to their needs: they do not want auto incremented ids!! I find that an instant message after input of id gives a plus feature to the result :) Do you have any idea why the $.post does not work? I am not too used to ajax and am learning to use it now with Yii.Thanks

Blueyell, Bennouna and Amiramir

Many thanks for the suggestions. Will look into them and revert. BTW, you have any idea what is wrong with my code?

You should use Firebug to see:

[list=1]

[*]if the jQuery event really fires. My opinion: if you “thisid” is the correct id, you should maybe use ‘blur’ instead of ‘change’ event

[*]if dupecheck.php is found and called. My opinion: you are in Yii, so you’be better use a controller/action pair, especially that you intend to use CActiveRecord…

[/list]

Two things are wrong. Please review:

first, add the line .complete(function(obj) { alert("error:"+obj.responseText); })

a the final ")" of your "$.post()" call. it will display the error.

second. the referenced file "dupecheck.php" is reference to your root path: "/myproject/dupecheck.php" , exactly were the main "index.php" yii file is located.





<?php Yii::app()->getClientScript()->registerScript('checkid','$("#thisid").change(function()

{

	$.post("dupecheck.php", {thisid: $(this).val()}, function(data) {

			$("#dupecheck").html(data);

		}).complete(function(obj) { alert("error:"+obj.responseText); });

	}

);');

?>



create a file named "dupecheck.php" , and locate it AT ROOT, in same place were main index.php is located, and put this code on it.





<?php

	echo "Response from dupecheck located at root";

?>

As a resume, the basic error is produced by an invalid path when "dupecheck.php" is called via ajax, assuming a path that is located at the root of your project. Making a path correction will solve, but, is not the right way to do that. you are trying to access a file in a very very unsafe location "http://www.yoursite.com/dupeckeck.php", it will be exploited by hackers. It must be located in a safe location…but, you are breaking the Yii rules when put this file in this location.

See my code above and you can do the same BUT using Yii.

I have tried your modified code exactly as you said: it is not working :( The function is not being called (it seems) Have also tried to insert it as registerscript, but it does not work. Please help!

Bianca,

the post is not invoked because the $.post() call cant find it. Please move this file (dupecheck.php) to the root and test again.

add a error reporter on the post call, as this:

this is your original code fragment taken from your first post, and modified by me, please note the ".complete(function(obj) { alert("error:"+obj.responseText); })" add text after "$.post()" call.




<?php Yii::app()->getClientScript()->registerScript('checkid','$("#thisid").change(function()

{

$.post("dupecheck.php", {thisid: $(this).val()}, function(data) {

$("#dupecheck").html(data); }).complete(function(obj) { alert("error:"+obj.responseText); });

}

);');

?>

run it and let me know what error it reports.

Hi Bluyell,

Sorry, I forgot to say that I modified my code and you were right: it worked when I moved the dupecheck.php to the root and tested. But as you suggested I abandoned that option for reasons you mentioned. I tried your code and added the function actionAjaxCheckMyId to my controller and the script calling this function to the view file but it seems the ajax function is not being called.

There is no error message: simply nothing happens when I input a value as id. The function is not being called. It seems it has to do with the url? The function is not found…

on the same code above, put an "alert" before $.post is called: alert("called") ;

this will trace if-or-not the $.post is reached. try it.

Well item no. 1 is unneeded. ‘change’ event includes ‘blur’ and is better since ‘blur’ doesn’t know whether the input value has changed or not.

Number no. 2 is still applicable. I’ve just pasted your code in a working view of mine and it’s obvious it cannot work, because the ajax call is made to [font=“Courier New”]path/to/webapp/currentController/dupecheck.php[/font] and it returns with a [color="#FF0000"]404 (CHttpException)[/color]: The system is unable to find the requested action “dupecheck.php”.

Bianca, a friendly advice: you should use (basic) development tools like Firebug or equivalent in order to debug your code.

Bluyell,

I have discarded my code (the $.post one: I modified it according to what you suggested and the dupecheck.php was found and called when I placed it at the root) But, following your advice which was a very good one (for security reasons), I have decided to use your code (the one with actionAjaxCheckMyId) I modified the controller file to include this function and I modified the view file by adding a script there which calls for the function.) It is this one which is not working.

Thanks Bennouna. These days, I feel like giving up :-[ You suggested that I use a controller/pair action. Could it be what Bluyell is suggesting with the function actionAjaxCheckMyId found in the controller file and the script calling for this function found in the view file? I will try to use Firebug. Thanks for the advice. I think I need a coach ;)

how it works ? do you solve your issue ?

Hi Bluyell,

After a great struggle, I managed to make it work. I had to define the access rules in the controller file for the actionAjaxCheckMyId. This function was not run because by default this action was not authorized. Thanks for the suggestion, I’ll be making use of this feature very often.