Autocomplete data fields in CakePHP - javascript

I am new in CakePHP. I have a CakePHP (2.5.1) application which has streets table (with columns id, street_name, house_no, district, city). I need to autocomplete a form by extracting the table data. It should be like, the user will be typing a street name in the Street Name field of a form which has fields- Street Name, House No, District and City. After selecting a street name from auto suggestions, corresponding data (House No, District and City) will be populated in the other fields.
Now, over 25000 data rows are loaded in the streets table which is the entire street database of a city. it is a ClearDB database on Windows Azure. streets table is not linked with other tables of the application through foreign keys. I have Street model, StreetsController , but view is in different folder (app/View/User/add.ctp ). Street model in app/Model/Street.php is following:
class Street extends AppModel {
public function getStreetNames($term = null) {
if(!empty($term)) {
$streets = $this->find('list', array(
'conditions' => array(
'street_name LIKE' => trim($term) . '%'
)
));
return $streets;
}
return false;
}
}
In app/Controller/StreetsController.php,
class StreetsController extends AppController {
public $components = array('RequestHandler');
public function autocomplete($term){
if ($this->request->is('get')) {
$this->autoRender = false;
$data = $this->Street->getStreetNames($term);
$this->set(compact('data'));
$this->set('_serialize', array('data'));
echo json_encode($data);
}
}
}
In app/webroot/js/View/Users/streetdata.js file,
(function($) {
$('#autocomplete').autocomplete({
source: "/streetdata.json",
minLength: 1
});
})(jQuery);
The input forms are in different controller. In app/View/Users/streetdata.ctp file,
<?php
echo $this->Html->script('View/Users/streetdata', array('inline' => false));
?>
<?php echo $this->Form->create('Street', array(
'class' => 'form-horizontal',
'role' => 'form',
'inputDefaults' => array(
'format' => array('before', 'label', 'between', 'input', 'error', 'after'),
'div' => array('class' => 'form-group'),
'class' => array('form-control'),
'label' => array('class' => 'col-lg-2 control-label'),
'between' => '<div class="col-lg-3">',
'style'=>array('width:200px; height:35px;'),
'after' => '</div>',
'error' => array('attributes' => array('wrap' => 'span', 'class' => 'help-inline')),
))); ?>
<fieldset>
<legend><?php echo __('Street data '); ?></legend>
<?php
echo $this->Form->input('Street.street_name', array(
'class' => 'ui-autocomplete',
'id' => 'autocomplete'));
echo $this->Form->input('Street.house_no');
echo $this->Form->input('Street.district');
echo $this->Form->input('Street.city');
?>
</fieldset>
<?php echo $this->Form->end(__('Proceed')); ?>
in View/Layouts/default.ctp, i have added followings
echo $this->Html->script('jquery.js');
echo $this->Html->script('bootstrap.min');
echo $this->Html->script('https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js');
echo $this->Html->script('https://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js', array('inline' => false));
echo $this->Html->script('https://ajax.googleapis.com/ajax/libs/jqueryui/1.10.3/jquery-ui.min.js', array('inline' => false));
echo $this->Html->css('https://code.jquery.com/ui/1.10.3/themes/smoothness/jquery-ui.css');
echo $this->Html->css('font-awesome.min');
echo $this->Html->css('bootstrap.min');
echo $this->Html->meta('icon');
echo $this->fetch('meta');
echo $this->fetch('css');
echo $this->fetch('script');
echo $this->Html->charset();
But the autocomplete fields (street name and others) are not working.
I found following error messages in the console of chrome browser :
-Failed to load resource: the server responded with a status of 404 (Not Found) http://localhost:26949/Users/js/jquery.js
-Failed to load resource: the server responded with a status of 404 (Not Found) http://localhost:26949/Users/js/bootstrap.min.js
-Uncaught TypeError: Cannot read property 'offsetWidth' of undefined bootstrap.min.js:6
I am struggling to find a solution. Could anyone tell me please what is wrong here ? is it because of the location of .js file ? am i missing anything here?

Related

Passing arrays with ajax to custom endpoints

I am using ajax to send data to a custom rest endpoint. I am doing this because i'm creating a filter function on my WP site.
Now I am stuck trying to get the tax_query to work with my array of terms collected with JS on the front end. No matter what I do I cant seem to get this to work, and I am strongly suspecting this is only a minor error that I keep overlooking...
Just to clarify, the ajax sends the request successfully but the query returns all posts no matter what.
Here is the checkboxes used on the front end:
<div class="form-group">
<?php
if( $terms = get_terms( array( 'taxonomy' => 'utst', 'hide_empty' => false, 'orderby' => 'name' ) ) ) :
foreach ( $terms as $term ) :
echo '<div class="form-check">';
echo '<label class="form-check-label" for="'.$term->slug.'"><input class="form-check-input" type="checkbox" id="'.$term->slug.'" name="utstyrAr[]" value="'.$term->term_id.'"> '.$term->name.'</label>'; // ID of the category as the value of an option
echo '</div>';
endforeach;
endif;
?>
</div>
The JS (ajax function):
filterOppdrag(fiOppdrag) {
var utst = [];
var utstyrArray = document.getElementsByName("utstyrAr[]");
for (var i = 0; i < utstyrArray.length; i++) {
if(utstyrArray[i].type =='checkbox' && utstyrArray[i].checked == true) utst.push(utstyrArray[i].value);
}
console.log(utst);
$.ajax({
url: the.root + '/wp-json/myfilter/v1/filter',
type: 'GET',
data: {
'checkUtst' : utst,
},
success: (response) => {
console.log(response);
},
error: (response) => {
console.log(response);
}
});
}
And the wp_query (php):
function myFilter ($data) {
$checkUtst = sanitize_text_field($data['checkUtst']);
//Main $args
$args = array(
'post_type' => 'ml_opp', // Query only "ml_opp" custom posts
'post_status' => 'publish', // Query only posts with publish status
'orderby' => 'date', // Sort posts by date
'order' => 'ASC' // ASC or DESC
);
// for taxonomies / utstyr
if( isset( $utstyr ) )
$args['tax_query'] = array(
array(
'taxonomy' => 'ml_utst',
'field' => 'id',
'terms' => $checkUtst
)
);
$query = new WP_Query( $args );
if( $query->have_posts() ) :
while( $query->have_posts() ): $query->the_post();
echo '<h2>' . $query->post->post_title . '</h2>';
endwhile;
wp_reset_postdata();
else :
echo 'No posts found';
endif;
die();
}
This returns all the posts regardless of terms no matter what I pass through. I get no error messages and yes I have tested so that there is value in the array when I send it to the query. But what happens to it on the road there, I dont know. That's why i figure that Its probably just a rookie mistake I am making here.
Any help would be greatly appreciated!
Have you tried removing the wrapping array and not using a key?
$args = array(
'taxonomy' => 'ml_utst',
'field' => 'id',
'terms' => $checkUtst
);

how will I append data I am selecting from a dropdown list to the next input field in yii2

I want to select courses from the course field, then let it show in my courses field and submit the courses to the database. or if someone can help me so my courses can appear has a checkbox and once i tick a checkbox, it appears in the courses field
<?php $form = ActiveForm::begin(); ?>
<?=$form->field($model, 'student_id') ?>
<?=
$form->field($model, 'faculty_id')->dropDownList(
ArrayHelper::map(Faculties::find()->asArray()->all(), 'faculty_id', 'faculty_name'), [
'prompt' => 'Select Faculty',
'onchange' => '$.post("' . Yii::$app->urlManager->createUrl('/departments/lists?id=') . '"+$(this).val(), function(data) {
$("select#registrations-department_id").html (data);
});'
]
);
?>
<?=
$form->field($model, 'department_id')->dropDownList(
ArrayHelper::map(Departments::find()->asArray()->all(), 'department_id', 'department_name'), [
'id' => 'registrations-department_id',
'prompt' => 'Select Department',
'onchange' => '$.post("' . Yii::$app->urlManager->createUrl('/courses/lists?id=') . '"+$(this).val(), function(data) {
$("select#registrations-course_id").html (data);
});'
]);
?>
<?=
$form->field($model, 'course_id')->dropDownList(
ArrayHelper::map(Courses::find()->asArray()->all(), 'course_id', 'course_name'), [
'id' => 'registrations-course_id',
'prompt' => 'Select Course',
'onchange' => '$.post("(selected:)."+$(this).val(), function(data){
$("#registrations-courses").append(data)
});'
]);
?>
<!-- <?//= $form->field($model, 'courses')->checkBoxList([]) ?> -->
<?=$form->field($model, 'courses') ?>
<?=$form->field($model, 'comment') ?>
<?=$form->field($model, 'status') ?>
<?=$form->field($model, 'created_at') ?>
<?=$form->field($model, 'updated_at') ?>
<div class="form-group">
<?=Html::submitButton('Submit', ['class' => 'btn btn-primary']) ?>
</div>
<?php ActiveForm::end(); ?>
EDIT
this is my controller how do I save the courses in the database in the same column?
public function actionCreate()
{
$model = new Registrations();
if ($model->load(Yii::$app->request->post())) {
if ($model->validate()) {
// form inputs are valid, do something here
$model->student_id = Yii::$app->user->identity->id;
$model->faculty_id = 1 ;
$model->department_id = null ;
$model->course_id = 1;
$model->save();
return $this->redirect('../site/profile');
}
}
return $this->render('create', [
'model' => $model,
]);
}
You can use the checkBoxList() to create the list of checkboxes based on the courses list.
Change your course_id field to the following
$form->field($model, 'course_id')->checkboxList(yii\helpers\ArrayHelper::map(Courses::find()->asArray()->all(), 'course_id', 'course_name'), [
'inline' => true,
'unselect'=>null,
'item' => function($index, $label, $name, $checked, $value){
$checked = $checked ? 'checked' : '';
return "<input type='checkbox' class='my-courses' name='{$name}' value='{$value}' {$checked} data-label='{$label}'> <label>{$label}</label>";
}]);
add an id attribute to your courses field like below
$form->field($model, 'courses', ['inputOptions' => ['id' => 'courses']]);
and then add this javascript code to the top of your page
$js = <<< JS
$(".my-courses").on('click',function(e){
let course_name=$(this).data('label');
let course_field=$("#courses");
if($(this).is(":checked")){
$("#courses").val()==''?course_field.val(course_name):course_field.val(course_field.val()+', '+ course_name);
}else{
let regex=new RegExp(',{0,1}\\\s{0,1}('+course_name+')','g');
course_field.val(course_field.val().replace(regex,''));
}
})
JS;
$this->registerJs($js, \yii\web\View::POS_READY);
Now if you select the checkbox the name of the course would be copied to the input field and when you submit your form you can get the fields in your $_POST array under your specific model index like below.
[course_id] => Array
(
[0] => 1
[1] => 2
)
[courses] => asdas, shugal, spoon
You can verify by adding a print_r(Yii::$app->request->post()) in your controller action inside the check
if($model->load(Yii::$app->request->post())){
print_r(Yii::$app->request->post());
You can iterate on the course_id to save all of the course_id that were selected as checkboxes.

Fetching events from database into FullCalendar

I am trying to fetch data from a MySQL database into a calendar. (FullCalendar plugin)
I want to send the fetched data as a json feed to be displayed on the calendar.
This is my Javascript code for displaying the events:
events: {
url: 'http://localhost/Hotel/event_source.php',
error: function() {
alert('There was an error while fetching events.');
}
This is the event_source.php page where I'm fetching the data from the database:
<?php
include('hoteldb.php');
global $conn;
if($stmt = $conn->prepare("SELECT title, startDate, endDate FROM event"))
{
$stmt->execute();
$stmt->bind_result($title, $startDate, $endDate);
while ($stmt->fetch())
{
$rows[] = array('title' => $title, 'startDate' => $startDate, 'endDate' => $endDate);
}
$stmt->close();
echo json_encode($rows);
}
?>
The code should be modified as followed. The statement fetch method will return the next row and you have to catch it as follows. Also the columns are accessed as I have shown in the following code.
$rows=array();
while ($row=$stmt->fetch())
{
$rows[] = array('title' => $row['title'], 'startDate' => $row['startDate'], 'endDate' => $row['endDate']);
}
Try Below one in your while loop
'title' and 'start' must be there in event to load in calendar.
while ($stmt->fetch())
{
$rows[] = array('title' => $title, 'start' => date('Y-m-d H:i:s', strtotime($startDate)), 'end' => date('Y-m-d H:i:s', strtotime($endDate)));
}

How to combine the functionality of a list with a textbox

Right now I have a form that I created in cakephp and it works fine but the problem I am running into is that we run queries off of the type in the database and there have been some user errors with spelling so I would like to have a list with the most common types that you can select from but if it is not in the list you can still type in something different.
I found this jquery autocomplete combobox that works great but I am not able to enter something that is not in the list. http://jqueryui.com/autocomplete/#combobox
I don't know if you need to see my form or not but I will post it anyway
<?php
echo $this->Form->create( 'Credential', array( 'class' => 'popup_form' ) );
echo $this->Form->hidden( 'account_id', array( 'value' => $account_id ) );
echo $this->Form->hidden( 'user_id', array( 'value' => $currentUser['User']['id'] ) );
echo $this->Form->hidden( 'created', array( 'value' => date("Y-m-d H:i:s") ) );
echo $this->Form->hidden( 'modified', array( 'value' => date("Y-m-d H:i:s") ) );
echo '<br/><br/>';
echo $this->Form->input( 'type', array( 'div' => false, 'label' => false, 'placeholder' => 'Account Type' ) );
echo '<br/><br/>';
echo $this->Form->input( 'url', array( 'div' => false, 'label' => false, 'placeholder' => 'URL' ) );
echo '<br/><br/>';
echo $this->Form->input( 'username', array( 'div' => false, 'label' => false, 'placeholder' => 'Username' ) );
echo '<br/><br/>';
echo $this->Form->input( 'password', array( 'div' => false, 'label' => false, 'placeholder' => 'Password' ) );
echo '<br/><br/>';
echo $this->Js->submit( 'Create Credential', array( 'div' => false, 'class' => 'button white medium', 'before' => 'return submitForm();', 'success' => "$('#qtip-add_account_credential').hide();", 'complete' => 'loadTasks();' ) );
echo '<br/><br/>';
echo $this->Form->end();
?>
<script type="text/javascript">
function submitForm(){
var x = document.getElementById("CredentialType").value;
if (x == null || x == "") {
alert("Account Type must be filled out");
return false;
}
else {
return true;
}
}
</script>
I am a backend developer and would love any help I could get on the front end. Thanks.
What you are searching for is a datalist (new in HTML5):
http://www.w3schools.com/tags/tag_datalist.asp
It provides an form input with a predefined list of options, which appears as soon as the user's input matches one of the entries.
BUT: it seems not to be supported in Safari
In your case it would look like that:
<input name="type" list="AccountTypes" placeholder="Account Type">
<datalist id="AccountTypes">
<option value="admin">
<option value="user">
<option value="something else">
</datalist>

CakePHP- Using the JsHelper for Ajax Search

Ok, So I am trying to implement sort of a livesearch using the cake's Js Helper. The user will select a criteria to search by, using a drop down, and then tyoe in his search in an input text field. So far, this is what I have.
echo $this->Form->create(false,array('type'=>'post','default'=>false));
echo $this->Form->input('criteria',array(
'label'=>'Search Criteria',
'options' => array(
'id'=> 'By ID',
'name' => 'By Name',
'blood' => 'By Blood Type',
'type' => 'By Donor Type',
'age' => 'By Age',
'gender' => 'By Gender'
)
));
?>
Here is the input:
<?php echo $this->Form->input('query', array('type' => 'text', 'id' => 'query', 'name' => 'query', 'label' => false, 'placeholder' => 'Search')); ?>
<div id="loading" style="display: none; ">
<?php echo $this->Html->image('ajax_clock.gif');?>
</div>
And this is my Js code generated using the helper!
<script type="text/javascript">
<?php
echo $this->Js->get('#query')->event('keyup',$this->Js->request(
array('controller' => 'donors', 'action' => 'search'),
array('update'=>'#results','async' => true,'dataExpression' => true,'method' => 'post','data'=>'$(\'#query,#criteria\').serializeArray()')
),false);
?>
</script>
The above Js should grab the values of the criteria drop down aswell as the value inside the input field , on the keyup event. That said, I thought it was better to encode the data, and found the serializeArray method in the doc, which should do just that (I think..)
Now, my problem is I do not know how to retrieve that serialized data from the action receiving the request. So far I have this
function search() {
if($this->request->is('post')){
$data = $this->request->input('json_decode');
}
}
So basically, I want to know how to access the data from the search action, as well as, I tried to echo the $data variable, and die($data), but I do not know where the debugging info is displayed. Any help regarding both my questions would be MUCH appreciated! thanks!

Categories