项目中开发的utils.js

项目中开发总结一些js
常见的js处理clear_xss,日期处理, nl2br, strip_html_tags, showDialog, htmlspecialchars等等
 
 
 
 
function addBookmark(title, url)
{
   if (title == undefined)
      title = document.title;

   if (url == undefined)
      url = top.location.href;

   if (window.sidebar) // firefox
      window.sidebar.addPanel(title, url, '');
   else if(window.opera && window.print) // opera
   {
      var elem = document.createElement('a');
      elem.setAttribute('href',url);
      elem.setAttribute('title',title);
      elem.setAttribute('rel','sidebar');
      elem.click();
   }
   else if(document.all) // ie
      window.external.AddFavorite(url, title);
   else if (navigator.appName=="Netscape") //Netscape
      alert( 'To bookmark this site press "Ctrl+D".' );
   else
      alert( 'Your browser doesn\'t support this feature' );
}

var DEVELOPMENT_MODE = 1; /* This should be off when in production mode */
function debug(msg) {
   if(DEVELOPMENT_MODE <= 0)
      return;

   if ("console" in window)
      console.log(msg);
}

function debugMethod(method, msg) {
   if(DEVELOPMENT_MODE <= 0)
      return;

   /* the time in console is from firebug only */
   if ("console" in window && "time" in window.console) {
      console.time(method.toString());
      var result = method();
      console.timeEnd(method.toString());
      console.log(msg, result);
   }
}

function showConfirmDialog(html, okcallback, cancelcallback, title)
{
   var ok = 0;
  
   if(typeof(title)=='undefined') {
      title = '请确认';
   }
  
   if(jQuery("#dialogConfirm").length <= 0) {
      jQuery('body').append('<div id="dialogConfirm" class="modal hide fade">'+
         '<div class="modal-header">'+
           '<button aria-hidden="true" data-dismiss="modal" class="close" type="button">×</button>'+
           '<h3 id="dialogConfirmLabel">'+title+'</h3>'+
         '</div>'+
         '<div id="dialogConfirmBody" class="modal-body"></div>'+
         '<div id="dialogConfirmFooter" class="modal-footer">'+
            '<button id="confirmButton" class="btn btn-info">确定</button>'+
            '<button id="cancelButton" class="btn">取消</button>'+
         '</div>'+
         '</div>');
   }
   jQuery("#dialogConfirmBody").html(html);
   jQuery("#dialogConfirm #confirmButton").unbind('click').click(function() {
      ok = 1;
      if(okcallback) okcallback.call();
      jQuery("#dialogConfirm").modal('hide');
   });
   jQuery("#dialogConfirm #cancelButton").unbind('click').click(function() {
      jQuery("#dialogConfirm").modal('hide');
   });
   jQuery("#dialogConfirm").off('hide').on('hide', function(){
      if(!ok && cancelcallback) cancelcallback.call();
   });
   jQuery("#dialogConfirm").modal('show');

}


function showMessageDialog(html)
{
   if(jQuery("#dialogMessage").length <= 0) {
      jQuery('body').append('<div id="dialogMessage" class="modal hide fade">'+
         '<div class="modal-header">'+
           '<button aria-hidden="true" data-dismiss="modal" class="close" type="button">×</button>'+
           '<h3 id="dialogMessageLabel">Hi</h3>'+
         '</div>'+
         '<div id="dialogMessageBody" class="modal-body"></div>'+
         '<div id="dialogMessageFooter" class="modal-footer">'+
            '<button id="confirmButton" aria-hidden="true" data-dismiss="modal" class="btn btn-info">确定</button>'+
         '</div>'+
         '</div>');
   }
   $("#dialogMessageBody").html(html);
   $("#dialogMessage").modal('show');

}

function showMessagePanel(html, anchorEl, error, options)
{
   $('.popover').hide();
   var options = jQuery.extend({
      animation: true,
      html: true,
      placement: 'bottom',
      selector: false,
      trigger: 'click',
      content: html,
      template: '<div class="popover"><div class="arrow"></div><div class="popover-inner text-info"><div class="popover-content"></div></div></div>',
      timeout:1800
   }, options || {});

   if(!anchorEl) {
      anchorEl = jQuery('body');
   }

   if(error) {
      options.template = '<div class="popover" style="width:auto"><div class="arrow"></div><div class="popover-inner text-error"><div class="popover-content"></div></div></div>';
   }
   anchorEl.popover(options).popover('show');
   setTimeout(function() { anchorEl.popover('destroy'); }, options.timeout);
}

/*
* 77youyue: show dialog box
*/
function showDialog(event, alignment, width)
{
   /* convert literal event to jQuery event */
   event = jQuery.event.fix(event);
   var target = jQuery(event.target);

   var url = target.attr("href");

   /*fix for IE */
   event.returnValue = false;
   return showDialogWin(target, url, null, null, alignment, {width: width});
}

function showDialogWin(target, url, title, html, alignment, option)
{
   // var defalign = {my: "left top", at: "left bottom", of: target, collision: 'fit none'};
   // if(!alignment)
   //    alignment = defalign;
   // else
   //    alignment = jQuery.extend({}, defalign, alignment);

   if(jQuery("#jobDialog").length <= 0) {
      jQuery('body').append('<div id="jobDialog" class="modal hide fade" ></div>');
   }

   var openDialog = function(data) {
      title = title ? title : (target && target.attr("title") ? target.attr("title") : '');
      title = title ? title : (target && target.attr("modalTitle") ? target.attr("modalTitle") : '');
      jQuery('#jobDialog').html("<div>"+data+"</div>");
      jQuery('#jobDialog #jobDialogLabel').html(title+"&nbsp;");
      jQuery('#jobDialog').modal('show');
   };

   if(url) {
     jQuery.ajax({
       url: url,
       success: function(data) {
         /* check whether it's login response */
         if(showLogonDialog(data))
            return;
         openDialog(data);
       }
     });
   } if(html) {
     openDialog(html);
   }
   return false;
}

function strip_html_tags(input, allowed) {
   allowed = (((allowed || "") + "")
       .toLowerCase()
       .match(/<[a-z][a-z0-9]*>/g) || [])
       .join(''); // making sure the allowed arg is a string containing only tags in lowercase (<a><b><c>)
   var tags = /<\/?([a-z][a-z0-9]*)\b[^>]*>/gi,
          commentsAndPhpTags = /<!--[\s\S]*?-->|<\?(?:php)?[\s\S]*?\?>/gi;
   return input.replace(commentsAndPhpTags, '').replace(tags, function($0, $1){
         return allowed.indexOf('<' + $1.toLowerCase() + '>') > -1 ? $0 : '';
   });
}

function nl2br(text) {
   text = escape(text);
   re_nlchar = null;
   if(text.indexOf('%0D%0A') > -1){
      re_nlchar = /%0D%0A/g ;
   }else if(text.indexOf('%0A') > -1){
      re_nlchar = /%0A/g ;
   }else if(text.indexOf('%0D') > -1){
      re_nlchar = /%0D/g ;
   }

   if(!re_nlchar)
      return unescape(text);
   else
      return unescape( text.replace(re_nlchar,'<br />') );
}

function br2nl(text) {
   return text.replace(/<br\s*\/?>/mig,"\n");
}

function getUrlQuery(url, params) {
   return /\?/.test(url) ? (url+'&'+params) : (url+'?'+params);
}

function validateEmail(email) {
   if(!email || email.length<=0) return false;

   return /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+([\.]{1}[a-zA-Z]{1,4}){1,4}$/.test(email);
}
function compact_strlen(data) {
   if(!data || data.length <= 0)
      return 0;
   data = data.replace(/(\r?\n)+/g, "\n"); // replace windows CR/LF to single \n
   var m = encodeURIComponent(data).replace(/%[89ABCDEFabcdef]\S{1}/g, ''); // utf8
   var s = m.replace(/%[01234567]\S{1}/g, ' '); // ascii special chars, including \n

   if(s) m = s; 
   if (m)
      return (data.length - m.length) + Math.round(m.length/2);
   else
      return data.length;
}
function htmlspecialchars(htmlstring) {
   return htmlstring.replace(/&/g, '&amp;').replace(/>/g, '&gt;').replace(/</g, '&lt;').replace(/\"/g, '&quot;').replace(/\'/g, '&#039;');
}
function htmlspecialchars_decode(htmlstring, quote_style) {
   var str = htmlstring.replace(/&amp;/g, '&');
   str = str.replace(/&lt;/g, '<');
   str = str.replace(/&gt;/g, '>');

   // decode depending on quote_style
   if (quote_style == 'ENT_QUOTES')
   {
      str = str.replace(/&quot;/g, '"');
      str = str.replace(/&#039;/g, '\'');
   }
   else if (quote_style != 'ENT_NOQUOTES')
   {
       // All other cases (ENT_COMPAT, default, but not ENT_NOQUOTES)
       str = str.replace(/&quot;/g, '"');
   }

   return str;
}
function stripHtml(value) {
   // remove html tags and space chars
   return jQuery.trim(value.replace(/<.[^<>]*?>/g, ' ').replace(/&nbsp;|&#160;/gi, ' ').replace(/[ \t\r\n]+/g, ' ').replace(/\s+/, ' '));
}
function padDate(value) {
   return (value < 10 ? '0' : '') + value;
};

/* set focus when form is diplayed. id should be form id or input/textarea id */
function setFocus(id) {
   var el = jQuery("#" + id);
   if(el.length <= 0)
      return;

   if(el.prop("tagName").toUpperCase() == "FORM") {
      el.find("input[type!='hidden']:first").filter("[type='text'],textarea,[type='password']").focus();
   }
   else
      jQuery("#" + id).focus();
}

/* show loading indicator while ajax is processing */
function showLoading(id, settings, options, formoptions, stopoptions) {
      var $form = null;
      if(typeof(id) == 'object')
         $form = jQuery(id);
      else
         $form = jQuery("#" + id.replace(/^#/, ""));

      if($form.length <= 0)
         return false;

      if(!$form.is(':visible')) return true;
      // already running ?
      if($form.data("loading")) {
         if(settings)
            settings.suppressAjaxEvent = true;
         return false;
      }

      var offset = $form.offset();
      var width = $form.width();
      var height = $form.height();

      var defaults = {position: "absolute", top: offset.top+height/2-15, left: offset.left+width/2-15, 'z-index': 99999};
      options = jQuery.extend({}, defaults, options);

      var loader = jQuery("#job_ajax_loader");
      if(loader.length <= 0) {
         loader = jQuery('<div id="job_ajax_loader"></div>').appendTo('body').hide();
      }

      if(formoptions && typeof(formoptions.button) != 'undefined') {
         loader.addClass("ajax_loader_small").removeClass("ajax_loader");
         // hiding the button style
         formoptions.visibility = "hidden";
      }
      else
         loader.addClass("ajax_loader").removeClass("ajax_loader_small");

      loader.css(options).show();

      formoptions = jQuery.extend({}, {opacity : "0.5", visibility:"visible"}, formoptions || {});
      stopoptions =  jQuery.extend({}, {opacity:"1.0", visibility:"visible"}, stopoptions || {});

      $form.css(formoptions).data("loading", true);
      jQuery(document).ajaxStop(function() {
         $form.css(stopoptions).removeData("loading");
         loader.hide();
      }).ajaxError(function(evt, xhr, settings) {
         if(settings.suppressAjaxEvent)
            return;  
         $form.css(stopoptions).removeData("loading");
         loader.hide();
      });

      return true;
}

/**
* beautify table td label caption
*/

function beautifyTableCaption(el) {
   /* disable string beautification as requested */
   if(jQuery(el).attr("no_bfy") || jQuery(el).hasClass('bfy'))
      return;

   var s = jQuery(el).html();
   s = s.replace(/^\s+|\s+$/g, '');

   if((/^&/).test(s)) return;
   var beautify = function(str) {
      // str is supposed to have ':'
      if(str.length ==3) {
         str = str.substring(0,1) + "<span class='invisible'>__</span>" + str.substring(1, str.length);
      }
      else if(str.length == 4) {
         str = str.substring(0,1) + "<span class='invisible'>_</span>" + str.substring(1,2) + "<span class='invisible'>_</span>" + str.substring(2, s.length);
      }
      return str;
   };

   if(s.length < 5) {
      s = beautify(s);
   }
   else if(!/__/.test(s)){
    var matches = s.match(/<span class=["]?required["]?>\*<\/span>(\S+)(\&nbsp;)*\s*/i);
    if(matches && matches.length > 1) {
      var caption = matches[1];
      caption = beautify(caption + ((/:$/.test(caption)) ? '' : ":"));
      s = '<span class="required">*</span> &nbsp;' + caption;
    }
   }
   jQuery(el).addClass('bfy').html(s);
}

function  setClientTimezone() {
   if(readCookie("CLIENT_GMT") != null)
      return;
   var rightNow = new Date(),
   date1 = new Date(rightNow.getFullYear(), 0, 1, 0, 0, 0, 0),
   date2 = new Date(rightNow.getFullYear(), 6, 1, 0, 0, 0, 0),
   temp = date1.toGMTString(),
   date3 = new Date(temp.substring(0, temp.lastIndexOf(" ")-1)),
   temp = date2.toGMTString(),
   date4 = new Date(temp.substring(0, temp.lastIndexOf(" ")-1)),
   hoursDiffStdTime = (date1 - date3) /(60 * 60 *1000),
   hoursDiffDaylightTime = (date2 - date4) /(60 *60 *1000);

   if (hoursDiffDaylightTime != hoursDiffStdTime) {
      if(hoursDiffStdTime < 0)
          createCookie("CLIENT_GMT", (hoursDiffStdTime * (-1) - 1));
      else
          createCookie("CLIENT_GMT", (hoursDiffStdTime * (-1) + 1));

      createCookie("CLIENT_DAYLIGHT", 1);
   }
   else
   {
      createCookie("CLIENT_GMT", hoursDiffStdTime * (-1));
      createCookie("CLIENT_DAYLIGHT", 0);
   }

}

function  prettyDate(date, compareTo) {
   var time_formats = [
      [60, '几秒钟'],
      [90, '1分钟'], // 60*1.5
      [3600, '分钟', 60], // 60*60, 60
      [5400, '1小时'], // 60*60*1.5
      [86400, '小时', 3600], // 60*60*24, 60*60
      [129600, '1天'], // 60*60*24*1.5
      [604800, '天', 86400], // 60*60*24*7, 60*60*24
      [907200, '1星期'], // 60*60*24*7*1.5
      [2628000, '星期', 604800], // 60*60*24*(365/12), 60*60*24*7
      [3942000, '1月'], // 60*60*24*(365/12)*1.5
      [31536000, '月', 2628000], // 60*60*24*365, 60*60*24*(365/12)
      [47304000, '1年'], // 60*60*24*365*1.5
      [3153600000, '年', 31536000], // 60*60*24*365*100, 60*60*24*365
      [4730400000, '1世纪'], // 60*60*24*365*100*1.5
   ];


   var isString = typeof date == 'string',
   date = isString ?
        new Date(('' + date).replace(/-/g,"/").replace(/[TZ]/g," ")) :
        date,
   compareTo = compareTo || new Date,

   seconds = (compareTo - date +
             (compareTo.getTimezoneOffset() -
              // if we received a GMT time from a string, doesn't include time zone bias
              // if we got a date object, the time zone is built in, we need to remove it.
              (isString ? 0 : date.getTimezoneOffset())
            ) * 60000
        ) / 1000,

   token = '前',
   i = 0,
   format;

   if (seconds < 0) {
      seconds = Math.abs(seconds);
   }

   while (format = time_formats[i++]) {
      if (seconds < format[0]) {
         if (format.length == 2) {
            return format[1] + token;
         } else {
            return parseInt(seconds / format[2]) + format[1] + token;
         }
      }
   }

   // overflow for centuries
   if(seconds > 4730400000)
      return Math.round(seconds / 4730400000) + '世纪' + token;
  
   return date;
}

/**
* display height
*/
function displayHeight(sel) {
   var defvalue = jQuery(sel).attr("defvalue") ? jQuery(sel).attr("defvalue"): 170;
   for(var i=150; i<250; i++) {
      if(i==defvalue)
         jQuery(sel).append("<option selected value='" + i + "'>" + i + "</option>");
      else
         jQuery(sel).append("<option value='" + i + "'>" + i + "</option>");
   }
}

/**
* display weigh
*/
function displayWeight(sel) {
   var defvalue = jQuery(sel).attr("defvalue") ? jQuery(sel).attr("defvalue"): 65;
   for(var i=40; i<150; i++) {
      if(i==defvalue)
         jQuery(sel).append("<option selected value='" + i + "'>" + i + "</option>");
      else
         jQuery(sel).append("<option value='" + i + "'>" + i + "</option>");
   }
}

/*
* a wrapper function for storage/cookie. All must call this function instead of directly calling Storage
* all key will be preappend with yyjob_(subject to change) to avoid conflict
*/
function storageSet(key, value) {
  
   if(!value) {
      storageRemove(key);
      return;
   }

   key = "hulahoo_" + key;
   if(typeof value!=="object") {
      /* make sure everything is string type */
      jQuery.Storage.set(key, value + "");
   }
   else {
      jQuery.Storage.set(key, JSON.stringify(value));
   }
}

function storageGet(key, object) {
   key = "hulahoo_" + key;
   if(object) {
      var value = jQuery.Storage.get(key);
      if(value)
         try {
            return JSON.parse(value);
         } catch(e) {
            return value;
         }

      return value ? value : {};
   }
   else {
      return jQuery.Storage.get(key);
   }
}

function storageRemove(key) {
   key = "hulahoo_" + key;
   if(jQuery.Storage.get(key))
      jQuery.Storage.remove(key);
}

/* is empty MultiSelectData */
function isEmptyMultiSelectData(data) {
   if(jQuery.isEmptyObject(data))
      return true;

   if(jQuery.isEmptyObject(data.valueslist))
      return true;

   return false;
}

/* init multiselect selection */
function setMultiSelectData(dataSelected, nolabeltag) {
      if(!dataSelected || typeof(dataSelected) != 'object')
        return {'allselect': {}, 'valueslist': {}, 'label': ""};
     
      if(!dataSelected.allselect) dataSelected.allselect = {};
      if(!dataSelected.valueslist) dataSelected.valueslist = {};
      if(!dataSelected.label) dataSelected.label = "";
      if(!nolabeltag)
         return {'allselect' : dataSelected.allselect, 'valueslist': dataSelected.valueslist, 'label': dataSelected.label};
      else
         return {'allselect' : dataSelected.allselect, 'valueslist': dataSelected.valueslist};
}

/* flat multiselect selection */
function flatMultiSelectData(dataSelected) {

      var valueslist = {}, allselectlist={};
      if(!dataSelected || typeof(dataSelected) != 'object')
        return {'allselect': allselectlist, 'valueslist': valueslist};


      if(dataSelected.length > 0) {
        jQuery(dataSelected).map(function(){
            jQuery.each(this, function(k, v) {
               if(k == 'label') return true;
               if(k == 'allselect') {
                  jQuery.each(v.split(","), function(kk, vv) { allselectlist[vv] = 1; });
               }
               else if(typeof(v) == 'object') {
                  var values = '', texts = '';
                  jQuery.each(v, function(kk, vv) { values = kk; texts = vv; });
                  valueslist[k] = {values: values, texts: texts};
               }
               else {
                  valueslist[k] = {values: v, texts: ''};
               }
            });

        });
      }

      return {'allselect': allselectlist, 'valueslist': valueslist};
}

/* show login form. The login form is returned via error handling */
function showLogonDialog(html)
{
   if(!html) return false
   if(/id="loginrequired"/.test(html)) {
      showDialogWin(null, null, "请登录或注册", html,
                    {my: "center center", at: "center center", collision: 'fit', of: window},
                    {modal: true, minHeight: 300, width:420});
      return true;
   }

   return false;
}

/* don't fire ajax or any other event too frequently */
function throttle(fn, delay) {
   var timer = null;
   return function () {
      var context = this, args = arguments;
      clearTimeout(timer);
      timer = setTimeout(function () {
         fn.apply(context, args);
      }, delay);
   };
}

function truncate(str, max, compact){
   return (compact ? compact_strlen(str) : str.length) > (max - 3) ? str.substring(0,max-3) + '...' : str;
}

function randomString(length, chars) {
   if(!chars)
      chars = "0123456789abcdefghijklmnopqrstuvwxyz";

   var result = '';
   for (var i = length; i > 0; --i)
      result += chars[Math.round(Math.random() * (chars.length - 1))];
   return result;
}

function isLoggedIn(html, target, options){
   if(!html) return false
   if(/id="loginrequired"/.test(html)) {
      /* show message based on whether the target is given */
      if(target) {
         options = jQuery.extend({
            placement: 'bottom'
         }, options || {});
         showMessagePanel('您需要登陆', target, true, {placement: options.placement});
      }
      return false;
   } else {
      return true;
   }
}

function getMaxZIndex(selector) {
   return Math.max.apply(null, $.map($(selector).filter(function(i) { return $(this).css("display") != "none"; }),function(item){
      var z;
      return isNaN(z = parseInt($(item).css("z-index"), 10)) ? 0 : z;
   }));
};
/* invoke any document.ready script */
//jQuery.noConflict();if (typeof(window.$) === 'undefined') { window.$ = jQuery; }

/**
* Get the current coordinates of the first element in the set of matched
* elements, relative to the closest positioned ancestor element that
* matches the selector.
* @param {Object} selector
*/
jQuery.fn.positionAncestor = function(selector) {
   var left = 0;
   var top = 0;
   this.each(function(index, element) {
        // check if current element has an ancestor matching a selector
        // and that ancestor is positioned
        var $ancestor = $(this).closest(selector);

        if ($ancestor.length && $ancestor.css("position") !== "static") {
            var $child = $(this);
            var childMarginEdgeLeft = $child.offset().left - parseInt($child.css("marginLeft"), 10);
            var childMarginEdgeTop = $child.offset().top - parseInt($child.css("marginTop"), 10);
            var ancestorPaddingEdgeLeft = $ancestor.offset().left + parseInt($ancestor.css("borderLeftWidth"), 10);
            var ancestorPaddingEdgeTop = $ancestor.offset().top + parseInt($ancestor.css("borderTopWidth"), 10);
            left = childMarginEdgeLeft - ancestorPaddingEdgeLeft;
            top = childMarginEdgeTop - ancestorPaddingEdgeTop;
            // we have found the ancestor and computed the position
            // stop iterating
            return false;
        }
   });
   return {
        left:    left,
        top:    top
   }
};

jQuery.fn.jobUtil = function(method) {
   var methods = {
      moveAnimate: function(element, position){
         var p = jQuery(this);
         var oldOffset = p.offset();
         if(typeof(position) == 'undefined')
            position = "append";

         switch(position) {
            case 'before':   
               p.insertBefore(element);
            break;
            case 'after':
               p.insertAfter(element);
            break;
            default:
               p.appendTo(element);
            break;
         }

         var newOffset = p.offset();
         var temp = p.clone().appendTo('body');

         temp.css('position', 'absolute')
             .css('left', oldOffset.left)
             .css('top', oldOffset.top)
             .css('width', p.width())
             .css('border', '1px dashed #999')
             .css('zIndex', 1000);
         p.fadeOut('fast', function() {
            temp.animate( {'top': newOffset.top, 'left':newOffset.left}, '5400', 'easeOutQuint', function(){
               p.fadeIn();
               temp.remove();
            });
         });        
         return this;
      },

      showError: function(html, callback) {
         jQuery(this).html(html).addClass("error").removeClass("success").removeClass("checked").stop(true,true).fadeIn('fast', function() {
            if(jQuery.isFunction(callback)) callback.apply(this);
         });
         return this;
      },

      showSuccess: function(html, callback) {
         jQuery(this).html(html).addClass("success").removeClass("error").stop(true, true).fadeIn('fast', function() {
            if(jQuery.isFunction(callback)) callback.apply(this);
         });
         return this;
      },
      showPass: function(callback) {
         jQuery(this).html('').addClass("checked").removeClass("error").fadeIn('fast', function() {
            jQuery(this).css("display", "inline-block");
            if(jQuery.isFunction(callback)) callback.apply(this);
         });
         return this;
      },

      showTooltip: function() {
         var form = jQuery(this);
         $(":input[title]", form).not(function() { if($(this).hasClass('hint')) return true;}).each(function() {
            $(this).tooltip({placement: "right"});
         });

         return this;
      },

      setCursorPosition: function(pos) {
         var elem  = jQuery(this).get(0);
         if (elem.setSelectionRange) {
            pos = typeof(pos) == 'undefined' ? elem.value.length : pos;
            elem.setSelectionRange(pos, pos);
         } else if (elem.createTextRange) {
            pos = typeof(pos) == 'undefined' ? elem.value.length : pos;
            var range = elem.createTextRange();
            range.collapse(true);
            range.moveEnd('character', pos);
            range.moveStart('character', pos);
            range.select();
         }
         return this;
      },

      loginDialog: function(options) {
         var pform = jQuery(this);

         // the form is standard login form and show up as dialog box
         var buttons = jQuery("button, input:submit, input:button", pform);
         if(buttons.is(':data(button)'))
            return;

         buttons.button();
         // re-size the table td key label field for alignment
         jQuery("label.key", pform).each(function(i, el) { beautifyTableCaption(el); });
         // enable email provider list
         jQuery(".email", pform).jobUtil("emailProvider");

         pform.find("form").ajaxForm({
            dataType: "json",
            beforeSubmit: function(data, form, options) {
               jQuery("#regmsg", pform).hide();
               var el = jQuery(".email", pform);
               if(!validateEmail(jQuery.trim(el.val()))) {
                  jQuery("#regmsg", pform).html("请输入正确的邮件地址").fadeIn();
                  return false;
               }
               el = jQuery("input[type='password']", pform);
               if(jQuery.trim(el.val()).length <=0) {
                  jQuery("#regmsg", pform).html("请输入密码").fadeIn();
                  return false;
               }
               if(!showLoading(pform))
                  return false;
            },
            success:function(data) {
               if(data.error) {
                  jQuery("#regmsg", pform).html(data.error).fadeIn();
                  if(typeof(data.data) != 'undefined' && typeof(data.data.captcha) != 'undefined' && data.data.captcha) {
                     jQuery("#logincaptcha", pform).fadeIn('fast', function() {
                        pform.parent().css("height", pform.outerHeight()+10);
                        if(jQuery("#logincaptcha #captcha_code", pform).addClass("required").val().length > 0)
                           jQuery("#logincaptcha #captcha_reload", pform).trigger("click");
                     });
                  }
                  else if(/captcha_code/.test(data.error)) {
                     jQuery("#logincaptcha", pform).show();
                     jQuery("#logincaptcha #captcha_reload", pform).trigger("click");
                  }

               }
               else if(data.success) {
                  pform.fadeOut();
                  window.location = getUrlQuery(data.redirect, "_="+(new Date()).getTime());
               }
            }
         });

         return this;
      },
      loginform: function(options) {
         // the form is not a standard login form
         var pform = jQuery(this);

         // keydown on input[text] field trigger submit
         pform.delegate("input[type!='submit']", "keydown", function(e) {
               if(e.which == 13) {
                  e.preventDefault();
                  jQuery("input[type='submit']", pform).trigger("click");
               }
         }).delegate("input[type='submit']", "click", function(e) {
            var el = jQuery(".email", pform);
            if(!validateEmail(jQuery.trim(el.val()))) {
               jQuery("#regmsg", pform).html("请输入正确的邮箱").fadeIn();
               return false;
            }

            var data = {}
            jQuery("input", pform).each(function() {
               if(jQuery(this).attr("name"))
                  data[jQuery(this).attr("name")] = jQuery(this).val();
               else if(jQuery(this).attr("aname"))
                  data[jQuery(this).attr("aname")] = jQuery(this).val();
            });

            jQuery.ajax({ 
               type: 'POST',
               url: options.loginurl,
               data: data,
               dataType: 'json',
               beforeSend: function(xhr, settings) {
                  if(!showLoading(pform, settings))
                     return false;
                  jQuery("#regmsg", pform).hide();
               },
               success: function(retmsg) {
                     if(retmsg.error) { jQuery("#regmsg", pform).html(retmsg.error).fadeIn();}
                     else {
                        if(jQuery.isFunction(options.success))
                           options.success(pform, options, retmsg);
                  }
               }
            });

            return false;
         })
      },

      reportbad: function(options) {
         var dialog = jQuery(this);

         var data = dialog.data("data");
         if(!data || !data.initialized) {
            // we only initialized once
            data = {};
            data.initialized = true;
            dialog.data("data", data);

            // handle keydown
            dialog.keydown(function(e){
               switch(e.which){
                  case 27: // esc
                     jQuery(this).find("#cancelbtn").trigger("click");
                  break;
               }
            });

            jQuery(".autogrow", dialog).autogrow();
            jQuery("#cancelbtn", dialog).click(function() {
               dialog.fadeOut();
               jQuery("#commentbox", dialog).val('');
               jQuery(".server", dialog).html('');
               return false;
            });

            jQuery("#submitbtn", dialog).click(function(event) {
               var data = dialog.data("data"),
                   submitdata = {'id': data.jobid};

               // clean out hint value
               jQuery(dialog).jobUtil('clearHint');

               var value = jQuery.trim(jQuery("#commentbox", dialog).val());
               if(value.length <= 0) {
                  jQuery(".server", dialog).html("请给出您的举报原因!");
                  return false;
               }
               var hidden = dialog.find("input[type='hidden']");
               hidden.each(function(i, elem) {
                  elem = jQuery(elem);
                  submitdata[elem.attr("name")] = elem.val();
               })
               submitdata['reason'] = value;

               jQuery.ajax({
                  type: 'POST',
                  data: submitdata,
                  url: options.reporturl,
                  dataType: 'json',
                  beforeSend: function(xhr, settings) {
                     if(!showLoading(dialog, settings)) {
                        return false;
                     }
                  },
                  success: function(data) {
                     if(data.error) {
                        jQuery(".server", dialog).html(data.error);
                     }
                     else {
                        var box = jQuery("#commentbox", dialog);
                        box.val('').hide();
                        var p = jQuery("<div class='success' style='font-size:80%'>" + data.success + "</div>").insertAfter(box);
                        setTimeout(function() { 
                           jQuery("#cancelbtn", dialog).trigger("click");
                           p.remove();
                        }, 1500);
                     }
                  }
               });
            });

         } /* init */

         dialog.fadeIn().
               position({my: "right bottom", at: "right top", of: options.anchor}).
               find("#commentbox").show().focus();

         data.jobid = options.jobid;
         dialog.data("data", data);
      },

      evaluatedialog: function(options) {
         var dialog = jQuery(this);

         var el = options.anchor.parents(".actions").prev().find(".evaluated");

         var data = dialog.data("data");
         if(!data || !data.initialized) {
            // we only initialized once
            data = {};
            data.initialized = true;
            dialog.data("data", data);

            // handle keydown
            dialog.keydown(function(e){
               switch(e.which){
                  case 27: // esc
                     jQuery(this).find("#cancelbtn").trigger("click");
                  break;
               }
            });

            jQuery(".autogrow", dialog).autogrow({minHeight: 120});
            jQuery("#cancelbtn", dialog).click(function() {
               dialog.fadeOut();
               jQuery("#notebox", dialog).val('');
               jQuery(".server", dialog).html('');
               return false;
            });

            // button widget render
            if(!dialog.find("button").hasClass("ui-widget"))
               dialog.find("button").button();
        
            dialog.find("form").ajaxForm({
               dataType: "json",
               beforeSerialize: function(form, options) {
                  if(form.find("input[name='evaluated']:checked").length <= 0) {
                     jQuery(".server", dialog).html("您还没有作出综合评价");
                     return false;
                  }
                  var data = dialog.data("data");
                  // options is same object, so can be altered
                  options.data = {'jobid': data.jobid, 'uid': data.userid};
               },
               beforeSubmit: function(data, form, options) {
                  if(!showLoading(form))
                     return false;
               },
               success: function(data, status, xhr, form) {
                  if(data.error) {
                     jQuery(".server", form).html(data.error);
                  }
                  else {

                     var data = dialog.data("data");
                     var neweval = form.find("input[name='evaluated']:checked").val();
                     var newtext = form.find("input[name='evaluated']:checked").next().text();

                     var el = data.anchor.parents(".actions").prev().find(".evaluated");
                     el.find(".overall").attr("data", neweval).html(newtext);

                     el.removeClass().addClass('evaluated').
                        addClass(neweval).
                        find(".note").html(jQuery("#notebox", form).val()).
                        next().html("1秒钟前");

                     jQuery("#cancelbtn", form).trigger("click");
                     if(jQuery.isFunction(options.oncomplete)) {
                        options.oncomplete(el);
                     }
                  }
               }
            });
         } /* init */

         /* find out current evaluation */
         var currvalues = [];
         if(!el.hasClass("hide")) {
            currvalues.push({name:'evaluated', value: el.find(".overall").attr("data")});
            currvalues.push({name:'evaluated_note', value: el.find(".note").html()});
         }
         else {
            /* reset */
            dialog.find("form").find("input[name='evaluated']:checked").prop("checked", false);
            currvalues.push({name:'evaluated', value: ''});
            currvalues.push({name:'evaluated_note', value: ''});
         }

         data.jobid = options.jobid;
         data.userid = options.userid;
         data.anchor = options.anchor;
         dialog.data("data", options);

         dialog.fadeIn().
               position({my: "right top", at: "right bottom", of: options.anchor}).
               find("form").fill(currvalues).
               find("#notebox").show().focus(function() {
                  // handle hint blur   
                  jQuery(this).removeClass("blur");
               }).focus();

      },

      /* the function controls how many chars can be input in textarea box */
      setInputLimit: function() {
         var onEditCallback = function(remaining, maxlength){
            // check whether it has hint enabled
            if(jQuery(this).hasClass("hint") && jQuery(this).val() === jQuery(this).attr("title"))
               return;

            if(remaining == maxlength)
               jQuery(this).siblings('.charsRemaining').text("最多输入: " + remaining + "字符").removeClass("limit");
            else if(remaining > 0)
               jQuery(this).siblings('.charsRemaining').text("还可输入: " + remaining + "字符").removeClass("limit");
            else
               jQuery(this).siblings('.charsRemaining').text("已达输入上限,不能再输入了哦!").addClass("limit");
         }

         var onLimitCallback = function() {
            jQuery(this).siblings('.charsRemaining').text("已达输入上限,不能再输入了哦!").addClass("limit");
         }

         jQuery(this).limitMaxlength({
            onEdit: onEditCallback,
            onLimit: onLimitCallback
         });

         return this;
      },

      setTagSelector: function(options) {
         var tagbox = jQuery(options.tagbox);
         options = jQuery.extend({
            html: "",
            minNumTags: 0,
            position: {my: "left top", at: "left bottom", of: options.anchor, collision: 'fit fit', offset: "0 5"},
            width: tagbox.outerWidth()
         }, options || {});

         /* trigger tag removed event */
         if(tagbox.hasClass("tagbox")) {
            /* tag alike */
            tagbox.tagit({
               onTagRemoved: function(e, tag) {
                  var label = jQuery("label[for=tagbox]", tagbox.parent());
                  var assigned = tagbox.tagit("assignedTags");
                  /* if there is only tag left, it's going to me empty after removed */
                  if(assigned.length <=options.minNumTags)
                     label.show();
               },
               onTagAdded: function(e, tag) {
                  var label = jQuery("label[for=tagbox]", tagbox.parent());
                  var assigned = tagbox.tagit("assignedTags");
                  /* if there are more tags, ignore the error */
                  if(assigned.length >=(options.minNumTags-1))
                     label.hide();
               }
            });
         }

         var target = jQuery(this);
         target.tagselector({
               html: options.html,
               position: options.position,
               width: options.width,
               beforeTagCreated: function(item, aoptions) {
                  /* don't proceed if it's not a tagbox */
                  if(!tagbox.hasClass("tagbox")) {
                        if(tagbox.is("input") && tagbox.val()==jQuery(item).text())
                           return true;
                     return false;
                  }

                  var assigned = tagbox.tagit("assignedTags", true);
                  if(jQuery.inArray(jQuery(item).attr('title').toUpperCase(), assigned) != -1)
                     return true;
                  else
                     return false;
               },
               onTagSelected: function(tag, selected, aoptions) {
                  if(!tagbox.hasClass("tagbox")) {
                     if(tagbox.is("input")) tagbox.val(jQuery(tag).text());
                     return false;
                  }
                  /* handle tag creation */
                  var tagname = jQuery(tag).attr('title');
                  if(selected) {
                     if(!tagbox.tagit("createTag", tagname)) {
                        return false;
                     }
                  } else {
                     tagbox.tagit("removeTagByName", tagname);
                  }
                  /* re-position self */
                  target.tagselector({position: aoptions.position});
                  return true;
               }
         });

         return this;
      },

      setCaptcha: function(options) {
         var pform = jQuery(this);
         var ppform = pform;
         if(!ppform.is('form'))
           ppform = pform.closest('form');

         // Add this step to fix IE placeholder issue
         ppform.submit(function() {
            $("#captcha_code", pform).focus();
         });

         pform.find("#captcha_reload").bind("click", function(event, unfocusinput) {
            jQuery("#captcha", pform).attr('src', getUrlQuery(options.captchaurl, "t="+Math.random())).data("timestamp", new Date().getTime()).show();
            if(!unfocusinput)
               jQuery("#captcha_code", pform).val('');
            return false;
         });

         pform.find("#captcha_code", pform).bind("focus", function(event) {
            var last = jQuery("#captcha", pform).data("timestamp") || 0;
            var now = new Date().getTime();
            if((now - last) >= 60000 && jQuery(this).val().length <= 0) {
               jQuery("#captcha", pform).attr('src', getUrlQuery(options.captchaurl, "t="+Math.random())).data("timestamp", now);
            }
         });

         jQuery("#captcha", pform).data("timestamp", new Date().getTime());

         setTimeout(function() {
            jQuery("#captcha_reload", pform).trigger("click")
         },500);
         return this;
      },

      strengthCheck: function() {
         var input = jQuery(this);
         var strength = 1;
         H = input.val();
         var D=(H.length);
         if(D>5){ D=5; }
         var F=H.replace(/[0-9]/g,"");
         var G=(H.length-F.length);
         if(G>3){G=3}
         var A=H.replace(/\W/g,"");
         var C=(H.length-A.length);
         if(C>3){C=3}
         var B=H.replace(/[A-Z]/g,"");
         var I=(H.length-B.length);
         if(I>3){I=3}
         var E=((D*10)-20)+(G*10)+(C*15)+(I*10);
         if(E<0){E=0}
         if(E>100){E=100}
         return E>=40 ? true : false;
      },

      emailProvider: function() {
         var emails = ["163.com", "sina.com", "hotmail.com", "gmail.com", "qq.com", "sohu.com", "126.com"];
         var useremail = storageGet('useremail_provider');
         if(useremail && validateEmail("t@"+useremail)) {
            var n = jQuery.inArray(useremail, emails);
            if(n == -1) {
               emails.splice(0, 0, useremail);
            }
            else {
               emails.splice(n, 1);
               emails.splice(0, 0, useremail);
            }
         }
         if(!jQuery.isFunction(jQuery.fn.autocomplete))
            return;

         jQuery(this).autocomplete({
            messages: {
                 noResults:'',
                 results:function(){}
            },           
            source: function(req, add) {
               var term = decodeURIComponent(req.term);
               var domain = null;
               if(/,/.test(term)) {
                  /* multiple case */
                  var list = term.split(/,\s*/mg);
                  /* only use last one */
                  term = jQuery.trim(list[list.length-1]);
               }
               if(term.length <= 0)
                  return;

               if(/@/.test(term)) {
                  var s = term.split(/@/);
                  term = s[0] + "@";
                  domain = s[1];
               }
               else
                  term = term + "@";

               add(jQuery.map(emails, function(item) {
                  if(domain && !item.match(domain))
                     return;
                  return {
                     label: term+item,
                     value: term+item
                  }
               }))
            }
         }).bind("autocompletefocus", function(event, ui) {
            /* disable focus event to not replace text in textarea */
            if(jQuery(this).is("textarea"))
               return false;
         }).bind("autocompleteselect", function(event, ui) {
            if(!jQuery(this).is("textarea"))
               return true;
            var value = jQuery(this).val();
            if(/,/.test(value)) {
               /* multiple case */
               var list = value.split(/,\s*/mg);
               /* only change last one */
               list[list.length-1] = ui.item.value;
               jQuery(this).val(list.join(","));
               return false;
            }

            return true;
         });

         return this;
      },

      showLargeAvatar: function() {
         jQuery(this).hover(function() {
            var existing = jQuery("#largeavatar");
            var img = jQuery(this).find("img");
            if ( existing.size() > 0) {
               existing.first().empty().html("<img style='min-height:120px;max-height:240px;' src='" + img.attr("src")+ "' />")
               .show()
               .position({my: 'left top', at: 'right top', of: jQuery(this)})
               .show();
            }
            else {
               jQuery("<div id='largeavatar'><img style='min-height:120;max-height:240px;' src='" + img.attr("src")+ "' /></div>").appendTo("body")
               .position({my: 'left top', at: 'right top', of: jQuery(this)})
               .show();
            }
         }, function() {
            jQuery("#largeavatar").hide();
         });

         return this;
      },

      clearHint: function(blurClass) {
         var form = jQuery(this);
         if (!blurClass) {
            blurClass = 'blur';
         }

         jQuery("textarea.hint, input.hint", form).each(function() {
            if (jQuery(this).val() === jQuery(this).attr('title') && jQuery(this).hasClass(blurClass)) {
               jQuery(this).val('').removeClass(blurClass);
            }
         });

         return this;
      },

      setLinkPanel: function() {
         var sidebar = jQuery(this);
         var ghref = window.location.href;
         jQuery("a", sidebar).each(function() {
            var href = jQuery(this).attr("href");
            var pos = ghref.indexOf(href);
            if(pos >0 && (pos + href.length == ghref.length)) {
               sidebar.find(".active").removeClass("active");
               jQuery(this).parent().addClass("active");
               jQuery(this).parents(".subsection").prev(".section").addClass("active");
            }
         });
      },

      getContainer: function(options) {
         var target = jQuery(this);
         options = jQuery.extend({
            containerId: 'fcontainer',
            width: '400',
            height: 'auto',
            html: '',
            position: {my: "left top", at: "left bottom", of: target, collision: 'fit none', offset: "5 0"}
         }, options || {});

         var existing = jQuery("#" + options.containerId);
         if ( existing.size() > 0) {
            return existing.first().empty().html(options.html)
                   .css({width: options.width, height: options.height})
                   .show()
                   .position(options.position);
         }
         else {
            return jQuery('<div id="' + options.containerId + '"></div>')
                   .appendTo('body')
                   .html(options.html)
                   .addClass('ui-widget ui-widget-content ui-corner-all quickdialog')
                   .css({width: options.width, height: options.height})
                   .show()
                   .position(options.position) ;
         }
      },

      timerDown: function(callback, delay, no_clear) {
         target = jQuery(this);
         if (no_clear == null)
            no_clear = false;

         if(target.data("timer")) {
            clearInterval(target.data("timer"));
         }

         if(!jQuery.isFunction(callback) && callback == 'clear') {
            if(target.data("timer")) {
               clearInterval(target.data("timer"));
            }

            return;
         }

         var currentvalue = jQuery.trim(target.text());
         if(!currentvalue || currentvalue.length <= 0 || !jQuery.isNumeric(currentvalue))
            currentvalue = delay || 60;
         else
            currentvalue = parseInt(currentvalue);

         var handler = setInterval(function() {
            currentvalue--;
            target.text(currentvalue);
            if(currentvalue <= 0) {
               if(jQuery.isFunction(callback))
                  callback.apply(target);
               clearInterval(handler);
               target.removeData("timer");
            }
         },1000);
         target.data("timer", handler);
         if (no_clear == false) {
            $(document).bind("mousedown", function(e) {
               if($(e.target).is('a') || $(e.target).parent().is('a') || $(e.target).is('input[type="button"]'))  {
                  target.jobUtil("timerDown", "clear");
               }
            });
         }
      },

      getVerifyCode: function(options) {
         var target = jQuery(this);
         options = jQuery.extend({
            url: '',
            email: '',
            phone: ''
         }, options || {});

         if(options.email.length <= 0 && options.phone.length <= 0)
            return this;

         var receiver = options.email;
         if(receiver.length <= 0)
            receiver = options.phone;

         if(target.data("sending"))
            return this;

         target.data('sending', true);

         jQuery.ajax({
            type: 'POST',
            url: options.url,
            data: {receiver: receiver},
            dataType: 'json',
            beforeSend: function(xhr, settings) {
               showLoading(target, settings, null, {button:true});
            },
            success: function(data) {
               if(data.error) {
                  target.parent().nextAll('label.success').remove();
                  target.parent().nextAll('label.error').first().jobUtil("showError", data.error, function() {
                     jQuery(this).fadeOut(3000, function() {
                        jQuery(this).html(jQuery(this).attr('derror'));
                     });
                  });
               }
               else {
                  var message = '';
                  if(options.email.length > 0)
                     message = '邮箱验证码已发出(半小时内有效),请登录邮箱查收';
                  else
                     message = '手机验证码短信已发出';
                  var html = $("<label>").addClass("success medium").html(message+",<span id='getvcode_wait'>60</span>秒后可再获取.");
                  target.parent().hide().nextAll('label.error').first().hide().after(html);
                  $("#getvcode_wait", target.parent().parent()).jobUtil('timerDown', function() {
                     $(this).parent().remove();
                     target.parent().show();
                     target.removeData("sending");
                  }, 60, true);
                }
            }
         });

         return this;
      },


      share: function(options) {
         $.metadata.setType("attr", "data");
         var data = $(this).metadata();
         options = jQuery.extend({
            content: '',
            img: '',
            url: ''}, options || {});

         switch(data.type) {
            case 'sina':
               url = getUrlQuery(data.url, "title=" + encodeURIComponent(truncate(options.content, 130, true)) +
                                           "&pic=" + encodeURIComponent(options.img) +
                                           "&url=" + encodeURIComponent(options.url));
            break;

            case 'renren':
               url = getUrlQuery(data.url, "title=" + encodeURIComponent(options.title) +
                                           "&description=" + encodeURIComponent(options.content) +
                                           "&pic=" + encodeURIComponent(options.img) +
                                           "&resourceUrl=" + encodeURIComponent(options.url) +
                                           "&srcUrl=" + encodeURIComponent(options.url));
            break;
         }

         var newwin = window.open(url, "_blank");
         newwin.focus();
      },

      linkify: function(inputText, options) {
         /* client side linkify */
         options = jQuery.extend({
            linkClass: 'url',
            targetBlank: true
         }, options || {});

         inputText = inputText.replace(/\u200B/g, "");
         //URLs starting with http://, https://, or ftp://
         var replacePattern1 = /(src="|href="|">|\s>)?(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;ï]*[-A-Z0-9+&@#\/%=~_|ï]/gim;
         var replacedText = inputText.replace(replacePattern1, function($0,$1){ return $1?$0:encodeURIComponent('<a class="'+ options.linkClass + '" href="') + $0 + encodeURIComponent('"' + (options.targetBlank?' target="_blank"':'') + '>') + $0+ encodeURIComponent('</a>');});

         //URLS starting with www and not the above
         var replacePattern2 = /(src="|href="|">|\s>|https?:\/\/|ftp:\/\/)?www\.[-A-Z0-9+&@#\/%?=~_|!:,.;ï]*[-A-Z0-9+&@#\/%=~_|ï]/gim;
         var replacedText = replacedText.replace(replacePattern2, function($0,$1){ return $1?$0:encodeURIComponent('<a class="'+ options.linkClass + '" href="http://' + $0 + '"' + (options.targetBlank?' target="_blank"':'') + '>'+ $0+ '</a>');});

         //Change email addresses to mailto:: links
         var replacePattern3 = /([\.\w]+@[a-zA-Z_]+?\.[a-zA-Z]{2,6})/gim;
         var replacedText = replacedText.replace(replacePattern3, '<a class="' + options.linkClass + '" href="mailto:$1">$1</a>');
         return replacedText;
      },

      // back to top
      backtotop: function() {
         var $backToTopTxt = "返回顶部", $backToTopEle = jQuery('<div class="backToTop"></div>').appendTo(jQuery("body"))
               .text($backToTopTxt).click(function() {
                    jQuery("html, body").animate({ scrollTop: 0 }, 120);
            }), $backToTopFun = function() {
                var st = jQuery(document).scrollTop(), winh = jQuery(window).height();
                (st > 0)? $backToTopEle.show(): $backToTopEle.hide();
                //IE6下的定位
                if (!window.XMLHttpRequest) {
                    $backToTopEle.css("top", st + winh - 166);
                }
            };
            jQuery(window).bind("scroll", $backToTopFun);
            jQuery(function() { $backToTopFun(); });
       }
   };

   if (methods[method] ) {
      return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
   } else if ( typeof method === 'object' || ! method ) {
      return methods.init.apply( this, arguments );
   } else {
      $.error( 'Method ' +  method + ' does not exist on jobUtil' );
   }   

};

jQuery.fn.jobLocation = function(method) {

   var methods = {
      getProvince: function(options, defaultvals, callback) {
         var target = this;

         jQuery.getJSON(options.getprovinceurl, function(data) {
               try {
                     var s = data;
                     if(!s.province || s.province.length <= 0)
                        return '';

                     var output = [];

                     if(!options.helpmsg || options.helpmsg == "1")
                        output.push("<option selected value=''>--请选择--</option>");
                     else if(options.helpmsg == "2")
                        output.push("<option selected value=''>--不限--</option>");

                     var defvalue = [];
                     if(defaultvals && defaultvals.length > 0)
                        defvalue = defaultvals;
                     else
                        defvalue[defvalue.length] = target.attr("defvalue");

                     for(var i=0; i<s.province.length; i++)
                     {
                        if(jQuery.inArray(s.province[i].provinceid, defvalue) != -1)
                           output.push('<option selected value="' + s.province[i].provinceid + '">' + s.province[i].province + '</option>');
                        else
                           output.push('<option value="' + s.province[i].provinceid + '">' + s.province[i].province + '</option>');
                     }

                     target.html(output.join(''));
                     if(callback)
                        callback.apply(target);
               } catch(e) {}
         });

      },

      getCity: function(options, pid, city) {
         var target = this;
         if(!pid || pid.length <= 0) {
            if(!options.helpmsg || options.helpmsg == "1")
               target.html("<option selected value=''>--请选择--</option>");
            else
               target.html("<option selected value=''>--不限--</option>");
            return;
         }

         jQuery.getJSON(getUrlQuery(options.getcityurl, "p="+encodeURIComponent(pid)), function(data) {
            try {
                  var s = data;
                  if(!s.city || s.city.length <= 0)
                     return '';

                  var output = [];

                  if(!options.helpmsg || options.helpmsg == "1")
                     output.push("<option selected value=''>--请选择--</option>");
                  else if(options.helpmsg == "2")
                     output.push("<option selected value=''>--不限--</option>");

                  var defvalue = target.attr("defvalue");

                  for(var i=0; i<s.city.length; i++) {
                     if(defvalue && defvalue == s.city[i].cityid)
                        output.push('<option selected value="' + s.city[i].cityid + '">' + s.city[i].city + '</option>');
                     else
                        output.push('<option value="' + s.city[i].cityid + '">' + s.city[i].city + '</option>');
                  }

                  target.html(output.join(''));

                  // update city
                  if(city) {
                     // current value
                     var value = jQuery('option:selected', target).val();
                     var text = jQuery('option:selected', target).text();
                     if(value.length <= 0)
                        text = "";
                     city.val(text);

                     target.change(function() {
                        value = jQuery('option:selected', this).val();
                        text = jQuery('option:selected', this).text();
                        if(value.length <= 0)
                           text = "";
                        city.val(text);
                     });
                  }

               } catch(e) {}
         });
      },

      init: function(options) {
         /* This assume id_state, id_city, state, city ordering. It's okay if one of them is missing
          * state/city is text field */
         /* this is id_state */
         var id_city =null, state = null, city = null;

         if(this.next().is('select')) {
            id_city = this.next();
            state = id_city.next();
            city = state.next();
         }
         else if(this.next().is('input'))
           state = this.next();

         if(state || id_city) {
            this.change(function() {
               if(state) {
                  value = jQuery('option:selected', this).val();
                  text = jQuery('option:selected', this).text();
                  if(value.length <= 0)
                     text = "";
                  state.val(text);
                  city.val("");
               }

               if(id_city)
                  id_city.jobLocation("getCity", options, this.value, city);
            });
         }

         if(!id_city)
            return;

         /* immediately trigger city request */
         id_city.jobLocation("getCity", options, (this.val().length > 0 ? this.val() : this.attr("defvalue")), city);

      }
   };

   if (methods[method] ) {
      return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
   } else if ( typeof method === 'object' || ! method ) {
      return methods.init.apply( this, arguments );
   } else {
      $.error( 'Method ' +  method + ' does not exist on jobLocation' );
   }   

};

jQuery.fn.setEmployer = function(method) {
   var methods = {
      init: function() { },

      changeHireType: function (type, callback) {
         if(type=='I')
         {
            /* individual */
            jQuery("#company_info2").hide();
            jQuery("#company_info3").hide();
            jQuery("#company_info4").hide();
            jQuery("#label_comp_name").hide();
            jQuery("#label_individual_name").show();
            jQuery("#contact_name").removeClass("required");
            jQuery("#id_comp_type").removeClass("required");
            jQuery("#id_industry").removeClass("required");
         }
         else if(type=='C')
         {
            /* company */
            jQuery("#company_info2").show();
            jQuery("#company_info3").show();
            jQuery("#company_info4").show();
            jQuery("#label_comp_name").show();
            jQuery("#label_individual_name").hide();
            jQuery("#contact_name").addClass("required");
            jQuery("#id_comp_type").addClass("required");
            jQuery("#id_industry").addClass("required");
         }
         else if(type=='H') {
            /* headhunter */
            jQuery("#company_info2").hide();
            jQuery("#company_info3").hide();
            jQuery("#company_info4").show();
            jQuery("#label_comp_name").show();
            jQuery("#label_individual_name").hide();
            jQuery("#contact_name").addClass("required");
            jQuery("#id_comp_type").removeClass("required");
            jQuery("#id_industry").removeClass("required");
         }

         if(callback) callback(window, type);

         return true;
      }
   };

   if (methods[method] ) {
      return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
   } else if ( typeof method === 'object' || ! method ) {
      return methods.init.apply( this, arguments );
   } else {
      $.error( 'Method ' +  method + ' does not exist on setEmployer' );
   }
   
};

jQuery.fn.jobSpec = function(method) {
   var methods = {
      getCategory: function(options) {

         var target = this;

         jQuery.getJSON(options.getcategoryurl, function(data) {
               try {
                     var s = data;
                     if(!s.category || s.category.length <= 0)
                        return '';

                     var output = [];

                     if(!options.helpmsg || options.helpmsg == "1")
                        output.push("<option selected value=''>--请选择--</option>");
                     else if(options.helpmsg == "2")
                        output.push("<option selected value=''>--不限--</option>");

                     var defvalue = target.attr("defvalue");
                     for(var i=0; i<s.category.length; i++)
                     {
                        if(defvalue && defvalue == s.category[i].id)
                           output.push('<option selected value="' + s.category[i].id + '">' + s.category[i].category + '</option>');
                        else
                           output.push('<option value="' + s.category[i].id + '">' + s.category[i].category + '</option>');
                     }
                     target.html(output.join(''));
               } catch(e) {}
         });

      },

      getSpec: function(options, cid) {
         var target = this;
         if(!cid || cid.length <= 0) {
            if(!options.helpmsg || options.helpmsg == "1")
               target.html("<option selected value=''>--请选择--</option>");
            else
               target.html("<option selected value=''>--不限--</option>");
            return;
         }

         jQuery.getJSON(getUrlQuery(options.getspecurl, "c="+encodeURIComponent(cid)), function(data) {
               try {
                     var s = data;
                     if(!s.jobspec || s.jobspec.length <= 0)
                        return '';

                     var output = [];

                     if(!options.helpmsg || options.helpmsg == "1")
                        output.push("<option selected value=''>--请选择--</option>");
                     else if(options.helpmsg == "2")
                        output.push("<option selected value=''>--不限--</option>");

                     var defvalue = target.attr("defvalue");

                     for(var i=0; i<s.jobspec.length; i++)
                     {
                        if(defvalue && defvalue == s.jobspec[i].id)
                           output.push('<option selected value="' + s.jobspec[i].id + '">' + s.jobspec[i].specialization + '</option>');
                        else
                           output.push('<option value="' + s.jobspec[i].id + '">' + s.jobspec[i].specialization + '</option>');
                     }

                     target.html(output.join(''));
               } catch(e) {}
         });
      },

      init: function(options) {
         /* state/city is text field */

         var id_spec = null;

         if(this.next().is("select"))
            id_spec = this.next();

         if(id_spec) {
            this.change(function() {
                id_spec.jobSpec("getSpec", options, this.value);
            });

            /* immediately trigger spec request */
            id_spec.jobSpec("getSpec", options, this.attr("defvalue"), 1);
         }
      }
   };

   if (methods[method] ) {
      return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
   } else if ( typeof method === 'object' || ! method ) {
      return methods.init.apply( this, arguments );
   } else {
      $.error( 'Method ' +  method + ' does not exist on jobSpec' );
   }

};

jQuery.fn.jobSelect = function(method) {

   var methods = {
      showDialog: function(options)
      {
         var curObj = this;
         var listurl = options.listurl;
           
         jQuery.fx.speeds._default = 1000;
         if(jQuery("#floatcontainer").length > 0) {
            jQuery('#floatcontainer').remove();
         }
        
         jQuery('body').append('<div class="modal hide fade resume_dialogposition" style="position:absolute;" id="floatcontainer">'+
                '<div class="modal-header">'+
                   '<button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>'+
                   '<h3>'+options.title+'</h3>'+
                '</div>'+
                '<div class="modal-body" id="floatcontainer_body"></div>'+
             '</div>');

         var scrolltop = $(window).scrollTop();
         $("#floatcontainer").css({top:scrolltop+75}).modal('show');
        
         //fix modal div caching issue
         $('#floatcontainer').on('show', function () {
            $(this).css('visibility', 'visible');
         });
        
         $('#floatcontainer').on('hidden', function () {
            $(this).css('visibility', 'hidden').show();
         });

         curObj.jobSelect("displayJob", options);
      },

      displayJob: function(options)
      {
         var data = {};
         var curObj = this;
         var listurl = options.listurl;
         var container = jQuery('#floatcontainer_body');
        
         if(options.data) {
            data = options.data;
         }
        
         container.undelegate();

         jQuery.ajax({
            url: options.listurl,
            data: data,
            cache: false,
            beforeSend: function(xhr, settings) {
               showLoading(jQuery(".itemlist", container));
            },
            success: function(data) {
               container.html(data).delegate("a.search_btn", "click", function(event) {
                     event.stopPropagation();
                     var q = $.trim(jQuery('.search_input', container).focus().val());
                     options.listurl = jQuery(this).attr("href").replace('%q', encodeURIComponent(q));
                     curObj.jobSelect("displayJob", options);
                     return false;
               }).delegate("a.displaylist", "click", function(event) {
                     event.stopPropagation();
                     if(!jQuery(this).hasClass("cur_a")) {
                        options.listurl = jQuery(this).attr("href");
                        curObj.jobSelect("displayJob", options);
                     }
                     return false;
               }).delegate("a.link", "click", function(event) {
                     event.stopPropagation();
                     jQuery('.link', container).removeClass('cur_a');
                     jQuery(this).addClass('cur_a');
               }).delegate("a.calendarview", "click", function(event) {
                  var target = jQuery(this);
                  event.stopPropagation();
                  jQuery('.calendarview', container).removeClass('cur_a');
                  target.addClass('cur_a');
                  if ( $.isFunction(options.calendarview) ) {
                     options.calendarview.apply(target);
                  }
                  return false;
               }).delegate("a.selectjobconfirm","click",function(event){
                  event.stopPropagation();
                  var target = jQuery('#floatcontainer');
                  if($.isFunction(options.selected)){
                     options.selected.apply(target);
                  }
               }).delegate("a.selectjobcancel",'click',function(event){
                  event.stopPropagation();
                  var target = jQuery('#floatcontainer');
                  if($.isFunction(options.emptySelected)){
                     options.emptySelected.apply(target);
                  }
               });
               jQuery('.search_input', container).keydown(function(e) {
                  if(e.which == 13) {
                     e.preventDefault();
                     jQuery('a.search_btn', container).trigger('click');
                  }
               });
               jQuery('#clear_search', container).click(function() {
                  var target = jQuery('#floatcontainer');
                  if($.isFunction(options.emptySelected)){
                     options.emptySelected.apply(target);
                  }
                  options.data.job_id = '';
                  options.listurl = jQuery('a.search_btn', container).attr("href").replace('%q', '');
                  curObj.jobSelect("displayJob", options);
                  return false;
               });
              
               jQuery("#floatcontainer").show();
            } 
         });

      },

      hideDialog: function()
      {
         jQuery("#floatcontainer").modal("hide");
      },

      init: function(options) {
         var curObj = this;
        
         options = jQuery.extend({
            title: '选择职位'
         }, options || {});
        
         curObj.jobSelect('showDialog', options);
      }

   };

   if (methods[method] ) {
      return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 ));
   } else if ( typeof method === 'object' || ! method ) {
      return methods.init.apply( this, arguments );
   } else {
      $.error( 'Method ' +  method + ' does not exist on jobSelect' );
   }   
 
};

你可能感兴趣的:(util)