I want to set the checkbox input to checked if specific inputs is filled with values but with the option to change checkbox to unchecked again.
the business need requires that this checkbox should be set to checked automatically if the user filled the required inputs but with the option to set it back to unchecked if he wants.(user experience stuff)usecase demo
Consider the following code:
autoAddFinalEvaluation = () => {
const {channelValue, evaluationValue, txtValue} = this.state;
if(channelValue !== null && evaluationValue !== null && txtValue !== '') {
this.setState({
checked: true
})
}
}
i updated the state dynamically like this
autoAddFinalEvaluation = () => {
const {channelValue, evaluationValue, txtValue} = this.state;
if(channelValue !== null && evaluationValue !== null && txtValue !== '') {
this.setState({
checked: !this.state.checked
})
}
}
now i can set the checkbox normally but still not working as i expect, while filling the 3rd input(text area) the checkbox switches from true to false and vice versa.
I think the problem is "autoAddFinalEvaluation" is executed after you uncheck the checkbox while it should be called only when input changed in what we may call parent field (The field which input causes the checkbox to be checked).
Related
I have an input field in my react application like below. suggestedTerm and searchTerm are coming from component's state. searchTerm state is being set in onChange handle. suggestedTerm state is being set when i navigate up or down in autocomplete suggestion list.
<input value={suggestedTerm || searchTerm}
onChange={handleInputChange}
onFocus={() => {
setShowFlyout(true);
clearActiveSuggestion();
}}
onKeyDown={handleInputKeyDown}
ref={searchInput}
/>
Here through onKeyDown handler, i am handling up and down arrow key events to navigate through the autosuggestion suggestions list that is being produced while keeping the focus on the input field. That was done basically to cater accesibility.
The requirement is to set the selected suggestion on the input field as we navigate through the autosuggestion list. However, the issue i am facing here is that my cursor moves to the beginning of the input field whenever i set suggestedTerm state which in return sets the input field's value while navigating up using up arrow key. This does not happen when i navigate through down key.
Attaching here my up key and down key logic
if ((e.key === "ArrowUp" || e.keyCode === 38) && !isEmpty(suggestions)) {
const focusedItem = getActiveSuggestion();
const index = focusedItem[0].index - 1;
if (!isEmpty(focusedItem) && focusedItem[0] && focusedItem[0].index > 0) {
setActiveSuggestion(index);
} else {
//Clear active suggestions if up is pressed while focus is on first element
clearActiveSuggestion();
}
if ((e.key === "ArrowDown" || e.keyCode === 40) && !isEmpty(suggestions)) {
const focusedItem = getActiveSuggestion();
//Set first suggestion active
if (isEmpty(focusedItem)) setActiveSuggestion(0);
else {
if (
!isEmpty(focusedItem) &&
focusedItem[0] &&
focusedItem[0].index < (suggestions && suggestions.length - 1)
) {
setActiveSuggestion(focusedItem[0].index + 1);
} else {
//Set first suggestion active when focus is on last item already and down key is pressed
setActiveSuggestion(0);
}
}
}
const clearActiveSuggestion = () => {
setSuggestions(suggestions.map(suggestion => ({ ...suggestion, active: false })));
setSuggestedTerm("");};
const getActiveSuggestion = () => {
return suggestions.filter(suggestion => suggestion.active);};
const setActiveSuggestion = activeItemIndex => {
const updatedSuggestion = suggestions.map(suggestion => {
if(activeItemIndex === suggestion.index)
setSuggestedTerm(suggestion.dq);
return {...suggestion, active: activeItemIndex === suggestion.index};
});
setSuggestions(updatedSuggestion);};
First, i do not understand why my input field is setting cursor to start of the input field even though i am changing the state and state change should reset value of input field.
Second, i searched a number of ways to manually set the cursor using setSelection method and manually setting input field's value using ref but nothing is changing the behavior.
Can anybody figure out the issue here?
Thanks
Figured out the root cause. Actually, it is a default behavior of an input field to take cursor to start of the string in an input field when up arrow is pressed on it so i simply added
e.preventDefault();
and that prevented the default behavior of the input field to move the cursor. It had nothing to do with how i am setting the state or setting the selectionRange of the input manually.
When I click the + button to expand the group and click the checkbox of group 1, it executes as expected.
But the problem is,
If I click the checkbox of group 1 first and then expand the group by clicking + button,
It shows all user clicked which is correct, if I clicked the checkbox of group 1 again, the checkbox of group 1 become unchecked, but the checkboxes of users do not get unchecked.
Reproduce step:
refresh the page > Click group 1 checkbox > click + to expand > click group 1 checkbox again > then you'll see user checkbox do not become unselected
SandBox Link below:
https://codesandbox.io/s/dazzling-antonelli-gl9rm
after Unselecting group 1, 2 checkboxes of users do not become unselected:
Your isExist method returns undefined instead of false, fix it to return always either true/false.
isExist = (id, group) => {
if (!this.props.selected) {
console.log("selected = null");
return false;
}
return (
this.props.selected.find((ele) => ele.id === group + id) !== undefined
);
};
This way you don't have to manually convert its return value to boolean using !!.
I suggest to also refactor your handleSelected method to
handleSelected = async (e) => {
const { selected } = this.state;
if (e.target.checked) {
let temp = { id: e.target.id, name: e.target.name };
return this.setState({ selected: [...selected, temp] });
}
this.setState({
selected: selected.filter(({ id }) => id !== e.target.id)
});
};
The issue you are experiencing is a result of a problem in the first render - as you can see - you have "undefined Contact". You need to solve this issue, and then the grouping will work as you desire.
If you click on the selected checkboxes, the problem is encountered while writing code that removes() the input val value that matches the val value in the checkbox, using each while it is being deleted.
Problem
When there are two or more checked checkboxes, only the first one is deleted even if the value of val is the same.
onlyremove.click(function () {
var chk = $("input[name='cbx']:checked").length;
$("input[name='cbx']:checked").each(function() {
pickbtn.find('.ordering').filter(function () {
return $("input[name='cbx']:checked").val() && $(this).find('.number').val() == $("input[name='cbx']:checked").val();
}).text('rldd'),alert('123123'), --num;
});
});
I'm writing a small required HTML5 attribute fallback for various inputs. It's going pretty well so far, but I'm having trouble when checking a radio button is ':checked' and using the 'OR' || operator in the loop:
if (self.val() === '' || self.is(':not(:checked)')) {
For some reason when I add this it breaks the script slightly and will indicate that the input fields (type=text) are empty when they're not. Is there a better way at all to loop through and indicate the difference between an input type 'text' and 'radio'?
Here's the loop:
var reqClass = $('.required')
reqClass.each(function(){
var self = $(this)
// if empty
if (self.val() === '' || self.is(':not(:checked)')) {
// if it doesn't have require-checked class
if (!self.hasClass('require-checked')) {
self.addClass('require-checked')
self.parent().append('<span class="form-error">This field is required.</span>')
}
e.preventDefault()
//$('.form-submit').attr('disabled', true)
// if it's been checked, but there is a value now
} else if (self.hasClass('require-checked') && !(self.val() === '')) {
self.siblings('.form-error').hide()
}
})
Classes are obviously present for 'fallback' browsers and changed on the fly. Here's a JSFiddle, thank you for any help:
http://jsfiddle.net/cyncV/2/
A text box is indeed :not(:checked) (even if it has text in it), so the text boxes are showing as empty when they are not.
Perhaps something like
if (self.val() === '' || self.is(':checkbox:not(:checked)') || self.is(':radio:not(:checked)')
var self = this;
var empty = self.type=='checkbox' ? !self.checked : self.value=='';
if (empty) {
// do stuff
}
FIDDLE
There is a solution :
var checked = (self.is(':checkbox') || self.is(':radio')) ? self.is(':not(:checked)') : false;
if (self.val() === '' || checked) {}
Just add a little condition that if input is checkbox or radio, it look if it's checked, else it return false. Then pass the result into the if condition.
Basically the same functionality as stackoverflow when posting a question, if you start writing a post then try to reload the page. You get a javascript alert box warning message.
I understand how to check if the form has been changed, although how do I do the next step.
I.E: How to I check this when leaving the page, on here you get "This page is asking you to confirm that you want to leave - data you have entered may not be saved."?
EDIT: found correct answer here to another question https://stackoverflow.com/a/2366024/560287
I'm very sure that if you search, 'jQuery detect form change plugin', you will find something much more usable than this semi-pseudo code i'm about to write:
formChanged = function(form) {
form.find('input[type="text"], textarea').each(function(elem) {
if (elem.defaultValue != elem.value) {
return true;
}
});
// repeat for checkbox/radio: .defaultChecked
// repeat for ddl/listbox: .defaultSelected
return false;
}
usage:
if (formChanged($('form')) { // do something }
Note that this is to detect changes against the original rendered value. For instance, if a textbox has a value = "x", and the user changes it to "y", then changes it back to "x"; this will detect it as NO change.
If you do not care about this scenario, you can just do this:
window.formChanged = false;
$(':input').change(function() {
window.formChanged = true;
});
Then you can just check that value.
Yes, it is JavaScript as HTML is just a markup language.
Yes, jQuery can be used for this. It's preferable over vanilla JavaScript as it makes things easier, although it does add some overhead.
There are a number of ways to check if any of a form's controls have changed.
To check for changes from the default, most can be checked against the defaultValue property. For radio buttons, you should always have one checked by default, so check if it's still selected or not. Similarly for selects, set the selected attribute for the default option and see if it's still selected, and so on.
Alternatively, if all your form controls have an ID or unique name, you can collect all their values onload and then check their values when the form is submitted.
Another method is to listen for change events on each form control, but that is a bit over the top.
Here's a POJS version that takes the same approach as rkw's answer:
/*
Check if any control in a form has changed from its default value.
Checks against the default value for inputs and textareas,
defaultChecked for radio buttons and checkboxes, and
default selected for select (option) elements.
*/
function formChanged(form) {
var control, controls = form.elements;
var tagName, type;
for (var i=0, iLen=controls.length; i<iLen; i++) {
control = controls[i];
tagName = control.tagName.toLowerCase();
type = control.type;
// textarea
if (tagName == 'textarea') {
if (control.value != control.defaultValue) {
return true;
}
// input
} else if (tagName == 'input') {
// text
if (type == 'text') {
if (control.value != control.defaultValue) {
return true;
}
// radio and checkbox
} else if (type == 'radio' || type == 'checkbox') {
if (control.checked != control.defaultChecked) {
return true;
}
}
// select multiple and single
} else if (tagName == 'select') {
var option, options = control.options;
for (var j=0, jLen=options.length; j<jLen; j++) {
option = options[j];
if (option.selected != option.defaultSelected) {
return true;
}
}
}
}
// Not really needed, but some like the return value to
// be a consistent Type
return false;
}
Note that you need to be careful with select elements. For a single select, you should always set one option to selected, as if there is no default selected, some browsers will make the first option selected and others wont.