初心者にもわかるCodeIgniter 其の六【Ajax通信とユーザー登録】

AJAX通信とは、簡単に言うとページ遷移しないでも新しい情報を取得したり送信できたりする機能ということです。
昔はこの機能がECサイトなんかに入っていると、他所とは違うサービスの一つとして売りにできたわけですが、それも昔。
使い勝手のいいサイトにするためには、必須のような機能なので入れていきましょうと。
この記事は最終更新日から1年以上が経過しています。

Ajax利用のための準備

説明よりも実践あるのみ。
コードを入れていきます。

assets/js/my_post.js を作成
Jsの読み込みを忘れずに

jQuery(document).ready(function($) {
	$(document).on('click','.send-post',function(){

		var data_form = $(this).attr("data-form");
		var form_target = $('#form-'+data_form);
		var str = form_target.serializeArray();
		step_2(form_target);
		
		var data_post = $(this).attr("data-post");
		if(data_post){
			var post_to = data_post;
		}else{
			var post_to = data_form;
		}
		
		var go_url = '/post/'+post_to;
		scrollMove($('.step_2'));
		
		$('.vali-item').html('');
	
		  $.ajax({
			type: 'post',
			url: go_url,
			dataType:'json',
			timeout: 10000,
			data: {
				'str': str
			},
		
			success: function(data) {
				if(data[0] =="OUT"){
					step_1(form_target);
					errorValidation(form_target,data[1]);
				}else{
					step_3(form_target);
					scrollMove($('.step_3', form_target));
					form_target.removeClass('confirm');
					form_target.addClass('sended');
				}
			},
			error: function(data) {
			   alert('送信失敗');
			}
	  });
	});
	
	function errorValidation(form_target,errors){
		form_target.find('.vali-main').removeClass('vali-error');

		var vali2 = '';
		j = 0;
		$.each(errors, function(i, value) {
			var vali = '<div class="return_vali vali_error"><i class="fa fa-exclamation-triangle"></i>'+value+'</div>';
			vali2 += '<li>'+value+'</li>';
			form_target.find('.vali-'+i).html(vali);

			//先頭のエラーに移動
			if( j == 0){
				scrollMove(form_target.find('.vali-'+i));
			}
			j++;
		});
		form_target.find('.all_vali').html(vali2);
	}
	
	function scrollMove(tg){
		var position = tg.offset().top - 150;
		$("html, body").animate({scrollTop:position}, "fast");
	}
			
	function step_1(tg){
		tg.find('.step_1').css('display','block');
		tg.find('.step_2').css('display','none');
		tg.find('.step_3').css('display','none');
	}
	function step_2(tg){
		tg.find('.step_1').css('display','none');
		tg.find('.step_2').css('display','block');
		tg.find('.step_3').css('display','none');
	}
	function step_3(tg){
		tg.find('.step_1').css('display','none');
		tg.find('.step_2').css('display','none');
		tg.find('.step_3').css('display','block');
	}
});

assets/css/style.css を作成
Cssの読み込みを忘れずに

@charset "utf-8";
header{padding: 60px 0 0;}
.fa{margin-right: 5px;}
.vali_error {
    color: #ff0000;
    margin-top: 5px;
}
.step_2, .step_3 {
    display: none;
}

application/views/index.php にフォームを追加

<form class="form-horizontal" id="form-regist">
<fieldset>
<legend>登録フォーム</legend>
	<div class="step_1">
		<div class="form-group">
			<label for="inputEmail" class="col-lg-2 control-label">Name</label>
			<div class="col-lg-10">
				<input class="form-control" name="name" id="inputName" placeholder="Name" type="text">
				<div class="vali-item vali-name"></div>
			</div>
		</div>
		<div class="form-group">
			<label for="inputEmail" class="col-lg-2 control-label">Email</label>
			<div class="col-lg-10">
				<input class="form-control" name="mail" id="inputEmail" placeholder="Email" type="text">
				<div class="vali-item vali-mail"></div>
			</div>
		</div>
		<div class="form-group">
			<label for="inputEmail" class="col-lg-2 control-label">Password</label>
			<div class="col-lg-10">
				<input class="form-control" name="password" id="inputPassword" placeholder="Password" type="password">
				<div class="vali-item vali-password"></div>
			</div>
		</div>
		
		<div class="form-group">
			<div class="col-lg-10 col-lg-offset-2">
				<button type="button" class="btn btn-primary send-post" data-form="regist">送信</button>
			</div>
		</div>
	</div>
	<div class="step_2">
		<h3 class="text-center"><i class="fa fa-spinner fa-pulse"></i>データ送信中</h3>
	</div>
	<div class="step_3">
		<h3 class="text-center">送信完了</h3>
	</div>
</fieldset>
</form>

これで送信側の処理は完了です。
どういう流れで送信されるのかは、見てもらえばなんとなくわかると思います。

PHP側の処理について

jsの記述を見てもらうと分かる通り、POSTデータはシリアライズ化しています。
これは、formで囲まれた内容を全て送信するものであり、とても便利です。
しかし、一塊になってこのままでは処理できないデータ型になるので、PHPの方でひと工夫が必要になります。

というわけで、POSTデータの処理をライブラリ化。
application/libraries/Lib.php に以下を追加

//バリデーション専用処理
public function postVali($post, $vali_type){

	$this->ci->form_validation->reset_validation();
	$_POST = $post;
	if ($this->ci->form_validation->run($vali_type) == FALSE){
		$error = $this->ci->form_validation->error_array();
		$html =array("OUT",$error);
		header('Content-type: application/json');
		echo json_encode($html);
		exit;
	}
	return NULL;
}

//Ajax用POSTデータの変換
public function makePost($json) {
	$data = array();
	foreach($json as $v1) {
		if(strpos($v1["name"],'[]') !== false){
			$key = str_replace('[]', '', $v1["name"]);
			$data[$key][] = $v1['value'];
		}else{
			$key = $v1["name"];
			$data[$key] = $v1['value'];
		}
		
	}
	return $data;
}
		
//パスワードの暗号化
public function getPassword($pass){
	$password = password_hash($pass, PASSWORD_BCRYPT, ['cost' => 12]);
	return $password;

}	

続いて、データ受信側での処理を一通り。
application/controllers/Post.php を編集

public function regist(){
	if($this->input->post()){
		
		$json = $this->input->post("str");
		$post = $this->lib->makePost($json);
		$this->lib->postVali($post, 'regist');

		$temp_pass = $post['password'];
		$post['password'] = password_hash($temp_pass, PASSWORD_BCRYPT, ['cost' => 12]);
		$user_id = $this->All->Insert('user', $post);

		$html =array('OK',NULL);
		header('Content-type: application/json');
		echo json_encode($html);
	}
	exit;
}

◆注目
バリデーションの処理を抜けたところにユーザーの登録処理が入っています。

$this->All->Insert('user', $post);

の部分ですね。
その直前にパスワードの暗号化処理を入れてあります。
こうしてみると、ものすごく単純化できているんじゃないかと思います。

あまり詳しい説明はしませんが、ライブラリとの連携、JSの記述を確認すれば、流れがわかるかと思います。
以上です。

以下の参考ページでユーザー登録ができるので、遊びまでに操作してみて下さい。
参考ページ:http://sample.xn--pbku02iq0izkz.net/

ブログ運営

株式会社ちょもらんま

https://qomolangma.jp