I am trying to implement a search module by using AJAX.
There is an index.ctp file in my Items Controller and I have linked my index.ctp file of Items to my search.ctp file which is present under Pages controller as below:
<li><?= $this->Html->link(__('Search Products'),['controller'=>'Pages','action' => 'search']) ?></li>
For the search.ctp pages the URL displayed is :
http://onlineelectronic.com/pages/search
In my search.ctp file the code is as follows:
<head>
<title> Search Results</title>
<?php echo $this->Html->script('//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js', array('inline' => false));?>
<script type="text/javascript">
$(document).ready(function() {
$("#Submit1").click(function () {
$.ajax({
type: 'post',
url: '/Items/searchData",
data: {
name: "search"
},
beforeSend: function(){
$("#resultField").html("Loading...");
},
success: function(response) {
jQuery('#resultField').val(response);
},
error: function(response, error) {
alert("Search :Error"+response.error());
},
dataType: 'json',
global: false
});
return false;
});
});
</script>
</head>
<div>
<?= $this->Form->create() ?>
<fieldset>
<legend><?= __('Search Item') ?></legend>
<?php
echo $this->Form->input('search',['label'=>'Search']);
?>
</fieldset>
<?= $this->Form->button('Search Items',['label'=>'Submit1']); ?>
<?= $this->Form->end() ?>
</div>
<div id="resultField">
</div>
In my ItemsContoller page the searchData method is implemented like this:
class ItemsController extends AppController
{
public $helpers = ['Form', 'Html', 'Time'];
public function initialize()
{
parent::initialize();
$this->loadComponent('RequestHandler');
}
public function search(){
//dummy
}
/**
*obtains search result for a given string.
*/
public function searchData()
{
$this->layout = 'ajax';
echo "here";
$search_data=[];
var_dump($search_data);
//$search_results = [];
if ($this->request->is('post')) {
$search_data= $this->request->data;
$search_data=implode("|",$search_data);
$search_results = $this->Items->find('all', array('conditions'=>array('Items.itemName LIKE'=>"%$search_data%")));
if(!empty($search_results)) {
$this->set(compact($search_results));
$this->set('_serialize',array('search_results'));
return json_encode($search_results);
}
}
}
public function beforeFilter(Event $event)
{
parent::beforeFilter($event);
$this->Auth->allow(['index', 'view','search','searchData']);
}
}
My issue is that the SearchData method is not being called and I am not getting any javascript errors also.How do i make sure that the method gets called on pressed after pressing the button.Is it due to the url in json?
I see 2 possible problems. First in ItemsController, you have to allow searchData method
// change this line
$this->Auth->allow(['index', 'view','search']);
// to this
$this->Auth->allow(['index', 'view','searchData']);
also make sure, that you have proper jQuery selector
// try to change this line
<?= $this->Form->button('Search Items',['label'=>'Submit1']); ?>
// to this
<?= $this->Form->button('Search Items',['id'=>'Submit1']); ?>
Edit: make more corrections to javascript:
Data passed with ajax should be double quoted
data: {
name: "search"
},
add return false; to the end of click handler, so you prevent submiting form and reloading page
Also note that you must have template for searchData in Template/Items/search_data.ctp
Related
I am trying to save to a database in yii2 using ajax but I am getting errors. I just want to insert the value or rate which is "up" into the database and I don't want to use a form, just on-click of a button.
This is my controller
public function actionThumbs()
{
$thumbs = new Thumbs;
$thumbs->user = Yii::$app->user->identity->email;
$thumbs->topic_id = Yii::$app->getRequest()->getQueryParam('id');
$thumbs->rate = $_POST["rate"];
if ($thumbs->load(Yii::$app->request->post()) ) {
$thumbs->load($_POST);
$thumbs->save();
return $this->redirect(['blog', 'id' => Yii::$app->getRequest()->getQueryParam('id')]);
}
return $this->redirect(['blog','id' => Yii::$app->getRequest()->getQueryParam('id')]);
}
This is my this is my ajax file
$("#mys").click(function() {
var rate = "up";
$.ajax({
type: 'POST',
url: 'vot/frontend/web/index.php?r=site%2Fthumbs',
data: 'rate='+rate,
success: function (rate) {
alert("test");
},
error: function (exception) {
alert(exception);
}
});
});
the view
<div>
<?= Html::Button('ups', ['class' => 'btn btn-primary', 'name' => 'mys' ,'id'=>'mys']) ?>
</div>
I get this alert error
The page at localhost says":
"[object Object]"
By default Yii2 controller doesn't accept POST request without _csrf protection, so there are 2 ways here:
1 - disable csrf:
public function actionThumbs() {
$this->enableCsrfValidation = false;
//your code here
}
2 - Send post request via ajax with _csrf token:
In your layout/main.php file, put this: <?= Html::csrfMetaTags() ?>
Before your "ajax" code, call this:
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="_token"]').attr('content')
}
});
//Your ajax code here
Ajax Auto-complete search with Code-igniter from my database. I am trying to search my database and Ajax completes the search from items saved on my database. I believe I am missing a simple trick. Maybe I am writing my controller or maybe everything all wrong... Code below
// View Page
Location path: application/views/template/header
<form class="navbar-form" >
<input type="text" id="mysearch" placeholder="search" onkeyup="doSearch();">
<br />
<script>
// This is the jQuery Ajax call
function doSearch()
{
$.ajax({
type: "GET",
url:"localhost/codeigniter/index.php/ajax/getdata/" + $("#mysearch").val(),
success:function(result){
$("#searchresults").html(result);
}});
}
//class example
</script>
Note: My form or search box is inside my header... So my view page is located in template/header
// Controller Page
Location path: codeigniter/application/controller/ajax.php
class Ajax extends CI_Controller
{
public function __construct()
{
parent::__construct();
$this->load->model('ajax_model');
//$this->load->helper('url_helper');
}
public function form ()
{
$data['title'] = 'Ajax search';
$this->load->view('template/header');
}
// function ends
public function getdata($param = '')
{
// Get data from db
$data['ajaxdata'] = $this->ajax_model->search($param);
// Pass data to view
$this->load->view('template/header', $data);
}
}
?>
// My Model
Location path: application/model/Ajax_model.php
<?php if (! defined('BASEPATH')) exit('No direct script access');
class Ajax_model extends CI_Model
{
public function __construct()
{
$this->load->database();
}
public function search ($title){
$this->db->select('title');
$this->db->select('text');
$this->db->like('title', $title, 'both');
return $this->db->get('news');
}
}
?>
Please be aware I am new to CodeIgniter. It explains my rather obvious ignorance
$data['ajaxdata'] = $this->ajax_model->search($param);
$data['ajaxdata'] = json_encode($data['ajaxdata']);
echo $data['ajaxdata'];
Ajax method expects data in form of (JSON) string. So you don't need to load header again. Instead, just pass needed data from DB and jQuery will put it in designated place. In this case into element with id of searchresults.
Try changing this
$this->load->view('template/header', $data);
to
$content = $this->load->view('template/header', $data,TRUE);
// load view to a variable.
echo $content;
if i am clear what you need try:
first define ajax request type:
function doSearch()
{
$.ajax({
type: "GET",
dataType:"html",
url:"localhost/codeigniter/index.php/ajax/getdata/" + $("#mysearch").val(),
success:function(result){
$("#searchresults").html(result);
}});
}
Then in controller :
just echo your view:
$auto_complete_html = $this->load->view('template/header', $data,TRUE);
echo $auto_complete_html;
//good practice always die(); after ajax called
die();
Try using POST in AJAX instead of GET:
<script>
// This is the jQuery Ajax call
function doSearch()
{
var search = $("#mysearch").val()
$.ajax({
type: "POST",
url:"localhost/codeigniter/ajax/getdata/",
data:'search=' + search,
success:function(data){
$("#searchresults").html(data);
}});
}
//class example
</script>
Then in your controller Get THE POSTED data from AJAX
public function getdata()
{
$param= $this->input->post('search');
// Get data from db
$result = $this->ajax_model->search($param);
// Pass data to view
echo $result;
}
I am new to codeigniter ajax and i have a problem with sessions.My sessions are not being set and unset
asynchronously and i have to refresh the page just to see the changes.
view/header:
<?php
if(!empty($product)){
$pid=$product[0]['product_id'];
}
?>
<script>
$(document).ready(function(){
if($('.add_to_basket').find('img')){
$('.add_to_basket').click(function(){
var message=$('#badgemessage');
$('#msgcart').append(message);
message.show('slow');
var trigger=$(this);
var param=trigger.attr("rel");
var item=param.split("_");
$.ajax({
type: 'POST',
url: '<?= base_url()."cart_c/myfunk/".$pid?>',
data: { id: item[0], job: item[1] },
dataType:'json',
success: function(data) {
console.log(data);
},
error:function(){
alert("error");
}
});
return false;
});
}
});
</script>
model/basket_model:
<?php
class Basket_model extends CI_Model{
function activeButton($sess_id){
$e=$this->session->userdata('basket');
if(isset($e[$sess_id])){
$id=0;
$label="<img src='".base_url()."images/remove.png' />";
}else{
$id=1;
$label="<img src='".base_url()."images/add.png' />";
}
$out="<a href='#' class='add_to_basket' rel='".$sess_id."_".$id."'>".$label."</a>";
return $out;
}
function setItem($pide,$qty=1){
$e=$this->session->userdata('basket');
if(isset($e)){
$e[$pide]['qty']=$qty;
$this->session->set_userdata('basket',$e);
}else{
$arr=array($pide=>array('qty'=>$qty));
$this->session->set_userdata('basket',$arr);
}
}
function removeItem($pide,$qty=null){
$e= $this->session->userdata('basket');
if($qty != null && $qty < $e[$pide]['qty']){
$e[$pide]['qty']=($e[$pide]['qty']-$qty);
$this->session->set_userdata('basket',$e);
}else{
$e[$pide]=null;
unset($e[$pide]);
$this->session->set_userdata('basket',$e);
}
}
}
?>
controller/cart_c:
<?php
class Cart_c extends CI_Controller{
function __construct(){
parent::__construct();
$this->load->model('catalogue_model');
$this->load->model('products_model');
$this->load->model('basket_model');
}
function myfunk($id){
if(isset($_POST['id']) && isset($_POST['job']))
$out=array();
$pid=$_POST['id'];
$job=$_POST['job'];
if(!empty($id)){
switch($job){
case 0:
$this->basket_model->removeItem($pid);
$out['job']=1;
break;
case 1:
$this->basket_model->setItem($pid);
$out['job']=0;
break;
}
echo json_encode($out);
}
}
}
?>
controller/products:
<?php
class Products extends CI_Controller{
function __construct(){
parent::__construct();
$this->load->model('catalogue_model');
$this->load->model('products_model');
$this->load->model('basket_model');
}
function product($id){
$kitties['cats']=$this->catalogue_model->get_categories();
$data['product']=$this->products_model->get_product($id);
$data['active_button']=$this->basket_model->activeButton($id);
$this->load->view('header',$data);
$this->load->view('sidebar',$kitties);
$this->load->view('product',$data);
$this->load->view('footer');
}
}
?>
view/product:
<div class="contentwrap">
<div id="content_area">
<?php
$e=$this->session->userdata('basket');
print_r($e);
if(!empty($product)){
foreach($product as $p){
?>
<h1><?=$p['product_name']?></h1>
<div id="product_image">
<img src="<?=base_url()?>/images/<?=$p['image']?>" width="400" height="300" />
</div>
<div id="product_desc">
<?=$p['description']?>
<br><br>
<?=$active_button?>
</div>
<?php
}
}else{
echo "Product unavailable";
}?>
</div>
</div>
The problem is my $active_button in the product view is not changing asynchronously but the sessions are being set and unset
i can see items being pushed into and out of the session array when i refresh the page.When i hit the button my chrome console displays: object{job:0}
ok after looking and studying youre code. you can implement what you want by retrieving the button again when making your AJAX call. The way to retrieve it is by calling that model again, then using jquery to replace the current button. Try the following:
Controller - Cart_c
function myfunk($id) {
if (isset($_POST['id']) && isset($_POST['job'])) {
$out = array();
$pid = $_POST['id'];
$job = $_POST['job'];
if (!empty($id)) {
switch ($job) {
case 0:
$this->basket_model->removeItem($pid);
$out['active_button'] = $this->basket_model->activeButton($pid);
break;
case 1:
$this->basket_model->setItem($pid);
$out['active_button'] = $this->basket_model->activeButton($pid);
break;
}
echo json_encode($out);
}
}
}
JS in header view:
<script>
$(document).ready(function() {
function add_to_basket($this) {
var param = $this.attr("rel");
var item = param.split("_");
$.ajax({
type: 'POST',
url: '<?= base_url() . "cart_c/myfunk/" . $pid ?>',
data: {id: item[0], job: item[1]},
dataType: 'json',
success: function(data) {
console.log(data);
$this.replaceWith(data.active_button);
$('.add_to_basket').click(function() {
add_to_basket($(this));
});
},
error: function() {
alert("error");
}
});
return false;
}
$('.add_to_basket').click(function() {
add_to_basket($(this));
});
});
</script>
Ok I think perhaps we should start by discussing the proper flow of your app. Assuming that your URL looks something like this Products/product/10 and you intially load the page, your function runs providing you with right button and products as expected.. Lets say in this case product 10 does not exist in the session/cart so you see the ADD image button come up.. All good.. Now, when you click add, and from what you are saying, it adds the product to the session/cart, and you get a return JSON of ‘job:0’. So far it works as expected from the code I am seeing. A return of job:0 means that you ran the setItem function. Now the problem you are saying is that the view “is not changing asynchronously”. By this, do you mean that you expect the page to reload and run the function again so that the image can now say “remove”?
Hey I'm new to CI and have scoured the internet for a tutorial that will work but for some reason it won't work. Can someone help me with the code please:
What's the right edit to the code to submit an entry to the database via ajax without reloading the page?
Controller:
public function index(){
$this->load->helper('url');
$this->load->view('template');
}
function create()
{
$this->load->library('form_validation');
$this->load->helper('form');
$this->load->model('dbmodel');
$response = array();
$this->load->model('dbmodel');
$result = $this->dbmodel->addnew_row();
}
Model:
public function addnew_row() {
$data = array(
'title' => $this->input->post('title'),
'description' => $this->input->post('description'),
);
$result = $this->db->insert('books', $data);
return $result;
}
View Form:
<h2>Create</h2>
<?php echo form_open('welcome/create', array('id'=>'form'));?>
<p>Title: <?php echo form_input('title') ?></p>
<p>Description: <?php echo form_input('description') ?></p>
<?php echo form_submit('btn_submit','Save'); ?>
<?php echo form_close();?>
View AJAX:
// $.POST Example Request
$('#form').submit(function(eve){
eve.preventDefault();
var title = $('#title').val();
var description = $('#description').val();
url = '<?php echo site_url('welcome/create');?>'
$.ajax({
url: url,
type: 'POST',
data:{title:title, description:description
}
$(#dynamic_container).html(response.output);
});
});
Ok,At first you need to briefly go through the syntax of jQuery.ajax() before using it.
Now going though the AJAX code you mentioned in the question , this block of code is not suppose to be there
$(#dynamic_container).html(response.output);
AJAX provides Callback Function Queues to manipulate response before/after an AJAX call has been successfully completed , and in your case using success will resolve the issue :
$.ajax({
url: url,
type: 'POST',
data:{title:title, description:description
},
success : function(response){
$(#dynamic_container).html(response.output);
}
});
And you might be interested in using jQuery.post().
What wants to be achieved ?
On-change the selection of a Select list, this selectedIndex is picked up by the controller, sent to the model the SQL query and results are returned via ajax underneath the select list. That is very easy to do in an ordinary php environment, but I am puzzled within the Laravel environment.
If it is not clear: what I want is to have this: http://www.w3schools.com/php/php_ajax_database.asp done in a Laravel environment
UPDATED: I have improven the code using the indications of Itachi:
This would be if I could use simple Ajax, but was adviced to use JQUERY/JSON instead, dont know why this would not work.
<script>
function showHint(str)
{
if (str.length==0)
{
document.getElementById("txtHint").innerHTML="";
return;
}
var xmlhttp=new XMLHttpRequest();
xmlhttp.onreadystatechange=function()
{
if (xmlhttp.readyState==4 && xmlhttp.status==200)
{
document.getElementById("txtHint").innerHTML=xmlhttp.responseText;
}
}
xmlhttp.open("GET","gethint.php?q="+str,true);
xmlhttp.send();
}
</script>
And then the PHP get stuff etc, would be easy.
So, the JQUERY/JSON would go more or less like this, though I dont know how to complete it
$('#ajax').submit(function(e){
$.ajax({
url: '<?php echo route("hint");?>',
type: 'POST',
data: { especialidades: $('especialidades').val() },
dataType: 'json',
success: THIS WOULD BE A FUNCTION THAT WOULD PRINT THE RESULTS FROM THE CONTROLLER
}
});
e.preventDefault();
});
And my own form looks like this:
<form role="form" class="bg-success" id="ajax">
<div class="form-group">
<select name ="especialidades" id = "especialidades" class="form-control" onchange="showHint(this.value)">
<?php foreach($data['kategori'] as $detalle): ?>
<option value="<?php echo $detalle->id_specialty; ?>"><?php echo $detalle->spec_description; ?></option>
<?php endforeach;?>
</select>
</div>
</form>
<div id="txtHint"><b>Person info will be listed here.</b></div>
And the controller should look like this:
class Hint extends BaseController{
public $restful = true;
public function post_appajax()
{
NEED TO GET THE SELECTED INDEX SENT BY THE JQUERY SCRIPT IN THE VIEW: HOW??
SOMETHING EQUAL TO THIS ===> ::json(Input::get('especialidades'));
}
}
AND THE ROUTE FILE GOES LIKE THIS: (by Itachi)
Route::post('hint', array(
'as' => 'hint',
'uses' => 'Hint#getHint'
));
it is actually very simple.
Routes.php
Route::post('hint', array(
'as' => 'hint',
'uses' => 'HintController#getHint'
));
HintController.php
class HintController extends BaseController {
public function getHint()
{
return Response::json(//whatever you want);
}
}
View
$.ajax({
url: '<?php echo route("hint");?>', //<-------- see this
type: 'POST',
data: { especialidades: $('especialidades').val() },
dataType: 'json',
success: SEND IT TO THE CONTROLER HOWEVER YOU CAN...
}
});
Rest will be upto you.
According to the method name in your controller the route should be (Laravel-3:RESTfull controller)
Route::post('hint', array( 'as' => 'hint', 'uses' => 'Hint#appajax'));
Your Controller
class Hint extends BaseController{
public $restful = true;
public function post_appajax()
{
// ...
}
}