Skip to content
This repository has been archived by the owner on Jun 1, 2023. It is now read-only.

tab-content :before-change params #40

Closed
MatthiasHertel opened this issue Aug 31, 2017 · 22 comments
Closed

tab-content :before-change params #40

MatthiasHertel opened this issue Aug 31, 2017 · 22 comments

Comments

@MatthiasHertel
Copy link

hi,

is it possible to retrieve the following params in the :before-change methods.

  • prevIndex
  • nextIndex

because i want show for each tab-content an info pannel outside the vue-form component and i dont know how can i retrieve the current and the intendend tab-content-index.

thanks for helping
matthias

@MatthiasHertel
Copy link
Author

furthermore:

i have implemented it in in the form-wizard a @on-change method called renewInfo , see here:

<form-wizard
                  @on-complete="onComplete"
                  color="#3097D1"
                  error-color="#a94442"
                  title="" subtitle=""
                  back-button-text="Zurück"
                  next-button-text="Weiter"
                  finish-button-text="Raumbuchung abschicken"
                  @on-change="renewInfo"
                  >

and now in the in the renewInfo i can retrieve the prevIndex and nextInfo ... it works but...

renewInfo: function(prevIndex, nextIndex) {
        if (this.$refs.firstTabForm.validate()) {
          $('#message0').hide();
          $('#message1').hide();
          $('#message2').hide();
          $('#message3').hide();
          $('#message'+nextIndex).show();
        } else {
        }

        // if (this.$refs.secondTabForm.validate()) {
        // } else {
        // }
        // if (this.$refs.thirdTabForm.validate()) {
        // } else {
        // }

      }

if the tab-content is valid - the infopanel would switch ... but not the tab-content (just if i clicked on the wizard-nav cycles, on the buttons the tab-switch will initiated correctly).

i hope u understand my issue.

@cristijora
Copy link
Collaborator

Sorry for that @MatthiasHertel but the last part of the issue is not very clear for me. Would you be willing to make a jsfiddle with what you have or at least the idea behind what you want to implement?

@MatthiasHertel
Copy link
Author

hi chris ,

first of all - thanks for the quick reply

use-case:

i would like to display a description field for the respective tab content.

here is the fiddle:
https://jsfiddle.net/rjadm584/1/

there are 3 tabs ... and 3 info panels ... if the user is on tab1 the infopanel 1 is shown and so on.

the problem is , if i clicked on the pills in the nav and the form is valid it does not switch the tab-content , can u reproduce it ?

if i use the buttons below - it will work correctly.

i know the solution is a hack ... maybe u have a better one for the use-case.

thanks for your help!
m.

@cristijora
Copy link
Collaborator

cristijora commented Aug 31, 2017

For me on chrome, the tab-content switches both when clicking the buttons as well as the circles.
Regarding the second part, isn't it easier to display the info together with each form? This way you won't have to deal with additional logic of showing/hiding it. Like this
https://jsfiddle.net/rjadm584/7/

@MatthiasHertel
Copy link
Author

isn't it easier to display the info together with each form? This way you won't have to deal with additional logic of showing/hiding it. Like this ...

i know its easier ... the problem is i want show the infopanel in another column

<div class="row">
  <div class="col-md-9">
    <form action="
      
        <vue-form-wizard>
          ...
        </vue-form-wizard>
      
    "></form>
  </div>
  <div class="col-md-3">
    <div class="panel">
      Infopanel 
    </div>
  </div>
</div>

@cristijora
Copy link
Collaborator

cristijora commented Aug 31, 2017

Hm then I don't know a clean way of doing this since the current on-change executes before changing tabs.

I have 2 options in mind which I could implement today

Option 1

<form-wizard @on-complete="onComplete" 
                      shape="tab"
                      color="#9b59b6">
  <template scope="wizardProps">
            <tab-content title="Personal details"
                         icon="ti-user">
              My first tab content
            </tab-content>
            <tab-content title="Additional Info"
                         icon="ti-settings">
              My second tab content
            </tab-content>
            <tab-content title="Last step"
                         icon="ti-check">
              Yuhuuu! This seems pretty damn simple
            </tab-content>
     </template>
</form-wizard>

Simply wrap the content in a scoped slot. The functionality would be the same but you will have access to some information from the wizard (e.g activeTabIndex, isLastStep, nextTab , prevTab methods)

Option 2.

<form-wizard @on-complete="onComplete" 
                       @on-tab-changed="handleTabChanged"
                      shape="tab"
                      color="#9b59b6">
            <tab-content title="Personal details"
                         icon="ti-user">
              My first tab content
            </tab-content>
            <tab-content title="Additional Info"
                         icon="ti-settings">
              My second tab content
            </tab-content>
            <tab-content title="Last step"
                         icon="ti-check">
              Yuhuuu! This seems pretty damn simple
            </tab-content>
</form-wizard>

// inside js
handleTabChanged(prevIndex, nextIndex){
  this.activeIndex = nextIndex;
}

For option 2, the event will be triggered exactly when the tab is going to change. If the tab is invalid, then the event won't be triggered since it won't change.
Based on that, you could do something like:

<div class="panel1" v-if="activeIndex === 0"></div>
<div class="panel1" v-else-if="activeIndex === 1"></div>
<div class="panel1" v-else-if="activeIndex ===2"></div>
....

Tell me which option you think would suit better

@MatthiasHertel
Copy link
Author

MatthiasHertel commented Aug 31, 2017

hm, i think option 1 is more universally usable with the access to the information from the wizard

but how it will work ? (sorry i am a vue new be)

Simply wrap the content in a scoped slot.

how can i inject the respective tab-description to col-md-3 from the vue-form-wizard>tab-content?

<div class="row">
  <div class="col-md-9">
    <form action="">
      
    <vue-form-wizard>
      <template scope="wizardProps">
        <tab-content title="Personal details"
                     icon="ti-user">
          My first tab content
        </tab-content>
        <tab-content title="Additional Info"
                     icon="ti-settings">
          My second tab content
        </tab-content>
        <tab-content title="Last step"
                     icon="ti-check">
          Yuhuuu! This seems pretty damn simple
        </tab-content>
      </template>
    </vue-form-wizard>
</form>
  </div>
  <div class="col-md-3">
    <div class="panel">
      <wizardProps></wizardProps>

      or ???

      <slot name="wizardProps"></slot>
    </div>
  </div>
</div>

option 2 is for me more understandable

<div class="row">
  <div class="col-md-9">
    <form action="">
      
    <vue-form-wizard
      @on-tab-changed="handleTabChanged"
      >
      <template scope="wizardProps">
        <tab-content title="Personal details"
                     icon="ti-user">
          My first tab content
        </tab-content>
        <tab-content title="Additional Info"
                     icon="ti-settings">
          My second tab content
        </tab-content>
        <tab-content title="Last step"
                     icon="ti-check">
          Yuhuuu! This seems pretty damn simple
        </tab-content>
      </template>
    </vue-form-wizard>
</form>
  </div>
  <div class="col-md-3">
    <div class="panel">
      <div class="panel1" v-if="activeIndex === 0">here infopanel1</div>
      <div class="panel1" v-else-if="activeIndex === 1">here infopanel1</div>
      <div class="panel1" v-else-if="activeIndex ===2">here infopanel1</div>
    </div>
  </div>
</div>

@cristijora
Copy link
Collaborator

I think I will implement them both since they might have different use cases. Indeed the second option would be more suited for your use-case

@MatthiasHertel
Copy link
Author

great thanks!

@hydraheim
Copy link

There seems to be a bug with :before-change. If you throw in a parameter with the function call, it gets loaded at least twice.

JSFiddle: https://jsfiddle.net/55pwdzaq/

@cristijora
Copy link
Collaborator

cristijora commented Sep 4, 2017

@hydraheim by default before-change is without parameters.

If you need parameters, use an arrow function which calls your function instead.

:before-change="()=>beforeTabSwitch(1)"

beforeTabSwitch: function(value){
     alert("This is called before switchind tabs")
     return true;
   }

See updated fiddle
https://jsfiddle.net/55pwdzaq/3/

@cristijora
Copy link
Collaborator

@MatthiasHertel Here is an updated fiddle for your example
https://jsfiddle.net/CristiJ/rjadm584/21/

I changed the current on-change event so it's called only when tabs actually change not before they change. This is not yet published to npm and you might need to do a hard page refresh once you load the fiddle so the new version of form-wizard is downloaded correctly.

@cristijora
Copy link
Collaborator

There is also a simple option if you want to keep in sync the current active index
https://jsfiddle.net/CristiJ/rjadm584/29/

You could

 <form-wizard  :start-index.sync="activeIndex"
                     
// js
data(){
 return {activeIndex: 0}
}

You can choose whatever seems easier for you

@Coreusa
Copy link

Coreusa commented Sep 5, 2017

If a "false" is never returned from a before-changed function, the error "t is not defined" will show in the console. Suggestion: Always assume false unless an explicit "true" has been returned.

Fiddle: https://jsfiddle.net/xkvqnLco/

Remembering to always return either false or true make the example work, but feels tacky and uneccessary.

Fiddle: https://jsfiddle.net/zgrxrok5/

@cristijora
Copy link
Collaborator

cristijora commented Sep 5, 2017

@Sobient I could do that but for me this explicit returning creates more predictable and readable code.

beforeTabSwitch: function(s) {
     if (s === 0) {
        if (this.name.length > 2) {
          return true;
        } else {
          this.formError = true;
          return false; 
        }
     } 
     return true
   }

So in this case, with the explicit returns it's pretty clear that if the step is 0 and the name has length > 2 the validation succeeds and in other cases, when the step is not 0 or the length is incorrect the validation fails.

@MatthiasHertel
Copy link
Author

@MatthiasHertel Here is an updated fiddle for your example
https://jsfiddle.net/CristiJ/rjadm584/21/

@cristijora thx great ... from me the issue can be closed

@cristijora
Copy link
Collaborator

Will close this when I publish to npm later on today

@Coreusa
Copy link

Coreusa commented Sep 5, 2017

Looking at how VueJS does it, when custom logic is involved, there are required return values for them to work.

For instance, vuejs' router require you to call next() when using the beforeEach method (i.e authentification on routes), otherwise route propagation will never complete. Docs: https://router.vuejs.org/en/advanced/navigation-guards.html

@cristijora
Copy link
Collaborator

Release 0.6.5

@hsalem7
Copy link

hsalem7 commented Jan 26, 2018

Hello,
I wanted to ask if it is possible to view tab title inside the circle instead of an icon.
in case I don't have an icon but I need to add a title instead

thank you

@cristijora
Copy link
Collaborator

Hi @hassanalisalem Please open an issue for that as github doesn't notify/send email when commenting on old issues. As for the quesiton, you can customize that via wizard-step slot and it's internal slots
https://jsfiddle.net/CristiJ/bt5dhqtf/1888/

Info on the step slot http://vuejs.creative-tim.com/vue-form-wizard/#/?id=step-slot
Details on how it's implemented https://github.com/cristijora/vue-form-wizard/blob/master/src/components/WizardStep.vue

@Provyzor
Copy link

Provyzor commented Oct 2, 2019

Hi!
Is it possible to hide a tab in certain condition, and then to show (when returning to previous tabs) in the same order as it was before hiding? It appears at the end...

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants