Jump to content
Adamhumbug

How to organise ajax code

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.

Share this post


Link to post
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"
    )

 

Share this post


Link to post
Share on other sites

Ahh ok.

So when you click the button that is going to run ajax, you use the "ajax" : "something" to tell it which php function to then run?

Edited by cyberRobot
Removed unnecessary quote

Share this post


Link to post
Share on other sites

Second question, what is the "TEXT" for?

Edited by cyberRobot
Removed unnecessary quote

Share this post


Link to post
Share on other sites

Sorry, missed the second question

1 minute ago, Adamhumbug said:

Second question, what is the "TEXT" for?

It's usually going to be either "TEXT" or "JSON", depending on whether the ajax response will contain text or json encoded data,

Share this post


Link to post
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.

Share this post


Link to post
Share on other sites
  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

Share this post


Link to post
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

Share this post


Link to post
Share on other sites
<a data-toggle='modal' href='#delConfModal' data-id='$miid' class='delButton btn btn-danger'>Delete Menu Item</a>

This is the button that calls the second ajax, it is an A tag so i can stack the modals

 

Edited by Adamhumbug

Share this post


Link to post
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.

Share this post


Link to post
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>

 

Share this post


Link to post
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.

Share this post


Link to post
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

Share this post


Link to post
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.

Share this post


Link to post
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)

Share this post


Link to post
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.

Share this post


Link to post
Share on other sites

Does the developer tool's network tab show the id being sent? Code seems OK.

Share this post


Link to post
Share on other sites

PS I always quote my variable names EG

data: {"ajax" : 'two', "id": menuItemId},

 

Share this post


Link to post
Share on other sites
4 minutes ago, Barand said:

Does the developer tool's network tab show the id being sent? Code seems OK.

Erm, no it doesnt

Share this post


Link to post
Share on other sites
2 minutes ago, Barand said:

does menuItemId have a value?

undefined - the button has a data ID though and i am trying to get it in the same way as on the other ajax.

Share this post


Link to post
Share on other sites

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.