Jump to content

How to organise ajax code


Adamhumbug

Recommended Posts

Hi All,

As i am going through my project i am creating more and more files. 

Is it possible to have one file that contains all of my ajax functions for example.

If so, when giving the ajax the file path, how do i also tell it where in the file to look.

I know thats not how it works but i thought it was the best way to explain what i mean.

@Barand - This is kind of a follow up to your last response but i thought it warranted a new post.

Link to comment
Share on other sites

I usually pass a variable called "ajax" in my ajax calls. This has two purposes

  1. if my ajax handling code is in the same file as my calling code (it often is) it enables me to check for ajax calls with if isset($_GET['ajax']) and handle them separately.
  2. if there are multiple ajax calls, the value of that variable tells me what to do with it.
if (isset($_GET['ajax'])) {
    switch ($_GET['ajax']) {
        case 'region' :
            exit(getRegionSales($conn, $_GET['region']));
            break;
        case 'area' :
            exit(getAreaSales($conn, $_GET['area']));
            break;   
    }
}

Example scenario -

  • a sales report showing totals by region
  • Clicking on a region name drills down to show that region's sales broken down by area
  • Clicking on an area drills down again to show the area's sales broken down by product
$(".regionname").click(function() {
    var rgn = $(this).data("id");
    $.get (
        "ajax_handler.php",
        {"ajax" : "region", "region" : rgn},
        function(resp) {
            // output region's totals figures by area
        },
        "TEXT"
    )
})

$(".areaname").click(function() {
    var area = $(this).data("id");
    $.get (
        "ajax_handler.php",
        {"ajax" : "area", "area" : area},
        function(resp) {
            // output area's sales totals by product
        },
        "TEXT"
    )

 

Link to comment
Share on other sites

I am trying to work with this but the second modal is not getting the data from the second ajax call.

 

if(isset($_POST['ajax'])){
	switch ($_POST['ajax']) {
		case 'one':
			exit(popManageMenuModal($conn, $_POST['id']));
			break;
		
		case 'two':
			exit(popConfDelModal($conn, $_POST['id']));
			break;
	}
	
}
function popConfDelModal($conn, $miid){
	$out.= "<div>This is some info</div>";
	return $out;
}
function popManageMenuModal($conn, $miid){

The second function that i have cut off at the bottom is actually the one that runs first and works just fine.  It is the popConfDelModal that doesnt output anything.

This is the ajax

	$('.modalTrigger').click(function () {
    	var menuItemId = $(this).data("id")
    	$.ajax({
    		type: 'post',
    		data: {ajax : 'one', id: menuItemId},
    		success: function(response){
    			$('#menuItemInfo').html(response)
    		}
    	})
    	$('#manageMenuItemModal').modal({
    		show: true
    	})
    })

    $('.delButton').click(function () {
    	var menuItemId = $(this).data("id")
    	$.ajax({
    		type: 'post',
    		data: {ajax : 'two', id: menuItemId},
    		success: function(response){
    			$('#delConfInfo').html(response)
    		}
    	})
		$('#delConfModal').modal({
    		show: true
    	})
    });

and here is the html for the modals that you probably dont need to see.

<div class="modal fade" id="manageMenuItemModal">
	<div class="modal-dialog modal-lg">
		<div class="modal-content">
			<div class="modal-header">
				<h4 class="modal-title">Manage Menu Item</h4>
				<button type="button" class="close" data-dismiss='modal'>&times;</button>
			</div>
			<div id="menuItemInfo" class="container">
				<!-- modal information will go here -->
			</div>
		</div>
	</div>
</div>
<!-- modal -->
<div class="modal fade" id="delConfModal">
	<div class="modal-dialog modal-lg">
		<div class="modal-content">
			<div class="modal-header">
				<h4 class="modal-title">Delete Menu Item</h4>
				<button type="button" class="close" data-dismiss='modal'>&times;</button>
			</div>
			<div id="delConfInfo" class="container">
				<!-- modal information will go here -->
			</div>
		</div>
	</div>
</div>

Your help is always appreciated.

Link to comment
Share on other sites

18 hours ago, Barand said:
  1. You have an "undefined variable (out) error where you are concatenating.
  2. ajax call "two" is triggered when something with class="delButton" is clicked. I can find no reference to delButton in your html

ok, so i have created $out by putting $out =""; on the line above.

The del button is coming from the modal that was created by the first function.

I have put a console log into both ajax calls and can confirm that the second is not running.

Edited by Adamhumbug
Link to comment
Share on other sites

38 minutes ago, Adamhumbug said:

The del button is coming from the modal that was created by the first function.

When does the $('.delButton').click(function () run to define what happens when it is clicked?

Is it before the delButton has been created?

If the answer to the second is "Yes" then the button object will not receive the click handler.

Link to comment
Share on other sites

3 minutes ago, Barand said:

When does the $('.delButton').click(function () run to define what happens when it is clicked?

Is it before the delButton has been created?

If the answer to the second is "Yes" then the button object will not receive the click handler.

No i am pretty sure it runs after - i think i have pretty much duplicated what i have done to make the first modal.  Here is everything for context.

 

 

<?php if (session_status() == PHP_SESSION_NONE) {
session_start();
}
if (!isset($_SESSION['user_id'])){
	header("location: index.php");
	exit;
}
//name of the pagea
$_SESSION['this_page'] = 'new-menu';

include '_includes/dbconn.php';

function getMenuItems($conn){
	$output = '';
	$stmt = $conn -> query("
	                         SELECT menu_category_name
	                         FROM ssm_menu_items
	                         INNER JOIN  ssm_menu_category on menu_item_category_id = menu_category_id
	                         ORDER BY menu_category_display_order
	                         ");
	//create an empty array of all of the menu categories that are in use
	foreach ($stmt as $item){
		$menuItemsInCat[$item['menu_category_name']] = [];
	}
	$stmt = $conn -> prepare("
	                         	SELECT menu_item_id, menu_item_name, menu_category_name, sum(menu_item_qty)
								FROM ssm_menu_items mi
								INNER JOIN ssm_menu_category mcat ON mi.menu_item_category_id = mcat.menu_category_id
								left join ssm_menu_order USING (menu_item_id)
								GROUP BY menu_item_id
	                         ");
	$stmt -> execute();
	$stmt -> bind_result($miid, $miname, $mcatname, $miqty);
	while ($row = $stmt -> fetch()) {
		//put items into the blank array created above under their correct category
		
		$menuItemsInCat[$mcatname][$miid] = [$miname, $miqty];
	}
		//foreach thing in $menuItemInCat array there is $menucat array associated with $menuit(ems) array
		//we want the menu cat
	foreach ($menuItemsInCat as $menucat => $menuit) {
		$output .= "<tbody>";
		$output .= "<tr class='bg-secondary text-white text-center'><th>$menucat</th>";
		$output .= "<th>Qty On Order</th><th>Manage</th></tr>";
		//foreach thing in menu items array there is an array of ids and an array of items
		foreach ($menuit as $itemId => $itemName) {
			$output .= "<tr><td>$itemName[0]</td>";
			$output .= "<td>$itemName[1]</td>";
			$output .= "<td><div class='modaltrigger btn btn-primary' data-id='$itemId' data-toggle='modal'>Manage</div></td></tr>";
		}
		$output .= "</tbody>";
	}
	return $output;
}

//handle ajax 

if(isset($_POST['ajax'])){
	switch ($_POST['ajax']) {
		case 'one':
			exit(popManageMenuModal($conn, $_POST['id']));
			break;
		
		case 'two':
			exit(popConfDelModal($conn, $_POST['id']));
			break;
	}
	
}
function popConfDelModal($conn, $miid){
	$out = "";
	$out .= "<div>This is some info</div>";
	return $out;
}

function popManageMenuModal($conn, $miid){
	$stmt = $conn -> prepare('
	                        	SELECT menu_item_name, menu_item_is_vegan, menu_item_is_vegetarian, 
	                        	menu_item_is_gf, menu_item_is_nf, menu_item_is_df, menu_item_category_id 
	                        	FROM ssm_menu_items
	                        	INNER JOIN ssm_menu_category on menu_item_category_id = menu_category_id
	                        	WHERE menu_item_id = ?
	                        ');
	$stmt -> bind_param('i', $miid);
	$stmt -> execute();
	$stmt -> bind_result($miname, $miisvegan, $miisveg, $miisgf, $miisnf, $miisdf, $mcatid);
	$stmt -> fetch();

	

	$output = "";
	$output .= "<form><div  class='modal-body'><div class='form-group'><label >Menu Item Name</label><textarea name='menuItemName' class='form-control'>$miname</textarea></div>";
	$output .= "<div class='form-inline'><input name='miid' type='hidden' value='$miid'>";
	
	$a = array('Vegan'=>$miisvegan, 'Vegetarian' => $miisveg, 'Gluten Free' => $miisgf, 'Nut Free' => $miisnf, 'Dairy Free' => $miisdf);

	foreach ($a as $type => $value) {
		if($value == '0'){
			$polarity = 'btn-danger';
		}
		if($value == '1'){
			$polarity = 'btn-success';
		}
		$output .= "<div class='m-1 col drButton btn {$polarity}' data-value='$value'>$type</div><input id='$type' type='hidden' value='$value' name='$type'>";
	}
	$output .= "</div>";
	$stmt -> close();
	$cat = $conn -> prepare('SELECT menu_category_id, menu_category_name FROM ssm_menu_category');
	$cat -> execute();
	$cat -> bind_result($menucatid, $mcatname);
	$output .= "<select name='menucategory' class='form-control mt-3'>";

	$selected ='';
	while($cat -> fetch()){
	if($mcatid==$menucatid){
		$selected = 'selected';
	}else{
		$selected = '';
	}
		$output.= "<option {$selected} value='$menucatid'>$mcatname</option>";
	}
	$output .= "</select>";
	$output .= "<div class='modal-footer'><a data-toggle='modal' href='#delConfModal' data-id='$miid' class='delButton btn btn-danger'>Delete Menu Item</a>
				<button formmethod='post' type='submit' class='btn btn-primary'>Save Changes</button>
				</div>";
	$output .= "</form>";

	return $output;
}

// handle post request

if ($_SERVER['REQUEST_METHOD']=='POST') {
	$miid 	= $_POST['miid'];
	$miname = $_POST['menuItemName'];
	$vegan 	= $_POST['Vegan'];
	$vegi 	= $_POST['Vegetarian'];
	$gluten = $_POST['Gluten_Free'];
	$nut 	= $_POST['Nut_Free'];
	$dairy 	= $_POST['Dairy_Free'];
	$cat	= $_POST['menucategory'];

	$stmt = $conn -> prepare("
	                         UPDATE ssm_menu_items
	                         SET menu_item_name = ?, menu_item_is_vegan = ?, menu_item_is_vegetarian = ?, menu_item_is_gf = ?, menu_item_is_nf = ?, menu_item_is_df = ?, menu_item_category_id = ?
	                         WHERE menu_item_id = ?
	                         ");
	$stmt -> bind_param('siiiiiii', $miname, $vegan, $vegi, $gluten, $nut, $dairy, $cat, $miid);
	$stmt -> execute();
}

function messageBar(){
	global $miname;
	if($miname !=''){
		$out = "<div id='messageBar' class='alert alert-success text-center'>{$miname} has been updated</div>";
		return $out;
	}
}


?>
<?php include '_includes/head.php'; ?>
<div class="container-fluid">
	<div class="row">
		<?php include '_includes/header.php'; ?>
	</div>
	<div class="row" >
		<div class="col-sm-2 p-0 bg-dark text-light">
			<?php include '_includes/nav.php'; ?>
		</div>
		<div class="col-sm-10" style="height: calc(100vh - 80px);overflow:scroll;">
			<div class="mt-3">
<?= messageBar() ?>
				<table class="table table-striped table-hover table-bordered text-center align-middle">
					<?= getMenuItems($conn) ?>
				</table>
			</div>
			<div class="col-sm-12"><?php include '_includes/footer.php'; ?></div>
		</div>
	</div>
	
</div>
<!-- modal -->
<div class="modal fade" id="manageMenuItemModal">
	<div class="modal-dialog modal-lg">
		<div class="modal-content">
			<div class="modal-header">
				<h4 class="modal-title">Manage Menu Item</h4>
				<button type="button" class="close" data-dismiss='modal'>&times;</button>
			</div>
			<div id="menuItemInfo" class="container">
				<!-- modal information will go here -->
			</div>
		</div>
	</div>
</div>
<!-- modal -->
<div class="modal fade" id="delConfModal">
	<div class="modal-dialog modal-lg">
		<div class="modal-content">
			<div class="modal-header">
				<h4 class="modal-title">Delete Menu Item</h4>
				<button type="button" class="close" data-dismiss='modal'>&times;</button>
			</div>
			<div id="delConfInfo" class="container">
				<!-- modal information will go here -->
			</div>
		</div>
	</div>
</div>

<script>
	//set sidebar active indicator
	//XX = name of parent if in dropdown eg "sheet"
	if(document.getElementById('menu')){
		document.getElementById('menu').classList.add('show')
	}
	//nav button ID
	if(document.getElementById('newMenu')){
		document.getElementById('newMenu').classList.add('blOrange')
	}

	$('.modalTrigger').click(function () {
    	var menuItemId = $(this).data("id")
    	$.ajax({
    		type: 'post',
    		data: {ajax : 'one', id: menuItemId},
    		success: function(response){
    			$('#menuItemInfo').html(response)
    		}
    	})
    	$('#manageMenuItemModal').modal({
    		show: true
    	})
    })

    $('.delButton').click(function () {
    	var menuItemId = $(this).data("id")
    	console.log('one')
    	$.ajax({
    		type: 'post',
    		data: {ajax : 'two', id: menuItemId},
    		success: function(response){
    			console.log('i ran')
    			$('#delConfInfo').html(response)
    		}
    	})
		$('#delConfModal').modal({
    		show: true
    	})
    })



//dietary requirement buttons polarity
$(document).on('click','.drButton', function(){
	var polarity = $(this).attr("data-value")
	var id = $(this).text()
	var hi = document.getElementById(id)
	if(polarity == '0'){
		$(this).addClass("btn-success")
		$(this).removeClass("btn-danger")
		$(this).attr("data-value", "1")
		
		if(hi){
			hi.value = '1'
		}

		return false
	}
	if (polarity == '1'){
		$(this).addClass("btn-danger")
		$(this).removeClass("btn-success")
		$(this).attr("data-value", "0")

		if(hi){
			hi.value = '0'
		}

		return false
	}
});

$('#messageBar').delay(2000).fadeOut(1000);

  $(document).ready(function () {
        $(document).on('show.bs.modal', '.modal', function (event) {
            var zIndex = 1040 + (10 * $('.modal:visible').length);
            $(this).css('z-index', zIndex);
            setTimeout(function() {
                $('.modal-backdrop').not('.modal-stack').css('z-index', zIndex - 1).addClass('modal-stack');
            }, 0);
        });
});


</script>

 

Link to comment
Share on other sites

  1. Page loads and the <script> at bottom of page runs, defining the .delButton click handler.
  2. User clicks "Manage" button and a delButton is created, but the handler has already been defined

When a handler is defined for a class it is attached to existing members of that class. Your delButton does not exist when the page is initially loaded.

Link to comment
Share on other sites

PS Your processing sequence is FUBAR. You should

  1. Handle ajax requests - any output in an ajax call is returned in the response, so you need to process and exit asap
  2. Handle POST processing - then after updating db reload the page with a location header and exit.
  3. Handle GET processing and other processing required for page output.
  4. HTML
Edited by Barand
Link to comment
Share on other sites

1 minute ago, Barand said:

PS Your processing sequence is FUBAR. You should

  1. Handle ajax requests
  2. Handle POST processing
  3. Handle GET processing and other processing required for page output.
  4. HTML

ahhhh, and i thought i was doing so well.  Ok ill have another look at resorting it.

I have chnaged the function to just be a function rather than looking for a click.  I have put an onclick on the button that is being created.

Link to comment
Share on other sites

3 minutes ago, Adamhumbug said:

I have chnaged the function to just be a function rather than looking for a click.  I have put an onclick on the button that is being created.

That's the easiest way. The other way is to put the code defining the handler inside the ajax call's response handling function (which can get a bit messy)

Link to comment
Share on other sites

1 minute ago, Barand said:

That's the easiest way. The other way is to put the code defining the handler inside the ajax call's response handling function (which can get a bit messy)

It is now showing the response which is nice.  I am however getting Undefined index: id on the switch calling the second function.

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.