jQuery nested XML question - javascript

I am using jQuery to insert an HTML shell into a page, and populate the shell with XML. Here is the XML in question
<minorPropCategory title="Test Title 1">
<minorProp>FLV</minorProp>
<minorProp>BLV</minorProp>
<minorProp>RLV</minorProp>
</minorPropCategory>
<minorPropCategory title="Test Title 2">
<minorProp>LAS</minorProp>
<minorProp>ILV</minorProp>
<minorProp>BIL</minorProp>
</minorPropCategory>
So first, what I do is import an HTML snippet for each minorPropCategory, and add the title using this code
$(xml).find('minorPropCategory').each(function(){
var minorHeader=$(this).attr("title");
var minorId=$(this).attr("title").replace(/ /g,'');
var minorModuleContainerCode = "minorModuleContainer.html";
//names the div with a unique ID
minorDiv = $("<div id='"+minorId+"minorModuleContainer' class='minorModuleGroupContainer'>");
//Sets loading message in case it takes longer than usual to load
minorDiv.html("Loading......");
//After minorModuleContainerCode.html code loads, starts populating module
minorDiv.load(minorModuleContainerCode,"t",
function(){
$("#"+minorId+"minorModuleContainer").find(".minorModuleHeader").html(minorHeader);
}
);
$("#minorModuleContainer").append(minorDiv);
Then, what I want to do is add another HTML snippet, and then populate it. This is where I am having a problem. I can try it like this
//Create the actual minor modules
$(this).find('minorProp').each(function(){
var minorPropCode = $(this).text();
var minorModuleCode = "minorModule.html";
minorModuleDiv = $("<div id='"+minorPropCode+"minorModule' class='minorModule'>");
minorModuleDiv.html("Loading......");
minorModuleDiv.load(minorModuleCode,"b",
function(){
$.ajax({
type: "GET", url: minorPropCode+".xml", dataType: "xml",
success: function(xml3) {
$("#"+minorPropCode+"minorModule").find(".minorPropLogo").attr(
{
src:$(xml3).find('smallImage').text(),
alt:$(xml3).find('smallImageAlt').text()
}
);
}
});
});
$("#"+minorId+"minorModuleContainer").append(minorModuleDiv);
});
});
But it never shows up on the page, because I don't think it is firing at the proper time. Alternatively, I tried moving the creation of the minor modules into the .load function of it's parent, but I run into another problem. The code looks like this.
//MINOR MODULE CODE
$(xml).find('minorPropCategory').each(function(){
var minorHeader=$(this).attr("title");
var minorId=$(this).attr("title").replace(/ /g,'');
var minorModuleContainerCode = "minorModuleContainer.html";
//names the div with a unique ID
minorDiv = $("<div id='"+minorId+"minorModuleContainer' class='minorModuleGroupContainer'>");
//Sets loading message in case it takes longer than usual to load
minorDiv.html("Loading......");
//After minorModuleContainerCode.html code loads, starts populating module
minorDiv.load(minorModuleContainerCode,"t",
function(){
$("#"+minorId+"minorModuleContainer").find(".minorModuleHeader").html(minorHeader);
$(this).find('minorProp').each(function(){
alert("minorPropFired");
var minorPropCode = $(this).text();
var minorModuleCode = "minorModule.html";
minorModuleDiv = $("<div id='"+minorPropCode+"minorModule' class='minorModule'>");
minorModuleDiv.html("Loading......");
minorModuleDiv.load(minorModuleCode,"b",
function(){
$.ajax({
type: "GET", url: minorPropCode+".xml", dataType: "xml",
success: function(xml3) {
alert("test");
$("#"+minorPropCode+"minorModule").find(".minorPropLogo").attr(
{
src:$(xml3).find('smallImage').text(),
alt:$(xml3).find('smallImageAlt').text()
}
);
}
});
});
$("#"+minorId+"minorModuleContainer").append(minorModuleDiv);
});
The problem is, that the line with "$(this).find('minorProp').each(function(){" doesn't fire because "this" has changed. I guess, by now, my noob is showing. I feel like I am doing this in the wrong way. Any help would be appreciated. Thanks.
Posted below is the full .js file of what I am trying to do.
// JavaScript Document<script language="JavaScript" type="text/javascript">
$(document).ready(function(){
//gets the code for the ad from the URL. Using URL jQuery add-on to make this super-easy
var adCode = $.url.param("adCode");
if (adCode != null){
//gets the ad code's XML file
$.ajax({
type: "GET", url: adCode+".xml", dataType: "xml",
success: function(xml) {
//Set the header image
$("#headerImg").attr(
{
src:$(xml).find('headerImage').text(),
alt:$(xml).find('headerImageAlt').text()
}
);
//set the header text
$("#headerText").html($(xml).find('adText').text());
//set the top image
$("#topImg").attr(
{
src:$(xml).find('topImage').text(),
alt:$(xml).find('topImageAlt').text()
}
);
//MAJOR MODULE CODE - This code reads all of the major modules, then adds a majorModule div, and populates it
//Gets all majorProps from ad XML
$(xml).find('majorProp').each(function(){
var propCode=$(this).text();
var majorModuleCode = "majorModule.html";
//names the div with a unique ID
div = $("<div id='"+propCode+"majorModule' class='majorModule'>");
//Sets loading message in case it takes longer than usual to load
div.html("Loading......");
//After majorModule.html code loads, starts populating module
div.load(majorModuleCode,"t",
function(){
//Get the XML for the prop, which contains prop specific stuff
$.ajax({
type: "GET",
url: propCode+".xml",
dataType: "xml",
success: function(xml2) {
$("#"+propCode+"majorModule").find(".propImg").attr(
{
src:$(xml2).find('smallImage').text(),
alt:$(xml2).find('smallImageAlt').text()
}
);
$("#"+propCode+"majorModule").find(".propLogoImg").attr(
{
src:$(xml2).find('smallLogo').text(),
alt:$(xml2).find('name').text()
}
);
$("#"+propCode+"majorModule").find(".viewCalendarLinkA").attr(
{
href:"https://www.harrahs.com/AvailabilityCalendar.do?propCode="+propCode+"&showHotDeal=Y"
}
);
$("#"+propCode+"majorModule").find(".learnMoreLinkA").attr(
{
href:$(xml2).find('homeLink').text()
}
);
$("#"+propCode+"majorModule").find(".propText").html(
$(xml2).find('bodyText').text()
);
}
});
//Get the lowest rate for the prop
$.ajax({
type: "GET",
url: "lowest_rate\\"+propCode+".xml",
dataType: "xml",
success: function(xml3) {
$("#"+propCode+"majorModule").find(".roomRate").html(
"$"+($(xml3).find('roomtype').filter(
function (index) {
return $(this).attr("lowest") == "Y";
}).text()).slice(0, -3)
)
}
});
}
);
$("#mainModuleContainer").append(div);
});
//MINOR MODULE CODE
$(xml).find('minorPropCategory').each(function(){
var minorHeader=$(this).attr("title");
var minorId=$(this).attr("title").replace(/ /g,'');
var minorModuleContainerCode = "minorModuleContainer.html";
//names the div with a unique ID
minorDiv = $("<div id='"+minorId+"minorModuleContainer' class='minorModuleGroupContainer'>");
//Sets loading message in case it takes longer than usual to load
minorDiv.html("Loading......");
//After minorModuleContainerCode.html code loads, starts populating module
minorDiv.load(minorModuleContainerCode,"t",
function(){
$("#"+minorId+"minorModuleContainer").find(".minorModuleHeader").html(minorHeader);
}
);
$("#minorModuleContainer").append(minorDiv);
//Create the actual minor modules
$(this).find('minorProp').each(function(){
var minorPropCode = $(this).text();
var minorModuleCode = "minorModule.html";
minorModuleDiv = $("<div id='"+minorPropCode+"minorModule' class='minorModule'>");
minorModuleDiv.html("Loading......");
minorModuleDiv.load(minorModuleCode,"b",
function(){
$.ajax({
type: "GET", url: minorPropCode+".xml", dataType: "xml",
success: function(xml3) {
$("#"+minorPropCode+"minorModule").find(".minorPropLogo").attr(
{
src:$(xml3).find('smallImage').text(),
alt:$(xml3).find('smallImageAlt').text()
}
);
}
});
});
$("#"+minorId+"minorModuleContainer").append(minorModuleDiv);
});
});
}
});
}
});

To fix this problem just before running minorDiv.load do something like this
var elem = $(this);
minorDiv.load(minorModuleContainerCode,"t", function(){
$("#"+minorId+"minorModuleContainer").find(".minorModuleHeader").
html(minorHeader);
// replace $(this) with elem here
elem.find('minorProp').each(function(){
...
}
...
}
This will keep the reference to correct object in your nested functions.

Related

Passing parameters between html pages using jquery

I have one html page which contains a jquery function.
<script>
function loadCustomers() {
$.ajax({
type: 'GET',
url: 'http://localhost:8080/cache/getCustomers',
dataType: 'json',
success: function(data) {
var rows = [];
$.each(data,function(id,value) {
rows.push('<tr><td><a href="clientSiteInfo.html?client=">'+id+'</td><td>'+value+'</td></tr>');
});
$('table').append(rows.join(''));
}
});
};
window.onload = loadCustomers;
</script>
I have linked another html page for each row. When each rows populated, the id values has to be passed to the clientSiteInfo.html page.
In the clientSiteInfo.html page i have another jquery function similar to above.
<script>
function loadSites() {
$.ajax({
type: 'GET',
url: 'http://localhost:8080/cache/getSite?clientName='+${param.client},
dataType: 'json',
success: function(data) {
var rows = [];
$.each(data,function(id,value) {
rows.push('<tr><td>'+id+'</td><td>'+value.machine+'</td><td>'+value.state+'</td></tr>');
});
$('table').append(rows.join(''));
}
});
};
window.onload = loadSites;
</script>
in the GET url I try to read client parameter. But it is not passing from my initial page.
What Im doing wrong here? I look for simple solution
jQuery doesn't have a native way to read the url parameters. However, javascript works just fine:
function getParameterByName(name) {
const match = RegExp(`[?&]${name}=([^&]*)`).exec(window.location.search);
return match && decodeURIComponent(match[1].replace(/\+/g, ' ') );
}
In your code you would just call it as getParameterByName('client')

Multiple AJAX calls and show div on finish

I have a JS script doing multiple AJAX requests. First I'm requesting a product by ID and then I'm requesting every single variant of this product. I can't do any form of backend coding since the environment I'm working in is closed.
My requests works fine, but right now I'm appending every single variant to a div, and my client don't really like this, so I was thinking is it possible to load all data into a variable and then fade in the parent div of all variants at the very end?
My script looks like this:
var variants = $('.single_product-variant-images');
$.ajax({
url: productMasterURL,
success: function (data) {
$(data).find('Combinations Combination').each(function () {
var variantID = $(this).attr('ProductNumber');
$.ajax({
url: "/api.asp?id=" + escape(variantID),
dataType: "json",
async: true,
cache: true,
success: function (data) {
variants.append('<div class="variant"><img src="' + data.pictureLink + '" alt=""/></div>');
variants.find('.variant').fadeIn(300);
}
});
});
}
});
Some fast and dirty solution, but idea and concept of solution is clear. It is bad solution, but works for you in your case when you have no access to backend code.
var all_load_interval;
var is_all_data_ready = false;
var all_data_count = 0;
var variants = $('.single_product-variant-images');
$.ajax({
url: productMasterURL,
success: function (data) {
var data_count = $(data).find('Combinations Combination').length;
$(data).find('Combinations Combination').each(function () {
var variantID = $(this).attr('ProductNumber');
$.ajax({
url: "/api.asp?id=" + escape(variantID),
dataType: "json",
async: true,
cache: true,
success: function (data) {
// make div with class variant hidden
variants.append('<div class="variant"><img src="' + data.pictureLink + '" alt=""/></div>');
// count every variant
all_data_count += 1
if (all_data_count == data_count) {
// when all data got and created, lets trigger our interval - all_load_interval
is_all_data_ready = true;
}
}
});
});
}
all_load_interval = setInterval(function() {
// Check does all data load every second
if (is_all_data_ready) {
// show all div.variant
variants.find('.variant').fadeIn(300);
clearInterval(all_load_interval);
}
}, 1000);
});

jQuery Ajax GET request not working correctly

I'm trying to call an AJAX query and have had lots of trouble recently.
Im trying to call a api that I have custom made myself, it displays this when the url api/reverse/test - tset (is just uses a php function to reverse the text given in the slug3.
That function works fine, just wanted to give some back on what gets requested.
reverse.php - HTML File
<textarea id="input"></textarea>
<div id="output">
</div>
index.js - All of my jQuery and AJAX
$(document).ready(function(){
var $input = $('#input');
var $output = $('#output');
$input.on('keyup', function(){
var text = $input.val();
var url = 'http://coder.jekoder.com/api/?area=reverse&text='+text;
$.ajax({
type: 'GET',
url: url,
dataType: 'text',
success: function(data) { var output = data; },
error: alert('fail')
}) // End of AJAX
$output.html = output;
});
});
api.php - PHP file being called
<?php
$area = $_GET['area'];
if ($area == 'reverse') {
if (isset($_GET['text']) ) $text = $_GET['text'];
else $text = 'Hello';
echo strrev($text);
}
It's then supposed to take the output variable and display that in a div but that's not the main thing that matters.
error removed - was trying to see if it fixed it
There are several issue I found:
Jquery:
var text = $('#input').val(); // if you are getting value from any inputbox - get value using .val() function
var url = 'http://localhost/test.php?data='+text; // pass data like this ?data='+text
// AJAX START
$.ajax({
type: 'GET',
url: url,
dataType: 'text',
async: true,
success: function(data) { var output = data; alert(output)},
error: function(data) { alert('fail') }
});
In php you ca get data like this:
echo $_GET['data'];
exit;
Try this. Scope of variable output is within the success call and you are using it outside the ajax call.
$(document).ready(function()
{
var $input = $('#input');
var $output = $('#output');
$input.on('keyup', function()
{
var text = $input.val();
var url = 'http://coder.jekoder.com/api/?area=reverse&text='+text;
$.ajax({
type: 'GET',
url: url,
dataType: 'text',
success: function(data) { var output = data; $output.html = output;},
error: alert('fail')
}) // End of AJAX
});
});

Fetch contenteditable=true data

I want to fetch data from div tag which set contenteditable=true
I have used autosuggestion in that..Data is successfully fetched but when I write item which is written in autosuggestion field then it wont be fetched because it add HTML tag and it wont save into database
My code
if data is changed:
var timeoutID;
$('[contenteditable]').bind('DOMCharacterDataModified', function () {
clearTimeout(timeoutID);
$that = $(this);
timeoutID = setTimeout(function () {
$that.trigger('change')
}, 50)
});
$('[contentEditable]').bind('change', function () {
getTextChangeContent();
});
UPDATE
function getTextChangeContent() {
var ma = document.getElementById('myAudio');
var remove = ma.src.slice(0, -4);
var path = remove.substring(remove.lastIndexOf("/") + 1);
var newPath = path.concat('.wav');
var text_id = document.getElementById('textbox');
var textdata = text_id.innerHTML;
$.ajax(
{
type: "POST",
url: '#Url.Action("getChangeContent")',
dataType: "json",
mtype: "post",
data: { arg: varid, content: textdata, path: newPath },
async: true,
success: function (data) {
alert(data + " DATA");
}
});
}
when I changed data and use autosuggestion then it will show data as
The door is blacl <span class="atwho-inserted">[[Ceilings]]</span>
How to ignore html tag and take only values of that?
Plz suggest me
Retrieve innerText rather than innerHTML in order to ignore the HTML content. If you want only the content inside the html tag with class .atwho-inserted, then retrieve only that content.
var textdata = text_id.innerText;

Only run ajax again if last is fully loaded and success

I got a problem while scrolling down and load content into my page.
The ajax executions load too fast, so the second, third and so... does not get correct information from the first ajax call, which are loaded into the DOM.
How do I make it, so the script only run if last ajax call is done and a success.
It should skip every scrolling up and down until the last ajax call is done. And then the ajax is allow to be executed.
And then over and over again until there no more to load though ajax.
Here is my jQuery script.
<script type="text/javascript">
$(document).ready(function(){
$(window).scroll(function(){
if ($(window).scrollTop() <= $(".wrapper_ac").offset().top + $(".wrapper_ac").height()) {
$(document).ajaxStart(function () {
var ajaxURLvalue = '../../modules/language_text_loading/load_content.php';
var langID = 'x';
var onID = 'x';
var setLimit = 'x';
var setIn = 'after';
var theme = 'x';
var setInWhere = 'x';
var conID = 'x';
loadInstant(ajaxURLvalue, langID, onID, setLimit, setIn, theme, setInWhere, conID);
});
}
});
});
</script>
This is my function.
function loadInstant(ajaxURLvalue, langID, onID, setLimit, setIn, theme, setInWhere, conID) {
var temp_s = $(".ltlID:last").attr("id");
var split_ltlID = temp_s.split(':');
var ltlID = split_ltlID[0];
var acContentBoxID = split_ltlID[1];
var dataString = {
action: 'load',
last_ltlID: ltlID,
//sharedID:acContentBoxID_sharedID,
langID:langID,
setInWhere: setInWhere,
onID:onID,
theme:theme,
conID:conID
};
$.ajax({
type: "POST",
url: ajaxURLvalue,
data: dataString,
cache: false,
success: function(html){
$("#accordionContent"+acContentBoxID+":last").after(html);
});
};
Thank you for your help.
Well what I would do is store the ajax function into a global variable like this:
global_variable = $.ajax({
type: "POST",
url: ajaxURLvalue,
data: dataString,
cache: false,
success: function(html){
$("#accordionContent"+acContentBoxID+":last").after(html);
});
and before the ajax call check if the variable is tru like this:
if(global_variable){
return false;
}
this will stop any ajax call to be called before the one running is over. I hope it helps you!

Categories