antd checkbox inside a button - html

react beginner here, here i have antd checkbox, i want to change this checkbox into a button but still have checkbox functionality: here is my checkbox:
import { Checkbox } from "antd";
<div className="modal-body d-flex flex-column">
<Checkbox
indeterminate={indeterminate}
onChange={onCheckAllChange}
checked={checkAll}
>
Select All{" "}
</Checkbox>
</div>
this is what i tried to do, i tried to give opacity zero to checkbox to hide it and then put checkbox inside a button in order to change the look of it to button and have checkbox functionality, but problem is, this new button is working if you click on the left side of the button but right side is not working, any solution ?
:
import { Checkbox } from "antd";
<div className="modal-body d-flex flex-column">
<button>
<Checkbox
style={{ opacity: "0" }}
indeterminate={indeterminate}
onChange={onCheckAllChange}
checked={checkAll}
>
Select All{" "}
</Checkbox>
Select All
</button>
</div>

If you want the button to do exactly what the checkbox does, simply pass the onCheckAllChange to the button onClick.
<div className="modal-body d-flex flex-column">
<button onClick={onCheckAllChange}>
Select All
</button>
</div>
and your handle change is something like this assuming your state variables are
checkedList, indeterminate, and checkAll:
const onCheckAllChange = (e: any) => {
setCheckedList(!checkedList.length ? allColumnKeys : []);
setIndeterminate(false);
setCheckAll(!checkAll);
};

Related

Kendo checkbox toggle true and false states not working properly

I'm trying to get it so when one or more checkbox is clicked, I'm able to get a button to appear. I would like the toggle function to work if one or more checkbox is clicked, but instead, it will turn on when I select one checkbox, then turn off during the next selection. I'm sure I've got a couple of unnecessary properties added into here as well, but not too concerned about that. Any help would be appreciated.
HTML: Button
<button class="btn btn-primary"
*ngIf="switchCase" style="float:right"
>Save</button>
HTML: Checkbox Column
<kendo-grid-column field="checkbox" editor="boolean">
<ng-template kendoGridCellTemplate let-dataItem id="flexSwitchCheckChecked"
>
<input type="checkbox" (click)="toggleButton(dataItem, 'checkbox'
[checked]="dataItem.checkbox"
[width]="40"
>
TS: Button click method
public switchCase: boolean = false;
toggleButton() {
this.switchCase = !this.switchCase;
pass an event to your function then access its value from typescript class:
Step1(pass an $event):
on *ngFor tag level add an index var
<div *ngFor="let item of items;let i = index" >
<input type="checkbox" (change)="toggleButton($event,i)">
</div>
Step1(get its value):
toggleButton($event,i) {
let newValue = $event.target.value;
// this.switchCase =newValue;
this.items[i].checked = newValue;
}

Button component wont show linktext inside <Link>

I expect that the text of the p tag inside the Link to be white, but for some reason the link text won't display. It appears to be hidden and only displays once I hover over the button. When I hover it is only barely visible. Can it be due to the <Link>?
I have appended the code and a picture that shows my button below.
Any help would be greatly appreaciated :)
Index.js file
<div class="py-4">
<Button>
<div className="p-1">
<Link to="/contact">
<p>Get in contact</p>
</Link>
</div>
</Button>
</div>
Button component:
import React from 'react';
const sizes = {
default: `py-3 px-8`,
lg: `py-4 px-12`,
xl: `py-5 px-16 text-lg`
};
const Button = ({ children, className = '', size }) => {
return (
<button
type="button"
className={`
${sizes[size] || sizes.default}
${className}
bg-primary
hover:bg-primary-darker
rounded
text-white
`}>
{children}
</button>
);
};
export default Button;
picture of button, which should show get in contact
try this :
<Link to="/contact" style={{color:'#fff'}}>Get in contact </Link>
or add your own className with the color u wanna use

Hide PayPal Button

I am trying to hide a PayPal button depending on the state of my switch. At the moment, once the paypal button gets rendered, it always stays there. Regardless of whether the switch gets set back to credit card
Here is the switch:
<p class="heading">Payment Method</p>
<div class="frame flex-row flex-center">
<button
class="flex-column flex-center"
(click)="paymentMethod = 'creditCard'; dismountPaypal()"
[ngClass]="
paymentMethod == 'creditCard' ? 'type-btn-active' : 'type-btn'
"
>
Debit/Credit Card
</button>
<button
class="flex-column flex-center"
(click)="paymentMethod = 'paypal'; renderPaypal()"
[ngClass]="paymentMethod == 'paypal' ? 'type-btn-active' : 'type-btn'"
>
PayPal
</button>
</div>
and here is the button itself:
<div>
<div #paypalRef></div>
</div>
on my component.ts file I've got this to render the button, this function gets called when paypal gets clicked in the switch:
#ViewChild("paypalRef", { static: true }) private paypalRef: ElementRef;
renderPaypal() {
if (this.paypalButtonRendered != true) {
window.paypal
.Buttons({
style: {
layout: "horizontal",
color: "white",
},
})
.render(this.paypalRef.nativeElement);
}
this.paypalButtonRendered = true;
}
I've tried using ngIf on the parent div component and the div of the button itself. This just results in the button never being displayed. I've also tried using [ngClass] snd setting a CSS style to display none if the payment method is credit card, but this also doesn't work. I'm kind of at a loss right now. Any help would be greatly appreciated.
Add the style display: none; to the button you don't want rendered, based on the paymentMethod condition.

Trying to get an overlay to toggle on a repeating element. Can't use getElementByID

As per the title I want an overlay to trigger when an image is clicked on, but I then want it to disappear if anywhere other than 3 buttons on the overlay are clicked.
Unfortunately using getElementbyID won't work as the items repeat on a masonry layout.
<Masonry
breakpointCols={breakpointColumnsObj}
className="my-masonry-grid"
columnClassName="my-masonry-grid_column">
{this.state.data.map((data) => (
<div>
<div className="tilebutton" key="" style={{width:'100%',position:'relative'}} href={data.URL} >
<div className="tileoverlay" id="overlay" onClick={overlayoff} onclickout key={data.URL} style={{display:'none',width:'100%',zindex:'2',position:'absolute'}}>
<a className="button1" href={data.URL} onClick>{data.Name}</a>
<a className="button2" href={data.CompURL}>{data.Company}</a>
<a className="button3" href={'instagram.com/'+data.insta}>{data.Company}<img src="\img\Icons\instagram.svg" className='instalogo'/></a>
</div>
<img src={data.img} onClick={overlayon} style={{width:'100%'}}/>
</div>
</div>
))}
</Masonry>
)
function overlayon() {
document.getElementById("overlay").style.display = "block";
}
function overlayoff() {
document.getElementById("overlay").style.display = "none";
}
Unfortunately using the id "overlay" means if I click any version of the masonry it will trigger the overlay on the first image. Is there some way to:
a) identify the element clicked so it will be the one with the toggling overlay
b) have an "onclickout" I could apply to the overlay's buttons
this is about 5 days into my first ever web build so frankly I haven't got a clue what I am doing - any help is appreciated.
Thanks in advance.
The idioms used in React discourages you to manipulate the DOM directly, unless you are doing something special, such as animation. And thus I don't recommend "identifying the element clicked".
With that said, you can manipulate the data, and trigger a redraw accordingly, by invoking some setSate function (in the example below, I've defined a setShouldShowOverlay, that, when invoked, will result in a redraw).
What I recommend is for you to pull out the code inside this.state.data.map() into its own component, like so:
import React, { useState } from 'react';
function Data({ data }) {
const [ shouldShowOverlay, setShouldShowOverlay ] = useState(false);
return (
<div>
<div className="tilebutton" key="" style={{width:'100%',position:'relative'}} href={data.URL} >
<div className="tileoverlay" id="overlay" onClick={() => { setShouldShowOverlay(false); }} onclickout key={data.URL} style={{display:'none',width:'100%',zindex:'2',position:'absolute'}}>
<a className="button1" href={data.URL} onClick>{data.Name}</a>
<a className="button2" href={data.CompURL}>{data.Company}</a>
<a className="button3" href={'instagram.com/'+data.insta}>{data.Company}<img src="\img\Icons\instagram.svg" className='instalogo'/></a>
</div>
<img src={data.img} onClick={() => {
setShouldShowOverlay(true);
}} style={{width:'100%'}}/>
</div>
</div>
);
}
Then finally, update your Masonry code like so:
<Masonry
breakpointCols={breakpointColumnsObj}
className="my-masonry-grid"
columnClassName="my-masonry-grid_column">
{this.state.data.map((data) => (
<Data data={data} />
))}
</Masonry>

AngularJS- how to hide elements using ng-hide?

I have an app that has been written in AngularJS, and am currently trying to add the functionality to hide the headings of some widgets displayed on one of the web pages when the user selects a checkbox to indicate that they should be hidden.
At the moment, I have a page that displays a number of widgets- on the 'heading' of each widget, there is a 'Settings' button. When the user clicks the Settings button, a dialog box opens up on top of the current page (i.e. the user does not navigate to another page- the URL does not change at all). That dialog box contains a form with a number of input fields- one of which is a checkbox that I want to use to 'hide' the headings of all of the widgets on the webpage.
I have been following the example at: https://docs.angularjs.org/api/ng/directive/ngHide to try and do this, but can't quite seem to get it working...
I have added the ng-hide attribute to my HTML element, as in the example:
<div data-ng-if="widget.name === 'tag-box'" ng-hide="hideWidgetHeading"> <!-- class="ng-hide"-->
<div class="divider"></div>
...
<div class="divider"></div>
<div class="row ui-checkbox-row">
<label class="col-sm-4 col-xs-6" data-i18n="Hide widget heading:"></label>
<div class="col-sm-8 col-xs-6">
<label class="ui-checkbox">
<input type="checkbox" name="noWidgetHeading" id="noWidgetHeading" ng-true-value= "'YES'" ng-false-value= "'NO'" ng-change="hideWidgetHeading()" ng-click="hideWidgetHeading()" ng-checked="hideWidgetHeading" ng-model="viewModel.hideWidgetHeading">
<!-- ng-model="viewModel.hideWidgetHeading" -->
<span></span>
</label>
</div>
</div>
</div>
I defined the hideWidgetHeading() function in the ctrl.js file as follows:
function hideWidgetHeading(){
if($scope.widgetHeadingCheckbox==false) {
$scope.$watch('noWidgetHeading', function() {
$scope.hideWidgetHeading = true;
console.log("Value of hideWidgetHeading: ", $scope.hideWidgetHeading);
});
return true;
} else {
console.log("hideWidgetHeading() else called (Widget/ctrl.js line 440) ");
$scope.$watch('noWidgetHeading', function() {
$scope.hideWidgetHeading = false; //document.getElementById('noWidgetHeading');
});
return false;
}
if($scope.hideWidgetHeading) {
console.log("hideWidgetHeading is true- hide the widget heading: ");
}
return $scope.hideWidgetHeading;
}
and I have added the following CSS to my widgets.scss file:
.animate-show-hide.ng-hide {
opacity: 0;
}
.animate-show-hide.ng-hide-add,
.animate-show-hide.ng-hide-remove {
transition: all linear 0.5s;
}
.umw-tag-box {
opacity: 1;
}
When I load my page as it is presently, when I click the Settings button, the dialog opens up. If I then check the 'Hide widget heading' checkbox, and click Submit, the debug that I have added displays the following in the console:
Value of hideWidgetHeading: true
which tells me that the code inside the $scope.$watch(...){...} function is running.
However, if I click the Settings button, and then either don't check the 'Hide widget heading' checkbox, or check it and uncheck it again, and then click Submit, I get the same true value displayed in the console debug, which indicates that the code inside the $scope.$watch(...){...} function is running regardless of whether the 'watched' element changes or not.
Questions
How can I ensure that the code inside the $scope.$watch(...){...} only runs when the 'watched' element (i.e. the checkbox) has its value changed?
How do I actually 'call' the CSS that I've added to hide the HTML elements on the particular HTML that I want to hide? Or how do I make that CSS 'apply' to the HTML elements that I want to hide?
Edit
I changed the HTML for the checkbox to:
<input type="checkbox" ng-model="checked" name="noWidgetHeading" id="noWidgetHeading">
as suggested, and when I now browse to my page, and open the dialog, it displays the widget as I expect:
When I click the 'Settings' button on the widget, the 'Configure Item' dialog opens up on top of the page:
But when I select the 'Hide widget heading' checkbox, it actually hides the 'Tag' label & input box from the dialog:
The element I want to hide is actually displayed on the page from which the dialog box is opened, not on the dialog box itself... but I can't seem to work out how I can hide that using a control on the dialog... Any suggestions?
So, this should work, it is even the first example shown in their docs, with your code it will be:
<div data-ng-if="widget.name === 'tag-box'" ng-hide="viewModel.hideWidgetHeading"> <!-- class="ng-hide"-->
<div class="divider"></div>
...
<div class="divider"></div>
<div class="row ui-checkbox-row">
<label class="col-sm-4 col-xs-6" data-i18n="Hide widget heading:"></label>
<div class="col-sm-8 col-xs-6">
<label class="ui-checkbox">
<input type="checkbox" name="noWidgetHeading" id="noWidgetHeading" ng-true-value= "'YES'" ng-false-value= "'NO'" ng-change="logWidgetHeading()" ng-click="logWidgetHeading()" ng-checked="viewModel.hideWidgetHeading" ng-model="viewModel.hideWidgetHeading">
<!-- ng-model="viewModel.hideWidgetHeading" -->
<span></span>
</label>
</div>
</div>
</div>
you can keep functions on the events if you wan to log values, but there is no need for hiding. The ng-model directive will update your value and the ng-hide should follow.
function logWidgetHeading(){
console.log("Value of hideWidgetHeading: ", $scope.hideWidgetHeading);
}
What i was saying about function or var: in some cases, i used to have values from the scope that were not updated, and the solution was to introduce a function to be called to retreive the value. It is what i thought you were trying because ng-hide="hideWidgetHeading" shows the same name as your function: function hideWidgetHeading(){, that's why i first said that the round brackets were missing. So another version would be something like this (without ng-model on purpose, to show an alternate way to modify stuff with your events):
<div data-ng-if="widget.name === 'tag-box'" ng-hide="getHideWidgetHeading()"> <!-- class="ng-hide"-->
<div class="divider"></div>
...
<div class="divider"></div>
<div class="row ui-checkbox-row">
<label class="col-sm-4 col-xs-6" data-i18n="Hide widget heading:"></label>
<div class="col-sm-8 col-xs-6">
<label class="ui-checkbox">
<input type="checkbox" name="noWidgetHeading" id="noWidgetHeading" ng-true-value= "'YES'" ng-false-value= "'NO'" ng-change="toggleWidgetHeading()" ng-checked="isHiddenWidgetHeading">
<!-- ng-model="viewModel.hideWidgetHeading" -->
<span></span>
</label>
</div>
</div>
</div>
and the js:
//initialisation to the default value:
$scope.isHiddenWidgetHeading = false;
//function that toggles the value:
$scope.toggleWidgetHeading = function(){
$scope.isHiddenWidgetHeading = !$scope.isHiddenWidgetHeading;
};
//function to retreive the value:
$scope.getHideWidgetHeading = function(){
return $scope.isHiddenWidgetHeading;
};
Sorry i was a bit quick in naming vars and such, but you should get what you need here..