How to use Ajax and the HTML structure to echo autocomplete options? - javascript

I want to create an autofill search box. it gets a JSON and sends them to an HTML5 <datalist> of <option>s.
It works fine but it cant use spaces in values! so it just returns the first word. for example, if the jresults.name is "lets go" - I get only "lets".
What is the best way doing this?
This part: $( "#prod_name_list" ).children().remove(); prevents me of choosing an option from the list. because it deletes everything in it when I "keyup" so I need a different solution for this.
The second part is after submitting the form I want to get the id chosen of the object. (jresults.id) and I'm not sure how to retrieve it with the submit.
MY CODE:
JS part:
$("#prod_name").bind("keyup", function(e) {
if (e.which <= 90 && e.which >= 48){
$( "#prod_name_list" ).children().remove();
var prod_name = $("#prod_name").val();
$.ajax({
method: "POST",
url: "<?php echo site_url('kas/search_prod_name'); ?>",
data: ({ "prod_name": prod_name }),
success: function (result){
var jresults = JSON.parse(result);
console.log("jresults: "+jresults);
var lng = jresults.length;
console.log("lng: "+lng);
for (var i=0; i<lng; i++) {
if (jresults.hasOwnProperty(i)) {
console.log("name: "+jresults[i].name);
$("#prod_name_list").append("<option name=\"prod_id\" id="+jresults[i].id+">"+jresults[i].name+"</option>");
}
}
}
});
}
});
HTML part(using codeigniter syntaxes for the form:
<?php
$attributes = array('class' => 'prod_name', 'id' => 'prod_name', 'name' => 'prod_name', 'list' => 'prod_name_list');
echo form_input('prod_name', 'prod Name', $attributes);
?>
<datalist id="prod_name_list">
</datalist>

A few things to work on here, but let's jump into a working example: https://jsfiddle.net/Twisty/a2z7e1yb/
The HTML I tested with:
Name: <input class="prod_name" id="prod_name" name="prod_name" list="prod_name_list" />
<datalist id="prod_name_list">
</datalist>
The JQuery I would advise using:
$(document).ready(function() {
$("#prod_name").keyup(function() {
$.ajax({
method: "POST",
url: "<?php echo site_url('kas/search_prod_name'); ?>",
data: {
"prod_name": $("#prod_name").val();
},
success: function(result) {
console.log(result);
var options = "";
$.each(result, function(k, v) {
console.log("name: " + v.name);
options += "<option value='" v.name + "'>\r\n";
});
console.log(options);
$("#prod_name_list").html(options);
}
});
});
});
As was mentioned, you can use onKeyPress versus onKeyUp. I leave that up to you.
I did testing with test data that looked like:
[
{
"name": "Lets Go"
}, {
"name": "Go More"
}
]
The $.each() works well for this. It will iterate over each array item and place it's Key into k and each object into v. We then generate a string of all the options and replace whatever is inside our datalist So if the result set is 15 options on the first character, it would be replaced ion the next keystroke with whatever result set we get.
Using .remove() and .append(), in my mind, becomes cumbersome for this type of application. You want to remove all the options, or replace them, with whatever new data you receive. In my working example, when a key is pressed, we see:
<datalist id="prod_name_list">
<option value="0">Lets Go</option>
<option value="1">Go More</option>
</datalist>
I hope this is clear and helps you out. If it's not, leave a comment and let me know.
Update
I think you may be using the <datalist> tag incorrectly. It should be fully populated when the page loads, not after text is entered. See more here: https://developer.mozilla.org/en-US/docs/Web/HTML/Element/datalist
It should be used like so: https://jsfiddle.net/Twisty/a2z7e1yb/2/
<label>Name:
<input class="prod_name" id="prod_name" name="prod_name" list="prod_name_list" /></label>
<datalist id="prod_name_list">
<option value="Let's Go" />
<option value="No Go" />
<option value="Go Back to Bed" />
</datalist>
If you really want to make it like JQuery UI's Autocomplete, you would build a <ul> or <div> with the results as a list inside. This list would be populated when a key is pressed, showing just the relevant results. For example if "L" was pressed it would sen that value to your PHP which would show "Let's Go" and any other product Names that begin with "L". It's different than <datalist> which looks for anything in your List that contains "L".

Related

value of an option appended to a select ends with " before the fetched value ends

I'm fetching some data using ajax from my database, the problem is when I append an option to a select with a value containing these data, the append ends the first word with " thus the rest is left outside the value tag.
Here's the empty select:
<select name="Sender" id="SenderNames" class="form-control" style="width: 100%;"></select>
This is the jQuery code:
$('#SenderSelect').on('change', function() {
$.ajax({
type: "POST",
url: 'operations/inner-operations/getNamesByService.php',
data: { action :"getService", "serviceName" : $("#SenderSelect option:selected").val() },
success: function(data) {
var responseObj = jQuery.parseJSON(data);
console.log(responseObj);
$.each(responseObj, function(i, value) {
$("#SenderNames").append('<option value='+value+'>'+value+'</option>');
});
}
});
});
The appended option should look like this:
<option value="First Second">First Second</option>
However, it is appended like this:
<option value="First" second="">First Second</option>
I just realised that I'm not closing the string properly. The append should be like this:
$("#SenderNames").append('<option value="'+value+'">'+value+'</option>');
the value tag must be wrapped by "".

Is this a proper way of using AJAX with jQuery and PHP?

I need some help. I'm going use AJAX (for the first time) and I'd like you to tell me whether the way I am going to show you is optimal.
Let's say that I have a select element.
<select class="update-db" data-id="25" data-original-value="2">
<option value="1">Yellow</option>
<option value="2" selected="selected">Red</option>
<option value="3">Blue</option>
</select>
So here is what I do:
$(document).on('change', 'select.update-db', function() {
// Get needed data
var select = $(this);
var id = select.attr('data-id');
var originalValue = select.attr('data-original-value');
var newValue = select.val();
// Perform the request
$.ajax({
method: 'POST',
url: 'update-db.php',
data: { id: id, 'original-value': originalValue, 'new-value': newValue }
});
// Then, if everything is okay, change the "original value" of the select element
// so that we can perform the updating operation again without having to refresh the page
.done(function() {
select.attr('data-original-value', newValue);
});
});
Then, on the other side, a PHP script validates everything and updates the database.
Is this the correct way of using AJAX? I feel it's not. What am I doing wrong?

How to incorporate filling in saved values on autocomplete selects

I have an autocomplete of 2 selects. The first one you make a choice and it populates the second one based on that choice.
My is this, I can save the record on my submit data but how do I get the saved values for that record and make those values the selected ones. Here is my code for the autocomplete part.
Here is the html for the 2 fields.
<div>
<label for="incimechtype">Incident Mechanism Type</label>
<select class="ehselect" name="incimechtype" id="incimechtype">
<option></option>
<option value="Mechanism">Mechanism</option>
<option value="Object">Object</option>
<option value="Other">Other</option>
</select>
<label for="injmechid">Incident Mechanism</label>
<select id="injmechid" name="injmechid">
</select>
</div>
here is the ajax jquery script
$(function(){
$("#incimechtype").change(function(){
var dropdown = $(this).val();
$.ajax({
url:"getinjuryjson.php",
dataType: "json"
}).done( function(data){
$("#injmechid").find("option").remove();
if(dropdown !== ""){
$("#injmechid").append($('<option/>'));
}
switch(dropdown){
case "Mechanism":
$.each(data, function(key,value){
if(value.injmech==='Mechanism'){
$("#injmechid").append($('<option/>',{
value: value.injmechid,
text: value.injmechdescrip
}));
}
});
break;
case "Other":
$.each(data, function(key,value){
if(value.injmech==='Other'){
$("#injmechid").append($('<option/>',{
value: value.injmechid,
text: value.injmechdescrip
}));
}
});
break;
case "Object":
$.each(data, function(key,value){
if(value.injmech==='Object'){
$("#injmechid").append($('<option/>',{
value: value.injmechid,
text: value.injmechdescrip
}));
}
});
break;
}
}
)
}
)
}
);
And here is the php code.
<?php
include('common.php');
if(!($_SESSION['incident']['mechenisms'])){
$query = "select injmechid,RTRIM(injmechdescrip)injmechdescrip,RTRIM(injmech)injmech from hrs.injurymech";
$result = sqlsrv_query($link,$query,array(),array( "Scrollable" => 'static' )) or die('Cannot get injury mechanism list');
while ($row = sqlsrv_fetch_array($result,SQLSRV_FETCH_ASSOC)){
$_SESSION['incident']['mechenisms'][] =$row;
}
}
echo json_encode($_SESSION['incident']['mechenisms']);
Now how in the world do I incorpate the stored record data to select the right choices in the form when I go to edit a saved form.
I am thinking I connect a variable to the ajax call and then query the database for the 2 field values and then somehow have those values selected if they exist.
I figured it out. I did not do it through the ajax. I did it using php on the page load.
I ended up using php to populate the answers. I left the dynamic ajax in place if the answer was to change.

How to set default value on an input box with select2 initialized on it?

How do I set default value on an input box with select2? Here is my HTML:
<input type="text" id="itemId0" value="Item no. 1">
and my javascript:
$("#itemId0").select2({
placeholder: 'Select a product',
formatResult: productFormatResult,
formatSelection: productFormatSelection,
dropdownClass: 'bigdrop',
escapeMarkup: function(m) { return m; },
minimumInputLength:1,
ajax: {
url: '/api/productSearch',
dataType: 'json',
data: function(term, page) {
return {
q: term
};
},
results: function(data, page) {
return {results:data};
}
}
});
function productFormatResult(product) {
var html = "<table><tr>";
html += "<td>";
html += product.itemName ;
html += "</td></tr></table>";
return html;
}
function productFormatSelection(product) {
var selected = "<input type='hidden' name='itemId' value='"+product.id+"'/>";
return selected + product.itemName;
}
Here is the issue:
If I won't initialize my input box into a select2 box, I can display the default value of my input box which is "Item no. 1":
but when I initialize it with select2 eg. $("#itemId0").select2({code here}); I can't then display the default value of my text box:
Anyone knows how can I display the default value please?
You need to utilize the initSelection method as described in Select2's documentation.
From the documentation:
Called when Select2 is created to allow the user to initialize the selection based on the value of the element select2 is attached to.
In your case, take a look at the Loading Remote Data example as it shows how to incorporate it along with AJAX requests.
I hope this helps.
Old initial selections with initSelection
In the past, Select2 required an option called initSelection that was
defined whenever a custom data source was being used, allowing for the
initial selection for the component to be determined. This has been
replaced by the current method on the data adapter.
{
initSelection : function (element, callback) {
var data = [];
$(element.val()).each(function () {
data.push({id: this, text: this});
});
callback(data);
}
}
You can use the set value too.
You should directly call .val on the underlying element
instead. If you needed the second parameter (triggerChange), you
should also call .trigger("change") on the element.
$("select").val("1").trigger("change"); // instead of $("select").select2("val", "1");
Refs:
https://select2.github.io/announcements-4.0.html
https://github.com/select2/select2/issues/2086
http://jsfiddle.net/F46NA/7/
If you have an input element, declare it as follows. Remember to populate the value field as well.
<input type="hidden" name="player" id="player" data-init-text="bla bla" value="bla bla" >
Write an initSelection function
initSelection : function (element, callback) {
var elementText = $(element).attr('data-init-text');
callback({"text":elementText,"id":elementText});
}
make sure that this call back has same key value pair as the one return by the ajax call.
callback({"text":elementText,"id":elementText});
I have noticed that keeping the value field empty will keep the input empty by default so remember to populate it as well.
The method initSelection can not have an empty value attribute to work properly.
That was my problem.
Hopefully this will help someone.
You can easily change the value of your select input by just putting the id's of your selected option in data attribute of your select input. And then in javascript
var select = $('.select');
var data = $(select).data('val');
$(select).val(data);
And after that initialize select2 on your select input
$(select).select2();
Here is the fiddle https://jsfiddle.net/zeeshanu/ozxo0wye/
you dont need ajax or json, you just need to put SELETED tag into your OPTION and SELECT2 will display the init value.
This works for me: 'Add default value to the head of array'
data.unshift({'id':-1, 'name':'xxx'});
$('#id_xxx).select2({
placeholder: '--- SELECT ---',
data: data,
allowClear: true,
width: '100%'
});
However, official doc says:
You can set default options by calling $.fn.select2.defaults.set("key", "value").
There is no example though.
I found the extremly simple solution.
You have to pass the ID and the Name of the default option and insert it like HTML inside
var html = ' <option value="defaultID">defaultName</option>';
$(".js-example-basic-single").html(html);
How to get defaultID or defaultName depends on your code.
For instance in ASP .Net MVC you can do it like
<select id="PersonalID" class="js-example-basic-single form-control form-control-sm" name="PersonalID">
<option value="#Model.PersonalID">#ViewBag.PersonalInfo</option>
</select>
I use another approach in this specific configuration:
- multiple="multiple"
- populating from AJAX on user's search
$("#UserID").select2({
placeholder: 'Input user name',
"language": {
"noResults": function () {
return "Sorry, bro!";
}
},
dropdownParent: $("#UserID").parent(),
ajax: {
delay: 200,
url: '#Url.Action("GetUserAsJSON", "AppEmail")',
cache: true,
dataType: 'json',
data: function (params) {
var query = {
search: params.term,
page: params.page || 1
};
// Query parameters will be ?search=[term]&page=[page]
return query;
}
}
});
There are few steps to get working my solution
1) Keep each added value in a global array.
var selectedIDs = new Array();
$("#UserID").on('change', function (e) {
//this returns all the selected item
selectedIDs = $(this).val();
});
2) So when you save data you always have selectedIDs array.
3) When you refresh/load webpage just populate selectedIDs with saved data for later resaving/editing from one hand and from another hand populate select2 object
In my case of ASP MVC it looks like this but you can use JQuery to insert <option> to <select>.
<select id="UserID" class="js-example-basic-multiple form-control border" name="UserID" style="width:100%!important;" multiple="multiple">
foreach (var item in Model.ToUsers)
{
<option selected="selected" id="#item.ID" value="#item.ID">#item.Value</option>
}
</select>

Get select selected value

I have a url like this:
index.php/home/lista_modelo_ajax?id="+$('#colecoes').val(),
The thing is that the: $('#colecoes').val() is always the first item of the select, not the one I choose.
Any ideas?
Thanks in advance.
EDIT
<script>
$(function() {
$( "#modelos" ).autocomplete({
source: "<?php echo base_url();?>index.php/home/lista_modelo_ajax?id="+$('#colecoes').val(),
minLength: 2
});
});
</script>
<label for="colecoes">Coleções</label>
<select name="colecoes" id="colecoes">
<option value="16">-</option>
<?php foreach($lista_colecao as $colecao){?>
<option value="<?php echo $colecao->idColecao;?>"><?php echo $colecao->nomeColecao;?></option>
<?php }?>
</select>
<label for="modelos">Modelo</label>
<input type="text" name="modelos" id="modelos" />
All php is working fine, generating the IDs on the value of options objects, the problem is only with JS
This will depend on where you are writing this code. If you are writing it directly in the document ready that would be normal as at the moment this code executes that's the selected value. On the other hand if you are writing it for example in the .change event of the dropdown list you will get the actual value:
$('#colecoes').change(function() {
var id = $(this).val(); // now you will get the actual selected value
$.ajax({
url: 'index.php/home/lista_modelo_ajax',
data: { id: id },
success: function(result) {
...
}
});
});
Just do:
$('#colecoes').val(); //assuming `colecoes` is the id of the select
Example with onchange:
$('#colecoes').change(function(){
alert(this.value); //alerts the selected option
});

Categories