In my user table I have id_user and name. My autocomplete searches only by name. I need id_user to input into the database. Usually, we can write id_user as a value attribute in the input tag. This is the code :
Controller :
function get_autocomplete(){
if (isset($_GET['term'])) {
$result = $this->User_model->search($_GET['term']);
if (count($result) > 0) {
foreach ($result as $row)
$arr_result[] = $row->name;
echo json_encode($arr_result);
}
}
}
Model :
function search($name){
$this->db->like('name', $name , 'both');
$this->db->order_by('name', 'ASC');
$this->db->limit(10);
return $this->db->get('user')->result();
}
View :
<input type="text" id="name" placeholder="Name" name="id_user">
<script type="text/javascript">
$(document).ready(function(){
$( "#name" ).autocomplete({
source: "<?php echo site_url('admin/user/get_autocomplete/?');?>"
});
});
</script>
You can fill the autocomplete options with Label/Value pairs.
So the options show the label (e.g. username) and when the user selects one option the value (e.g. id_user) is written to the input field (= the value and is therefor it's displayed in the input field)
So your php code should return a JSON array with label/value pairs
foreach ($result as $row)
$arr_result[] = array('label' => $row->name, 'value' => $row->id_user);
}
echo json_encode($arr_result);
Please take a look at my jsfiddle example - it shows the autocomplete with static data
https://jsfiddle.net/jf7ynxwz/3/
If you don't like the user_id to be written into the input (visible) it's a little bit more complicated. Have a look into the documentation and maybe set the value as an data-html attribute of the input after selection :-)
Related
Hey Developers i'm building a application form where the user input data into the different fields. One part of the application is a dynamic form from https://github.com/wbraganca/yii2-dynamicform. Now inside the dynamic form i have a dependent drop down but when i click the [+] sign the dependent drop down change data on the first row and not the second.
Here's my code.
in my controller
public function actionLists($name)
{
$countHs= Hs::find()
->where(['hscode'=> $name])
->count();
$Hs = Hs::find()
->where(['hscode'=> $name])
->all();
if($countHs > 0)
{
foreach ($Hs as $H)
{
echo "<option value='".$H->hsproduct."'> ".$H->hsproduct."</option>";
}
}else{
echo "<option> - </option>";
}
}
and my form
<div class="col-sm-6" style="width: 135px">
<?= $form->field($modelsItems, "[{$i}]hscode")->dropDownList(
ArrayHelper::map(Hs::find()->all(),'hscode','hsproduct'),
[
'prompt'=>'',
'onchange'=>
'$.get( "'.Url::toRoute('/hs/lists').'", { name: $(this).val() })
.done(function( data ) { $( "#'.Html::getInputId($modelsItems, "[{$i}]hsproduct").'" ).html( data ); } );'
])->label('HS.Code');
?>
</div>
<div class="col-sm-6" style="width: 135px">
<?= $form->field($modelsItems, "[{$i}]hsproduct")->dropDownList(
ArrayHelper::map(Hs::find()->all(),'hsproduct','hsproduct'),
[
'prompt'=>'',
])->label('HS.Product');
?>
</div>
Im a newbie sorry for my english
Updated for your case.
What I did was I declared global variable in JS file var i and assigned 0. After the first event is fired, I increase variable i by one. Now it contains 1 in memory. Next time it will take 1 and add 1 again. And so on:
var i = 0;
$(document).on('change', 'select', function(e) {
i++;
})
Note that this will only work if you choose in each row just once and you will not come back to specific row. If you want to do something like that, you should instead get element ID's number, parse to float (instead of string) and use that number to your event script.
parseFloat($('#hs-0-hscode')[0].id.split('-')[1])
Leaving below one additional solution (but not according to yours). Just in case.
Use Inspect source and find how your input fields are named (name or ID). Let's say, we have name="hs-0-hscode". This is for just Then your jQuery:
$(document).on('change', 'select', function(e) {
if ($(this)[0].id.indexOf('hscode') > 0) {
// Now you can use Ajax to get a list of items you want to show.
// Element itself can be reached: $(this).parent().parent().parent().children().eq(1);
// For example:
// var data = $.parseJSON(results);
// $.each(data, function(key, value) {
// $('#client-company_size')
// .append($("<option></option>")
// .attr("value", key)
// .text(value));
// });
}
});
I amn reading and testing but I still cannot get a grip on how to use the typeahed customization, I want to do show in the dropbox more than just 1 field, and use the ID to do the search.
<script>
$(document).ready(function(){
$("#search").typeahead({
name : 'imei',
remote: { url : 'pruebasql.php?query=%QUERY' }
});
});
</script>
<body>
Imei: <input type="text" name="search" id="search" autocomplete="off">
<input type="text" name="equipid" id="equipid" hidden>
</body>
And I get my json encoded array from a php query
<?php
include('inc/config.php');
$con=mysqli_connect("localhost",$user,$pass,$database);
$result = $con->query("SELECT imei,equipid,modelo FROM equipos WHERE imei LIKE '%{$query}%' or modelo LIKE '%{$query}%' or marca LIKE '%{$query}%' LIMIT 0,10");
$a_json_row = array();
$user_arr = array();
while ($row = $result->fetch_object()){
$a_json_row["id"] = $row->equipid;
$a_json_row["value"] = $row->modelo;
$a_json_row["label"] = $row->equipid.' '.$row->modelo;
array_push($user_arr, $a_json_row);
$user_arr2[] = $row->modelo;
}
$result->close();
echo json_encode($user_arr);
?>
and this is what I got from the php:
{"id":"179","value":"IPHONE 6","label":"179 IPHONE 6"},{"id":"180","value":"I9300","label":"180 I9300"
},{"id":"182","value":"XPERIA Z1","label":"182 XPERIA Z1"},{"id":"183","value":"i9300","label":"183 i9300"
},{"id":"186","value":"i9300","label":"186 i9300"},{"id":"188","value":"i9505","label":"188 i9505"},
{"id":"204","value":"IPHONE 6","label":"204 IPHONE 6"},{"id":"206","value":"535F","label":"206 535F"
}]
I have NO idea on how to show the label from the json, and be able to show use value and id on the form.
This is what I get now
I am trying this:
var users = {};
var userLabels = [];
$( "#search" ).typeahead({
source: function ( query, process ) {
//the "process" argument is a callback, expecting an array of values (strings) to display
//get the data to populate the typeahead (plus some)
//from your api, wherever that may be
$.get( "pruebasql.php?query=%QUERY", { q: query }, function ( data ) {
//reset these containers
users = {};
userLabels = [];
//for each item returned, if the display name is already included
//(e.g. multiple "John Smith" records) then add a unique value to the end
//so that the user can tell them apart. Using underscore.js for a functional approach.
_.each( data, function( item, ix, list ){
if ( _.contains( users, item.label ) ){
item.label = item.label + ' #' + item.value;
}
//add the label to the display array
userLabels.push( item.label );
//also store a mapping to get from label back to ID
users[ item.label ] = item.value;
});
//return the display array
process( userLabels );
});
}
, updater: function (item) {
//save the id value into the hidden field
$( "#equipid" ).val( users[ item ] );
//return the string you want to go into the textbox (e.g. name)
return item;
}
});
but got an error, the source part is my big problem.
I'm using jquery autocomplete on an input form 'city' but i would like the query in my 'autocity.php' file to only suggest cities in the pre selected country i.e. WHERE City LIKE '%$term%'" AND CountryID = '%$country%'. The form action submit uses a separate PHP file (create-business.php) for inserting the form data to the database so the usual $_POST['Countries_CountryId'] wouldn't work in the autocity.php. that's why i'm now using AJAX to post 'country' to autocity.php. Also it would be great to have a way to echo/alert/print_r from the the autocity.php file so i can confirm that the $_POST['$country'] from the ajax post reaches the autocity.php file.
I have two input boxes in the form
<pre>`
<form id="input" action="php/create-business.php" method="post">
<select name="Countries_CountryId" id="country">
<input type="text" id="city" name="City">`
</pre>
Here is the script from the form
<script>
$(function () {
var country = $("#country").val();
$.ajax({
type:"POST", url:"autocomplete/autocity.php", data:"country",
beforeSend:function () {
// alert(country);
}, complete:function () { // is there any need for this?
}, success:function (html) { // is there any need for this too?
}
});
$("#city").autocomplete(
{
source:'autocomplete/autocity.php'
})
});
</script>
And here is autocity.php
`
//database connection works fine and autocomplete
//suggestion works without the AND CountryID = '%$country%' part.
$country = "";
if (isset($_POST['country'])) {
$country = trim($_POST['country']);}
echo "window.alert($country);"; //This did nothing no alert
$term = $_REQUEST['term'];
$req = "SELECT City
FROM cities
WHERE City LIKE '%$term%' AND CountryID = '%$country%'";
$query = mysql_query($req);
while ($row = mysql_fetch_array($query)) {
$results[] = array('label' => $row['City']);
}
echo json_encode($results);
?>`
So the question is basically:
1 - how can i use a text input from a form using AJAX in a .php file that queries a MySQL db that is not the submit form action .php file
2 - how can i alert the post variable from the PHP file when ajax is used to show that the php file recieves my ajax post. In my brief experience echo and print_r only work on form submit when the web page changes showing the result of my form submit ont the form action.
3- how is my syntax?
Thank you very much in advance for helping this novice out :D
Ok here is my update on things i've tried. I think i'm close. i'm using Jquery UI -
//ajax.googleapis.com/ajax/libs/jqueryui/1.10.0/jquery-ui.min.js
here is the script method 1:
$(document).ready(function () {
var country = $('#country').value();
alert(country + " complete");
$("#city").autocomplete(
{
source:'autocomplete/autocity.php?country='+country,
minLength:1
});
});
here is the script method 2:
$(document).ready(function () {
$('#city').autocomplete({
// source: function() { return "GetState.php?country=" + $('#Country').val();},
source:function (request, response) {
$.ajax({
url:"autocomplete/autocity.php",
//dataType:"json",
data:{
term:request.term,
country:$('#country').val()
},
success:function (data) {
response(data);
}
});
},
minLength:2
});
});
I like method 2 more since it will allow me to add more than one parameter.
Finally here is my latest autocity.php code
<?php
$term = $_REQUEST['term'];
$country = $_REQUEST['country'];
$req = "SELECT City
FROM cities
WHERE City LIKE '%$term%' AND CountryID = '%$country%' ";
$query = mysql_query($req);
while ($row = mysql_fetch_array($query)) {
$results[] = array('label' => $row['City']);
}
echo json_encode($results);
?>
I'm still totally stuck though. can anybody see the problem with the code? Ive looked everywhere online for the right syntax. Thanks again
For the first problem, your approach is essentially correct. You can bind to the blur event for a particular field and use your function to get that field's value and submit to the php script much in the manner that you are doing so. $.blur() is what you're looking for.
For the second problem the error_log function will write stuff to php's error log. IF you use print_r to dump variables to this log, make sure to set print_r's second argument to true to output the result as the return value.
I am using jQuery Tag-it! to create a "Skills" input form for my users. I have the UI of tag-it working, but I cannot get the user input into a PHP array. I am trying to serialize this array and save it to a mysql database for displaying later, but I can't even get the data into an array.
Here is the javascript initializing tag-it:
$('#skills').tagit({
allowSpaces: true,
placeholderText: "Separate skills with a comma please",
autocomplete: true
});
Here is the HTML:
<div>
<label class="add_label">Skills: </label>
<ul id="skills" style="width: 275px; margin-bottom: 8px;"></ul>
</div>
This is the javascript that creates the input field where the user input is supposed to be stored:
if (!this.options.singleField) {
var escapedValue = label.html();
tag.append('<input type="hidden" style="display:none;" value="' + escapedValue + '" name="' + this.options.fieldName + '" />');
}
And this is the PHP which gets the user input -- this is the part that is not working. I cannot retrieve ANY data from the form:
$skillsArr = $link->real_escape_string($_POST['skills']);
When I do submit the form, the mysqli query executes and in the database I see "N;" where the serialized array should be.
How can I get the jQuery Tag-it values into a PHP array that I can serialize and save to a mysql database?
The problem is that tag-it will by default send the post request with data like this:
tags=foo&tags=bar&tags=blah
PHP will interpret that by making $_POST['tag'] ='blah'. For PHP to handle it like an array the post data needs to look like:
tags[]=foo&tags[]=bar&tags[]=blah
The easiest way to solve this is just by changing the fieldName parameter when you setup tag-it, such as:
$('.taglist').tagit({
allowSpaces: true,
placeholderText: 'add new tag here...',
fieldName: 'tags[]'
});
By simply changing the name to include the [] then it'll be interprested as you want by PHP and be an array.
Alternatively, if you're not able to adjust that you could always process the raw PHP data to get the tags as an array, like:
$query = array();
foreach (explode('&', file_get_contents('php://input')) as $kv) {
list($k, $v) = explode('=', $kv);
$k = urldecode($k);
$v = urldecode($v);
if (!isset($query[$k])) {
$query[$k] = $v;
} else {
if (is_array($query[$k])) {
$query[$k][] = $v;
} else {
$query[$k] = array($query[$k], $v);
}
}
}
Now $query['tags'] will be an array as expected.
NB: If only one tag is sent then it'll end up being a string with the above code, so just make sure you cast it as an array if the result is going in a loop or something:
foreach((array)$query['tags'] as $tag) ...
I found it easier to just do all the queries on the backend (php/mysqli).
That way the only thing I needed in my jQuery autocomplete was:
<script>
$(document).ready(function(){
$("#tagit").tagit({
autocomplete: {
source: "ajax-search.php",
}
});
});
</script>
I just defined the source of the file. You can add the delimiter, etc to this as you want (I just modded the source instead).
But the primary function is from the php file, which returns a JSON encoded result.
<?php
include("dbconnect.php"); //Including our DB Connection file
if ( !isset($_REQUEST['term'])) //if there's no search, exit
exit;
$keyword = trim($_REQUEST['term']);
$keyword = mysqli_real_escape_string($db, $keyword);
$query = "SELECT * FROM animals WHERE english LIKE '%$keyword%' LIMIT 10";
$result = mysqli_query($db, $query); //Run the Query
$data = array(); //initialize array
if ($result && mysqli_num_rows($result)){
while($row = mysqli_fetch_assoc($result)){
$data[] = array(
'id' => $row['row_id'],
'label' => $row['english'], //This is the 'live return of the search
'value' => $row['eng_dir'], //The value returned. Not needed if you're returning the label
'latin' => $row['latin'] //Another result (you can add more)
);
}
}
echo json_encode($data);
flush();
?>
Then inside the tag-it.js file you can select what you want to push as a tag:
if (this.options.availableTags || this.options.tagSource || this.options.autocomplete.source) {
var autocompleteOptions = {
select: function(event, ui) {
that.createTag(ui.item.id); //pushes the ID
that.createTag(ui.item.value); //pushes the value
that.createTag(ui.item.label); //pushes the label
that.createTag(ui.item.latin); //pushes the extra variable
// Preventing the tag input to be updated with the chosen value.
return false;
}
};
$.extend(autocompleteOptions, this.options.autocomplete);
The code above will return 4 instances of the same tag depending on your result.
I am using jQuery to create as many input textboxes as the user needs like so:
<script type="text/javascript">
$(document).ready(function() {
$('#names').on({
blur: function() {
var name = $("<p><input class='input' type='text' /></p>")
var nullFields = 0;
$(this).closest('div#names').find('input.input').each(function(){
if($(this).val() == ""){
nullFields++;
}
});
console.log(nullFields);
if(nullFields <= 1){
$('#names').append(name.fadeIn(500));
}
}
}, 'input');
});
</script>
Inserting a static textbox into a database isn't a problem using $_POST['blah'] andmysql_query("INSERT INTO ..."), but how do I insert the values of the dynamically created textboxes? I know I'll have to give the textboxes different names as they're created and I presume the MySQL query will be by way of some sort of loop.
EDIT
The website in question is here, specifically at step 4. As mentioned above, step 3 was quite straightforward.
This is an example to get you started, not the complete solution.
You create an array for the names then have the php insert each array item
var currentArrayNum = 1;
$('#someClickable').click(function(){
$('#td').append('<input name="arrayName['+currentArrayNum+']" value="" />');
currentArrayNum += 1;
});
php:
foreach ($_POST as $key){
if (is_array($key)){
foreach ($key as $key2 => $value){
//$key2 will equal arrayName[currentArrayNum]
//$value will equal the user input for the text field
do some stuff
}
You can create arrays out of name, simply try this:
<input type="text" name="post_input[input_1]" value="">
<input type="text" name="post_input[input_2]" value="">
After Submit, you would get an Array out of $_POST["post_input"] with the keys input_1 and input_2 and their assigned values. Then you just loop them as a normal array, for example
$aTextFields = $_POST["post_input"];
foreach( $aTextFields as $sValue ) {
...
}