Avoiding multiple AJAX calls on jQuery sortable( ) - javascript

I am new to jQuery. Basically I have a table which I can sort the rows. I want to save the new order in the backend, which I am able to do. However, I noticed that I am sending multiple Ajax calls depending on the number of times I sorted the table. The order is not saving properly in the backend. Here is my code. The variable order is where the new IDs are stored. I am sending it in my Django through the '/updateorder' route/
<script type="text/javascript">
$(document).ready(function(){
$("#sortable").sortable({
update: function (event, ui) {
var order = $(this).sortable('toArray');
console.log(order);
$(document).on("click", "button", function () {
$.ajax({
data: {csrfmiddlewaretoken: document.getElementsByName('csrfmiddlewaretoken')[0].value, 'order[]': order},
type: 'POST',
url: '/updateorder'
})
});
}
}).disableSelection();
$('button').on('click', function () {
var r = $("#sortable").sortable("toArray");
var a = $("#sortable").sortable("serialize", {
attribute: "id"
);
console.log(r);
});
});
</script>
How can I avoid sending multiple Ajax calls when I click on the button? Also, what is the correct way to redirect to a different page after the logic is executed? Thanks for reading!
PS: I am using python/django in the backend

The answer is in your code. You attach event handler everytime you move item. So when you sort 5 items, you attach 5 event handlers to your submit button. Then when you click the button all 5 event handlers fire ajax call at once. You should move onclick event handler outside and pass variable through function argument or public variable.

Related

Execute DataTables ajax.reload() Async before a function

I am trying to source some data from the datatable I am working on. I have an edit button on every row and when is clicked it suppose to bring a form with the data that is already in the table for editing. I need to get real time data when the form is render however ajax.reload() doesn't load the table on time for the form be filled by the correct data and with code below only shows the form for the first employee:
let editEmployeeId;
$(document).ajaxStop(function(){
$('#employeesTable tbody').on('click', '.btn.btn-warning.small-edit-button', function(){
let thisRow = this;
tableEmployees.ajax.reload(function(){
//tableDepartments.draw();
tableDepartments.columns().search("").draw();
//tableEmployees.columns().search("").draw();
getDropdown(1,'#departmentEditDropdown', 'Departments');
var data = tableEmployees.row($(thisRow).parents('tr')).data() || tableEmployees.row($(thisRow).parents('li').attr('data-dt-row')).data();
$('#editFirstName').val(data.firstName);
$('#editLastName').val(data.lastName);
$('#departmentEditDropdown>select').val(data.department);
updateLocation('#locationEditDropdown','#departmentEditDropdown>select');
$('#departmentEditDropdown>select').trigger('change');
$('#locationEditDropdown>select').val(data.locationID);
$('#editJobTitle').val(data.jobTitle);
$('#editEmail').val(data.email);
$('#editEmployeeModal').modal("show");
});
});
I tried:
promise
settimeout
nested functions
async functions
I also try to change ajax call to set async: false and this way it works perfect but I don't think that is a good practice and I have other calls through the document and takes double of time to load the page first time.
I changed the way of calling the button with an extra class for the employees page and used the .click() method instead .on() because for some reason it was going in a loop with the last one. Now works and this is how it looks:
let editEmployeeId;
$(document).ajaxStop(function(){
$('.btn.btn-warning.small-edit-button.employees').click(function(e){
e.preventDefault();
let thisRow = tableEmployees.row($(this).parents('tr'));
let thatRow = tableEmployees.row($(this).parents('li').attr('data-dt-row'));
tableDepartments.columns().search("").draw();
tableEmployees.columns().search("").draw();
getDropdown(1,'#departmentEditDropdown', 'Departments');
tableEmployees.ajax.reload(function(){
var data = thisRow.data() || thatRow.data();
editEmployeeId = data.id;
$('#editFirstName').val(data.firstName);
$('#editLastName').val(data.lastName);
$('#departmentEditDropdown>select').val(data.department);
$('#departmentEditDropdown>select').trigger('change');
$('#editJobTitle').val(data.jobTitle);
$('#editEmail').val(data.email);
$('#editEmployeeModal').modal("show");
})
});

Bootstrap modal does not work correctly with my ajax code

I created a partial view called ModalReq, which needs to be populated with data from the database.
The controller and view is working correctly.
But when you click on an element with the class '.car-box', nothing happens at first, after the second press, the correctly filled modal appears, but it doesn’t want to close in any way, how to make the modal work correctly?
Ajax code in main view:
<script>
function ajaxReq(url,type,selector) {
$.ajax({
url: url,
type: type,
contentType: 'application/json',
success: function (data) {
$(selector).html(data);
}
});
}
</script>
<script>
$(document).on('click', '.car-box', function () {
var objText = $(this).children('.box-his').children("span").text();
var objId = objText.substring(1, objText.length);
ajaxReq("#Url.Action("ModalReq")" + "?productId=" + objId, "POST", '#result');
$('#myModal').modal('show')
});
</script>
And I create a div with it at the very bottom of this view( but still above the Ajax code )
<div id="result"></div>
When you click on an element with the class '.car-box', the Ajax code creates an object that receives its number with a string type inside the card. It then leaves only a number with the same type of string. Then I call ajaxReq in which I transmit my partial view that accepts the Id specified by us. Then includes the created modal ...
I never use ajax before, so I need your help =)
In the current iteration $('#myModal').modal('show') is not waiting for the Ajax response.
How about moving it to your success function?
success: function (data) {
$(selector).html(data);
$('#myModal').modal('show')
}
Then the modal will get the data after one press.
Or: this answer jQuery ajax with ES6 Promises should give you guidance setting it up as a Promise.

submitting a form via ajax upon stop event of jquery

UPDATE
Added this error, just says "Error caught"
<script type="text/javascript">
window.onerror = function() {
alert("Error caught");
};
xxx();
</script>
This is not working, I don't understand why.
My php script inserts data properly if called by itself without an if{method=post} statement
I tried with and without an if method = post argument on the php side to get the ajax below to work but I can't tell if the script is being called at all.
My aim is to submit the data without the user knowing, it's a coordinate / dimension update for a variable design interface.
This is my ajax insert which is supposed to work when a function is invoked after the stop is triggered eg. after an object is done moving which the function is invoked properly as I have set up sequential alerts to pop up after certain lines.
$("#form").submit(function(event){
event.preventDefault();
var $form = $( this ),
url = $form.attr( 'action' );
var posting = $.post( url, {
id: $('#id').val(),
name: $('#name').val(),
wname: $('#wname').val(),
xcor: $('#xcor').val(xcor),
ycor: $('#ycor').val(ycor),
xwid: $('#xwid').val(xwid),
yhei: $('#yhei').val(yhei),
photo: $('#photo').val(),
targeturl: $('#targeturl').val()
});
posting.done(function( data ){
alert('success');
});
});
This is wrong
xcor: $('#xcor').val(xcor),
ycor: $('#ycor').val(ycor),
xwid: $('#xwid').val(xwid),
yhei: $('#yhei').val(yhei),
Those object are holding jQuery objects, not a value.
Looks like you want to set the value and use the new value. This makes me cringe, but it would do the job
xcor: $('#xcor').val(xcor).val(),
ycor: $('#ycor').val(ycor).val(),
xwid: $('#xwid').val(xwid).val(),
yhei: $('#yhei').val(yhei).val(),
You would be better off updating them before the call and just using the variable when setting the object. Or just use jQuery serialize() and don't deal with grabbing the elements.

Finding the element after an ajax event

I'm working on a site that allows users to love an item (like an item). The event is handled with jQuery and AJAX. The item array holds quite a lot of items and each item has a button to 'love'. I decided to efficiently reduce the number of forms on the page by putting one form at the bottom of the page and just submit it remotely.
So every time a user clicks the love button, the data attribute that holds the item id is put into the form and the form is submitted. Simple stuff.
But I'm finding the data response a bit more complex because I don't know how to find the element id of the item I want to update. I can't just use this or event.target because its inside a different event. I've also tried to carry the event parameter into the submit event, but it didn't work.
$(".love_item").click (event) ->
$(".love_item_item_id").val $(this).data 'id'
$(".love_item_form").submit()
$(this).hide(200)
$("form.love_item_form").submit (evt) ->
evt.preventDefault()
$form = $ #
$form.find(':submit').prop 'disabled', true
$.post($form.attr('action'), $form.serializeArray(), type: 'json').done (data) ->
$(event.target).parent().find(".item_info_box").html data
The last line, where it says event.target is as far as I've got. Its obvious that this variable is not carried, but I don't really know what to place there to achieve my goal. Also, I know that I could pass additional parameters through the form action (in other words send them to the rails controller and back), but I'd rather not. Any ideas?
You don't need an abitrary form at all. Something like this would work:
Example Markup (notice the data attribute):
Item to like
jQuery:
$('a.likeable').on('click', function() {
var $item = $(this);
var id = $item.data('id');
$.post('url/like/' + id, function() {
// success
// do something with $item here.
});
});
If you have an element like this: <div id="foo" data-id="foo1234">Foo</div>
You can select it after your ajax post like this, assuming you still have the ID of foo1234:
$('[data-id="' + id + '"]').doSomething();
Just use jQuery's ajax functionality
$('.love_item').on('click', function(e) {
$.ajax({
type: 'POST',
url: *insert url here*,
data: 'id=' + e.currentTarget.data-id,
success: function(response) {
var element = e.currentTarget;
// do whatever
}
})
});

Asp net mvc and javascript response

I had a javascript that needs to do two things:
1. Send data to be updated in database
2. Update my html form place in show mode.
3. Update the row of my table to reflect updated data.
My javascript do only 1 and 2:
$(".form-commands .save").live("click", function () {
var f = $(".form-edit");
var sf = f.serialize();
$.post(this.href,
sf,
function (response) {
f.html(response);
});
// I need to do something here to update the html table row...
return false;
});
I think that a solution is to call another action that will render only the table row elements.
How can I do this?
--
The table row was created something like this:
<tr id="h62">
<td>Ford</td>
<td>Focus</td>
</tr>
where 62 is the "id" of this record.
Working code, but ugly:
$(".form-commands .save").live("click", function () {
var f = $(".form-edit");
var sf = f.serialize();
var handle = $(".form-edit #Handle")[0].value;
var itemLink = this.attributes["edititem"].value;
var row = $("#grid #h" + handle);
$.post(this.href,
sf,
function (response) {
$("#form-edit").html(response);
$.get(itemLink,
sf,
function (response) {
row.replaceWith(response);
});
});
return false;
});
You need to do something like this:
$(".form-commands .save").live("click", function (evt) {
//Capture the jQuery event object and call preventDefault() to stop the default click action
evt.preventDefault();
var f = $(".form-edit");
var sf = f.serialize();
$.post(this.href,
sf,
function (response) {
f.html(response);
});
//UPDATE THE ROWS
$('#h62 td:eq(0)').text(newVehicleMakeName);
$('#h62 td:eq(1)').text(newVehicleModelName);
});
I am not sure from your code where the vehicle data is coming from. If you are passing it back from your controller then you will need to move this line into your success callback.
Also, you should generally never return false, you should capture the jQuery event as a param and call preventDefault(). If your click handler uses return false to prevent browser navigation, it opens the possibility that the interpreter will not reach the return statement and the browser will proceed to execute the anchor tag's default behavior. This is what was causing your problem, not because you were using click vs submit. The benefit to using event.preventDefault() is that you can add this as the first line in the handler, thereby guaranteeing that the anchor's default behavior will not fire.
Well I would just reload the page or recall the ajax routine (whichever is applicable) to reload the data, there is no straightforward method to do this. In fact I was not aware of the method you used (f.html(response)), i am still skeptical about that solution :)
Well, if you really just want to update that single row:
1) You need to know to know the updated row's id in your javascript code. This value is "h62" (without quotes) in this example.
2) Give class names to your TDs, e.g.
<tr id="h62">
<td class="brand">Ford</td>
<td class="model">Focus</td>
</tr>
3) Update using jquery. Let's say you hold the id of the row in a variable named "rowId":
$('#'+rowId).find('.brand').html(response.brand);
$('#'+rowId).find('.model').html(response.model);
This will conclude the process.

Categories