On click function parameters Knockout - javascript

I am trying to pass one parameter to a function by knockout click binding. If i try sending it without binding, it works.
Here is the fiddle of the working code without binding:
https://jsfiddle.net/Obviously/ev0Lcx7q/4/
But if I try binding like this, it does not works:
<input class="sometextbox">
<button type="button" data-bind="click: $root.someFunction.bind($root,$(this).siblings('input').val())"> Search!
</button>
I get the error at $(this), JavaScript runtime error: Object doesn't support property or method 'siblings'

$element gives you access to the current element in a Knockout binding.
<input class="sometextbox">
<button type="button" data-bind="click: $root.someFunction.bind($root, $($element).siblings('input').val())"> Search! </button>
Note that using jquery in a Knockout binding is not a common approach.

Your code isn't really making correct use of knockout. Using it to add click events when (as your fiddle example shows) a regular in-line event definition works fine, but ignoring the ability of knockout to bind that textbox to some variable in your program seems like you're getting things backwards.
Something more like this is how I think knockout was intended to be use:
<script>
ko.applyBindings(model);
function myModel(){
this.myInput = ko.observable('some default value');
}
function myClick(){
alert(model.myInput());
}
</script>
<input class="textbox" data-bind="value: myTextArea">
<button data-bind="click: myClick">Go</button>

Related

Uncaught ReferenceError: var is not defined

I have two textarea which starts on empty value.
Then when I fill the first textarea with id "postcrudo" I want that the next textarea (with id "posthecho") getthe same value as the first, and also show the same. Like a two way binding, like AngularJS, but only with JavaScript and jQuery.
This is the JS:
<script type="text/javascript">
$(document).ready(function(){
$("#submit").click(function(){
$("#postcrudo").val(function(){
algo = this;
});
postHecho = postCrudo;
console.log("OK!");
});
});
</script>
and this the HTML:
<body>
<div style="width:700px;float:left;">
<p>Post crudo:</p>
<p><textarea cols="100" maxlength="99999" name="postCrudo" id="postcrudo" rows="60"></textarea></p>
</div>
<div style="width:700px;float:left;">
<p>Post pasado:</p>
<p><textarea cols="100" maxlength="99999" name="postHecho" id="posthecho" rows="60"></textarea></p>
</div>
<div style="clear:both;"></div>
<p><input type="submit" value="submit" id="submit" /></p>
</body>
The error in Chrome console is:
Uncaught ReferenceError: postCrudo is not defined
Is this what you want?
https://jsfiddle.net/a4nmto6t/1/
Just get the value of the first textarea and change the value of the second to that:
$(document).ready(function(){
$("#submit").click(function(){
var postCrudoVal = $("#postcrudo").val();
$("#posthecho").val(postCrudoVal);
console.log("OK!");
});
});
Neither postHecho nor postCrudo are declared (by you**), and even if they were, assigning one of them to the other does not do what you want. You have to assign the value of the first textarea to the value of the second textarea using (in this case) jQuery selectors, because they ARE the ones referencing the DOM elements (the textareas).
** Elements that have an id are set as global 'variables' by default, but you shouldn't use them; it is instead suggested that you either use the DOM API to find elements or use jQuery (which uses the DOM API behind the scenes).
There is no declaration of postCrudo so it is undefined. Also why would you want to try and do this yourself instead using something like AngularJS to handle data bindings. You are essentially doing more work for no reason. Plus you have to handle all aspects of 2 way data binding manually. To me there is smarter ways to do this.
Your element id postcrudo is all lowercase. postCrudo is indeed not defined
This linepostHecho = postCrudo; makes no sense, I think you're trying to do this:
$('#posthecho').val($('#postcrudo').val())
JavaScript syntax is case sensitive.
`postHecho = postCrudo;`
Should be:
`postHecho = postcrudo;`

What it is the jQuery equivalent function of Javascript DafaultValue()

I want to get the default value of an input textbox when the page was loaded. As I searched around I saw that the DefaultValue() is a method to get a value from a textbox when is loaded . But what is the jQuery one?
<input id=text > </input>
<script>
$(#text).DefaultValue(); // This is wrong I need the Jquery function of this
</script>
Any Idea?
You can read the defaultValue DOM property like this:
$('#text').prop('defaultValue')
Heres a working example
$('#value').click(function(){
alert($('#text').val())
});
$('#def').click(function(){
alert($('#text').prop("defaultValue"))
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<input type="text" id="text" value="This is the default value">
<button id="value">Click to see the current value</button>
<button id="def">Click to see the default value</button>
If you want to call a Javascript DOM function on a jQuery object, you can simple extract the corresponding DOM object with .get(0) or [0]:
$("#text").get(0).defaultValue;
$("#text")[0].defaultValue;
Note also that you were calling the basic JS wrong. First, it's defaultValue, not DefaultValue. Second, it's a property, not a method, so there's no parentheses after it.
Try this,
$(function(){
console.log($('#text')[0].defaultValue);
// or try
console.log($('#text').prop( 'defaultValue' ));
});
Read https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement

ng-click doesn't take parameters from the DOM

I have the following code:
<input id="id">
<button data-action="bea" ng-click="Create($('#id1')[0].value);" class="btn">Insert ID</button>
<button data-action="bea" ng-click="Create($('#id2')[0].value);" class="btn">Insert ID</button>
In the JS I have:
$scope.Create = function (id){
if (id === undefined) {
$scope.data = "You must specify an id";
} else {
$scope.data = data;
console.log(data);
});
}
};
When the call gets into the Create function the value of the id is undefined.
If I add the following line at the beginging of the Create function everything works ok:
id = $('#id')[0].value;
If I send a constant value it works:
<button data-action="bea" ng-click="Create('SomeID');" class="btn">Insert ID</button>
Why is this happening and how can I do that without putting the line of value into the method?
Thanks
This is just an extension of comments and other answers, You could achieve this in many ways using angular, one simple example could be:-
<!-- Add a controller -->
<div ng-controller="MainCtrl">
<!-- Give a model binding to your text input -->
<input ng-model="userEntry" type="text"/>
<!-- ng-click pass which ever argument you need to pass, provided it is an expression that can be evaluated against the scope or any constants -->
<button data-action="bea" ng-click="Create(userEntry);" class="btn">Insert ID</button>
<!-- Some simple data binding using interpolation -->
{{data}}
<!-- Just for demo on repeater on a list of items on the scope -->
<div ng-repeat="item in items track by $index">{{item}}</div>
</div>
Example Demo
My 2 cents on the lines of what were originally trying to do:-
Use angular bindings instead of accessing DOM directly for getting the data, it really helps you deal with just the data without worrying about how to access or render it in DOM. If you think you need to access DOM for implementing business logic re-think on the design, if you really need to do it, do it in a directive. Angular is very opinionated on the design and when where you do DOM access.
ng-model
ng-binding
controller
all about ngmodel controller
This is not the way you should do in AngularJS. You should really think in Angular if you want to use AngularJS. Refer this post ("Thinking in AngularJS" if I have a jQuery background?)
All DOM manipulation should be done in Directive. Refer this page that I found really clear.
(http://ng-learn.org/2014/01/Dom-Manipulations/)
My guess is that $ is not bound to the jQuery function when the ng-click value is evaluated, because it is not exposed in the Angular scope.
Solutions to adress this:
expose the jQuery function in scope somewhere, e.g $scope.$ = $; in a controller.
make the Create function parameterless as you suggested, with a var id = $('#id')[0].value; at the beginning
my favorite : avoid using jQuery. If you put some data in the #id element, there's probably a more natural and AngularJS-idiomatic way of retrieving it than querying the DOM (e.g an Angular service).
In particular, if the element you're targeting is an <input> element, then use the ngModel directive to link the value to a $scopeproperty that will be accessible in the controller :
<input ng-model="inputData"/>
The JavaScript you are trying to pass as a parameter of the create function is not available in the scope of the Create function.
Try to target the element a different way.
Does that help?

Pass Angular JS Data to Button OnClick Event

Is it possible to pass angular js data available on a cshtml page to a button click event?
the angular js object is referenced as item.property. {{item.property}} works well between the html tags.
The function is:
function ShowFileDialog(ProjectID)
{
alert(ProjectID);
}
The cshtml that I would like to do is something like this, but clearly is very wrong.
<button id="button-view" onclick="ShowFileDialog({{item.projectId}})"></button>
I already have a work around - so others are not needed.
In your controller,
$scope.project= {"Id": 1, "name":"project1"};
$scope.ShowFileDialog = function(ProjectID)
{
alert(ProjectID);
}
then in your html,
<button id="button-view" ng-click="ShowFileDialog(project.Id)">show dialog</button>
If you have a list of projects as such,
$scope.projects= [{"Id": 1, "name":"project1"},{"Id": 2, "name":"project2"}];
then in your html use ng-repeat as,
<ul>
<li ng-repeat="proj in projects>
{{proj.name}} <button ng-click="ShowFileDialog(proj.Id)">show dialog</button>
</li>
</ul>
see more here
From my POV these type of mixes shouldn't be done. The closest correct approach should be:
Setting your view with a value in the way angular was meant to be used:
<input type="text" ng-model="myVariable" id="myVar" />
and if you want to you get or use this value get it from the view like:
<script type="text/javascript">
var param1 = document.getElementById("myVal").value;
samplefunction( param1 );
</script>
Online Demo
Note:
In this example I used an input but you could use a data-myVar attribute and get the value from there as well.

AngularJS ng-click fires twice

I am using ng-click and it fires twice when I apply it to SPAN tag.
HTML
<div ng-app="regApp" ng-controller="RegistrationCtrl" data-ng-init="GetEventDetail()" ng-show="data.EventName">
<h2>Registration for {{data.EventName}}</h2>
<span class="btn" id="btnSave" ng-click="PostRegistration()">Save </span>
</div>
CONTROLLER
var app = angular.module('regApp', ['ui']);
app.controller('RegistrationCtrl', function ($scope, $http) {
$scope.PostRegistration = function () {
alert('click '); <--- fires twice
/// some code here --
};
It should only fire once. How I can find why this is happening and how to fix it?
The code you've provided does not fire the event twice:
http://jsfiddle.net/kNL6E/ (click Save)
Perhaps you included Angular twice? If you do that, you'll get two alerts, demonstrated here:
http://jsfiddle.net/kNL6E/1/
I had a similar problem, but could not find where I included Angular twice in my files.
I was using an ajax calls to load specific form layouts, so I need to use $compile to activate Angular on the inserted DOM. However, I was using $compile on my directive $element which has a controller attached. Turns out this "includes" the controller twice, causing two triggers with ng-click or ng-submit.
I fixed this by using $compile directly on the inserted DOM instead of my directive $element.
Same problem using
<a ng-click="fn()"></a>
fn was called twice
Using a button fixed it :
<button ng-click="fn()"></button>
This is probably obscure, but I had ng-click firing twice because I had BrowserSync running, which would mirror my inputs into a tab that I had open in another window, thus doubling up all my clicks. To resolve, I disabled “ghostMode”: https://www.browsersync.io/docs/options/
I solved this by removing my ngsubmit handler as I don't have a need for it. I'm monitoring on change events and using SignalR to update the screen in near real-time.
I was also in a form and the AngularJS docs for ngSubmit states:
Warning: Be careful not to cause "double-submission" by using both the ngClick and ngSubmit handlers together. See the form directive documentation for a detailed discussion of when ngSubmit may be triggered.
In case of somebody having the same issue:
This was my problem:
<a type="submit" ng-click="login()">submit login<a>
Both, the type="submit" and the ng-click="login()"triggered the login()-method in my controller.
So just use either the type=submit or the ng-click directive
If other answers don't help, make sure that AngularJS profiling is disabled in Batarang (if you have it installed of course).
This was making ng-click to fire twice for me.
elements wrapped one another, and this can cause trigger event twice or more.
So i used a simple CSS trick for this solution :
.off{
pointer-events:none;
}
and apply it to an element correspond to click event.
You might have a ng-click inside a form container using a ng-submit. In that case, add type="button" to all your using ng-click.
I got it when I accidently called $compile for the dynamically added elements several times in the cycle, instead of just once. Compiling just once removed this effect.
was facing same issue.
Find out they were using https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js version and i switch it to latest 1.4.5 version and it just worked.
https://ajax.googleapis.com/ajax/libs/angularjs/1.4.5/angular.min.js
var app = angular.module('regApp', []);
app.controller('RegistrationCtrl', ['$scope','$http',function($scope,$http ) {
$scope.PostRegistration = function() {
alert('click '); // <--- fires twice
/// some code here --
};
}]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="regApp" ng-controller="RegistrationCtrl">
<h2 >Registration for {{data.EventName}}</h2>
<span ng-click="PostRegistration()" class="btn" id="btnSave">Save </span>
</div>
I have changed <button ng-click='clickHandler()'> to <a ng-click='clickHandler()'> and now event fires only once
I've had the same issue when dynamically injecting partial views in my SPA(Single Page Applications).The way I solved it was to store the content of my div in a local variable like this:
var html = $("#leftContainer").html();
Then empty out the div and reset its content like this:
$("#leftContainer").empty();
$("#leftContainer").append(html);
Now you can add any additional html you have received from an AJAX call or dynamically constructed and lastly remember to re-compile your HTML to make it bound to angular:
var entities = $("#entitiesContainer");
var entity = "<div><a href='#' ng-click='Left(" + entityId + ")'> " + entityName + "</a><div>"
entities.append(entity);
var leftContainer = angular.element(document.getElementById("entitiesContainer"));
$compile(leftContainer)($scope);
I'm a bit of a dummy and had this:
<li data-shape="amethyst" ng-click="toggleGem('amethyst')">
<label></label>
<i class="amethyst"></i>Amethyst
<input type="checkbox" name="gem_type" id="gem-amethyst" value="amethyst" />
</li>
The click event was triggering twice. I moved the ng-click to the label element and it's working as expected.
<li data-shape="amethyst">
<label ng-click="toggleGem('amethyst')"></label>
<i class="amethyst"></i>Amethyst
<input type="checkbox" name="gem_type" id="gem-amethyst" value="amethyst" />
</li>
This situation may be caused by lacking the ngTouch in Angular.
Event if the ngTouch is loaded, the bug in ngTouch and ngClick before Angular 1.5.0 may occur. It results from the ngClick being triggered by pointerup and mouseUp in Chrome for Desktop on device toolbar or mobile device.
I had a problem like this as well.
<button style="width: 100%;" class="btn btn-danger" ng-click="'{{vm.delete()}}'">
Thats not how you call ng-click, but no errors were thrown and the function calls still worked.
<button style="width: 100%;" class="btn btn-danger" ng-click="vm.delete()">
Is correct and will then only be called once.
I don't know what was the reason this happened, but I had to use event.stopPropagation(); inner my JavaScript function.
HTML
<button class="button" ng-click="save($event)">Save</button>
JAVASCRIPT
function save(event) {
event.stopPropagation();
}
I have handled it by following code
HTML :
<div>
<ui>
<li>
<button class="Button" ng-disabled="self.desableSubmitButton" ng-
click="self.SubmitClick($event)">Submit</button>
</li>
</ui>
</div>
Angular 1.0 Controller :
_self.SubmitClick = function(event){
_self.desableSubmitButton = true; //disable submit button
event.preventDefault();
event.stopPropagation();
setTimeout(funtion() {
_self.desableSubmitButton = false; //enable submit button after timeout
if(_self.$scope.$$phase != '$apply' || _self.$scope.$$phase != '$digest'){
_self.$scope.$digest();
}
}, 1000);//other Code logic
}
My case: I used ng-click event on my custom custom angular checkbox component. So just providing a method binding for custom component did the trick.
Before:
<mono-checkbox-ng ng-click="vm.onSelectAllClicked()">
After:
<mono-checkbox-ng on-changed="vm.onSelectAllClicked()">

Categories

Resources