www.webdeveloper.com
Results 1 to 9 of 9

Thread: Dynamic Checkboxes in a form

  1. #1
    Join Date
    Apr 2009
    Posts
    35

    Dynamic Checkboxes in a form

    I place this topic in HTML because so far it seems like the MYSQL, PHP, and JavaScript aspects of my code work. The issue seems to be in the checkboxes of my form since they are faded in Firebug and not relaying any results. The goal is to create a dynamic form that takes data from MYSQL and creates a form for users to modify certain aspects of their gallery. I have two dropdown menus where the second menu's values are based on the first menu. The user is to select the photos from his gallery that he wishes to affect from the dropdown menus. Then once the user submits the form, the Ajax sends the form data to PHP for processing.
    The complication, I think, is that I'm trying to have non-traditional checkboxes. The hope is that the user will only need to click on a bordered display of his photo and its title/description. The user clicks in the bordered area and the background changes color to indicate it is selected.
    Currently the visual works but I think there is an issue with how I am creating the checkboxes since Firebug fades the <input type="checkbox" value="*some number*" name="pix[]" id=="*some number*" > of each.
    Here is the script so far.

    PHP Code:
    <?php
    require"connection.php";
    if(!isset(
    $_SESSION)) {session_start();}
    ?>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head></head>
    <body>
    <link rel="stylesheet" href="../css/main.css" type="text/css" />
    <script type="text/javascript">
    $(document.body).ready(function () {
        $(function () {
         
          var main_obj_id = 'on_off';
          var on_class = 'on_off_on';
          var off_class = 'on_off_off';        
              
            $('#' + main_obj_id).click(function () {
                  if ($(this).is('.' + on_class)) {
                      
                     $(this).removeClass(on_class);
                     $(this).addClass(off_class);
                     $(this).html('OFF');
                      
                  } else {
                      
                     $(this).removeClass(off_class);
                     $(this).addClass(on_class);
                     $(this).html('ON');                  
                  
                  }
            });
        });
    });
    function setOptions(chosen){
    var selbox = document.multipix_form.table;
    selbox.options.length = 0;
    if (chosen == " ") {
        selbox.options[selbox.options.length] = new Option('No database selected',' ');
        }
    if (chosen == "1") {
        <?php
        $cat
    =10000+$_SESSION['userid'];
        
    $sql "SELECT * FROM albums WHERE category = ".$cat;
        
    $query mysqli_query($con$sql);
        while (
    $rs mysqli_fetch_array($queryMYSQLI_ASSOC)) { ?>
        selbox.options[selbox.options.length] = new Option('Move Photo To "<?php echo $rs["title"]; ?>" Album','<?php echo $rs["aid"]; ?>');
        <?php ?>

        }
    if (chosen == "2") {
        selbox.options[selbox.options.length] = new Option('Turn Rating ON for selected photos','1');
        selbox.options[selbox.options.length] = new Option('Turn Rating OFF for selected photos','0');
        }
    if (chosen == "3") {
        selbox.options[selbox.options.length] = new Option('Select Photos To Delete','1');
        }
    }

    $('#multipicupdate').click(function() {
            $.ajax({
              type    : "POST",
              url    : "php/picformdata.php",
              data    : $("#multipix_form").serialize(),
              datatype : 'html',
              success: function(data) {
                $('#message_profile').html(data);
            }
        });
    });

    </script>
    <div id="multi_pic">
    <fieldset class="multipic_options">
    <form id="multipix_form" name="multipix_form" action="#">
    <select id="optone" name="optone" size="1" onChange="setOptions(document.multipix_form.optone.options[document.multipix_form.optone.selectedIndex].value);">
    <option value=" ">Please select below</option>
    <option value="1">Move Photos To Album</option>
    <option value="2">Set Photos Rating</option>
    <option value="3">Delete Photos</option>
    </select>
    <select id="table" name="table" size="1">
        <option value=" " selected="selected">No database selected</option>
    </select>
    </fieldset>
    <fieldset class="pic_listing">
    <?php

    $sql
    "SELECT * FROM photos WHERE owner_id='".$_SESSION['userid']."'";
    $query mysqli_query($con$sql);
    while (
    $rs mysqli_fetch_array($queryMYSQLI_ASSOC)) 
        {
    ?>
            <input type="checkbox" id="<?php echo $rs["pid"]; ?>" name="pix[]" value="<?php echo $rs["pid"]; ?>" >
    <label for="<?php echo $rs["pid"]; ?>">
                <img class="mod_thumb" src="<?php echo $rs["filepath"]; ?>T/<?php echo $rs["filename"]; ?>"><BR>TITLE: 
            <?php 
                
    if (!$rs['title'])
                    {
                        
    $rs['title']="None Yet";
                    }
                echo 
    $rs["title"];
            
    ?>
            <BR>DESCRIPTION: 
            <?php 
                
    if (!$rs['caption'])
                    {
                        
    $rs['caption']="None Yet";
                    }
                echo 
    $rs["caption"];
            
    ?>
            </label>
            <?php
        
    }

    ?>
    </fieldset>
    <P><input type="button" value="Save changes to this photo" id="multipicupdate"></P></form></div>

    </body>
    </html>
    The CSS has the checkbox inputs as display:none so that the little squares don't show up
    Visually this code is working properly. But I think none of the checkbox values when checked are being serialized due to the CSS display:none. I hope I'm incorrect because I want this form to work with the look it has. Any help will be greatly appreciated.

  2. #2
    Join Date
    May 2014
    Posts
    1,051
    Generally, display:none should be used with an eyedropper if at all. You are usually much better off hiding them underneath something, or chopping them off with overflow and a negative indent, or some other method.

    Though linking in the jquery-tardery from outside might help at least make PHP's job easier... as would swinging an axe at opening and closing PHP a dozen times for no good reason other than trying to make the parser work harder and the code less clear. Likewise you should probably be using a SWITCH/CASE not multiple IF so you aren't wasting time checking for values you may already know are false.

    Also, if you don't care about IE9/earlier you could probably use the :checked state with the adjacent sibling selector instead of dicking around with classes in JS... and if you did care about it, you could add it with a polyfill for the older browsers only saving yourself some scripting. In a lot of ways you've got precisely what I call "jQuery doing CSS' job"

    I'm also wondering why you even have AJAX involved, much less the mouse-only action for it... Do you have a normal non-scripted submit fallback even in there? Remember, make it work without scripting FIRST, THEN enhance it with scripting.

    Looking deeper, you have the fieldset AROUND The form, instead of inside it... I'm assuming that's a typo as it doesnae make much sense. Likewise the DIV around it for nothing (there's little you can do to a DIV you can't do to the FORM itself), paragraph around a non-paragraph element (A single input), oddball SIZE declaration on SELECT (REALLY reducing it's usefulness to nil)... might help to actually have labels on those select rather than trying to use an empty OPTION as the label...

    I'd probably also not blindly trust the [] in the name attribute to pull the associations correctly.

    Oh, and is $rs["pid"] a number value? You're dumping it into ID and ID's can't start with numbers.

    Likewise you're using mysqli, STOP blindly pasting values -- even ones you assume should be ok like from $_SESSION -- into your query strings -- honestly the way you're using the query strings there's no reason to be wasting time putting them in a variable either.

    Might also help if you had a DOCTYPE in there, at the very least put a space between require and the string (or used the proper function model since not having the () is allegedly going away soon)... and of course if you're not using the variable parsing feature switching to single quotes is always a good idea. Don't forget your MEDIA attribute on the CSS link either, which is also misplaced since there is no such thing as a LINK tag inside BODY. Malformed <head> and quirks mode can always have unpredictable results not just in rendering, but in scripting functionality as well.

    You know, looking at this, I'd consider using a class selection to set the second select to show, instead of replacing it's contents via scripting. Put them all on the DOM, use a class swap on the parent fieldset to change which one is showing/active.

    So I'd probably have written that something more like this:
    Code:
    <?php
    
    require('connection.php');
    require('template.php');
    session_start();
    session_regenerate_id();
    
    template_header('Image Control Demo');
    
    echo '
    	<form id="multiPix" action="updateMultiPix.php">
    	
    		<fieldset id="multiPix_options">
    		
    			<label for="multiPix_action">With Selected Photographs:</label>
    			<select id="multiPix_action" name="action">
    				<option selected="selected"></option> 
    				<option>Move</option> 
    				<option>Enable Ratings</option>
    				<option>Disable Ratings</option>
    				<option>Delete</option>
    			</select>
    			
    			<label for="multiPix_destination" class="multiPix_destination">
    				Destination:
    				<select id="multiPix_destination">
    					<option selected="selected"></option>';
    				
    $statement = $con->query('
    	SELECT aid, title
    	FROM albums
    	WHERE category = ?
    ');
    $statement->bindParam('i', 10000 + $_SESSION['userid']);
    $statement->bindResult($id, $title);
    $statement->execute();
    while ($statement->fetch()) echo '
    					<option value="', $id, '">', $title, '</option>';
    $statement->close();
    				
    echo '
    				</select>
    			</label>
    			
    		</fieldset>
    		
    		<fieldset id="multiPix_pictures">';
    		
    /* REALLY starting to remember why I prefer PDO here... */
    
    $statement = $con->query('
    	SELECT pid, title, filepath, fileName, caption
    	FROM photos
    	WHERE owner = ?
    ');
    $statement->bindParam('i', $_SESSION['userid']);
    $statement->bindResult($id, $title, $filePath, $fileName, $caption);
    $statement->execute();
    while ($statement->fetch()) {
    	$fullId = 'multiPix_picture_' . $id;
    	echo '
    	
    			<input
    				type="checkbox"
    				id="', $fullId, '"
    				name="pix[', $id, ']"
    				value="', $id, '"
    			/>
    			<label for="', $fullID, '">
    				<img
    					src="', $filePath, 'T/', $fileName, '"
    					alt="', $caption, '"
    				/><br />
    				TITLE: ', (empty($title) ? 'None Yet' : $title), '<br />
    				Description: ', (empty($caption) ? 'None Yet', $caption), '
    			</label><hr />';
    }
    $statement->close();
    
    echo '
    
    		</fieldset>
    
    		<div>
    			<input
    				type="submit"
    				value="Save Changes to these Photos"
    				id="multiPic_update"
    			/>
    		</div>
    	</form>
    	
    	<script type="text/javascript" src="multiPic.js"></script>';
    
    template_footer();
    
    ?>
    Hiding and showing that second select as needed -- forgoing the need to even have it show when it's not used. The template.php would have template_header($title) and template_footer() outputting everything from </head><body> upwards in _header with <title>$title</title> and _footer outputting everything after the content.

    I'm gonna toss together a quick demo of the CSS and JS I'd use based on that code's output... gimme a while.
    Last edited by deathshadow; 08-11-2014 at 12:48 PM. Reason: minor goof, nested input in label which won't work for :checked
    Java is to JavaScript as Ham is to Hamburger.

  3. #3
    Join Date
    May 2014
    Posts
    1,051
    Alright I tossed up a working demo of how I'd approach that here:
    http://www.cutcodedown.com/for_other.../template.html

    as with all my examples the directory:
    http://www.cutcodedown.com/for_others/killinspre/form

    Is wide open for easy access to the gooey bits and pieces. It's a wee bit larger than what you had in terms of the scripting, but it does far, far more.... for example there's a polyfill for the fact that IE and Chrome are too stupid to let you click on an IMG inside a LABEL and actually have it focus the associated INPUT -- laughable since in both it does work with any plaintext

    It also adds some validation code making it easy to add your ajax submit, or just let it drop through to a normal submit. I also added code to make it gracefully degrade so you could/should make it work scripting off. You take all that out, it's effectively the same code size even with a 'decent sizes' set of libary functions added to the mix. jQuery? BAH!

    I also put it all in a nice safe anonymous function (wait for it... wait for it...) preventing the possibility of namespace conflicts.

    I put a verbose/commented version of the scripting here:
    http://www.cutcodedown.com/for_other...iPicVerbose.js

    ... and a updated PHP source equivalent here:
    http://www.cutcodedown.com/for_other...Version.source

    Hope this helps.
    Java is to JavaScript as Ham is to Hamburger.

  4. #4
    Join Date
    Apr 2009
    Posts
    35
    @deathshadow, looks great, thanks. However when I try to use the coding from the dbVersion, I get a "Fatal error: Call to a member function bindParam() on a non-object".
    Last edited by killinspre; 08-12-2014 at 09:42 AM.

  5. #5
    Join Date
    Aug 2004
    Location
    Ankh-Morpork
    Posts
    19,408
    I'm guessing where DS used this...
    PHP Code:
    $statement $con->query
    ...he actually intended this...
    PHP Code:
    $statement $con->prepare
    "Please give us a simple answer, so that we don't have to think, because if we think, we might find answers that don't fit the way we want the world to be."
    ~ Terry Pratchett in Nation

    eBookworm.us

  6. #6
    Join Date
    Apr 2009
    Posts
    35
    tried $con->prepare as well and get same error msg. even tried bind_param instead of bindParam in case it made a difference...it didn't

  7. #7
    Join Date
    Apr 2009
    Posts
    35
    Nevermind. The owner after WHERE is supposed to be owner_id LOL. Error all gone

  8. #8
    Join Date
    May 2014
    Posts
    1,051
    Quote Originally Posted by NogDog View Post
    I'm guessing where DS used this...
    Good catch, what I get for originally typing it in the quick reply box on a laptop keyboard

    @killinspre -- good to hear you got it sorted. It's annoying when you have a small query error like that -- you want to blame the later code; good tip on that, when you get a 'non-object' error in PHP on a database operation, check the SQL error logs as it's probably actually a query error that's explained there.

    In general actual SQL error reporting in PHP is a joke...
    Java is to JavaScript as Ham is to Hamburger.

  9. #9
    Join Date
    Aug 2004
    Location
    Ankh-Morpork
    Posts
    19,408
    Quote Originally Posted by deathshadow View Post
    In general actual SQL error reporting in PHP is a joke...
    I should probably create an editor macro to do...
    PHP Code:
    if($stmt == false) {
        throw new 
    Exception(print_r($stmt->errorInfo(), 1).PHP_EOL.$sql);

    "Please give us a simple answer, so that we don't have to think, because if we think, we might find answers that don't fit the way we want the world to be."
    ~ Terry Pratchett in Nation

    eBookworm.us

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
HTML5 Development Center



Recent Articles