问:
table column width changing while toggling between readonly and edit mode
I have implemented a dynamically generated html table in angular 7. I have also implemented a toggle mode that enables the user to toggle between edit and read-only mode. Clicking on edit makes the cells editable by showing the respective controls. Currently the problem that I am facing is that clicking on edit button is expanding the cell to a large extent. I need to have fixed width in either mode. At the moment if you see the CSS , I have set the min-width to the td and th to 250px. I tried width and max-width properties but not working.

Read only mode

Edit mode

html component

```

    <input type="checkbox" id="chk" style="width: 13px; height: 13px;" checked="checked"
        (click)="isInvestedSelected($event)" />
    Invested

        Legal Fund Classes

            <button style="text-align: center; vertical-align:middle" class="btn btn-default pull-right"
                (click)="openFundClassModal()">  Add
                Class</button>

        {{ c }}
        <ng-container *ngFor="let f of LegalFundClasses.LegalFundClassDetailsViewModel; let i=index">
          {{f.Description}}
          {{f.AuditSummary}}
          {{f.Id}}
          COMMERCIAL TERMS

              <button type="button" class="btn btn-default btn" style="float: left;"
                  (click)="reviewClicked(f.Id,1)">Review Terms</button>
                  {{reviewTerm}}

          <td  colspan="7" class="tableItem" *ngIf="c == ColumnNames[5] && i<1">
           {{f.PrimaryCurrencyName}}

                <kendo-dropdownlist  style="width: 100%; height: 29.5px;" [(ngModel)]="f.CurrencyId" [defaultItem]="defaultItem"
                    class="form-control  form-control-sm" [data]="LegalFundClasses.Currencies"
                    [filterable]="false" textField="Name" [valuePrimitive]="true" valueField="Id">
                </kendo-dropdownlist>

            {{f.ManagerStrategyName}}

              <kendo-dropdownlist  style="width: 100%; height: 29.5px;" [(ngModel)]="f.ManagerStrategyId"
                  [defaultItem]="defaultItem" class="form-control  form-control-sm"
                  [data]="LegalFundClasses.ManagerStrategies" [filterable]="false" textField="Name"
                  [valuePrimitive]="true" valueField="Id">
              </kendo-dropdownlist>

           {{f.OtherCurrencyName}}

              <kendo-multiselect [data]="LegalFundClasses.Currencies"  style="width:100%; height: 29.5px;" [(ngModel)]="f.OtherCurrencyName" [textField]="'Name'"
                  [valueField]="'Id'" [autoClose]="false">
                  <ng-template kendoMultiSelectItemTemplate let-dataItem>
                      <input type="checkbox" class="k-checkbox" [checked]="isItemSelected(dataItem.Name)">
                      {{ dataItem.Name }}
                  </ng-template>
              </kendo-multiselect>

           {{f.SubVotingName}}

              <kendo-dropdownlist  style="width: 100%; height: 29.5px;" [(ngModel)]="f.SubVotingId" [defaultItem]="defaultItem"
                  class="form-control  form-control-sm" [data]="LegalFundClasses.LiqVoting"
                  [filterable]="false" textField="Name" [valuePrimitive]="true" valueField="Id">
              </kendo-dropdownlist>

           {{f.SubHotIssueName}}

              <kendo-dropdownlist  style="width: 100%; height: 29.5px;" [(ngModel)]="f.SubHotIssueId" [defaultItem]="defaultItem"
                  class="form-control  form-control-sm" [data]="LegalFundClasses.LiqHotIssue"
                  [filterable]="false" textField="Name" [valuePrimitive]="true" valueField="Id">
              </kendo-dropdownlist>

          <td colspan="7" class="tableItem" *ngIf="c == ColumnNames[11] && i<1" >
          <td  colspan="7" class="tableItem" *ngIf="c == ColumnNames[12] && i<1">
          {{f.RedsFrqncyName}}

              <kendo-dropdownlist  style="width: 100%; height: 29.5px;" [(ngModel)]="f.RedsFrqncyId" [defaultItem]="defaultItem"
                  class="form-control  form-control-sm" [data]="LegalFundClasses.LiqRedsFrequency"
                  [filterable]="false" textField="Name" [valuePrimitive]="true" valueField="Id">
              </kendo-dropdownlist>

          {{f.RedsNoticeDays}}

              <kendo-numerictextbox [(ngModel)]="f.RedsNoticeDays" style="width: 100%; height: 29.5px;"></kendo-numerictextbox>

          {{f.NoticeTypeOfDaysName}}

              <kendo-dropdownlist  style="width: 100%; height: 29.5px;" [(ngModel)]="f.NoticeTypeOfDaysId"
                  [defaultItem]="defaultItem" class="form-control  form-control-sm"
                  [data]="LegalFundClasses.LiqTypeOfDays" [filterable]="false" textField="Name"
                  [valuePrimitive]="true" valueField="Id">
              </kendo-dropdownlist>

          <td  colspan="7" class="tableItem" *ngIf="c == ColumnNames[16] && i<1">
          {{f.LockupTypeName}}

              <kendo-dropdownlist  style="width: 100%; height: 29.5px;" [(ngModel)]="f.LockupTypeId" [defaultItem]="defaultItem"
                  class="form-control  form-control-sm" [data]="LegalFundClasses.LiqLockupType"
                  [filterable]="false" textField="Name" [valuePrimitive]="true" valueField="Id">
              </kendo-dropdownlist>

          {{f.HardDurationMonthsName}}

              <kendo-dropdownlist  style="width: 100%; height: 29.5px;" [(ngModel)]="f.HardDurationMonthsId"
                  [defaultItem]="defaultItem" class="form-control  form-control-sm"
                  [data]="LegalFundClasses.LiqDurationMonths" [filterable]="false" textField="Name"
                  [valuePrimitive]="true" valueField="Id">
              </kendo-dropdownlist>

          {{f.SoftDurationMonthsName}}

              <kendo-dropdownlist  style="width: 100%; height: 29.5px;" [(ngModel)]="f.SoftDurationMonthsId"
                  [defaultItem]="defaultItem" class="form-control  form-control-sm"
                  [data]="LegalFundClasses.LiqDurationMonths" [filterable]="false" textField="Name"
                  [valuePrimitive]="true" valueField="Id">
              </kendo-dropdownlist>

          {{f.LockupFees0To12Pct}}

                <kendo-numerictextbox [(ngModel)]="f.LockupFees0To12Pct" style="width: 100%; height: 29.5px;"></kendo-numerictextbox>

          {{f.LockupFees12To24Pct}}

                <kendo-numerictextbox [(ngModel)]="f.LockupFees12To24Pct" style="width: 100%; height: 29.5px;"></kendo-numerictextbox>

          {{f.LockupFees24To36Pct}}

                <kendo-numerictextbox [(ngModel)]="f.LockupFees24To36Pct" style="width: 100%; height: 29.5px;"></kendo-numerictextbox>

          {{f.WebfolioRedsFee}}

                <kendo-numerictextbox [(ngModel)]="f.WebfolioRedsFee" style="width: 100%; height: 29.5px;"></kendo-numerictextbox>

          {{f.LockupComments}}

              <input kendoTextBox [(ngModel)]="f.LockupComments" style="width: 100%; height: 29.5px;" />

          <td colspan="7" class="tableItem" *ngIf="c == ColumnNames[25] && i<1">

              {{f.ApplyGateDecliningBalance === 'true' ? 'Yes' : 'No'}}

                  <input type="checkbox" value="{{f.ApplyGateDecliningBalance}}"
                      style="width: 13px; height: 13px;" /> Yes

          {{f.GateInvestorPct}}
          <input kendoTextBox [(ngModel)]="f.GateInvestorPct"
                  style="width: 100%; height: 29.5px;" />
          {{f.GateSourceName}}

              <kendo-dropdownlist style="width: 100%; height: 29.5px;" [(ngModel)]="f.GateSourceId" [defaultItem]="defaultItem"
                  class="form-control  form-control-sm" [data]="LegalFundClasses.LiqGateSource"
                  [filterable]="false" textField="Name" [valuePrimitive]="true" valueField="Id">
              </kendo-dropdownlist>

          {{f.GateFundClassPct}}

              <input kendoTextBox [(ngModel)]="f.GateFundClassPct" style="width:100%; height: 29.5px;" />

          {{f.IntialProceeds}}

              <input kendoTextBox [(ngModel)]="f.IntialProceeds" style="width: 100%; height: 29.5px;" />

          {{f.PaymentInDays}}

              <input kendoTextBox [(ngModel)]="f.PaymentInDays" style="width: 100%; height: 29.5px;" />

          {{f.PaymentTypeOfDaysName}}

              <kendo-dropdownlist  style="width: 100%; height: 29.5px;" [(ngModel)]="f.PaymentTypeOfDaysId"
                  [defaultItem]="defaultItem" class="form-control  form-control-sm"
                  [data]="LegalFundClasses.LiqTypeOfDays" [filterable]="false" textField="Name"
                  [valuePrimitive]="true" valueField="Id">
              </kendo-dropdownlist>

          {{f.HoldbackPercentage}}

              <input kendoTextBox [(ngModel)]="f.HoldbackPercentage" style="width: 100%; height: 29.5px;" />

          {{f.HoldbackPayment}}

              <input kendoTextBox [(ngModel)]="f.HoldbackPayment" style="width: 100%; height: 29.5px;" />

          {{f.HoldbackTypeOfDaysName}}

              <kendo-dropdownlist  style="width: 100%; height: 29.5px;" [(ngModel)]="f.HoldbackTypeOfDaysId"
                  [defaultItem]="defaultItem" class="form-control  form-control-sm"
                  [data]="LegalFundClasses.LiqTypeOfDays" [filterable]="false" textField="Name"
                  [valuePrimitive]="true" valueField="Id">
              </kendo-dropdownlist>

          <td colspan="7" class="tableItem"  *ngIf="c == ColumnNames[38] && i<1">

              <button type="button" class="btn btn-default btn" style="float: left;"
                  (click)="reviewClicked(f.value.Id,2)">Review Fees</button>

          {{f.ManagementFeeRate}}

                <kendo-numerictextbox [(ngModel)]="f.ManagementFeeRate" style="width: 100%; height: 29.5px;"></kendo-numerictextbox>

          {{f.IncentiveFeeRate}}

                <kendo-numerictextbox [(ngModel)]="f.IncentiveFeeRate" style="width: 100%; height: 29.5px;"></kendo-numerictextbox>

          {{f.RealizationFrequencyName}}

              <kendo-dropdownlist  style="width: 100%; height: 29.5px;" [(ngModel)]="f.RealizationFrequencyId"
                  [defaultItem]="defaultItem" class="form-control  form-control-sm"
                  [data]="LegalFundClasses.LiqFrequencys" [filterable]="false" textField="Name"
                  [valuePrimitive]="true" valueField="Id">
              </kendo-dropdownlist>

          {{f.HighWaterMarkName}}

              <kendo-dropdownlist  style="width: 100%; height: 29.5px;" [(ngModel)]="f.HighWaterMarkId"
                  [defaultItem]="defaultItem" class="form-control  form-control-sm"
                  [data]="LegalFundClasses.LiqHighWaterMarks" [filterable]="false" textField="Name"
                  [valuePrimitive]="true" valueField="Id">
              </kendo-dropdownlist>

          {{f.HurdleRate === 'true' ? 'Yes' : 'No'}}

                  <input type="checkbox" value="{{f.HurdleRate}}" style="width: 13px; height: 13px;" /> Yes

          {{f.HurdleRateBasisName}}

              <kendo-dropdownlist  style="width: 100%; height: 29.5px;" [(ngModel)]="f.HurdleRateBasisId"
                  [defaultItem]="defaultItem" class="form-control  form-control-sm"
                  [data]="LegalFundClasses.LiqHurdleRateBasis" [filterable]="false" textField="Name"
                  [valuePrimitive]="true" valueField="Id">
              </kendo-dropdownlist>

          {{f.HurdleRatePct}}

             <kendo-numerictextbox [(ngModel)]="f.HurdleRatePct" style="width: 100%; height: 29.5px;"></kendo-numerictextbox>

          {{f.HurdleRateIndexName}}

              <kendo-dropdownlist  style="width: 100%; height: 29.5px;" [(ngModel)]="f.HurdleRateIndexId"
                  [defaultItem]="defaultItem" class="form-control  form-control-sm"
                  [data]="LegalFundClasses.LiqHurdleRateIndex" [filterable]="false" textField="Name"
                  [valuePrimitive]="true" valueField="Id">
              </kendo-dropdownlist>

          {{f.PreferredReturnRatePct}}

              <kendo-numerictextbox [(ngModel)]="f.PreferredReturnRatePct" style="width: 100%; height: 29.5px;"></kendo-numerictextbox>

          {{f.GpCatchUp}}

              <input kendoTextBox [(ngModel)]="f.GpCatchUp" style="width:100%; height: 29.5px;" />

          {{f.PrefferedReturnComments}}

              <input kendoTextBox [(ngModel)]="f.PrefferedReturnComments"
                  style="width: 100%; height: 29.5px;" />

          {{f.Clawback === 'true' ? 'Yes' : 'No'}}

                  <input type="checkbox" value="{{f.Clawback}}" style="width: 13px; height: 13px;" /> Yes

          {{f.ClawbackPercentage}}

              <kendo-numerictextbox [(ngModel)]="f.ClawbackPercentage" style="width: 100%; height: 29.5px;"></kendo-numerictextbox>

          {{f.AssetFeeDiscountTypeName}}

              <kendo-dropdownlist  style="width: 100%; height: 29.5px;" [(ngModel)]="f.AssetFeeDiscountTypeId"
                  [defaultItem]="defaultItem" class="form-control  form-control-sm"
                  [data]="LegalFundClasses.FeeDicountTypes" [filterable]="false" textField="Name"
                  [valuePrimitive]="true" valueField="Id">
              </kendo-dropdownlist>

          {{f.FeeComments}}

              <textarea kendoTextArea [(ngModel)]="f.FeeComments" style="width: 100%; height:200px;" ></textarea>

          {{f.FeeReductionsNegotiated  === 'true' ? 'Yes' : 'No'}}

                  <input type="checkbox" value="{{f.FeeReductionsNegotiated}}"
                      style="width: 13px; height: 13px;" /> Yes

                <button *ngIf="!EditMode[f.Id]" type="button" class="btn btn-primary btn mr-1 col-sm-4"
                    (click)="buttonClicked(f.Id)">Edit</button>
                <button *ngIf="EditMode[f.Id]" type="button" class="btn btn-primary btn mr-1 col-sm-3"
                    (click)="Update(f.Id)">Save</button>
                <button *ngIf="EditMode[f.Id]" type="button" class="btn btn-primary btn mr-1  col-sm-3"
                    (click)="Delete(f.Id)">Delete</button>
                <button *ngIf="EditMode[f.Id]" type="button" class="btn btn-primary btn mr-1  col-sm-3"
                    (click)="buttonClicked(f.Id)">Cancel</button>

        </ng-container>

```

答:
Yes, pindev is right, you only have to style your inputs in the editable lines. I would add an Class on click editing to the table rows which affected. then you can make this into your css file:

```<code>.yourExtraClassForEditableLines input {
    // your style goes here
}
</code>```

Greetz Toxi

Body:
I have implemented a dynamically generated html table in angular 7. I have also implemented a toggle mode that enables the user to toggle between edit and read-only mode. Clicking on edit makes the cells editable by showing the respective controls. Currently the problem that I am facing is that clicking on edit button is expanding the cell to a large extent. I need to have fixed width in either mode. At the moment if you see the CSS , I have set the min-width to the td and th to 250px. I tried width and max-width properties but not working.

Read only mode

Edit mode

html component

    <input type="checkbox" id="chk" style="width: 13px; height: 13px;" checked="checked"
        (click)="isInvestedSelected($event)" />
    Invested

        Legal Fund Classes

            <button style="text-align: center; vertical-align:middle" class="btn btn-default pull-right"
                (click)="openFundClassModal()">  Add
                Class</button>

        {{ c }}
        <ng-container *ngFor="let f of LegalFundClasses.LegalFundClassDetailsViewModel; let i=index">
          {{f.Description}}
          {{f.AuditSummary}}
          {{f.Id}}
          COMMERCIAL TERMS

              <button type="button" class="btn btn-default btn" style="float: left;"
                  (click)="reviewClicked(f.Id,1)">Review Terms</button>
                  {{reviewTerm}}

          <td  colspan="7" class="tableItem" *ngIf="c == ColumnNames[5] && i<1">
           {{f.PrimaryCurrencyName}}

                <kendo-dropdownlist  style="width: 100%; height: 29.5px;" [(ngModel)]="f.CurrencyId" [defaultItem]="defaultItem"
                    class="form-control  form-control-sm" [data]="LegalFundClasses.Currencies"
                    [filterable]="false" textField="Name" [valuePrimitive]="true" valueField="Id">
                </kendo-dropdownlist>

            {{f.ManagerStrategyName}}

              <kendo-dropdownlist  style="width: 100%; height: 29.5px;" [(ngModel)]="f.ManagerStrategyId"
                  [defaultItem]="defaultItem" class="form-control  form-control-sm"
                  [data]="LegalFundClasses.ManagerStrategies" [filterable]="false" textField="Name"
                  [valuePrimitive]="true" valueField="Id">
              </kendo-dropdownlist>

           {{f.OtherCurrencyName}}

              <kendo-multiselect [data]="LegalFundClasses.Currencies"  style="width:100%; height: 29.5px;" [(ngModel)]="f.OtherCurrencyName" [textField]="'Name'"
                  [valueField]="'Id'" [autoClose]="false">
                  <ng-template kendoMultiSelectItemTemplate let-dataItem>
                      <input type="checkbox" class="k-checkbox" [checked]="isItemSelected(dataItem.Name)">
                      {{ dataItem.Name }}
                  </ng-template>
              </kendo-multiselect>

           {{f.SubVotingName}}

              <kendo-dropdownlist  style="width: 100%; height: 29.5px;" [(ngModel)]="f.SubVotingId" [defaultItem]="defaultItem"
                  class="form-control  form-control-sm" [data]="LegalFundClasses.LiqVoting"
                  [filterable]="false" textField="Name" [valuePrimitive]="true" valueField="Id">
              </kendo-dropdownlist>

           {{f.SubHotIssueName}}

              <kendo-dropdownlist  style="width: 100%; height: 29.5px;" [(ngModel)]="f.SubHotIssueId" [defaultItem]="defaultItem"
                  class="form-control  form-control-sm" [data]="LegalFundClasses.LiqHotIssue"
                  [filterable]="false" textField="Name" [valuePrimitive]="true" valueField="Id">
              </kendo-dropdownlist>

          <td colspan="7" class="tableItem" *ngIf="c == ColumnNames[11] && i<1" >
          <td  colspan="7" class="tableItem" *ngIf="c == ColumnNames[12] && i<1">
          {{f.RedsFrqncyName}}

              <kendo-dropdownlist  style="width: 100%; height: 29.5px;" [(ngModel)]="f.RedsFrqncyId" [defaultItem]="defaultItem"
                  class="form-control  form-control-sm" [data]="LegalFundClasses.LiqRedsFrequency"
                  [filterable]="false" textField="Name" [valuePrimitive]="true" valueField="Id">
              </kendo-dropdownlist>

          {{f.RedsNoticeDays}}

              <kendo-numerictextbox [(ngModel)]="f.RedsNoticeDays" style="width: 100%; height: 29.5px;"></kendo-numerictextbox>

          {{f.NoticeTypeOfDaysName}}

              <kendo-dropdownlist  style="width: 100%; height: 29.5px;" [(ngModel)]="f.NoticeTypeOfDaysId"
                  [defaultItem]="defaultItem" class="form-control  form-control-sm"
                  [data]="LegalFundClasses.LiqTypeOfDays" [filterable]="false" textField="Name"
                  [valuePrimitive]="true" valueField="Id">
              </kendo-dropdownlist>

          <td  colspan="7" class="tableItem" *ngIf="c == ColumnNames[16] && i<1">
          {{f.LockupTypeName}}

              <kendo-dropdownlist  style="width: 100%; height: 29.5px;" [(ngModel)]="f.LockupTypeId" [defaultItem]="defaultItem"
                  class="form-control  form-control-sm" [data]="LegalFundClasses.LiqLockupType"
                  [filterable]="false" textField="Name" [valuePrimitive]="true" valueField="Id">
              </kendo-dropdownlist>

          {{f.HardDurationMonthsName}}

              <kendo-dropdownlist  style="width: 100%; height: 29.5px;" [(ngModel)]="f.HardDurationMonthsId"
                  [defaultItem]="defaultItem" class="form-control  form-control-sm"
                  [data]="LegalFundClasses.LiqDurationMonths" [filterable]="false" textField="Name"
                  [valuePrimitive]="true" valueField="Id">
              </kendo-dropdownlist>

          {{f.SoftDurationMonthsName}}

              <kendo-dropdownlist  style="width: 100%; height: 29.5px;" [(ngModel)]="f.SoftDurationMonthsId"
                  [defaultItem]="defaultItem" class="form-control  form-control-sm"
                  [data]="LegalFundClasses.LiqDurationMonths" [filterable]="false" textField="Name"
                  [valuePrimitive]="true" valueField="Id">
              </kendo-dropdownlist>

          {{f.LockupFees0To12Pct}}

                <kendo-numerictextbox [(ngModel)]="f.LockupFees0To12Pct" style="width: 100%; height: 29.5px;"></kendo-numerictextbox>

          {{f.LockupFees12To24Pct}}

                <kendo-numerictextbox [(ngModel)]="f.LockupFees12To24Pct" style="width: 100%; height: 29.5px;"></kendo-numerictextbox>

          {{f.LockupFees24To36Pct}}

                <kendo-numerictextbox [(ngModel)]="f.LockupFees24To36Pct" style="width: 100%; height: 29.5px;"></kendo-numerictextbox>

          {{f.WebfolioRedsFee}}

                <kendo-numerictextbox [(ngModel)]="f.WebfolioRedsFee" style="width: 100%; height: 29.5px;"></kendo-numerictextbox>

          {{f.LockupComments}}

              <input kendoTextBox [(ngModel)]="f.LockupComments" style="width: 100%; height: 29.5px;" />

          <td colspan="7" class="tableItem" *ngIf="c == ColumnNames[25] && i<1">

              {{f.ApplyGateDecliningBalance === 'true' ? 'Yes' : 'No'}}

                  <input type="checkbox" value="{{f.ApplyGateDecliningBalance}}"
                      style="width: 13px; height: 13px;" /> Yes

          {{f.GateInvestorPct}}
          <input kendoTextBox [(ngModel)]="f.GateInvestorPct"
                  style="width: 100%; height: 29.5px;" />
          {{f.GateSourceName}}

              <kendo-dropdownlist style="width: 100%; height: 29.5px;" [(ngModel)]="f.GateSourceId" [defaultItem]="defaultItem"
                  class="form-control  form-control-sm" [data]="LegalFundClasses.LiqGateSource"
                  [filterable]="false" textField="Name" [valuePrimitive]="true" valueField="Id">
              </kendo-dropdownlist>

          {{f.GateFundClassPct}}

              <input kendoTextBox [(ngModel)]="f.GateFundClassPct" style="width:100%; height: 29.5px;" />

          {{f.IntialProceeds}}

              <input kendoTextBox [(ngModel)]="f.IntialProceeds" style="width: 100%; height: 29.5px;" />

          {{f.PaymentInDays}}

              <input kendoTextBox [(ngModel)]="f.PaymentInDays" style="width: 100%; height: 29.5px;" />

          {{f.PaymentTypeOfDaysName}}

              <kendo-dropdownlist  style="width: 100%; height: 29.5px;" [(ngModel)]="f.PaymentTypeOfDaysId"
                  [defaultItem]="defaultItem" class="form-control  form-control-sm"
                  [data]="LegalFundClasses.LiqTypeOfDays" [filterable]="false" textField="Name"
                  [valuePrimitive]="true" valueField="Id">
              </kendo-dropdownlist>

          {{f.HoldbackPercentage}}

              <input kendoTextBox [(ngModel)]="f.HoldbackPercentage" style="width: 100%; height: 29.5px;" />

          {{f.HoldbackPayment}}

              <input kendoTextBox [(ngModel)]="f.HoldbackPayment" style="width: 100%; height: 29.5px;" />

          {{f.HoldbackTypeOfDaysName}}

              <kendo-dropdownlist  style="width: 100%; height: 29.5px;" [(ngModel)]="f.HoldbackTypeOfDaysId"
                  [defaultItem]="defaultItem" class="form-control  form-control-sm"
                  [data]="LegalFundClasses.LiqTypeOfDays" [filterable]="false" textField="Name"
                  [valuePrimitive]="true" valueField="Id">
              </kendo-dropdownlist>

          <td colspan="7" class="tableItem"  *ngIf="c == ColumnNames[38] && i<1">

              <button type="button" class="btn btn-default btn" style="float: left;"
                  (click)="reviewClicked(f.value.Id,2)">Review Fees</button>

          {{f.ManagementFeeRate}}

                <kendo-numerictextbox [(ngModel)]="f.ManagementFeeRate" style="width: 100%; height: 29.5px;"></kendo-numerictextbox>

          {{f.IncentiveFeeRate}}

                <kendo-numerictextbox [(ngModel)]="f.IncentiveFeeRate" style="width: 100%; height: 29.5px;"></kendo-numerictextbox>

          {{f.RealizationFrequencyName}}

              <kendo-dropdownlist  style="width: 100%; height: 29.5px;" [(ngModel)]="f.RealizationFrequencyId"
                  [defaultItem]="defaultItem" class="form-control  form-control-sm"
                  [data]="LegalFundClasses.LiqFrequencys" [filterable]="false" textField="Name"
                  [valuePrimitive]="true" valueField="Id">
              </kendo-dropdownlist>

          {{f.HighWaterMarkName}}

              <kendo-dropdownlist  style="width: 100%; height: 29.5px;" [(ngModel)]="f.HighWaterMarkId"
                  [defaultItem]="defaultItem" class="form-control  form-control-sm"
                  [data]="LegalFundClasses.LiqHighWaterMarks" [filterable]="false" textField="Name"
                  [valuePrimitive]="true" valueField="Id">
              </kendo-dropdownlist>

          {{f.HurdleRate === 'true' ? 'Yes' : 'No'}}

                  <input type="checkbox" value="{{f.HurdleRate}}" style="width: 13px; height: 13px;" /> Yes

          {{f.HurdleRateBasisName}}

              <kendo-dropdownlist  style="width: 100%; height: 29.5px;" [(ngModel)]="f.HurdleRateBasisId"
                  [defaultItem]="defaultItem" class="form-control  form-control-sm"
                  [data]="LegalFundClasses.LiqHurdleRateBasis" [filterable]="false" textField="Name"
                  [valuePrimitive]="true" valueField="Id">
              </kendo-dropdownlist>

          {{f.HurdleRatePct}}

             <kendo-numerictextbox [(ngModel)]="f.HurdleRatePct" style="width: 100%; height: 29.5px;"></kendo-numerictextbox>

          {{f.HurdleRateIndexName}}

              <kendo-dropdownlist  style="width: 100%; height: 29.5px;" [(ngModel)]="f.HurdleRateIndexId"
                  [defaultItem]="defaultItem" class="form-control  form-control-sm"
                  [data]="LegalFundClasses.LiqHurdleRateIndex" [filterable]="false" textField="Name"
                  [valuePrimitive]="true" valueField="Id">
              </kendo-dropdownlist>

          {{f.PreferredReturnRatePct}}

              <kendo-numerictextbox [(ngModel)]="f.PreferredReturnRatePct" style="width: 100%; height: 29.5px;"></kendo-numerictextbox>

          {{f.GpCatchUp}}

              <input kendoTextBox [(ngModel)]="f.GpCatchUp" style="width:100%; height: 29.5px;" />

          {{f.PrefferedReturnComments}}

              <input kendoTextBox [(ngModel)]="f.PrefferedReturnComments"
                  style="width: 100%; height: 29.5px;" />

          {{f.Clawback === 'true' ? 'Yes' : 'No'}}

                  <input type="checkbox" value="{{f.Clawback}}" style="width: 13px; height: 13px;" /> Yes

          {{f.ClawbackPercentage}}

              <kendo-numerictextbox [(ngModel)]="f.ClawbackPercentage" style="width: 100%; height: 29.5px;"></kendo-numerictextbox>

          {{f.AssetFeeDiscountTypeName}}

              <kendo-dropdownlist  style="width: 100%; height: 29.5px;" [(ngModel)]="f.AssetFeeDiscountTypeId"
                  [defaultItem]="defaultItem" class="form-control  form-control-sm"
                  [data]="LegalFundClasses.FeeDicountTypes" [filterable]="false" textField="Name"
                  [valuePrimitive]="true" valueField="Id">
              </kendo-dropdownlist>

          {{f.FeeComments}}

              <textarea kendoTextArea [(ngModel)]="f.FeeComments" style="width: 100%; height:200px;" ></textarea>

          {{f.FeeReductionsNegotiated  === 'true' ? 'Yes' : 'No'}}

                  <input type="checkbox" value="{{f.FeeReductionsNegotiated}}"
                      style="width: 13px; height: 13px;" /> Yes

                <button *ngIf="!EditMode[f.Id]" type="button" class="btn btn-primary btn mr-1 col-sm-4"
                    (click)="buttonClicked(f.Id)">Edit</button>
                <button *ngIf="EditMode[f.Id]" type="button" class="btn btn-primary btn mr-1 col-sm-3"
                    (click)="Update(f.Id)">Save</button>
                <button *ngIf="EditMode[f.Id]" type="button" class="btn btn-primary btn mr-1  col-sm-3"
                    (click)="Delete(f.Id)">Delete</button>
                <button *ngIf="EditMode[f.Id]" type="button" class="btn btn-primary btn mr-1  col-sm-3"
                    (click)="buttonClicked(f.Id)">Cancel</button>

        </ng-container>

Body:
Yes, pindev is right, you only have to style your inputs in the editable lines. I would add an Class on click editing to the table rows which affected. then you can make this into your css file:

.yourExtraClassForEditableLines input {
    // your style goes here
}

Greetz Toxi


来源: stackexchange

问:
How do I center my buttons on my website?
I'm having a problem with my code and can't figure it out. I'm writing my own website and can't get my buttons to go to the center of the page. I tried almost everything I think but it always goes to about 30% or 70% for some reason... The website is not fully responsive for now I will work on that later. What's wrong with my code? What can I do to fix it next time? Thanks for any ideas!

function showHide() {
    var navList = document.getElementById("nav-lists");

    if (navList.className == '_Menus') {
        navList.classList.add("_Menus-show");
    } else {
        navList.classList.remove("_Menus-show");
    }

    const body = document.querySelector('body')
    const twitter = document.querySelector('.twitter')

    twitter.addEventListener("mouseover", function () {
        body.classList.add('linked')
    },false)

    twitter.addEventListener("mouseout", function () {
        body.classList.remove('linked')
    }, false)

}```
<pre class="snippet-code-css lang-css prettyprint-override"><code>@font-face {
    font-family: 'familiar_probold';
    src: url('fonts/FamiliarPro/familiar_pro-bold-webfont.woff2') format('woff2'),
    url('fonts/FamiliarPro/familiar_pro-bold-webfont.woff') format('woff');
    font-weight: normal;
    font-style: normal;

}
@font-face {
    font-family: 'uni_sansheavy_caps';
    src: url('fonts/UniSansHeavy/uni_sans_heavy-webfont.woff2') format('woff2'),
    url('fonts/UniSansHeavy/uni_sans_heavy-webfont.woff') format('woff');
    font-weight: normal;
    font-style: normal;

}
@font-face {
    font-family: 'source_sans_problack';
    src: url('fonts/SourceSans/sourcesanspro-black-webfont.woff2') format('woff2'),
    url('fonts/SourceSans/sourcesanspro-black-webfont.woff') format('woff');
    font-weight: normal;
    font-style: normal;

}
*{
    margin: 0;
    padding: 0;
}
*,
*::before,
*::after {
    box-sizing: border-box;
    -webkit-box-sizing: border-box;
}

body {
    padding: 0;
    margin: 0;
    background-color: #f7f7f7;
    font-family: sans-serif;
}
img {
    width: 100%;
    height: auto;
}
.navbar {
    width: 100%;
    background-color: #000;

}

.container {
    max-width: 1140px;
    margin: 0 auto;
    height: 60px;
    display: flex;
    flex-wrap: wrap;

}

._Logo {
    overflow: hidden;
    text-align: center;
    flex-basis: 230px;
}

._Logo img {
    height: 100% !important;
    width: 150px !important;
}

._Menus ul {
    display: flex;
    list-style: none;
    padding: 0;
    margin: 0;
    flex-wrap: wrap;
}
._Menus ul li a {
    display: block;
    padding: 0 10px;
    height: 60px;
    line-height: 60px;
    text-decoration: none;
    color: #FFF;
    outline: none;
    font-family: 'uni_sansheavy_caps';
}
._Menus ul li a:hover {
    background-color: #FFF;
    color: #000;
}

._Iconbar {
    display: none;
    background-color: #000;
}

.menu-bar {
    width: 45px;
    align-self: center;
    cursor: pointer;
}

.icon-bar {
    height: 3px;
    width: 100%;
    background: #FFF;
    margin: 7px 0;
    display: block;
    border-radius: 2px;
}
.toppadding{
    padding-top: 0;
}
.topbackround{
    width: 100%;
    height: auto;
    position: relative;
    text-align: center;
    color: white;
}
.sloganlefttextfirst{
    position: absolute;
    top: 20%;
    left: 5%;
    font-family: 'familiar_probold';
    font-size: 200%;
    color: grey;
}
.sloganlefttextsecond{
    position: absolute;
    top: 25%;
    left: 5%;
    font-family: 'uni_sansheavy_caps';
    font-size: 500%;
}
.sloganlefttextthird{
    position: absolute;
    top: 35%;
    left: 5%;
    font-family: 'uni_sansheavy_caps';
    font-size: 500%;
    color: #DCC98E;
    border-bottom: 6px solid #DCC98E;
    padding-bottom: 3px;
}
.howitworkslefttextfirst a{
    position: absolute;
    top: 51%;
    left: 5%;
    font-family: 'familiar_probold';
    font-size: 200%;
    color: #B9CDBE;
    border-bottom: 3px solid #B9CDBE;
    padding-bottom: 3px;
    text-decoration: none;
}
.howitworkslefttextsecond{
    position: absolute;
    top: 57%;
    left: 5%;
    font-family: 'Arial';
    font-size: 200%;
    color: white;
}
hr{
    color: black;
    background-color: black;
    height: 8px;
    border: none;
}
.midbackground{
    background-color: #1B1C1E;
    padding-bottom: 100px;
}
.tutorial{
    padding-top: 3%;
    padding-bottom: 3%;
    text-align: center;
    left: 50%;
    font-family: 'uni_sansheavy_caps';
    color: #DCC98E;
    font-size: 350%;
    width: 100%;
}
.tutorial p{
    padding-top: 20px;
    padding-bottom: 20px;
    text-align: center;
    left: 50%;
    font-family: 'Arial';
    color: white;
    font-size: 50%;
    width: 100%;
}
.circles{
    margin: 0 auto;
}
.circles > div {
    overflow: hidden;
    float: left;
    width: auto;
    height: auto;
    position: relative;
    border-radius: 50%;
    -moz-border-radius: 50%;
    -webkit-border-radius: 50%;
    background: #1B1C1E;
}

.circles > div > div {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    font-family: 'uni_sansheavy_caps';
    font-size: 400%;
    color: grey;
}
.circles > div > div > div {
    display: table;
    width: 100%;
    height: 100%;
}
.circles > div > div > div > div {
    display: table-cell;
    text-align: center;
    vertical-align: middle;
}
@media (max-width: 320px)
{
    .circles > div {padding: 50%;}
}

@media (min-width: 321px) and (max-width: 800px)
{
    .circles > div {padding: 25%;}
}

@media (min-width: 801px)
{
    .circles{width:800px}
    .circles > div {padding: 12.5%;}
}
.circlescontent{
    margin: 0 auto;
}
.circlescontent > div {
    overflow:hidden;
    float:left;
    width:auto;
    height:auto;
    position: relative;
    background: #1B1C1E;
}

.circlescontent > div > div {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    font-family: 'familiar_probold';
    font-size: 250%;
    color: grey;
}
.circlescontent > div > div > div {
    display: table;
    width: 100%;
    height: 100%;
}
.circlescontent > div > div > div > div {
    display: table-cell;
    text-align: center;
    vertical-align: middle;
}
@media (max-width: 320px)
{
    .circlescontent > div {padding: 50%;}
}

@media (min-width: 321px) and (max-width: 800px)
{
    .circlescontent > div {padding: 25%;}
}

@media (min-width: 801px)
{
    .circlescontent{width:800px}
    .circlescontent > div {padding: 12.5%;}
}
.statement{
    padding-top: 25%;
    padding-bottom: 3%;
    text-align: center;
    left: 50%;
    font-family: 'uni_sansheavy_caps';
    color: #DCC98E;
    font-size: 350%;
    width: 100%;
}
.statement p{
    padding-top: 20px;
    padding-bottom: 0;
    text-align: center;
    left: 50%;
    font-family: 'familiar_probold';
    color: white;
    font-size: 50%;
    width: 100%;
}
.statementfinal{
    padding-top: 0;
    padding-bottom: 3%;
    text-align: center;
    left: 50%;
    font-family: 'uni_sansheavy_caps';
    color: #DCC98E;
    font-size: 350%;
    width: 100%;
}  /*HERE*/
.buttonbkg{
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100%;
    height: 90vh;
}
.button {
    width: 320px;
    max-width: 100%;
    overflow: hidden;
    position: relative;
    transform: translatez(0);
    text-decoration: none;
    box-sizing: border-box;
    font-size: 130%;
    font-weight: normal;
    font-family: 'familiar_probold';
    color: #B9CDBE;
    box-shadow: 0 9px 18px rgba(0,0,0,0.2);
    display: inline-block;
    left: 50%;
    margin: 3%;
    align-content: center;
}

.steam{
    text-align: center;
    border-radius: 50px;
    padding: 26px;
    color: white;
    background: #BD3381;
    transition: all 0.2s ease-out 0s;
    display: inline-block;
    align-content: center;
}

.gradient {
    position: absolute;
    top: 0;
    right: 0;
    width: 100%;
    height: 100%;
    bottom: auto;
    margin: auto;
    z-index: -1;
    background: radial-gradient(90px circle at top center, rgba(238,88,63,.8) 30%, rgba(255,255,255,0));
    transition: all 0s ease-out 0s;
    transform: translatex(-140px);
    animation: 18s linear 0s infinite move;
    display: inline-block;
    align-content: center;
}

@keyframes move {
    0% {
        transform: translatex(-140px);
    }
    25% {
        transform: translatex(140px);
        opacity: 0.3;
    }
    50% {
        transform: translatex(140px);
        opacity: 1;
        background: radial-gradient(90px circle at bottom center, rgba(238,88,63,.5) 30%, rgba(255,255,255,0));
    }
    75% {
        transform: translatex(-140px);
        opacity: 0.3;
    }
    100% {
        opacity: 1;
        transform: translatex(-140px);
        background: radial-gradient(90px circle at top center, rgba(238,88,63,.5) 30%, rgba(255,255,255,0));
    }
}
@media (max-width: 900px) {
    ._Logo {
        height: 60px;
    }

    ._Menus {
        flex: 100%;
        background: #333;
        height: 0;
        overflow: hidden;

    }

    ._Menus ul{
        flex-direction: column;
    }

    ._Menus ul li a {
        height: 40px;
        font-size: 14px;
        text-transform: uppercase;
        line-height: 40px;
    }

    ._Menus ul li a:hover {
        background-color: #81d742;
        color: #FFF;
    }

    .container {
        justify-content: space-between;
    }

    ._Iconbar {
        display: flex;
        margin-right: 10px;

    }

    ._Menus-show {
        height: auto;
    }
    .brandimage{
        display: none;
    }

@media (max-width: 600px) {
    ._Logo {
        height: 60px;
    }

    ._Menus {
        flex: 100%;
        background: #333;
        height: 0;
        overflow: hidden;

    }

    ._Menus ul{
        flex-direction: column;
    }

    ._Menus ul li a {
        height: 40px;
        font-size: 14px;
        text-transform: uppercase;
        line-height: 40px;
    }

    ._Menus ul li a:hover {
        background-color: #81d742;
        color: #FFF;
    }

    .container {
        justify-content: space-between;
    }

    ._Iconbar {
        display: flex;
        margin-right: 10px;

    }

    ._Menus-show {
        height: auto;
    }

    .brandimage{
        display: none;
    }
}}

/*
#0C0028
#1D5EC3
#181A1B
 */</code>```

<!DOCTYPE html>

    <meta charset="utf-8">
    <title>Reff Skins</title>
    <link rel="stylesheet" href="style.css">
    <link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS responsive navigation menu</title>

<!DOCTYPE html>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS responsive navigation menu</title>

ABOUT

HOW IT WORKS

FAQ

AVAILABLE SKINS

SIGN IN THROUGH STEAM

WEBSITE WITH TRULY FREE SKINS

LOW ON SKINS?

TIME TO GET NEW FREE!

HOW IS THIS WORKING?

check how it works page or visit our YouTube

HOW CAN I DO IT?
If you want your new skins complete the four easy steps.

                        1.

                        2.

                        3.

                        4.

                        SIGN IN WITH STEAM

                        DO THE REFERR PROCESS

                        SELECT WANTED SKINS

                        GET YOUR SKINS

IT'S THAT EASY
NO DEPOSITS, NO PAYMENT METHODS, NO RISKY GAMBLING, NO SKINS HOLDING

WE SAID NO TO CATCHES!

        SIGN IN WITH STEAM
        AVAILABLE SKINS
        HOW IT WORKS

```

答:
You need to add this to your button selector:</p>

```<code>.button {
transform: translateX(-50%);
}
</code>```

ContentLicense: CC BY-SA 4.0

Body:
I'm having a problem with my code and can't figure it out. I'm writing my own website and can't get my buttons to go to the center of the page. I tried almost everything I think but it always goes to about 30% or 70% for some reason... The website is not fully responsive for now I will work on that later. What's wrong with my code? What can I do to fix it next time? Thanks for any ideas!

function showHide() {
    var navList = document.getElementById("nav-lists");

    if (navList.className == '_Menus') {
        navList.classList.add("_Menus-show");
    } else {
        navList.classList.remove("_Menus-show");
    }

    const body = document.querySelector('body')
    const twitter = document.querySelector('.twitter')

    twitter.addEventListener("mouseover", function () {
        body.classList.add('linked')
    },false)

    twitter.addEventListener("mouseout", function () {
        body.classList.remove('linked')
    }, false)

}

@font-face {
    font-family: 'familiar_probold';
    src: url('fonts/FamiliarPro/familiar_pro-bold-webfont.woff2') format('woff2'),
    url('fonts/FamiliarPro/familiar_pro-bold-webfont.woff') format('woff');
    font-weight: normal;
    font-style: normal;

}
@font-face {
    font-family: 'uni_sansheavy_caps';
    src: url('fonts/UniSansHeavy/uni_sans_heavy-webfont.woff2') format('woff2'),
    url('fonts/UniSansHeavy/uni_sans_heavy-webfont.woff') format('woff');
    font-weight: normal;
    font-style: normal;

}
@font-face {
    font-family: 'source_sans_problack';
    src: url('fonts/SourceSans/sourcesanspro-black-webfont.woff2') format('woff2'),
    url('fonts/SourceSans/sourcesanspro-black-webfont.woff') format('woff');
    font-weight: normal;
    font-style: normal;

}
*{
    margin: 0;
    padding: 0;
}
*,
*::before,
*::after {
    box-sizing: border-box;
    -webkit-box-sizing: border-box;
}

body {
    padding: 0;
    margin: 0;
    background-color: #f7f7f7;
    font-family: sans-serif;
}
img {
    width: 100%;
    height: auto;
}
.navbar {
    width: 100%;
    background-color: #000;

}

.container {
    max-width: 1140px;
    margin: 0 auto;
    height: 60px;
    display: flex;
    flex-wrap: wrap;

}

._Logo {
    overflow: hidden;
    text-align: center;
    flex-basis: 230px;
}

._Logo img {
    height: 100% !important;
    width: 150px !important;
}

._Menus ul {
    display: flex;
    list-style: none;
    padding: 0;
    margin: 0;
    flex-wrap: wrap;
}
._Menus ul li a {
    display: block;
    padding: 0 10px;
    height: 60px;
    line-height: 60px;
    text-decoration: none;
    color: #FFF;
    outline: none;
    font-family: 'uni_sansheavy_caps';
}
._Menus ul li a:hover {
    background-color: #FFF;
    color: #000;
}

._Iconbar {
    display: none;
    background-color: #000;
}

.menu-bar {
    width: 45px;
    align-self: center;
    cursor: pointer;
}

.icon-bar {
    height: 3px;
    width: 100%;
    background: #FFF;
    margin: 7px 0;
    display: block;
    border-radius: 2px;
}
.toppadding{
    padding-top: 0;
}
.topbackround{
    width: 100%;
    height: auto;
    position: relative;
    text-align: center;
    color: white;
}
.sloganlefttextfirst{
    position: absolute;
    top: 20%;
    left: 5%;
    font-family: 'familiar_probold';
    font-size: 200%;
    color: grey;
}
.sloganlefttextsecond{
    position: absolute;
    top: 25%;
    left: 5%;
    font-family: 'uni_sansheavy_caps';
    font-size: 500%;
}
.sloganlefttextthird{
    position: absolute;
    top: 35%;
    left: 5%;
    font-family: 'uni_sansheavy_caps';
    font-size: 500%;
    color: #DCC98E;
    border-bottom: 6px solid #DCC98E;
    padding-bottom: 3px;
}
.howitworkslefttextfirst a{
    position: absolute;
    top: 51%;
    left: 5%;
    font-family: 'familiar_probold';
    font-size: 200%;
    color: #B9CDBE;
    border-bottom: 3px solid #B9CDBE;
    padding-bottom: 3px;
    text-decoration: none;
}
.howitworkslefttextsecond{
    position: absolute;
    top: 57%;
    left: 5%;
    font-family: 'Arial';
    font-size: 200%;
    color: white;
}
hr{
    color: black;
    background-color: black;
    height: 8px;
    border: none;
}
.midbackground{
    background-color: #1B1C1E;
    padding-bottom: 100px;
}
.tutorial{
    padding-top: 3%;
    padding-bottom: 3%;
    text-align: center;
    left: 50%;
    font-family: 'uni_sansheavy_caps';
    color: #DCC98E;
    font-size: 350%;
    width: 100%;
}
.tutorial p{
    padding-top: 20px;
    padding-bottom: 20px;
    text-align: center;
    left: 50%;
    font-family: 'Arial';
    color: white;
    font-size: 50%;
    width: 100%;
}
.circles{
    margin: 0 auto;
}
.circles > div {
    overflow: hidden;
    float: left;
    width: auto;
    height: auto;
    position: relative;
    border-radius: 50%;
    -moz-border-radius: 50%;
    -webkit-border-radius: 50%;
    background: #1B1C1E;
}

.circles > div > div {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    font-family: 'uni_sansheavy_caps';
    font-size: 400%;
    color: grey;
}
.circles > div > div > div {
    display: table;
    width: 100%;
    height: 100%;
}
.circles > div > div > div > div {
    display: table-cell;
    text-align: center;
    vertical-align: middle;
}
@media (max-width: 320px)
{
    .circles > div {padding: 50%;}
}

@media (min-width: 321px) and (max-width: 800px)
{
    .circles > div {padding: 25%;}
}

@media (min-width: 801px)
{
    .circles{width:800px}
    .circles > div {padding: 12.5%;}
}
.circlescontent{
    margin: 0 auto;
}
.circlescontent > div {
    overflow:hidden;
    float:left;
    width:auto;
    height:auto;
    position: relative;
    background: #1B1C1E;
}

.circlescontent > div > div {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    left: 0;
    font-family: 'familiar_probold';
    font-size: 250%;
    color: grey;
}
.circlescontent > div > div > div {
    display: table;
    width: 100%;
    height: 100%;
}
.circlescontent > div > div > div > div {
    display: table-cell;
    text-align: center;
    vertical-align: middle;
}
@media (max-width: 320px)
{
    .circlescontent > div {padding: 50%;}
}

@media (min-width: 321px) and (max-width: 800px)
{
    .circlescontent > div {padding: 25%;}
}

@media (min-width: 801px)
{
    .circlescontent{width:800px}
    .circlescontent > div {padding: 12.5%;}
}
.statement{
    padding-top: 25%;
    padding-bottom: 3%;
    text-align: center;
    left: 50%;
    font-family: 'uni_sansheavy_caps';
    color: #DCC98E;
    font-size: 350%;
    width: 100%;
}
.statement p{
    padding-top: 20px;
    padding-bottom: 0;
    text-align: center;
    left: 50%;
    font-family: 'familiar_probold';
    color: white;
    font-size: 50%;
    width: 100%;
}
.statementfinal{
    padding-top: 0;
    padding-bottom: 3%;
    text-align: center;
    left: 50%;
    font-family: 'uni_sansheavy_caps';
    color: #DCC98E;
    font-size: 350%;
    width: 100%;
}  /*HERE*/
.buttonbkg{
    display: flex;
    justify-content: center;
    align-items: center;
    width: 100%;
    height: 90vh;
}
.button {
    width: 320px;
    max-width: 100%;
    overflow: hidden;
    position: relative;
    transform: translatez(0);
    text-decoration: none;
    box-sizing: border-box;
    font-size: 130%;
    font-weight: normal;
    font-family: 'familiar_probold';
    color: #B9CDBE;
    box-shadow: 0 9px 18px rgba(0,0,0,0.2);
    display: inline-block;
    left: 50%;
    margin: 3%;
    align-content: center;
}

.steam{
    text-align: center;
    border-radius: 50px;
    padding: 26px;
    color: white;
    background: #BD3381;
    transition: all 0.2s ease-out 0s;
    display: inline-block;
    align-content: center;
}

.gradient {
    position: absolute;
    top: 0;
    right: 0;
    width: 100%;
    height: 100%;
    bottom: auto;
    margin: auto;
    z-index: -1;
    background: radial-gradient(90px circle at top center, rgba(238,88,63,.8) 30%, rgba(255,255,255,0));
    transition: all 0s ease-out 0s;
    transform: translatex(-140px);
    animation: 18s linear 0s infinite move;
    display: inline-block;
    align-content: center;
}

@keyframes move {
    0% {
        transform: translatex(-140px);
    }
    25% {
        transform: translatex(140px);
        opacity: 0.3;
    }
    50% {
        transform: translatex(140px);
        opacity: 1;
        background: radial-gradient(90px circle at bottom center, rgba(238,88,63,.5) 30%, rgba(255,255,255,0));
    }
    75% {
        transform: translatex(-140px);
        opacity: 0.3;
    }
    100% {
        opacity: 1;
        transform: translatex(-140px);
        background: radial-gradient(90px circle at top center, rgba(238,88,63,.5) 30%, rgba(255,255,255,0));
    }
}
@media (max-width: 900px) {
    ._Logo {
        height: 60px;
    }

    ._Menus {
        flex: 100%;
        background: #333;
        height: 0;
        overflow: hidden;

    }

    ._Menus ul{
        flex-direction: column;
    }

    ._Menus ul li a {
        height: 40px;
        font-size: 14px;
        text-transform: uppercase;
        line-height: 40px;
    }

    ._Menus ul li a:hover {
        background-color: #81d742;
        color: #FFF;
    }

    .container {
        justify-content: space-between;
    }

    ._Iconbar {
        display: flex;
        margin-right: 10px;

    }

    ._Menus-show {
        height: auto;
    }
    .brandimage{
        display: none;
    }

@media (max-width: 600px) {
    ._Logo {
        height: 60px;
    }

    ._Menus {
        flex: 100%;
        background: #333;
        height: 0;
        overflow: hidden;

    }

    ._Menus ul{
        flex-direction: column;
    }

    ._Menus ul li a {
        height: 40px;
        font-size: 14px;
        text-transform: uppercase;
        line-height: 40px;
    }

    ._Menus ul li a:hover {
        background-color: #81d742;
        color: #FFF;
    }

    .container {
        justify-content: space-between;
    }

    ._Iconbar {
        display: flex;
        margin-right: 10px;

    }

    ._Menus-show {
        height: auto;
    }

    .brandimage{
        display: none;
    }
}}

/*
#0C0028
#1D5EC3
#181A1B
 */

<!DOCTYPE html>

    <meta charset="utf-8">
    <title>Reff Skins</title>
    <link rel="stylesheet" href="style.css">
    <link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet">

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS responsive navigation menu</title>

<!DOCTYPE html>

    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CSS responsive navigation menu</title>

ABOUT

HOW IT WORKS

FAQ

AVAILABLE SKINS

SIGN IN THROUGH STEAM

WEBSITE WITH TRULY FREE SKINS

LOW ON SKINS?

TIME TO GET NEW FREE!

HOW IS THIS WORKING?

check how it works page or visit our YouTube

HOW CAN I DO IT?
If you want your new skins complete the four easy steps.

                        1.

                        2.

                        3.

                        4.

                        SIGN IN WITH STEAM

                        DO THE REFERR PROCESS

                        SELECT WANTED SKINS

                        GET YOUR SKINS

IT'S THAT EASY
NO DEPOSITS, NO PAYMENT METHODS, NO RISKY GAMBLING, NO SKINS HOLDING

WE SAID NO TO CATCHES!

        SIGN IN WITH STEAM
        AVAILABLE SKINS
        HOW IT WORKS

Body:
You need to add this to your button selector:

.button {
transform: translateX(-50%);
}


问:
Angular wildcard route replacing child routes
I have a module called "host" with its own routing that I want to insert into the app-routing.module. However, I have the problem of the wildcard loading first and displaying PageNotFoundComponent, instead of the Host component loading. I have the following files.

host.module.ts

```<code>....
const routes: Routes = [
  {
    path: 'host',
    children: [
     { path: '', component: HostComponent }
    ]
  }
];

@NgModule({
  declarations: [HostComponent],
  imports: [
    CommonModule,
    RouterModule.forChild(routes)
  ]
})
export class HostModule { }
</code>```

app-routing.module.ts

```<code>const routes: Routes = [
  { path: '', component: HomeComponent, pathMatch: "full"},
  { path: '**', component: PageNotFoundComponent }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }
</code>```

app.module.ts

```<code>@NgModule({
  declarations: [
    AppComponent,
    HomeComponent,
    PageNotFoundComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    HostModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
</code>```

app.component.html

```<code><h2>Home</h2>
<ul>
  <li>
    <h2><a routerLink="/host">host</a></h2>
  </li>
</ul>
<router-outlet></router-outlet>
</code>```

Problem: When I run the app and click on the "Host" button, it loads the PageNotFoundComponent. I obviously want it to go to the HostComponent.

答:
In your app.module.ts you need to reorder your imports

```<code>@NgModule({
  declarations: [
    AppComponent,
    HomeComponent,
    PageNotFoundComponent
  ],
  imports: [
    BrowserModule,
    HostModule, <--- this before AppRoutingModule
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }
</code>```

Reason being is because the order of the routes in the configuration matters.  https://angular.io/guide/router#configuration

The ** path in the last route is a wildcard. The router will select this route if the requested URL doesn't match any paths for routes defined earlier in the configuration. This is useful for displaying a "404 - Not Found" page or redirecting to another route.

The order of the routes in the configuration matters and this is by design. The router uses a first-match wins strategy when matching routes, so more specific routes should be placed above less specific routes. In the configuration above, routes with a static path are listed first, followed by an empty path route, that matches the default route. The wildcard route comes last because it matches every URL and should be selected only if no other routes are matched first.

Body:
I have a module called "host" with its own routing that I want to insert into the app-routing.module. However, I have the problem of the wildcard loading first and displaying PageNotFoundComponent, instead of the Host component loading. I have the following files.

host.module.ts

....
const routes: Routes = [
  {
    path: 'host',
    children: [
     { path: '', component: HostComponent }
    ]
  }
];

@NgModule({
  declarations: [HostComponent],
  imports: [
    CommonModule,
    RouterModule.forChild(routes)
  ]
})
export class HostModule { }

app-routing.module.ts

const routes: Routes = [
  { path: '', component: HomeComponent, pathMatch: "full"},
  { path: '**', component: PageNotFoundComponent }
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})
export class AppRoutingModule { }

app.module.ts

@NgModule({
  declarations: [
    AppComponent,
    HomeComponent,
    PageNotFoundComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    HostModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

app.component.html

Home

host

<router-outlet></router-outlet>

Problem: When I run the app and click on the "Host" button, it loads the PageNotFoundComponent. I obviously want it to go to the HostComponent.

Body:
In your app.module.ts you need to reorder your imports

@NgModule({
  declarations: [
    AppComponent,
    HomeComponent,
    PageNotFoundComponent
  ],
  imports: [
    BrowserModule,
    HostModule, <--- this before AppRoutingModule
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Reason being is because the order of the routes in the configuration matters.  https://angular.io/guide/router#configuration

The ** path in the last route is a wildcard. The router will select this route if the requested URL doesn't match any paths for routes defined earlier in the configuration. This is useful for displaying a "404 - Not Found" page or redirecting to another route.

The order of the routes in the configuration matters and this is by design. The router uses a first-match wins strategy when matching routes, so more specific routes should be placed above less specific routes. In the configuration above, routes with a static path are listed first, followed by an empty path route, that matches the default route. The wildcard route comes last because it matches every URL and should be selected only if no other routes are matched first.


问:
How to only allow a popup message to occur on first visit with jQuery
I'm working to include a GDPR-style / Cookie notification for when users visit our site for the first time, but not again until they clear their cache. I have a notification set up to show when the window opens, and a close button to close it.

I've tried using localStorage and sessionStorage jquery, similar to those used to help other users, including hiding the popup first then checking in localStorage to see if it's there:

```<code> $(document).ready(function() {
        $('#toast').hide();
        var element= localStorage.getItem('status');
        if (element == null || element == '') {
            localStorage.setItem('element', 1);
            $('#toast').show();
        }});
</code>```

But 1) I don't want to copy pasta because 2) it doesn't work.

html for the popup here:

```<code><div id="toast" class="toast-close fixed-bottom" style="background-color: #DB7232; color: white; opacity: .7; margin: 0 0 2rem 2rem; padding: 1rem; width: 18rem;">
     <small>By continuing to browse this site, you're accepting the use of cookies.</small>
     <small><button type="button" data-dismiss="toast" class="close" aria-label="Close">&times</button></small>
</div>
</code>```

the jquery to close the popup here:

```<code>    $(document).on('click', '.toast-close', function() {
        $(this).fadeOut(function(){
           $(this).remove();
        });
    });
</code>```

I expect when a user comes to our site for the first time (or since we add this feature) the popup will occur; once they x out of either the popup or the browser, the notification will not occur again until their cache is cleared.

答: You are reading 'status', but setting 'element'. Those two names should be the same.</p>

Body:
I'm working to include a GDPR-style / Cookie notification for when users visit our site for the first time, but not again until they clear their cache. I have a notification set up to show when the window opens, and a close button to close it.

I've tried using localStorage and sessionStorage jquery, similar to those used to help other users, including hiding the popup first then checking in localStorage to see if it's there:

 $(document).ready(function() {
        $('#toast').hide();
        var element= localStorage.getItem('status');
        if (element == null || element == '') {
            localStorage.setItem('element', 1);
            $('#toast').show();
        }});

But 1) I don't want to copy pasta because 2) it doesn't work.

html for the popup here:

     By continuing to browse this site, you're accepting the use of cookies.
     <button type="button" data-dismiss="toast" class="close" aria-label="Close">&times</button>

the jquery to close the popup here:

    $(document).on('click', '.toast-close', function() {
        $(this).fadeOut(function(){
           $(this).remove();
        });
    });

I expect when a user comes to our site for the first time (or since we add this feature) the popup will occur; once they x out of either the popup or the browser, the notification will not occur again until their cache is cleared.


问:
How to get User info via FB Graph API
I am finding the way to get user info by using the FB Graph API.

In my app when i get my friends list it shows me 403 friends from graph API, But actually there are 408 friends in my fb account friends section, but when i rewuest by using Graph API it gives me 402 friends records only.

Is it possible that Graph API doesn't give accurate friends list?

答: Probably means that some of your friends have 'opted out' of their data being made available to any 3rd party apps.</p>

ContentLicense: CC BY-SA 3.0

Title: How to get User info via FB Graph API


问:
Is this running truly parallel?
I'm using requests and threading in python to do some stuff. My question is: Is this code running truly multithreaded and is it safe to use? I'm experiencing some slow down over time. Note: I'm not using this exact code but mine is doing similar things.

import time
import requests

current_threads = 0
max_threads = 32

def doStuff():
    global current_threads
    r = requests.get('https://google.de')
    current_threads-=1

while True:
    while current_threads >= max_threads:
        time.sleep(0.05)

    thread = threading.Thread(target = doStuff)
    thread.start()

    current_threads+=1
```

答:
There could be a number of reasons for the issue you are facing.  I'm not an expert in Python but I can see the potential for a number of causes for the slow down.  Potential reasons I can think of are as follows:

Depending on the size of the data you are pulling down you could potentially be overloading your bandwidth.  Hard one to prove without seeing the exact code you are are using and what your code is doing and knowing your bandwidth.

Kinda connected to the fist one but if your files are taking some time to come down per thread it maybe getting clogged up at the:

```<code>while current_threads >= max_threads:
    time.sleep(0.05)
</code>```

you could try reducing the max number of threads and see if that helps though it may not if it's the files that are taking time to download.

The problem may not be with your code or your bandwidth but with the server you are pulling the files from, if that server is over loaded it maybe slowing down your transfers.

Firewalls, IPS, IDS, Policys on the server maybe throttling your requests. If you make too many requests to quickly all from the same IP the server side network equipment may mistake this as some sort of DoS attack and throttle your requests in response.

Unfortunately Python, as compared to other lower level languages such as C# or C++ is not as good at multithreading. This is due to something called the GIL (Global Interpreter Lock) which comes into play when you are accessing/manipulating the same data in multiple threads.  This is quite a sizeable subject in it's self but if you want to read up on it have a look at this link.

https://medium.com/practo-engineering/threading-vs-multiprocessing-in-python-7b57f224eadb

Sorry I can't be of any more assistance but this is as much as I can say on the subject given the provided information.

Title: Is this running truly parallel?

Body:
There could be a number of reasons for the issue you are facing.  I'm not an expert in Python but I can see the potential for a number of causes for the slow down.  Potential reasons I can think of are as follows:

Depending on the size of the data you are pulling down you could potentially be overloading your bandwidth.  Hard one to prove without seeing the exact code you are are using and what your code is doing and knowing your bandwidth.

Kinda connected to the fist one but if your files are taking some time to come down per thread it maybe getting clogged up at the:

while current_threads >= max_threads:
    time.sleep(0.05)

you could try reducing the max number of threads and see if that helps though it may not if it's the files that are taking time to download.

The problem may not be with your code or your bandwidth but with the server you are pulling the files from, if that server is over loaded it maybe slowing down your transfers.

Firewalls, IPS, IDS, Policys on the server maybe throttling your requests. If you make too many requests to quickly all from the same IP the server side network equipment may mistake this as some sort of DoS attack and throttle your requests in response.

Unfortunately Python, as compared to other lower level languages such as C# or C++ is not as good at multithreading. This is due to something called the GIL (Global Interpreter Lock) which comes into play when you are accessing/manipulating the same data in multiple threads.  This is quite a sizeable subject in it's self but if you want to read up on it have a look at this link.

https://medium.com/practo-engineering/threading-vs-multiprocessing-in-python-7b57f224eadb

Sorry I can't be of any more assistance but this is as much as I can say on the subject given the provided information.


问:
graphql-upload data does not work when I try to send it to the server
When using graphql-upload and then I try to send the return data to a flask python server, the data always ends up in the body instead of the file. The header is automatically set successfully to content-type: multipart/form-data boundary etc.... when I use the below graphql connector.

I based a lot of the below on this example https://github.com/jaydenseric/apollo-upload-examples/blob/master/api/resolvers.mjs

```<code>async fileUpload(page, id, file) {
  const { filename, mimetype, createReadStream } = await file;
  const stream = await createReadStream();

  const form = new FormData();
  form.append('file', JSON.stringify({
    filename, mimetype, stream
  }));

  // form.append('file', stream)); // this attempt fails as well

  const url = `/${page}/${id}/file`;

  return this.post(
    url,
    null,
    {
      body: form
    }
  );
}
</code>```

My schema looks like so:

```<code>  type File {
    id: ID!
    page: String!
    name: String
    url: String!
  }

  input FileUploadInput {
    id: ID!
    page: String!
    files: [Upload!]!
  }

  extend type Mutation {
    fileUpload(data: FileUploadInput!): File
  }
</code>```

Resolver

```<code>const { GraphQLUpload } = require('graphql-upload');

const singleFileUpload  (
  root,
  { data: { id, page, files } },
  { dataSources }
) => dataSources.files.fileUpload(id, page, files[0]);

module.exports = {
  Upload: GraphQLUpload,
  Mutation: {
    singleFileUpload
  }
};
</code>```

答:
For whatever reason, the read stream provided by graphql wasn't working but saving the file locally, then creating a readStream for that file was successful.</p>

```<code>    const { filename, createReadStream } = await file;
    const stream = await createReadStream();

    const { path } = await saveLocally(stream, filename); // this function pipes the stream to save it locally

    const newFile = await fs.createReadStream(path);

    const form = new FormData();
    form.append(
      'file',
      newFile
    );

    // I delete the file after I received a succesful response.
    await fs.unlink(path, (err, res) => {
      if (err) return err;
      return res;
    });

</code>```

Body:
When using graphql-upload and then I try to send the return data to a flask python server, the data always ends up in the body instead of the file. The header is automatically set successfully to content-type: multipart/form-data boundary etc.... when I use the below graphql connector.

I based a lot of the below on this example https://github.com/jaydenseric/apollo-upload-examples/blob/master/api/resolvers.mjs

async fileUpload(page, id, file) {
  const { filename, mimetype, createReadStream } = await file;
  const stream = await createReadStream();

  const form = new FormData();
  form.append('file', JSON.stringify({
    filename, mimetype, stream
  }));

  // form.append('file', stream)); // this attempt fails as well

  const url = `/${page}/${id}/file`;

  return this.post(
    url,
    null,
    {
      body: form
    }
  );
}

My schema looks like so:

  type File {
    id: ID!
    page: String!
    name: String
    url: String!
  }

  input FileUploadInput {
    id: ID!
    page: String!
    files: [Upload!]!
  }

  extend type Mutation {
    fileUpload(data: FileUploadInput!): File
  }

Resolver

const { GraphQLUpload } = require('graphql-upload');

const singleFileUpload  (
  root,
  { data: { id, page, files } },
  { dataSources }
) => dataSources.files.fileUpload(id, page, files[0]);

module.exports = {
  Upload: GraphQLUpload,
  Mutation: {
    singleFileUpload
  }
};

Body:
For whatever reason, the read stream provided by graphql wasn't working but saving the file locally, then creating a readStream for that file was successful.

    const { filename, createReadStream } = await file;
    const stream = await createReadStream();

    const { path } = await saveLocally(stream, filename); // this function pipes the stream to save it locally

    const newFile = await fs.createReadStream(path);

    const form = new FormData();
    form.append(
      'file',
      newFile
    );

    // I delete the file after I received a succesful response.
    await fs.unlink(path, (err, res) => {
      if (err) return err;
      return res;
    });


问:
Join list of sentences up to max character limit
I have a list in which each item is a sentence. I want to join the items as long as the new combined item does not go over a character limit.

You can join items in a list fairly easily.

x = ['Alice went to the market.', 'She bought an apple.', 'And she then went to the park.']
' '.join(x)
>>> 'Alice went to the market. She bought an apple. And she then went to the park.'
```

Now say I would like to sequentially join the items as long as the new combined item is not greater than 50 characters.

The result would be :

['Alice went to the market. She bought an apple.','And she then went to the park.']

You can maybe do a list comprehension like here.  Or I can maybe do a conditional iterator like here.   But I run into problems where the sentences get cut off.

Clarifications

The max character limit refers to the length of a single item in the list...not the length of the entire list. When the list items are combined, no single item in the new list can be over the limit.

The items that were not able to be combined are returned in the list as they were unchanged.

Combine sentences together as long as they do not exceed limit.  If they exceed limit, do not combine and keep as is. Only combine sentences that are sequentially next to each other in the list.

Please make sure your solution satisfies the output result as indicated previously above :
['Alice went to the market. She bought an apple.','And she then went to the park.']

答:
List comprehension would probably be a little less legible, since you want to keep checking total length.

A simple function will do. This one accepts empty joined_str or unspecified as default, but can also start with some specified initial str.

```<code>def join_50_chars_or_less(lst, limit=50):
    """
    Takes in lst of strings and returns join of strings
    up to `limit` number of chars (no substrings)

    :param lst: (list)
        list of strings to join
    :param limit: (int)
        optional limit on number of chars, default 50
    :return: (list)
        string elements joined up until length of 50 chars.
        No partial-strings of elements allowed.
    """
    for i in range(len(lst)):
        new_join = lst[:i+1]
        if len(' '.join(new_join)) > limit:
            return lst[:i]
    return lst
</code>```

After defining the function:

```<code>>>> x = ['Alice went to the market.', 'She bought an apple.', 'And she then went to the park.']
>>> join_50_chars_or_less(x)
['Alice went to the market.', 'She bought an apple.']
>>> len('Alice went to the market. She bought an apple.')
47
</code>```

And let's test against a possibly longer string:

```<code>>>> test_str = "Alice went to the market. She bought an apple on Saturday."
>>> len(test_str)
58

>>> test = test_str.split()
>>> test
['Alice', 'went', 'to', 'the', 'market.', 'She', 'bought', 'an', 'apple', 'on', 'Saturday.']

>>> join_50_chars_or_less(test)
['Alice', 'went', 'to', 'the', 'market.', 'She', 'bought', 'an', 'apple', 'on']
>>> len(' '.join(join_50_chars_or_less(test)))
>>> 48
</code>```

Body:
I have a list in which each item is a sentence. I want to join the items as long as the new combined item does not go over a character limit.

You can join items in a list fairly easily.

x = ['Alice went to the market.', 'She bought an apple.', 'And she then went to the park.']
' '.join(x)
>>> 'Alice went to the market. She bought an apple. And she then went to the park.'

Now say I would like to sequentially join the items as long as the new combined item is not greater than 50 characters.

The result would be :

['Alice went to the market. She bought an apple.','And she then went to the park.']

You can maybe do a list comprehension like here.  Or I can maybe do a conditional iterator like here.   But I run into problems where the sentences get cut off.

Clarifications

The max character limit refers to the length of a single item in the list...not the length of the entire list. When the list items are combined, no single item in the new list can be over the limit.

The items that were not able to be combined are returned in the list as they were unchanged.

Combine sentences together as long as they do not exceed limit.  If they exceed limit, do not combine and keep as is. Only combine sentences that are sequentially next to each other in the list.

Please make sure your solution satisfies the output result as indicated previously above :
['Alice went to the market. She bought an apple.','And she then went to the park.']

Body:
List comprehension would probably be a little less legible, since you want to keep checking total length.

A simple function will do. This one accepts empty joined_str or unspecified as default, but can also start with some specified initial str.

def join_50_chars_or_less(lst, limit=50):
    """
    Takes in lst of strings and returns join of strings
    up to `limit` number of chars (no substrings)

    :param lst: (list)
        list of strings to join
    :param limit: (int)
        optional limit on number of chars, default 50
    :return: (list)
        string elements joined up until length of 50 chars.
        No partial-strings of elements allowed.
    """
    for i in range(len(lst)):
        new_join = lst[:i+1]
        if len(' '.join(new_join)) > limit:
            return lst[:i]
    return lst

After defining the function:

>>> x = ['Alice went to the market.', 'She bought an apple.', 'And she then went to the park.']
>>> join_50_chars_or_less(x)
['Alice went to the market.', 'She bought an apple.']
>>> len('Alice went to the market. She bought an apple.')
47

And let's test against a possibly longer string:

>>> test_str = "Alice went to the market. She bought an apple on Saturday."
>>> len(test_str)
58

>>> test = test_str.split()
>>> test
['Alice', 'went', 'to', 'the', 'market.', 'She', 'bought', 'an', 'apple', 'on', 'Saturday.']

>>> join_50_chars_or_less(test)
['Alice', 'went', 'to', 'the', 'market.', 'She', 'bought', 'an', 'apple', 'on']
>>> len(' '.join(join_50_chars_or_less(test)))
>>> 48


答:
A not-so-elegant solution:</p>

```<code>result = []
counter = 0
string = ""
for element in x:
    for char in element:
        if len(string) < 50:
            string.append(char)
        else:
            result.append(string)
            string = ""
if len(string) > 0:
    result.append(string)
</code>```

Title: Join list of sentences up to max character limit

Body:
A not-so-elegant solution:

result = []
counter = 0
string = ""
for element in x:
    for char in element:
        if len(string) < 50:
            string.append(char)
        else:
            result.append(string)
            string = ""
if len(string) > 0:
    result.append(string)


问:
Creating recursive function to find object with certain attribute value
I have a list of objects based on:

```<code>class foo:
    def __init__(self,name):
         self.name = name
         self.children = [] #other instances contained in this list
</code>```

I have created a function that will find the object when .name matches the search term and will search through all the children of these objects:

```<code>def find(lst,search_term):
    for obj in lst:
        if obj.name == search_term:
            return obj
        elif obj.children != []:
            try:
                if find(obj.children,search_term).name == search_term:
                    return find(obj.children,search_term)
            except AttributeError:
                pass
</code>```

Is there a more elegant way of doing this?

答:
Your "normal" base case is fine.
Your "failure" base case should be explicit:

```<code>for obj in lst:
    if obj.name == search_term:
        return obj
    else:
        ...
# If all searches failed
return None
</code>```

Your recursion step has redundant work: (1) you test the name of the returned object, when you already know it matches; (2) you recur twice with identical data.  Try streamlining the logic: iterate through the obj list until you find a match.

```<code>    else:
        if obj.children:
            found_child = find(obj.children,search_term)
            if found_child:
                return found_child
</code>```

This code goes in place of the ellipsis in the above block.

Body:
I have a list of objects based on:

class foo:
    def __init__(self,name):
         self.name = name
         self.children = [] #other instances contained in this list

I have created a function that will find the object when .name matches the search term and will search through all the children of these objects:

def find(lst,search_term):
    for obj in lst:
        if obj.name == search_term:
            return obj
        elif obj.children != []:
            try:
                if find(obj.children,search_term).name == search_term:
                    return find(obj.children,search_term)
            except AttributeError:
                pass

Is there a more elegant way of doing this?

Body:
Your "normal" base case is fine.
Your "failure" base case should be explicit:

for obj in lst:
    if obj.name == search_term:
        return obj
    else:
        ...
# If all searches failed
return None

Your recursion step has redundant work: (1) you test the name of the returned object, when you already know it matches; (2) you recur twice with identical data.  Try streamlining the logic: iterate through the obj list until you find a match.

    else:
        if obj.children:
            found_child = find(obj.children,search_term)
            if found_child:
                return found_child

This code goes in place of the ellipsis in the above block.


问:
DataTable in SweetAlert2 Pop-Up
Is this possible or am I wasting my time?

Tried many things.

First of all I have

```<code>$html = listings_swal()
</code>```

which is

```<code>function listings_Swal() {
    return '<table id="datatable"><thead><tr><th>Col1</th><th>Col2</th></tr></thead>
    <tfoot><tr><th>Col1</th><th>Col2</th></tr></tfoot></table>';
</code>```

Which is just simply the empty table without the contents.

Here is my target link to open the SweetAlert Dialogue:

```<code><a id="listings">Listings</a>
</code>```

and my script:

```<code>  echo "<script>
$('#listings').on('click', function(){
  swal({
    title: 'Listings',
    html:'" . $html . "',
    showCancelButton: false,
  showConfirmButton: false,
  showCloseButton: true}, function() {
      $.ajax({
    url: 'listings.js',
    dataType: 'script'
      })
      .done(function(data) {
        swal('Deleted!', 'our file was successfully deleted!', 'success');
      })
      .error(function(data) {
        swal('Oops', 'We couldnt connect to the server!', 'error');
      });
    });
     });
</script>";
</code>```

In my listings.js file

I have the standard Datatable init

```<code>$(document).ready(function() {
  $('#datatable').dataTable({
     .....
</code>```

I've tried a few things with no success.

Such as adding the script after the sweetalert dialogue

```<code>  echo "<script>
$('#listings').on('click', function(){
  swal({
    title: 'Table',
    html:'" . $html . "',
    showCancelButton: false,
  showConfirmButton: false,
  showCloseButton: true
  })
});
</script>";
echo '<script src="listings.js"></script>';
</code>```

I've also tried doing a php ajax return in my sweetalert script table.php which just had an echo '';

I've tried modifying my listings_Swal() function so that after the closing
 the script is added.

This all works fine if it's not within a sweetalert2 dialogue pop-up--- and the sweetalert dialogue does indeed work, but the table is not populated with the DataTable contents (it just simply shows the

 and
 with no table rows generated from DataTables.

I am certain that my scripts otherwise work fine and populate the table rows if they are not in the sweetalert2 dialogue box and just normal html table, so I am confused as to how to get DataTables to init the loading of the table rows within the sweet alert pop-up itself.

Not sure what else I can try.  Is it something with the DOM not recognizing the table to initialize the Datatable?  Anyone have any ideas?

Thank you!

edit: To clarify, as I said the sweetalert2 dialogue does pop-up just does not populate it with datatable's rows, and no console/js errors to be shown so I'm not sure how to debug.

答:
Got it. I guess I had to separate the two. Do the SweetAlert command (swal), and then the Datatable command.

```<code><script>
      $(document).ready(function(){
$('#listings').on('click', function(){
  Swal.fire({
    title: 'Listings',
    html: '<?php echo $html; ?>'
});
    $('#datatable').DataTable( {
    "processing": true,
    "serverSide": false,
    "ajax": "scripts/server_processing.php"
  } )
    });
});
</script>
</code>```

Works as expected!

Title: DataTable in SweetAlert2 Pop-Up

Body:
Is this possible or am I wasting my time?

Tried many things.

First of all I have

$html = listings_swal()

which is

function listings_Swal() {
    return '

Col1	Col2

Col1	Col2

';

Which is just simply the empty table without the contents.

Here is my target link to open the SweetAlert Dialogue:

Listings

and my script:

  echo "";

In my listings.js file

I have the standard Datatable init

$(document).ready(function() {
  $('#datatable').dataTable({
     .....

I've tried a few things with no success.

Such as adding the script after the sweetalert dialogue

  echo "";
echo '';

I've also tried doing a php ajax return in my sweetalert script table.php which just had an echo '';

I've tried modifying my listings_Swal() function so that after the closing
 the script is added.

This all works fine if it's not within a sweetalert2 dialogue pop-up--- and the sweetalert dialogue does indeed work, but the table is not populated with the DataTable contents (it just simply shows the

 and
 with no table rows generated from DataTables.

I am certain that my scripts otherwise work fine and populate the table rows if they are not in the sweetalert2 dialogue box and just normal html table, so I am confused as to how to get DataTables to init the loading of the table rows within the sweet alert pop-up itself.

Not sure what else I can try.  Is it something with the DOM not recognizing the table to initialize the Datatable?  Anyone have any ideas?

Thank you!

edit: To clarify, as I said the sweetalert2 dialogue does pop-up just does not populate it with datatable's rows, and no console/js errors to be shown so I'm not sure how to debug.

Body:
Got it. I guess I had to separate the two. Do the SweetAlert command (swal), and then the Datatable command.

<script>
      $(document).ready(function(){
$('#listings').on('click', function(){
  Swal.fire({
    title: 'Listings',
    html: '<?php echo $html; ?>'
});
    $('#datatable').DataTable( {
    "processing": true,
    "serverSide": false,
    "ajax": "scripts/server_processing.php"
  } )
    });
});
</script>

Works as expected!


答:
On your .button class you have left: 50%;, remove it. Also add margin: 3% auto
On you .steam class change display: inline-block; to display: block;

margin: 3% auto

3% -> top/bottom margin

auto -> left/right margin, auto will make left an right margin the same

Other solution would be to change your transform: translatez(0); to transform: translateX(-50%);, but I think transform is like shooting with a shotgun at a fly.

Title: How do I center my buttons on my website?


问:
Talking to container on Kubernetes (GKE) from other container
I have an API written in Express, that connects to a Mongo container. When I spin these up locally, I can connect to the mongo instance using something like mongodb://${DB_HOST}:${DB_PORT}/${DB_NAME} and setting .env variables.

What I am struggling to understand, is once this deployed to GKE, how will my API connect to the mongo container / pod?

It won't be running on localhost I assume, so perhaps I will need to use the internal IP created?

Should it actually be connecting via a service? What would that service look like?

I am struggling to find docs on exactly where I am stuck so I am thinking I am missing something really obvious.

I'm free new to GKE so any examples would help massively.

答:
You'll want to deploy mongodb, probably as a StatefulSet so it can use stable persistent storage.  You'll need to configure a StorageClass for the persistent storage.  Then you'll want to expose it as a Service.  Here's an example on kubernetes.io

If you use Helm (hint, do it) it's a lot easier.  You can be up and running with a single command

```<code>helm install stable/mongodb
</code>```

The output of the helm install contains some helpful instructions for connecting to your new mongodb cluster.

Body:
You'll want to deploy mongodb, probably as a StatefulSet so it can use stable persistent storage.  You'll need to configure a StorageClass for the persistent storage.  Then you'll want to expose it as a Service.  Here's an example on kubernetes.io

If you use Helm (hint, do it) it's a lot easier.  You can be up and running with a single command

helm install stable/mongodb

The output of the helm install contains some helpful instructions for connecting to your new mongodb cluster.


问:
Selenium: Point towards default Chrome session
Though I realize it's NOT "good" practice - I have a use case where I need to point (hook up) the Selenium driver to my default Chrome session/profile.

My default profile is here:
~/Library/Caches/Google/Chrome/Default

Here is how I'm seting it up currently: (not working)

```<code>from selenium import webdriver

options = webdriver.ChromeOptions()
options.add_argument("--user-data-dir=~/Library/Caches/Google/Chrome")
options.add_argument("--profile-directory=Default")
browser = webdriver.Chrome(options=options, executable_path=r"./chromedriver")
browser.get("http://google.com")
</code>```

I'm using Chrome version 74.0.3729.169 and chromedriver version ChromeDriver 74.0.3729.6 (which is the compatible version).

When Chrome opens I don't see any cookies in Chrome's settings so it's clear it's NOT being pointed to my default session. Also, I see that a Selenium directory has been created (which appears to mean that it has failed to connect to the session at ~/Library/Caches/Google/Chrome/Default.

How do I hook up selenium to my default Chrome session? This is the same session as one sees when normally opening up Chrome.

I've looked at this other question, but the answer there fails to address how to point Selenium towards default session. Also - it's an outdated question - Chrome and Chromedriver have progressed a lot since then. Also, the question there assumes that the poster is able to connect to default session - I am not able to do that which suggests that the Chromedriver/Chrome have changed since then. Also that question is for Windows - I'm on a Mac where things work differently.

答:
To start with, No, you can't point (hook up) the Selenium driver to any of the existing/previous Web Browsing session. Even if you are able to extract the Session ID, Cookies and other session attributes from the existing/previous Web Browsing session, still you won't be able to pass those attributes as a HOOK to the WebDriver.

You can find a detailed discussion in How can I reconnect to the browser opened by webdriver with selenium?

But of coarse you can connect to the existing Default Chrome profile.

You seem to be already aware that trying to use the Default Chrome Profile for Test Automation will be against all the best practices as the Default Chrome Profile may contain either/all of the following:

browser settings

Extensions

Bookmarks

Apps

Saved Passwords

Browsing History

etc

So the Default Chrome Profile may not be in compliance with you Test Specification and may occasionally raise exception while trying to load. Hence you should always use a customized Chrome Profile.

You can find a detailed discussion in How to open a Chrome Profile through --user-data-dir argument of Selenium

If your usecase still warrants to use the Default Chrome Profile you need to follow the below mentioned details.

Location of Default Chrome Profile

As per the documentation in How to Find Your Chrome Profile Folder on Windows, Mac, and Linux the location for Chrome’s default profile folder differs depending on your platform. The locations are:

Windows 7, 8.1, and 10: C:\Users\<username>\AppData\Local\Google\Chrome\User Data\Default

Mac OS X El Capitan: Users/<username>/Library/Application Support/Google/Chrome/Default

Linux: /home/<username>/.config/google-chrome/default

You need to replace <username> with the name of your user folder. The default profile folder is simply named Default (or default in Linux). However, if you’ve created additional profiles, their folder names are not as obvious. The name you assigned to the profile when you created it displays on a name button on the right side of the title bar on the Chrome window. Unfortunately, the name Chrome uses on the associated profile folder is a generic, numbered name like Profile 3.

If you need to know any of the Chrome Profile's folder name, you simply need to access chrome://version in the address bar and press Enter.

Snapshot:

The Profile Path shows the location of the current profile. For example, the location of my Default profile in my Windows 10 system is C:\Users\Soma Bhattacharjee\AppData\Local\Google\Chrome\User Data\Default. You can select the path and copy it and paste it into File Explorer in Windows, the Finder on OS X or into a file manager like Nautilus in Linux to access that folder.

Sample Code (Windows 10)

Finally, to access the Default Chrome Profile you can use the following Python based solution:

```<code>from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = webdriver.ChromeOptions()
options.add_argument("user-data-dir=C:\\Users\\Soma Bhattacharjee\\AppData\\Local\\Google\\Chrome\\User Data\\Default")
driver = webdriver.Chrome(executable_path=r'C:\WebDrivers\chromedriver.exe', chrome_options=options)
driver.get("https://www.google.co.in")
</code>```

You can find a detailed discussion in How to use Chrome Profile in Selenium Webdriver Python 3

Body:
Though I realize it's NOT "good" practice - I have a use case where I need to point (hook up) the Selenium driver to my default Chrome session/profile.

My default profile is here:
~/Library/Caches/Google/Chrome/Default

Here is how I'm seting it up currently: (not working)

from selenium import webdriver

options = webdriver.ChromeOptions()
options.add_argument("--user-data-dir=~/Library/Caches/Google/Chrome")
options.add_argument("--profile-directory=Default")
browser = webdriver.Chrome(options=options, executable_path=r"./chromedriver")
browser.get("http://google.com")

I'm using Chrome version 74.0.3729.169 and chromedriver version ChromeDriver 74.0.3729.6 (which is the compatible version).

When Chrome opens I don't see any cookies in Chrome's settings so it's clear it's NOT being pointed to my default session. Also, I see that a Selenium directory has been created (which appears to mean that it has failed to connect to the session at ~/Library/Caches/Google/Chrome/Default.

How do I hook up selenium to my default Chrome session? This is the same session as one sees when normally opening up Chrome.

I've looked at this other question, but the answer there fails to address how to point Selenium towards default session. Also - it's an outdated question - Chrome and Chromedriver have progressed a lot since then. Also, the question there assumes that the poster is able to connect to default session - I am not able to do that which suggests that the Chromedriver/Chrome have changed since then. Also that question is for Windows - I'm on a Mac where things work differently.

Body:
To start with, No, you can't point (hook up) the Selenium driver to any of the existing/previous Web Browsing session. Even if you are able to extract the Session ID, Cookies and other session attributes from the existing/previous Web Browsing session, still you won't be able to pass those attributes as a HOOK to the WebDriver.

You can find a detailed discussion in How can I reconnect to the browser opened by webdriver with selenium?

But of coarse you can connect to the existing Default Chrome profile.

You seem to be already aware that trying to use the Default Chrome Profile for Test Automation will be against all the best practices as the Default Chrome Profile may contain either/all of the following:

browser settings

Extensions

Bookmarks

Apps

Saved Passwords

Browsing History

etc

So the Default Chrome Profile may not be in compliance with you Test Specification and may occasionally raise exception while trying to load. Hence you should always use a customized Chrome Profile.

You can find a detailed discussion in How to open a Chrome Profile through --user-data-dir argument of Selenium

If your usecase still warrants to use the Default Chrome Profile you need to follow the below mentioned details.

Location of Default Chrome Profile

As per the documentation in How to Find Your Chrome Profile Folder on Windows, Mac, and Linux the location for Chrome’s default profile folder differs depending on your platform. The locations are:

Windows 7, 8.1, and 10: C:\Users\<username>\AppData\Local\Google\Chrome\User Data\Default

Mac OS X El Capitan: Users/<username>/Library/Application Support/Google/Chrome/Default

Linux: /home/<username>/.config/google-chrome/default

You need to replace <username> with the name of your user folder. The default profile folder is simply named Default (or default in Linux). However, if you’ve created additional profiles, their folder names are not as obvious. The name you assigned to the profile when you created it displays on a name button on the right side of the title bar on the Chrome window. Unfortunately, the name Chrome uses on the associated profile folder is a generic, numbered name like Profile 3.

If you need to know any of the Chrome Profile's folder name, you simply need to access chrome://version in the address bar and press Enter.

Snapshot:

The Profile Path shows the location of the current profile. For example, the location of my Default profile in my Windows 10 system is C:\Users\Soma Bhattacharjee\AppData\Local\Google\Chrome\User Data\Default. You can select the path and copy it and paste it into File Explorer in Windows, the Finder on OS X or into a file manager like Nautilus in Linux to access that folder.

Sample Code (Windows 10)

Finally, to access the Default Chrome Profile you can use the following Python based solution:

from selenium import webdriver
from selenium.webdriver.chrome.options import Options

options = webdriver.ChromeOptions()
options.add_argument("user-data-dir=C:\\Users\\Soma Bhattacharjee\\AppData\\Local\\Google\\Chrome\\User Data\\Default")
driver = webdriver.Chrome(executable_path=r'C:\WebDrivers\chromedriver.exe', chrome_options=options)
driver.get("https://www.google.co.in")

You can find a detailed discussion in How to use Chrome Profile in Selenium Webdriver Python 3