Jump to content
Larry Ullman's Book Forums

another_noob

Members
  • Posts

    60
  • Joined

  • Last visited

  • Days Won

    3

Everything posted by another_noob

  1. You still with us? I haven't seen a post in awhile which is unusual. I miss your input. I learned a lot of cool "tricks of the trade" from your posts. I hope all is well and you are busy making $$.
  2. I decided to install Yii2 on my Ubuntu server I use for live demo's for clients. While trying to install Composer I ran into permissions problems with this line of code: curl -sS https://getcomposer.org/installer | php I would get these errors: Downloading... Could not create file //composer.phar: fopen(//composer.phar): failed to open stream: Permission denied Download failed: fopen(//composer.phar): failed to open stream: Permission denied fwrite() expects parameter 1 to be resource, boolean given I prefaced the command with "sudo" and received the same permissions output. After some poking around I found the problem to be I needed to add a "sudo" after the pipe also. Like this: sudo curl -sS https://getcomposer.org/installer | sudo php After that, Things worked as expected. Hopefully this will save someone some agony someday.
  3. Good eye Larry! I am impressed that you spotted that. No one can ever say you aren't paying attention. I made the change and it works as expected. I over thought (and over looked) that detail. Thanks.
  4. I have refactored this jQuery click handler several times over. It has became the basis, and heart & soul, of several practice "single page applications". Now it looks like this: $(document).ready(function () { //Flag variable to track state of clicked element var btnProcessing; //Event attached to the document object $(document).click(function(e){ //target is the element clicked. e is the event if ($(e.target).is('.js_button') || $(e.target).is('.js_list_item')){ //Get the id of clicked element to use for the switch cases var element_id = e.target.getAttribute("id"); //Do not submit a form with a <button> click e.preventDefault(); //Keep event bubbling from duplicating events e.stopImmediatePropagation(); //Get the clicked button's default text var initial_text = $(e.target).text(); //Get the html5 data attribute from the clicked element to select the php switch case in ajax_action.php var ajax_action = e.target.getAttribute("data-ajax_action"); //Get the html5 data attribute from the clicked element to use as data for PHP/MySQL processing var ajax_data = e.target.getAttribute("data-ajax_data"); //If form submission, collect form data with serialize() if(element_id == 'js_submit'){ ajax_data = $('.js_form').serialize(); } //If clicked element is of class ".js_button" and not currently processing another request, or is of class ".js_list_item" if (($(e.target).hasClass( "js_button" ) && !btnProcessing) || ($(e.target).is('.js_list_item'))) { //Flag to denote processing btnProcessing = true; //Set visual feedback on button or list item $(e.target).text('Processing...'); //Process the request $.post('ajax_action.php', {ajax_data : ajax_data, ajax_action : ajax_action}, function(ajax_response){ //ajax response returns whatever the called script is written to return $('.ajax_div').html(ajax_response); //Got the response...free up the buttons btnProcessing = false; //re-set the element text back to the original value $(e.target).text(initial_text); }); } } }) }); I refactored it to follow some very basic conventions. Buttons will all be of class js_button and use the following example for all HTML5 data attributes: <buttons class="js_button" data-ajax_action="someFunction" data-ajax_data="someData">Click Me</button> Forms follow a simple convention: <form class="js_form"> //form fields as usual <button class="js_button" id="js_submit" data-ajax_action="someAction">Submit</button> </form> The ajax_action attribute will relate to a case of the same name in the ajax_action.php script which will call a function of the same name: case 'someFunction': someFunction($ajax_data); break; I use a mysqli_connect.php as a "model" type of thinking. In this script I have database interaction functions: function someFunction($ajax_data){ //Do some database CRUD stuff } Of course the $ajax_data parameter could (and should) be named something that makes sense to the query, like perhaps $customer_id or $customer_data. That would make it easier to see at a glance the function's purpose. I can submit form data and I can pass a php array as JSON with the data-ajax_data attribute. This has given me a lot of flexibility for SPA development. Following the required conventions of the click handler and with the required simple file structure, I have set up a simple to use MVC SPA where the index.php is the view, the ajax_action.php is controller and the mysqli_connect is the model. The click_handler.js file is the router...sort of. it all may appear convoluted...as most code does, it is quite simple to use. It is a lot of fun to play with and the possibilities are endless.
  5. Okay, so I got this working. Here is how I did it, probably is an easier way, but I don't know one. To get the PK of the client, I send it from the clientController's actionView function when a user clicks the view icon on the index page: public function actionView($id) { return $this->render('view', [ 'model' => $this->findModel($id), 'client_id' => $id, ]); } In My client/view script that renders the list of projects belonging to the client, I now have the $client_id variable available to send as an argument to the projectController's actionCreate function. I had to use 'yii\helpers\url' to take advantage of "url creation" in my button code. So now the client/view script that renders the list of projects belonging to a client looks like this: <?php use yii\helpers\Html; use yii\helpers\Url; use yii\widgets\DetailView; /* @var $this yii\web\View */ /* @var $model app\models\Client */ $this->title = $model->client; $this->params['breadcrumbs'][] = ['label' => 'Clients', 'url' => ['index']]; $this->params['breadcrumbs'][] = $this->title; ?> <div class="client-view"> <h1><?= Html::encode($this->title) ?></h1> <h3>Client Projects</h3> <ul> <?php foreach($model->projects as $project):?> <a href="index.php?r=project/view&id=<?= $project['id'] ?>" > <li> <?= $project['proj_name']?> </li> </a><br /> <?php endforeach;?> </ul> <?= Html::a('Add A New Project', Url::to(['project/create', 'client_id' => $client_id]), ['class' => 'btn btn-success']) ?> </div> Now when the "Add A New Project" button is clicked, the $client_id is passed to the projectController's actionCreate function which I have changed to accept an argument of $client_id. So now the projectController's actionCreate function looks like this: public function actionCreate($client_id) { $model = new Project(); if ($model->load(Yii::$app->request->post()) && $model->save()): return $this->redirect(['view', 'id' => $model->id]); else: return $this->render('create', [ 'model' => $model, 'client_id' => $client_id, ]); endif; } So now I have passed the $model and $client_id variables to the views/project/create script that now looks like this: <?php use yii\helpers\Html; /* @var $this yii\web\View */ /* @var $model app\models\Project */ $this->title = 'Create New Project'; $this->params['breadcrumbs'][] = ['label' => 'Projects', 'url' => ['index']]; $this->params['breadcrumbs'][] = $this->title; ?> <div class="project-create"> <h1><?= Html::encode($this->title) ?></h1> <?= $this->render('_form', [ 'model' => $model, 'client_id' => $client_id, ]) ?> </div> Which basically just renders the html form script that now has access to the $model and $client_id variables. The _form view script now looks like this: <?php use yii\helpers\Html; use yii\widgets\ActiveForm; /* @var $this yii\web\View */ /* @var $model app\models\Project */ /* @var $form yii\widgets\ActiveForm */ ?> <div class="project-form"> <?php $form = ActiveForm::begin(); ?> <?= $form->field($model, 'client_id')->input('hidden', ['value' => $client_id])?> <?= $form->field($model, 'proj_num')->textInput(['maxlength' => 10]) ?> <?= $form->field($model, 'proj_name')->textInput(['maxlength' => 100]) ?> <?= $form->field($model, 'pm_id')->textInput(['maxlength' => 10]) ?> <?= $form->field($model, 'date_started')->textInput() ?> <?= $form->field($model, 'date_closed')->textInput() ?> <?= $form->field($model, 'status')->textInput() ?> <div class="form-group"> <?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?> </div> <?php ActiveForm::end(); ?> </div> I went with a hidden form field to get the $client_id back to the controller->model for insertion into the database. I had to use trial and error on the hidden form field syntax because I couldn't find a single example anywhere for that. It works as expected, and now I can do the same for client contacts and for any specific contacts associated with a specific project. If anybody has a better yii 2 implementation of this idea, I am all eyes. There must be a simple one line of code solution at the model level, but I can't figure it out with my limited experience with Yii2/MVC/OOP.
  6. Thank you for your time Jonathon. I see what you are getting at. I don't think I was very clear in what my confusion is. I will explain this further. Same scenario, client->one-to-many->project. My client/index route renders a gridview of client names. I can click on the view icon to open a client/view&id=3 (for example). This will render my view that codes like this: <?php use yii\helpers\Html; use yii\widgets\DetailView; /* @var $this yii\web\View */ /* @var $model app\models\Client */ $this->title = $model->client; $this->params['breadcrumbs'][] = ['label' => 'Clients', 'url' => ['index']]; $this->params['breadcrumbs'][] = $this->title; ?> <div class="client-view"> <h3>Client Projects</h3> <ul class="list-project"> <?php foreach($model->projects as $project):?> <a href="index.php?r=project/view&id=<?= $project['id'] ?>" class=""> <li class="project_list_item"> <?= $project['proj_name']?> </li> </a> <?php endforeach;?> </ul> <?= Html::a('Add A New Project', ['project/create'], ['class' => 'btn btn-success']) ?> </div> This view gives me a list of hyperlinks of the current projects for the client with the id of 3. I can click a project hyperlink and the project/view&id=1 route will render a view showing all the pertinent details about the project. With the data I manually entered into my database tables all of this works the way I want it to. My confusion is this: in that view I have a button to create a new project for the client: <?= Html::a('Add A New Project', ['project/create'], ['class' => 'btn btn-success']) ?> This line of code renders the _form to enter a new project via the project/create route. I don't know how to get the client model PK to have available to insert into the project table thus cementing the relationship of this new project to the client with the id of 3, in this example. The Gii generated views/project/form: <?php use yii\helpers\Html; use yii\widgets\ActiveForm; /* @var $this yii\web\View */ /* @var $model app\models\Project */ /* @var $form yii\widgets\ActiveForm */ ?> <div class="project-form"> <?php $form = ActiveForm::begin(); ?> <?= $form->field($model, 'client_id')->textInput(['maxlength' => 10]) ?> <?= $form->field($model, 'proj_num')->textInput(['maxlength' => 10]) ?> <?= $form->field($model, 'proj_name')->textInput(['maxlength' => 100]) ?> <?= $form->field($model, 'pm_id')->textInput(['maxlength' => 10]) ?> <?= $form->field($model, 'date_started')->textInput() ?> <?= $form->field($model, 'date_closed')->textInput() ?> <?= $form->field($model, 'status')->textInput() ?> <div class="form-group"> <?= Html::submitButton($model->isNewRecord ? 'Create' : 'Update', ['class' => $model->isNewRecord ? 'btn btn-success' : 'btn btn-primary']) ?> </div> <?php ActiveForm::end(); ?> </div> From a user's perspective it has to as easy as this: The User sees a list of clients, Compuware U of M Baseball U of M Football U of M Hockey U of M School of Social Study Whirlpool User clicks a client choice (view icon) and is then presented the list of current projects for that client and and the end of the list has a button to add a new project to the list that is automatically linked to the client, without the use needing to remember anything about the client that they clicked. The dropdown idea would work, but my users will be able to add a football stadium project to Whirlpool instead of U of M Football as they intended. Sometimes it takes me a bit to explain the problem I am having in a coherent fashion because I don't completely understand what I am trying to say. I think this is a more lucid explanation than last night's ramblings.
  7. I hunkered down this winter to get a better grasp on OOP, MVC, frameworks, and then Yii. Now I am trying to apply all this new knowledge, or my lack of... which is about to become very obvious. I have a very simple application design concept that works flawlessly in procedural PHP. A simplified version looks like this: A database table of "client" and a table of "project". A one (client) to many (project) relationship with a "client_id" foreign key relating to "id" in client table. Couldn't be simpler. I use composer to spin up a Yii 2 skeleton, change the config/db file to my database settings. Now with Gii I spin up my models and CRUD. Gii even sets up the table relationships...magic I say! Here is what I don't get about all this: Gii spins up the necessary CRUD forms which is great, but the project form has no knowledge of the client model. If I go to "localhost/myapp/web/index.php?r=project/create" I get the project entry form, but the first form entry is client ID. That is fine if I know the "id" from the client model. I don't understand how I link a project model to a client model dynamically in code. If Gii knew about the one->many relationship of these two tables, why not give me the model link in code to allow adding a project to the client with some PK to FK linked forms. I am baffled by this. I don't see how to make this happen with the Gii generated code. This was incredibly simple in my procedural projects. I must have missed a tidbit of knowledge somewhere that explains how I do this simple thing with the Yii framework. I don't expet Yii or Gii to read my mind and do what I am thinking, I know I need to write code to get what I want and be gracious to Gii for all of the time saving boiler plate code. If anyone can enlighten me a tad or point me to the sentence I missed that makes this concept clear, I would greatly apprciate it. Oh, I am using Yii 2, but it shouldn't matter for this question.
  8. Thanks HartleySan for the reply. I got it to work with a variation of your suggestion. Before I posted for help, I did try exactly what you suggested, I got a newline, but I would get a "undefined variable $dbc" notice and $dbc would be blank in the generated string. I had to initialize $dbc to a string literal '$dbc' for it to show up as a variable in the generated string. Like this: function make_mysqli_connection_file($db_host,$db_user,$db_pass,$db_name){ $dbc='$dbc'; $mysqli_connect_file = fopen("includes/mysqli_connect.inc.php", "w") or die("Unable to open file!"); $conn_string = "<?php \r\n $dbc = mysqli_connect ('" . $db_host . "', '" . $db_user . "', '" .$db_pass . "', '" . $db_name . "') OR die('Could not connect to MySql: ' . mysqli_connect_error() )"; fwrite($mysqli_connect_file, $conn_string); fclose($mysqli_connect_file); } Now I get the output I need in my auto generated connection script. This is a fun little project that I have become obsessed with...too much time on my hands I guess. Oh well, even if it goes nowhere, I learned a lot. Thanks again.
  9. Perhaps this thread started by chop may be of some help: http://www.larryullman.com/forums/index.php?/topic/3568-e-mail-issues-related-to-php-mail-form/
  10. I am creating a basic application framework just for a challenging project. Things are going good except for this silly problem: function make_mysqli_connection_file($db_host,$db_user,$db_pass,$db_name){ $mysqli_connect_file = fopen("includes/mysqli_connect.inc.php", "w") or die("Unable to open file!"); $conn_string = '<?php $dbc = mysqli_connect ("' . $db_host . '", "' . $db_user . '", "' . $db_pass . '", "' . $db_name . '") OR die("Could not connect to MySql: " . mysqli_connect_error() );'; fwrite($mysqli_connect_file, $conn_string); fclose($mysqli_connect_file); } This function will create an "includes" directory and a "mysqli_connect.inc.php" file with the standard connection string, it works as expected. The problem is that I want a newline after the opening php tag. I have tried double quoting the string, single quoting and all the necessary concatenation combinations necessary to keep the variables correct. The current output of the function is this: <?php $dbc = mysqli_connect ("localhost", "root", "", "database_test") OR die("Could not connect to MySql: " . mysqli_connect_error() ); And what I want is this: <?php $dbc = mysqli_connect ("localhost", "root", "", "database_test") OR die("Could not connect to MySql: " . mysqli_connect_error() ); It seems so simple, but the solution is eluding me. If I can get this solved I can move forward on other parts of this script. Thanks for any advice!
  11. I had a similar complaint from a client recently. He was not receiving registration confirmation emails when his students registered for training. I used my several different email addresses in place of his and all worked fine. What I found was this: he had an AOL email account, AOL blacklisted the IP address from his shared hosting account at HostGator. I found this out by digging into the log file in his HostGator CPanel. Apparently, some knucklehead was sending oodles of spam mail from his shared host server, so... AOL blacklisted the IP, which probably affected a lot of website's email functionality. He created a gmail email account and all is well. That's all I got...
  12. I added a needed feature to the click handler. I need to select the "action" for the controller switch case, but some times I do need a database record id from the from the button click. So I came up with a generic data attribute I will call an "extra". In my HTML here is an example how I will do it: <button id="get_dmd_form" class="button" data-action="get_dmd_pdf" data-extra="'.$dmd_row['repair_id'].'">Get DMD Form</> Now if I keep this generic attitude in my handler like this: if(extra != null){ var data = 'action=' + action + '&extra=' + extra; }else{ var data = 'action=' + action; } Then in the PHP controller script: case 'get_dmd_pdf': $repair_id = isset($_POST['extra']) ? $_POST['extra'] : NULL; display_dmd_pdf($repair_id); break; In the controller is where I actually break from generic to specific by naming the variable to something meaningful. In this case the function sets up an fpdf document and outputs it for download. The handler in it's entirety now looks like this: $(document).ready(function(repair_id){ //Flag variable to track state of clicked button var btnProcessing; //Event attached to the document object $(document).click(function(e){ //target is the button clicked. e is the event if ($(e.target).is('.button')){ //Get the clicked button's default text var initial_text = $(e.target).text(); //Get the html data attribute from the clicked button to select the php switch case var action = e.target.getAttribute("data-action"); //Set up an additional data attribute here var extra = e.target.getAttribute("data-extra"); //Set up the ajax data variable to select the correct switch case in action.php, name and append the extra data to the action variable if needed if(extra != null){ var data = 'action=' + action + '&extra=' + extra; }else{ var data = 'action=' + action; } //If class of "button" and not currently processing another request if ($(e.target).hasClass( "button" ) && !btnProcessing) { //Flag to denote processing btnProcessing = true; //Visual feedback on button $(e.target).text('Processing...'); //Process the request $.post('modules/action.php', data, function(ajax_response){ //ajax response returns whatever the called script is written to return $('.placeholder_div').html(ajax_response); //Got want we wanted...free up the buttons btnProcessing = false; //re-set the button text back to the original value $(e.target).text(initial_text); });//$.post }//if ($(e.target).hasClass }//if ($(e.target).is('.button') })//$(document).click(function(e) });//ready Works great.
  13. I am glad I pursued this. I learned several big new things which will help me get to that ever elusive "next level", it's like a never ending ladder. Attaching the click event to the Document Object solved another issue for me. I was having trouble with dynamically created elements and attaching click events with one script. Sometimes I had to create another javascript file to attach click handlers to the dynamically created elements. I would then have to include that script in my PHP function or PHP script. It was getting confusing to keep things straight. This solved all those problems because the click handler works great on dynamically created content elements. The data-key="value" attribute is clearly explained in a HTML5 book I have, but the author was explaining how to set dimensions of pop-ups with it, so I wasn't interested in pop up windows and skipped over those few (now very important) pages. I gotta learn to pay better attention when reading. Thanks for the nudge in the right direction!
  14. Once again HartleySan, Thank you for you time! I couldn't just leave it the way it was knowing that you suggested a better way. With some sleep, time to think, research things a little, and comparing to your javascript example, I think I have it! It works perfectly. I monitored things closely each step in firebug console and confirmed values with console.log(). I clicked away like a madman and no problems. The flag variable allowed me to eliminate the functions and function calls previously used to toggle the text values...sweet! Here is my latest code: $(document).ready(function(){ //Flag variable to track state of clicked button var btnProcessing; //Event attached to the document object $(document).click(function(e){ //target is the button clicked. e is the event if ($(e.target).is('.button')){ //Get the clicked button's default text var initial_text = $(e.target).text(); //Get the html data attribute from the clicked button var action = e.target.getAttribute("data-action"); //Set up the ajax data variable to select the correct switch case in action.php var data = 'action=' + action; //If class of "button" and not currently processing another request if ($(e.target).hasClass( "button" ) && !btnProcessing) { //Flag to denote processing btnProcessing = true; //Visual feedback on button $(e.target).text('Processing...'); //Process the request $.post('modules/action.php', data, function(ajax_response){ //ajax response returns whatever the called script is written to return $('.placeholder_div').html(ajax_response); //Got want we wanted...free up the buttons btnProcessing = false; //re-set the button text back to the original value $(e.target).text(initial_text); });//$.post }//if ($(e.target).hasClass }//if ($(e.target).is('.button') })//$(document).click(function(e){ });//ready Now all I do is always use .button as the class name for a button (a no brainer) and use html data-key="value" to feed to the PHP ajax controller script and I never have to reinvent the wheel to process my ajax calls. I think I should be able modify this code to work more generically too. I am thinking about when I attach a click event to a list item. Thanks for your help! This is a cool piece of code! If you see anything that should be changed let me know.
  15. I spent some time with your suggestions and I am half way there. Here is the HTML: <script src="js/admin_dashboard.js"></script> <?php include('includes/mysqli_connect.inc.php'); //All button ids will correspond to the associated action called in the jquery click handler echo'<div class="admin_buttons_div"> <button id="get_user_table" data-action="get_user_table" class="button">View Users</button> <button id="get_dmd_info" data-action="get_dmd_info" class="button">Get DMD Report</button> <button id="get_dmd_entry" data-action="get_dmd_entry" class="button">DMD Entry</button> <button id="button_4" class="button">button_4</button> <button id="button_5" class="button">button_5</button> <button id="button_6" class="button">button_6</button> </div>'; //This is our place holder div to contain our ajax responses echo'<div class="placeholder_div"></div>'; And here is the refactored jquery: //admin_dashboard.js $(document).ready(function(){ $('.button').on('click',function(evt){ //disable the other buttons temporarily $('.button').prop( "disabled", true ); //Get a reference to the clicked button var button = this; //Get the data attribute from the clicked button var action = button.getAttribute("data-action"); //Set the ajax data and the action variable for the called php script - action.php var data = 'action=' + action; //Get the clicked button's default text var initial_text = $(this).text(); //Button was clicked...give the user some visual feedback processing(button); //Send the ajax data request to the action.php script $.post('modules/action.php', data, function(ajax_response){ //ajax response returns whatever the called script is written to return $('.placeholder_div').html(ajax_response); //re-enable the other buttons now $('.button').prop( "disabled", false ); //Set the button text back to it's default value $(button).text(initial_text); });//$.post });//End click function //Give the user some visual feedback after a button click function processing(button){ $(button).text('Processing...'); } //Reset the button text to the default static text set in the calling script function done_processing(initial_text){ $(button).text(initial_text); } });//ready I couldn't get the flag to work correctly for me, I could still click like a madman on the buttons and cause too much processing at once. I will revisit that when I have more time. For now, it works and I have to move on. I do really like the data-key="value" attribute concept. It gives us more flexibility when integrating ajax calls into the fold. I played around with it and see many places in my other code where it would have helped big-time. For instance in a case where I need to get the value from, say for example, a <li> which was generated from a mySQL fetch and is made clickable with jquery: <li id="part-num" class="part-num_422">122-12345AZS</li> And then I have to break down the class in jquery to extract the id of the part number, instead I can use this: <li id="part-num" class="whatever" data-part-id="'. $php_variable .'" >122-12345AZS</li> Now it is a snap to grab the id and process as needed. Or is this a bad practice to set the data-key="value" dynamically from a database with PHP?
  16. Thank you HartleySan for the advice! I had to Google the data-id attribute as I have never, until now, had a real world application for it...or I didn't know how to use it correctly so I didn't. Good stuff. I will refactor my code and post the results. I probably should use straight javascript, but I guess I just got lazy and comfortable with jquery.
  17. I found that if a user started clicking buttons like a madman, the system would fail. My solution was to disable the other buttons until the ajax response was completed, immediately after that I re-enable the buttons. Now it is impossible to click too fast. $('.button').on('click',function(evt){ //disable the other buttons temporarily $('.button').prop( "disabled", true ); //Get a reference to the clicked button var button = $(this); //Get the clicked button's default text var initial_text = $(this).text(); //Get the button's id which is also the php $_POST['action'] variable in action.php var action = $(this).attr('id'); //Button was clicked...give the user some visual feedback processing(button); //Set the action variable for the called php script - action.php var data = 'action=' + action; //Send the ajax data request to the action.php script $.post('modules/action.php', data, function(ajax_response){ //ajax response returns whatever the called script is written to return $('.placeholder_div').html(ajax_response); //re-enable the other buttons now $('.button').prop( "disabled", false ); //Set the button text back to it's default value $(button).text(initial_text); });//$.post });//End click function
  18. When I am developing an application for a client, I run into situations where I have to engineer what seems to be the best idea that I can come up with at the time. Of course that is the whole game right? I work alone and have no other programmer buddies to bounce a code idea off of, so I wing it and hope for the best. Recently an application specification calls for a "row of buttons" across the top of an admin page that also has tabbed "main navigation" links to non-admin application stuff. The idea is to make it "so simple a caveman could do it" by seeing the desired functionality at a glance and clicking a button to refresh the page via ajax to get the desired content. This is where the question comes in. I started with a jquery button click handler for each button that contained the associated ajax call. Ten buttons meant 10 separate click functions with an anonymous ajax function call. It seemed like way too much code to accomplish the mission with a lot of places for things to go wrong. It also did not at all adhere to the DRY axiom one bit. So I am trying something to streamline the process. Here is the HTML for the buttons: //All button ids will correspond to the associated action called in the jquery click handler echo'<div class="admin_buttons_div"> <button id="get_user_table" class="button">View Users</button> <button id="get_dmd_info" class="button">Get DMD Report</button> <button id="get_dmd_entry" class="button">DMD Entry</button> <button id="button_4" class="button">button_4</button> <button id="button_5" class="button">button_5</button> <button id="button_6" class="button">button_6</button> </div>'; //This is our place holder div to contain our ajax responses echo'<div class="placeholder_div"></div>'; Here is the jquery code: //admin_dashboard.js $(document).ready(function(){ $('.button').on('click',function(evt){ //Get a reference to the button var button = $(this); //Get the clicked button's default text var initial_text = $(this).text(); //Get the button's id which is also the php $_POST['action'] variable in action.php var action = $(this).attr('id'); //Button was clicked...give the user some visual feedback processing(button); //Set the action variable for the called php script - action.php var data = 'action=' + action; //Send the ajax data request to the action.php script $.post('modules/action.php', data, function(ajax_response){ //ajax response returns whatever the called script is written to return $('.placeholder_div').html(ajax_response); //Set the button text back to it's default value $(button).text(initial_text); });//$.post });//End click function //Give the user some visual feedback after a button click function processing(button){ $(button).text('Processing...'); } //Reset the button text to the default initial text function done_processing(initial_text){ $(button).text(initial_text); } });//ready The data sent in the ajax function is the button's id and is received by action.php as a post variable that is used in a switch to select either a php function or a php script that returns a response and populates the the place holder div with whatever the clicked button was supposed to do. Here is the scaled down relevant php code: include('../includes/mysqli_connect.inc.php'); $action = isset($_POST['action']) ? $_POST['action'] : NULL; // Determine what action to take based on $action sent by js click function switch ($action) { case 'get_user_table': echo display_users(); break; case 'get_dmd_info': display_dmd_info(); break; case 'get_dmd_entry': display_dmd_form(); break; // Default is to include the main page. default: $page = 'main.inc.php'; $page_title = 'Site Home Page'; break; }//end switch ?> I actually have many more cases to the switch because it is acting as a controller for all of my ajax function calls. The code works very well and seems real easy to add buttons, cases and functions to achieve the desired functionality. The user clicks the button, gets visual feedback via button text changing to "Processing..." then the content is updated and the button text reverts back to the original value. Seems like a good idea to me. The main application framework is built on the concepts presented in Chapter 2 "Modularizing a Web Site" with a MVC flavor tossed in all coded in a procedural fashion. So...Is one programmer's clever idea another programmer's spaghetti code? Is this a bad idea? Thanks for any suggestions or opinions.
  19. Yeah...no problem there, they will hold a clinic for Michigan. The Wolverines are in bad shape. I think Brady Hoke's days are numbered. I do a lot of A/V work in the team's building; a very impressive set up, but it doesn't help them win games as of lately. I am not a huge Michigan fan, I am more of a Michigan State guy myself. Of course the Buckeyes whooped us good.
  20. Great post HartleySan! I see ads for this type of position from the University Of Michigan and U of M Hospital in Ann Arbor, MI. It sounds like a great job, but way, way out of my league. I work in Ann Arbor in my day job and find that this city is hungry for programmers/developers and IT people in general. I will keep plugging away and maybe someday I will have the skills and the intestinal fortitude to apply for such a position. Thanks HartleySan for all the time you put in here!
  21. Well Howdy Buttercream Cupcake! I wondered how you were. I haven't been posting any questions lately and I don't feel like I have the experience to answer questions yet, so...I lurk and learn. I have been involved in some really cool training/testing web apps for the automotive industry. The application is used in a competition format. The project is basically questions with multiple choice answers (selected via radio buttons). The participant is presented one question at a time and a new question presented depending on what answer they selected. The cool part is I used the lesson in chapter 1 of "PHP Advanced" concerning the adjacency list data table method. This way each top level parent question can go as many levels deep as my client wants, 1 level or many without me having to "hard code" a set max depth level. This allows for a "choose your own adventure" type of an experience for the participants. Each answer has a score weight, if you go down a bad path with your answer selections, the answers have a lower or negative score value. The participant with the highest score wins and gets some major perks from the company. I also set up live scoring for the client. As the participants are taking the test in a hotel conference room, an HTML table with participants names and their current scores is projected on to a screen. As the scores change in the database it is updated on the screen. Participants can watch themselves sink or swim in real time, it adds extra pressure to test their mettle. It was recently used in a regional completion and performed flawlessly...whew! Chapter 1 of the advanced book made it all possible because I had to have a way to let the client select "depth levels" dynamically. Thanks Larry! I am also creating a knowledge base wiki type of an web application for my "day job" employer. We are an Audio/video integrator for big business, universities and k-12 educators. The company had no way to save company knowledge in an electronic format accessible from the internet. I saw that as an awesome opportunity to code an application from scratch that will not only be very useful, but will add another accomplishment to my programming portfolio. I keep seeing software application solutions for real world problems and it is fun creating them. I am not yet ready to leave my day job to pursue a full time programming/web developing career and not sure that I ever will. I love my day job and the people I work for/with, so I develop in the evenings. I am also a Raspberry Pi addict. Maybe if I posted more often I wouldn't have long winded posts like this...lol. Thanks to Larry, HartleySan, and all the other folks who share valuable knowledge on this site, it has truly changed my life.
  22. Ah ha, that makes sense. I knew there had to be a very specific reason. Thanks Larry. Thanks HartleySan for all your input. I appreciate all your time and input you lend to this forum.
  23. Thanks HartleySan for the reply. I studied that thread, but can't seem to apply it to this exact situation. Maybe I am missing something. I wrote the if/else into a switch as follows: switch($type){ case 'application/json': $output = json_encode($data); break; case 'text/csv': $output = ''; foreach($data as $v){ $output .= '"' . $v . '",'; } $output = substr($output, 0, -1); break; case 'text/plain': $output = print_r($data, 1); break; default: $type = 'text/plain'; $output = 'This service has been incorrectly used.'; } I haven't tested the code, this is just for example. I can't find a reason to not write it this way as opposed to an if/else conditional. Surely speed can't be the issue or the switch statement above it in the original code would be an if/else. There are as many cases in my switch as there is in the original code's switch, so the number of conditions sure can't be a reason to use if/else. I am thinking that the switch in the original code could of course be easily rewritten as an if/else and function just fine. This is just an OCD thing for me now. I have to know why (in this exact case) Larry chose to do it the way he did. There must be a very specific reason. Assuming my rewrite of the if/else is correct, which way would you be inclined to write this code? Maybe I should go back to chapter 2 and shut up...lol.
  24. I am actually still beating chapter 2 to death, but started looking ahead to see what the future chapters are all about. In chapter 10, page 349 I find this script 10.5 (aka 11.5 in my book) that uses a switch to check which format was passed through the POST. Starting on line 34 of the code, Larry uses an if/else conditional to select the format based on what the requester submitted. My question is this, why would we not use another switch statement instead of the if/else? The switch looks cleaner and makes it easier to see at a quick glance what is going on. Not that it is confusing the way the code is written, it just isn't as clean and straight forward. I am just wondering if there is a reason to not use a switch in this specific case even though we are checking the value of the same variable throughout the if/else. In my learning, I like to see how other programmer's were thinking when a decision was made to do it "this was, or that way". Here is the code in question: <?php # Script 10.5 - service.php // This script acts as a simple Web service. // The script only reports back the data received, along with a bit of extra information. // Check for proper usage: if (isset($_POST['format'])) { // Switch the content type based upon the format: switch ($_POST['format']) { case 'csv': $type = 'text/csv'; break; case 'json': $type = 'application/json'; break; case 'xml': $type = 'text/xml'; break; default: $type = 'text/plain'; break; } // Create the response: $data = array(); $data['timestamp'] = time(); // Add back in the received data: foreach ($_POST as $k => $v) { $data[$k] = $v; } // Format the data accordingly: if ($type == 'application/json') { $output = json_encode($data); } elseif ($type == 'text/csv') { // Convert to a string: $output = ''; foreach ($data as $v) { $output .= '"' . $v . '",'; } // Chop off the final comma: $output = substr($output, 0, -1); } elseif ($type == 'text/plain') { $output = print_r($data, 1); } } else { // Incorrectly used! $type = 'text/plain'; $output = 'This service has been incorrectly used.'; } // Set the content-type header: header("Content-Type: $type"); echo $output;
  25. Yeah, but it will remind me where I came from. I will be around here as long as Larry has this forum up, it is one of my favorite places on the web. Thanks Antonio, I will press onward.
×
×
  • Create New...