JQuery: Pro Tip Toggle Visibility

I’ve been coding with JQuery for a very long time, so I can’t believe I didn’t know this…

When I wanted to show/hide elements I would always use .is(:visible) and show or hide the object accordingly.

Yesterday, while looking for something else I found .toggle.

So:



$(this).toggle();

//will show or hide an element

I imagine a lot of you are thinking, “Well yeah…”

Advertisements

JQuery/HTML: Handling events for elements created after initial page load.

My regular readers already know that I add a lot of stuff to my pages programmatically using PHP. Naturally much of this code is added after the initial page load.

I used to defeat this by loading in the scripting with the new elements, but that’s very tedious, and honestly, sloppy.

The issue is that new elements aren’t registered with the Document Object Model (DOM) set up when the page loads.

To get around that you can sort of “pre-register” these elements using JQuery’s .on method.

Here’s the syntax:


$(document).on([event],[selector],function(e) {

//do your stuff here

});

Here’s a working example from an actual piece of code I’m working on.

In this example I’m posting data to a php script when the target element (id=”edname_1″) loses focus, provided it doesn’t match what’s there already. I do this by loading the contents of the control into txtval on the focusin event.

var txtval = '';    //global variable.
		
		
		    $(document).on("focusin","#edname_1",function(e){
		    	
		    	txtval = $(this).val();   //loads global
		    	
		    });
		
			$(document).on("focusout","#edname_1",function(e){
				
					if ($(this).val() == txtval) {
						console.log("doing nothing");
						return;
						
					}
				
					if($(this).val().length < 1) {
						
						alert("This shouldn't be blank");
						return;
						
					}
				console.log("updating");
				$.post('PHP/updateftable.php', {field: $("#activefld").val(), val: $(this).val()}) 
                                            
                                        /*
                                         In order to avoid having to add the db table primary key of the row I want to update to every element I add to the div,                         
                                         I created a hidden field and placed that key as the value.
                                         */

				.done(function(data){
					
					console.log(data);   //checks the output.
							
				});
				
	
			});
		


This example is from a piece of actual code for a project in development, so there’s some exception handling, etc. I haven’t done yet.

Solving Multi-Lingual Keyboard Woes

Any one who has used a Windows computer with their location/language set to Canada has likely experienced this issue.
Suddenly, for no apparent reason, you end up typing French characters instead of the ones you want.

It happens all the time, you are typing, and accidentally enter some funny key stroke combination (or are doing so because its required in whatever application you’re in) and suddenly slashes are question marks, curly brackets are carets and your brain starts to melt with frustration.

When I played World of Warcraft one of my guildmates was from Quebec…we were often assailed by French invectives when we suddenly saw him typing accents and other characters common in the French language.

I was coding today when I noticed several times that my keyboard changed to French. This is a new machine at work, but I’ve been using it for more than a week with no problem.

Not able to type {} (an essential programmer thing) I went on a quest to ensure this never happens to me again.

I’ve seen other people looking for solutions on this, so here’s how to get rid of this on a Windows 7 machine once and for all.

Control Panel->Region and Language->Change Keyboards

Here you can click on languages and remove them:

keybrdlang

I’ve already removed the languages, but I found that I couldn’t switch away from the French layout.
So, I went back and this time I clicked on the tab Advanced Key Settings…and here I found the culprit!

I forget what the default “Switch to French Layout” key combination was, but I set it to none. I then set to switch to the US layout with CTRL-0.

keylangchange

Clicked Apply and everything was cool…

JQuery: Add Rows and Columns to Tables Programmatically

This turned out to be a bit of a bear to search for exactly what I wanted, in such a way that I understood it…so I’m posting here.

The Problem

To create a table which the user could add columns or rows as they required.
New rows must contain the columns added earlier.

There is no requirement to isolate additional columns to specific rows.

The Solution

The example below uses a class selector as there are several tables (also added programmatically).

Adding a column.


$(".sbutc").click(function(e){
		
		var tid = this.id;
		var bid = tid.replace('sbutc_','stable_');   //This points to the appropriate parent table

                //first, I need to know how many rows there are so I can get the number of columns in the last one (skipping header rows)
                //Note that I point to the tbody object,  if you don't use these,  that should be the table id.

		var rows = document.getElementById(bid).getElementsByTagName("tbody")[0].getElementsByTagName("tr").length;
		

		var cols = $('#' + bid + ' tr:nth-child(' + rows + ') td').length;   //get's the number of columns in the last row
		console.log('cols: ' + cols);
		
		$("#" + bid).find('tr').each(function(){                            
						
                $(this).find('td').eq(cols-1).after('<td>new cell added</td>');      //adds the new cell. 
   		}); 

               /*
                You'll note that I subtract 1 from the column count when adding the column.  This is because when pulling the count, it starts with 1, while 
                object indexes always start at 0
               */

This adds the row.


$(".sbutr").click(function(e){
		
		var tid = this.id;
		var bid = tid.replace('sbutr_','stable_');
		var rows = document.getElementById(bid).getElementsByTagName("tbody")[0].getElementsByTagName("tr").length;
		var cols = $('#' + bid + ' tr:nth-child(' + rows + ') td').length; 
		
                
		
		var apstring = '<tr>';             //sets up the string used in the append statement
		
		for(var i=1;i<=cols;i++) {        //adds a td element for each row detected above and appends it to the apstring
			
			apstring += '<td ondrop="drop(event)" ondragover="allowDrop(event)">-</td>';
			
		}
		
		apstring += '</tr>';              //very important!
		
		$('#' + bid + ' > tbody:last').append(apstring);   //append the row to the bottom of the table
		
		
		
	});



I will post a link so you can see it in action when I get a chance (behind a firewall currently).

Set Selected Option when building HTML Select List in PHP

Wow…you know…the hardest thing about this whole exercise was coming up with a title for this post!

As you’ve gathered from previous entries, I build a lot of my HTML pages in PHP scripts.

When you are building a select list (dropdown, pulldown, picklist) from a database, how do you ensure that the user sees the value that’s in the database?

You could do it using a switch case routine and build your options list in it’s entirety for each option, or you could do it this way.

Scenario, you have an ENUM field in your database that you want to give the user the ability to edit. You also think its very handy for the user to know what’s actually in the database, so you have the select element default to the database value.

Short answer:

Use string replace (str_replace) to add the property selected to the appropriate option.


$options = str_replace('value="G"','value="G" selected',$options);

And now for the long version:

<?php
/*
A bunch of code that creates a dataset from a database and puts it in $row[]
*/

$row['ftype'] = 'T';      //you can change these to test the code.
$row['fname'] = 'Text';

$options = '<option value="0">Select a Type</option>';
$options .= '<option value="D">Date</option>';
$options .= '<option value="G">Group</option>';
$options .= '<option value="T">Text</option>';

switch ($row['ftype']) {

    case "D": 

        $options .= str_replace('value="D"','value="D" selected',$options);
        break;

   case "G":

      $options .= str_replace('value="G"','value="G" selected',$options);
      break;

  case "T":

     $options .= str_replace('value="T"','value="T" selected',$options);
     break;

  default:
     //nothing to do here
     break;
}

$output = '<html>';
$output .= '<body>';
$output .= '<form id="f1" method="post" action="">';
$output .= '<input type="text" id="f1a" name="f1at" value="'.$row['fname'].'"><br>';

$output .= '<select id="f1b" name="f1b">'.$options.'</select>';
$output .= '</form>';    //pro tip:  type this line immediately after typing the <form> line so you don't forget.

$output .= '</body></html>';
echo $output;

Some of you may have noticed that there is a much easier way to do this if things are as straightforward as in the example.
Simply concatenate the value used in the switch case. This will work great, unless you have additional properties or different formatting in the option tag.


 $options .= str_replace('value="'.$row['ftype'].'"','value="'.$row['ftype'].' selected',$options);

Happy coding…