Menu

Multiple Tabs with the same name issue

Users
2016-03-10
2016-03-10
  • federico piazza

    federico piazza - 2016-03-10

    Hello guys,

    I'm testing metawidget by creating a demo but having some issues with it. I'm trying to generate a couple of sections and show them by Jquery UI tabs. I could do it with tiny objects, however my object has 250 fields and it generates multiple sections (which is correct) but the problem is that it generates also multiple repeated sections with the same name. For instance:
    CMS|Flags|Other|CMS|Flags|Other|CMS|Flags|Other|CMS|Flags|Other|CMS|Flags|Other

    I just want:
    CMS|Flags|Other|

    Do you know why is happening this or how can I fix it?

    Thanks a lot.
    Federico

     
  • Kennard Consulting

    Can you send a small example project to support@metawidget.org?

    At a guess, though: are you putting 'section' attributes on each of your fields? This is not necessary, you only have to put them on the fields where the section changes. However, it's okay to do provided you are also sorting your fields such that you don't keep swapping back/forth between sections. You can sort your fields either by a) the natural order they appear in the JSON; b) explicitly using a 'propertyOrder' attribute.

     
    • federico piazza

      federico piazza - 2016-03-10

      Hi Kennard,

      At the beginning I put section attributes on some fields but noticed that lots of fields were added automatically so my sections which I didn't want. So, then I added more sections and wanted to put all the remaining fields in a 'Other' section, although this didn't solve my problem either.

      I have started with a hardcoded object, however the webservices returning the object does not ensure order, that's why I wanted to explicitly set tabs for all of them.

      I have sent the html sample to the email you provided above.

      Federico

       
  • Kennard Consulting

    There are a few different (and conflicting) points I need to make here:

    1. You have put your PropertyTypeInspector first in your CompositeInspector. This means it will be dictating the order of the returned fields (based on the natural ordering of the 'toInspect' object). You should probably put it second, after your custom Inspector, so that it just 'fills in' the property types, without dictating the ordering

    2. Your custom inspector is basically returning a JSON Schema, so you should use JsonSchemaInspector instead. Doing it your way, you'll have to check the 'names' array passed in to the function. If Metawidget is asking to inspect anything other than the root of the object (i.e. 'names' is not empty) you'll have to return an empty inspection result, or else you'll get an infinite loop. But JsonSchemaInspector takes care of this little detail for you.

    3. It's fine to explicitly set sections. But you must explicitly set order too, or else the natural ordering of the properties may jump back/forth between sections, and you'll end up with multiple tabs

    4. It sounds like explicitly setting sections is going to be cumbersome for you. If your webservices are returning abitrary objects, you'll want to keep your UI as arbitrary as possible. Therefore you might be better off using an InspectionResultProcessor to process the inspection result, rather than a custom Inspector to produce the inspection result. Then you can attach sections and sort fields without knowing much about what data is returned.

    <!DOCTYPE html>
    <html>
        <head>
            <script src="http://metawidget.org/js/4.2/metawidget-core.min.js" type="text/javascript"></script>
            <link rel="stylesheet" href="http://code.jquery.com/ui/1.9.2/themes/base/jquery-ui.css" />
            <script src="http://code.jquery.com/jquery-1.8.3.js"></script>
            <script src="http://code.jquery.com/ui/1.9.2/jquery-ui.js"></script>
            <script src="http://metawidget.org/js/4.2/metawidget-jqueryui.min.js" type="text/javascript"></script>
            <script type="text/javascript">
                var card  = {"id":0,"productId":0,"name":"","uniqueCardId":"","description":"","shortDescription":"","imageLink":"","linkUrl":"","importantDetails":"","mostAttractive":"","leastAttractive":"","expiryDate":"","apr":0,"introApr":0,"btFee":0,"yearlyFee":0,"lateFee":0,"lateFeeDetail":"","gracePeriod":"","issuer":"","cardCategory":"","cardType":"","rating":0,"cardStatus":"","creditRating":"","requiredCreditRating":"","cashAdvanceFee":"","minCreditLimit":0,"maxCreditLimit":0,"minDeposit":"","maxDeposit":"","applicationFee":"","participationFee":"","reloadFee":"","inactiveFee":"","bullets":"","introDetails":"","annualFeeDetails":"","creditNetwork":"","introductoryRateOffer":"","highlights":"","introBtMonths":"","introBtPercent":0,"overTheLimitFee":"","expirationDate":"","creditCategory":"","requiredCreditStanding":"","payout":0,"epc":0,"noOfClicks":0,"imageLink1":"","imageLink2":"","minAmountForRewardsPerDollarSpent":0,"maxCardValue":0,"typeofReward":"","rewardExpiration":"","rebateMinimum":0,"rebateMaximum":0,"additionalRebates":"","rebateDetails":"","pointDetails":"","mileDetails":"","rewardDetails":"","additionalPerks":"","importantNotations":"","chargeCardFlag":false,"bonusDetails":"","btFeeDetails":"","aprDetails":"","timePeriodMonthsorBillingCycles":"","cardRewardType":"","secureCardFlag":false,"noAnnualFeeFlag":false,"zeroAprFlag":false,"active":true,"createdDate":"","chFlag":false,"introMonthsLimit":"","rewardsPerDollarSpent":0,"rewardsPercentage":0,"btFeePercent":0,"defaultBtFeePercent":0,"prepaidFlag":false,"introBtApr":-1,"errorMessage":"","publicSiteRule":"","secureSiteRule":"","bonus":0,"bonusTime":"","bonusRequirement":0,"firstYearAnnualFeeWaived":false,"cardProviderSource":"","maxAmountForRewardsPerDollarSpent":0,"maxRewardOfferTime":"","gasrewardsPerDollarSpent":0,"gasrewardsPercentage":0,"gasminAmountForRewardsPerDollarSpent":0,"gasmaxAmountForRewardsPerDollarSpent":0,"gasmaxRewardOfferTime":"","groceriesRewardsPerDollarSpent":0,"groceriesRewardsPercentage":0,"groceriesMinAmountForRewardsPerDollarSpent":0,"groceriesMaxAmountForRewardsPerDollarSpent":0,"groceriesMaxRewardOfferTime":"","restaurantRewardsPerDollarSpent":0,"restaurantRewardsPercentage":0,"restaurantMinAmountForRewardsPerDollarSpent":0,"restaurantMaxAmountForRewardsPerDollarSpent":0,"restaurantMaxRewardOfferTime":"","entertainmentRewardsPerDollarSpent":0,"entertainmentRewardsPercentage":0,"entertainmentMinAmountForRewardsPerDollarSpent":0,"entertainmentMaxAmountForRewardsPerDollarSpent":0,"entertainmentMaxRewardOfferTime":"","travelRewardsPerDollarSpent":0,"travelRewardsPercentage":0,"travelMinAmountForRewardsPerDollarSpent":0,"travelMaxAmountForRewardsPerDollarSpent":0,"travelMaxRewardOfferTime":"","poorAprPurchase":0,"goodAprPurchase":0,"excellentAprPurchase":0,"activationFee":0,"monthlyFee":0,"balanceInquiryFee":0,"atmCashWithdrawalFeeNetwork":0,"atmCashWithdrawalFeeNonNetwork":0,"paperStatementFee":0,"custServiceFee":0,"directDepositFlag":false,"inactivityFee":0,"pinTransactionFee":0,"bankTellerCashWithdrawalFee":0,"achDebitFee":0,"dailyCashDepositLimit":0,"dailyATMWithdrawalLimit":0,"bonusFirst":0,"bonusTimesFirst":"","bonusRequirementFirst":0,"bonusSecond":0,"bonusTimesSecond":"","bonusRequirementSecond":0,"bonusThird":0,"bonusTimesThird":"","bonusRequirementThird":0,"bonusFourth":0,"bonusTimesFourth":"","bonusRequirementFourth":0,"bonusFifth":0,"bonusTimesFifth":"","bonusRequirementFifth":0,"dailySpending":0,"purchaseFee":0,"insuranceFlag":false,"conciergeFlag":false,"transferrableRewardsFlag":false,"sportsFlag":false,"rewardsCardFlag":false,"btCardFlag":false,"issuerEnum":"","avgRewardsRate":0,"otherRewardsPerDollarSpent":0,"otherRewardsPercentage":0,"bonusUsed":0,"displayOnWeb":false,"displayOnMobile":false,"nlfCardFlag":false,"stateCodes":"","rewardDetailText":"","introPurchaseAprPeriodText":"","introBtAprPeriodText":"","rewardsBonusText":"","signupBonusText":"","maxRewardsValue":0,"baseRewardsValue":0,"rewardDollarValue":0,"version":"","hasMultiBonus":false,"lowestApprovedScore":0,"highestApprovedScore":0,"averageApprovedScore":0,"approvalOddsFair":0,"approvalOddsGood":0,"approvalOddsVeryGood":0,"avgScoreFlag":false,"tcText":"","tcUrl":"","btText":"","editorial":"","categoryPros":"","categoryCons":"","categoryCreditStanding":"","categoryBestExcellentRank":0,"categoryBestGoodRank":0,"categoryBestFairRank":0,"categoryBestPoorRank":0,"categoryBestNoCreditRank":0,"categoryAirlineExcellentRank":0,"categoryAirlineGoodRank":0,"categoryAirlineFairRank":0,"categoryAirlinePoorRank":0,"categoryBalanceTransferExcellentRank":0,"categoryBalanceTransferGoodRank":0,"categoryBalanceTransferFairRank":0,"categoryBalanceTransferPoorRank":0,"categoryLowInterestExcellentRank":0,"categoryLowInterestGoodRank":0,"categoryLowInterestFairRank":0,"categoryLowInterestPoorRank":0,"categoryRewardsExcellentRank":0,"categoryRewardsGoodRank":0,"categoryRewardsFairRank":0,"categoryRewardsPoorRank":0,"categoryCashBackExcellentRank":0,"categoryCashBackGoodRank":0,"categoryCashBackFairRank":0,"categoryCashBackPoorRank":0,"categoryStudentExcellentRank":0,"categoryStudentGoodRank":0,"categoryStudentFairRank":0,"categoryStudentPoorRank":0,"categoryBusinessExcellentRank":0,"categoryBusinessGoodRank":0,"categoryBusinessFairRank":0,"categoryBusinessPoorRank":0,"categorySecureExcellentRank":0,"categorySecureGoodRank":0,"categorySecureFairRank":0,"categorySecurePoorRank":0,"categorySecureNoCreditRank":0,"categoryZeroPercentExcellentRank":0,"categoryZeroPercentGoodRank":0,"categoryZeroPercentFairRank":0,"categoryZeroPercentPoorRank":0,"categoryAirlinePublicRank":0,"categoryBalanceTransferPublicRank":0,"categoryLowInterestPublicRank":0,"categoryRewardsPublicRank":0,"categoryCashBackPublicRank":0,"categoryStudentPublicRank":0,"categoryBusinessPublicRank":0,"categorySecurePublicRank":0,"categoryZeroPercentPublicRank":0,"categoryZeroPercent0Rank":0,"categoryZeroPercent18Rank":0,"categoryZeroPercent19Rank":0,"categoryZeroPercent20Rank":0,"categoryZeroPercent21Rank":0,"categoryZeroPercent22Rank":0,"categoryZeroPercent23Rank":0,"categoryZeroPercent24Rank":0,"categoryZeroPercent25Rank":0,"categoryZeroPercent26Rank":0,"categoryZeroPercent27Rank":0,"categoryZeroPercent28Rank":0,"categoryZeroPercent29Rank":0,"categoryZeroPercent30Rank":0,"categoryRewards0Rank":0,"categoryRewards18Rank":0,"categoryRewards19Rank":0,"categoryRewards20Rank":0,"categoryRewards21Rank":0,"categoryRewards22Rank":0,"categoryRewards23Rank":0,"categoryRewards24Rank":0,"categoryRewards25Rank":0,"categoryRewards26Rank":0,"categoryRewards27Rank":0,"categoryRewards28Rank":0,"categoryRewards29Rank":0,"categoryRewards30Rank":0,"categoryBest0Rank":0,"categoryBest18Rank":0,"categoryBest19Rank":0,"categoryBest20Rank":0,"categoryBest21Rank":0,"categoryBest22Rank":0,"categoryBest23Rank":0,"categoryBest24Rank":0,"categoryBest25Rank":0,"categoryBest26Rank":0,"categoryBest27Rank":0,"categoryBest28Rank":0,"categoryBest29Rank":0,"categoryBest30Rank":0,"categoryBalanceTransfer0Rank":0,"categoryBalanceTransfer18Rank":0,"categoryBalanceTransfer19Rank":0,"categoryBalanceTransfer20Rank":0,"categoryBalanceTransfer21Rank":0,"categoryBalanceTransfer22Rank":0,"categoryBalanceTransfer23Rank":0,"categoryBalanceTransfer24Rank":0,"categoryBalanceTransfer25Rank":0,"categoryBalanceTransfer26Rank":0,"categoryBalanceTransfer27Rank":0,"categoryBalanceTransfer28Rank":0,"categoryBalanceTransfer29Rank":0,"categoryBalanceTransfer30Rank":0,"primaryAttribute":"","relatedCardsMatchedRule":"","relatedCardsMatchCriteriaText":"","streamId":0};
            </script>
        </head>
        <body>
            <div id="metawidget"></div>
            <script type="text/javascript">
                var mw = new metawidget.Metawidget( document.getElementById( 'metawidget' ), {
    
                    inspectionResultProcessors: [ function( inspectionResult ) {
    
                        var sortedProperties = [];
    
                        if ( inspectionResult !== undefined ) {
    
                            // Extract JSON Schema to an array, and attach sections to each property
    
                            var propertyOrder = 0;
    
                            for ( var propertyName in inspectionResult.properties ) {
    
                                var properties = inspectionResult.properties[propertyName];
                                properties.name = propertyName;
    
                                if ( propertyName.startsWith( "category" )) {
                                    properties.section = 'Categories';
                                } else if ( propertyName.startsWith( "display" )) {
                                    properties.section = 'Display';
                                } else if ( propertyName.indexOf( "Fee" ) !== -1 ) {
                                    properties.section = 'Fees';
                                } else if ( propertyName.startsWith( "bonus" )) {
                                    properties.section = 'Bonus';
                                } else {
                                    properties.section = 'CMSProduct';
                                }
    
                                properties.propertyOrder = propertyOrder++;
    
                                sortedProperties.push( properties );
                            }
    
                            // Sort by section name
    
                            sortedProperties.sort( function( a, b ) {
    
                                // Artifical ordering for first tab
    
                                if ( a.section === 'CMSProduct' && b.section !== 'CMSProduct' ) {
                                    return -1;
                                } else if ( a.section !== 'CMSProduct' && b.section === 'CMSProduct' ) {
                                    return 1;
                                }
    
                                // Sort other tabs alphabetically
    
                                var compare = a.section.localeCompare( b.section );
    
                                if ( compare !== 0 ) {
                                    return compare;
                                }
    
                                // Keep property order within tabs
    
                                return a.propertyOrder - b.propertyOrder;
                            } );
    
                            // Apply new ordering back to JSON Schema
    
                            for( var loop = 0, length = sortedProperties.length; loop < length; loop++ ) {
                                inspectionResult.properties[sortedProperties[loop].name].propertyOrder = loop;
                            }
                        }
    
                        return inspectionResult;
                    } ],
                    layout: new metawidget.jqueryui.layout.TabLayoutDecorator(
                            new metawidget.layout.TableLayout( { numberOfColumns: 2 } ))
                });
                mw.toInspect = card;
                mw.buildWidgets();
            </script>
        </body>
    </html>
    
     
  • federico piazza

    federico piazza - 2016-03-10

    Kennard,

    Thanks a lot for the comments, I've based on the "1.2 Part 1" examples to come up with that sample. I have to dig deeper in your explanation because I'm studying this.

    For the example you displayed, it gathers the fields by the names, however I need specific fields to be set in specific sections and all the remaining fields to be set in "Others".

    Can you send over a link to the inspectors documentation where I can find more information like what you stated the JsonSchemaInspector ?

     
  • Kennard Consulting

    The example I sent can easily be modified to assign different sections to different fields, based on each field's name/type/other metadata. I did a few versions in there for you, but you should be able to modify to suit your needs?

    For JsonSchemaInspector, see 4.2.4 JsonSchemaInspector (JavaScript version):

    http://metawidget.org/doc/reference/en/html/ch04s02.html

     
    • federico piazza

      federico piazza - 2016-03-10

      Wonderful, I'll continue doing testing with your suggestions.

      Thanks, you rock!

       

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.