Wizard for the advanced tab panel

I am facing a challenge with my advanced TabPanel Wizard. It consists of 4 tabs, each serving as its own form to allow for validation within the tab itself. The issue I am encountering is related to the validation behavior of non-rendered tabs.

One problem is that a non-rendered tab incorrectly registers as valid even when it has an empty value and the field is set to allowBlank: false. Conversely, there are instances where a tab with a value set is marked as invalid.

Another quirk is that I need to call this.getViewModel().notify() when the tab panel loads to prevent the initial form from being deemed invalid. This could be due to binding delay, which I can manage for now.

While using deferredRender: false would resolve this issue, I prefer not to use it due to performance concerns in my application where each tab contains substantial content and functionality.

In a Fiddle example, only 3 out of 4 tabs are enabled despite the third tab having data from its model. This leads to incorrect validity checks triggering further methods.

  • Tab3 incorrectly thinks it's invalid despite having a value bound to it and allowBlank: false set
  • Tab4 wrongly appears valid while it should be marked as invalid without a value and allowBlank: false set

I'm seeking insights or suggestions on how to address these issues. Am I approaching this problem incorrectly?

Answer №1

The reason this issue is occurring is due to the behavior of view models and binding not aligning with your expectations.

When you define a field like this:

{ fieldLabel: 'Value3', xtype: 'textfield', name: 'value2', allowBlank: false,
  bind: { value: '{model1.value2}' }
}

The field is initially created without a value because it has been bound instead of explicitly defined. The binding does not take effect immediately for performance reasons and typically binds after the tab is rendered, which explains why rendering the tab works for you.

As a result, when you check the validity of Tab 3, it fails because the values have not yet been bound. This becomes clearer if you modify the log statement on line 24 as follows:

console.log(form.owner.title, form.getValues(), form.owner.rendered, isValid)

With this adjustment, upon first rendering the tab panel, you will observe the following output (excluding comments):

afterrender // triggers the view model to notify.
activate
checking
tab1 Object {value: "blah"} true true  // Value bound because it was rendered.
tab2 Object {value: ""} false true
tab3 Object {value2: ""} false false // Value not bound because it is not rendered
checking
tab4 Object {} false true // No properties yet...

If you omit this.getViewModel().notify(), the output changes to:

afterrender
activate
checking
tab2 Object {} false true
tab3 Object {} false true
tab4 Object {} false true
tab1 Object {value: "blah"} true true

Note the difference in order.

Essentially, individual forms on the tabs remain dataless until their field values are bound. Without fields, they are deemed valid. Calling isValid prompts the fields to be defined but still not bound. Consequently, tab3 is considered invalid (lacking data binding), leading to tab 4 being disabled.

If you forego using viewModel.notify(), during the initial checkValidity() call, tab1 lacks data binding. Consequently, it is deemed invalid (having fields but no values), impacting tab2, and so forth.

The validation ultimately resolves itself, but checks only occur when transitioning from true to false, not vice versa, influencing the observed behavior.

To rectify this situation, there are likely multiple approaches available. One effective method involves extracting values from the viewModel during panel initComponent and explicitly assigning them to the fields during creation. This ensures they start with the correct state, enabling them to pass the validity assessment immediately.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to maintain the position of components (such as a Card component) when one is expanded in a Material-UI and ReactJS project

Currently, I am working with an expandable Card component from Material-UI and using flex for aligning the components. However, when one card expands, it affects the positioning of the other components in the row: https://i.stack.imgur.com/vGxBU.png What ...

What is the best way to divide an array into pairs and store them in separate arrays?

I'm attempting to challenge my JavaScript skills and faced with a dilemma. There is an array containing data var array = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];. The goal is to pair the elements and generate a new array of arrays such as var newArray = [[1 ...

An AJAX function nested within another AJAX function

Is there a way for me to return the second ajax call as the result of the ajax function? I could use some assistance with this. function ajax(url: string, method:string, data:any = null) { var _this = this; return this.csrfWithoutDone().done(funct ...

The invocation of $.ajax does not work as a function

I'm encountering an issue when running npm start and trying to access the browser, I keep getting this error message in the stack trace. Error: $.ajax is not functioning properly at findLocation (G:\CodeBase\ExpressApp\routes\ind ...

What is the best way to trigger a controller action when the datepicker's value changes?

Hello, I have a custom datepicker and I am trying to perform a calculation when the year is changed. The code provided below does not seem to work on onchange. I also attempted using the onchange attribute and calling a JavaScript function like this oncha ...

Animate sliding bar to move from the left using jQuery

I am currently experiencing an issue with a sliding animation on mouseover in the navigation. The animation works fine, but the problem arises when I hover over any menu item - the sliding bar starts from the very left instead of starting where the navigat ...

switchMap: Triggering multiple requests simultaneously (2)

Currently, I am utilizing Angular 2 RC-4 and facing an issue where a network request is being triggered twice whenever there is a change in the input box. This is what my code looks like: component.ts this.term = new Control(); this.suggestions = this. ...

The battle between dynamic PDF and HTML to PDF formats has been a hot

In my current project, I am developing multiple healthcare industry dashboards that require the functionality to generate PDF documents directly from the screen. These dashboards do not involve typical CRUD operations, but instead feature a variety of char ...

Filter the specific output in a generator function

I have a code snippet that I need help with. function* iterateRecord() { const db = yield MongoClient.connect(''); const collection = db.collection(''); const query = {} const cursor = collection.find(query); ...

Can you explain the process of a put request in Angular, Express, and Mongoose?

My colleague and I are currently deciphering the inner workings of a code snippet generated by a tutorial. Our main focus is on how the client/server communication flows once line 8 of factory.js is triggered: factory.js app.factory('postFactory&apo ...

The Express server powered by Node.js is failing to send responses back to HTTP requests initiated from a JavaScript file, despite successfully receiving and processing the requests

I am facing an issue with my setup where I have both a node-js server and an apache server running on the same machine. One of my javascript files is sending an HTTP request to the node-js server, which receives the file, reads the data, and puts it in the ...

Using jQuery, set a restriction on the total number of options in three dropdown menus to

I am currently facing a challenge with 3 dropdowns, each containing 8 options. My aim is to restrict the total selection across all three dropdowns to 8. For instance, if I choose 7 in the first dropdown, I should only be able to pick 1 in the next two. Si ...

Incorporating a hyperlink into an Iframe triggered by Fancybox2-AJAX, specific to the Iframe's unique identifier

One thing I have noticed is that everything seems to be working fine up until the point where I try to load it through fancybox via AJAX. An example of it working statically: <iframe id="videourl1" width="640" height="340" src="" frameBorder="0">& ...

Steps for invoking the next() function within the beforeRouterEnter guard

I've been grappling with this issue for countless hours now. I'm currently using Vue3 My goal is to implement a beforeRouterEnter guard in order to check the user's role upon login and direct them to the appropriate route accordingly. Once ...

Performing ajax requests with nested ajax calls within a loop

I'm facing a particular issue. My code structure involves nested/foreach loops with ajax calls like below: var children = []; $.fn.ajaxHelper.loadAjax({ url: someUrlReturningJsonOfChildren, cache: true, callback: function(options) { ...

How to Utilize findIndex to Validate the Presence of Elements in an Array of Objects using TypeScript

I need assistance in checking which properties from an array are present in another array of objects and which ones are not. My object structure is as follows: var tempObj=[{id: '1', color: 'red, blue, green', age: 27},{id: '2& ...

What is the process for importing specific modules from jQuery?

When working with webpack or browserify, what is the specific procedure required to import only the essential modules from jQuery as mentioned here? import {core, dimensions} from 'jquery' Unfortunately, this approach does not seem to be effect ...

Encountering invalid parameters while attempting to utilize the track.scrobble service from the Last.Fm API in a Node.js application

After successfully completing the Last.Fm authentication process following the instructions provided here, I received the session key without any issues. However, my attempts to make an authenticated POST request to the track.scrobble method of the Last.Fm ...

Issue - The 'defaultValue' is failing to load the state value, and the 'value' is not being updated when changed

My current setup involves an input field in my MovieInput.tsx file: <input id="inputMovieTitle" type="text" onChange={ e => titleHandleChange(e) } value={ getTitle() }> </input> This is how the titleHandleChange function ...

What is the best way to generate the message dynamically?

I have implemented the react-intl package for translation purposes in my project. Users have the option to choose between Spanish and English languages, with Spanish being the default language. When a user switches to English, all text should be dynamicall ...