In this chapter, we will cover:
Executing functions when a page has loaded
Binding and unbinding elements
Adding events to elements that will be created later
Submitting a form using jQuery
Checking for missing images
Creating a select/unselect all checkbox functionality
Capturing mouse movements
Creating keyboard shortcuts
Displaying user-selected text
Dragging elements on a page
Events are actions that execute some JavaScript code for producing the desired result. They can be either some sort of manipulation of a document or some internal calculations.
Since different browsers handle events differently, it takes a lot of effort to write JavaScript code that is compatible with all browsers. This chapter will help you understand event handling and explore related methods of jQuery that can make scripts compatible on different browsers. You will learn to work with the keyboard and mouse events. Advanced event handling topics like dragging and keyboard shortcuts are also discussed.
AJAX applications make extensive use of JavaScript to manipulate the content and the look and feel of web pages. Web pages should have the DOM loaded before any JavaScript code tries to perform any such modification on it.
This recipe will explain how to execute the JavaScript after the content has been loaded and the DOM is ready.
Create a file and name it as
domReady.html
.To run any JavaScript code only after the DOM has completely loaded, write it between the curly braces of
.ready()
method:<script type="text/javascript"> $(document).ready(function () { // code written here will run only after the DOM has loaded }); </script>
jQuery ensures that code written inside .ready()
gets executed only after the DOM is fully loaded. This includes the complete document tree containing the HTML, stylesheets, and other scripts. You can, therefore, manipulate the page, attach events, and do other stuff. Note that .ready()
does not wait for images to load. Images can be checked using the .load()
method, which is explained in a separate recipe in this chapter.
If .ready()
is not used, the jQuery code does not wait for the whole document to load. Instead it will execute as it is loaded in the browser. This can throw errors if the written code tries to manipulate any HTML or CSS that has not been loaded yet.
In the previous example code we used an anonymous function with .ready()
. You can also pass a handler instead of the anonymous function. It can be done as follows:
<script type="text/javascript"> $(document).ready(doSomething); function doSomething() { // write code here } </script>
This recipe will demonstrate how you can attach events to DOM elements using the .bind()
method
and how to remove them using the .unbind()
method.
Create a new file, in a directory named
chapter1
, and name it asbinding.html
.Write the HTML markup to create some HTML elements. Create an unordered list with the names of some countries. After that, create a select box containing names of continents as options. Finally, create a button that will be used to remove the event handler from the select box.
<html> <head> <title>Binding Elements</title> <style type="text/css"> ul { background-color:#DCDCDC; list-style:none; margin:0pt; padding:0pt; width:250px;} li { cursor:pointer; margin:10px 0px;} </style> </head> <body> <ul> <li>India</li> <li>USA</li> <li>UK</li> <li>France</li> </ul> <select> <option value="Africa">Africa</option> <option value="Antarctica">Antarctica</option> <option value="Asia">Asia</option> <option value="Australia">Australia</option> <option value="Europe">Europe</option> <option value="North America">North America</option> <option value="South America">South America</option> </select> <input type="button" value="Unbind select box"/> </body> </html>
It's time to add some jQuery magic. Attach a
click
event handler to list items using the.bind()
method, which will set the background color of the clicked item to red. Attach thechange
event handler to the select box, which will display the value of the selected item. Finally, add aclick
handler to the button. Clicking on the button will remove the event handler from the select box.<script type="text/javascript" src="jquery.js"></script> <script type="text/javascript"> $(document).ready(function () { $('input:text').bind( { focus: function() { $(this).val(''); }, blur: function() { $(this).val('Enter some text'); } }); $('li').bind('click', function() { $(this).css('background-color', 'red'); }); $('select').bind('change', function() { alert('You selected: '+ $(this).val()); }); $('input:button').bind('click', function() { $('select').unbind('change'); }); }); </script>
Run the
binding.html
file in your browser and click on some items in the list. The background color of each item clicked upon will change to red. Now select some value from the select box and you will see an alert box that displays the selected value as shown in the following screenshot:Clicking on the Unbind select box button will remove the
change
event handler here and the selection of a value from the combo box will now do nothing.
jQuery uses the .bind()
method to attach standard JavaScript events to elements. .bind()
takes two parameters. The first parameter is the event type to attach. It is passed in string format, and event types such as click
, change
, keyup
, keydown
, focus
, blur
, and so on can be passed to it. The second parameter is the callback function, which will be executed when the event fires.
In the previous code, we used .bind()
for the list items to attach a click
handler. In the callback function, $(this)
refers to the element that fired the event. We then use the .css()
method to change the background color of the element that is clicked upon.
Similarly, we attached the change
event to the select box using the .bind()
method. The callback function will be called each time the value of the select box is changed.
The input
button has also been attached to a click
event. Clicking on the button calls the .unbind()
method. This method accepts an event type name and removes that event from the element. Our example code will remove the change
event from the select box. Therefore, changing the value of the select box will not display any further alerts.
Multiple events can also be attached using the .bind()
method. The following code attaches two events focus
and blur
to a textbox. Focusing on a textbox will empty it, whereas taking the focus away from it will put some text in it.
$('input:text').bind( { focus: function() { $(this).val(''); }, blur: function() { $(this).val('Enter some text'); } });
Instead of using .bind()
, events can be attached directly by using shortcut event names to elements. For example, $(element).click(function() { });
can be written instead of using $(element).bind('click', function() { });
.
Other events can be attached similarly.
Events can also be triggered from the code. For this we have to pass the event name without any parameter.
$(element1).click(function() { $(element2).keydown(); });
The above code will execute the keydown
event of element2
when element1
is clicked.
Here is a list of some common events that can be passed to the bind()
and unbind()
methods.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
The .bind()
method attaches events to only those elements that exist on a page. If any new elements are created that match the criteria for the .bind()
method, they will not have any event handlers.
Create a new file in the
chapter1
directory and name it aslive.html
.Write the HTML, which creates a button and a DIV on the page and styles them a bit.
<html> <head> <title>Attaching events elements </title> <style type="text/css"> div { border: 1px solid black;cursor:pointer;width:200px;margin:10px; } </style> </head> <body> <input type="button" id="button" value="Create New Element"/> <div class="future">Already on page</div> </body> </html>
Time to spice things up with jQuery. Attach a
click
event to the button. This button will create the new DIV elements and will insert them into the page. Now attach aclick
event handler to the DIV using thelive()
method. Clicking on the DIV will change its CSS and HTML.<script type="text/javascript" src="jquery.js"></script> <script type="text/javascript"> $(document).ready(function () { $('#button').click(function() { $('body').append('<div class="future">I am a new div</div>'); }); $('div').live('click', function() { $(this).css({'color':'red','font-weight':'bold'}).html('You clicked me'); }); }); </script>
Run the
live.html
file and click on the DIV. You will see that its HTML and CSS has changed. Now click on the Create New Element button a few times to create some DIV elements. Clicking on any of these DIV elements will change their appearances. A typical screenshot after a few clicks will look similar to the following:
The input
button creates the new DIV elements and appends them to the body of a document. The secret lies in the next function. We have used jQuery's live()
method to attach an event on click of a DIV element. live()
behaves exactly like bind()
for attaching events with only one major difference. Where bind()
can add events to only existing elements on a page, live()
remembers the attached event for that selector and applies it to matching elements even if they are created later and then inserted into a page.
Therefore, all new DIV elements that are created as a result of clicking on the Create New Element button also respond to the click
event handler.
The die()
method is similar to the unbind()
method. It is used to remove event handlers that were attached using the live()
method. Similar to unbind()
, die()
also has two variations.
If it is called with no parameters, all event handlers will be removed. Another variation accepts an event type name that will remove that particular event:
$(element).die();
The following is the code for other variations that will remove only the specified event handler.
$(element).die('click');
If an element has more than one event handler attached to it, the above code will remove only the click
event handler and will leave the others intact.
We know that submit
buttons are used in HTML forms to submit data to a server. Apart from submit
buttons, JavaScript also provides a submit method that can be used to submit forms.
In this recipe, you will learn how to submit forms the jQuery way and will also learn how the form submission can be controlled using the submit
button.
Create a new file, name it as
formSubmit.html
and save it in thechapter1
directory.Write the following code, which creates a form with an
input
button (notsubmit
button). Add some jQuery code that will be triggered on clicking the button and will submit the form.<html> <head> <title>Submitting forms</title> </head> <body> <form id="myForm"> <input type="button" value="Submit Form" /> </form> <script type="text/javascript" src="jquery.js"></script> <script type="text/javascript"> $(document).ready(function () { $('input:button').click(function() { $('#myForm').submit(); }); }); </script> </body> </html>
Run the
formSubmit.html
file and click on theinput
button. It will submit the form.
In this example we attached the click
event handler to the input
button. The event handler function will execute when the button is clicked. On clicking the button, jQuery's submit()
method is called on the form, which submits the form. All browsers have a native submit method to submit the form programmatically. jQuery has wrapped this functionality into its own submit()
method.
If a form has a submit
button then we can control whether to submit the form or not. In this case we will have to attach an event handler to the form. This event handler will be executed when a submit
button on that particular form is clicked.
$('#myForm').submit(function() { return false; });
The above code will execute when a submit
button on the form with ID myForm
is clicked. If false
is returned by the handler function, the form will not be submitted. This can be pretty handy for validating forms. The code for validating form values can be placed in the handler function. If values are validated, true can be returned, which will submit the form. In case the validation fails, false can be returned, which will not allow the form to be submitted.
Another option is to use preventDefault()
. As the name indicates, preventDefault()
prevents the default event from being executed. It is a property of the event
object.
$('#myForm').submit(function(event) { event.preventDefault() });
If you are displaying some images in the browser and unfortunately some of the images are missing, the browser will either display a blank space or will display a placeholder with a cross symbol. This surely looks ugly and you would definitely want to avoid it. Wouldn't it be good if you had a method with which you could find missing images or those that failed to load?
After going through this recipe you will be able to detect missing images and replace them with an image of your choice.
Get three or four images from your computer. You will need these with this recipe. Also keep the jQuery file handy. Create another image using a program like paint with text "Could not load image" written on it. This will be the default placeholder for images that fail to load.
Create a new file in the
chapter1
directory and name it aserror.html
.Place a DIV in the page, which will be filled with images. Also, write some CSS to style the DIV and the images.
<html> <head> <title>Check missing images</title> <style type="text/css"> div { border:1px solid black; float:left; } img { width:180px; height:200px; margin:10px; } </style> </head> <body> <div id="imageContainer"></div> </body> </html>
Write the jQuery code that creates an array of image names. Intentionally put some random names of images that do not exist. Then fill the DIV by creating image tags from this array. Next, bind the
error()
event handler to the image elements.<script type="text/javascript" src="jquery.js"></script> <script type="text/javascript"> $(document).ready(function () { var images= ['himalaya.png', 'chaukori.png', 'tree.png', 'noSuchimage.png', 'anotheNonExistentImage.png']; var html = ''; $.each(images,function(key, value) { html+= '<img src="'+value+'" />'; }); $('#imageContainer').html(html); $('img').error(function() { $(this).replaceWith('<img src="missing.png" alt="Could not load image">'); }); }); </script>
Run the
error.html
file in a browser. You will see that the last two images, which do not exist, have been replaced by another image that says Could not load image.
First we use jQuery's $.each()
method to iterate in the array that holds image names and fills the DIV by creating image
tags.
Then there is an error()
event handler attached to image
tags. This gets executed when the image fails to load or has a broken src
attribute. The event handler for the error()
method replaces the nonexistent image with another image of our choice. In our case we replace it with an image that we have created and that says Could not load image.
This is a frequently-used feature of web applications. A group of checkboxes exists on a page, which can be controlled by a single checkbox. Clicking on the master checkbox selects all checkboxes and unchecking it deselects all.
We will create the functionality to toggle checkboxes in this recipe. We will also learn how to get values for checked elements using jQuery's selectors.
Create a new file in the
chapter1
directory and name it ascheckbox.html
.Let us design the page first. Create an unordered list and apply some CSS to it. The first item in this list will be a checkbox that will work as a handle to toggle other checkboxes. Then create other items in the list: names of books each having a checkbox before it. All these checkboxes have the same class name
toggle
. Create another list item consisting of a button that will be used to display the selected books. Finally, create a last list item and assign an ID to it. We will use it to display selected book names.<html> <head> <title>Select/Unselect Checkboxes</title> <style type="text/css"> ul { background-color:#DCDCDC; list-style:none; margin:0pt;padding:0pt; width:350px;} li { padding:10px; } </style> </head> <body> <ul> <li> <input type="checkbox" id="handle"> <label for="handle"><strong>Toggle All</strong></label> </li> <li> <input type="checkbox" class="toggle"/> <label>A Study in Scarlet</label> </li> <li> <input type="checkbox" class="toggle"/> <label>The Sign of the Four</label> </li> <li> <input type="checkbox" class="toggle"/> <label>The Adventures of Sherlock Holmes</label> </li> <li> <input type="checkbox" class="toggle"/> <label>The Valley of Fear</label> </li> <li> <input type="checkbox" class="toggle"/> <label>His Last Bow</label> </li> <li><input type="button" id="getValue" value="Get Selected Values"/></li> <li id="selected"></li> </ul> </body> </html>
Running the
checkbox.html
file in browser will display the following screen:
To bring this page to life include the jQuery library and attach event handlers to the checkboxes. The first event handler will be attached to the first checkbox, which will take care of selecting and deselecting all other checkboxes. The second one will be attached to individual checkboxes. It will select/deselect the main handle depending on whether all checkboxes are checked or not. The last event handler is for the
input
button that will display the selected values beneath it.<script type="text/javascript" src="jquery.js"></script> <script type="text/javascript"> $(document).ready(function() { $('#handle').click(function(){ if($(this).attr('checked') == true) $('.toggle').attr('checked', 'true'); else $('.toggle').removeAttr('checked'); }); $('.toggle').click(function(){ if($('.toggle:checked').length == $('.toggle').length) $('#handle').attr('checked', 'true'); if($('.toggle:checked').length < $('.toggle').length) $('#handle').removeAttr('checked'); }); $('#getValue').click(function(){ var values = ''; if($('.toggle:checked').length) { $('.toggle:checked').each(function(){ values+= $(this).next('label').html() + ' ,'; }); $('#selected').html('Selected values are: ' + values); } else $('#selected').html('Nothing selected'); }); }); </script>
Now, refresh your browser and start playing with the checkboxes. Clicking on the Toggle All checkbox will select and deselect all the checkboxes alternatively. Click on the Get Selected Values button and a comma-separated list will appear below the button displaying names of all selected books.
On clicking the Toggle All checkbox we check if it is selected or not. If it is selected, we select all the other checkboxes having the class toggle
using the class selector and set their checked
attribute to true, which selects all the checkboxes. On the other hand, if it is not selected we remove the checked
attribute from all checkboxes that makes all of these deselected.
We will have to take care of another issue here. If all the checkboxes are selected and any one of them is deselected, the handler checkbox should also get deselected. Similarly, if all checkboxes are selected one by one, the handler checkbox should also get checked. For this we attach another event handler to all the checkboxes having class toggle
. The .toggle:checked
selector selects all those elements that have class toggle
and those which are also selected. If the length of the selected elements is equal to the total number of checkboxes, we can conclude that all are selected and hence we select the handler checkbox too.
If the number of selected elements is less than the total number of checkboxes then we remove the checked
attribute of the handler checkbox to deselect it.
In the previous example we used .toggle:checked
to select all the checkboxes that have class toggle
and are checked. :
is a selector that is used to filter a set of elements. Listed below are examples that demonstrate how it can be used to filter elements.
$('div:first').click(function() { //do something });
The above code will select the first DIV on the page and will add a click
event handler to it.
$(p:gt(2)').hide();
gt
stands for greater than. It accepts a 0-based index and matches elements that have an index greater than the one specified. If a page has 5 p elements, the above example will hide p numbers 3 and 4. Remember that the index is 0-based.
You can read about all the selectors on the jQuery site at this URL: http://api.jquery.com/category/selectors/.
jQuery can be used to determine the position of the mouse pointer on screen. This recipe explains the technique for getting the mouse pointer position on screen. You will learn how to create a tooltip that will appear at current mouse pointer position on a particular element.
Open a new file in your text editor and save it in
chapter1
directory asmouse.html
.Create a DIV with the ID
tip
anddisplay
set tonone
. This DIV will be displayed as tooltip. Create three more DIV elements and assign classhoverMe
to the first and the last DIV. Write CSS styles for the DIV elements. The DIV that will be displayed as the tooltip must haveposition
set toabsolute
.<html> <head> <title>Mouse Movements</title> <style type="text/css"> div { border:1px solid black; float:left; width:200px; height:200px; margin:10px; font-family:verdana,arial; font-size:14px; } div#tip { position:absolute; width:100px; height:auto; } </style> </head> <body> <div id="tip" style="display:none;">YaY! I am a tooltip</div> <div class="hoverMe">Hover me for a tooltip.</div> <div>This div will not display a tooltip</div> <div class="hoverMe">Hover me for a tooltip.</div> </body> </html>
Write the jQuery code that will display the tooltip when hovering over the DIV with class
hoverMe
. Two functions will be required for this. The first one will take care of showing and hiding the tooltip on hover with fade effect. The second function will actually set the position of tooltip and will move it as the mouse pointer moves.<script type="text/javascript" src="jquery.js"></script> <script type="text/javascript"> $(document).ready(function () { $('.hoverMe').hover( function() { $('#tip').fadeIn('slow'); }, function() { $('#tip').fadeOut('slow'); }); $('.hoverMe').mousemove(function(e) { var topPosition = e.pageY+5; var leftPosition = e.pageX+5; $('#tip').css( { 'top' : topPosition+ 'px', 'left' : leftPosition +'px' }); }); }); </script>
Open your browser and run the
mouse.html
file. Hovering over the first and last DIV elements will display a tooltip with fade effect. The tooltip will also follow the mouse pointer as it moves.
We have used the hover()
method on the DIV elements to show and hide the tooltip. This method attaches two event handlers to the specified element. The first event handler gets executed when the mouse pointer enters the element and the second one executes when the mouse pointer leaves that element. We have used the fadeIn()
method to display the tooltip when a mouse pointer enters a DIV and the fadeout()
method to hide the DIV as soon as the mouse pointer leaves it.
The most important thing now is to position the tooltip where the mouse pointer is. For this we attached an event handler mousemove
on the DIV. As the name indicates, the handler function will execute when the mouse pointer is moving over the DIV. jQuery makes an event object available to the handler function, using which we can get the current mouse pointer position. The pageX
property of the event gives us the cursor position relative to the left corner of the document. Similarly, the pageY
property gets the mouse pointer position relative to the top of the window.
We have the mouse pointer coordinates with us now. We then assign the value of pageX
and pageY
to the CSS properties left
and top
of the tooltip DIV respectively.The value 5 has been added to each value to avoid the cursor from hiding part of the tooltip.
Keyboard navigation is common in window-based applications. This is very handy for those who prefer keyboard controls over mouse controls. Keyboard shortcuts can also be created in web applications but they are difficult to implement due to inconsistency among browsers.
We will create a simple example in this recipe that will give you the basic understanding of implementing shortcut keys. You will be able to create your own shortcut keys for use in your web applications.
Create a new file named
keyboard.html
and save it in thechapter1
directory.In the body of HTML create two DIV elements and in the
<head>
section write some CSS to apply styles to these DIV elements.<html> <head> <title>Keyboard Shortcuts</title> <style type="text/css"> div{ border : 1px solid black;float:left;height:200px; margin:10px; width:220px;} </style> </head> <body> <div>You can toggle this div using Alt+S</div> <div>You can toggle this div using Alt+G </div> <p style="clear:both;"> </p> <p>Press Alt+B to toggle both divs</p> </body> </html>
Write the jQuery code that will create keyboard shortcuts to toggle these DIV elements. The
keydown
event handler will be used to implement this behaviour. It will check for the keys that are pressed and then take actions accordingly. Three shortcuts will be created. Pressing Alt + S will toggle the first DIV. Alt + G will toggle the second DIV. Pressing Alt + B will toggle both the DIV elements together.Another handler
keyup
will be used to reset the required variables.<script type="text/javascript" src="jquery.js"></script> <script type="text/javascript"> $(document).ready(function () { //remember that this is a global variable var altPressed = false; $(document).keydown(function (event) { if(event.which == 18) altPressed = true; if(altPressed) { switch(event.which) { case 83: $('div:first').slideToggle('slow'); return false; break; case 71: $('div:last').slideToggle('slow'); return false; break; case 66: $('div').slideToggle('slow'); return false; break; } } }); $(document).keyup(function (event) { if(event.which == 18) altPressed = false; }); }); </script>
Open your browser and run the
keyboard.html
file. Try pressing the shortcuts that we have just created. You will see that the DIV elements will toggle with a slide effect.
In order to be able to create shortcut keys, first we need to find out which key was pressed. Different browsers have their own methods of determining the value of the pressed key. jQuery normalizes the way this information can be retrieved across browsers. An event
object is available to handler functions. This event
object has a property which
that gives the code of the pressed key. Alt key has the value 18.
The keyboard shortcuts in this recipe use the combination of Alt and the other keys. We begin by declaring a global variable altPressed
with the value set to false
. Then there are two events attached to the page. keydown
will execute when a key is in a pressed state and keyup
when a key is released. Whenever Alt is pressed the keydown
event will set its value to true. When released, it will be reset to false
again by the keyup
handler function.
Next comes the if
statement, which will evaluate to a true
value if the Alt key is pressed. If Alt is pressed and another key is pressed along with it, the switch
case will check the key's value and will execute the corresponding switch
case.
The value for the S key is 83. So, pressing S along with Alt will select the first DIV and will apply the slideToggle
effect to it. Similarly, Alt + G will toggle the second DIV and Alt + B will toggle both DIVs.
A list of key codes can be found at http://goo.gl/v2Fk
You must have seen the WYSIWYG (What You See Is What You Get) editors in web applications, which allow you to select some text using the mouse or keyboard and then format it (like making it bold, changing its color, and so on).
This recipe will teach you how to retrieve the text that is selected by a user and perform some basic formatting on it.
Create a file named
textSelect.html
in yourchapter1
directory.Create four buttons out of which the first three will be used to make the text bold, italic, and underlined respectively. Then create a textarea with some text in it. And finally, enter a paragraph that will be used to display the formatted HTML.
The last button will get the value of textarea and will insert it in the paragraph.
<html> <head> <title>Manipulating user selected text</title> <style type="text/css"> p { color:red;font-size:17px;width:670px;} </style> </head> <body> <input type="button" value="b" id="bold" class="button"> <input type="button" value="i" id="italics" class="button"> <input type="button" value="u" id="underline" class="button"> <input type="button" id="apply" value="Apply HTML"> <div> <textarea id="selectable" rows="20" cols="80">I consider thata man's brain originally is like a little empty attic, and you have to stock it with such furniture as you choose. A fool takes in all the lumber of every sort that he comes cross, so that the knowledge which might be useful to him gets crowded out, or at best is jumbled up with a lot of other things, so that he has a difficulty in laying his hands upon it.</textarea> </div> <p id="container"></p> </body> </html>
Include the jQuery library and write the JavaScript function that will get the start and end positions of the selected text.
<script type="text/javascript" src="jquery.js"></script> <script type="text/javascript"> function getPositions() { var startPosition = endPosition = 0; var element = document.getElementById('selectable'); if (document.selection) { //for Internet Explorer var range = document.selection.createRange(); var drange = range.duplicate(); drange.moveToElementText(element); drange.setEndPoint("EndToEnd", range); startPosition = drange.text.length - range.text.length; endPosition = startPosition + range.text.length; } else if (window.getSelection) { //For Firefox, Chrome, Safari etc startPosition = element.selectionStart; endPosition = element.selectionEnd; } return {'start': startPosition, 'end': endPosition}; }
Next, write the code for the Apply HTML button that will simply get the text from the textarea and insert it in the paragraph.
$('#apply').click(function() { var html = $('#container').html($('#selectable').val()); });
Let's code the first three buttons now. We will bind the click event with the three buttons. On the click of each button, the position of the selected text will be retrieved and it will be enclosed within HTML tags depending on which button is clicked.
$('.button').click(function() { var positions = getPositions(); if(positions.start == positions.end) { return false; } var tag = $(this).val(); var textOnPage = $('#selectable').val(); var startString = textOnPage.substr(0, positions.start); var targetString = textOnPage.substr(positions.start, positions.end - positions.start); var formattedString = "<" + tag +">" + targetString + "</" + tag +">"; var endString = textOnPage.substr(positions.end); $('#selectable').text(startString + formattedString + endString); });
Save the code, start your browser and point it to the file. Select some text with your mouse and click on any of the buttons. You will see that the selected text has been enclosed with the corresponding HTML tags. If you click on the second button (u), the selected text will be enclosed in
<u>
and</u>
HTML tags.Now click on the Apply HTML button. You will be able to see the formatted text of the textarea in HTML format inside the paragraph, as seen in the following screenshot:
On click of a button, we first get the start and end positions of selected text using the ge
tPositions()
function. Determining this value is a bit complex as different browsers have different methods for handling selections. Internet Explorer uses document.selection
, which represents a subset of documents, whereas Mozilla and similar browsers use window.getSelection
.
IE has a range of objects using which we can determine what text was selected, and the start and end positions of selection in original text. First we create a range object from the selection. Then we create a clone of it using the duplicate
method. After this, two functions moveToElementText()
and setEndPoint()
are used on the duplicated range. These methods align the values of original text and the selection.
Once this is done, we compare the values of the original and the duplicated range to find out the start position. Then we add the length of the selection to the start position, which gives us the end position marker.
For other browsers, getting positions is relatively simple. Start and end positions of selections in textarea can be retrieved using .selectionStart
and .selectionEnd
properties.
Once we get both these values, we create an object in which we put both of these and return the object to the calling function.
If the values of both these positions are equal, it means that no text is selected. In this case we simply return from the function and do nothing.
Then we determine which button was clicked. The clicked button's value will be used to format the selected text. After that, we store the value of textarea in a local variable textOnPage
.
Now comes the part where the actual manipulation takes place. We break the textOnPage
variable into three parts. The first part contains the string from the beginning to the starting position of the selection. The second part of the string is the actual selected text of textarea that has to be formatted. We now enclose it in HTML tags (<b>
, <i>
, or <u>
) according to the button clicked. The third and final part is from where the selection ends to the end of the string.
To get the resulting string we can now simply concatenate these three strings and place it back into the textarea. The textarea will now have text that has the selected text enclosed in HTML tags. To verify this, click on the Apply HTML button. This will take the text from the textarea and insert it as HTML into the paragraph with ID container
.
Another method can be used to get the selected text from other elements, such as <div>
, <p>
, and so on. This will not give any positions but simply the selected text. Note that this method will not work for textareas for Mozilla and similar browsers but it will work in Internet Explorer for textareas as well as other controls.
Use the following function to get the selected text:
function getSelectedText() { var selectedText = ''; if (document.selection) { var range = document.selection.createRange(); selectedText = range.text; } else if (window.getSelection) { selectedText = window.getSelection(); } return selectedText; }
There are many plugins based on JavaScript, jQuery, and other libraries, which let users implement the dragging functionality. A user presses the mouse button on an element and moves it without releasing it. The element gets dragged along with the mouse pointer. The dragging stops once the mouse key is released.
After finishing this recipe, you will be able to implement a dragging feature for elements on your own. This recipe will show you how to make elements on a page draggable.
Create a new file in the
chapter1
directory and name it asdrag.html
.Create some DIV elements and assign the
dragMe
class to customize their appearance. This class will also be used to attach event handlers to the DIV.<html> <head> <title>Dragging</title> <style type="text/css"> .dragMe { background-color:#8FBC8F; border:1px solid black; color: #fff; float:left; font-family:verdana,arial; font-size:14px; font-weight:bold; height:100px; margin:10px; text-align:center; width:100px; } </style> </head> <body> <div class="dragMe">Drag Me</div> <div class="dragMe">Drag Me too</div> </body> </html>
In the jQuery code, declare variables that will hold the coordinates of DIV being dragged and the mouse pointer. Proceed to
attach
event handlers for mouse movement to elements with thedragMe
class.We have attached two event handlers. The first is
mousedown
, which will execute while the mouse button is in a pressed state on the target DIV. This will get the current left and top coordinates of the DIV being dragged and the mouse pointer. Now bind themousemove
element to the current DIV. ThedragElement
function will be called when the mouse moves while its button is pressed.The function
dragElement
calculates new values for the top and left of the DIV by determining mouse movements and the DIV's current position and applies these properties to the DIV. This results in the movement of the DIV.Finally, bind the
mouseup
event to the document, which will stop the dragging after the mouse has been released.<script type="text/javascript" src="jquery.js"></script> <script type="text/javascript"> $(document).ready(function () { var mousex = 0, mousey = 0; var divLeft, divTop; $('.dragMe').mousedown(function(e) { var offset = $(this).offset(); divLeft = parseInt(offset.left,10); divTop = parseInt(offset.top,10); mousey = e.pageY; mousex = e.pageX; $(this).bind('mousemove',dragElement); }); function dragElement(event) { var left = divLeft + (event.pageX - mousex); var top = divTop + (event.pageY - mousey); $(this).css( { 'top' : top + 'px', 'left' : left + 'px', 'position' : 'absolute' }); return false; } $(document).mouseup(function() { $('.dragMe').unbind('mousemove'); }); }); </script>
Open the browser and run the
drag.html
file. Both DIV elements would be draggable by now. You will now be able to drag any of these DIV elements by pressing the mouse button over them and moving them around.
Global variables mousex
an
d mousey
will be used to store the left and top positions for the mouse pointer, and the div
Left
and divTop
variable will store the left and top coordinates of the DIV. Then we attached two event handlers to the DIV with class dragMe
. First is mousedown
, which will execute when the mouse button is in a pressed state on the target DIV. In this function get the left and top positions of the DIV being dragged and store them in the divLeft
and divTop
variables respectively. Secondly, get the left and top values for the current mouse pointer position from the event object and save them in the mousex
and mousey
variables. Now when the button is pressed, bind the mousemove
element to current DIV. The dragElement
function will be called when the mouse pointer moves while its button is pressed.
The dragElement
function now calculates the new left and top values for the DIV being dragged. To calculate the new value for left, take the left value for the DIV (divLeft
) and add the difference in the mouse position to it. The difference in mouse position can be calculated by subtracting the previous left value for mouse pointer from the current left value. Similarly calculate the new value for top.
After both these values are calculated, use the css()
method to apply these values to the DIV being dragged. Don't forget to set the position as absolute
. Without absolute positioning the DIV will not be able to move.