I am kind of new to Svelte and trying to solve this (seemingly trivial) problem with my UI:
I would like to change the classes of a checkbox and/or its parent element when the checkbox is checked. The Svelte docs tell me to create a boolean var for every checkbox and bind activation the classes to it: https://svelte.dev/tutorial/class-shorthand
but I have a random amount of checkboxes and many different types of checkboxes with different behaviour in styling and I don't want to create (or generate) a variable for every single checkbox.
Is there any elegant way in Svelte for changing the classes of checkboxes when they are indivually checked? (vanilla javascript instead if jquery if possible :) )
Cheers
Some Svelte noob
Based on what you have said, I would create a subcomponent to wrap the checkbox.
Lets Call it ToggleCheck. And if you want a div around each checkbox, then the div would live inside of of the ToggleCheck component
Then each instance of ToggleCheck would have its own var.
Your parent component could then have one or many instances of , even within a loop.
For something like this I would use... use, or actions. You can add/remove the class/classes using vanilla JS.
Since the class doesn't actually exist in the component you'll get an error if you define the class in your component unless you use :global()and even when doing that if you've set a property of CSS you'll need to make sure the specificity of the global selector is higher than the class generated by Svelte (i.e. :global(div.class))
Here's a REPL showing it in action with a few checkboxes and no need for variables or id's.
Related
I am trying to test the states of slide-toggles within my app using Cypress.
These time out and fails the test:
cy.get('label.mat-slide-toggle-label').eq(2).should('be.checked')
or
cy.get('div.mat-slide-toggle-bar').eq(2).should('be.checked')
Where as these pass
cy.get('label.mat-slide-toggle-label').eq(2).should('not.checked')
or
cy.get('div.mat-slide-toggle-bar').eq(2).should('not.checked')
The only difference is that the state of the toggle has changed.
Can someone help explain why the "not.checked" tests pass, but the others don't?
The documentation states:
The <mat-slide-toggle> uses an internal <input type="checkbox">
to provide an accessible experience. This internal checkbox
receives focus and is automatically labelled by the text content of
the <mat-slide-toggle> element.
When Angular Material adds the switch, it adds a whole little hierarchy of elements under the outer <mat-slide-toggle> element; divs with classes like mat-slide-toggle-label, mat-slide-toggle-bar, etc. But it also adds a real (but hidden) <input> element.
The 'checked' test only applies to input elements (this is probably why your should('not.be.checked') tests are working--because non-input elements can never be checked. So, to use Cypress's should('be.checked') test, you need to tell Cypress to get a reference to the actual <input> contained within the <mat-slide-toggle>, and not one of the other mat-xxx elements.
Example:
cy.get('mat-slide-toggle#whateverId input').should('be.checked');
// get reference to the single <input> inside the <mat-slide-toggle>
or:
cy.get('mat-slide-toggle#whateverId .mat-slide-toggle-input').should('be.checked');
// get reference to the element with class "mat-slide-toggle-input" inside the <mat-slide-toggle> (which is the <input> itself)
I was going to invite you to use the GUI snapshots panel to better understand what could be wrong, and maybe increase the timeout(s).
But in fact, I'm tempted to conclude that neither <label> nor <div> can be checked. <input type="checkbox"> can.
Is there another property you can assert on your label ?
I have managed to find a element for each toggle that allows me to check the state (checked or not checked).
input#mat-slide-toggle-29-input.mat-slide-toggle-input.cdk-visually-hidden
All I need to do is change the number to related to the toggle under test. I can check that the toggle is checked, press the master switch and then check that it is unchecked. I will also created a test where I test each toggle individually to ensure that the toggle works in a ground and singularly.
In my angular 1.5 html5 application, I have an accordion group and inside it's body I have Couple of check-boxes. Since direct scope binding will not work inside accordion, I'm using ng-click event as attached.
This works as expected, I'm getting click events with correct value.
I have another reset button on screen, when user clicks this button I have to reset all filters including the checkbox inside the accordion. Even after I reset the model value to false, checkbox still shows as checked. I know this is because the binding is not there.
How can I update the checkbox value from javascript. Is there any angular way. I'm not a big fan of JQuery.
Regards,
Nixon
We faced a similar issue with the data bindings while using accordian.
Instead of using directly model variable, we created an object of it.
For eg, instead of using $scope.includeLocalParties, try using $scope.checkbox.includeLocalParties.
Also initialize it in your controller. Something like this:
$scope.checkbox = { includeLocalParties : false};
Hope it helps!
I was creating a Dropdown component for React. Inside the dropdown, I have a form of radio group buttons.
<DropdownButton />
<DropdownForm />
In the DropdownButton, I have an state to know if it is open or not. Depends on that, DropdownForm it's hidden or not (using display: none).
The use case is: User selects a radio button, click apply and something happen. However, if user selects some radio button, and mouse out the dropdown (without clicking the apply button), the one that is selected should be the one that I get from the store.
Something like:
render: function () {
...
if(store.getSomeParam() != this.state.someParam && !this.props.isOpen){
someParam = store.getSomeParam()
}
Then the radio buttons are like:
<input checked={someParam == "something"} ... />
It doesn't really work. It re-renders but it doesn't change the button that is checked. I also tried with refs:
this.refs.myInput.getDOMNode().checked = true
But still nothing. Is this a correct behaviour?
The only solution I found so far is not using a css hiding class (display: none). So what I do is that the DropdownButton renders the DropdownForm depending on if it's open or not (so if you close it, you are forcing DropdownForm to unmount). Then when opening again, it is taking the values from the store (getInitialState) and it shows the correct radio button selected. But, I am not sure if this is the best solution and if there is any drawback in unmounting the component instead of just css hiding it.
This probably has nothing to do with React at all.
Most browsers don't validate the value of the checked attribute, but merely if it is there or not: http://jsfiddle.net/7jzm7gvw/
Just set the checked attribute to either true or null:
<input checked={someParam == "something" ? true: null} ... />
TL;DR: You must use the componentDidMount lifecycle method, not render, to work with the rendered dom nodes directly.
I was struggling with this as well, and after doing some online research I figured I might as well look into it for myself. Here's what I came up with:
Use the componentDidMount lifecycle method and update whatever you need to in there. Here's a Pen I used to prototype this, and I think it looks okay: http://codepen.io/gholts/pen/GpWzdb
You could drop this in pretty easily to what your'e working on by just putting a componentDidMount method on your object and doing it there. I used document.getElementById but you could definitely use jQuery or whatever else you wanted in there, as once the component has mounted it's available to DOM selectors.
I'm using this now to update 20 radio button groups (so it has to check a prop for three different states and update accordingly) and it loads instantly.
Hope it helps! I used the ES6 class syntax in my Pen, you should check it out if you have some time to refactor :) It's fun.
EDIT: So I figured it out, I'm a dummy. You don't need to do the whole document.getElementById business that I was doing. Just use your this.refs.whichever.getDOMNode().checked = true and it'll work, so long as you do it in componentDidMount. It works there because there is an actual DOM element on the page at that point.
I've got a table with the type ahead feature from jQuery UI. It is working with my form when there is only 1 table row (initial view). There's a button to allow the user to create additional table rows as required which also increments the IDs for the text inputs and select menus.
There's another script that inserts a matching value into the select menu based on the typeahead selection. Both of these work fine for the first row, but stop working for any additional Rows that are created.
I've setup a sample JSFiddle:
http://jsfiddle.net/fmdataweb/hxzME/1/
I think I understand why they only work for the first row - they are tied to these IDs: #lastYearSelect1 and #nextYearSelect1 - but I'm not sure how to change them so they then work with #lastYearSelect2, #nextYearSelect2, #lastYearSelect3, #nextYearSelect3 and so on.
There's a few problems with the script.
Firstly you're right, you need to setup all the scaffolding again after you clone the row, the clone method will not copy the functionality, just the html elements.
To find the right element you can use the JQuery ^= selector, which matches the start of an attribute name, on the on the clone object to find the right child input to turn into an autocomplete field. You can do the same trick in the function to change the dropdown to the correct function.
Finally a lot of your code and variables were in the wrong scope to be accessible properly. I've moved a lot of the vars around so they're accessible, mainly into the global scope. When you're a bit more experienced you won't want to do this, but for now this is fine.
I also created a new function setDropDown, but this code is almost identical to what was there before.
Here is a working version of your code:
http://jsfiddle.net/hxzME/3/
Add classes to elements and use class selectors when binding an event handlers.
Hello I have been using JQuery for quite a while. I need to get the ids of the checked elements. I have all my checkboxes as rows sitting inside a container, and I want to get the ids of all the checkboxes that have are checked.
I would use
$("#container input:checkbox")
to get all the checkboxes in that container, and then would check for which ones have been checked.
To do the same in ExtJS, i have been using the "get" method, and would do a
Ext.get('input')
which gives me all the input items, but I still have to check if they are of type "checkbox", is there a way I could get only the checkbox elements from DOM?
The equivalent function to JQuery's selector would be either Ext.query, or Ext.DomQuery.selectNode.
Ext.Query works in a very similar way as JQuery (see how the selectors work here).
In your case, you could try this:
Ext.query("#container input:checked")
Of course, this will only obtain DOM values rather than Ext components.
If you are using the CheckboxGroup object, you can use the getValues() method which will return an Array of the Checkboxes which you can use to look at the values...