XPages and Me

My Journey into XPages Development

(Revised) Dabbling in Bootstrap and Font Awesome Part 4: Holding a special place in my field (Placeholders and IE8 / IE9)

As I mentioned before, the fix I posted regarding placeholders in IE8 / IE9, was causing some issues:

  • After a refresh, the placeholders became the fields actual value / content
  • When having a field flagged as required, triggering the server-side validation would not flag the field as “not valid” as the placeholder was being submitted as the value of the field.

But, yours truly didn’t give up and I found a solution that is stable and works. It just involves a few more steps than just adding an output script.

So, without further ado, here we go:

One of the many cool HTML5 features is the placeholder, which displays some text in the fields, either explaining what value is expected in the field or it can be used instead of a label, if your form doesn’t have a lot of space. To make use of the placeholder, simply add an attribute to your field named “placeholder” and assign it a value:

Image 5

When you open your XPage in Firefox or Chrome, the placeholder will look something like this:

Image 1

However, if you open the same XPage in IE8 / IE9, the placeholder doesn’t work:

Image 2

That is because, IE8 and IE9 don’t support the placeholder attribute. But, if you follow the steps below, it should work just fine.

Create the client-side JavaScript library:

I found a different jquery fix here (thank you Nico Hagenburger) and copied the code from GitHub. Create a new client-side JavaScript library (either under Code – Script Libraries or in the WebContent folder in the Package Explorer) and give it a name (I named mine placeholder.fix.js). We need to create two functions: One to apply the placeholders to the fields that have the attribute set and one that will remove the the placeholders before a submit. I named my first function “addPlaceholder” and it contains the whole jquery code:

function addPlaceholder(){
    $('[placeholder]').focus( function() {
        var input = $(this);
        if (input.val() == input.attr('placeholder')) {
            input.val('');
            input.removeClass('placeholder');
        }
    }).blur( function() {
        var input = $(this);
        if (input.val() == '' || input.val() == input.attr('placeholder')) {
            input.addClass('placeholder');
            input.val(input.attr('placeholder'));
        }
    }).blur().parents('form').submit( function() {
        $(this).find('[placeholder]').each( function() {
            var input = $(this);
            if (input.val() == input.attr('placeholder')) {
                input.val('');
            }
        })
    });    
}

Now, add a second function (I named mine “removePlaceholder”) and copy the part of the jquery code that removes the placeholders. Your function should now look like this:

function removePlaceholder(){
    $( function() {
        $(this).find('[placeholder]').each( function() {
            var input = $(this);
            if (input.val() == input.attr('placeholder')) {
                input.val('');
            }
        })
    });        
}

So, your whole JavaScript library should now look like this:

function addPlaceholder(){
    $('[placeholder]').focus( function() {
        var input = $(this);
        if (input.val() == input.attr('placeholder')) {
            input.val('');
            input.removeClass('placeholder');
        }
    }).blur( function() {
        var input = $(this);
        if (input.val() == '' || input.val() == input.attr('placeholder')) {
            input.addClass('placeholder');
            input.val(input.attr('placeholder'));
        }
    }).blur().parents('form').submit( function() {
        $(this).find('[placeholder]').each( function() {
            var input = $(this);
            if (input.val() == input.attr('placeholder')) {
                input.val('');
            }
        })
    });    
}

function removePlaceholder(){
    $( function() {
        $(this).find('[placeholder]').each( function() {
            var input = $(this);
            if (input.val() == input.attr('placeholder')) {
                input.val('');
            }
        })
    });        
}

Save and close the JavaScript Library

Create css file:

By default, the font color of the placeholder fix is black. However, we want it to appear gray as it does in Chrome or Firefox. Create a new css file and give it name (I named mine ie89.fixes.css) and add the following css statement:

/* Used for placeholder.fix.js. Applies a gray font color for placeholders */
.placeholder{
	color: #aaa !important;
}

Save and close the css file

Now we need to add the JavaScript and css file to our theme.

Add JavaScript and css to Theme:

In Part 2 of this series, I showed you how you have to set up your theme in order to make Bootstrap / Font Awesome work with IE8/ IE9. Open the theme that contains the bootstrap.css, html5shiv.js, respond.js etc. This is where we need to add the jquery.placeholder.js reference. In my case, the theme was called bootstrap:

<theme extends='fontawesome' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:noNamespaceSchemaLocation='platform:/plugin/com.ibm.designer.domino.stylekits/schema/stylekit.xsd'>

    <!-- Bootstrap Styleheet -->
        <resource>
            <content-type>text/css</content-type>
            <href>/.ibmxspres/domino/webres.nsf/bootstrap/css/bootstrap.min.css</href>
        </resource>


       <!-- START: IE 9 and lower specific. -->
       
        <!-- JavaScript libraries to make IE8/9 play nicely with Bootstrap and Font Awesome        
             These files need to be loaded before the jquery and bootstrap JavaScript libraries -->
                 <resource rendered='#{javascript:context.getUserAgent().isIE(7,9)}'>
                    <content-type>application/x-javascript</content-type>
                    <href>/.ibmxspres/domino/webres.nsf/IE89/html5shim/html5shiv.min.js</href>
                </resource>
                
                <resource rendered='#{javascript:context.getUserAgent().isIE(7,9)}'>
                    <content-type>application/x-javascript</content-type>
                    <href>/.ibmxspres/domino/webres.nsf/IE89/respond/respond.min.js</href>
                </resource>
                
       <!-- END: IE 9 and lower specific. -->
        
    <!-- jquery, placeholder and bootstrap JavaScript libraries need to be placed at the end of the head-tag -->
        <resources>
            <metaData name='viewport' content='width=device-width, initial-scale=1.0' />
            <script clientSide='true' src='/.ibmxspres/domino/webres.nsf/jquery/jquery.min.js' />
            <script clientSide='true' src='/.ibmxspres/domino/webres.nsf/bootstrap/js/bootstrap.min.js' />
        </resources>
        
</theme>

Now we need to add the references to the new JavaScript and css file. We add the css file before the html5shiv.js and respond.js with the rendered option set to load the css file when we open our application in IE8 / IE9. The placeholder.fix.js goes between the jquery.min.js and bootstrap.min.js references and your theme should look something like this:

<theme extends='fontawesome' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:noNamespaceSchemaLocation='platform:/plugin/com.ibm.designer.domino.stylekits/schema/stylekit.xsd'>

    <!-- Bootstrap Styleheet -->
        <resource>
            <content-type>text/css</content-type>
            <href>/.ibmxspres/domino/webres.nsf/bootstrap/css/bootstrap.min.css</href>
        </resource>
    
    
    <!-- START: IE 9 and lower specific. -->
       
        <!-- Stylesheet for the placeholder fix for IE8/9 to make the font color gray -->
               <resource rendered='#{javascript:context.getUserAgent().isIE(7,9)}'>
                   <content-type>text/css</content-type>
                <href>/.ibmxspres/domino/webres.nsf/ie89.fixes.css</href>
               </resource>
           
        <!-- JavaScript libraries to make IE8/9 play nicely with Bootstrap and Font Awesome        
             These files need to be loaded before the jquery and bootstrap JavaScript libraries -->
                 <resource rendered='#{javascript:context.getUserAgent().isIE(7,9)}'>
                    <content-type>application/x-javascript</content-type>
                    <href>/.ibmxspres/domino/webres.nsf/IE89/html5shim/html5shiv.min.js</href>
                </resource>
                
                <resource rendered='#{javascript:context.getUserAgent().isIE(7,9)}'>
                    <content-type>application/x-javascript</content-type>
                    <href>/.ibmxspres/domino/webres.nsf/IE89/respond/respond.min.js</href>
                </resource>
                
       <!-- END: IE 9 and lower specific. -->
        
    <!-- jquery, placeholder and bootstrap JavaScript libraries need to be placed at the end of the head-tag -->
        <resources>
            <metaData name='viewport' content='width=device-width, initial-scale=1.0' />
            <script clientSide='true' src='/.ibmxspres/domino/webres.nsf/jquery/jquery.min.js' />
            <script clientSide='true' src='/.ibmxspres/domino/webres.nsf/IE89/placeholder/placeholder.fix.js' />
            <script clientSide='true' src='/.ibmxspres/domino/webres.nsf/bootstrap/js/bootstrap.min.js' />
        </resources>
        
</theme>

Save and close your theme.

Enable the placeholders on your custom control:

Open the custom control / XPage that contains the fields for which you’d like to enable the placeholder. Select the “Events” tab and locate the event “onClientLoad”. Open the “Client” tab, select “Script Editor” and enter the following statement into the field below:

addPlaceholder()

It should now look something like this:

Image 2

Save and close your custom control / XPage.

Handling Placeholder during refresh

To make the placeholder fix work even during and after a refresh, we need to add “removePlaceholder()” to the onStart event of the event handler and “addPlaceholder” to the onComplete event.

In this example I am just adding it to the onClick event of a button:

Select the button expand it in the Outline and click on the Event handler:

Image 3

In the “All Properties” tab, scroll down until you find the section “events”. Now add “addPlaceholder()” to the onComplete event and “revmovePlaceholder()” to the onStart event. It now should look like this:

Image 4

Save and close and you are all set.

I did some extensive testing and it seems to be working very well. You just need to remember to add “addPlaceholder()” and “removePlaceholder()” to the onComplete, onStart events wherever you use placeholders and do refreshes.

If you come across a better solution or you ran into other issues with this placeholder fix and found a solution for it, please do not hesitate to share it with us.

Thank you

Advertisements

One response to “(Revised) Dabbling in Bootstrap and Font Awesome Part 4: Holding a special place in my field (Placeholders and IE8 / IE9)

  1. Pingback: xpages image placeholder | Share4you blog

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: