Ajax call problem - javascript

I am having problems returning the HTML from this ajax call. It works fine in FF but gives me a "null" in IE for the alert(result.html());
Here is the code. Any ideas? Thanks!!!
The errors variable is also null in IE.
Also, it makes not difference what element i use in the .find() as it still comes up null.
function update_price() {
$.ajax({
url: $("form[name='MainForm']").attr('action'),
data: $("form[name='MainForm']").serialize() + '&btnupdateprice.x=0&btnupdateprice.y=0',
type: 'POST',
cache: false,
success: function (response) {
var errors = $(response).find("#listOfErrorsSpan");
var result = $(response).find(".colors_productprice:eq(0)");
alert(result.html());
$(".colors_productprice:eq(0)").replaceWith('<font class="colors_productprice">' + result.html() + '</font>');
$('#listOfErrorsSpan').replaceWith('<span id="listOfErrorsSpan">' + errors.html() + '</span>');
}
});
}
$(function () {
$("select[name^='SELECT___'],input[name^='SELECT___'][type='radio']").each(function () {
$(this).change(function () {
update_price();
});
});
$("a[href^='javascript:change_option']").each(function () {
$(this).click(function () {
var result_href = $(this).attr('href').match(/\'(.*?)\'/)[1];
var result_val = $(this).attr('href').match(/\,(.*?)\)/)[1];
change_option(result_href, result_val);
update_price();
return false;
});
});
});
Here is the HTML from the Ajax call.
<table border="0" cellspacing="0" cellpadding="0">
<tr>
<td>
<b><font class="pricecolor colors_productprice"><span class="price_name"><font class="text colors_text"><b>Our Price: </b></font></span>
<span class="price1">$505.00</span>
</font>
</b>
</tr>
</table>
In FF I get this for the alert.
<span class="price_name"> Price with added options: </span><span class="price1">$505.00</span>

you might have errors on this code
var errors=$(response).find("#listOfErrorsSpan");
var result=$(response).find(".colors_productprice:eq(0)");
alert(result.html());
i am not sure maybe the selector for $(response) is undefined

The :eq(0) in your find statement may be the problem. It is probably sufficient to just say find(".colors_productprice").

You don't have </td>
Not sure this is the root problem, but FF and IE work differently in quirksmode, especially when inserting elements into the DOM on the fly.

Related

Datatables Jquery Cannot set properties of undefined (setting '_DT_CellIndex')

I know this has been asked a lot but I really cannot find my error on this one. I've been doing a lot of changes but still cannot figure out what's wrong. <th> and <td> matched number, I tried removing colspans too but had no luck. Any advice? By the way, here is my code please have a look.
window.load_tbl = function(){
var val = document.getElementById('assignval').value;
$('#faculty-tbl tbody').html('<tr><td colspan="6" class="text-center">Please Wait...</td></tr>')
$.ajax({
url:'functions/'+val,
success:function(resp){
if(typeof resp != undefined){
resp = JSON.parse(resp)
if(Object.keys(resp).length > 0){
$('#faculty-tbl tbody').html('')
var i = 1;
Object.keys(resp).map(k=>{
var date_updated = moment(resp[k].date_updated).format('MM/DD/YYYY h:mm a');
var tr = $('<tr></tr>')
tr.append('<td class="text-center"><button type="button" class="btn btn-outline-secondary">'+resp[k].id+'</button></td>')
tr.append('<td class="text-center">'+resp[k].firstname+'</td>')
tr.append('<td class="text-center">'+resp[k].middlename+'</td>')
tr.append('<td class="text-center">'+resp[k].lastname+'</td>')
if(resp[k].section_id != 0) {
tr.append('<td class="text-center">'+resp[k].advisory+'</td>')
} else {
tr.append('<td class="text-center">Unassigned</td>')
}
tr.append('<td><center><button class="btn btn-info btn-sm text-white edit_faculty" data-id = "'+resp[k].id+'"><i class="fa fa-edit"></i></button><button class="btn btn-danger btn-sm remove_faculty" data-id = "'+resp[k].id+'" data-firstname="'+resp[k].firstname+'" data-middlename="'+resp[k].middlename+'" data-lastname="'+resp[k].lastname+'" data-uid="'+resp[k].user_id+'"><i class="fa fa-trash"></i></button><button class="btn btn-dark btn-sm text-white show_date" data-date = "'+date_updated+'"><i class="fa-solid fa-database"></i></button></center></td>')
$('#faculty-tbl tbody').append(tr)
})
}else{
$('#faculty-tbl tbody').html('<tr><td colspan="6" class="text-center">No Data...</td></tr>')
}
}
},
complete:function(){
$('#faculty-tbl').dataTable()
}
})
}
$(document).on('change', '.assigned', function() {
if(this.checked) {
document.getElementById('assignval').value = 'load_ajax.php?action=load_faculty';
load_tbl();
} else {
document.getElementById('assignval').value = 'filter_ajax.php?action=filter_unassignedfaculty';
load_tbl();
}
});
$('#new_faculty').click(function(){
uni_modal('Add faculty','functions/manage_faculty.php');
})
$(document).ready(function() {
load_tbl()
$('#faculty-tbl tbody').on('click', '.edit_faculty', function () {
uni_modal("Update Faculty Information",'functions/manage_faculty.php?id='+$(this).attr('data-id'))
});
$('.help').on('click', function () {
help_modal("Need Help?")
});
$('#faculty-tbl tbody').on('click', '.remove_faculty', function () {
window.uid = $(this).attr('data-uid');
window.firstname = $(this).attr('data-firstname');
window.middlename = $(this).attr('data-middlename');
window.lastname = $(this).attr('data-lastname');
_conf("Are you sure to remove this data?",'remove_faculty', [$(this).attr('data-id')])
});
$('#faculty-tbl tbody').on('click', '.show_date', function () {
static_modal("Faculty Information", "Last Date Updated: "+$(this).attr('data-date'))
});
$('#print_faculty').click(function(){
var redirectWindow = window.open('print/report_faculty.php');
redirectWindow.location;
});
$('#reloadBtn').click(function(){
location.reload();
});
var table = $('#users-tbl')
if (!$.fn.DataTable.isDataTable('#users-tbl')) {
return;
}
else {
var table = $('#users-tbl').DataTable();
table.dataTable().fnDestroy();
}
});
If I miss anything also let me know, I'm doing an Enrollment System atm.
I've tried multiple things like matching rows and columns, and also did a few code that is recommended by the others but still no luck. I have no trouble loading the data but I just want this error gone and never thrown in the first place.
Never mind. I've been ignoring the simplest mistake ever, I keep putting a default message when there is no data available in the table which is clearly not supported by the data table, and when I removed it all my problems went away.
Considered this fixed.
Edit: As said by anrdewJames, I'll expand my answer for anyone who also encounters this error.
In my code there are two with colspans which in my case:
$('#faculty-tbl tbody').html('<tr><td colspan="6" class="text-center">Please Wait...</td></tr>')
$('#faculty-tbl tbody').html('<tr><td colspan="6" class="text-center">No Data...</td></tr>')
I completely removed the first line because I run this code when the data is still loading. Here's my solution:
The first error changed into:
window.check_tbl = function() {
var table = $('#faculty-tbl').DataTable();
if ( ! table.data().any() ) {
$('#faculty-tbl').dataTable().fnDestroy();
}
}
The second error, if the table has no data simply clear and draw.
var table = $('#faculty-tbl').DataTable();
table.clear()
.draw();
In any case, don't try to be so fancy as Datatable has default messages.

how can i compare class to a string in js

I want to add toggle star functionality in my project. For which I'm calling this script on click. This code fails to compare value of starclass to the class defined in the string.
Here i m trying to add star/unstar functionality just like gmail messages to my project.
$(".mailbox-star").click(function (e) {
debugger;
e.preventDefault();
var $this = $(this).find("a > i");
var glyph = $this.hasClass("glyphicon");
var fa = $this.hasClass("fa");
var msgId = $("#MsgId").val();
var StarClass = $(".mailbox-star i").attr('class');
var StarStatus;
if (StarClass === "fa text-yellow fa-star-o") {
StarStatus = true;
} else {
StarStatus = false;
}
//var starstatus = document.getElementById('ReadstatusStarred');
if (glyph) {
$this.toggleClass("glyphicon-star");
$this.toggleClass("glyphicon-star-empty");
}
$.ajax({
url: "/Home/Starred",
type: "GET",
dataType: "json",
data: {
ChangeStarredStatus: StarStatus,
ChangeMessageId: msgId
},
success: function (status) {
if (status) {
alert(status);
if (fa) {
$this.toggleClass("fa-star");
$this.toggleClass("fa-star-o");
}
}
},
error: function () {
alert("starfailed1");
}
})
});
//HTML CODE
here i m fetching values from my controller using model .If I can send value of IsStarred parameter in my js code my problem will be sorted
<table class="table table-hover table-striped">
<tbody>
#{int count = 0;}
#foreach (var item in Model)
{
string[] dt = #item.DateTime.ToString().Split(' ');
<tr title="#item.DateTime" id="ReadMessage" class="#((item.IsRead != true) ? "row row-highlight" : "row")" >
<td><input type="hidden" value="#item.IsRead" id="Readstatus_#count"></td>
<td><input type="hidden" value="#item.IsStarred" id="ReadstatusStarred"></td>
<td><input type="hidden" id="MsgId" value="#item.MessageId" /></td>
<td><input type="checkbox"></td>
<td class="mailbox-star" ><i class="#((item.IsStarred==true)? "fa fa-star text-yellow":"fa text-yelow fa-star-o")"></i></td>
<td class="mailbox-name" id="Text1" onclick="location.href='#Url.Action("Read", "Home", new
{
NameRead = item.FullName,
SubjectRead = item.Subject,
BodyRead = item.Body,
DateRead = item.DateTime,
MessageIdRead= item.MessageId,
})'">
<a href="#" id="Name">
#item.FullName
</a>
</td>
<td class="mailbox-subject" id="Text1">
<b>#item.Subject</b>-
#if (item.Body == null || item.Body.Length == 0)
{
}
else
{
if (item.Body.Length >= 100)
{
#item.Body.Substring(0, 100)
}
else
{
#item.Body
}
}
</td>
<td class="mailbox-attachment"></td>
<td class="mailbox-date">
#dt[0]
</td>
</tr>
count++;
}
</tbody>
</table>
</div>
Try using jQuery's is() to check for classes instead
var StarStatus = $(".mailbox-star i").is('.fa, .text-yellow, .fa-star-o')
If I got your description right you wanna have something like gmail has, click to star a mail, click again to destar it?
It's hard to say what is broken without the HTML you are using but I would do this in the following manner:
When loading mails from back you have to set up class "starMarked" to starred mails depending on how you mark the starred mail in the data comming from back you would check if something is true or equal to some value and then .addClass("starMarked") to that element.
bind the .click(Function that does the logic below) to all elements that represent mail (list member, square, icon, depends on what you have in the UI)
A functionality of that click then checks if that mail is stared or not. Since the status is already represented with class no need to check through data pulled from the server or make an additional request to the server to get that email's status. This saves time and load on the server.
NOTE: You must be certain the request to change status on the server went through or your logic of toggling on front and status on backend might become inconsistent!
Toggle on front could be done numerous ways but simplest would be using the CSS class "starMarked" to represent it's starred and lack of it to signal it's not. It gives 2 birds with one stone (looks and logic). If you need to check the status you could use .hasClass("starMarked").
When toggling a class use .removeClass() to remove the class from the element

display loading image with jquery/ajax

I am trying to display a spinning image while ajax call is being completed. I am using the following jsp and jquery code yet it is not working.
Any help will be appreciated
jsp:
<div class="tab-content" id="rdfTabs">
<div id="data">
<p>Please enter dataset URL or absolute file location (e.g: c:\data\dbpedia.rdf)</p>
<table width="100%">
<tr>
<td colspan="2"><input name="txtDataSource" id="txtDataSource" type="text" class="textbox"/>
<input type="button" value="Analyse File"
name="btnAnalyseFile" id="btnAnalyseFile" class="btn-blue" /></td>
</tr>
</table>
**<div id="loadingImage" style="display:none">
<img src="http://preloaders.net/preloaders/287/Filling%20broken%20ring.gif">
</div>**
<p id="presult">
</div>
and here is the jquery code
$(document).ready(function()
{
$("#presult").hide();
$("#btnAnalyseFile").click(
function(e)
{
**$("#loadingImage").show();**
$.ajax({
url : 'CreatePatternServlet',
type : 'POST',
dataType : 'json',
data : $("#formCreatePattern").serialize(),
success : function(data)
{
if(data.analyseResult==true){
var predicates = {};
var objectList = {};
var ddlSubject = $('#ddlSubject');
var ddlPredicate = $('#ddlPredicate');
var ddlObject = $('#ddlObject');
var ddlClass = $('#ddlClass');
$.each(data.Subjects, function(key, value)
{
ddlSubject.append($('<option></option>')
.val(value).html(key));
});
$.each(data.Classes, function(key, value)
{
ddlClass.append($('<option></option>')
.val(value).html(key));
});
$.each(data.Predicates, function(key, value)
{
ddlPredicate.append($('<option></option>')
.val(value).html(key));
});
$.each(data.Objects, function(key, value)
{
ddlObject.append($('<option></option>')
.val(value).html(key));
});
$('#ddlSubject').filterByText(
$('#txtSearchSubject'));
$('#ddlPredicate').filterByText(
$('#txtSearchPredicate'));
$('#ddlObject').filterByText(
$('#txtSearchObject'));
$('#ddlClass').filterByText(
$('#txtSearchClass'));
$("#presult").html("Data uploaded successfully");
$("#presult").css("color","green");
$("#presult").fadeIn(500);
}
else{
$("#presult").html("Upload failed, please check file path or URL. Server returned error: "+data.result);
$("#presult").css("color","red");
$("#presult").fadeIn(500);
}
}
});
**$('#loadingImage').hide();**
return false;
});
});
Problem is that your ajax function is asynchronous, so you are showing the loader, firing the ajax and inmediately hiding the loader, without waiting for the request to end.
Easy fix is putting the $('#loadingImage').hide(); inside the success function, but would be better to add a done function in case it fails
$("#btnAnalyseFile").click(function() etc...
shoudn't be
$("#btnAnalyseFile").on("click", function() { etc...
?

javascript auto complete function

Hello i have the following code with problems, i'm trying to make it when you click on the output to insert it into the input field. Can you help me please, been trying for hours without any luck.
<script type="text/javascript">
var input = $('#CompanyName');
var output = $('#output');
var timer;
input.on('keyup', function() {
delaySearch(this.value);
});
function delaySearch(keywords) {
clearTimeout(timer);
timer = setTimeout(function() {
performSearch(keywords);
}, 1000);
}
function performSearch(keywords) {
$.ajax({
type: "POST",
url: "/print/order/search",
data: { query: keywords },
cache: false,
dataType: "json",
async: true,
success: function(data) {
for(var key in data) {
output.append('<li onclick="fill('+ data[key].ClientName +')">' + data[key].ClientName) + '</li>';
}
}
});
}
function fill(thisValue) {
input.val(thisValue);
clearTimeout(timer);
}
</script>
<!-- Text input-->
<div class="form-group">
<label class="col-md-4 control-label" for="CompanyName">Firma</label>
<div class="col-md-5">
<input id="CompanyName" onblur="fill();" name="CompanyName" type="text" placeholder="Firma" class="form-control input-md">
<ul id="output"></ul>
<span class="help-block"></span>
</div>
</div>
Uncaught ReferenceError: somevalue is not defined
Update:
After adding jquery ready function i noticed some errors around and fixed them here is an update on the code
<div class="form-group">
<label class="col-md-4 control-label" for="CompanyName">Firma</label>
<div class="col-md-5">
<input id="CompanyName" name="CompanyName" type="text" placeholder="Firma" class="form-control input-md">
<ul id="output"><li onclick="fill(Ionut)">Ionut</li></ul>
<span class="help-block">Nume Firma</span>
</div>
</div>
<script type="text/javascript">
$(document).ready(function() {
var input = $('#CompanyName');
var output = $('#output');
var timer;
input.on('keyup', function() {
delaySearch(this.value);
});
function delaySearch(keywords) {
clearTimeout(timer);
timer = setTimeout(function() {
performSearch(keywords);
}, 1000);
}
function fill(thisValue) {
input.val(thisValue);
}
function performSearch(keywords) {
$.ajax({
type: "POST",
url: "/print/order/search",
data: { query: keywords },
cache: false,
dataType: "json",
async: true,
success: function(data) {
for(var key in data) {
output.append('<li onclick="fill(' + data[key].ClientName + ')">' + data[key].ClientName) + '</li>';
}
}
});
}
});
</script>
onclick the error persists
Uncaught ReferenceError: fill is not defined
realseanp is onto the correct answer. I'll try to explain it a little better for you. When a browser starts processing and rendering a page, it loads top down. So your javascript scripts are being ran and evaluated before the DOM is created.
So your jquery selectors: var input = $('#CompanyName'); if you were to inspect them are going to be an empty array. They cannot find the #CompanyName element because it has not yet been rendered.
If you use jQuery's $(document).ready() function, then you can be assured that your code will not run until the dom is finished rendering, and therefore will find the elements as you intend them to. So in the end, your code will need to change to this:
$(document).ready(function(){
//Put your code in here.
//It will then fire once the dom is ready.
});
UPDATE:
Additionally, with your update. I'm noticing that the error is that 'fill' is not defined. fill being your onclick method. You have your js script evaluating after the dom is rendered. So at the time that the dom is rendered, and the tag with the onclick is rendered, no fill method yet exists. Two solutions:
Move the script above the dom, and place a var fill; outside of the $(document).ready so essentially this:
var fill;
$(document.ready(function(){
//your code
});
Don't use the onclick dom attribute, and instead use jquery to bind the event. So change
Ionut
to this:
<ul id="output"><li>Ionut</li></ul>
and inside the document.ready, add:
$('#output li').click(function(e) {
fill(/*your value/*)
});
You need to put your script below your HTML. That or wrap it in the jQuery Document ready function. And make sure you have jQuery loaded on the page, before your script

Infinite scrolling fills completely rather than incrementally

I am attempting to create infinite scrolling on my web page using an example I found. However, the page fills up completely with all the items instead of just showing several items at a time. In other words it is not doing infinite scrolling. I noticed in some of the examples they parsed out data in chunks but in the real world how are you supposed to do that?
Below is my html code:
<table class="table table-striped table-bordered"><tr>
<th style="text-align:center;">User ID</th> <th>Username</th><th>Rank</th>
<th>Posts</th><th>Likes</th> <th>Comments</th> <th>Flags</th><th>Status</th><th>Action</th></tr>
<tr><td class="center">
<div ng-app='scroll' ng-controller='Scroller'>
<div when-scrolled="loadMore("")">
<div ng-repeat='item in items'>
<span>{{item.id}}
<span style="position:absolute;left:140px;">{{item.username}}</span>
<span style="position:absolute;left:290px;">{{item.rank}}</span>
<span style="position:absolute;left:360px;">{{item.posts}}</span>
<span style="position:absolute;left:440px;">{{item.likes}}</span>
<span style="position:absolute;left:530px;">{{item.comments}}</span>
<span style="position:absolute;left:640px;">{{item.flags}}</span>
<span class="label label-success" style="position:absolute;left:710px;">Active</span>
<a style="position:absolute;left:790px;" class="btn btn-info" style="width:30px" ng-href='/admin/userDetail?userid={{item.id}}'>
View Detail</a>
<hr>
</div>
</div>
</div>
</td></tr>
</table>
Below is my angularjs code:
function Scroller($scope, $http, $q, $timeout) {
$scope.items = [];
var lastuser = '999999';
$scope.loadMore = function(type) {
todate = document.getElementById("charttype").value;
var url = "/admin/getusers?type=" + todate + "&lastuser=" + lastuser;
var d = $q.defer();
$http({
'url': url,
'method': 'GET'
})
.success(function (data) {
var items = data.response;
for (var i = $scope.items.length; i < items.length; i++) {
$scope.items.push(items[i]);
count++;
if (count > 100)
{
lastuser = $scope.items[i].id;
break;
}
d.resolve($scope.items);
d.promise.then(function(data) {
});
}
)
.error(function (data) {
console.log(data);
});
return d.promise;
};
$scope.loadMore();
}
angular.module('scroll', []).directive('whenScrolled', function() {
return function(scope, elm, attr) {
var raw = elm[0];
alert("scroll");
elm.bind('scroll', function() {
if (raw.scrollTop + raw.offsetHeight >= raw.scrollHeight) {
scope.$apply(attr.whenScrolled);
}
});
};
});
My question is why does my web page show all 3200 lines initially rather than allowing me to do infinite scrolling. You will notice I put an alert in the scroll module and it is never displayed. Do I have to incrementally read my database? Any help is appreciated.
You are adding all of the items returned from your API call into $scope.items.
for (var i = 0; i < items.length; i++) {
$scope.items.push(items[i]);
}
Don't you want to add only a subset of those items?
P.S. Might help if you create a Plunkr to show the specific problem.
EDIT:
Based on your comment about the directive not working, I put together this Plunkr, which is a copy of your code but with the $http get code ripped out. The "scroll" alert fires here. I think you're just missing a closing bracket on your for loop (since I don't have your API endpoint to test against, I can't actually run your code live).
EDIT 2:
I'm not sure why you aren't seeing the function fire correctly on scroll. I've set up another plunker where I've changed the result of the scroll event firing to show an alert and load more items from a data variable, so you can see that the scroll event is firing correctly and it will load more items.

Categories