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?
Related
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".
Am a little bit newbie to django ajax so my question might be an easy thing for experts.
I have a select option dropdown where i want when the user selects a value from dropdown, the value is submitted via ajax so that i can run querysets in the django backend using the selected value.
I can somehow figure out to do this in the backend but need a little help with how to submit this value in the front end by ajax.
here is the dropdown code,just basic html,
<select>
<option>joshua</option>
<option>peter</option>
<option>james</option>
<option>pawine</option>
<option>flonah</option>
</select>
I want an ajax function that will send the selected value to server so that i can use it to run a queryset in the django backend and return the result to ajax success function appropriately.
Thanks in adavnce
Here's an example using JQuery that places an event handler on the select widget that will call your Django view when the user makes a selection. In this example the selected name is being appended to the URL so that Django can grab it with the following regex in urls.py:
url(r'^path_to_app/(?P<name>\w+)$', 'app.views.function'),
Here's an example:
<select id="chooseme">
<option>--select a name--</option>
<option>joshua</option>
<option>peter</option>
<option>james</option>
<option>pawine</option>
<option>flonah</option>
</select>
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script>
$(document).ready(function() {
$('#chooseme').change(function(){
var name = document.getElementById("chooseme").value;
$.get('/path_to_app/' + name, function(data){
// do something here with a return value data, if desired
});
});
});
</script>
Check that:
<select id="select_form">
<option>joshua</option>
<option>peter</option>
<option>james</option>
<option>pawine</option>
<option>flonah</option>
</select>
var name = $('#select_form').find(":selected").text();
var url = 'your_url_here'+userName+'/';
$.get(url, function(data)
{
//do something with data
})
I tried like this for the following select dropdown:
<select id="select_dropdown">
<option value='joshua'>joshua</option>
<option value='peter'>peter</option>
....
....
</select>
<script>
$(document).ready(function(){
$('#select_dropdown').change(function(){
var e = document.getElementById("select_dropdown");
var value = e.options[e.selectedIndex].value;
$.ajax({
url: "your-url",
type: "post",
data: value,
success: function(data) {
console.log(data);
}});
});
</script>
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>
Here is my js function;
function getCountryRegions() {
var postData = "id="+$("#selectedCountryId").val();
$.ajax({
url:"/region",
data: postData,
dataType:"html",
type:"POST",
success: function(data){
$("#selRegion2").html(data);
$("#selRegion")== $("#selRegion2").html($(data).find("#selRegion"));
}});}
The 'data' come exactly like this;
<label>Bölge</label>
<select name="selRegion" id="selRegion">
<option value="0" selected="selected" >-- tümü</option>
<option value="4140104">Adana</option>
<option value="4141360">Adrasan</option>
<option value="4137856">Afyon</option>
</select>"
My aim is to get selRegion element and pass it to an Array of Objects. Each object has value and text
I tried this line to make it;
$("#selRegion")== $("#selRegion2").html($(data).find("#selRegion"));
If your data is coming through in perfect HTML format, one trick you can use is this:
var $data = $("<data />").html(data);
Then you can get elements from it like:
$data.find("select").each(function(i) { /* DO WORK */ });
What this does is create a jQuery Element object Tagged <data>. Thus you're able to act upon it like any other jQuery element like $("div") or $("select")
I have a jQuery/Ajax function that is appending 2 <option>s to a <select>.
function addOption() {
var author = $("#authors").val();
$('#books').empty();
$('#books').html('<option value="">Please Select</option>');
$.ajax({
type: "post",
url: "books.php",
data: { author:author },
success: function(response){
$('#books').append(response);
}
});
}
response comes back as -
<option value="bookA">Book A</option>
<option value="bookB">Book B</option>
and now books is -
<select id="books">
<option value="">Please Select</option>
<option value="bookA">Book A</option>
<option value="bookB">Book B</option>
</select>
This works great.
Now I want to set the selected option using .val() after calling addOption() -
$('#authors').change( function(){
addOption();
$('#books').val('bookB');
});
This does not make Book B selected.
If I hard code the .append() it works -
function addOption() {
var author = $("#author").val();
$('#books').empty();
$('#books').html('<option value="">Please Select</option>');
$('#books').append('<option value="bookA">Book A</option>\n<option value="bookB">Book B</option>);
}
$('#authors').change( function(){
addOption();
$('#books').val('bookB');
});
Is there a reason why my option(s) appended in the .ajax function cannot be selected using .val(), put it can if I append them directly?
That's because the AJAX call is asynchronous, so when you try to select the options, it hasn't been added to the select yet.
Use a callback in the function, so that you can do something when the response has arrived:
function addOption(callback) {
var author = $("#authors").val();
$('#books').empty();
$('#books').html('<option value="">Please Select</option>');
$.ajax({
type: "post",
url: "books.php",
data: { author:author },
success: function(response){
$('#books').append(response);
callback();
}
});
}
Usage:
$('#authors').change( function(){
addOption(function(){
$('#dropdownB').val('bookB');
});
});
AJAX is asynchronous, meaning that when you call the addOption() method, it might (and probably will) return before the Ajax call has actually been made, so you are calling $('#dropdownB').val('bookB'); before the Ajax callback has been triggered to append the options.
Try putting the $('#dropdownB').val('bookB'); into the success callback of the ajax call and you should see it working.
Ajax is asynchronous, when you set the value, there is no option with that value, you can put your code in your success callback.
success: function(response){
$('#books').append(response);
// ...
}
Or set that value of async property of your Ajax request to false;
This is because ajax is asynchronous. That is, by the time it returns and appends the new options to the select list, the browser engine has already continued and tried to set the value (which wasn't yet added). Try moving the value setting logic to work as part of the ajax response.
1) You should put $('#dropdownB').val('bookB'); inside the success-event of your ajax-call, because AJAX is asynchronous and your request may not be done when you try to change the selected item, so there is no item to select yet.
2) You append to #books but change the selected item of #dropdownB. Those are two different ids and hence two different DOM elements.