I have a list of guests that I want to be able to use in the jQuery autocomplete but I can't seem to get the format correct. I'm using CakePHP 2.3.8 and have a list of guests sent from my controller to view. When I type into the text box, I get the following error
//in reference to source of the elements to populate the autocomplete list
Property 'source' of object [object Object] is not a function
I searched for this error on here, but I couldn't find anything related to converting a PHP array while also accounting for the index number of that item. I have a PHP array in the format of
echo "<pre>"; print_r($guest_list); echo "</pre>";
//results in the following, where the index is the guest's ID
array(
[1] => guest a,
[2] => guest b,
[3] => guest c
)
Keep in mind, the index refers to the guest's ID.
I used json_encode to convert the php $guests array which results in the following format
var guests = {"1":"guest a","2":"guest b","3":"guest c"};
I noticed in the documentation the source of the data is usually in a format like
var guests = [guest_a, guest_b, guest_c];
Keep in mind index refers to the guest's ID, so I need to use this number to make sure the correct guest is chosen, if there happens to be two guests with the same name
So, here's the javascript/jquery for the autocomplete box
var guests = <?php echo json_encode($guest_list); ?>;
$(function() {
$( "#guests_autocomplete" ).autocomplete({
source: guests
});
});
How can I properly format my guests array to work with autoComplete and still keep track of the guest's id?
use
var guests = ["<?php echo implode('","',$guest_list); ?>"];
instead of
var guests = <?php echo json_encode($guest_list); ?>;
and if guest names are unique you can use array_search to find id
Related
I am using Jquery-option-tree plugin on a standalone website not based on Wordpress as in example 7 on the demo page, except that I am not passing a .txt file but a PHP page is generating the array of < options > to be passed to the plugin.
http://kotowicz.net/jquery-option-tree/demo/demo.html
This perfectly works: so let's say that the user wants to select a category for a new product, the plugin suits the purpose generating a nice: " Food -> fruit -> apples " upon user clicks. (see demo page ex. 7)
What instead if a product already exists with its categories assigned? I want to show it to the user when he edit that product, preloading the tree.
I have the ids path coming from database, so it would just be a matter of having the plugin to run without the user interact, using the value I pass. I saw this question: jQuery simulate click event on select option
and tried to simulate user' click with this (and other) methods with no luck.
$('#select')
.val(value)
.trigger('click');
Here the call to the function:
$(function() {
var options = {
empty_value: '',
set_value_on: 'each',
indexed: true, // the data in tree is indexed by values (ids), not by labels
on_each_change: '/js/jquery-option-tree/get-subtree.php', // this file will be called with 'id' parameter, JSON data must be returned
choose: function(level) {
return 'Choose level ' + level;
},
loading_image: '/js/jquery-option-tree/ajax-load.gif',
show_multiple: 10, // if true - will set the size to show all options
choose: ''
};
$.getJSON('/js/jquery-option-tree/get-subtree.php', function(tree) { // initialize the tree by loading the file first
$('input[name=parent_category_id]').optionTree(tree, options);
});
});
Here you can see the plugin:
https://code.google.com/p/jquery-option-tree/
I don't know that plugin, but looking at the examples there seems to be one that fits your need; Example 6 - AJAX lazy loading & setting value on each level change.
This would, in theory, just require some config options:
preselect: {'demo6': ['220','226']}, // array of default values - if on any level option value will be in this list, it will be selected
preselect_only_once: true, // prevent auto selecting whole branch when user maniputales one of branch levels
get_parent_value_if_empty: true,
attr: "id" // we'll use input id instead of name
If this doesn't fit you need though, you could initiate it from an event, like change, keyup, etc.
$(document).on('change', '#select', function() {
$('#nextSelect').val($(this).val());
})
$(document).on('change', '#nextSelect', function() {
$('#finalInput').val($(this).val());
})
Yes, you are right Mackan ! I saw that "preselect" option but I was initially unable to use it transferring the path from database to javascript, I ended up with my "newbie" solution to match the syntax:
preselect: {'parent_category_id': [0,'2','22']},
PHP
$category_path comes from DB query and is like "0,2,76,140,"
$path = explode(',', $category_path);
$preselect="";
foreach ($path as $value) {
$int = (int)$value;
if ($int != 0) $preselect.= "'". $int ."',";
else $preselect.= $int.","; // have to do this as ZERO in my case has to be without apostrophes ''
}
$preselect = "{'parent_category_id':[".$preselect."]}"
JS
var presel= <?php echo($preselect); ?>;
var options = {
preselect: (presel),
}
Any suggestion for a better code ?
Thanks a lot !!
I am using CakePhp 2.2.1 and I am having some problems to implement what I just asked in the title, I found several tutorials but most of them are for cakephp 1.3 and the others are not what I want to do. I have a "events" table which contains a "player_id" thus a Player has many Events and an Event belongs to a Player.
In my Event add form I proceed as the cookbook says and I get a dropdown list of players to choose from, however what I want is to just write the names of the players and select the one I want from the autocomplete results. Also these players must be from the team that I select before that. Any ideas?
Thanks in advance.
Special thanks to Andrew for pointing out this api.jqueryui.com/autocomplete. However there is not a real guide to use this one. So i found this post, which explains what Abhishek's second link says but I could understand it better. So here is my solution if anyone is interested:
1 - Download from the autocomplete page the .js you need. Save it in app/webroot/js
2 - Either in your app/View/Layouts/default.ctp or in the view you want to use the autocomplete add:
echo $this->Html->script('jquery-1.9.1.js');
echo $this->Html->script('jquery-ui-1.10.3.custom.js');
echo $this->fetch('script');
3 - In your view add (mine was add_goal.ctp):
<script>
$(document).ready(function(){
var myselect = document.getElementById("EventTeam"); //I needed to know which team I was looking players from.
var team = myselect.options[myselect.selectedIndex].value; //"EventTeam" was a dropdown list so I had to get the selected value this way.
$("#EventPlayer").autocomplete({
source: "/events/autoComplete/" + team,
minLength: 2, //This is the min ammount of chars before autocomplete kicks in
autoFocus: true
});
$("input:submit").button();
$("#EventPlayerId").autocomplete({
select: function(event, ui) {
selected_id = ui.item.id;
$('#EventAddGoalForm').append('<input id="EventPlayerId" type="hidden" name="data[Event][player_id]" value="' + selected_id + '" />');
}
});
$("#EventPlayerId").autocomplete({
open: function(event, ui) {
$('#EventPlayerId').remove();
}
});
});
</script>
4 - In your Controller (mina was EventController.php):
public function autoComplete($team = null){
Configure::write('debug', 0);
$this->autoRender=false;
$this->layout = 'ajax';
$query = $_GET['term'];
$players = $this->Event->Player->find('all', array(
'conditions' => array('Player.team_id' => $team, 'Player.name LIKE' => '%' . $query . '%'),
'fields' => array('name', 'id')));
$i=0;
foreach($players as $player){
$response[$i]['id']=$player['Player']['id'];
$response[$i]['label']=$player['Player']['name'];
$response[$i]['value']=$player['Player']['name'];
$i++;
}
echo json_encode($response);
}
visit below link ,this might help you as the ajax helper is no more in cake2.X versions core all related functionality moved to JS helper class.(here third one link for AJAX helper for contributed by user may help you)
http://bakery.cakephp.org/articles/matt_1/2011/08/07/yet_another_jquery_autocomplete_helper_2
or
http://nuts-and-bolts-of-cakephp.com/2013/08/27/cakephp-and-jquery-auto-complete-revisited/
or
http://bakery.cakephp.org/articles/jozek000/2011/11/23/ajax_helper_with_jquery_for_cakephp_2_x
You need to use ajax because your autocomplete-results depends on the team you have selected.
Something like this in jquery:
var team = $('#teamdropdown').find(":selected").text();
$.ajax({
type: "POST",
url: 'http://domain.com/playersdata',
data: {'team':team},
success: function(data){
console.log(data);
//put data in for example in li list for autocomplete or in an array for the autocomplete plugin
},
});
And in cake on playersdata page (Controller or model) something like this.
if( $this->request->is('ajax') ) {
$arr_players = $this->Players->find('all', array('conditions'=>array('team'=>$this->request->data('team')))); //pr($this->request->data) to get all the ajax response
echo json_encode($arr_players);
}
Also set headers to a json respons and $this->layout = null; to remove the layout tpl.
Another solution would be to use json_encode in your php and pass it to js-code like
<script>var players = <?php echo json_encode($array_players_with_teams); ?>; </script>
This solution is only interesting for a small amount of data, if you have a big database with teams and players I wouldn't recommend this, because why load all this data if you only need just a bit of it...
I didn't test the code but it should help you to go on...
Good luck!
I am trying to autopopulate a textarea with values from a (wordpress) database based on the value selected in a select menu. Basically the select menu contains a list of teams and I wish to populate my textarea with names of the players from the selected team.
The problem is that I need to convert the selected text to a php variable in order to use it to query the database. Like so:
PHP
$usergroups = $mingleforum->get_usergroups();
$team_title = $_GET['usergroup'];
$team_id = get_page_by_title( $team_title );
$players = get_users( array (
'meta_key' => 'team-meta',
'meta_value' => $team_id
));
JS
jQuery(function(jQuery){
jQuery('#usergroup').change(function() {
jQuery.ajax({
type: "GET",
url: "http://localhost:8888/dev_wordpress/wp-admin/admin.php?page=mfgroups&mingleforum_action=usergroups&do=add_user_togroup",
data: { usergroup: jQuery(this).find(':selected').text() }
}).done(function( msg ) {
alert( "Data Saved: " + msg );
});
});
});
UPDATE: corrected the url (based on #jterry 's comment) and no longer getting error (although it still isn't working)
I am getting the following error:
GET http://localhost:8888/dev_wordpress/wp-admin/wpf-addusers.php?usergroup=Coq+and+Bulldog 404 (Not Found)
For the points! :D
wpf-addusers.php doesn't exist at that path. Specify the absolute URI and you'll at least make it past the 404 error. Also, it looks like your url parameter has "" on both sides of the variable - you just need one on each side.
EDIT
To access the variable you're looking for (usergroup) to use in your PHP script, you can use $_GET['usergroup']. From there, you can use it as you see fit or insert it as the value of an input element.
If you use the value in an input element, be sure to use htmlentities to properly escape the value.
In a PHP MVC application, the model part has a city.php file that defines a city class.
The city class has a method to fetch all cities for a province i.e.
getCitiesByProvince('ProvinceId')
When the user selects a province from a province dropdown, I need to make an ajax call to getCitiesByProvince('ProvinceId') depending upon what value for Province Id was selected by the user inside the Province dropdown.
How do I do this?
Edit: 1) The page uses the GET method and not the POST method. 2) The controller file uses a switch($action) to execute a specific case. For example to fetch all cities
case 'cities': //Get all cities for a provinceId
$city= new city();
$cities = $City->getCitiesByProvince('ProvinceId');
echo json_encode($cities);
Action is probably a hidden html attribute that tells the php script what action/case to perform... maybe something like
<input type="hidden" name="action" value="cities" />
This is another developer's code that i'm not too familiar with at the moment and i'm just trying to guess how things work by looking into various files...
Have your PHP file do the following:
<?php
$province = $_GET['p'];
$cities = array();
$city_results = ... // fetch cities from database
foreach($city_results as $city_result) {
$cities[] = $city_result->city;
}
echo json_encode($cities);
?>
Have your Javascript do the following:
$.ajax({
type: "GET",
url: "php_url_path",
data: { p: get_province_here() },
success: function (cities) {
for (var i = 0; i < cities.length; i++) {
... // handle options here
}
}
});
This will create the inter-file connection that you seek. Enjoy and good luck!
You wouldn't be able to call this straight from the model insted you'd need to make an action in the controller called getcities or whatever and use $.ajax or $.get or $.post or $.getJSON to retreve the results assuming they'd be in json format heres an example using $.post
if your controller is citycntrl.php inside the controller you would do
//whatever logic to get an array of cities in whatever format you'd like
ex: '{zip}' => '{cityname}', or just {cityname} with regular keys
using the $_POST['providenceId']; key were sending with jQuery
What you'd want to do is run the array through json_encode($arrayname); and echo that out in your controller based on the providenceId post value.
Heres a better code example for your drop down senario i misread the first time and missed the drop down part
$.post('controller/getcities', {
provinceId: $('#{dropdownIDorCLASS}:selected').val();
}, function (data) {
//data will contain your list of cities passed down from your controller.
//do whatever with returned json data
}, 'json');
if I'm just confusing the crap out of you feel free to contact me on Skype and i hopefully assist a bit better UN: fallen.networks
Background
For the country field, the system detects and defaults to Canada. For the city field, the user types a Canadian city name, populated Facebook-style.
Both the country list and city list are populated using AJAX and JSON, sourced from a remote database using a proxy (queried via PHP).
The country is defaulted to the user's country of origin using MaxMind's GeoIP PHP API.
When the user selects a different country, its two-letter ISO code must be passed as a parameter to the city input so that the query that drives it can search for cities in the selected country.
For example, a user whose IP address is in Canada can choose the United States. When this happens:
the city field will be erased;
the city field gains focus; and then
only U.S. cities are displayed (as the user types).
Problem
The following PHP snippet proxies retrieval of the city list to a remote server:
echo file_get_contents( 'http://server/city.dhtml?q=' .
urlencode( $_GET['q'] ) );
The jQuery tokenInput function does not seem to provide a mechanism to pass additional content. The relevant jQuery snippets follow.
Acquire Countries
The following code gets a country code and a list of countries. It sets the user's country as the default country.
// Where in the world?
$.getJSON( 'geoip.dhtml', function( data ) {
country = data[0].id;
});
// Select from countries that have significant amounts of data.
$.getJSON( 'country.dhtml', function( data ) {
var h = '';
var len = data.length;
for( var i = 0; i < len; i++ ) {
var s = '';
// Make the person's own country the default selection.
if( data[i].id == country ) {
s = '" selected="selected"';
}
h += '<option value="' + data[i].id + s + '">' + data[i].name + '</option>';
}
$('#country').html(h);
});
Acquire Cities
The following code downloads the list of cities. The tokenInput function automatically passes the q parameter to the code inside the "local version" of city.dhtml (the PHP source code snippet is shown above). The q parameter is the text that the user types for the city.
$('#city').tokenInput( 'city.dhtml', {
hintText: "Type a city name.",
tokenLimit: 1,
classes: {
tokenList: "token-input-list-facebook",
token: "token-input-token-facebook",
tokenDelete: "token-input-delete-token-facebook",
selectedToken: "token-input-selected-token-facebook",
highlightedToken: "token-input-highlighted-token-facebook",
dropdown: "token-input-dropdown-facebook",
dropdownItem: "token-input-dropdown-item-facebook",
dropdownItem2: "token-input-dropdown-item2-facebook",
selectedDropdownItem: "token-input-selected-dropdown-item-facebook",
inputToken: "token-input-input-token-facebook"
}
});
The city.dhtml must to filter the cities by country code.
Question
How would you provide the country code to city.dhtml, without using a cookie?
Ideas
The latest version of the token input supports JSONP, would that be useful?
Thank you!
The problem is that the tokenInput URL parameter cannot be changed once the input has been set. While perhaps possible to delete the existing tokenInput and recreate it each time a new country is selected, the solution would be a hack.
The solution is to use a patch for the jQuery TokenInput that allows setting the URL parameter based on the result from a function call.
https://github.com/loopj/jquery-tokeninput/pull/77
Apply the patch and use the following code to change the query dynamically:
function cityURL() {
return 'city.dhtml?c=' + $('#country').val();
}
$('#city').tokenInput( cityURL, { /* ... */ });
And disable caching in jquery.tokeninput.js (near line 650):
//var cached_results = cache.get(query);
var cached_results = false;
Neat question, +1! What's keeping you from just doing:
$('#city').tokenInput('city.dhtml?c=' + $('#country').val(), { /* ... */ });
You probably need to enclose that within a onChange event, but it should work.