EDIT
Forgot a couple of improtant points.
I am doing this to eliminate the page from having to refresh and therefore jumping back up to the top of the page.
The success function of the ajax function will kick back an entire new div id="comments" to replace the existing one with either an error msg or the new comment with all other below it.
END EDIT
I have been trying to this jquery-ajax function under wraps unsuccessfully. I have X number of posts on a page with each having a form for inserting comments under each post. I think I am pretty close and have tried to debug it using firebug, but honestly I don't really know what I am looking at or for in firebug.
All code is below, any help would be much appreciated!
HTML form and structure (because of the repetative forms, I feel I should use the parent jquery selection method, rather than iterating each post-comment partition in my output script)
<div id="content_body_right">
<div id="activity">
....this is the area for each post....
</div>
<div id="comments">
<p class="comments_label">' . $reply_count . ' Comment</p>
<div id="comment1">
<div id="comment_user_img">
' . $imgOutputReply . '
</div>
<div id="comment_user">
<p class="user_text_comment">' . $firstNameReply . ' ' . $lastNameReply . '</p><p class="date_text_comment">' . $date_timeReply . '</p>
<p class="message_text_comment">' . $messageReply . '</p>
</div>
</div>
<div id="add_comment">
<form id="formAddComment" action="dashboard.php" enctype="multipart/form-data" method="post">
<div id="add_comment_left">
<textarea id="comment" name="comment" cols="75" rows="2">Add a Comment...</textarea>
</div>
<div id="add_comment_right">
<input id="userID" name="userID" type="hidden" value="' . $userID . '" />
<input id="actID" name="actID" type="hidden" value="' . $actID . '" />
<input id="btnComment" name="btnComment" type="submit" value="" title="Add Comment" />
</div>
</form>
</div>
</div>
</div>
OK, now the JQuery markup
<script type="text/javascript">
$(document).ready(function(){
$("#formAddComment").submit( function(e) {
e.preventDefault();
var form = $(this);
var div_add_comment = form.parent();
var div_comments = div_add_comment.parent();
$.ajax({
type: "POST",
data: form.serialize(),
url: "includes/comment.php",
success: function(msg){
$div_comments.html(msg);
}
});
return false;
});
});
</script>
Lastly the external php script (NOTE: I will only post the initial lines where i localize the data feed into php vars.)
if(isset($_POST['actID'])){
$actID = mysql_real_escape_string($_POST['actID']);
$userID = mysql_real_escape_string($_POST['userID']);
$comment = mysql_real_escape_string($_POST['comment']);
............other processing here...........
}
I am suspicious of my jquery script mostly.
Thanks again,
I dropped the general structure into a jsfiddle at http://jsfiddle.net/cori/JsLWq/, and when I submit the form I do indeed get an ajax POST to the non-existant http://fiddle.jshell.net/cori/JsLWq/show/includes/comment.php due to the relative ajax url, so that's not the problem as far as I can tell. What I do think is the problem is that you're mixing your variable naming rules.
You start off naming your variables like plain-old javascript objects
var form = $(this);
var div_add_comment = form.parent();
var div_comments = div_add_comment.parent();
but then in your success handler you switch to the fairly-common $x convention, often used to indicate that a variable is a jQuery instance:
$div_comments.html(msg);
however at that point there is no variable $div_comments; only div_comments. If you submit the form in http://jsfiddle.net/cori/JsLWq/1/, which has an ajax error handler, and look at your firebug console, you'll see that you get a ReferenceError because $div_comments is undefined.
EDIT
Incorporating kgarrigan's suggestions, if in your php you loop over the forms you want to create, and keep track of your position using an index, you could rename your forms with the index, so your form php/html code would look something like:
<form id="formAddComment-' . $index . '" action="dashboard.php" enctype="multipart/form-data" method="post">
so you would end up with form elements with ids like formAddComment-1.
Then in your jquery you would select all the forms using the startsWith selector and bind the submit event to them, thusly:
$('[id^="formAddComment"]').submit( function(e) {
// do your ajax
});
That way each form will have it's own submit handler.
jquery works with selectors. When you write $(something) something is the selector. It can be an id, a class name, a variable, html elements. So instead of
$("#formAddComment").submit( function(e) {
You could use
$(".someclassName").submit( function(e) {
just like css, use # for id, . for class. Just make sure you add the class attribute to your form with the same name. You could also try
$("form").submit(function(e) {
which should select any form elements. I think the rest of your function should work fine with this change, since you are using 'this' and parent() instead of any direct references.
In firebug, click on console, then on all. When you click on the button to trigger your ajax call you should see a line pop up, probably with a loading icon that shows a post request being sent. You should be able to click on the tabs to see what data is being posted and what response is given as well as a response status code...
In your edit, you say the success function will send out a new div id="comments" to replace the existing one, but as you have it written now, I believe it will just add a div id="comments" inside the existing one. Don't know if this would cause your problem though.
If you have multiple forms on the same page, with the same id's this will cause the problem. Especially the # formAddComment id, which is attached to the submit () call. If there are multiple of these ids, this won't work
Related
I'm learning AJAX and want to create a really simple web app to use my knowledge in the "real world".
I'm trying to calculte different percentages of a user input value, and make it appears on the webpage, without refreshing, thanks to AJAX.
Here is my HTML form:
<form id="warmupForm" class="form">
<label for="userWorkLoad">Work load (in kgs)</label><br>
<input type="text" name="userWorkLoad" id="userWorkLoad">
<button type="submit">Calculate</button>
</form>
<div id="#output">This is where I want the result to be shown with AJAX</div>
Here is some of my PHP code, for you to get the idea:
# Get the user input (work load in kgs)
if (isset($_POST['userWorkLoad'])) {
$workload = $_POST['userWorkLoad'];
# Avoid JS hacking
$workload = htmlspecialchars($workload);
}
# CALCULATION #
# Calculate 55% of the work load (1st warm up set)
$FirstWarmupSet = ($workload * 0.55);
# Calculate 70% of the work load (2nd warm up set)
$SecondWarmupSet = ($workload * 0.7);
# First Warmup set #
echo "<li>Do 8 reps with " . $FirstWarmupSet . " kgs, then take 1 minute rest.</li>";
echo "<br>";
# Second Warmup set #
echo "<li>Do 5 reps with " . $SecondWarmupSet . " kgs, then take 1 minute rest.</li>";
echo "<br>";
// etc etc...
I'd like the different variables values from PHP to be shown in my "#output" div when the user click on the submit button.
I've tried a lot of different things (AJAX without jQuery, AJAX with jQuery), but didn't manage to get what I want.
I'm sure I'm doing something wrong, but I don't know what. I'm sure my PHP script is working, since I used it without AJAX without any problem.
I would be very grateful if someone could help me on that.
As mentioned above, the easiest way to make an AJAX request for you is probably to try jQuery:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<!-- Add jQuery on your HTML page -->
<script src="https://code.jquery.com/jquery-3.5.1.min.js"></script>
<!-- Add some custom JavaScript file -->
<script type="text/javascript" src="script.js"></script>
</head>
<body>
<form id="warmupForm" class="form">
<label for="userWorkLoad">Work load (in kgs)</label><br>
<input type="text" name="userWorkLoad" id="userWorkLoad">
<button id="btn" type="submit">Calculate</button>
</form>
<div id="output">This is where I want the result to be shown with AJAX</div>
</body>
</html>
The script.js content:
$(function() {
// Process a button click
$("#btn").click(function() {
event.preventDefault();
// Get input field
var userWorkLoadInput = $("#userWorkLoad");
// Build some request parameters
var params = {
userWorkLoad: userWorkLoadInput.val()
};
// Let's name your PHP script file as "server.php"
// And send POST request with those parameters
$.post("server.php", params, function(response) {
// Response text we're going to put into the `output`
$("#output").html(response);
});
});
});
You can simply do it using Jquery instead of using Ajax (using PHP you should add method="POST" to the form).
Here's an example:
$(document).ready(function(){
$("#send").click(function(){
// your calculates
$("#output").html(...);
});
});
...
<button type="submit" id="send">Calculate</button>
I'm working with Ehsan Abbasi's Ajax Live Search (ALS)
https://github.com/iranianpep/ajax-live-search
http://ajaxlivesearch.com/
which invokes MySQL, PHP & jQuery to search and display search suggestion results as you type (similarly to popular search engines).
I'm struggling with the following:
When the user copies data and pastes it into the form, thereby rendering the live search pointless, what is the syntax to pass that data into the submitted form?
What does "onResultEnter" refer to? The user hits the enter button?
What does "onAjaxComplete" refer to? The user clicks a submit button?
Here's my relevant work to put these issues into context.
First, we initialize some variables and connect to our database via PHP:
# Live search initialization.
# --
file_exists($_SERVER['DOCUMENT_ROOT'].'/als/core/Handler.php') ? require_once $_SERVER['DOCUMENT_ROOT'].'/als/core/Handler.php' : die('Handler.php not found');
file_exists($_SERVER['DOCUMENT_ROOT'].'/als/core/Config.php') ? require_once $_SERVER['DOCUMENT_ROOT'].'/als/core/Config.php' : die('Config.php not found');
use AjaxLiveSearch\core\Config;
use AjaxLiveSearch\core\Handler;
if (session_id() == '') {
session_start();
}
$handler = new Handler();
$handler->getJavascriptAntiBot();
# Connect to database.
# --
require_once($_SERVER["DOCUMENT_ROOT"]."/connect.php");
global $dbc;
# Initialize required CSS and JavaScript files to be included.
# --
$additional_css = "<link href=\"/als/css/ajaxlivesearch.css\" rel=\"stylesheet\" type=\"text/css\" />";
$additional_js = "<script type=\"text/javascript\" src=\"/als/js/ajaxlivesearch.js\"></script>";
We next include two distinct forms to execute unrelated searches:
<!-- Model number search form -->
<form role="form" id="productsSearch" action="search-models.php" method="get" class="search-form">
<div class="input-group">
<input type="text" name="model_number" id="models" class="form-control modelSearch" placeholder="Enter your model number">
<input type="hidden" name="model_number" id="model_number">
<span class="input-group-btn">
<button type="submit" class="btn btn-default" onclick="return model_validator();">Go</button>
</span>
</div>
</form>
<!-- Part number search form -->
<form onsubmit="return part_validator();" action="search-parts.php" role="form" method="get">
<div class="input-group">
<input type="text" name="part_number" id="parts" class="form-control partSearch" placeholder="Enter your part number">
<input type="hidden" name="part_number" id="part_number">
<span class="input-group-btn">
<button type="submit" class="btn btn-default">Go</button>
</span>
</div>
</form>
Note here that the model search form involves an onclick event to validate model numbers. Similarly, the part number search form invokes an onsubmit event to validate part numbers. Both of these events were in our custom code before ALS entered the picture.
In addition, we have included a hidden field in each form to contain the value selected by the user in the ALS to be passed into the form when submitted to the action scripts.
These hidden field values are set in ALS functions associated with each of these input forms:
<!-- Model search: ALS functions -->
<script>
jQuery(document).ready(function() {
jQuery(".modelSearch").ajaxlivesearch({
onResultClick: function(e, data) {
// Get the index 0 (first column) value.
var selectedOne = jQuery(data.selected).find('td').eq('0').text();
// Set the input value.
jQuery('#models').val(selectedOne);
// Hide the result.
jQuery("#models").trigger('ajaxlivesearch:hide_result');
// Set the hidden field value.
$('input[name=model_number]').val(selectedOne);
},
onResultEnter: function(e, data) {
// What does this refer to? The user hits the enter button?
},
onAjaxComplete: function(e, data) {
// What does this refer to? The user clicks a submit button?
}
});
})
</script>
<!-- Part search: ALS functions -->
<script>
jQuery(document).ready(function() {
jQuery(".partSearch").ajaxlivesearch({
onResultClick: function(e, data) {
// Get the index 0 (first column) value.
var selectedOne = jQuery(data.selected).find('td').eq('0').text();
// Set the input value.
jQuery('#parts').val(selectedOne);
// Hide the result.
jQuery("#parts").trigger('ajaxlivesearch:hide_result');
// Set the hidden field value.
$('input[name=part_number]').val(selectedOne);
},
onResultEnter: function(e, data) {
// What does this refer to? The user hits the enter button?
},
onAjaxComplete: function(e, data) {
// What does this refer to? The user clicks a submit button?
}
});
})
</script>
I'd very much appreciate any help troubleshooting the syntax to get data that's copied by users from unknown sources & pasted into either of these forms and passed into the form action search scripts. Any light that could be shed on the onResultEnter and onAjaxComplete functions would likewise be welcomed.
If there's any additional information I can pass along to assist troubleshooting, do please let me know!
Best,
Allison
I'm a complete beginner with jQuery and I have this bit of script here and I want to mix jQuery with PHP. I have Courses and in those Courses are Lessons. A Teacher is assigned to teach a Course. What I want is a link where if I press it a popup appears and in it shows the Lesson details or Course details. My problem is that I will be having multiple links and thus dialogs/modal windows in a page such that $l['id'] and $c['id'] will be different. How can I therefore use $l['id'] and $c['id'] in or with jQuery given that the jQuery script is inside the view file and I'm creating the actual content itself in the controller and passing it onto view. Sorry if I don't make sense cause I'm still quite confused about all this myself.
view.php
<script type="text/javascript">
$(function(){
// setup ul.tabs to work as tabs for each div directly under div.panes
$("#tabs").tabs();
$('#dialog').dialog({
modal: true
});
})
</script>
<h1>Student Hub: Courses for <?php echo $studentName;?></h1>
<div id="tabs">
<?php echo $content;?>
</div>
controller.php
This is in a foreach loop
<div class="lessonDetails">
<p>Lesson Details:<p>
<div id="lessonDialog'.$l['id'].'" title="Lesson Details">
'.$l['name'].'
</div>
</div>
<div class="courseDetails">
<p>Course Timetable & Resources<p>
<div id="courseDialog'.$c['id'].'" title="Course Details">
<p>'.$c['fullname'].'</p>
<p>'.$c['summary'].'</p>
<p>Upcoming Lessons: </p>
</div>
Technical answer is you don't as one is a server-side language and one is a client-side language; you can't access PHP variables via JavaScript (jQuery). You can, however, drop your PHP variables into your HTML page on generation, and then pick them up with JavaScript or jQuery.
Reading your scenario, I think your over-complicating things. Think of your application; don't think of the technical aspects, but more the way it should be laid out. I'm guessing you have a students controller, a lessons controller, and a courses controller. Those controllers will have actions, called view or similar, and then these actions will take an ID to display a particular student/course/lesson.
In your HTML page/view/template, you should have just vanilla URLs. JavaScript should then be used to enhance the website. So in your case, I would have mark-up it up similar to as follows:
<ul class="courses">
<?php foreach ($courses as $course): ?>
<li><?php echo $course->title; ?></li>
<?php endforeach; ?>
</ul>
I'd then, in an external JavaScript file, have a function that listens for a click on the <a> tag and instead of navigating to that URL, instead displays the page content in a pop-up/modal window.
<script>
$('.courses a').click(function(e) {
e.preventDefault();
// load external page and display it in a modal
});
</script>
This way, if for some reason JavaScript's not available then the user will be taken to the course details page. If they do have JavaScript, then they'll get a fancy modal pop-up.
Hope this helps. If you need anything clearing up then let me know, as I have wrote this in the early hours after a few JD and Cokes!
you can create in every link some extra attributes and using jQuery retrieve the information with the attr function $('a').attr('courses').
somethig like
<a href="#" class=".information" teacher="idTeacher" course="idCourse" >list </a>
then using jquery
$('.information').click(function(){
teacher= $(this).attr('teacher');
course=$(this).attr('course');
});
remember to use $('.information').live() if you are using some AJAX to get the data from the server and the parse it to create the links
You can place tags within your JavaScript code. Since that code is server side, it will "render" to your JavaScript client side code. So your JavaScript can access values stored by your PHP script.
Here's a solution using jQueryUI dialog. No ID's are required however should they be needed add them as a data attribute to that links
<p><a href="#courseInfo'.$c['id'].'" data-id="'.$c['id'].'" >Course Timetable & Resources</a><p>
This allows easily getting ID with jQuery data() method.
Dialog is created and destroyed each use. As noted in comments, no idea what content goes in dialog. I can easily adjust if it is ajax from href
$('.lessonDetails a, .courseDetails a').click(function(){
var $this=$(this);
/* if need the id associated to link*/
var id=$this.data('id');
var content= ''/* ??????? */
var title=$this.parent().next().attr('title')
loadDialog(title, content);
return false; /* stop browser following href*/
})
function loadDialog(title, content) {
var dialogOpts = {
modal: true,
title: title,
width: 800,
close: function() {
/* remove this dialog from DOM on close*/
$(this).remove()
}
};
$('<div>').append(content).dialog(dialogOpts);
}
Maybe you can create forms that have hidden values in it.
<?php foreach($lesson as $l): ?>
<form method="POST" action="">
<input type="hidden" name="lesson_id" value="<?php echo $l['id']; ?>" />
Click
</form>
<?php endforeach; ?>
javascript:
$(document).ready(function() {
$('.modal_window').click(function() {
var form = $(this).closest('form');
var lesson_id = $(form).find('input[name=lesson_id]').val();
// Do something with lesson_id
});
});
The idea is the same for courses.
****** Edit ********
Maybe you can try using input arrays. Assumming you have something like this
<input type="hidden" name="courses[]" value="1" />
<input type="hidden" name="courses[]" value="2" />
javascript:
var courses = $(form).find('input[name^=courses]');
$(courses).each(function() {
var course = $(this).val();
});
So I have this html code
<div id="wrap">
<div id="header">
</div>
<div id="content">
<form method="POST" action="code.php">
Name:
<input type="text" name="name" size="50">
<input type=submit value="Get Code">
</form>
</div>
<div id="footer">
</div>
Is it possible to load the code.php after the user clicks submit into the #content div?
Essentially, what I want is when the user clicks the submit button, the code.php after processing is loaded onto the same #content div.
So let say in my code.php, after processing the inputted data, I come up with this lilne of code,
<?php
some processing code here;
$name = 'john';
echo $name;
?>
So then after hitting submit, user would see
<div id="content">
john
</div>
Hope I didn't complicate my question by repeating myself, please let me know if this is possible with javascript, php or whatever.
Thanks for the read!
#JohnP yes, $.load is a good solution. However, you'll need to send the form data in the request:
UPDATED [3] for sending a POST with multiple fields and checkboxes:
$('form').submit(function(){
// create an object to send as a post
var form = this,
fields = form.elements,
el,
post = {};
for (var i = fields.length; i--; ) {
el = fields[i];
if (el.name) {
switch (el.type) {
case 'checkbox':
case 'radio':
post[el.name] = (el.checked) ? el.value : '';
break;
default:
post[el.name] = el.value;
}
}
}
// send the form data in the load request...
$('#content').load(this.action, post);
return false;
});
This will send the data as a POST.
Since you've tagged jQuery, I'll use a jQuery example
$(document).ready(function(){
$('form').submit(function(){
$('#content').load('code.php');
return false;
})
})
This makes a couple of assumptions here
This assumes that code.php is in the same path that you are in now.
There is only one form in the page.
As #johnhunter points out, this example obviously won't work with post. You can send the post data along with the method. See here for usage : http://api.jquery.com/load
EDIT
Here's a fiddle example : http://jsfiddle.net/jomanlk/J4Txg/
It replaces the form area with the content from jsfiddle/net/echo/html (which is an empty string).
NOTE 2 Make sure to include the code in $(document).ready() or include it at the bottom of the page. It goes without saying you need jQuery in your page to run this.
You might want to check out jquery form plugin http://jquery.malsup.com/form/#
in simple way use
<div id="content">
if(isset($_POST['submit'] && !empty($_POST) )
{
// do your all post process
$name ='John';
echo $name;
}
else {
<form method="POST" action="$_SERVER['PHP_SELF']">
<label for="uname" >Name:</label><input type="text" name="uname" id="uname" size="50">
<input type=submit value="Get Code" name="submit">
</form>
}
</div>
Have a form that is not being read by serialize() function.
<script type="text/javascript">
function submitTrans1(){
var formData = $('form1').serialize();
var options = {
method:'post',
postBody:'formData',
onCreate: function(){alert(formData)},
onSuccess: function(transport){alert("onSuccess alert \n" + transport.responseText);},
onComplete: function(){alert('complete');},
onFailure: function(){alert('Something went wrong...')}
}
new Ajax.Request('/clients/addTrans/<?=$clientID123?>/',options);
}
</script>
<?php
$datestring = "%Y-%m-%d";
$time = time();
$clid1 = $this->uri->segment(3);
?>
<form name="form1" id="form1">
<div id="addTransDiv" style="display:none">
<div class="">
<label for="transDesc" id="transDesc" value="sadf" class="preField">Description</label>
<textarea cols="40" rows="3" id="transDesc" value="" name="transDesc" class=""></textarea>
</div>
<div class="">
<label for="date" class="preField">Date</label>
<input type="date" id="transDate" name="date" value="<?=mdate($datestring, $time);?>" size="40" class=""/><br/>
</div>
<div class="">
<label for="userfile" class="preField">File</label>
<input type="file" name="transFile" id="userfile" size="20" /><br>
</div>
<input type="button" id="submitTrans" name="submitTrans" value="Submit" onclick="submitTrans1()">
</div>
</form>
Uh, I have an alert in the onSuccess parameter of the Ajax.Request that would ideally alert the variable assigned to the serialized form. However, when it alerts, it alerts nothing. I also have the processing url printing out the $_POST data just in case, but that as well returns an empty array in the responseText, so indeedidly nothing is being posted to the form.
Thx.
Edit1
it seems that the problem might be related to the fact that the form is inside a div. If I remove everything on the page except for the form and js, it works ok. But the form is in a div that is hidden by default and uses another function to be displayed. Is there some kind of magic needed to get form data via serialize if it's in a div?
Edit 2
Tried adding quotes and pound signs and all that other jazz. I am using web developer toolbar, firebug, etc... it isn't throwing any js errors and doesn't afraid of anything.
Try removing the quotes from around the variable name formData in the postBody field.
The web developer toolbar in Firefox is as useful as anything for debugging client-side javascript.
BTW, the snippet contains a few undefined items, like the JS function showTransAdd(), several PHP variables, the PHP function mdate(), and the inclusion of the prototype library.
Change this line:
var formData = $('form1').serialize();
to this:
var formData = $('#form1').serialize();
I had to change several other things to make a working copy, but I'm not sure about what all code you withheld or how your environment may differ. If that doesn't work, I can send you the full code snippet I used.
Erroneous table does the breaking.
I had the form within a table with no tr's or td's (not sure if the last part matters) and upon removing the table tags, everything is working.
The relevant js now looks like:
var formData = $('form1').serialize();
var options = {
method:'post',
postBody:formData,
[...]
I'd like to thank the Academy, and all those that helped me.