How to bind element only if the function return true;
<label class="hello" data-bind="if: myFunction">Hello World</label>
function myFunction(n){
if(n==2) return true;
}
it is visible also function return false
The if binding applies to the content of the element. If you want the element itself to disappear rather than just the text within it you'll need to wrap the label inside of something else and apply the binding to the wrapper. You can also use the virtual binding for this.
<--ko if: myFunction-->
<label class="hello">Hello World</label>
<!--/ko-->
Additionally, for your function to update properly it will have to be a computed property rather than a normal function, and n needs to be an observable.
var n = ko.observable();
myFunction = ko.computed(function(){
if(n()==2) return true;
});
Related
I have an object with many attributes, one of them is a boolean called "is_mandatory". Whenever an object of this sort is instantiated, "is_mandatory" is initially set to false.
I want to set this attribute to true/false whenever a certain checkbox is clicked.
objectID.is_mandatory = (function() {
$("#checkboxID").change(function() {
if ($("#checkboxID").prop("checked")) {
return true;
} else {
return false;
}
});
})();
I'm new to JavaScript and jQuery. I'm new to front-end development altogether. I've tried many variations of the above code, can't seem to get this work.
use the on change event to update your object.
run snippet below
let myObject = {is_mandatory: false};
$( document ).ready(function() {
render();
$('#container').on('change', '#checkboxID', () => {
myObject.is_mandatory = $('#checkboxID:checked').length ? true : false;
render();
});
});
function render(){
$('#container').empty().append(`<input type="checkbox" id="checkboxID" ${myObject.is_mandatory ? 'checked' : ''}/>`)
console.log(myObject);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="container">
</div>
Have you tried
objectID.is_mandatory = $("#checkboxID").prop("checked");
$(document).on('change','#checkboxID',function(){
var cb = document.getElementById("checkboxID");
myObject.is_mandatory = cb.checked;
});
Basically, "$" is a function that return an jquery object, jquery has several methods in your case "change" method.
"change" method most likely return void since it is actually a shortform of addEventListener("change").
Thus your code need to be modified. instead of returning value. It should access myObject, and set the property manually instead of returning.
or use other method like "prop" which return the value of the DOM Element.
I have this in my HTML. Ignore any inline style, I'm testing,
<label class="toggle" style="float: right;">
<input id="check" type="checkbox" ng-model="check" ng-change="funCheck(check)">
<div class="track">
<div class="handle"></div>
</div>
</label>
<div ng-init="fromClock='01:00'; toClock='03:30';">
<clock-editor from="fromClock" to="toClock"
on-change="fromClock = from; toClock = to; funClock(from, to);">
</clock-editor>
<strong>{{fromClock}}</strong>
<strong>{{toClock}}</strong>
</div>
That's a toggle radio button and a clock.
Then I have these two functions in my controller:
$scope.funCheck = function(check) {
alert(check);
};
$scope.funClock = function(f_from, f_to) {
console.log(f_from + "---" +f_to)
$scope.check = false;
}
};
When the toggle is turned on I send the time from the clock somewhere. This works alright. However, what I want to do is uncheck the toggle if the time was changed.
I can do that with document.getElementById('check').checked = false; and the toggle moves back, but the ng-change on that radio won't fire again until I double check it. Like the value didn't change even if I can see how it's turned off visually.
ng-model does not work on strong element and there is no ng-change event for strong element. So basically you can achieve this by using two watch variables like this, Hope this will help you.
$watch(function(){
return $scope.fromClock;
}, function() {
$scope.funCheck();
})
$watch(function(){
return $scope.toClock;
}, function() {
$scope.funCheck();
})
The whole point of using angular is the fact that you shouldn't have to edit the DOM manually like you're doing.
Change this part of your code which unchecks the checkbox
$scope.funClock = function(f_from, f_to) {
if (document.getElementById('check').checked) {
document.getElementById('check').checked = false;
}
};
to
$scope.funClock = function(f_from, f_to) {
if($scope.check){
$scope.check = false;
}
};
Also, you shouldn't care about checking if it's already checked or not as if you set the checked to false and it's already false there will be no change so just remove the if statement completely.
Edit
Seems like ng-change will only fire if there is a change on the input itself and not if that change has happened programmatically, so there are two ways to do this.
Call the change function inside of the funClock.
This would be the code for that
$scope.funClock = function(f_from, f_to) {
if($scope.check){
$scope.check = false;
funCheck($scope.check);
}
};
Add a watch for check.
Or the code for the watch
$scope.$watch('check', function(newValue, oldValue) {
if (newValue != oldValue) {
funCheck(newValue);
}
});
In angularjs , we cann't directly change elements value. we need to
use $compile . First include it in controller and then make use of
it like wise -
var list = '<input id="check" type="checkbox" ng-model="check" checked ng-change="funCheck(check)">';
var selctr = $("#selector");
var ele = angular.element(list);
compiled = $compile(ele);
selctr.html(ele);
compiled($scope);
My goal is to include Element.ID within function and then, fetch their value or text. It is important to reduce code lines as well because there are many others buttons with the same rule.
So, I tried the below code and many others to get the appropriate results.
How do I fix it?
var el = document.getElementById("p1");
var id = document.getElementById("p1").id;
el.addEventListener("click", modifyText(id), false);
function modifyText(e) {
var x = e.value;
if (x < 40) {
e.value = 1;
}
};
<input id="p1" type="button" class="button" value=0>
<input id="pn" type="button" class="button" value=0>
Well, the second argument to .addEventListener() has to be a function reference, not "loose" code to execute. So, if you want to call another function and pass it an argument, the line should be:
el.addEventListener("click", function(){modifyText(id)}, false);
Now, you are making quite a bit out of the element's id, but you really only need the id to get your initial reference to the element. Once you've got that, you can just work with it.
You've got a lot of unnecessary code here. Also, I'm assuming (perhaps incorrectly) that you want both buttons to have the same click behavior, so that's what I'm proceeding with.
// You only need to get a reference to the element in question
var el1 = document.getElementById("p1");
var el2 = document.getElementById("pn");
// Set up each button to use the same click callback function
// The second argument needs to be a function reference
el1.addEventListener("click", modifyText);
el2.addEventListener("click", modifyText);
function modifyText(){
// When inside of an event handler, "this" refers to the element
// that triggered the event.
if (this.value < 40 ) {
this.value = 1;
}
}
<input id = "p1" type="button" class="button" value=0>
<input id = "pn" type="button" class="button" value=0>
Event listener callbacks tend to be executed with the execution context of the element (unless otherwise modified, or using Arrow functions). This means you can just use this keyword to refer to the element. So inside the callback you could use this.value / this.innerText (depending on type of element)
function modifyText() {
var x = this.value;
if ( x < 40 ) {
this.value = 1;
}
}
Also the way you called addEventListener was wrong.
.addEventListener("click", modifyText(id), false);
This will execute modifyText immediately and use the return value of the function as the callback. And since your function doesnt return anything nothing is set as the callback.
If you wanted to pass a variable to an event callback you would do it like the following
el.addEventListener("click", modifyText.bind(el,yourValue),false);
You would then need to modify the function definition
function modifyText(passedValue,event) {
}
for an example how to execute a javascript function when the binding is visible:true meaning BooleanIndicator() have returned true, assuming that the function called has e as a parameter, whereby e is an event.
<div data-bind="visible: shouldShowMessage">
You will see this message only when "shouldShowMessage" holds a true value.
</div>
<div >
Also show this div when the above div is visble
<div>
Binding is dependent on the data in your view model. If BooleanIndicator() is an observable property of your viewmodel you can create a computed function that should get called whenever the BooleanIndicator() changes
self.ComputedFunction = ko.computed(function() {
if (self.BooleanIndicator()){
//Do something - I'm visible
} else {
// Do something else
}
});
I'm having an issue with an element object and a jQuery function:
HTML
<label for='state'>State</label>
<input id='state' name='state' type='text' value=''/>
<span class='info'><img class='tick' /><img class='cross' /></span>
JavaScript / jQuery
var state = $("#state");
function validatefield(myelement) {
if (myelement.val().length > 3) {
alert("word");
} else {
alert("sup");
}
}
state.blur(validatefield(state));
state.keyup(validatefield(state));
Nothing happens on page load, even when state has more than 3 chars entered.
Any ideas?
Awesome - learning new stuff ftw
No need for arguments at all, the event handler is bound to the element so that you can use the this keyword inside the function:
var state = $("#state");
function validatefield(event) {
if (this.value.length > 3) { // <-- use `this.value` instead
alert("word");
} else {
alert("sup");
}
}
state.blur(validatefield);
state.keyup(validatefield);
The way you're attempting it will actually call the function and use its return value as the event handler, which is why nothing was happening:
// validatefield(state) is executed immediately and the return value, "undefined"
// is passed as the first argument to state.blur()
state.blur(validatefield(state));
To fix other situations like this where the this keyword is not available, you should use an anonymous function:
state.blur(function () { validatefield(state) });
Wrap the function calls in anonymous functions.
$(document).ready(function(){
var state = $("#state");
state.blur(function() {validatefield(state)});
state.keyup(function() {validatefield(state)});
});
http://jsfiddle.net/eW8E8/1/
You should use an anonymous function as jQuery event handler, instead of
state.keyup(validatefield(state));
use
state.keyup(function() {
validatefield(state);
});
Shouldnt it be:
if(myelement.value.length > 3) {
state.keyup(validatefield.call(this, state))
should also work (see http://ejohn.org/apps/learn/#26)