Change Dynamic field of Typeahead - javascript

I'm programming a form with dynamic typeaheads fields, and i have found a problem when i want to show and select the suggestions.
I have two first fields, a input select and a input typeahead. When a option is selected, it's load a list of values in the input typeahead. The problem comes when i create(dynamically) a clone of this pair of fields and i want to get de list of values in the correct typeahead.
I get the id of the field (idTypeAhead) when i focus in the field and i use it in the typeahead.
This is the code:
//TYPEAHEAD
$('input.typeahead').focus(function(){
idTypeAhead = parseInt($(this).attr('id').replace('typeAhead_',''));
selectAttr = $('select#selectAttr_'+idTypeAhead).find('option:selected').val();
if(selectAttr=="null"){
selectAttr=0;
}
});
$("input#typeAhead_"+idTypeAhead).on("typeahead:select").typeahead({
name:'input#typeAhead_'+idTypeAhead,
displayKey: 'input#typeAhead_'+idTypeAhead,
input: 'input#typeAhead_'+idTypeAhead,
container:'input#typeAhead_'+idTypeAhead,
display: $(this),
suggestion: $(this),
minLength : 1,
sorter : this.query,
source : function(query, process){
return $.ajax({
url:'/aplicaciones/jsonValorAttr?selectAttr='+selectAttr,
dataType: 'json',
type:'POST',
success: function(data){
states = [];
map = {};
$.each(data, function (i, state) {
map[state] = state;
states.push(state);
});
process(states);
}
});
}
});
I have this code in form (i use Spring STS). Also i have two buttons "+" and "-". When i click "+", i clone this two fields and increase de id number of each element. When i click "-", i remove a pair of fields. (example: selectAttr_101 ->newclone: selectAttr_102).
<div class="controls">
<form:select path="rolHerramientaID" id="selectAttr_101" cssClass="field-required lstAtributos" cssErrorClass="select-error">
<form:option value="null" selected=""><spring:message code="altaAplicacion.form.seleccionar" />
</form:option>
<c:forEach var="selectAtributos" items="${resultAtributos}" varStatus="rowCount">
<form:option value="${selectAtributos.atributosId}">${selectAtributos.nombreAtributo}</form:option>
</c:forEach>
</form:select>
<form:errors path="rolHerramientaID" class="help-block" /></div>
</div>
<div class="control-group required">
<label for="input01" class="control-label"><spring:message code="altaAplicacion.form.valor" /></label>
<div class="controls">
<input id="typeAhead_101" class="input-medium typeahead" type="text" data-provide="typeahead" autocomplete="on">
</div>
How can i change the container of the typeahead dynamically?

I've been searching for the solution for this problem and found your post, with some small changes that worked for me.
I've stated the fixed input field in the form as typeAheadId_1 and created a function before create the typeahead object to manipulate the typeahead index.
on the insert operation, I increase the counter and destroy the typeahead object before each dynamic fields wrapping and recreate the typeahead object
(passing the counter) after the fields creation.
For edition (some dynamic fields are created direct in the form), I've created a REST service to return how many fields were wrapped and start counting from this.
It worked perfect for me.
If you didn´t solve or need some help, please let me know!

Following codes are working for me -
var typeaheadSettings = {
source: function (query, result) {
$.ajax({
url: "{{url('/work-order/get_parts_suggestion')}}",
data: 'txt=' + query,
dataType: "json",
headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') },
type: "POST",
success: function (data) {
result($.map(data, function (item) {
return item;
}));
}
});
}
};
$('.typeahead').typeahead(typeaheadSettings); /* init first input */
$('.typeahead').on('added',function(){
$('.typeahead').typeahead(typeaheadSettings);
});
add this line after appending/creating dynamic element -
$('.typeahead').trigger('added');
Reference - https://www.bootply.com/61431

Related

How to populate input fields dynamically created based on another one after an AJAX request is done?

I have this HTML code that dynamically adds barcode[] and description[] input fields to my form, using the onfocusout event, the get_barcode_data JS function below is triggered to get the barcode description, but it only works for a single barcode[] input field:
<div>
<input type="text" id="barcode[]" name="barcode[]" onfocusout="get_barcode_data(this);"/>
</div>
<div>
<textarea id="description[]" name="description[]" disabled="disabled"></textarea>
</div>
<div align="center">
</div>
The console.log(name) call displays the value I entered on any of the dynamically created barcode[] input fields and the request is successfully done but after that I don't know how to point the response to the right barcode[] and description[] fields:
function get_barcode_data(element)
{
var name = element.value;
console.log(name);
$.ajax({
method: 'POST',
url: 'include/get_barcode_data.php',
data: {
barcode: name
},
success: function(response){
if (response == 'FALSE') {
$('#barcode[]').focus();
$('#barcode[]').val('');
$('#description[]').val('');
var message = 'Invalid barcode.';
alert( message );
} else {
var res = jQuery.parseJSON(response);
$('#description').val(res.description);
}
}
});
}
Any ideas on how to solve this would be much appreciated.
Like James pointed out in the comment section, you cant have duplicate IDs in your document. You should either generate unique IDs for each element, or remove the IDs altogether.
If you generate unique IDs, you can pass the generated ID to your event handler and use it to select the correct element.
<div>
<input type="text" id="barcode_123" name="barcode[]" onfocusout="get_barcode_data(this, 'description_123');"/>
</div>
<div>
<textarea id="description_123" name="description[]" disabled="disabled"></textarea>
</div>
<div align="center">
</div>
123 should be a dynamically generated number.
And in your handler:
function get_barcode_data(element, target_id)
{
var name = element.value;
console.log(name);
$.ajax({
method: 'POST',
url: 'include/get_barcode_data.php',
data: {
barcode: name
},
success: function(response){
if (response == 'FALSE') {
$(element).focus();
$(element).val('');
$('#' + target_id).val('');
var message = 'Invalid barcode.';
alert( message );
} else {
var res = jQuery.parseJSON(response);
$('#' + target_id).val(res.description);
}
}
});
}
I would like to point out though, that this is not very good practice. Code like this get hard to maintain and breaks easily.
You would really be better off by learning a well though out framework, like Vue.js, Angular or React.

Is there a way to show datalist options that don't match user input?

I've got two elements, a datalist and an input:
<datalist id="choices"></datalist>
<input id="custom_id" name="custom_name" type="text" value="" list="choices" class="medium-field"/>
Additionally,here is an AJAX request, which populates the datalist (this works; not my issue)
var params = {
"partial": $("#custom_id").value;
};
$.ajax({
cache: true,
url: "http://www.example.com",
type: "POST",
data: JSON.stringify(params), // contains the input.value
contentType: "application/json",
headers: {
"Range": "0-9"
},
dataType: "json",
processData: false,
// On success, create <option> elements and append them to datalist
success: function(data) { .. };
The data returned by the REST endpoint is formatted like so:
[
{
"label": "active",
"name": "iron"
},
..
]
Basically the AJAX request hits a REST endpoint in front of a PostgreSQL db that does runs a SELECT based on the provided partial parameter, and returns a 2-column table (which gets formatted as the above response).
However, I have situations where the data returned from the AJAX request is spelled differently from the user's input; for example, when input.value = 'magnet', I sometimes return a list of options where a few might read 'iron'.
The problem : due to 'iron' being spelled differently than 'magnet', the user won't see this option in the datalist dropdown (even though the option element is created) unless the user actually types 'iron'. Is there a way for me to display 'iron' in the datalist even though it doesn't match what the user has typed?
As far as I can understand your question, you are willing to show the synonyms as a result when an input is typed in the search box, i.e if a user types magnet, he shall see the synonyms to 'magnet', which in this case happens to be iron
What you can do is when the ajax hit is sent to example.com I understand that there is some SQL code as SELECT keyword FROM table_name WHERE keyword LIKE '%<whatever string is in data>%'. This would return 'magnet' even if the user types mag. Now coming to returning 'iron' and 'magnet' when a user types say 'mag'
You will have to modify the table a little bit as follows:
1. Create a keywords table having columns: id, keyword and synonym_to_keyword
2. Enter the data like
(1, 'iron' , null)
(2,'magnet',1)
Now modify the query as: SELECT id as I, keyword FROM table_name WHERE keyword like '%<whatever string is in data>%' OR keyword like (SELECT keyword FROM table_name WHERE synonym_to_keyword = I)
Note that you will have to maintain a list of keywords and probable synonyms to the keywords so that the user sees all the probable options (like magnet, iron, etc) when he types 'magnet'.
Since Chrome will compare both the value and label to see if it should show the datalist option, you can set all of your option labels to the value you have in your input for them to show up.
Relevant Chromium patch
Code Example below:
function autoSuggestAddress(input) {
if (input.value) {
// dummy data
let suggestions = ["Example 1", "Example 2", "Example 3"];
// clear old datalist
let datalist = input.list;
while (datalist.hasChildNodes()) {
datalist.removeChild(datalist.firstChild);
}
suggestions.forEach((item) => {
let option = document.createElement("option");
option.label = input.value;
option.value = item;
datalist.appendChild(option);
});
}
}
<form method="GET" id="search-form">
<label for="address">Address</label>
<input type="text" id="address" name="address" form="search-form" oninput="autoSuggestAddress(this)" type="search" value="" required autocomplete="off" list="suggestions" />
<datalist id="suggestions">
</datalist>
</form>

Javascript populates input, but not span?

I am using Select2 dropdown menu to get data from database threw ajax and json/php.
The option i make will then populate some input fileds for editing the database.
I use (This field get´s populated ok):
<input type="text" class="form-control" name="valt_element_id" id="valt_element_id" placeholder="Objekt ID" />
But on some field i just want to show the data, not to be edited.
I figured to use:
<span id="valt_element_id"></span>
But this span code won´t work!
Why?
JS:
$(document).ready(function(){
var valtObjektElement = $('#valj_objekt_element');
$('#valj_objekt_element').select2({
ajax: {
url: "valj_objekt_element.php",
dataType: 'json',
data: function (term, page) {
return {
q: term
};
},
results: function (data, page) {
return { results: data };
}
} // Ajax Call
}); // Select2
// Start Change
$(valtObjektElement).change(function() {
var ElementId = $(valtObjektElement).select2('data').id;
var ObjektNummer = $(valtObjektElement).select2('data').text;
$('#valt_element_id').val(ElementId);
$('#valt_objekt_nummer').val(ObjektNummer);
}); //Change
}); //Domument Ready
There is no value attribute for span. You should either use text or html.
Replace
$('#valt_element_id').val(ElementId);
with
$('#valt_element_id').text(ElementId);
Using javascript:
document.getElementById("valt_element_id").innerHTML = ElementId;
Or jQuery:
$('#valt_element_id').html(ElementId);
You mentioned:
But on some field i just want to show the data, not to be edited . Why not use readonly attribute in input rather than replacing it with a span ?

how to validate dynamic created element in jquery without using plugin

here i have created dynamic elements after clicking its adding one row.but how to validate it without plugin.
var cnt = 1;
$("#anc_add").click(function() {
cnt++;
$("input[id=rows]").val(cnt);
$('#tbl1 tr').last().after('<tr><td><select name="'+cnt+'1" id="'+cnt+'1" class="Exp"><option value="0" >Select Expenses Type</option></select></td><td><textarea name="'+cnt+'2"></textarea></td><td><input type="text" name="'+cnt+'3" id="'+cnt+'3" onkeypress="return isNumberKey(event)"></td></tr>');
element_id=cnt+'1';/*alert(element_id);*/
$.ajax({
url: "../../modal/system_operator/get_companyexpenses_type.php",
dataType: "html",
type: 'POST',
success:function(json) {
var result = jQuery.parseJSON(json);
length=result.len;
/*alert(length);*/
for(k=1;k<=length;k++) {
$('#'+element_id+' option').last().after('<option value="'+eval("result.row"+k+".company_expenses_type_id")+'">'+eval("result.row"+k+".company_expenses_type")+'</option>');
}
$('select[name="'+element_id+'"]').rules('add', {required:true});
}
});
});
I assume by without plugin means you do not use jquery.validate or some other plugin to validate your input control values.
Then try the following snippet
$(document).on('blur','#form_id input,#form_id select', function(){
// write your validation logic here
});
The above code says that all (including dynamic) input,select controls within #form_id element will call the function on blur event.

strange behaviour - serialize

i have this code:
var sizes = ["1/9","1/8","1/7","1/6","1/5","1/4","1/3","1/2","1/1","2/1","3/1","4/1","5/1","6/1","7/1","8/1","9/1"];
var slider = new dijit.form.HorizontalSlider({
value:8,
name:"value"+[i],
slideDuration:0,
onChange:function(val){
dojo.byId('value'+[i]).value = sizes[val];
},
minimum:0,
maximum:sizes.length-1,
discreteValues:sizes.length,
intermediateChanges:"true",
},node);
now, when i made:
$("#custom").submit(function() {
var formdata = $("#custom").serializeArray();
$.ajax({
url: "insert.php",
type: "post",
dataType: "json",
data: formdata,
success: function(data) {
}
});
For example, if i choose the value 1/8 it is sent as 1, or 9/1 as 16.
What i want is send the fraction value, that is showed in the input box, but as i said, not sent to the insert.php
Any idea ? thanks
At the beginning during the init of the slider an <input type="hidden" name="input0" ... /> will be created.
After using the slider this input get the current slider value (a number between 0 and sizes.length - 1). The onChange sets an other html input tag with the value from the array called sizes.
While submitting the serializeArray() takes the values of all input fields which have a name attribute.
In my EXAMPLE I gave the input field that will be filled at the onChange a name attribute, so the serialization takes both values.
HTML:
<form action="#" id="custom">
<div id="slider0"></div>
<input type="text" id="value0" data-dojo-type="dijit.form.TextBox" name="value0" />
<input type="submit" value="submit" />
</form>

Categories

Resources