I am new to php and javascript. I want to dynamically add a div to a page with php. In the end what I want is to be able to call a php function that adds a div. I want to call the function multiple times for a single page - so I want to add multiple divs via multiple function calls.
That doesn't seem to be difficult, but... I want each of the dynamically added divs to have the same class name, but a unique id and, for various reasons, I want the id to be based on the number of divs of that class already on the page (e.g. the first div added might have id = 0. the second id = 1, third id = 2 etc.).
I have looked a stackoverflow but haven't found any clues. I'd really appreciate any help.
I have tried the following, but it doesn't work (this is a very simplified version):
function getCount() {
?><script>
$(document).ready(function(){
var elems = $('body').find('.mydiv');
$.ajax({
type: 'POST',
url: '',
data: {count: elems.length},
cache: false,
success: function(response) {
console.log(response);
}
});
});
</script><?
}
echo '<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<script src="../jquery-3.2.1.js"></script>
</head>
<body>';
$count = -1;
getCount();
if (!empty($_POST)) {
foreach($_POST as $key => $value) {
if (!empty($key) && !empty($value)) {
echo 'key = '.$key.' value = '.$value;
if ($key == 'count') {
$count = $value;
}
}
}
}
if ($count > -1)
echo "<div class = 'mydiv' id = 'mydiv".$count."'></div>";
echo "</body></html>";
you dont want to mix js and php here, you can achieve this using php alone, here is the code sample
<?php
echo 'your headers and layout tags go here';
function addDiv($count){
echo "<div class = 'mydiv' id = 'mydiv".$count."'>current div id is ".$count."</div>";
}
$count=0;
addDiv($count++);
addDiv($count++);
addDiv($count++);
?>
Related
I have undercome a problem when implementing a "Show more button"
The page will initially display 5 rows of data, then on click the button will make a call to a php function through ajax and load more results, ultimately displaying them on the page. It does this very well.
The problem is that each of the divs are clickable in their own right to allow for user interaction. Before clicking the button the first 5 are clickable and work correctly, however after loading the first 10, the first 5 become unclickable and the rest work as expected.
See my code here:
HTML:
<div class="col-sm-12 col-xs-12 text-center pushDown">
<div id="initDisplay">
<?php
// Display all subjects
echo displaySubjects($limit);
?>
</div>
<div id="show_result"></div>
<button id="show_more" class="text-center pushDown btn btn-success">Show More</button>
</div>
On click of the button the following is happening:
JQuery:
<script>
$("#show_more").on("click", function() {
$("#initDisplay").fadeOut();
});
/* This bit is irrelevant for this question
$("#addBtn").on("click", function(){
addSubject();
});
*/
var stag = 5;
$("#show_more").on("click", function(){
stag+=5;
console.log(stag);
$.ajax({
dataType: "HTML",
type: "GET",
url: "../ajax/admin/loadSubjects.php?show="+stag,
success: function(result){
$("#show_result").html(result);
$("#show_result").slideDown();
}
});
var totalUsers = "<?php echo $total; ?>";
if(stag > totalUsers) {
$("#show_more").fadeOut();
}
});
</script>
My PHP page and functions are here:
<?php
include_once '../../functions/linkAll.inc.php';
$limit = filter_input(INPUT_GET, "show");
if (isset($limit)) {
echo displayUsers($limit);
} else {
header("Location: ../../dashboard");
}
function displaySubjects($limit) {
$connect = db();
$stmt = $connect->prepare("SELECT * FROM Courses LIMIT $limit");
$result = "";
if ($stmt->execute()) {
$results = $stmt->get_result();
while($row = $results->fetch_assoc()){
$id = $row['ID'];
$name = $row['Name'];
$image = $row['image'];
if($image === ""){
$image = "subjectPlaceholder.png"; // fail safe for older accounts with no images
}
$result .=
"
<div class='img-container' id='editSubject-$id'>
<img class='miniProfileImage' src='../images/subjects/$image'>
<div class='middle' id='editSubject-$id'><p class='middleText'>$name</p></div>
</div>
";
$result .= "<script>editSubjectRequest($id)</script>";
}
}
$stmt->close();
return $result;
}
The script being called through this is:
function editSubjectRequest(id) {
$("#editSubject-"+id).click(function(e) {
e.preventDefault(); // Prevent HREF
console.log("You clicked on " + id);
$("#spinner").show(); // Show spinner
$(".dashContent").html(""); // Empty content container
setTimeout(function() {
$.ajax({ // Perform Ajax function
url: "../ajax/admin/editSubjects.php?subjectID="+id,
dataType: "HTML",
type: "POST",
success: function (result) {
$("#spinner").hide();
$(".dashContent").html(result);
}
});
}, 1500); // Delay this for 1.5secs
});
}
This will then take the user to a specific page depending on the subject which they clicked on.
Your problem is duplicate ids. First five items are present on the page always. But when you load more, you are loading not new items, but all, including first five. As they are already present on the page, their duplicates are not clickable. The original items are however clickable, but they are hidden.
Here is what you need:
$("#show_more").on("click", function(){
$("#initDisplay").html("");
});
Don't just fadeOut make sure to actually delete that content.
This is the easiest way to solve your issue with minimum changes. But better option would be to rewrite your php, so it would load only new items (using WHERE id > $idOfLastItem condition).
Also you don't need that script to be attached to every div. Use common handler for all divs at once.
$("body").on("click", "div.img-container", function() {
var id = $(this).attr("id").split("-")[1];
});
When you are updating a DOM dynamically you need to bind the click event on dynamically added elements. To achieve this change your script from
$("#editSubject-"+id).click(function(e) {
To
$(document).on("click","#editSubject-"+id,function(e) {
This will bind click event on each and every div including dynamically added div.
I've got a complicated little problem here.
I'm building a WordPress plugin where I select a "parent" post (of a custom type that I made called 'step') and then an AJAX function shows a new select bar with all of the children of that parent. I do this by outputting the new and elements in the PHP file that's called in the AJAX function. This works, but now I want to repeat the process to run a function from the same JQuery file when this new outputted element is added to the page. (See Javascript code)
Main php plugin file (in a folder within the plugin directory):
<?php
/*
Plugin Name: n8jadams Step by Step Plugin (WIP)
Plugin URI:
Description:
Author: Nathan James Adams
Author URI: http://nathanjamesadams.com
Version: 0.0.1a
*/
//Exit if accessed directly
if(!defined('ABSPATH')) {
exit;
}
//My custom post type, it works fine
require_once(plugin_dir_path(__FILE__).'n8jadams-step-funnel-cpt.php');
require_once(plugin_dir_path(__FILE__).'n8jadams-ajax.php');
//Add my javascript
function n8jadams_init_javascript() {
wp_register_script('n8jadams_javascript', plugin_dir_url(__FILE__).'n8jadams-scripts.js', array('jquery'),'1.1', false);
wp_enqueue_script('n8jadams_javascript');
}
add_action('wp_enqueue_scripts', 'n8jadams_init_javascript');
//Adds a plugin menu to the wordpress sidebar
function n8jadams_add_plugin_menu() {
add_menu_page('', 'Steps Settings', 4, 'steps-settings', 'n8jadams_steps_settings', '');
}
add_action('admin_menu', 'n8jadams_add_plugin_menu');
//The actual function for the menu page
function n8jadams_steps_settings() {
//Access the database and the tables we want
global $wpdb;
$posts = $wpdb->prefix.'posts';
//Get the user id
$user = wp_get_current_user();
$userid = $user->ID;
//Initialize javascript (it works here!)
n8jadams_init_javascript();
/* Get all the parents */
$parentsquery = "
SELECT `ID`, `post_title`
FROM $posts
WHERE `post_author` = $userid
AND `post_parent` = 0
AND `post_status` = 'publish'
AND `post_type` = 'step'
";
$parentsarray = $wpdb->get_results($parentsquery);
?>
<h4>My Forms:</h4>
<select id="parentselect">
<option id="-1"> - Select Your Step Form - </option>
<?php
//output the parents
for($i=0;$i<sizeof($parentsarray);$i++) {
echo '<option id="'.$parentsarray[$i]->ID.'">'.$parentsarray[$i]->post_title.'</option>';
}
?>
</select>
<div id="displayChildren"></div>
<?php
}
?>
Javascript (n8jadams-scripts.js):
(function($){
$('#parentselect').change(function(s) {
var thisID = s.target[s.target.selectedIndex].id;
var outputDisplay = document.getElementById('displayChildren');
if(thisID != '-1') {
$.ajax({
type: 'POST',
url: 'admin-ajax.php',
data: {
action: 'n8jadams_get_children',
id: thisID
},
success: function(response){
if(response == "") {
outputDisplay.textContent = "This form has no children. Add them in the sidebar menu of this step form.";
} else {
outputDisplay.innerHTML = response;
}
},
error: function(errorThrown) {
alert(errorThrown);
}
});
} else {
outputDisplay.textContent = '';
}
});
// I want this function to work
/*
$('#childselect').change(function(t) {
console.log("test");
});
*/
})(jQuery);
PHP file called by AJAX (n8jadams-ajax.php):
<?php
function n8jadams_get_children() {
//Get the id of the parent
$parent_post_id = $_POST['id'];
//Sanitize the input (Added after question was answered)
$parent_post_id = preg_replace("/[^0-9]/","",$parent_post_id);
//Access database
global $wpdb;
$posts = $wpdb->prefix.'posts';
$user = wp_get_current_user();
$userid = $user->ID;
$childrenquery = "
SELECT `ID`, `post_title`,`post_content`
FROM $posts
WHERE `post_parent` = $parent_post_id
AND `post_status` = 'publish'
AND `post_type` = 'step'
AND `post_author` = $userid
";
//Retrieve the children associated with this parent
$childrenarray = $wpdb->get_results($childrenquery);
//Initialize Javascript (it doesn't work here!)
n8jadams_init_javascript();
if(!empty($childrenarray)) { ?>
<h4>My Steps:</h4>
<select id="childselect">
<option id="-1"> - Select Your Step - </option>
<?php
//output the children of the parent
for($i=0;$i<sizeof($childrenarray);$i++) {
echo '<option id="'.$childrenarray[$i]->ID.'">'.$childrenarray[$i]->post_title.'</option>';
} ?>
</select>
<?php wp_die();
}
}
add_action('wp_ajax_n8jadams_get_children', 'n8jadams_get_children');
add_action('wp_ajax_nopriv_n8jadams_get_children', 'n8jadams_get_children');
?>
Screenshot of Plugin Menu
I cannot figure out why my javascript file isn't working in the PHP file that's called by AJAX. Maybe the vast wisdom of the StackOverflow can help me. Thanks for the help in advance. :)
You are hooking into wp_enqueue_scripts, which is only run for the frontend of Wordpress (the part the average visitor sees). If you want to load a script into wp-admin, the backend of Wordpress, use the admin_enqueue_scripts action.
Since this code does not work in /wp-admin/, you don't need to use admin_enqueue_scripts. I guess the whole problem would be that you are attaching a handler to $('#childselect'), while no such element exists on the page at that time. Use deferring with $(..).on(..):
$(document).on('change', '#childselect', function(e) {
//Black magic
});
Side note: As already mentioned in the comments, the following part contains an unsanitised variable which will allow an attacker to perform sql injections.
$childrenquery = "
SELECT `ID`, `post_title`,`post_content`
FROM $posts
WHERE `post_parent` = $parent_post_id
AND `post_status` = 'publish'
AND `post_type` = 'step'
AND `post_author` = $userid
";
Use WP_Query if at all possible. If this is only used from the backend of Wordpress, don't use wp_ajax_nopriv_*, because users that are not logged in into your site have no right to use that anyway.
i'm developing a simple Content Management System that allow users to create categories and subcategories. This is the code.
$categories = mysql_query("SELECT * FROM categories");
while($row = mysql_fetch_array($categories)) {
$text = $row['text'];
$id = $row['id'];
echo "<li><a href='?category=$id'>$text</a></li>";
}
Now, all works fine as expected but i would like that when a user click on <li> items the system loads subcategories related to the selected category. In PHP i can't do this so i need to use JavaScript but i don't understand why. I wrote this code.
<script type="text/javascript">
function loadSubCategories() {
<?php
if(isset($_REQUEST['category'])) {
echo "Hello";
}
?>
}
</script>
and obviously
echo "<li><a href='?category=$id' onClick='javascript:loadSubCategories()'>$text</a></li>";
This not works because nothing appear when i click on a link. How can i solve?
Pass id attribute in function call like this:
echo "<li><a id="$id" onClick='javascript:loadSubCategories(this.id)'>$text</a></li>";
Then you can use jQuery/Ajax, try something like this:
$( document ).ready(function() {
function loadSubCategories(id){
$.ajax({
url : Class/Method-Name,
type : 'POST',
data : form_data,
success : function(msg){
// Action
}
}),
}
});
I am trying to call a PHP script in my main PHP file.Below is the Jquery/Ajax part of the main php file. The display_stationinfo.php is supposed to create the DIVs in the main but it isnt.
this is what I tried so far, im new to Jquery and AJAX. thanks in advance!
working fiddle: http://jsfiddle.net/52n861ee/
thats what I want to do but when I click on desk_box DIV, the toggle station_info DIV is not being created by my display_stationinfo.php script.
When I view source code both DIVs are supposed to be already created but only desk_box is.. what am I doing wrong?
JQuery/AJAX part:
<div id="map_size" align="center">
<script type="text/javascript">
//Display station information in a hidden DIV that is toggled
//And call the php script that queries and returns the results LIVE
$(document).ready(function() {
$(".desk_box").click(function() {
alert("before toggle");
var id = $(this).attr("data")
alert(id);
alert($(this));
$("#station_info_"+id).toggle();
alert("after toggle");
$.ajax({
url: 'display_stationinfo.php',
type: 'GET',
success: function(result) {
alert("before result");
$("#station_info_"+id).html(result);
alert("result: " + result); //it shoes every DIV being created and not the one that I clicked on
alert("after result");
}
});//end ajax
});//end click
});//end ready
</script>
</div> <!-- end map_size -->
display_station.php (script that I want to call):
<?php
include 'db_conn.php';
//query to show workstation/desks information from DB for the DESKS
$station_sql = "SELECT coordinate_id, x_coord, y_coord, section_name FROM coordinates";
$station_result = mysqli_query($conn,$station_sql);
//see if query is good
if ($station_result === false) {
die(mysqli_error());
}
//Display workstations information in a hidden DIV that is toggled
while ($row = mysqli_fetch_assoc($station_result)) {
//naming values
$id = $row['coordinate_id'];
$x_pos = $row['x_coord'];
$y_pos = $row['y_coord'];
$sec_name = $row['section_name'];
//display DIV with the content inside
$html = "<div class='station_info_' id='station_info_".$id."' style='position:absolute;left:".$x_pos."px;top:".$y_pos."px;'>Hello the id is:".$id."</br>Section:".$sec_name."</br></div>";
echo $html;
}//end while loop for station_result
mysqli_close($conn); // <-- DO I NEED TO INCLUDE IT HERE OR IN MY db_conn.php SINCE IM INCLUDING IT AT THE TOP?
?>
"SELECT coordinate_id, x_coord, y_coord, section_name FROM coordinates";
Is fetching every row from the table coordinates, is this what you want to do? Or do you just want to return only the row with the id the users clicked?
jQuery
$.ajax({
url: 'display_stationinfo.php',
data: { 'id': id },
type: 'POST',
success: function(result) {}
});
php
$id = $_POST['id']
"SELECT coordinate_id, x_coord, y_coord, section_name FROM coordinates WHERE coordinate_id == " $id;
Looking at you example, I would also guess that the problem could be that you are returning a string and putting it inside the target div so that the finished div looks somthing like this:
<div class="station_info_" id="station_info_84" style="position: absolute; left: 20px; top: 90px; display: block;">
<div class="station_info_" id="station_info_84" style="position:absolute;left:20px;top:90px;">
Hello the id is:84<br>
Section:Section B<br>
</div>
</div>
Instead of returning a string you could return a json object and append only data to the target div
php
while ($row = mysqli_fetch_assoc($station_result)) {
$id = $row['coordinate_id'];
$x_pos = $row['x_coord'];
$y_pos = $row['y_coord'];
$sec_name = $row['section_name'];
$result = array('id' => $id, 'x_pos' => $x_pos, 'y_pos' => $y_pos, 'sec_name' => $sec_name);
echo json_encode($array);
}
jQuery
$.ajax({
url: 'display_stationinfo.php',
data: { 'id': id },
type: 'POST',
dataType: "json",
success: function(json) {
$("#station_info_"+id)
.css({'left':json.x_pos ,'top': json.y_pos})
.append('<p>Hello the id is:'+ json.id +'</br>Section:'+ json.sec_name +'</p>');
}
});
I'm trying to make user interface to edit/insert records and i'm having some troubles with my code.
Lists the records :
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)){
extract($row);
$html.="<tr>
<td style>{$row['name']}<input type='hidden' id='id' value='$row[a_id]'></td>
<td>{$row['season']}</td>
<td><a href='edit1/new' id='edit'></a></td>
<tr style='height: 5px;'></tr>
</tr>..
Now the js that i`m having trubles with:
<script type='text/javascript'>
$('#edit').on( 'click', function () {
var x = document.getElementById('id').value;
$.ajax({
type: 'post',
url: 'insert_edit.php',
data: {
id: x
},
success: function( data ) {
console.log( data );
}
});
});
</script>
inside the insert_edit.php
if(isset($_POST['id'])){
$html = Edit();
}else{
$html = Add();
}
For some reason the on click function doesnt seem to work and it doesnt posts datainsert_edit.php`
Any help will be apriciated thank you.
NOTE: I'm not sure even if the posts works I'm using the Java Script the right way since my while loop prints it foreach ID and my guess is even it if it posts the data it will aways posts the value of the first record.
Try this- on click function replace with this-
$(document).on("click", "#edit", function(){
// ..
})
I managed to fix it. Here is how I did it:
I made an array $urlparts wich is my permalinks.
The button code goes like this
..a href='/account/competitions/edit1/update/$row[a_id]'>Edit..
And some php
if (isset($urlparts[4]) && is_numeric($urlparts[4])){
require_once ("insert_edit.php");
$html = Edit();
}
and inside the Edit();
just snach the id with
$id = $urlparts[4];
Thank you for the feeedback guys. Made me realize that I`m looking at the issue from the wrong angle:)