Why AJAX does not change field's value? I wrote simple code:

function rah_cc_generate_form($form,$form_state){
    $form=array();

    $form['gen']=array(
        '#type' =&gt; 'fieldset',
        '#name' =&gt;t('generate gift card code'),
        '#collapsible' =&gt; TRUE,
        '#collapsed' =&gt; false,
//        '#weight' =&gt; 5,

    );
    $form['gen']['code']=array(
            '#type' =&gt; 'textfield',
            '#title' =&gt; t('gift code'),
            //'#default_value' =&gt; '',
            '#prefix' =&gt; '&lt;div id="gc-code"&gt;',
            '#suffix' =&gt; '&lt;/div&gt;',
            '#size' =&gt; variable_get('rah_gc_code_size', 8),
            '#maxlength' =&gt; 20,
            //'#required' =&gt; TRUE,
    );
    $form['gen']['price']=array(
            '#type' =&gt; 'textfield',
            '#title' =&gt; t('price'),
            '#default_value' =&gt; 10000,
            '#size' =&gt; 10,
            '#maxlength' =&gt; 20,
            '#required' =&gt; TRUE,
    );

    $form['gen']['random']=array(
     '#type' =&gt; 'submit',
    '#value' =&gt; t('generate'),
    '#description' =&gt; t("if you want generate random use this plz"),
    //'#weight' =&gt; 1,
    //'#submit' =&gt; array('rah_cc_generate_random'), // If no javascript action.
    '#ajax' =&gt; array(
      'callback' =&gt; 'rah_cc_generate_ajax',
      'wrapper' =&gt; 'gc-code',
      'method' =&gt; 'replace',
      'effect' =&gt; 'fade',
      ),
   );


    $form['gen']['save']=array(
        '#type' =&gt; 'submit',
        '#value' =&gt;t('save'),
         );

    return $form;


}
function rah_cc_generate_ajax(&amp;$form,&amp;$form_state){

    $form['gen']['code']['#value']=33;
  return $form['gen']['code'];

}


but it doesn't work: textfield is not replaced by the one that has value 33.

There is no JS error and AJAX request returns HTTP code 200.
There are several problems with your code:


Your AJAX callback should return a form element. Now it returns plain 33.
All changes should be made inside form building function, in your case rah_cc_generate_form. Simply add condition to test $form_state['triggering_element'] and perform action if it was your AJAX trigger. Do not alter things in AJAX handler, it's not what it is for. I know it's counter-intuitive, but that's the way it is.
Changing default value once there is some user input will have no effect. Maybe you should try to change appropriate entry in $form_state['input']? But that depends on your intentions.