jquery tokeninput : how to pass a dynamic array for autocompletion - jquery-plugins

With tokenInput, my autocompletion returns nothing and I don't find why.
First I do a query on the database to find all the contacts for the connected user.
I get an array like for instance :
$contacts = Array( [0] => Array ( [id] => 1 [name] => John ) [1] => Array ( [id] => 3 [name] => Peter ) )
Then I use http_build_query as I want to pass the array through URL :
$contacts_url =http_build_query($contacts);
which returns :
print_r($contacts_url)= 0%5Bid%5D=1&0%5Bname%5D=John&1%5Bid%5D=3&1%5Bname%5D=Peter
Then I use tokenInputs, and I send my array through the url :
$(document).ready(function () {
$("#my-text-input").tokenInput("<?php echo $this->webroot.'populate.php?'.$contacts_url ?>", {theme: "facebook"});
});
the populate.php page contains :
<?php
header('Content-type: text/javascript');
$a= $_GET;
$json_string = json_encode($a);
echo $json_string;
?>
If I open the php page ../populate.php?0%5Bid%5D=1&0%5Bname%5D=John&1%5Bid%5D=3&1%5Bname%5D=Peter i see:
[{"id":"1","name":"John"},{"id":"3","name":"Peter"}]
which I think looks good
But the autocompletion returns nothing :(
Any help much much appreciated !
Many thanks

By default, the search parameter is also sent as a $GET variable, which I imagine would be messing up your JSON encode.
A much better way of doing this would be locally, as below:
$(document).ready(function () {
$("#my-text-input").tokenInput("<?php echo json_encode($contacts) ?>", {theme: "facebook"});
});

$(document).ready(function() {
$("#searchword").tokenInput(
/* Given that $json_res = json_encode($user_arr); in the PHP.
Using <?php echo $json_res ?> OR <?php echo json_encode($user_arr) ?> without quotes and blocks gives the same result.
The other way is to define var ar =<?php echo $json_res?>; in JS and pass it as .tokenInput(ar, {} */
<?php echo $json_res ?>
, {
propertyToSearch: "username",
theme: "facebook",
preventDuplicates: true,
excludeCurrent: true
});
});
// if JSON file has [{"id":"856","product":"sample1"}, {"id":"1035","product":"sample product 2"}], execute the following:
$('#product_tokens').tokenInput('/products.json', { propertyToSearch: 'product' });

Related

Validation message not showing below the field in cakephp 3 latest version

I am trying to validate a multiple select field that have jquery chosen applied.
Validation is working perfectly but only problem is that validation message is not showing below the input field.
Here is my files.
profile_edit.ctp
<?php echo $this->Form->create($user,['action' => '', 'role'=>"form",'novalidate'=>true,'method'=>'post','id'=>'ProfileForm','templates'=>['label'=>false,'inputContainer'=>'{{content}}']]); ?>
<?php echo $this->Form->control('user_grades[].grade_id',['multiple','hiddenField'=>false, 'escape'=>false, 'type'=>'select', 'id'=>'sp_grade', 'options'=>App\Model\Table\GradesTable::getGrades('list'),'class'=>'form-control chosen-select']); ?>
<button type="submit" class="btn footer_btns float-left">Save</button>
<?php echo $this->Form->end(); ?>
MyAccountController.php
<?php
public function profileEdit(){
$user = $this->Users->get($this->Auth->user('id'), ['contain'=>['UserGrades']]);
if($this->request->is(['put','post'])){
$data = $this->request->getData();
if(isset($data['user_grades']) && !empty($data['user_grades'])) {
$this->UserGrades->deleteAll(['user_id' => $this->Auth->user('id')]);
}
if(null == $this->request->getData('user_grades')){
$this->request = $this->request->withData('user_grades.0.grade_id','');
}
$user = $this->Users->patchEntity($user, $this->request->getData(), [
'validate' => 'editProfileSection',
'associated' => [
'UserGrades' => ['validate'=> 'editProfileSection']
]
]);
if(empty($user->getErrors())){
if ($this->Users->save($user)) {
$this->Flash->success(__('Succesfully updated <strong>'.$user->full_name .'</strong> Information||Success'));
return $this->redirect(['action' => '']);
}
}
$this->Flash->error(__('Please check your inputs and try again.||Action Failed!'));
}
$this->set(compact('user'));
}
UserGradesTable.php
<?php
namespace App\Model\Table;
use Cake\ORM\Table;
use Cake\ORM\Query;
use Cake\ORM\TableRegistry;
use Cake\Event\Event;
use Cake\ORM\RulesChecker;
use Cake\Validation\Validator;
class UserGradesTable extends Table {
public function initialize(array $config) {
$this->addBehavior('Timestamp');
$this->addBehavior('Trim');
}
public function validationEditProfileSection(Validator $validator) {
$validator
->notEmpty('grade_id',"Please select at least one grade.");
return $validator;
}
}
I have tried to get error message and got following:
Array
(
[user_grades] => Array
(
[0] => Array
(
[grade_id] => Array
(
[_empty] => Please select at least one grade.
)
)
)
)
But this error is not showing below the input field. Any help will be appreciated.
You are not using the correct naming scheme for the form control, you cannot use [], if you want the form helper magic to work, then you must supply the actual index, ie:
user_grades.0.grade_id
See also Cookbook > Views > Helpers > Form > Creating Inputs for Associated Data

yii2 inserting 2 params as text inside dropdownlist

Here is yii2 drop down list.
<?php echo $form->field($model, 'param1')->dropDownList(
ArrayHelper::map(Model::find()->all(),'param1','param2');
It makes drop Down list with values of param1s and text to choose from of param2s.
So you see param2 texts , choose one and corresponding param1 value goes to server.
No my problem is that I want to do the same but show user not only param2 text but I want text to be constructed from param2+param3.
example of what I want.
hidden value___________text
1_____________________alpha
2_____________________bravo
3_____________________lima
hidden value___________text
1_____________________alpha-red
2_____________________bravo-white
3_____________________lima-blue
Is that possible ?
One of the ways to do it will be using built-in ArrayHelper with toArray() method.
Put this in your model:
use yii\helpers\ArrayHelper;
...
public static function getList()
{
$initialModels = static::find()->all();
$models = ArrayHelper::toArray($initialModels, [
'app\models\YourModel' => [
'param1',
'combinedParam' => function ($model) {
return "$model->param2 - $model->param3";
},
],
]);
return ArrayHelper::map($models, 'param1', 'combinedParam');
}
Displaying it in view:
<?= $form->field($model, 'param1')->dropDownList(YourModel::getList()) ?>

html::link to dynamic route

I am trying to output a list of users on my blade.php page. Clicking on a user's id should take you to an individual profile page.
Here is my View browse.blade.php file
<?php
$cars = DB::table('cars')->get();
foreach ($cars as $car)
{
echo "<table >" ;
echo "<tr>";
HTML::linkRoute('browse/'.$car->car_id, 'Car ID: '.$car->car_id);
echo "<td>Make: $car->make <br/ ></td>" ;
echo "</tr>";
echo "</table>";
}
?>
My Controller
public function browse()
{
return View::make('car/browse');
}
public function showProfile($car_id)
{
return View::make('car/profile')->with('car_id', $car_id);
}
My Route
Route::any('browse/{car_id}', 'BrowseController#showProfile');
I want my view page to output a bunch of cars in my Database. Clicking on a car with car_id = i should tak me to http://localhost:8000/browse/i for each respectic car_id.
Am I taking the wrong approach with my html::linkRoute?
Typing http://localhost:8000/browse/i into the browser works for any i. Therefore, my route and showProfile is working properly.
However when I load the browse.blade.php I receive the following error
10018 is my first car id. Why isn't my Route::any('browse/{car_id}' working?
edit:
Thanks to msturdy for the suggestion
changed
Route::any('browse/{car_id}', 'BrowseController#showProfile');
to
Route::any('browse/{car_id}', [
'as' => 'profile',
'uses' => 'BrowseController#showProfile']);
and changed HTML route to
HTML::linkRoute('profile', 'Car ID: '.$car->car_id, array($car->car_id));
The errors are gone but no link is displaying on the browse page.
First, update your route so that it has a 'name' you can use elsewhere in your application. We'll call it 'browse' in this example:
Route::any('browse/{car_id}', array('as' => 'browse', 'uses' => 'BrowseController#showProfile'));
Then HTML::linkRoute() takes this route name, the title of the link and the parameters as separate arguments:
HTML::linkRoute('browse', "Car ID: " . $car->car_id, array($car->car_id));

CakePHP setting up dependent AJAX dropdown

I have done a lot of research, tried to apply a few different examples but it seems that nothing really works.
So I have the following 3 models: Customers, Projects and Events. Customers have many Projects and Projects have many Events.
While creating an Event, I would like a user to select a Customer from a dropdown list and then the user should be provided with a list of Projects that belong to the selected Customer. The closest I have got to is the following. I do not have experience with AJAX, so that really is a hard nut to brake.
Action in the Porject's controller:
public function getbycustomer(){
$customer_id = $this->request->data['Event']['customer_id'];
$projects = $this->Project->find('list', array('conditions'=>array('Project.customer_id' => $customer_id), 'recursive' => -1));
$this->set('projects', $projects);
$this->layout = 'ajax';
}
View for this action is the following:
<?php foreach ($projects as $key => $value): ?>
<option value="<?php echo $key; ?>"><?php echo $value; ?></option>
<?php endforeach; ?>
And here is the snippets from the view for adding an event:
echo $this->Form->input('customer_id');
echo $this->Form->input('project_id');
//form continues and at the end of a page there is the AJAX call
$this->Js->get('#EventCustomerId')->event('change',
$this->Js->request(array(
'controller'=>'projects',
'action'=>'getbycustomer'
), array(
'update'=>'#EventProjectId',
'async' => true,
'method' => 'post',
'dataExpression'=>true,
'data'=> $this->Js->serializeForm(array(
'isForm' => true,
'inline' => true
))
))
);
Any help is much much appreciated as I do not even know the proper way for debugging it, so I could provide more valuable information.
go to this. this helped me to do the dependent drop down list. it provies a details step by step process.
I think you need to set autoRender to false otherwise it will try to render the template at app/View/Project/getbycustomer.ctp. Also, you probably want to return or print JSON. Ther are probably several ways to do this, but I have something similar that is working and the controller action is basically this:
public function getbycustomer() {
$this->autoRender = $this->layout = false;
$customer_id = $this->request->data['Event']['customer_id'];
$projects = $this->Project->find('list', array('conditions'=>array('Project.customer_id' => $customer_id), 'recursive' => -1));
$this->set('projects', $projects);
echo json_encode(array('html' => $this->render('your_partial_template')->body())); // This template would be in app/View/Project/json/
}
Then in your Ajax call there should be a 'success' callback that handles the JSON returned:
success: function(data) {
$('#EventProjectId').html(data.html); // assuming this an empty container
}
Also, unless your projects table is only two columns the result of your find is probably not what you're expecting. Change it to
$projects = $this->Project->find('list', array('conditions'=>array('Project.customer_id' => $customer_id), 'fields' => array('id', 'name_or_whatever', 'recursive' => -1));
Then in your partial template you can use the form helper:
<?php echo $this->Form->input('Projects.id', array('options' => $projects)); ?>

CakePHP AJAX call

I am using CakePHP and this is my first project on this framework. I am going to send the value of an input to UsersController's check_username() action. And fill an element having id na with the string returned by check_username(). So far what I did is:
//in my form
<input type="text" name="data[User][username]" style="width: 60%" required="required" id="username" oninput="check_username(this.value)">
<label style="margin-left: 20px; color: red" id="na">Not Available!</label>
//after the form
<script type="text/javascript">
function check_username(un) {
$.ajax({
type: 'POST',
url: '/oes/users/check_username',
data: {username:un},
cache: false,
dataType: 'HTML',
beforeSend: function(){
$('#na').html('Checking...');
},
success: function (html){
$('#na').val(html);
}
});
}
</script>
//and my check_username() is
public function check_username(){
return 'Test string';
}
But this isn't working. Anybody know why or how to modify it so that it works?
It could be problem with your check_username controller action. CakePHP-way is to use JsonView class to send any data throw XHR (see http://book.cakephp.org/2.0/en/views/json-and-xml-views.html). It allows you to call any action with .json extension (ex.: /oes/users/check_username.json) and get response in serialized JSON format without manual conversion beetween array data and JSON.
This method is recommended for your needs, but not obligated, of course.
Now I think that CakePHP tries to render check_username view, but could not do this because you have not specified or created it. Try to change your action code to something like this:
public function check_username(){
$this->autoRender = false;
echo 'Test string';
}
Also, try not to use such code construction in the future.
CakePHP has a JS Helper to help write aJax functions. The only catch is to include jquery in your head our cake will throw jQuery errors.
Your Form:
<?php
echo $this->Form->create('User', array('default'=>false, 'id'=>'YourForm'));
echo $this->Form->input('username');
echo $this->Form->submit('Check Username');
echo $this->Form->end();
?>
The Ajax Function:
<?php
$data = $this->Js->get('#YourForm')->serializeForm(array('isForm' => true, 'inline' => true));
$this->Js->get('#YourForm')->event(
'submit',
$this->Js->request(
array('action' => 'checkUsername', 'controller' => 'user'),
array(
'update' => '#na',
'data' => $data,
'async' => true,
'dataExpression'=>true,
'method' => 'POST'
)
)
);
echo $this->Js->writeBuffer();
?>
The Function in User Controller
function checkUsername(){
$this->autoRender = false;
//run your query here
if ( $username == true )
echo 'Username is taken';
else
echo 'Username is not taken';
}
There are many examples through google. Here is a good one to visit.

Resources