Jquery - selecting subset of data from ajax request not working - javascript

I am using a modal to submit a form. I have it working correctly. The problem I am having with is replacing a subset of the modal with a subset of the data returned by the ajax request.
$.ajax({ url: actionUrl, method: 'post', data: dataToSend, processData: false, contentType: false })
.done(function (data) {
var newBody = $('.modal-body', data);
console.log(newBody);
placeholderElement.find('.modal-body').replaceWith(newBody);
//other stuff
}
I am trying to replace a subset of the modal that is active (i.e. get the modal-body) and replace it with a subset of the data from the ajax request.
My response from the ajax request in some cases will be below:
<div class="modal-body"><div class="alert alert-danger">Error</div></div>
But when my ajax request completes, the newbody is empty. The selector ($('.modal-body', data);) returns an empty object. I'm not sure why as the selector it is looking for exists in the response and it should be returning the <div class="alert alert-danger">Error</div> as the new object.
If I modify my response as <div class="modal"><div class="modal-body"><div class="alert alert-danger">Error</div></div></div>, above selector then works.
My question is, why does one work vs the other not working?
Works: $('.modal-body', '<div class="modal"><div class="modal-body"><div class="alert alert-danger">Error</div></div></div>');
Does Not Work: $('.modal-body', '<div class="modal-body"><div class="alert alert-danger">Error</div></div>');
What do I need to do to simplify this? Any reason why one of the options does not work?
My placeholderElement at the point of the ajax request is a simple bootstrap modal:
<div class="modal fade" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-lg" role="document">
<div class="modal-content">
<div class="loading"></div>
<div class="modal-header">
<h5 class="modal-title">Modal title</h5>
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
//stuff
</div>
<div class="modal-footer">
<button type="button" class="btn btn-danger" data-dismiss="modal">Cancel</button>
<button type="button" class="btn btn-dark text-light" data-save="modal">Save changes</button>
</div>
</div>
</div>
</div>

Firstly, the jQuery function takes 2 arguments, one is a string (the selector) and the second have to be a DOM Element, Document, or jQuery element to be used as a context.
http://api.jquery.com/jquery/#jQuery1
Finally, the reason because the second way doesnt works it's because the context takes the root node and ignore him to search the selector. This is a deduction I did >_<.
EDIT:
From the link i just give you:
"By default, selectors perform their searches within the DOM starting at the document root. However, an alternate context can be given for the search by using the optional second parameter to the $() function."
So it's saying that it's ignoring the root element because says within ^^.
I hope i could help you :)

The selector $('.modal-body', data) tries to find an existing element with that class within data, but data must be an actual Element or another jQuery instance. If data is a string you can try to parse the HTML first:
var newBody = $('.modal-body', $(data));

Related

Jquery replaceWith(html) not replacing element; appending it to end instead

I have the following HTML. Its a form inside of a modal window:
<div class="modal fade" id="requestModal" tabindex="-1" role="dialog" aria-labelledby="requestModalLabel">
<div class="modal-dialog wide-modal" role="document">
<form novalidate>
<div class="modal-content">
....
</div>
</form>
</div>
</div>
Whenever the form is opened, I want to render a fresh version of the form, free of any old inputs or error messages. The following handler gets the data for hidden fields plus the form's HTML I can obtain the data for the form along with the raw HTML for the form via an Ajax request:
$(document).on('click', '#por-detail-tbl .dropdown-menu', e => {
// This route will get fresh form HTML also.
$.get(`/projects/${$(e.target).attr('project-id')}`, res => {
$('#requestModal').replaceWith(res.html)
...more code here to populate hidden fields...
})
})
I would expect the $('#requestModal') element to be replaced with whatever res.html is (in this case, a new version of the form). Instead, res.html is getting inserted as the last element in the document body. The old $('#requestModal') is still there.
Here is a snippet from res.html:
<div class="modal fade" id="requestModal" tabindex="-1" role="dialog" aria-labelledby="requestModalLabel">
<div class="modal-dialog wide-modal" role="document">
<form novalidate>
<div class="modal-content">
...
</div>
</form>
<div>
</div>
I'm able to use this technique successfully in other Ajax callbacks. Any ideas why this one is behaving strangely?
You actually want jQuery's .html() function here.
In your original code, the replaceWith() function replaces $('#requestModal'). But the element you replaced is the element that's been manipulated by Bootstrap to perform the modal behavior you expect.
So I think you really want to set the content of the div.modal-dialog element to just the form and its children. If you can pare down res.html to just the form and children, you can change $('#requestModal').replaceWith(res.html) to $('#requestModal').find('div.modal-dialog').html(res.html).

Getting data from text file via data-src using jQuery

I am trying to retrieve text from a .txt file using jQuery (I am also using Bootstrap). I am very new to web design but I am familiar somewhat with coding. I have the following button in my HTML:
<button type="button" class="btn btn-primary-outline-btn text-btn" data-toggle="modal" data-src="test.txt" data-target="#textModal"><img class="video_icon" src="assets/icons/parchment_icon.png" alt="text"</button>
As you can see, the target of the button is a modal which loads up text like so:
<!-- Text Modal -->
<div class="modal fade" id="textModal" tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog modal-dialog-centered" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">×</span>
</button>
</div>
<div class="modal-body">
<p id="outputText">File not found.</p>
</div>
</div>
</div>
</div>
My JS file looks like this (changed following one of the answers):
$(".text-btn").on("click", textFunction);
function textFunction() {
var el = document.getElementById('test');
console.log(el.getAttribute('data-src'));
jQuery.get(el.getAttribute('data-src'), function(data) {
$( '#outputText' ).html(data.replace('n',''));
});
}
Whilst the filepath outputs to the console correctly, I am unsure how to use jQuery to utilise this so that it will input the file contents into the modal-body. Additionally, my issue is now how to make the variable assigned through getElementById correctly correspond to the button pressed. Moreover, I am not sure how to use getAttribute or attr in jQuery to obtain the data source in javascript.
This is an issue as I will have multiple buttons with multiple file sources so I would like the jQuery to retrieve from each button's respective data source. Is there a way in which I can do this...?
You have to set the full file url in data-src then use:
$('.text-btn').on('click', function() {
$.get($(this).data('src'), function(data) {
$('#outputText').html(data);
});
});
For the case of multiple buttons, you can use an onclick event on each, which will fire textFunction. Then, inside the text function, you can retrieve the correct button's data-src using jQuery's data() function:
//assuming all your relevant buttons have class `text-btn`
//call textFunction on button click
$(".text-btn").on("click", textFunction);
function textFunction() {
//inside event handler, `this` points to the button that triggered the event
jQuery.get($(this).data('src'), function(data) {
alert(data);
$( '#outputText' ).html(data.replace('n',''));
});
}

Ajax calls doubles every time I click a link to open a window in modal

I have a table with action column and column has button(link) to show details of that row.
Following is the code that shows the button in every row :rowid will be actual ineger number.
<a data-path="http://example/rowdetails/:rowid" class="btn btn-info btn-xs load-ajax-modal" role="button" data-toggle="modal" data-target="#dynamic-modal">
<span data-toggle="tooltip" title="Show Details">
<span class="glyphicon glyphicon-eye-open"></span>
</span>
</a>
Following is the html for dynamic modal
<!-- Modal -->
<div id="dynamic-modal" class="modal modal-wide hide fade in" tabindex="-1" role="dialog">
<div class="modal-dialog">
<!-- Modal content-->
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal">×</button>
<h4 class="modal-title">Row Details</h4>
</div>
<div class="modal-body">
<!--Dynamic body content appears here-->
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
<!-- /.Modal -->
Following is the Javascript that I am using.
$(document).ajaxComplete(function () {
// when .modal-wide opened, set content-body height based on browser height; 200 is appx height of modal padding, modal title and button bar
$(".modal-wide").on("show.bs.modal", function () {
var height = $(window).height() - 200;
$(this).find(".modal-body").css("max-height", height);
});
/*Dynamic Modal window to load row details usin ajax load*/
$('.load-ajax-modal').on('click',function () {
url = $(this).data('path');
//ajax call using load function
$('.modal-body').load(url, function (result) {
$('#dynamic-modal').removeClass('hide');
});
});
});
Problem
Everything works good here when I click the button in a row, one single ajax(xhr) call is made. second time I click this time for the same url there are two ajax requests. third time I click a button there are four, fourth time eight and so on, it doubles every-time the previous number.
I saw in other posts and tried .one() .live() .die() etc but I think I could figure out where exactly use these functions (I tried these functions with $('.load-ajax-modal') and it doesn't seems to work).
Thanks,
K
Your ajaxComplete handler fires everytime any Ajax request completes and each time it adds a new function as a handler when the button is clicked. So, not so surprising that the handler function gets executed once, then twice, then four times ...
What you should do is use event delegation.
$(function onDocumentReady() {
var $modal = $('#dynamic-modal');
var $modalBody = $('.modal-body');
var $window = $(window);
$modal.on("show.bs.modal", function () {
var height = $window.height() - 200;
$(this).find(".modal-body").css("max-height", height);
});
$(document).on('click', '.load-ajax-modal', function (e) {
url = $(this).data('path');
//ajax call using load function
$modalBody.load(url, function (result) {
$modal.modal('show');
});
});
});
Couple of points to remember:
Always cache the jQuery object ( e.g. $(window) ) in a variable if you use it multiple times. This makes sure that jQuery does not need to query the DOM everytime you look for a specific DOM element.
Read up on Event Delegation . It makes sure that your event handler gets executed even when the elements are added dynamically to your page. Similar to what jQuery.live() offered but that has long been deprecated.
That's because you are appending clicks to already existing element. Quickest fix will be to off all registered actions before attaching new one: $('.load-ajax-modal').off('click').on('click',function () {... Like I said that's is just a workaround, to get rid of that problem dispose dom elements when the dialog is closed.

Setting a Bootstrap 3 modal title dynamically

I have the same modal dialog for three different buttons.
However, depending upon which button is clicked, I need to dynamically set the title of the modal dialog.
I thought this would be simple setting the title in the appropriate javascript function using jQuery. However, when debugging, I can see the title is set accordingly in the code, but after the modal is displayed, the modal title is blank.
How can I properly display the modal title accordingly?
Here is the pertinent part of the HTML:
<div class="modal fade" id="btnJournalVoucherEditGrid" tabindex="-1" role="dialog" aria-labelledby="btnJournalVoucherEditGrid-label" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h4 class="modal-title" id="btnJournalVoucherEditGrid-label"></h4>
Here is the JS
function onEditJournalVoucher(gdId, rwID)
{
$('#btnJournalVoucherEditGrid-label').val("Edit Journal Voucher")
Well, you're trying to use .val() on an H4 tag. Should it not be:
$('#btnJournalVoucherEditGrid-label').text("Edit Journal Voucher");
or
$('#btnJournalVoucherEditGrid-label').html("Edit Journal Voucher");
.val() is the right mindset, but what it does in JQuery is why it won't work in this situation. Take an element that has a value="something" attribute, for example:
<input id="example" type="text" name="something" value="something"/>
Targeting this id using $("#example") and calling .val() can access or change the value="something" attribute. Now take a look at a <label> element:
<label id="example"> This is some text </label>
Notice the lack of a value="something" attribute? In this case, since "This is some text" is simply plain-text, using:
$("#example").text("Updated Text");
is the correct way to go about this. Hope that helps clear things up!
.val() is used for form elements (like inputs, checkboxes, etc.)
For divs/other elements (e.g. h4 in your situation) use either .text() or .html() depending on the situation you want to do.
In this case since this is just text change your line to:
$('#btnJournalVoucherEditGrid-label').text("Edit Journal Voucher");
It should be
function onEditJournalVoucher(gdId, rwID)
{
$('#btnJournalVoucherEditGrid-label').html("Edit Journal Voucher")
Try text() function instead of val():
$('#btnJournalVoucherEditGrid-label').text("Edit Journal Voucher")
I would set the title in the button:
<button id="edit-journal-voucher" data-title="Edit Journal Voucher" data-toggle="modal" data-target="#btnJournalVoucherEditGrid">Edit this Journal</button>
Then in the JS do something like:
$("#edit-journal-voucher").on("click", funtion(e){
e.preventDefault();
var title = $(this).data('title');
$("h4#btnJournalVoucherEditGrid-label").html(title);
});

Variable value not passing into mySQL statement in Bootstrap Modal

I'm passing variables using jQuery to Bootstraps modal through span tags but having issue when running PHP within the modal. The variables all pull through normally but when I try to run mySQL statements, the span tag I store in a variable appears as nothing even though it echos fine. I have given an example of the code below:
HTML:
<a role='button' data-topicid='$number' data-toggle='modal' data-target='#modaluserinfo' class='modalsend'>
JS:
<script>
$(document).ready(function () {
$('.modalsend').click(function () {
$('span.user-topicid').text($(this).data('topicid'));
});
});
</script>
Modal:
<div class="modal fade" id="modaluserinfo" tabindex="-1" role="dialog" aria-labelledby="modaluserinfo" aria-hidden="true">
<div class="modal-dialog modal-sm">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="myModalLabel">Details...</h4>
</div>
<div class="modal-body" style="text-align:center; margin-top:10px;">
<?php
$numberid = "<span class='user-topicid'></span>";
echo $numberid;// THE VALUE ECHOS FINE IN THE MODAL, BUT FAILS TO LOAD IN THE MYSQL QUERY BELOW
$sqlcomment = mysql_query("SELECT * FROM comments WHERE comments.topic_id='$numberid' AND comments.emotions_id='1'");
$commentnumber = mysql_num_rows($sqlcomment);
echo $commentnumber;
?>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
My guess is that the PHP statement is running on page load rather than when the modal is opened and the variable is sent to the span tag. Not too sure how to fix this though.
Issue has been resolved for passing multiple variables using the following method:
HTML:
$page = mysql_real_escape_string($_GET['page']);
<a role='button' data-topicid='$number' data-page='$page' data-toggle='modal' data-target='#modaluserinfo' class='modalsend'>
jQuery:
$(document).ready(function () {
$('.modalsend').click(function () {
$('span.user-topicid').load('get_number_comments.php?topicid=' + $(this).data('topicid') + '&page=' + $(this).data('page'));
});
});
Refer to #bloodyKnuckles post for any further details
PHP only runs on the server. For the Javascript or jQuery to execute a PHP script a call to the server needs to be made. There's two ways to do that GET (like a link) and POST (like a form). And there's two ways you GET and POST, one way is to reload the page, the other is an XHR object, AKA Ajax.
So, make a separate PHP file, such as...
get_number_comments.php:
<?php
// LOAD YOUR DATABASE CREDENTIALS HERE
$numberid = mysql_real_escape_string($_GET['topicid']);
$page = mysql_real_escape_string($_GET['page']);
$sqlcomment = mysql_query("SELECT * FROM comments WHERE comments.topic_id='$numberid' AND comments.emotions_id='1'");
$commentnumber = mysql_num_rows($sqlcomment);
echo $commentnumber;
?>
And change your document ready function to:
$(document).ready(function () {
$('.modalsend').click(function () {
$('span.user-topicid').load('get_number_comments.php?topicid=' + $(this).data('topicid') + '&page=' + encodeURIComponent('<?php echo page; ?>'));
});
});
The inner DIV of your modal now looks like:
<div class="modal-body" style="text-align:center; margin-top:10px;">
<span class='user-topicid'></span>
</div>
jQuery's load function makes an XHR call to the server, executing the file you enter in the first argument, get_number_comments.php in this case. So then get_number_comments.php takes the GET variable, safely escapes it, interpolates it in the query, and sends the result back to the page through the XHR object.
(By the way, since PHP mysql_* functions are apparently SOON to be null and void I urge you to convert to the PHP mysqli_* functions. Then you can also use rigorous database security measures.)

Categories

Resources