I am using AngularJS to write the front-end of my website, and currently have a number of widgets displayed on a particular page. I am looking to add the functionality to hide the widget heading based on whether or not the user has selected a particular checkbox on a dialog box that is opened when they click one of the buttons on a widget.
The HTML for this checkbox is:
<div data-ng-if="widget.name === 'umw-tag-box'" ng-hide="hideWidgetHeading()">
...
<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" ng-true-value="true" ng-false-value="false" ngChange="hideWidgetHeading()">
<span></span>
</label>
</div>
</div>
</div>
The JS is called when the 'Preview' button is clicked on the dialog box:
var widgetHeadingCheckbox = document.getElementById("noWidgetHeading");
//if(widgetHeadingCheckbox == true){
console.log("Value of widgetHeadingCheckbox: ", widgetHeadingCheckbox);
if(widgetHeadingCheckbox){
console.log("if(widgetHeadingCheckbox) statement entered ");
hideWidgetHeading();
} else {
console.log("else of if(widgetHeadingCheckbox) statement entered ");
hideWidgetHeading();
}
$scope.preview = function(e) {
function hideWidgetHeading(){
if(widgetHeadingCheckbox){
console.log("hideWidgetHeading() called (Widget/ctrl.js line 501) ");
console.log("Value of widgetHeadingCheckbox (should be true): ", widgetHeadingCheckbox);
return widgetHeadingCheckbox;
} else {
console.log("hideWidgetHeading() called (Widget/ctrl.js line 501) ");
console.log("Value of widgetHeadingCheckbox (should be false): ", widgetHeadingCheckbox);
return widgetHeadingCheckbox;
}
}
$timeout(function() { previewDisabled = false; }, 500);
};
At the moment, regardless of whether the checkbox is checked or not, when I click the 'Preview' button on the dialog box, the console is displaying the message:
Value of widgetHeadingCheckbox (should be false): null
which tells me that the widgetHeadingCheckbox variable is either not being set correctly, or it's taking the value of the checkbox when the checkbox is declared, but not initialised (i.e. null), and is not being updated when any changes are made to the value of the checkbox...
What is the best way to ensure that my JS function always holds the correct value of the HTML checkbox element, and is updated any time any changes are made to the element in the HTML?
Edit
So, having done a bit more research, I finally came across AngularJS' $scope.$watch() which is, it seems, how to add an 'event listener' for a change in the value of the checkbox.
I tried adding the following code beneath the declaration of the widgetHeadingCheckbox variable that I am using to get the HTML checkbox element:
var widgetHeadingCheckbox = document.getElementById("noWidgetHeading");
console.log(widgetHeadingCheckbox);
if(widgetHeadingCheckbox){
hideWidgetHeading();
} else {
hideWidgetHeading()
}
function hideWidgetHeading(){
if(widgetHeadingCheckbox){
console.log("Value of checkbox in if(): ", widgetHeadingCheckbox);
return widgetHeadingCheckbox;
} else {
$scope.$watch('widgetHeadingCheckbox', function(){
console.log("Value of checkbox has changed inside $watch() ", widgetHeadingCheckbox);
}, true)
return widgetHeadingCheckbox;
}
}
But, when I load the page, click the button that opens the dialog box, select the checkbox (so that its value is checked/ true), and click the 'Preview' button on the dialog box, the console displays the output:
Value of checkbox has changed (inside $watch() null
I also found that I shouldn't be using quotes in the HTML for the true/ false values of the checkbox, so changed that to:
<div class="col-sm-8 col-xs-6">
<label class="ui-checkbox">
<input type="checkbox" name="noWidgetHeading" ng-true-value= true ng-false-value= false ngChange="hideWidgetHeading()" ng-click="hideWidgetHeading()" ng-model="checkboxModel">
<span></span>
</label>
</div>
So it would seem that the checkbox is never actually being given a true/ false value... Why is this? How can I set it in order to use it in the JS function?
when you use ng-if, it acts like a child.
So the you should access it like $parrent.foo...
Related
In order to get you familiar with my work, I have table filled with data from database and it's basically CRUD - Create, Read, Update, Delete table.
Now, I have one table column where are EDIT and DELETE buttons placed. When I click on EDIT button, Bootstrap 5 modal pop-ups and inside of that modal there're <input> elements, also filled with data from database. Everything works fine (is filled correctly and based on ID of selected row) except that I can't get <select> to change its value on value from database.
Here's my <select> element (HTML):
<div class="mb-3">
<select name="carStatus" id="carStatus" class="form-control form-control-lg" required>
<option value="U obradi" selected disabled hidden></option>
<option value="Na cekanju">Na cekanju</option>
<option value="U procesu">U procesu</option>
<option value="Zavrseno">Zavrseno</option>
</select>
<div class="invalid-feedback">Niste unijeli status!</div>
</div>
This is js code where I handle values of input fields inside of modal:
// Fill in values and handle edit event
tbody.addEventListener("click", (e) => {
if (e.target && e.target.matches("a.editLink")) {
e.preventDefault();
let id = e.target.getAttribute("id");
editUser(id);
}
});
const editUser = async (id) => {
const data = await fetch(`action.php?edit=1&id=${id}`, {
method: "GET",
});
const response = await data.json();
//Here I am handling value of carStatus (<select>)
if(response.carStatus == "Na cekanju"){
selectElement("carStatus", 'Na cekanju');
}
else if(response.carStatus == "U procesu"){
selectElement("carStatus", 'U procesu');
}
else if(response.carStatus == "Zavrseno"){
selectElement("carStatus", 'Zavrseno');
}
else{
selectElement('carStatus', '');
}
//There are a lot of others element that I handle on the way like this:
document.getElementById("id").value = response.id; //This works
enter code here
//But I didn't want to put all of them because it'd take too much space...
//Here's my function where I am trying to handle value of selected element:
function selectElement(request, valueToSelect) {
let element = document.getElementById(request);
element.value = valueToSelect;
//Also I am getting the correct value -> when I select some row where Zavrseno is placed I really get Zavrseno in console...
console.log(response.carStatus);
}
};
Ohh, by the way there are 4 possible values that can be selected:
"U obradi", "Na cekanju", "U procesu", "Zavrseno"
I actually found out what's the reason why my code didn't work, even though it should've worked perfectly fine, because code itself was written correctly.
The problem was I also had the add modal at the same page with same id which was carStatus (id="carStatus"). Removing it was enough to fix the problem.
Now, the thing is I know that you can't have same id's at the same page, but can somebody explain me why's element which is placed inside Add modal causing problem when I am triggering this action on edit button?
I have the following checkbox in a form:
<input type="checkbox" name="preparationNeeded" >
This is sent to a SpringController via javascript:
.ajax({
type : 'POST',
url : '${home}ui' + action + name + '.html',
data : $('#updateform').serialize(),
success : function(data) {
console.log("SUCCESS: ", data);
document.getElementById('viewmodal').style.display = 'none';
display(data);
},
error : function(e) {
console.log("ERROR: ", e);
displayError(e.responseText);
}
});
The serialization is the following:
When checked:
FORM: id=1& ... preparationNeeded=true ...
When unchecked(checkbox value not included):
FORM: id=1& ...
This is parsed to an object with the boolean field Article.preparationNeded. This works fine in almost all cases but the problem is that preparationNeded has the default value of true.
So, if the checkbox is checked, the value true is sent correctly. But if the checkbox is not checked, the value is not serialized and is taking the default value of the field, instead of false.
Some suggestions:
How to change the value of a check box onClick using JQuery?
you can also consider introducing a hidden input
The problem if I include a Hidden value with value="false" this works fine when the checkbox is not checked. But if this is checked the serialization is the following:
FORM: id=1& ... preparationNeeded=false&preparationNeeded=true ...
This raise an org.springframework.validation.FieldError
Field error in object 'item' on field 'preparationNeeded': rejected value [false,true]; codes [typeMismatch.item.preparationNeeded,typeMismatch.preparationNeeded,typeMismatch.boolean,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [item.preparationNeeded,preparationNeeded]; arguments []; default message [preparationNeeded]]; default message [Failed to convert property value of type [java.lang.String[]] to required type [boolean] for property 'preparationNeeded'; nested exception is java.lang.IllegalArgumentException: Invalid boolean value [false,true]]
Bacause the value is "false,true"
Any suggestion? Thanks!
You can set the default of the checkbox to be false so that when the form is parsed into an object, it will only be true if the checkbox was checked.
If you want it to be checked by default so that the user doesn't have to click it, you can check the box manually via JavaScript when the page loads.
You could change the checkbox to a dummy name, and make preparationNeeded a hidden field, and use JS to set the value of preparationNeeded appropriately on every change to the checkbox state.
One option is to observe clicks on the checkbox and when the checkbox is checked, clear the name on the hidden input. That way the hidden input value will only be added to the serialized output when the checkbox is not checked.
See a demonstration of this below:
$(document).ready(function() {
$('#serialize').click(serializeForm);
$('#preparationNeededCheckbox').click(handleCheckboxClick);
});
function serializeForm() {
console.log('serialized form: ',$('#updateform').serialize());
}
function handleCheckboxClick() {
$('#hiddenCheckboxInput').attr('name', this.checked ? '' : this.name);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<form id="updateform">
Needs Preparation: <input type="checkbox" name="preparationNeeded" value="true" id="preparationNeededCheckbox" />
<input type="hidden" name="preparationNeeded" value="false" id="hiddenCheckboxInput" />
</form>
<button id="serialize">Serialize</button>
But perhaps it might be simpler to have two radio buttons- one for true, one for false...
I have 2 text inputs which are related to each other and I need to validate once user tabs out of both the input text fields. This is a snapshot:
And the HTML counterpart:
<div class="four float_left field_div_wrapper">
<div class="padding_5">
<div class="field_title">
Telephon rumah
</div>
<div class="twelve height_30 land_phone_div">
<input type="text" id="telephon_rumah_field_1" class="three land_phone_field_1 land_phone_field">
<input type="text" id="telephon_rumah_field_2" class="eight land_phone_field_2 land_phone_field">
</div>
<div class="twelve float_left clear_left red_text display_hidden error_div_text">
This field must be numeric with 3 to 4 and 7 to 8 digits
</div>
</div>
</div>
My javascript code for validating the 2 text fields of land phone:
function performLandPhoneValidationOnDiv(landphoneDiv) {
var landPhoneValid = true;
// Here we consider both fields (code of area and office / home phone numbers) for validation if they are non-empty
// If both the fields are empty then it is a valid entry!
var areaCodeField = $(landphoneDiv).find(".land_phone_field_1");
var phoneField = $(landphoneDiv).find(".land_phone_field_2");
// We need to check current focus and perform validations only if both the text fields do not have focus currently
// http://stackoverflow.com/a/2684561/260665
// var phoneFieldsHasFocus = $(areaCodeField).is(":focus") || $(phoneField).is(":focus");
var phoneFieldsHasFocus = $(landphoneDiv).is(":focus");
if (!phoneFieldsHasFocus) {
.
.
.
// Internal validation to check if both the fields (area & phone) has valid data
}
return landPhoneValid;
}
And the code which triggers this validation is blur: (I have also tried focusout)
$(".land_phone_field").blur(function () {
performLandPhoneValidationOnDiv($(this).closest(".land_phone_div"));
});
Problem: As you can see in the first image, as soon as I tab out from first field, validation is triggered even before user attempts to enter something in the second section of the phone field.
To avoid this I have tried the following in the performLandPhoneValidationOnDiv callback after the event is triggered:
var phoneFieldsHasFocus = $(areaCodeField).is(":focus") || $(phoneField).is(":focus");
And:
var phoneFieldsHasFocus = $(landphoneDiv).is(":focus");
Both return false as result. I suspect this is so because the blur / focusout event is triggered as soon as I tab out and even before any other element gains focus. For the same reason I tried to see if the parent contains focus in the interim by any chance, it seems not to be the case.
I can handle this situation by using booleans and set the state when user tabs out of both the fields to perform validation, but it would not be a clean solution and I want to know the best way to handle such situations.
So I have a simple log in that requires a user to input values from a json file into two different text boxes ,when the user name and (in this case I have used ID as password) matches then an alert appears to say... "welcome"
After the .click function is carried out the users text still remains in the text box, how can I get both text boxes to appear blank after the .click function?
$(document).ready(function() {
//Hide alert when page loads
$("#loginalert").hide();
$("#invalid").hide();
$("#loginbtn").click(function(event){
$.getJSON('result.json', function(jd) {
var id = $('#userName').val();
var name = $('#userName2').val();
var valid = false;
for (var i=0; i<jd.user.length; i++) {
if ((jd.user[i].ID == id) && (jd.user[i].name == name)) {
valid=true;
$('#loginalert').html('<img src="' + jd.user[i].imgpath + '"><br><p> Welcome: ' + jd.user[i].name + '</p><button type="button" id="btnhide" class="btn btn-primary btn-md">Hide</button>');
//show the alert after loading the information
$("#loginalert").stop().fadeIn('slow').animate({ opacity: 1.0 }, 3000)
$('#invalid').hide();
$('#btnhide').on('click', function(e){
//console.log('here');
e.preventDefault();
$('#loginalert').hide();
});
}
}
if (!valid) {
$('#invalid').fadeIn('slow');
$('#loginalert').hide();
}
});
}); });
username 1 and #username 2 are the text boxes - is there any way to get user name 2 to display in stars ****** when the user enters the password - this question is not that necessary but if i could also get that working that would be good.
thanks guys hope someone can help :)
is there any way to get user name 2 to display in stars ****** when
the user enters the password
You can use an input box with text property set as password. But that password masking character will be . instead of *. Not exactly sure, whether it will be a different character in some browsers.
<input type="password" id="txtPassword" />
text box to appear blank after .click function
You can set the .val() property of the jQuery objects of two those two textboxes.
$('#userName, #username2').val('');
Use <input type="password"> to show typing as stars.
Clear inputs by setting their value to be empty: $('#userName').val('');
And perhaps consider breaking your code down into a couple smaller functions so it's easier to follow.
document.getElementById("#myTextbox").value="";
This should get your textbox and set the value of it to "", which is blank.
Edit: JSFiddle
Another Method:
You can also add the script directly inside the button without using/creating a function.
<input id="inputId" type="name" />
<button onclick="document.querySelector('#inputId').value='';"> Clear </button>
Using querySelector:
<input id="inputId" type="name" />
<button onclick="click()"> Clear </button>
<script>
function click() {
document.querySelector('#inputId').value="";
}
</script>
I have checkbox list and I want to clear all checked data after Clear button.
The data is fetch from json for checkboxes.
HTML:
<div ng-repeat="data in array" >
<label class="Form-label--tick">
<input type="checkbox" id="statusid" value="{{data.id}}" class="Form-label-checkbox" ng-click="print(data.id)">
<span class="Form-label-text" id="statusname" value="{{data.name}}"> {{data.name}}</span>
</label>
</div>
JavaScript:
$scope.clearFilters = function() {
document.getElementById('statusid').value="";
document.getElementById('statusname').value="";
};
clearFilters() is called when Clear Button is clicked.But I am not able clear the checked boxes.It remains checked even after the clear button.
This code is not angular. Don't try to modify any DOM elements directly, but use the $scope variables to change their value.
In angular the checkbox return true or false so to uncheck a checkbox just change it's value to false.
so your code should look like this:
$scope.clearFilters = function() {
$scope.data.id = false;
$scope.data.name = "";
};