I have a script that get's some data from the backend and populates the select2 dropdown. The problem is that the ajax call is called 2 times always and it should not be like this. I am not sure what I am doing wrong... any help would be apreciated.
this is my code:
var select2Element = $('select').select2({
theme: "classic",
escapeMarkup: function (markup) { return markup; },
});
select2Element.on('select2:opening', function(event) {
var clicked = $(this);
var route = "{{ path('get_attribute_list', {'articleId': 'ARTICLEID', 'attributeGroupId': 'ATTRIBUTEGROUPID'}) }}"
var url = route.replace("ARTICLEID", $(this).attr('data-articleId')).replace('ATTRIBUTEGROUPID', $(this).attr("data-attributeGroupId"));
$.ajax ({
url: url,
dataType: 'json',
async: false,
type: "GET",
}).then(function (data) {
//#TODO get out elements already inserted
for (var d = 0; d < data.length; d++)
{
var item = data[d];
// Create the DOM option that is pre-selected by default
var option = new Option(item.text, item.id, true, true);
// Append it to the select
clicked.append(option);
}
// Update the selected options that are displayed
clicked.trigger('change');
});
});
var inputResult = [];
select2Element.on('select2:select', function(e) {
var jsonValue = {
"articleId": $(this).attr("data-articleId"),
"attributeGroupId": $(this).attr("data-attributeGroupId"),
"attributeId": e.params.data.id
}
inputResult.push(jsonValue);
$('#addAttributes').val(JSON.stringify(inputResult));
});
select2Element.on('select2:close', function() {
$(this).html('');
});
Seems there is a bug in 'select2:open' and 'select2:opening'. There is a fix for this but not published.
Anyway who has this problem until it is fixed can see more details here:
https://github.com/select2/select2/issues/3503
and the fix for this here:
https://github.com/select2/select2/commit/c5a54ed70644598529a4071672cca4a22b148806
Related
I have this div
<div class='additional_comments'>
<input type="text" id='additional_comments_box', maxlength="200"/>
</div>
Which will only sometimes appear on the page if jinja renders it with an if statement.
This is the javascript i have to send an ajax request:
$(document).ready(function() {
var button = $("#send");
$(button).click(function() {
var vals = [];
$("#answers :input").each(function(index) {
vals.push($(this).val());
});
vals = JSON.stringify(vals);
console.log(vals);
var comment = $('#additional_comments_box').val();
var url = window.location.pathname;
$.ajax({
method: "POST",
url: url,
data: {
'vals': vals,
'comment': comment,
},
dataType: 'json',
success: function (data) {
location.href = data.url;//<--Redirect on success
}
});
});
});
As you can see i get the comments div, and I want to add it to data in my ajax request, however if it doesnt exist, how do I stop it being added.
Thanks
You can use .length property to check elements exists based on it populate the object.
//Define object
var data = {};
//Populate vals
data.vals = $("#answers :input").each(function (index) {
return $(this).val();
});
//Check element exists
var cbox = $('#additional_comments_box');
if (cbox.length){
//Define comment
data.comment = cbox.val();
}
$.ajax({
data: JSON.stringify(data)
});
I have dropdown list of country suggestions and input above. When i click on one of them - AJAX should work(and it does) and add value to #msg_native. HTML:
echo '<div class="search_native"><input type="text" name="native_input" id="native"/>';
echo "<div id='output'></div></div>";
All JQUERY :
<script type="text/javascript">
$(document).ready(function() {
$("input").keyup(function(){
$array = ['usa','france','germany'];
$input_val = $("input[name='native_input']").val();
$('#output').text('')
r = new RegExp($input_val)
for (i = 0; i < $array.length; i++) {
if ($array[i].match(r)) {
$('#output').append('<p class="match">' + $array[i] + '</p>')
}
}
});
$(document).on('click', '.match', function(){
$value = $(this).text();
$('#native').val($value);
});
});
</script>
<script type="text/javascript">
$(function() {
$('#native').change(function() {
alert('cl');
$.ajax({
type: "POST",
url: "home.php",
dataType: 'json',
encode: true,
data: {native_input: $("input[name='native_input']").val()},
cache: false,
success: function(data){
alert(data);
$("#msg_native").after(data);
}});
return false;
});
});
</script>
The problem is that the value that gets posted is only what Ive typed myself, regardless on clicked element. But I want complete value- not only typed letters...so it firstly posts value and then 'finishes' the input (if clicked)
What can you practically advice to me?
data: {native_input: $value},
returns empty string
Some of this might be debatable but I put those in place for maintainability of the code and/or to match the most recent jQuery.
Only use one document ready handler (if possible)
Remove all the global objects (put var in front of them)
Use the native id when possible as fastest selector (not $("input[name='native_input']") for instance)
use this in the event handler, not the full selector (see next item)
If I enter "France" not "france" match does not work so need to case that input to equality var $input_val = $(this).val().toLowerCase();
You start with an empty field, might be good to show the match for that - simply trigger the keyup on startup to show all the array: }).trigger('keyup'); Now they are available for your clicking.
Attach the click handler on the wrapper for the "match" elements: $('#output').on('click', '.match', function() {
Use the promise form of the ajax .done(
Create a new custom event instead of the "change" on the native. We can then trigger that event as/when needed (the real issue you describe) Example: $('#native').trigger('myMatch'); and as I use it here:
trigger the event on a full match:
if (jQuery.inArray($input_val, $array) !== -1) {
$(this).trigger('myMatch');
}
Revised code:
$(document).ready(function() {
$("#native").on('keyup', function() {
var $array = ['usa', 'france', 'germany'];
var $input_val = $(this).val().toLowerCase();
$('#output').html('');
var r = new RegExp($input_val);
for (var i = 0; i < $array.length; i++) {
if ($array[i].match(r)) {
$('#output').append('<p class="match">' + $array[i] + '</p>');
}
}
// full match entered, trigger the match
if (jQuery.inArray($input_val, $array) !== -1) {
$(this).trigger('myMatch');
}
}).on('myMatch', function() {
alert('cl');
var nativeMatch = {
native_input: $("#native").val()
};
$.ajax({
type: "POST",
url: "home.php",
dataType: 'json',
encode: true,
data: nativeMatch,
cache: false
}).done(function(data) {
alert(data);
$("#msg_native").after(data);
});
return false;
}).trigger('keyup');
$('#output').on('click', '.match', function() {
var $value = $(this).text();
$('#native').val($value).trigger('myMatch');
});
});
I'm very new to ajax/javascript so I will try my best to explain my problem. Here's what I have so far:
$(function () {
$("#chkFilter").on("click", "input", function (e)
{
var filterCheckboxes = new Array();
$("#chkFilter").find("input:checked").each(function () {
//console.log($(this).val()); //works fine
filterCheckboxes.push($(this).val());
console.log($(this).val());
//var filterCheckboxes = new Array();
//for (var i = 0; i < e.length; i++) {
// if (e[i].checked)
// filterCheckboxes.push(e[i].value);
//}
});
console.log("calling ajax");
$.ajax({
url: "/tools/oppy/Default.aspx",
type: "post",
dataType: "json",
data: { UpdateQuery: filterCheckboxes }, // using the parameter name
success: function (result) {
if (result.success) {
}
else {
}
}
});
});
});
Every time a checkbox is checked, ajax passes the data onto the server. Here is an example of some checkbox values after a few have been checked in the data form obtained from the Developer's Console:
You can try the following code:
filterCheckboxes.push($(this).prop("name") + "=" + $(this).val());
I have been using this jQuery before I use $.ajax(); and it was working good:
$(document).ready(function(){
var urlSerilize = 'some link';
var appList = $("#applications > li > a");
var appCheck = $('input[type=checkbox][data-level="subchild"]');
var installbtn = $('#submitbtn');
var form = [];
var checked = [];
//var appList = $(".body-list > ul > li");
//var appCheck = $('input[type=checkbox][data-level="subchild"]');
appList.click(function(){
console.log('here!');
if($(this).children().find("input").is(":checked")){
$(this).children().find("input").prop('checked', false);
$(this).children('form').removeClass('checked');
$(this).removeClass("li-checked");
var rmValue = $(this).children('form').attr('id');
form = jQuery.grep(form, function(value) {
return value != rmValue;
});
}else{
$(this).children().find("input").prop('checked',true);
$(this).addClass("li-checked");
$(this).children('form').addClass('checked');
form.push($(this).children('form').attr('id'));
}
console.log(form);
});
installbtn.on('click', function () {
event.preventDefault();
jQuery.each( form, function( i, val ) {
console.log(val);
var request = $.ajax({
url: urlSerilize,
type: 'GET',
data: $('#'+val).serialize(),
success: function( response ) {
console.log( response );
$('#applications').html();
$('#apps_box').html();
}
});
request.done(function(msg){
console.log('Ajax done: ' + 'Yeah it works!!!');
});
request.fail(function(jqXHR, textStatus){
console.log('failed to install this application: ' + textStatus);
});
});
});
});
but after I used this ajax code the .click() jQuery event don't work anymore:
$(document).ready(function() {
/* loading apps */
//console.log('active');
var request = $.ajax({
url: 'some link',
type: 'GET',
dataType: 'html',
data: {id: 0},
})
request.done(function(data) {
console.log("success");
$('#applications').empty().append(data);
})
request.fail(function() {
console.log("error");
})
request.always(function() {
console.log("complete");
});
//end loading apps
var showmore = $('.showapps');
showmore.click(function(){
var parent = $(this).parent('.tv_apps');
var displayC = parent.children('.body-list').css('display');
console.log(displayC);
if (displayC=='none') {
parent.children('.body-list').show('400');
$(this).children().find('img').rotate({animateTo: 180});
}else{
parent.children('.body-list').hide('400');
$(this).children().find('img').rotate({animateTo: 0});
};
});
});
at first place I though it was because of the ajax loads and don't stop, then i was wrong.
I have tried the window.load=function(); DOM function to load the script after Ajax finish loading and also was wrong.
So please if there any idea to fix this problem,
Thanks.
This is the event I want it to be fixed:
appList.click(function(){
console.log('here!');
if($(this).children().find("input").is(":checked")){
$(this).children().find("input").prop('checked', false);
$(this).children('form').removeClass('checked');
$(this).removeClass("li-checked");
var rmValue = $(this).children('form').attr('id');
form = jQuery.grep(form, function(value) {
return value != rmValue;
});
}else{
$(this).children().find("input").prop('checked',true);
$(this).addClass("li-checked");
$(this).children('form').addClass('checked');
form.push($(this).children('form').attr('id'));
}
console.log(form);
});
showmore.click(function(){
should be
$('.showapps').on('click', function(){
OR
$(document).on('click','.showapps', function(){
For dynamically added contents, you need to bind events to it.
For more info: http://learn.jquery.com/events/event-delegation/
Thanks everyone, at last I have found the solution.
It was a question of the DOM, when I use the ready method of jquery it loads an empty ul (without content), so then what I figured out in the first time was correct, all I did is to remove the ready and use a simple function that includes all the .click() events, then call it in request.done();.
This is the solution:
function loadInstaller(){
var urlSerilize = 'some link';
var appList = $("#applications > li");
var appCheck = $('input[type=checkbox][data-level="subchild"]');
var installbtn = $('#submitbtn');
var form = [];
var checked = [];
//...etc
};
$(document).ready(function() {
/* loading apps */
//console.log('active');
var request = $.ajax({
url: 'some link',
type: 'GET',
dataType: 'html',
data: {id: 0},
})
request.done(function(data) {
console.log("success");
$('#applications').empty().append(data);
loadInstaller();
})
//...etc
});
I hope this answer will help someone else :)
Im having an issue with jquery autocomplete plugin. the textbox im using wont populate the results of autocomplete until i enter a value that is in the first entry of my data. After it populates that, then the autocomplete works how its supposed to.
$(document).ready(function () {
});
function textChange() {
var callback = function (request, response) {
var searchText = request.item;
var searchField = $(".ddlist > option:selected").attr("value");
$.ajax({
type: "GET",
dataType: "text",
url: "SearchCallback.aspx?searchText=" + searchText + "&searchField=" + searchField,
success: function (data) {
var splitData = data.split(",");
response(splitData);
}
});
}
$(".searchTextBox").autocomplete({
source: callback,
autoFill: true
})
}
after playing around with it i got the following code to work, before i was using an onkeyup event in the text box but i guess i didnt need it. i dont know if this is efficient but it is working correctly now.
$(document).ready(function () {
$(".searchTextBox").autocomplete({
source: callback,
autoFill: true
});
});
var callback = function (request, response) {
var searchText = request.term;
var searchField = $(".ddlist > option:selected").attr("value");
$.ajax({
type: "GET",
dataType: "text",
url: "SearchCallback.aspx?searchText=" + searchText + "&searchField=" + searchField,
success: function (data) {
var splitData = data.split(",");
response(splitData);
}
});
}
You have to use a callback as the source option when you initialize the autocomplete (in your example you initialize the autocomplete every time a key is being pressed):
var callback = function(request, response) {
var searchText = request.item;
// Set searchField somehow here
$.ajax({
type: "GET",
dataType: "text",
url: "SearchCallback.aspx?searchText=" + searchText + "&searchField=" + searchField,
success: function (data)
{
var splitData = data.split(",");
response(splitData);
});
});
};
$( ".searchTextBox" ).autocomplete({
source: callback,
autoFill: true
});
There are some more examples and a more detailed description in the documentation.