I have manage to get autocomplete data with typeahead search tutorial where I change in a way that now searching by three columns instead of one. So, when I start typing in search field autocomplete display:
Street from-to
and based on that I supposed to display other data from that ID (ID of that row but ID is not displayed).
You can see how it looks in my controller:
public function ajaxData(Request $request)
{
$query = $request->get('query', '');
$streets = Street::select('id', 'name')
->where('name', 'LIKE', '%'.$query.'%')
->get();
$results = array();
foreach($streets as $sn) {
$street_numbers = StreetNumber::select('from', 'to')
->where('town_id', Auth::user()->town_id)
->where('street_id', $sn->id)
->get();
foreach($street_numbers as $st) {
$data = array(
'name' => $sn->name." ".$st->from."-".$st->to
);
$results[] = $data;
}
}
return response()->json($results);
}
In view I supposed to select from autocomplete and when I click on submit it should display data like town, settlement etc...
But, if I try to use $street_numbers variable it shows me error:
(2/2) ErrorException
Undefined variable: street_numbers
In view beside field I have JQuery from typeahed tutorial:
{!! Form::open(['route'=>'add.index', 'method'=>'GET']) !!}
<div class="col-sm-12">
<div class="panel panel-default">
<div class="panel-heading">Search</div>
<div class="panel-body">
<div class="input-group">
{!! Form::text('search_text', null, array('placeholder' => 'Street from - to','class' => 'form-control','id'=>'search_text')) !!}
<span class="input-group-btn">
{!! Form::button('<i class="fa fa-search"></i>', ['type' => 'submit', 'class'=>'btn btn-default']) !!}
</span>
</div>
</div>
</div>
</div>
{!! Form::close() !!}
<script type="text/javascript">
var url = "{{ route('autocomplete.ajax') }}";
$('#search_text').typeahead({
source: function (query, process) {
return $.get(url, { query: query }, function (data) {
return process(data);
});
}
});
</script>
I'm very stuck on this one and don't know how to start from here because in JS or JQuery I'm a beginner.
Before ajaxData() function I have index() function and there I have:
return view('members.index', compact('towns', 'user', 'activist', 'capillary'));
So there is my view.
I'm trying to use $street_numbers variable in view like this:
<div class="col-sm-6">
<div class="form-group">
{!! Form::label('', 'Settlement') !!}
{!! Form::select('', [$street_numbers? $street_numbers->settlement->name : null => $street_numbers? $street_numbers->settlement->name : null], null, ['class'=>'form-control', 'readonly']) !!}
</div>
</div>
I succeeded and I want to share with others in case somebody needs it:
In submit button I placed 'id'=>'get_cust_data' and then I made separate .js file where I pull information from autocomplete search field when it's submitted.
JS:
$(document).ready(function(){
$('#get_cust_data').click(function(){
var st = $.trim($("#search_text").val());
get_cust_data(st);
});
});
In controller I get data with explode function because, as I said in first post I have street-from-to from database, not just one data. In further codes you will see how I get ID from street and then object which I use to get other info from same row like settlement, electorUnit and so...
public function get_cust_data(Request $reques)
{
$arr = explode("-", $reques->st);
$street = $arr[0];
$from = $arr[1];
$to = $arr[2];
// Street ID
$street_id = Street::select('id')
->where('name', $street)
->first()->id;
// Object
$street_data = StreetNumber::select('*')
->where('street_id',$street_id)
->where('from', $from)
->where('to', $to)
->get();
$result = array();
// Settlement ID
$settlement_id = $street_data[0]->settlement_id;
$result['settlement_id'] = $settlement_id;
// Settlement Name
$settl_data = Settlement::select('name')
->where('id',$settlement_id)
->get();
// ElectoralUnit ID
$electoral_unit_id = $street_data[0]->electoral_unit_id;
$result['electoral_unit_id'] = $electoral_unit_id;
// ElectoralUnit Name
$el_unit_data = ElectoralUnit::select('name')
->where('id',$electoral_unit_id)
->get();
// ElectoralUnitNumber
$el_unit_number_data = ElectoralUnit::select('electoral_unit_number')
->where('id',$electoral_unit_id)
->get();
$result['s_name'] = $settl_data[0]->name;
$result['e_name'] = $el_unit_data[0]->name;
$result['e_n_name'] = $el_unit_number_data[0]->electoral_unit_number;
$result['street'] = $street;
$result['str_id'] = $street_id;
return response()->json(json_encode($result));
}
Then in the sam JS file, which is connected in header to view, I put another function that I googled and can't explain completely how it works, but that function forwarding variables from controller through view with fields ID-s like this:
function get_cust_data(street_data){
var method_url= "/get_cust_data";
$.ajax({
type: "POST",
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
url: method_url,
cache: false,
data:{ st:street_data},
async: true,
success: function(response){
var data = JSON.parse(response);
// console.log(data.id);
$('#street').append("<option value='"+data.street+"'>"+data.street+"</option>");
$('#settlement_id').append("<option value="+data.settlement_id+">"+data.s_name+"</option>");
$('#electoral_unit').append("<option value='"+data.e_name+"'>"+data.e_name+"</option>");
$('#electoral_unit_number').append("<option value="+data.electoral_unit_id+">"+data.e_n_name+"</option>");
// console.log(data.message);
}, error: function (xhr, ajaxOptions, thrownError) {
alert(xhr.status);
alert(thrownError);
}
});
}
I hope that at least I explained a bit and will help somebody. Cheers!
Related
This is my first question here so apologies for any logic errors, etc. I'm working on budget manager webapp, allowing the user to save his incomes and expenses data. Here specifically is an area for the user to create a custom category for either of those two. I'm trying to validate input data before submitting it, using ajax and php, the function is not working however. My aim was to check whether the category already exists in database. Please find my code below:
options.html
<div class="row gap-2 mt-3 mx-3" id="addCategory">
<button class="btn btn-success" onclick="addCategoryHandler('income')"
id="addIncomeCategory">Add new category</button>
</div>
<form id="editForm" action="javascript:addCategory()">
<label id="cattegoryNameLabel" for="categoryName">Category Name</label>
<input class="form-control inputBox errorCategory" type="text" id="categoryName" name="categoryName" aria-label="Nazwa kategorii"
aria-describedby="cattegoryNameLabel">
</form>
jquery validation:
$(document).ready(function() {
$('#editForm').validate({
rules: {
categoryName: {
required: true,
minlength: 3,
maxlength: 20,
categoryRegex: true,
remote: '/settings/validate-category'
},
},
});
After pressing the button the code is being handled via Javascript and then an according modal is being displayed:
settings.js
function addCategoryHandler(newCategoryType) {
categoryType = newCategoryType;
//Set proper modal title
$('#editModalLabel').text(addCategoryModalTitle);
//Reset category name & limit input
$('#categoryName').val('');
$('#limit').val(parseFloat(0).toFixed(2));
$('#limitCheck').prop( "checked", false );
//Set proper button function
$('#editForm').attr('action', "javascript:addCategory()");
switchLimitForm();
$('#editModal').modal('show');
}
function addCategory() {
categoryName = $('#categoryName').val();
categoryLimit = $('#limit').val();
categoryLimitState = $('#limitCheck').is(':checked');
$.ajax({
type: 'POST',
url: '/settings/addCategory',
dataType: 'json',
data: {
postCategoryType: categoryType,
postCategoryName: categoryName,
postCategoryLimitState: categoryLimitState,
postCategoryLimit: categoryLimit
},
success: function(result) {
addCategoryRow(categoryName, result);
},
error: function(xhr){
console.log(xhr);
}
});
}
The data is later passed to the controller, Settings.php:
public function validateCategoryAction()
{
$isEqual = ! $this->validateNewIncomeCategory($_GET['categoryName'], $_GET['ignore_id'] ?? null);
header('Content-Type: application/json');
echo json_encode($isEqual);
}
public function validateNewIncomeCategoryAction($name, $ignore_id = null)
{
$categories = Finance::getUserIncomeCategories();
$name = 'Inne';
if($categories)
{
$isEqual = true;
foreach ($categories as $category)
{
if (strtolower($category['name']) == strtolower($name)) {
$isEqual = false;
}
}
return $isEqual;
}
}
Database is being checked in the model, Finance.php:
public static function getUserIncomeCategories()
{
$db = static::getDB();
$query = $db->prepare('SELECT id, name FROM incomes_category_assigned_to_users WHERE user_id = :user_id');
$query->bindValue(':user_id', $_SESSION['user_id'], PDO::PARAM_INT);
$query->execute();
return $query->fetchAll();
}
My biggest concern for now is that the categoryName is not being passed to the Controller (as the form has not been submitted yet). The validation process on server side is fine but I want to set it for client's side as well. I was thinking about passing the data using Cookies, I do not know how to do it properly however. Also, sorry for such a long post, there are just lots of things going on here and it's been bugging me for a while. I'd appreciate any help.
Controller:
public function index()
{
.
.
.
$search_result = $this->m_results->search_people(array('country'=>$country,'state'=>$state,'city'=>$city,'sort'=>$this->sort,'id'=>$data['id']),$keyword,$s_id);
$this->load->view('include/header',$data);
if($search_result != FALSE)
{
$data['results']['freelancers'] = $search_result;
// print_r($data['results']['freelancers']); exit();
$data['sort_value'] = $this->sort;
$this->load->view('search',$data);
}else{
$data['string'] = $this->input->post('keyword');
$this->load->view('search_empty',$data);
}
$this->load->view('include/footer',$data);
}
Ajax function:
$("body").on("change", "#sort", function () {
$.ajax({
method: "get"
, url: base_url + "search"
// , cache: false
, data: {
skills: $("#inputtags").val()
, sort: $("#sort").val()
, city: $("#locationTextField").val()
}
, success: function (data) {
// console.log(data);
alert(data);
$("body").html(data);
}
})
});
View:
<div class="form-group sidemargin">
<select name="sort" id="sort" class="form-control select color2 bold">
<option value="rating" <?php echo set_select('sort','rating',( $sort_value == "rating" ? TRUE : FALSE )); ?>>Ratings</option>
<option value="review_count" <?php echo set_select('sort','review_count',( $sort_value == "review_count" ? TRUE : FALSE )); ?>>Reviews</option>
</select>
</div>
Above are the code I'm using for display the results after sorting by Ajax. But now the problem is after sorting the result, when I alert the success data its coming the entire html code but not the result from database.
I can't understand why its showing the html code instead of the sorted data from db. When I try to print_r() those result in controller, its showing correct value. When it come to Ajax success the values are different.
So folks help me to solve this. Answers will are appreciated. Thanks in advance.
I have a problem using bootstrap modal for updating data.
On CGridView selectionChanged, it will trigger a function to show modal dialog form and insert the data to the form
Here is my CGridView :
<?php
$this->widget('customCGridView', array(
'id'=>'contactperson-grid',
'itemsCssClass' => 'table table-bordered',
'selectionChanged'=>'showmodal',
'dataProvider' => $contactperson->search(),
'emptyText' => '',
'enableSorting' => false,
'htmlOptions' => array('class' => ' '),
'columns' => array('nama', 'jabatan')
));
?>
On selectionChanged, it will trigger this script to open the update dialog modal and fill the form with selected CGridView column data :
function showmodal(grid_id) {
var keyId = $.fn.yiiGridView.getSelection(grid_id);
keyId = keyId[0]; //above function returns an array with single item, so get the value of the first item
$.ajax({
url: '<?php echo $this->createUrl("suppliertable/personview"); ?>',
data: {id: keyId},
type: 'GET',
success: function(data) {
$("#contact-person-modal").html(data);
$('#kontakmodalupdate').modal('show');
}
});
}
Here is the actionPersonView which will be executed upon selecting column :
public function actionPersonView($id) {
$contactperson = SupplierContactPersonTable::model()->findByPk($id);
if ($contactperson === null)
throw new CHttpException(404, 'The requested page does not exist.');
$this->renderPartial('updateForm', array('contactperson'=> $contactperson));
Yii::app()->end();
}
Now, here is the problem :
When I Click update button on update form, I need to pass ID to my action :
public function actionPersonUpdate($id) {
$model2=$this->loadModel2($id);
// Uncomment the following line if AJAX validation is needed
// $this->performAjaxValidation($model);
if(isset($_POST['SupplierContactPersonTable']))
{
if($model2 === null) {
throw new CHttpException(404, 'The requested page does not exist.');
}
$model2->attributes=$_POST['SupplierContactPersonTable'];
$model2->save();
}
}
To pass this value, I'm using AjaxButton on my form:
<div id="contact-person-modal">
<?php
$form = $this->beginWidget('CActiveForm', array(
'id' => 'suppliercontactmodalform',
'htmlOptions' => array(
'class' => 'smart-form',
'novalidate' => '1',),
'enableAjaxValidation' => false,));
?>
...
<footer>
<button type="button" class="btn btn-labeled btn-danger cancel-button" style="float: left">
Hapus Pengguna
</button>
<?php
echo CHtml::ajaxButton('Update', Yii::app()->createUrl('suppliertable/personupdate',array('id'=>$contactperson->contact_person_id)), array('type'=>'POST'), array('type'=>'submit',"class" => "btn btn-primary"));
?>
<button type="button" class="btn btn-default" data-dismiss="modal">
Batal
</button>
</footer>
...
However, it seems like ID isn't passed. Here is Firebug console :
POST http://localhost/webapp/index.php/suppliertable/personupdate/
400 Bad Request
As you can see, no ID is passed.
But, if I use static parameter value :
echo CHtml::ajaxButton('Update', Yii::app()->createUrl('suppliertable/personupdate',array('id'=>'5')), array('type'=>'POST'), array('type'=>'submit',"class" => "btn btn-primary"));
The ID is passed :
POST http://localhost/webapp/index.php/suppliertable/personupdate/5
So, I think the problem is here, is not outputing value :
$contactperson->contact_person_id
Here is generated jQuery from Yii :
jQuery('body').on('click','#yt0',function({
jQuery.ajax({
'type':'POST',
'url':'/webapp/index.php/suppliertable/personupdate id=',
'cache':false,
'data':jQuery(this).parents("form").serialize()
});
return false;
});
Thanks for your help :)
I've found my solution.
In case someone have the same problem, I need to update my actionPersonView method :
public function actionPersonView($id) {
if (Yii::app()->request->isAjaxRequest) {
Yii::app()->clientScript->scriptMap['jquery.js'] = false;
Yii::app()->clientScript->scriptMap['jquery.min.js'] = false;
$contactperson = SupplierContactPersonTable::model()->findByPk($id);
if ($contactperson === null)
throw new CHttpException(404, 'The requested page does not exist.');
$this->renderPartial('updateForm', array('contactperson'=> $contactperson),false,true);
Yii::app()->end();
}
}
I need to add in my actionPersonView method
$this->renderPartial('updateForm', array('contactperson'=> $contactperson),false,true);
And add
Yii::app()->clientScript->scriptMap['jquery.js'] = false;
Yii::app()->clientScript->scriptMap['jquery.min.js'] = false;
To prevent the script being executed multiple.
I am making a LIVE UPDATE in CodeIgniter and it is almost working.
Just one little issue: When I click the button it also appears my navigation inside the "responds" box which is very strange.
And when I refresh the page it is removed and the record is there.
Here is an image to explain what I mean
Here is the JavaScript:
<script type="text/javascript">
$(document).ready(function() {
//##### Add record when Add Record Button is click #########
$("#FormSubmit").click(function (e) {
e.preventDefault();
if($("#contentText").val() ==='')
{
alert("Please enter some text!");
return false;
}
var myData = 'content_txt='+ $("#contentText").val(); //build a post data structure
jQuery.ajax({
type: "POST", // Post / Get method
url: "<?php echo site_url('admin/dashboard/index'); ?>", //Where form data is sent on submission
dataType:"text", // Data type, HTML, json etc.
data:myData, //Form variables
success:function(response) {
$("#responds").append(response);
},
error:function (xhr, ajaxOptions, thrownError) {
alert(thrownError);
}
});
});
});
</script>
EDIT:
HERE IS THE CONTROLER
class Dashboard extends CI_Controller
{
public function __construct()
{
parent::__construct();
// Load libraries
$this->load->library('ion_auth');
$this->load->library('parser');
// Load models
$this->load->model('note_model');
// Load helpers
$this->load->helper('date');
// Set error delimiters
$this->form_validation->set_error_delimiters('<div class="alert alert-danger">', '</div>');
}
public function index()
{
// Check if user is loged in
if (!$this->ion_auth->logged_in())
{
redirect('auth/login');
}
else
{
// Create notes object
$notes = new Note_model();
// Order the notes by date post
$notes->order_by('date_post', 'desc')->get();
$recent_notes = array();
foreach ($notes as $note)
{
$single_note = array
(
'id' => $note->id,
'note_text' => $note->note_text,
'date_post' => $note->date_post,
);
array_push($recent_notes, $single_note);
}
// Get the user id as an object
$getinfo = $this->ion_auth->user($this->session->userdata('user_id'))->row();
// Create a new note
$createNote = new Note_model();
$createNote->note_text = $this->input->post('content_txt');
$created = date('Y-m-d H:i:s');
$createNote->date_post = $created;
// Validation rules
$rules = $this->note_model->rules;
$this->form_validation->set_rules($rules);
$data = array
(
'admin_content' => 'admin/dashboard',
'notes' => $recent_notes,
'username' => $getinfo->{'first_name'} . ' ' . $getinfo->{'last_name'},
);
if ($this->form_validation->run() == FALSE)
{
$this->parser->parse('admin/template_admin', $data);
}
else
{
$createNote->save();
redirect('admin/dashboard');
}
}
}
The problem is the action you are calling.
It seems admin/dashboard/index outputs the navigation as well as the data you want to display.
You should post to an action that ONLY displays the data you require, and nothing else
I am using smarty framework in my project, I perfectly did my comment system but I cannot get the exactly result I want.
This is my PHP code inside event-detail.php :
$event_comment = $eventComment->geteventcomment($record, $startfrom, $max);
$tpl->assign("event_comment", $event_comment);
$tpl->display("event-detail.html");
This is HTML code inside event-detail.php :
//this is javasctipt
<script type="text/javascript">
// on post comment click
$('.bt-add-com').click(function(){
$.ajax({
type: "POST",
url: "add-comment.php",
data: 'act=add-com&event_id='+theEventId.val()+'&comment='+theCom.val()+'&user_id='+theUserId.val()+'&user_name='+theUserName.val()+'&file_path='+theFilePath.val(),
success: function(html){
theCom.val('');
theEventId.val('');
theUserId.val('');
theUserName.val('');
theFilePath.val('');
$('.new-com-cnt').hide('fast', function(){
$('.new-com-bt').show('fast');
$('.new-com-bt').before(html);
})
}
});
});
});
</script>
<div class="content-container-left">
<{section name=thisrsa loop=$event_comment}>
<div class="comment-box">
<div class="comment-listing">
<div><small><{$event_comment[thisrsa].date}></small></div>
<div class="avatar">
<img src="<{$smarty.const._CONST_CONTENT_MEMBER_THUMBNAIL}><{$event_comment[thisrsa].file_path}>"/>
<p><{$event_comment[thisrsa].name}></p>
</div>
<div class="comment-template">
<p><{$event_comment[thisrsa].content}></p>
</div>
</div>
</div>
<{/section}>
</div>
This is SQL statement which I had did it limit 3 record shows each page :
function geteventcomment($record, $startfrom, $max){
global $db,$comment;
$arrResult = array();
$stmt = "SELECT tbl1.event_id, tbl2.name, tbl2.file_path, tbl1.text, tbl1.modified_timestamp, tbl1.creation_timestamp FROM "._CONST_TBL_EVENT_COMMENT." tbl1, "._CONST_TBL_ALUMNI." tbl2 WHERE tbl1.event_id = $record AND tbl1.member_id = tbl2.id ORDER BY tbl1.creation_timestamp DESC";
$stmt .= " LIMIT $startfrom, $max";
if($rs = $db->Execute($stmt))
{
while($rsa = $rs->FetchRow())
{
array_push($arrResult, array(
"id" => $record,
"name" => $rsa['name'],
"file_path" => $rsa['file_path'],
"content" => $rsa['text'],
"date" => $rsa['modified_timestamp']
));
}
}
return $arrResult;
}
I had get the following result in my website :
But what I really want is to refresh div and make it only display the latest 3 comment in my website, like below :
I hope I can get some help from you guys.
Please check if following code helps.
$('.new-com-cnt').hide('fast', function(){
$('.new-com-bt').show('fast');
$('.new-com-bt').empty().append(html);
});