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();
});
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 am looking to build a website which has a page, upon which there are some jChartFX charts, which are driven by a MySQL query. The query is driven by a date selected on a drop down on the main page.
I am struggling to structure the code properly (all completely self taught so fraught with poor practice!) so that the graph will update when a different option is selected.
The code is listed below, however my question is; where should the code sit for the drawing the chart to make this work. Should the function loadChart exist on the main page and echo the data in from the query from another page, or should I have the whole function on a separate page, which is loaded by the jquery, or option 3 - am I completely wide of the mark?
The code for the chart is; <> The echo $data is the section which echos the MySQL output, and works fine when the code and the SQL query is fixed.
<script>
var chart1;
function loadChart()
{
chart1 = new cfx.Chart();
chart1.getData().setSeries(1);
chart1.getAxisY().setMin(100);
chart1.getAxisY().setMax(1000);
var series1 = chart1.getSeries().getItem(0); series1.setGallery(cfx.Gallery.Lines);
var data = <?php echo json_encode($temp, JSON_NUMERIC_CHECK); ?>;
chart1.setDataSource(data);
var divHolder = document.getElementById('ChartDiv');
chart1.create(divHolder);
}
</script>
The SQL Query is
SELECT COUNT(`column_Date`) AS 'Count' FROM Dates WHERE `column_Date` > date('2013-06-01')
Note: Where the date is above 2013-06-01, I want this to change based on the drop down from the main page.
<head>
<script src="js/jquery-1.7.1.min.js"></script>
<script>
$(document).ready(function(){
$("#optionschosenid").click(function(){
if($("#optionsid").val() == "OptionA" ){
$("#chart").load("weeks.php");
}
else {
$("#chart").load("text_test.php");
}
});
});
</script>
</head>
<body onload="loadChart()">
<div id="row">
<form method="post" id="weekcommencing" name="dateselector">
<select id="optionsid" name="optionsname">
<option value="2013-06-01">June</option>
<option value="2013-01-01">January</option>
</select>
<button name="optionschosenname" id="optionschosenid"> Select Additional Option </button>
</form>
</div>
<div id="chart" name="chart">
<?php echo $data;
echo 'hello'; ?>
<br /> -->
Test 0.11
</div>
<button id="testId">click me</button>
<br />
<br />
<div id="ChartDiv">
</div>
</body>
The answer to your question is most likely "option 3" - you are completely wide of the mark :)
I don't know what is in your PHP $data variable - you don't show where it was declared and set. I see a Javascsript variable named data. I wonder if you might have the impression that javascript variables and PHP variables are visible to each other? They most certainly are not.
Bottom line is that you should separate everything as much as possible - as it seems you are starting to do. Include your javascript from a JS file. Include your HTML from a template.
Even though you are new, you are biting off enough that you should just dive right into an MVC framework. It will force you to learn at least some good practices.
So because my experience with jquery is zero i have no idea how to run my mysql script when the form is submitted without reloading a page?
in short
form radio button submit --> form sended --> query without reload
My script:
<form id="myForm" method="get">
<div class="row">
<div class="span4 info1">
<section class="widget">
<img src="../bootstrap/img/thumb/0.jpg" width="auto" height="auto">
<?php if ($selectedBg == '0') {
echo '<h2>Current one</h2>';
} ?>
<input type="radio" name="options[]" value="0" onclick="document.getElementById('myForm').submit();"/>
Choose Background
</section>
</div>
</div>
<?php
$checked = $_GET['options'];
for ($i = 0; $i < count($checked); $i++) {
$sql = 'UPDATE blog_users SET background = '.$checked[$i].' WHERE username=?';
$bg = $db->prepare($sql);
$bg->execute(array($session->username));
}
?>
</form>
So my question is how do I submit my form without reloading the page + running my query?
you will need to create a separate page that accepts the form data, and use jQuery's ajax functions to asynchronously submit the data.
Here is some pseudocode to show how you would accomplish this:
$('form').on('click', 'input:radio', function() {
$.get('NEW_PAGE_URL' + $(this).serialize(), function(data) {
// this function is the success function.
// your page should return some kind of information to let this function
// know that the submission was successful on the server side as well.
// This was you can manipulate the DOM to let the user know the submission
// was successful.
});
});
What you are describing is a technique that is called AJAX. It is a technique that is not specific to jQuery, php, or mysql. With that said, it is a common task for JQuery to help assist with.
You may want to check this post out: https://stackoverflow.com/a/5004276/1397590
Or if you're looking for more of a tutorial, then take a peak here: http://net.tutsplus.com/tutorials/javascript-ajax/submit-a-form-without-page-refresh-using-jquery/
Either way, there's lots of resources out there to get started learning about AJAX.
What I'm trying to do is to pass a user to a php script via a href link, then have them passed back to exactly the same position that they were at before they clicked the link, like the page hasn't been refreshed. Does anyone know if or how this could be possible possible? Thank you.
Using HTML you can have the following
<p id='open_here'><a href='script.php'> Send to script </a> </p>
And then you can link back to that exact position with
Send Back to page
So essentially, instead of using a regular link as in the previuos code snippet, you could redirect back to the page using
//php redirect
<?php header('Location: mypage.html#open_here'); ?>
//Javascript redirect
<script type='text/javascript'>
window.location = "mypage.html#open_here";
</script>
If you don't mind adding some Javascript to make it work, here is a solution that will make it possible to redirect back to the exact same scrollbar position as when the user clicked the link.
index.php (the file where the link is)
<script>
window.addEventListener('load', function() {
// Do we have a #scroll in the URL hash?
if(window.location.hash && /#scroll/.test(window.location.hash)) {
// Scroll to the #scroll value
window.scrollTo(0, window.location.hash.replace('#scroll=', ''));
}
// Get all <a> elements with data-remember-position attribute
var links = document.querySelectorAll('a[data-remember-position]');
if(links.length) {
// Loop through the found links
for(var i = 0; i < links.length; i++) {
// Listen for clicks
links[i].addEventListener('click', function(e) {
// Prevent normal redirection
e.preventDefault();
// Redirect manually but put the current scroll value at the end
window.location = this.href + '?scroll=' + window.scrollY;
});
}
}
});
</script>
page.php (the PHP script that redirects back)
<?php
// Get the provided scroll position if it exists, otherwise put 0
$scrollPos = (array_key_exists('scroll', $_GET)) ? $_GET['scroll'] : 0;
// Redirect back to index.php and provide the scroll position as a hash value
header('Location: index.php#scroll='.$scrollPos);
Hope it helps! :)
I am just spilling ideas here, but I would use javascript to intercept user's click on the href, and .preventDefault first. Then figure out where the user is on the page. Maybe by splitting the page into sections, indentified by IDs. Your html markup would be something like
<div id="section-1"></div>
<div id="section-2"></div>
<div id="section-3"></div>
so when javascript prevents the link from executing, it would figure out in which section the user currently is. Let's say we know each section's height. Then we need to find out the scrollbar position. I haven't done that, but have a look here
http://api.jquery.com/scrollTop/
Once we know the height of each section and once we can detect where the scroll bar is, we can determine in which section the user is residing. Then, we fetch the url of the href link and add a query string to it like, http://something.com/script.php?section=2 and redirect user to it with whatever data you want . Then once the script has done it's job append the query string to the redirect-uri and redirect the user back with something like http://something.com#section-2 and the user will immediatly pop to section-2
I know this isn't a very specific answer, but hopefully I've given you some leads and ideas how to accomplish this. Let me know how it works!
I'd had to remember the scroll position for a <select>. Example below. Three
submit buttons to illustrate why there's three getElementById. To see
it work you must move the scroll bar first
<?php
$scrollusObscura=$_GET["imgbtn"];
$header = <<<EOD
<!DOCTYPE html>
<html>
<head>
<title>snk_db</title>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
<head>
<script>
function gety(){
var y=document.getElementById('myUlID').scrollTop;
document.getElementById('imgbtn1').value=y;
document.getElementById('imgbtn2').value=y;
document.getElementById('imgbtn3').value=y;
}
function itemRelevatur(scrollum){
document.getElementById('myUlID').scrollTo(0, scrollum);
}
</script>
</head>
<body onload="itemRelevatur({$scrollusObscura})" >
EOD;
$html= <<<EOD
<div >
<select size="6" id="myUlID" name="myUlName" onscroll="myTimer = setInterval(gety, 300)">
<option>'1'</option>
<option>'2'</option>
<option>'3'</option>
<option>'4'</option>
<option>'5'</option>
<option>'6'</option>
<option>'7'</option>
<option>'8'</option>
<option>'9'</option>
<option>'10'</option>
<option>'11'</option>
<option>'12'</option>
<option>'13'</option>
<option>'14'</option>
<option>'15'</option>
<option>'16'</option>
<option>'17'</option>
<option>'18'</option>
<option>'19'</option>
</select>
</div>
EOD;
$html1= <<<EOD
<div><form method='GET' action'myscript.php'>
<input type='hidden' name='imgbtn' id='imgbtn1' value=''></input>
<input type='submit' value='Submit' ></input>
</form>
EOD;
$html2= <<<EOD
<form method='GET' action'myscript.php'>
<input type='hidden' name='imgbtn' id='imgbtn2' value=''></input>
<input type='submit' value='Submit' ></input>
</form>
EOD;
$html3= <<<EOD
<form method='GET' action'myscript.php'>
<input type='hidden' name='imgbtn' id='imgbtn3' value=''></input>
<input type='submit' value='Submit' ></input>
</form></div>
EOD;
echo $header;
echo $html;
echo $html1;
echo $html2;
echo $html3."</body></html>";
I had major problems with cookie javascript libraries, most cookie libraries could not load fast enough before i needed to scroll in the onload event. so I went for the modern html5 browser way of handling this. it stores the last scroll position in the client web browser itself, and then on reload of the page reads the setting from the browser back to the last scroll position.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function () {
if (localStorage.getItem("my_app_name_here-quote-scroll") != null) {
$(window).scrollTop(localStorage.getItem("my_app_name_here-quote-scroll"));
}
$(window).on("scroll", function() {
localStorage.setItem("my_app_name_here-quote-scroll", $(window).scrollTop());
});
});
</script>
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