最近工作一直跟匯入的資料處理有關,弄到自己有點頭痛,其中比較頭痛的是 想要美觀的 Wizard 或是 Step 這種步驟式的plugin 大多都沒有達到我的需求
後來在網路上看到一段很簡略的 Step Wizard 應用上了一個案子,運行的很順暢。
不過還是不敷我使用,一直大量用到了之後決定寫成個 plugin 先寫個雛形方便未來修改擴增。
因為是用 Bootstrap 所以CSS範例也是跑 Bootstrap
HTML 部分很簡單 最主要就是 id=wizard 要包住 wizard-sidebar 導航條,wizard-content 變成內容,一對一對應,內容不需要打標題,產生後會自動 的塞入
<div class="row wizard" id="wizard"> <div class="col-md-3"> <div class="wizard-sidebar list-group"> <a>Import Step1</a> <a>Import Step2</a> <a>Import Step3</a> <a>Import Step4</a> <a>Import Step5</a> <a>Import Step6</a> </div> </div> <div class="col-md-9"> <div id="step1" class="well wizard-content">1</div> <div id="step2" class="well wizard-content">2</div> <div id="step3" class="well wizard-content">3</div> <div id="step4" class="well wizard-content">4</div> <div id="step5" class="well wizard-content">5</div> <div id="step6" class="well wizard-content">6</div> </div> </div>
JS的部分
$('#wizard').wizard({ step_prev : 'Prev Step', step_next : 'Next Step', move3to4 : function(){ alert('3to4'); oWizard.moveToAction('next'); }, moveTo4after : function(){ alert('this is 4'); }, move4to3 : function(){ alert('4to3'); }, move4to5 : function(){ return false; }, move3to2 : function(){ alert('3to2'); } })
基本上可以不用設定,想自訂上一步下一步的字串就自己新增然後是 event
在執行過程中會有 第 N 步到第 N+1 步的動作,只需要寫在 event 裡面 也很直觀的用數字呈現 如果回傳 return false 整個 步驟就暫停,適合對應 Validation 類型的套件
然後有個 倒退的事件,這個不少 plugin 都沒有做,事件寫法是 n to n-1 這種寫法適合用在RESET 資料,當然只要 return false 一樣可以停止退回
另外還寫了一個 moveTo?after 就是移動到 這個步驟之後要執行的 Function ,比較適合用選擇後載入某些AJAX 資料或是欄位關閉開啟變動,以下可以看範例
JS 沒有正式命名或是打上資料,目前先放這樣 XD需要自行複製存為 JS 檔
(function($){ $.fn.wizard = function(data,opt) { var $that = $(this), options = { step_prev : 'Prev', step_next : 'Next' }; if( jQuery.isPlainObject(data) ) { opt = data; } $.extend(options,data); $.each(options,function(k,v){ if( jQuery.isFunction(v) ) { $that.bind('wizard.'+k,v) } }) function init(){ $that.data({ 'now_step' : 0 , }); var links = $that.data('wizard-links'); $that.find('.wizard-sidebar > a').each(function(i,n){ if( typeof links != 'undefined' ) { links = links.add(n); }else{ links = $(n); } var title = n.innerHTML; $(n) .attr('href','#') .attr('data-step',(i+1) ) .data('title',title) .addClass('list-group-item') .html('<h4 class="list-group-item-heading">'+title+'</h4>'); }) $that.data('wizard-links',links); var wells = $that.find('.wizard-content'); $that.data('wizard-wells',wells); wells.hide().each(function(i,n){ var $well = $(n); $well.attr('data-step',(i+1)); if( ! $well.find('.header').lenght ){ $well.prepend('<div class="header"><h2>'+ links.eq(i).data('title')+'</h2></div>'); } if( ! $well.find('.btn-step-area').lenght ){ $btnArea = $('<ul />', { class : 'btn-step-area pager' }).appendTo( $well ); } if( i>0 && ! $well.find('.btn-prev').lenght ){ $btnArea.append('<li class="previous"><a href="#" class="btn btn-info btn-prev">'+options.step_prev+'</a></li>') } if( ! $well.find('.btn-next').lenght ){ $btnArea.append('<li class="next"><a href="#" class="btn btn-danger btn-next">'+options.step_next+'</a></li>') } }) $that.on('click','.btn-next,.btn-prev',function(e){ var caseMove = $(this).hasClass('btn-next') ? 'next' : 'prev'; var $p = $(this).closest('div[data-step]'); var step = parseInt( $p.data('step') ,10 ) step = caseMove == 'next' ? step+1 : step-1; console.log(step) $that.moveToAction( step ); e.preventDefault(); }) $that.on('click','.wizard-sidebar > a',function(e){ //var index = $that.data('links').index( this ) var index = $('.wizard-sidebar > a').index( this ); if ( !$(this).hasClass('disabled')) { $that.moveToAction( index+1 ); } e.preventDefault(); }); $.extend($that,{ eventMoveTo : function( form , to ) { var result = true; form = parseInt(form,10);to = parseInt(to,10); var case_event = $that.createTo(form,to); for(x in case_event ){ var ev = $that.triggerHandler('wizard.move'+case_event[x]); if( ev === false ){ result = false; break; } } return result; }, createTo : function createTo( a , b ) { var arr = []; if( b > a ) for(var i = a;i < b;i++) arr.push( i + 'to' + (i+1) ); else if( a > b ) for(var i = a;i > b;i--) arr.push( i + 'to' + (i-1) ); return arr; }, moveToAction : function(new_step){ var now_step = $that.data('now_step'); if( typeof new_step =='string'){ new_step = (new_step=='next') ? now_step+1 : now_step-1; } var $item = $that.data('wizard-links').filter('[data-step="'+new_step+'"]'); if( $that.eventMoveTo( $that.data('now_step') , new_step ) ) { $that.data('now_step',new_step) $that.data('wizard-links').addClass('disabled').removeClass('active'); $item.addClass('active'); $item.removeClass('disabled').prevAll().removeClass('disabled'); $that.data('wizard-wells').hide().filter('[data-step="'+new_step+'"]').show(); $that.triggerHandler('wizard.moveTo'+new_step+'after'); } } }) $that.data('wizard' ,true); $that.moveToAction(1); } var initz = $that.data('wizard'); if( initz !== true) { init(); } return $that; } })(jQuery);