How to access a selector on AJAX Complete? - javascript

I make an Ajax Request that adds content to the page with HTML from the back-end, and then I make another Ajax Request that modifies that dynamically added HTML.
$("#list-customers-button").click(function () {
var selectedAcquirer = $("#acquirer-select").val();
if (selectedAcquirer === "adyen") {
if (listed) {
listed = false;
$("#customer-list-area").hide().html('').fadeIn(fadeTime);
} else {
listed = true;
$.ajax({
type: "GET",
url: "/adyen_list_customers",
contentType: "application/json; charset=utf-8",
dataType: "json",
beforeSend: function () {
$("#list-progress").show();
},
success: function (data) {
console.log(JSON.stringify(data));
$("#customer-list-area").hide().html(data["response_html"]).fadeIn(fadeTime).promise().done(function () {
$(".collapsible").collapsible();
resetDatepicker();
});
},
complete: function () {
$(document).on("change", "#file-download-datepicker", function () {
$("#file-download-progress").hide();
$("#file-download-date").val(selectedDate);
fileDownloadData = $("#file-download-form").serialize();
displayMessage(fileDownloadData);
$.ajax({
type: "POST",
url: "/adyen_update_file_list_by_date",
data: fileDownloadData,
beforeSend: function () {
$("#file-download-progress").show();
},
success: function (response) {
},
complete: function (response) {
$("#file-download-progress").hide();
console.log(response.responseText);
// Doesn't work. Selector should exist, but it doesn't.
$("#merchant-file-list").html(response.responseText);
},
error: function (response) {
displayMessage(response["responseText"]);
}
});
});
},
error: function (data) {
displayMessage(data);
},
});
}
} else if (selectedAcquirer === "stone") {
displayMessage("Adquirente indisponível no momento.");
} else {
displayMessage("É necessário selecionar uma adquirente.");
}
});
I get a perfect HTML response from the server, but selectors that were previously added with HTML also from the server (#file-download-progress, #merchant-file-list) are completely ignored. .html() doesn't work, nor anything, and I don't know how to use .on() to work around this because I just need to access that content. Since the ajax request is being made after the previous one is complete, they should be able to be accessed. They just don't exist nowhere in time.

Related

Add CSS element after kendogrid refresh

I have an ajax call that sends to MyAction in MyController.. it returns me with result of success and an Id for an element to which I want to attach some CSS.
the Id is returned, and the css is added but the refreshGridData happens afterwards removing the css I just added to the element.
Is there a way to wait for refreshGridData to finish and then add the css?
I did try the done for ajax.. it did not work.
$.ajax({
url: "#Url.Action("MyAction", "MyController")",
type: "POST",
data: postData,
success: function (result) {
if (result.Success) {
alert("success");
refreshGridData();
}
},
error: function (result) {
alert("Error!");
}
AddMyCSSToThis(result.Id);
// done: AddMyCSSToThis(result.Id);
});
function refreshGridData() {
var ajaxContainer = $(".grid-wrap");
kendo.ui.progress(ajaxContainer, true);
refreshGrid();
kendo.ui.progress(ajaxContainer, false);
}
Why don't you pass in the Id you want to add the change into your refreshGridData() function like:
$.ajax({
url: "#Url.Action("MyAction", "MyController")",
type: "POST",
data: postData,
success: function (result) {
if (result.Success) {
alert("success");
var savedId = result.Id;
refreshGridData(savedId);
}
},
error: function (result) {
alert("Error!");
}
AddMyCSSToThis(result.Id);
// done: AddMyCSSToThis(result.Id);
});
function refreshGridData(savedId) {
var ajaxContainer = $(".grid-wrap");
kendo.ui.progress(ajaxContainer, true);
refreshGrid(savedId); // I'm assuming this function is what adds the css
kendo.ui.progress(ajaxContainer, false);
}
You could create a global variable and use it in the grid dataBound event to add the CSS.
_addCssToResultId = null;
$.ajax({
url: "#Url.Action("MyAction", "MyController")",
type: "POST",
data: postData,
success: function (result) {
if (result.Success) {
alert("success");
_addCssToResultId = result.Id;
refreshGridData();
}
},
error: function (result) {
alert("Error!");
}
});
// add a dataBound handler to your grid
$("#grid").kendoGrid({
dataBound: function(e) {
if(_addCssToResultId) {
AddMyCSSToThis(_addCssToResultId);
_addCssToResultId = null;
}
}
});

Dynamically loaded partial view dynamically load another partial [duplicate]

This question already has answers here:
Event binding on dynamically created elements?
(23 answers)
Closed 5 years ago.
Just wondering if this is even possible.
I am making a store web application in asp.net MVC 4 i guess.
And my articles have a category and a sub category.
So I got this code which I can't make to work.
Script:
$("#ManageCategories").click(function (e) {
$.ajax({
type: "GET",
url: "Acp/LoadManageCategories",
success: function (response) {
$("#main-acp-display").html(response);
},
error: function () {
alert("Error!");
}
});
});
$(".get-subcategories").click(function () {
$.ajax({
type: "GET",
url: "Acp/LoadManageSubCategories",
data: { subCategoryId: $(this).attr("id") },
contentType: "application/json; charset=utf-8",
dataType: "html",
success: function (response) {
$("#subcategory-display").html(response);
},
error: function (response) {
alert(response.responseText);
}
});
});
(the first part works like a charm)
Controler:
[CustomAuthorize(Roles.Admin)]
public ActionResult LoadManageCategories()
{
IEnumerable<CategoryModel> model = _categoryManager.GetAll().Select(x => (CategoryModel)x);
return PartialView("Partial/_LoadManageCategories", model);
}
[CustomAuthorize(Roles.Admin)]
public ActionResult LoadManageSubCategories(string subCategoryId)
{
int id = Convert.ToInt32(subCategoryId);
IEnumerable<SubCategoryModel> model = _categoryManager.GetAllSubCategoriesByCategoryId(id).Select(x => (SubCategoryModel)x);
return PartialView("Partial/_LoadManageSubCategories", model);
}
Now you see the first level code works. When I click a div on index it loads all categories. But the other function wont load unless I place the clickable div on index page too and I wanted it to be a part of first partial view.
So it should be Button(click) > Shows all categories(click any) > Loads subcategories.
Is this even possible?
Offtopic: Does MVC work only on one level? Cause I remember trying to have a Model with List of other models inside of it and inside this list there was another model and it wasn't so good xD (Managed to find simpler solution, but this is where I got the mvc one level only thought)
Update:
So #bigless had an idea to make this a function so here it is so far:
function createSubcategories(id) {
$.ajax({
type: "GET",
url: "Acp/LoadManageSubCategories",
data: { subCategoryId: id },
contentType: "application/json; charset=utf-8",
dataType: "html",
success: function (response) {
$("#subcategory-display").html(response);
},
error: function (response) {
alert(response.responseText);
}
});
};
And calling it by:
<button onclick="createSubcategories(1)"><i class="fas fa-angle-double-right main-cat-icon"></i></button>
Current error:
Uncaught ReferenceError: createSubcategories is not defined
at HTMLButtonElement.onclick (Acp:89)
You can not attach event listener to DOM element(.get-subcategories) that does not exist yet. Try something like $(document).on('click', '.get-subcategories', function() { .. or:
$("#ManageCategories").click(function (e) {
$.ajax({
type: "GET",
url: "Acp/LoadManageCategories",
success: function (response) {
$("#main-acp-display").html(response).ready(function() {
$(".get-subcategories").click(createSubcategories);
});
},
error: function () {
alert("Error!");
}
});
});
function createSubcategories() {
$.ajax({
type: "GET",
url: "Acp/LoadManageSubCategories",
data: { subCategoryId: $(this).attr("id") },
contentType: "application/json; charset=utf-8",
dataType: "html",
success: function (response) {
$("#subcategory-display").html(response);
},
error: function (response) {
alert(response.responseText);
}
});
};

Session Storage error on firefox only

My code works well in Chrome and Edge, but I'm getting this error in Firefox:
TypeError: 'key' called on an object that does not implement interface Storage
function goToNextStep() {
$.post("../manager.php", {
dados: sessionStorage,
action: "save"
}, function(response) {
if (response === "1") {
$.ajax({
type: "GET",
url: "../final.php",
success: function(data) {
$('#content').html(data);
}
});
}
});
}
You're attempting to pass the entire sessionStorage object in an AJAX request. Don't do that. Instead pull out the specific keys that you require. Something like this:
function goToNextStep() {
$.post("../manager.php", {
dados: {
foo: sessionStorage.getItem('foo'),
bar: sessionStorage.getItem('bar')
},
action: "save"
}, function(response) {
if (response === "1") {
$.ajax({
type: "GET",
url: "../final.php",
success: function(data) {
$('#content').html(data);
}
});
}
});
}
I'd also suggest that you return JSON instead of plain text, as the latter can lead to issues with whitespace causing unexpected results. It's also better typed, so you can return a boolean state flag, eg:
if (response.success) {
// your logic here...
}
I was able to solve this with the following workaround:
function goToNextStep() {
$.post("../manager.php", {
dados: JSON.parse(JSON.stringify(localStorage)), // <----- change
action: "save"
}, function(response) {
if (response === "1") {
$.ajax({
type: "GET",
url: "../final.php",
success: function(data) {
$('#content').html(data);
}
});
}
});
}

Rebind function when change DOM after ajax

I'm trying to get the height of an element before and after an ajax call to change the content of this element (for learning reasons).
Example:
$(document).ready()
calcHeigth('#listar-cursos');
});
funcion calcHeigth(idElement){
console.log($(idElement).outerHeight(true));
}
<div id="listar-cursos">all the content is here</div>
When the document is ready, calcHeigth function returns 200px.
There is a form on that page that is sent by ajax and when the request ends I just empty the contents of the element, and then call calcHeigth again (in ajaxComplete event).
$("#formSeacrh").submit(function () {
if ($(this).valid()) {
var url = $(this).attr("action");
var data = $(this).serialize();
$.ajax({
type: "POST",
url: url,
data: data,
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
success: function (data) {
$("#listar-cursos").html("");
},
complete: function () {
Completo();
},
beforeSend: function () {
Carregando();
},
error: function () {
Falha();
},
ajaxComplete: function () {
calcHeigth('#listar-cursos');
}
})
return false;
}
return false;
});
The result from calcHeigth is always 200px, like when the document is ready, even with the empty element. calcHeigth not realized that the element was changed. The result that I expected was 40px. How to fix and get the current height?
$("#formSeacrh").submit(function () {
if ($(this).valid()) {
var url = $(this).attr("action");
var data = $(this).serialize();
$.ajax({
type: "POST",
url: url,
data: data,
contentType: "application/x-www-form-urlencoded; charset=UTF-8",
success: function (data) {
$("#listar-cursos").html("");
Completo();
calcHeigth('#listar-cursos');
},
beforeSend: function () {
Carregando();
},
error: function () {
Falha();
}
})
return false;
}
return false;
});
you only need 1 ready function, not 3. i hope this works now how you wish.
if you do your calc after your clear the html from the node, the height should be 0.
by the way. $('listar-cursos').empty() is better than .html("")

how to load div from html by using jquery?

I made 3 navigation navbarheader.html, navbar.html and sidebar.html.Only navbarheader.html is loading but others is not loading. if I remove navbarheader.html navbar.html is loading.
<script type="text/javascript">
// let $ = requirejs('./jquery.min.js');
//mainWindow.$ = $;
$(document).ready(function () {
var navbarheaderData = localStorage.getItem('navbarheaderStorage');
if (navbarheaderData) {
$('#navbarheader1').html(navbarheaderData);
} else {
$.ajax({
url: 'navbarheader.html',
dataType: 'text',
success: function (data) {
localStorage.setItem('navbarheaderStorage', data);
$('#navbarheader1').html(data);
var navbarData = localStorage.getItem('navbarStorage');
if (navbarData) {
$('#navbar1').html(navbarData);
} else {
$.ajax({
url: 'navbar.html',
dataType: 'text',
success: function (data) {
localStorage.setItem('navbarStorage', data);
$('#navbar1').html(data);
var sidebarData = localStorage.getItem('sidebarStorage');
if (sidebarData) {
$('#sidebar1').html(sidebarData);
} else {
$.ajax({
url: 'sidebar.html',
dataType: 'text',
success: function (data) {
localStorage.setItem('sidebarStorage', data);
$('#sidebar1').html(data);
}
});
}
}
});
}
}
});
}
});
</script>
That's because you are using ajax requests, which stands for Asynchronous JavaScript and XML, but can be used with other datatypes (like text and therefore json), so the lines where you retrieve navbarheaderData, navbarData, and sidebarData are being executed immediately after you launch the requests, which would explain why only the first one would load (because there's only time for the first one to get a response before you start rendering the data).
What you really want is
<script type="text/javascript">
$(document).ready(function () {
$.ajax({
url: 'navbarheader.html',
dataType: 'text',
success: function (data) {
localStorage.setItem('navbarheaderStorage', data);
//console.log(localStorage.getItem('navbarheaderStorage'));
var navbarheaderData = localStorage.getItem('navbarheaderStorage');
$('#navbarheader1').html(navbarheaderData);
}
});
$.ajax({
url: 'navbar.html',
dataType: 'text',
success: function (data) {
localStorage.setItem('navbarStorage', data);
//console.log(localStorage.getItem('navbarStorage'));
var navbarData = localStorage.getItem('navbarStorage');
$('#navbar1').html(navbarData);
}
});
$.ajax({
url: 'sidebar.html',
dataType: 'text',
success: function (data) {
localStorage.setItem('sidebarStorage', data);
//console.log(localStorage.getItem('sidebarStorage'));
var sidebarData = localStorage.getItem('sidebarStorage');
$('#sidebar1').html(sidebarData);
}
});
});
</script>
which could be simplified into the following if you don't need to use local storage.
<script type="text/javascript">
$(document).ready(function () {
$.ajax({
url: 'navbarheader.html',
dataType: 'text',
success: function (data) {
$('#navbarheader1').html(data);
}
});
$.ajax({
url: 'navbar.html',
dataType: 'text',
success: function (data) {
$('#navbar1').html(data);
}
});
$.ajax({
url: 'sidebar.html',
dataType: 'text',
success: function (data) {
$('#sidebar1').html(data);
}
});
});
</script>
#Penguen replied and changed their above code.
I see that you don't want to send an ajax request unless you need to, which is functioning as some sort of weird caching mechanism. In this case the way you have written this, we only had navbarHeaderData cached and not the rest, then the page would fail to render properly. The following way not only protects against what I said, but is also faster than if the rewritten method works as if you were loading this for the first time and didn't have this cached, then the ajax requests would be sent out almost at the same time, rather than one by one.
<script type="text/javascript">
// let $ = requirejs('./jquery.min.js');
//mainWindow.$ = $;
$(document).ready(function () {
var navbarheaderData = localStorage.getItem('navbarheaderStorage');
if (navbarheaderData) {
$('#navbarheader1').html(navbarheaderData);
} else {
$.ajax({
url: 'navbarheader.html',
dataType: 'text',
success: function (data) {
localStorage.setItem('navbarheaderStorage', data);
$('#navbarheader1').html(data);
}
});
}
var navbarData = localStorage.getItem('navbarStorage');
if (navbarData) {
$('#navbar1').html(navbarData);
} else {
$.ajax({
url: 'navbar.html',
dataType: 'text',
success: function (data) {
localStorage.setItem('navbarStorage', data);
$('#navbar1').html(data);
}
});
}
var sidebarData = localStorage.getItem('sidebarStorage');
if (sidebarData) {
$('#sidebar1').html(sidebarData);
} else {
$.ajax({
url: 'sidebar.html',
dataType: 'text',
success: function (data) {
localStorage.setItem('sidebarStorage', data);
$('#sidebar1').html(data);
}
});
}
});
</script>
From what I see, I see 3 templates being fetched by making AJAX calls and then you are caching the template in your local storage and then use that to render the 3 sections of your web page.
Here is what you are doing it wrong. The render part of the code is written all together in the window.load and does not care about whether the AJAX call is complete or not. As your calls are asynchronous the code will not wait until the response template is fetched.
What you can do instead is have a common render function which each ajax call success method can call.
You are suffering from asynchronous issues, you should do the work inside each request. I dont think its related to local storage.
<script type="text/javascript">
$(document).ready(function () {
var navbarheaderData = localStorage.getItem('navbarheaderStorage');
if (navbarheaderData) {
$('#navbar1').html(data);
} else {
$.ajax({
url: 'navbarheader.html',
dataType: 'text',
success: function (data) {
$('#navbar1').html(data);
}
});
}
.... and so on...
});

Categories