最近工作一直跟匯入的資料處理有關,弄到自己有點頭痛,其中比較頭痛的是 想要美觀的 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);