I dynamically add hidden input to my form. If you're messaging say four people at once (whose names are in callsign_array) it will add four hidden inputs. The form is then submitted using ajax. I then want to remove all the appended hidden inputs, but $('.remove').remove(); isn't working (if you send a message to Andy, then try to send a different message to Barry, it actually sends the message to Andy and Barry. Sending a third message to Chas would result in a message to Andy, Barry and Chas). I know there are thousands of similar "jquery remove() doesn't work" questions on SO, I've looked at them and I think this should work, but I'm baffled, I just can't see what's wrong.
var callsign_array = $('#callsigns-div').data('callsigns');
var form = $("#message_form");
for(var i=0; i<callsign_array.length; i++) {
form.append('<input type="hidden" class="remove" name="callsigns[]" value="' + callsign_array[i] + '" />');
}
$.ajax({
type: 'POST',
url: $(this).attr('action'),
data: $(this).serialize(),
dataType: 'script'
});
// remove all appended inputs
$('.remove').remove();
// reset the callsigns array
$('#callsigns-div').attr('data-callsigns', '[]');
The page includes this div to hold the callsigns array:
<div id="callsigns-div" data-callsigns='[]'></div>
<crystalball on>
You are not removing entries from your callsign_array container. That is why messages for different users accumulate.
</crystalball off>
Add logging:
console.log("Before remove: ", $('.remove').length);
$('.remove').remove();
console.log("After remove: ", $('.remove').length);
to convince yourself that $().remove works.
Update
Do not mix $().data and $().attr calls when reading/writing dataset properties of DOM elements. These dataset items are cached as separate memory objects by jQuery.
Add logging:
$('#callsigns-div').attr('data-callsigns', '[]');
console.log("Hope array is empty: ", $('#callsigns-div').data('callsigns'));
to convince yourself that your $().attr call does nothing to the result of the subsequent $().data call.
#robert-wade is correct. I don't have reps to comment but you might consider holding all of your users in an array or object and then passing that array/object in the form. It's a little cleaner than adding/removing elements. Of course you would have to parse it on the server-side.
try this
$.ajax({
type: 'POST',
url: $(this).attr('action'),
data: $(this).serialize(),
dataType: 'script' ,
success: function (){
$('.remove').remove(); // reset the callsigns array
$('#callsigns-div').attr('data-callsigns', '[]');
}
}); // remove all appended inputs
Related
I have two HTML elements: 1). the div element is a multiple select (it is a predefined widget that automatically creates the multiple select element) and 2). a button that triggers onclick event.
On the JS side, there is the global variable 'prev_selection' which is set to empty array for now. The idea of prev_selection is to remember the array of values in the multiple select div element before user clicks the button. I want to remember the value before and after a click to see what selections have been added/removed.
When the button is clicked, 'sendData()' is called. It gets the selected data from the div element. Then, it performs some operations using the prev_selection to know what the newly selected values are (in the beginning everything is newly selected in the div).
I want to find out the additions/deletions in the selected values between user clicks. For that, I update the prev_selection with 'selected_data' that I get from the div element jut after the click.
But this does not work as expected. There is something happening with the asynchronous Ajax call and I am not able to find a better solution for this. Everytime a click happens you had expect that 'prev_selection' remembers the value before the click but instead when I print it using console.log() (as shown in the code) it already gets updated to the latest selections even before reaching the success function (where it is supposed to get updated).
Thanks in advance! And please let me know if further explanation is required.
<!-- multiple select/deselect div -->
<div id="someSelectionID"></div>
<button id="updateButtonID" onclick="sendData()">Click to send</button>
// at first, no data is selected
var prev_selection = [];
function sendData() {
// get the selected data from the div element "someSelectionID"
let selected_data = $('#someSelectionID').val();
// perform some operations on the selected data
// this operation involves the use of prev_selection
// printing prev_selection already has value of updated click
console.log(prev_selection );
$.ajax({
type: "POST",
url: "<some url>",
dataType: 'json',
contentType: 'application/json;charset=UTF-8',
data: JSON.stringify( < some data > ),
success: function(result) {
console.log(result);
/* once the request is successfully done update the
previous selection to what the current selected data is */
prev_selection = selected_data;
}
});
}
Try this
$.ajax({
type: "POST",
url: "<some url>",
dataType: 'json',
contentType: 'application/json;charset=UTF-8',
data: JSON.stringify( < some data > ),
}
}).then(function(response){
if (response.status === 200){
console.log('succeed');
} else {
console.log('failed')
}
});
So it worked by changing this line
prev_selection = selected_data;
to:
prev_selection = Array.from(selected_data);
Because the prev_selection variable kept changing without me updating, it lead me to believe that it was some kind of reference to value instead of value itself. So just using Array.from to do a shallow copy actually worked.
I'm having a list with a lot of entries (100+) identified by an (MongoDB-)ID. Each of the entries is in an html-table and has a checkbox. When the user now selects a group, I need to query the server if each of the entries is in the specific group. The query for getting the membership isn't to heavy, but I can't execute it 100+ times, that's too much load.
Currently I have php code for getting the group membership (too long to post) and following javascript code, which is executed whenever the select is changed:
$('checkbox[data-type="group"]').each(function(idx, val) {
// get the ID and set it checked/unchecked
});
My problem is: How can I query performantly the Server once and then check for every ID if the entry is in the selected group?
Your question is a little hard to understand, but I think you should post a JSON list and post that in one query, and handle the iteration server-side, like so:
id_list = {};
$('checkbox[data-type="group"]').each(function(idx, val) {
the_id = //get the id into a variable somehow;
id_list[the_id] = val;
});
$.ajax({
url: "some url",
dataType: "json",
type: "post",
data:id_list
}).done(function(data) {
//using returned data, set each to check/unchecked
//assuming that the returned data had format of id:boolean, and the boolean defines whether it should be checked (e.g. {1: true, 2: false, 3: false} )
$.each(data, function(index,value) {
if (value == true) {
$('checkbox#'+index).attr('checked',true);
} else {
$('checkbox#'+index).attr('checked',false);
}
});
If this doesn't answer your question then please rephrase your question with more detail.
There is one feature on my site: delete without page refresh. The user just presses 'delete' and the browser will send Ajax-request. It will load 'delete' script with id parameter.
All work well. But it is not very good because of referential integrity of the database. For example, It is possible to delete street, where some people are living.
I want to upgrade my script. I want to add a check to delete script and don't let delete data if some 'people' are connected to 'street' table.
jQuery handler of button click:
$('body').on('click', '.deleteStreet', function()
{
var id = $(this).attr('id');
var hideMe = $(this).parent().parent();
var dataString = 'id=' + id;
if(confirm("Are you sure you want to delete street? It is possible some people living there!"))
{
$.ajax({
type: "GET",
url: "/index.pl?mode=streets&action=delete",
data: dataString,
cache: false,
success: function(e)
{
hideMe.hide();
}
});
return false;
}
});
It will call script anyway and now will delete data anyway. I can add some checks to delete script now and it wouldn't delete, but jquery script would work anyway and will hide table row anyway (because request was send ok, without 404, etc)
1) Is it possible to see delete script result and hide or not hide row depending on it? For example, it will return true or false, js script will catch it and show message about deleting or not deleting of data depending on it.
2) This problem caused by structure of my site. There are some switches on index.pl and load appropriate scripts loading depending on query (mode=street then load street.pl, mode=user then load users.pl etc). So it will show all data loaded before delete.pl script and it will be impossible to check script returned true or false.
Any help? :) Thank you!
P.S.: I am very sorry for my awful english.
You can have the result of your ajax call in the first parameter of the success callback. ex:
$.ajax({
type: "POST",
url: "/index.pl?mode=streets&action=delete",
data: dataString,
cache: false,
success: function(e)
{
if(e === '1'){
hideMe.hide();
}
}
});
try to log your result in the console for tests: console.log(e).
For deleting data you should use a POST request ( or DELETE but not supported by all browsers).
I dont know how your datas (streets) looks like but an other way could it be to return all your existing streets in a json object on the delete request result. And refresh all lines.
I have a jquery script that accesses a db and returns a numeric result and writes that result into a table cell. This scripts runs when the page loads but also when the drop down menu is changed. I want to be able to limit only 1 result per table cell.
Right now when page loads it writes the result to the cell and when the drop down menu is changed it just adds the new result to the cell instead of replacing it.
I have search quite a bit trying to figure out how to do this and can not come up with anything. Can someone help me?
Here is the jQuery:
$(document).ready(function(){
$('.typeval').change(function(){
var movement = $(this).val();
var client_id = $(this).parent().siblings().find('.clientval').val();
var class_id = <? echo $class_id; ?>;
$count = $(this).parents('tr').find('label.count');
$.ajax({
type: "POST",
url: "movement_count.php",
data: {movement:movement, client_id:client_id, class_id:class_id},
dataType: "json",
async: false,
success:(function(output) {
$.each(output, function(index, value){
//alert(value);
$count.append(output[index]);
}); // each
})
}) // ajax
}).change(); // .typeval
}); // document
Here is the table cell where I only want to show one result at a time.
<td><label class="count">5</label></td>
Please let me know if I have not provided enough info for the assistance needed.
Use .text() instead of .append():
$count.text(output[index]);
As its name implies, .append() adds the content to the end of the container. Whereas, .text() sets the text displayed in the container, overwriting any existing text.
Actually, .html(), behaves more like .append() than .text() does, but I don't recommend using .html() unless you are actually setting .html(). Since you said the result is numeric, .text() is better.
Try updating your AJAX call to clear the contents before adding new results:
$.ajax({
type: "POST",
url: "movement_count.php",
data: {movement:movement, client_id:client_id, class_id:class_id},
dataType: "json",
async: false,
success:(function(output) {
$.each(output, function(index, value){
//alert(value);
$count.html(''); // Clear current content
$count.append(output[index]); // Append new content
}); // each
})
}) // ajax
We're working on a big ASP.NET\VB.NET website project.
I need to populate three dropdownlists. To last two are independent of the previous ones. The population data comes from an SQL Server. I'd have no problem doing this with code-behind with post back but we don't want any PostBacks so I started to develop this in Ajax\jQuery.
Preface:
The dropdownlist's values and text are both different and tied up to the database. Server-side, the function called by the Ajax method returns a list of list of string with the values and text, i.e.
list[0][0] = "ID0"
list[0][1] = "VP"
The list is well built and returns the right value taken from the database.
Problem:
Now I want to populate the dropdownlist from the list sent to the ajax success response and I have a hard time doing it.
Here's the ajax part of it so far
$.ajax(
{
type: "POST",
url: "Projet.aspx/GetDir",
data: "{VP:'" + dd_effort_vp + "',DP:'" + dd_effort_dp + "',Direction:'" + dd_effort_d + "'}",
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(response) {
// This code works if only a simple list of string is
// returned from the server-side called function.
var cars = response.d;
$.each(cars, function(index, value) {
$('#<%= dd_effort_directionp.clientid()%>').append(
$('<option></option>').val(value).html(value));
});
}
This code works IF and only IF I have a simple list of string returned by the server side function.
Now I want to modify it to get the values from the List of List of String (in var cars and assign the right ID and Description to each item in the newly populated DropdownList.
If your server is returning to you a list of list of strings, that will come to jQuery via an array, whose elements are arrays. You need to figure out/know which element of that array—which, again, will contain a list of strings—needs to go with your dropdown. If you want the 0th array, you would do:
var cars = response.d[0];
Also, it looks like you're going through a lot of trouble to find the relevant dropdown lists since asp.net is giving them unpredictable names.
Consider giving each drop down a unique class, via the CssClass property, and then select it that way.
<asp:DropDownList runat="server" CssClass="dd_effort_directionp"></asp:DropDownList>
$.each(cars, function(index, value) {
$(".dd_effort_directionp").append(
$("<option />").val(value).html(value));
});