01ca81bf26ed83e854836298ad890595ffd4c2aa
[framework/web/web-ui-fw.git] / src / widgets / searchbar / js / jquery.mobile.tizen.searchbar.js
1 /* ***************************************************************************
2  * Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd.
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a
5  * copy of this software and associated documentation files (the "Software"),
6  * to deal in the Software without restriction, including without limitation
7  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8  * and/or sell copies of the Software, and to permit persons to whom the
9  * Software is furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20  * DEALINGS IN THE SOFTWARE.
21  * ***************************************************************************
22  */
23 /*
24 * jQuery Mobile Framework : "textinput" plugin for text inputs, textareas
25 * Copyright (c) jQuery Project
26 * Dual licensed under the MIT or GPL Version 2 licenses.
27 * http://jquery.org/license
28 * Authors: Jinhyuk Jun <jinhyuk.jun@samsung.com>
29 *          Wongi Lee <wongi11.lee@samsung.com>
30 */
31
32 /**
33  * Searchbar can be created using <input> element with type=search
34  * <input type="search" name="search" id="search1" value=""  />
35  *
36  * Searchbar can be inserted 3 cases
37  * content : seachbar behave same as content element
38  * header : searchbar placed below title(header), It doesn't move when scrolling page
39  * inside optionheader : Searchbar placed inside optionheader, searchbar can be seen only expand optionheader
40  *
41  * Examples:
42  *
43  *      HTML markup for creating Searchbar
44  *              <input type="search"/>
45  *
46  *      How to make searchbar in content
47  *              <input type="search" name="" id="" value=""  />
48  *
49  *      How to make searchbar in title
50  *              <div data-role="header" data-position ="fixed" >
51  *                      <h1>Searchbar</h1>
52  *                      <input type="search" name="" id="" value=""  />
53  *              </div>
54  *
55  *      How to make searchbar inside optionheader
56  *              <div data-role="header" data-position ="fixed" >
57  *                      <h1>Searchbar</h1>
58  *                      <div id="myoptionheader2" data-role="optionheader">
59  *                              <input type="search" name="" id="" value=""  />
60  *                      </div>
61  *              </div>
62 */
63
64 (function ( $, undefined ) {
65
66         $.widget( "tizen.searchbar", $.mobile.widget, {
67                 options: {
68                         theme: null,
69                         initSelector: "input[type='search'],:jqmData(type='search'), input[type='tizen-search'],:jqmData(type='tizen-search')"
70                 },
71
72                 _create: function () {
73                         var input = this.element,
74                                 o = this.options,
75                                 theme = o.theme || $.mobile.getInheritedTheme( this.element, "c" ),
76                                 themeclass  = " ui-body-" + theme,
77                                 focusedEl,
78                                 clearbtn,
79                                 currentPage = input.closest( ".ui-page" ),
80                                 searchicon,
81                                 cancelbtn,
82                                 defaultText,
83                                 defaultTextClass,
84                                 trimedText,
85                                 newClassName,
86                                 newStyle,
87                                 newDiv,
88                                 inputedText,
89                                 extraLineHeight,
90                                 keyupTimeoutBuffer,
91                                 keyup,
92                                 keyupTimeout;
93
94                         function toggleClear() {
95                                 if ( !input.val() ) {
96                                         clearbtn.addClass( "ui-input-clear-hidden" );
97                                 } else {
98                                         clearbtn.removeClass( "ui-input-clear-hidden" );
99                                 }
100                         }
101
102                         function showCancel() {
103                                 focusedEl
104                                         .addClass( "ui-input-search-default" )
105                                         .removeClass( "ui-input-search-wide" );
106                                 cancelbtn
107                                         .addClass( "ui-btn-cancel-show" )
108                                         .removeClass( "ui-btn-cancel-hide" );
109                                 searchicon.hide();
110                         }
111
112                         function hideCancel() {
113                                 focusedEl
114                                         .addClass( "ui-input-search-wide" )
115                                         .removeClass( "ui-input-search-default" );
116                                 cancelbtn
117                                         .addClass( "ui-btn-cancel-hide" )
118                                         .removeClass( "ui-btn-cancel-show" );
119
120                                 if ( input.val() == "" ) {
121                                         searchicon.show();
122                                 }
123
124                                 toggleClear();
125                         }
126
127                         $( "label[for='" + input.attr( "id" ) + "']" ).addClass( "ui-input-text" );
128
129                         focusedEl = input.addClass( "ui-input-text ui-body-" + theme );
130
131                         // XXX: Temporary workaround for issue 785 (Apple bug 8910589).
132                         //      Turn off autocorrect and autocomplete on non-iOS 5 devices
133                         //      since the popup they use can't be dismissed by the user. Note
134                         //      that we test for the presence of the feature by looking for
135                         //      the autocorrect property on the input element. We currently
136                         //      have no test for iOS 5 or newer so we're temporarily using
137                         //      the touchOverflow support flag for jQM 1.0. Yes, I feel dirty. - jblas
138                         if ( typeof input[0].autocorrect !== "undefined" && !$.support.touchOverflow ) {
139                                 // Set the attribute instead of the property just in case there
140                                 // is code that attempts to make modifications via HTML.
141                                 input[0].setAttribute( "autocorrect", "off" );
142                                 input[0].setAttribute( "autocomplete", "off" );
143                         }
144
145                         focusedEl = input.wrap( "<div class='ui-input-search ui-shadow-inset ui-corner-all ui-btn-shadow" + themeclass + "'></div>" ).parent();
146                         clearbtn = $( "<a href='#' class='ui-input-clear' title='clear text'>clear text</a>" )
147                                 .tap( function ( event ) {
148                                         event.preventDefault();
149                                         event.stopPropagation();
150
151                                         input.val( "" )
152                                                 .blur()
153                                                 .focus()
154                                                 .trigger( "change" )
155                                                 .trigger( "input" );
156                                         clearbtn.addClass( "ui-input-clear-hidden" );
157                                 } )
158                                 .appendTo( focusedEl )
159                                 .buttonMarkup({
160                                         icon: "deleteSearch",
161                                         iconpos: "notext",
162                                         corners: true,
163                                         shadow: true
164                                 } );
165
166                         toggleClear();
167
168                         input.keyup( toggleClear );
169
170                         input.bind( 'paste cut keyup focus change blur', toggleClear );
171
172                         //SLP --start search bar with cancel button
173                         focusedEl.wrapAll( "<div class='input-search-bar'></div>" );
174
175                         input.tap( function ( event ) {
176                                 inputedText = input.val();
177                                 input
178                                         .blur()
179                                         .focus();
180                         } );
181
182                         searchicon = $("<div class='ui-image-search ui-image-searchfield'></div>");
183                         searchicon
184                                 .tap( function ( event ) {
185                                         searchicon.hide();
186
187                                         input
188                                                 .blur()
189                                                 .focus();
190                                 } )
191                                 .appendTo( focusedEl );
192
193                         cancelbtn = $( "<a href='#' class='ui-input-cancel' title='clear text'>Cancel</a>" )
194                                 .tap(function ( event ) {
195                                         event.preventDefault();
196                                         event.stopPropagation();
197
198                                         input
199                                                 .val( "" )
200                                                 .blur()
201                                                 .trigger( "change" );
202
203                                         hideCancel();
204                                 } )
205                                 .appendTo( focusedEl.parent() )
206                                 .buttonMarkup( {
207                                         iconpos: "cancel",
208                                         corners: true,
209                                         shadow: true
210                                 } );
211
212                         // Input Focused
213                         input.focus( function () {
214                                 showCancel();
215                                 focusedEl.addClass( "ui-focus" );
216                         } );
217
218                         // Input Blured
219                         /* When user touch on page, it's same to blur */
220                         $( "div.input-search-bar" ).tap( function ( event ) {
221                                 input.focus();
222                                 event.stopPropagation();
223                         } );
224
225                         $( currentPage ).bind("tap", function ( e ) {
226                                 focusedEl.removeClass( "ui-focus" );
227                                 hideCancel();
228                                 input.trigger( "change" );
229                         } );
230
231                         // Autogrow
232                         if ( input.is( "textarea" ) ) {
233                                 extraLineHeight = 15;
234                                 keyupTimeoutBuffer = 100;
235                                 keyup = function () {
236                                         var scrollHeight = input[ 0 ].scrollHeight,
237                                                 clientHeight = input[ 0 ].clientHeight;
238
239                                         if ( clientHeight < scrollHeight ) {
240                                                 input.height(scrollHeight + extraLineHeight);
241                                         }
242                                 };
243
244                                 input.keyup( function () {
245                                         clearTimeout( keyupTimeout );
246                                         keyupTimeout = setTimeout( keyup, keyupTimeoutBuffer );
247                                 });
248
249                                 // binding to pagechange here ensures that for pages loaded via
250                                 // ajax the height is recalculated without user input
251                                 $( document ).one( "pagechange", keyup );
252
253                                 // Issue 509: the browser is not providing scrollHeight properly until the styles load
254                                 if ( $.trim( input.val() ) ) {
255                                         // bind to the window load to make sure the height is calculated based on BOTH
256                                         // the DOM and CSS
257                                         $( window ).load( keyup );
258                                 }
259                         }
260
261                         // Default Text
262                         defaultText = input.jqmData( "default-text" );
263
264                         if ( ( defaultText != undefined ) && ( defaultText.length > 0 ) ) {
265                                 defaultTextClass = "ui-input-default-text";
266                                 trimedText = defaultText.replace(/\s/g, "");
267
268                                 /* Make new class for default text string */
269                                 newClassName = defaultTextClass + "-" + trimedText;
270                                 newStyle = $( "<style>" + '.' + newClassName + ":after" + "{content:" + "'" + defaultText + "'" + "}" + "</style>" );
271                                 $( 'html > head' ).append( newStyle );
272
273                                 /* Make new empty <DIV> for default text */
274                                 newDiv = $( "<div></div>" );
275
276                                 /* Add class and append new div */
277                                 newDiv.addClass( defaultTextClass );
278                                 newDiv.addClass( newClassName );
279                                 newDiv.tap( function ( event ) {
280                                         input.blur();
281                                         input.focus();
282                                 } );
283
284                                 input.parent().append( newDiv );
285
286                                 /* When focus, default text will be hide. */
287                                 input
288                                         .focus( function () {
289                                                 input.parent().find( "div.ui-input-default-text" ).addClass( "ui-input-default-hidden" );
290                                         } )
291                                         .blur( function () {
292                                                 var inputedText = input.val();
293                                                 if ( inputedText.length > 0 ) {
294                                                         input.parent().find( "div.ui-input-default-text" ).addClass( "ui-input-default-hidden" );
295                                                 } else {
296                                                         input.parent().find( "div.ui-input-default-text" ).removeClass( "ui-input-default-hidden" );
297                                                 }
298                                         } );
299                         }
300                 },
301
302                 disable: function () {
303                         this.element.attr( "disabled", true );
304                         this.element.parent().addClass( "ui-disabled" );
305                 },
306
307                 enable: function () {
308                         this.element.attr( "disabled", false );
309                         this.element.parent().removeClass( "ui-disabled" );
310                 }
311         } );
312
313         //auto self-init widgets
314         $( document ).bind( "pagecreate create", function ( e ) {
315                 $.tizen.searchbar.prototype.enhanceWithin( e.target );
316         } );
317
318 }( jQuery ) );