I am having a very weird problem. I am trying to load a "Group" which has a list of devices. The devices exist in a table and a checkmark should appear when the device is inside the group.
My code looks like this:
function LoadGroup(Input)
{
document.querySelectorAll('input[type=checkbox]').forEach(el => el.checked = false);
console.log(Input.id);
GroupData.find(Element => {
if(Element["ID"] == Input.id)
{
Element["Devices"].forEach(Device => {
Checkmark = document.getElementById(Device["DeviceID"]);
Checkmark.checked = true
console.log(Checkmark.checked);
})
return true;
}
});
document.querySelectorAll('input[type=checkbox]').forEach(Element => console.log(Element.checked));
}
So a group gets clicked on, I search for the right Group in my data and then go through the devices to set the Checkmark and log the current state. I get 4 true in the console.
After this I query all checkmarks and check if they are checked. I get 3 true one false.
I dont understand what the problem is. He sets all true but then one is false.
Any ideas?
Related
I'm currently trying to render a specific class across two lightning-badge components that is suppose to change both badges from inverse to success, but am getting this instead:
When the value on the left badge equals the value on the right (so in this case both are 3), they should both be green, otherwise they should both be grey. They should never be seperate colours.
The value on the left increases as the user saves a record and is checked on status of "Completed". For some reason only the class on the second badge is being updated with the new class that includes slds-theme_success. I may be missing something small, but just haven't been able to figure it out. Please see code below:
badgeClass = "slds-badge_inverse slds-var-m-horizontal_x-small slds-col";
get patientsCompleted() {
if(this.records) {
let completedArr = this.records.filter(value => value.fields.Status__c.value == "Completed");
if(completedArr.length === this.patientsTotal) {
this.badgeClass = "slds-badge_inverse slds-theme_success slds-var-m-horizontal_x-small slds-col";
}
return completedArr.length;
}
};
get patientsTotal(){
if(this.records) {
return this.records.length;
}
};
<span class="slds-col_bump-left">
<div class="slds-grid slds-gutters">
<lightning-badge class={badgeClass} label={patientsCompleted}></lightning-badge>
<div class="slds-col"> of </div>
<lightning-badge class={badgeClass} label={patientsTotal}></lightning-badge>
</div>
</span>
Have you tried moving badgeClass to a getter? Something like this:
get patientsCompleted() {
if(this.records) {
let completedArr = this.records.filter(value => value.fields.Status__c.value == "Completed");
// No longer needed
// if(completedArr.length === this.patientsTotal) {
// this.badgeClass = "slds-badge_inverse slds-theme_success slds-var-m-horizontal_x-small slds-col";
// }
return completedArr.length;
}
};
get patientsTotal(){
if(this.records) {
return this.records.length;
}
};
get badgeClass() {
let baseClass = "slds-badge_inverse slds-var-m-horizontal_x-small slds-col";
return this.patientsCompleted === this.patientsTotal ? `${baseClass} slds-theme_success` : `${baseClass}`
}
I suspect LWC field tracking has some precautionary mechanism and didn't trigger the update.
I am not sure but perhaps if 0 records are available you want the badges to remain gray? In that case include this.patientsTotal > 0 in the get badgeClass() {...}.
Happy coding.
I am writing a trivia app. When I select an answer, I check if it is the right one and get a new question right after. The problem is that I can't get the React to render the selected radio button when it is the wrong answer.
Screenshot of what it looks like
I am generating the Trivia questions from a JSON file. I have to make a input and a label tag dynamically. This is what I have so far:
I can get my next question when the selected one is right, but it doesn't show any radio selected. My isRadioChecked starts with false. I also tried checked={this.state.isRadioChecked == object}.
Below, I check if the clicked radio was the right answer and my render method
checkResult = event => {
this.setState(
{
selectedAnswer: event.target.value
},
() => {
if (this.state.selectedAnswer === this.state.correctAnswer) {
this.setState(
{
isRadioChecked: false,
currentQuestionNumber: this.state.currentQuestionNumber + 1
},
() => {
this.getNewQuestion();
}
);
render() {
return (
<div onChange={this.checkResult}>
<h2>Question Component</h2>
<h3>{this.displayQuestion()}</h3>
<div>{this.displayAlternatives()}</div>
</div>
);
}
}
I really appreciate your help. Thank You!!
[EDIT]
Thank You, Arpitha that was the first thing I tried and actually my last attempts came straight from http://react.tips/radio-buttons-in-reactjs/ . I think the issue is that I am creating the radios using dynamic data.
Anyways, I did change it to like it was before and still, I get no visible selected radio, even though the log shows the selected answer.
setUpAnswers() {
let tempAnswerArray = this.mergeAnswers(this.state.currentQuestionNumber);
tempAnswerArray = tempAnswerArray.map((object, i) => renderHTML(object));
console.log(tempAnswerArray[0]);
tempAnswerArray = tempAnswerArray.map((object, i) => (
<div key={i}>
<input
type="radio"
name="answers"
checked={this.state.selectedAnswer === object}
onChange={this.handleOptionChange}
id={object}
value={object}
/>
<label htmlFor={object}>{object}</label>
</div>
));
this.setState({
answerArray: tempAnswerArray
});
}
//*************************************************** */
handleOptionChange = changeEvent => {
this.setState(
{
selectedAnswer: changeEvent.target.value
},
() => {
console.log(this.state.selectedAnswer);
}
);
};
You are assigning this.state.isRadioChecked status to all the radio buttons like this checked={this.state.isRadioChecked} . So all the radio buttons will be checked or unchecked at the same time.
Instead you can use state.selectedAnswer to update checked attribute of radio button. Something like this -
checked={this.state.selectedAnswer === object}
A nice article on how to create radio groups is explained here - http://react.tips/radio-buttons-in-reactjs/
I have (n) check boxes and a button in my angular2 view . When I click on one of them a function is called. When I click on the button every checkbox must be unchecked. How to do it?? (n) may vary dynamically.
enter image description here
I will give you an example from a table, since I have no idea what your code actually looks like, but it should work for what you need.
You need some object defined for all of your checkboxes. They likely all have certain properties in common, like labels. Here is an example of such an object:
myData = {
content: [
{
some_string: '',
some_number: 0,
type: '',
selected: false
}
]
};
With this object you can create checkbox instances and push each one to an array, which will hold all of your checkbox objects.
Create your checkboxes in your html in a loop using the objects you have defined above. In your html have your checkboxes call a function. In the case below the checkToggle() function is called.
<input id='{{row.id}}' class='bx--checkbox bx--checkbox--svg'
type='checkbox' name='checkbox' (change)="checkToggle($event,
row.id)" [checked]="row.selected">
checkToggle() has been defined as follows:
//select or deselect this check box
checkToggle(event, nodeId) {
const id = this.findNode(nodeId);
this.myData.content[id].selected = !this.myData[id].selected;
}
Your button should end up calling a function to check all of the boxes
<button (click)="checkToggleAll($event)">Your Button Title</button>
Finally, have your checkToggleAll() function go through the entire array of checkboxes and set them. Here is an example:
//select or deselect all the check boxes
checkToggleAll(event) {
for (let i = 0; i < this.myData.content.length; i++) {
if (this.controls[this.myData.content[i].type]) {
this.myData.content[i].selected = event.target.checked;
}
}
}
This is not something you can plug into your code but it should give you some idea of how to accomplish what you're after.
So I have a table, with which I need to be able to sort and filter (form submit) as well as being able to show and hide columns. I have a simple checkbox that does nothing but toggle the columns. I have been able to get that to work properly, but my problem now is that I need to save the state throughout the entire page lifecycle -- which doesn’t happen.
The basic column show/hide is in the page itself, right after the table:
#section Scripts {
<script type="text/javascript">
$('input[name="columnControl"]').on('switchChange.bootstrapSwitch', function (event, state) {
if (state) {
$("th.status").removeClass("columnHide");
$("td.status").removeClass("columnHide");
$("th.information").addClass("columnHide");
$("td.information").addClass("columnHide");
$("td#p1").attr('colspan', 4);
$("td#p2").attr('colspan', 6);
localStorage.setItem('columnControl', 'true');
} else {
$("th.status").addClass("columnHide");
$("td.status").addClass("columnHide");
$("th.information").removeClass("columnHide");
$("td.information").removeClass("columnHide");
$("td#p1").attr('colspan', 2);
$("td#p2").attr('colspan', 3);
localStorage.setItem('columnControl', 'false');
}
});
</script>
}
So please note: the above DOES WORK, at least in terms of showing and hiding the columns.
Now, the best method I have found so far for saving information through the page cycle is via the localstorage setting, as seen in the code above. This works splendidly for tabs on other pages, but I have been unable to get it to work for my table and bootstrap switch.
Specifically:
On page load, I want the switch to be conditional on the state of the localstorage setting. If it is true or false, the switch needs to be at the appropriate setting, and the appropriate classes need to be set for the columns. If there is no localstorage content (no True or False stored), I need the switch to be ON (true) and certain classes set (a default case).
On form submit (a GET, not a POST), I need to have the switch and all applied classes to remain the same as they were, and to NOT revert to a default case.
If the user leaves the page and returns to it, the switch and classes should remain at their last state and to not revert to the default.
The best I have been able to come up with is this:
#section Scripts {
<script type="text/javascript">
$( document ).ready(function() {
var columnState = localStorage.getItem('columnControl'); //grab the localstorage value, if any
if (columnState) { //does the localstorage value even exist?
$('input[name="columnControl"]').bootstrapSwitch('setState', columnState); //if localstorage exists, set bootstrap switch state based off of localstorage value
if (columnState == 'true') { //if localstorage value == true
$("th.status").removeClass("columnHide");
$("td.status").removeClass("columnHide");
$("th.information").addClass("columnHide");
$("td.information").addClass("columnHide");
$("td#p1").attr('colspan', 4); //set tfoot colspans
$("td#p2").attr('colspan', 6);
} else { //if localstorage value == false
$("th.status").addClass("columnHide");
$("td.status").addClass("columnHide");
$("th.information").removeClass("columnHide");
$("td.information").removeClass("columnHide");
$("td#p1").attr('colspan', 2); //set tfoot colspans
$("td#p2").attr('colspan', 3);
}
} else { //if localstorage value doesn't exist, set default values
$('input[name="columnControl"]').bootstrapSwitch('setState', true);
$("th.information").addClass("columnHide");
$("td.information").addClass("columnHide");
}
});
$('input[name="columnControl"]').on('switchChange.bootstrapSwitch', function (event, state) {
… first script, above …
});
</script>
}
The actual Bootstrap Switch is initialized by a global JS file, via
$("input[type=checkbox]").bootstrapSwitch(); // checkbox toggle
which appears in the head of the webpage.
I have two groups of columns, information and status which comprise 80% of the columns between them. Three columns have no flag for being hidden or unhidden, because they are meant to be displayed at all times.
for test if the local storage exist use :
columnState === null
You just need to fire the switchChange event after define the default value
Full exemple :
#section Scripts {
<script type="text/javascript">
$( document ).ready(function() {
$('input[name="columnControl"]').on('switchChange.bootstrapSwitch', function (event, state) {
if (state) {
$("th.status").removeClass("columnHide");
$("td.status").removeClass("columnHide");
$("th.information").addClass("columnHide");
$("td.information").addClass("columnHide");
$("td#p1").attr('colspan', 4);
$("td#p2").attr('colspan', 6);
localStorage.setItem('columnControl', true);
} else {
$("th.status").addClass("columnHide");
$("td.status").addClass("columnHide");
$("th.information").removeClass("columnHide");
$("td.information").removeClass("columnHide");
$("td#p1").attr('colspan', 2);
$("td#p2").attr('colspan', 3);
localStorage.setItem('columnControl', false);
}
});
var columnState = localStorage.getItem('columnControl'); //grab the localstorage value, if any
if (columnState === null) { //does the localstorage value even exist?
columnState = true //if localstorage value doesn't exist, set default values
}
$('input[name="columnControl"]').bootstrapSwitch('setState', columnState);
</script>
}
I am building a pretty combobox with checkboxes and conditional entries. Everything works out alright, except for two features that I cannot figure out how to implement.
1) I would like to move the label inside the combobox, make it shift the values to the right, and appear in a slightly gray color.
2) I would like the value to ignore certain entries (group headers) selected. Those entries are there for functionality only - to select/unselect groups of other entries.
The entire project is in the zip file. You don't need a server, it's a client base app. Just download the archive, unpack, and launch app.html in your browser.
http://filesave.me/file/30586/project-zip.html
And here's a snapshot of what I would like to achieve.
Regarding your second issue, the best way I see is to override combobox onListSelectionChange to filter the values you don't want:
onListSelectionChange: function(list, selectedRecords) {
//Add the following line
selectedRecords = Ext.Array.filter(selectedRecords, function(rec){
return rec.data.parent!=0;
});
//Original code unchanged from here
var me = this,
isMulti = me.multiSelect,
hasRecords = selectedRecords.length > 0;
// Only react to selection if it is not called from setValue, and if our list is
// expanded (ignores changes to the selection model triggered elsewhere)
if (!me.ignoreSelection && me.isExpanded) {
if (!isMulti) {
Ext.defer(me.collapse, 1, me);
}
/*
* Only set the value here if we're in multi selection mode or we have
* a selection. Otherwise setValue will be called with an empty value
* which will cause the change event to fire twice.
*/
if (isMulti || hasRecords) {
me.setValue(selectedRecords, false);
}
if (hasRecords) {
me.fireEvent('select', me, selectedRecords);
}
me.inputEl.focus();
}
},
And change your onBoundlistItemClick to only select and deselect items in the boundlist not to setValue of the combo:
onBoundlistItemClick: function(dataview, record, item, index, e, eOpts) {
var chk = item.className.toString().indexOf('x-boundlist-selected') == -1;
if ( ! record.data.parent) {
var d = dataview.dataSource.data.items;
for (var i in d) {
var s = d[i].data;
if (s.parent == record.data.id) {
if (chk) { // select
dataview.getSelectionModel().select(d[i],true);
} else { // deselect
dataview.getSelectionModel().deselect(d[i]);
}
}
}
}
},
Regarding your first issue, it is easy to add the label using the displayTpl config option. But this will only add the text you need, without any style (grey color, etc). The combo is using a text input, which does not accept html tags. If you don't need the user to type text, than you may want to change the combo basic behavior and use another element instead of the text input.