I have a input type of button. Button is something like this:
<h2>RFI Status Type</h2>
<input type="button" class="btn btn-small btn-primary" value="New RFI Status" data-bind="click: $root.createRFIStatusType" />
<hr />
<table class="search">
<tr class="table_title">
<th>RFI Status Type Name</th>
<th>Sequence</th>
<th>Active Status</th>
</tr>
<tbody data-bind="foreach: RFIStatusTypes">
<tr class="table_data">
<td><a data-bind="text: RFIStatusTypeName, click: $parent.editRFIStatusType">Edit</a></td>
<td data-bind="text: Sequence"></td>
<td>
<input type="button" id="chkActiveStatus" data-bind = "value: activeStatus(ActiveStatus) "/>
</td>
</tr>
</tbody>
</table>
The JavaScript function activeStatus(ActiveStatus) is:
<script>
function activeStatus(ActiveStatus)
{
if (ActiveStatus == 0) {
return "Deactivate";
}
else {
return "Activate";
}
}
</script>
What it is doing is that, it is taking the value of ActiveStatus, which is a column in my database table. The value of ActiveStatus is either 1 or 0. When it takes the value 0, it returns the value of the button as "Deactivate", otherwise "Activate".
When I click the button, I want to change the button value from "Activate" to "Deactivate" and vice versa, and at the same time, the corresponding ActiveStatus value will also change. If ActiveStatus is 0, it will change to 1; if it is 1 then it will change to 0.
How can I do this? I have tried this multiple times and failed. I tried an onclick event in my input but it didn't work.
EDIT-1: I've written the JavaScript code inside my view page and have modified it a bit but still not getting the desired result. Here it goes:
<script>
function activeStatus(ActiveStatus)
{
if (ActiveStatus == 0) {
ActiveStatus++;
return "Deactivate";
}
else if (ActiveStatus == 1)
{
ActiveStatus--;
return "Activate";
}
}
</script>
EDIT-2: Many have been mentioning that I haven't included knockout.js code here. So here is the RFIStatusType.js code:
var RFIStatusTypesViewModel = function () {
var self = this;
var url = "/RFIStatusType/GetAllRFIStatusType";
var refresh = function () {
$.getJSON(url, {}, function (data) {
self.RFIStatusTypes(data);
});
};
// Public data properties
self.RFIStatusTypes = ko.observableArray([]);
// Public operations
self.createRFIStatusType = function () {
window.location.href = '/RFIStatusType/RFIStatusTypeCreateEdit/0';
};
self.editRFIStatusType = function (RFIStatusType) {
window.location.href = '/RFIStatusType/RFIStatusTypeCreateEdit/' + RFIStatusType.RFIStatusTypeID;
};
self.removeRFIStatusType = function (RFIStatusType) {
// First remove from the server, then from the UI
if (confirm("Are you sure you want to delete this RFI Status?")) {
var id = RFIStatusType.RFIStatusTypeID;
$.ajax({ type: "DELETE", url: 'RFIStatusType/DeleteRFIStatusType/' + id })
.done(function () { self.RFIStatusTypes.remove(RFIStatusType); });
}
}
refresh();
};
ko.applyBindings(new RFIStatusTypesViewModel());
EDIT-3: Now my button is this:
<input type="button" id="chkActiveStatus" data-bind="value: activeStatus(ActiveStatus), click: toggleActiveStatus(ActiveStatus)" />
And my JavaScript is re-written here:
<script>
function activeStatus(ActiveStatus)
{
if (ActiveStatus == 0)
{
alert("ActiveStatus is now 0");
return "Activate";
}
else if (ActiveStatus == 1)
{
alert("ActiveStatus is now 1");
return "Deactivate";
}
}
function toggleActiveStatus(ActiveStatus)
{
if (ActiveStatus == 0)
{
ActiveStatus++;
alert("ActiveStatus is now 1");
return ActiveStatus;
}
else if (ActiveStatus == 1)
{
ActiveStatus--;
alert("ActiveStatus is now 0");
return ActiveStatus;
}
else alert("Error");
}
</script>
But still no luck.
As Govan seems the most correct, you cannot just grab a global function within the data-bind concept of knockout. 'value' will only set the value of the button...which isn't really relevant. data-bind='click: activeStatus' is how you want to handle your click event...but the function activeStatus() needs to be declared where you declare the object type defining each instance of RFIStatusTypes.
Provide more of your knockout code and this example may magically show more information as well.
Personally, I smell a good example of a custom bindingHandler coming on.
Related
I have a simple form written in AngularJS.
I would like to make the form invalid immediately after loading. Unfortunately $scope.myForm.$valid = false; doesn't want work. Do you have any other technique to do it? It is important for me as I want to let user click the button only when he/she choose at least on checkbox. Now you can submit the form always after loading the form.
<form name="myForm" ng-submit="myForm.$valid">
<input type="checkbox" ng-model="obj.first" ng-change="onChange()" /> First <br />
<input type="checkbox" ng-model="obj.second" ng-change="onChange()"/>Second <br />
<input type="checkbox" ng-model="obj.third" ng-change="onChange()"/> Third <br>
<button type="submit" ng-disabled="!myForm.$valid" ng-click="click()">test</button> <br>
</form>
$scope.myForm = {};
$scope.myForm.$valid = false;
$scope.click=function () {
console.log('-------------2', $scope.myForm);
};
$scope.onChange=function () {
console.log('before:', $scope.myForm);
var isValid = false;
angular.forEach($scope.obj, function(value, key) {
if(value == true){
isValid=true;
}
console.log(key + ': ' + value);
});
if(!isValid){
$scope.myForm.$valid = false;
$scope.myForm.$error.checkBoxes = {
isChecked: false
};
}
console.log('after:', $scope.myForm);
}
So this is my final solution, the form in the scope has a function called $setValidity() where we can change the validity state, and notify the form. Refer here, so I check if any of the checkboxes are having true value, then I set the value for one checkbox alone as true, if not then one of the checkboxes with name one is set to $valid = false, thus the entire form will be invalid, please go through my code for the implementation of the solution!
JSFiddle Demo
JS:
var app = angular.module('myApp', []);
app.controller('MyController', function MyController($scope) {
$scope.onChange = function() {
if ($scope.obj) {
if ($scope.obj.first || $scope.obj.second || $scope.obj.third) {
$scope.myForm.one.$setValidity("Atleast one checkbox needs to be selected", true);
} else {
$scope.myForm.one.$setValidity("Atleast one checkbox needs to be selected", false);
}
} else {
$scope.myForm.one.$setValidity("Atleast one checkbox needs to be selected", false);
}
}
});
Try this in your submit button. hope it works
data-ng-disabled="myForm.$submitted || myForm.$invalid && !myForm.$pristine"
I've got a while loop with multiple buttons, they are like this:
<button onclick="confirmDelete()" value="<?php echo $game['id'];?>" name="deleteButton">Delete </button>
It is followed by the following confirm message:
<script>
function confirmDelete() {
var r = confirm(" **HERE I WANT THE ID TO START WITH** ");
if (r == true) {
// delete
} else {
// cancel
}
}
</script>
Each button has his own value, but now i want that value in my javascript when i click on that button. I tried multiple things but cant make it work.
EDIT:
If someone can tell me an better/easier way to do this, you're welcome to tell me
Use your function with this argument, i.e.:
<button onclick="confirmDelete(this)" id="myButton" value="someId" name="deleteButton">Delete </button>
<script>
function confirmDelete(elem) {
var r = confirm(" **HERE I WANT THE ID TO START WITH** ");
var theValue = elem.value; //someId
var theId = elem.id; //myButton
if (theValue == "True") {
alert("True")
} else {
alert("False")
}
}
</script>
LIVE DEMO:
http://codepen.io/anon/pen/QyZgqO
Pass the game ID into the confirmDelete function as a parameter
<button onclick="confirmDelete(<?php echo $game['id'];?>)" name="deleteButton">Delete </button>
<script>
function confirmDelete(id) {
var r = confirm(id);
if (r == true) {
// delete
} else {
// cancel
}
}
</script>
I am new to angular and I am trying ui-grid. In my code, when I am clicking the filter button, I am not getting data and I am not getting any error either. Can anyone please hep me?? This is my code:
HTML code:
<input type="button" value="Filter"
ng-model="filterValue" class="btn btn-primary"
ng-click="applySearchFilter()" />
JavaScript code:
$scope.applySearchFilter = function () {
assignService.getResult($scope.RequestPrefix, $scope.RequestYear, $scope.RequestNumber, $scope.AssignedToStaff).then(function (assignResult) {
$scope.assign = assignResult.data;
if ($scope.AssignedToStaff == "-1") {
$scope.assign = $.grep($scope.assign, function (element, index) {
return element.AssignStaffId == 0;
});
}
});
};
$scope.applySearchFilter = function () {
alert("entering"); // init();
assignService.getResult($scope.RequestPrefix, $scope.RequestYear, $scope.RequestNumber, $scope.AssignedToStaff).then(function (assignResult) {
$scope.assign = assignResult.data;
alert("Result");
if ($scope.AssignedToStaff == "-1") {
alert("if condition");
$scope.assign = $.grep($scope.assign, function (element, index) {
alert("staff Data:::" + $scope.assign);
return element.AssignStaffId == 0;
});
}
});
};
<div class="col-md-2">
<input type="button" value="Filter" ng-model="filterValue" class="btn btn-primary"
ng-click="applySearchFilter()" />
</div>
First make sure assignService.getResult promise really resolved, try to add a reject callback, to check whether the promise is resolved or not.
If the promise is resolved and you get the data from remote method, then you should check if ui-grid has updated its data in successful callback, I suppose you use $scope.assign = assignResult.data; to update ui-grid data, it looks no problem, but make sure in your ui-grid options, the data property should assigned a scope object name string, not a scope object:
$scope.uiGridOption = {
data: 'assign',
...other options...
}
$scope.$scope.applySearchFilter = function () {
assignService.getResult($scope.RequestPrefix, $scope.RequestYear, $scope.RequestNumber, $scope.AssignedToStaff).then(function (assignResult) {
$scope.assign = assignResult.data;
alert("Result");
if ($scope.AssignedToStaff == "-1") {
alert("if condition");
$scope.assign = $.grep($scope.assign, function (element, index) {
alert("staff Data:::" + $scope.assign);
return element.AssignStaffId == 0;
});
}
});
};
I am having tough time in understanding why my element shows ng-dirty after updating the model.
I have a collection of bridges which need to be rendered on UI. On each tab click, I am changing the index and rendering the data.
If my first tab data has changed and moved to second tab why are input elements still dirty on second tab. (Function - $scope.changeIndex)
After executing calculate, the model gets updated but still the input elements are still dirty
UI
<td style="padding:10px;text-align:center">
<label>Length:</label>
<input type="text" class="currencyLabel-editable" ng-model="bridgeModel.bridges[currentIndex].length" />
</td>
<td style="padding:10px;text-align:center">
<label>Width:</label>
<input type="text" class="currencyLabel-editable" ng-model="bridgeModel.bridges[currentIndex].width" />
</td>
<td style="padding:10px;text-align:center">
<label> Skew:</label>
<input type="text" class="currencyLabel-editable" ng-model="bridgeModel.bridges[currentIndex].skew" />
</td>
Controller
(function () {
var bridgeCtrl = function ($scope, $bootstrapBridgeData, $crudService,$log) {
$scope.bridgeModel = $bootstrapBridgeData.bridgeModel;
var onCalculateComplete = function (data) {
$scope.bridgeModel.bridges[$scope.currentIndex] = angular.copy(angular.fromJson(data));
}
var onCalculateError = function (reason){
$scope.error = "Unable to perform calculation";
$log.error(reason);
}
var onError = function (reason) {
$scope.error = "Unable to fetch data";
}
//function to null the values which needs to be re-computed
var removeCalculatedValues = function () {
$scope.bridgeModel.bridges[$scope.currentIndex].foundation_PreBoringCalculated = null;
$scope.bridgeModel.bridges[$scope.currentIndex].foundation_DrilledShaftsCalculated = null;
}
//function to compute the bridge values
$scope.calculate = function (url) {
if (!preValidation()) {
return false;
}
removeCalculatedValues();
$crudService.postAndGetData(url, $scope.bridgeModel.bridges[$scope.currentIndex])
.then(onCalculateComplete, onCalculateError)
}
//function to select the bridge and change the index of the bridge
$scope.changeIndex = function (bridgeName,index) {
$scope.selectedBridge = bridgeName;
$scope.currentIndex = index;
}
$scope.save = function (index, url) {
$scope.currentIndex = index;
crudService.postAndGetData(url, $scope.bridges[index])
.then(onUserComplete, onError);
}
//$scope.enableSave = function isFormDirty() {
// if ($(".ng-dirty").length) {
// return false;
// }
// else { return true; }
//}
//Behaviour Changes
//function which changes the css
$scope.isBridgeSelected = function (bridge) {
return $scope.selectedBridge === bridge;
}
var preValidation = function () {
if ($(".ng-invalid").length) {
alert("Please correct the errors.")
return false;
}
else { return true;}
}
}
//Get the module and add a controller to it
var module = angular.module("bridgeModule");
module.controller("bridgeCtrl", bridgeCtrl);
}());
From the documentation
ng-dirty is set if the form is dirty.
This is a check for whether the form itself has been interacted with in any way. It doesn't care what the underlying object binding is. So this is the expected behavior, since you are using the same form but changing the ng-model behind the scenes.
Dunno if this is the problem or not, but the line $scope.$setPristine; is not doing anything. It should be: $scope.$setPristine();
Basically I have a script the function "hola ()" that should return the value of 1 if the radio button value is 1. But for some reason when I try to get the return value in another function i never get it.
The form works perfectly.. the only issue is that it doesnt return the value
Can anyone tell me what i did wrong?? thanks
$(document).ready(function(){
function hola() {
$("form[name=yN]").show("slow");
$('input[type=radio]').click( function (){
var opt = $(this).attr("value");
if (opt == "1") {
this.checked = false;
$("form[name=yN]").hide("slow");
return 1;
}
if (opt == 0) {
$("p").html ("ok");
this.checked = false;
}
})
}
$("#iForm").submit( function(event){
event.preventDefault();
var user = $("input[name=username]").val();
var password = $("input[name=password]").val();
var dbName = $("input[name=dbName]").val();
var server = $("input[name=server]").val();
$.get("1.php",
{username: user, password: password, dbName: dbName, server: server },
function(data){
if (data == "The table PAGE exists" || data == "The table SUBJECTS exists" || data == "The table USERS exists" ) {
// CALLING THE hola () function and expecting a return
var opt = hola();
$("p").html(data + opt);
}
}
)
})
})
HTML
<!-- Yes or No form -->
<form name="yN" style= "display: none; margin-left: auto; margin-right: auto; width: 6em">
<input type="radio" name="yN" value="1">yes</input>
<input type="radio" name="yN" value="0">no</input>
<button id=1 >click me!</button>
</form>
<!-- Login Form -->
<form id="iForm" style= "display: show">
<label id="username" >Username</label>
<input id="username" name="username"/>
<label id="password">Password</label>
<input id="password" name="password" />
<label id="server" >Server</label>
<input id="server" name="server"/>
<label id="dbName" >dbName</label>
<input id="dbName" name="dbName"/>
<input type="submit" value="submit" />
</form>
<p> </p>
Event handlers cannot return values because they're called asynchronously*.
Your existing hola() function will return immediately and the return statements in the click handlers are only called much later, i.e. when the button is clicked.
My approach would be this, using jQuery deferred objects (jQuery 1.6+):
function hola() {
var def = $.Deferred();
// show the popup confirm form
...
$('input[type=radio]').click(function() {
// determine return value
...
// send it back to anything waiting for it
def.resolve(retval);
});
// return a _promise_ to send back a value some time later
return def.promise();
}
$.get("1.php", { ... }).done(function(data) {
if (...) {
hola().done(function(opt)) { // will be called when the promise is resolved
$("p").html(data + opt);
});
}
});
If you prefer, instead of returning the opt value you could use def.reject() to indicate "non-acceptance" and then use a .fail handler to register a handler to be called for that condition.
You return 1 only in the click function of the radiobutton.
If you want to have a function "hola" that returns 1 if the radiobutton is checked, you simply need something like this:
function hola() {
return $("input:radio[name='yN']:checked").val();
}
hola does not even have a return statement. That's the reason for its not returning anything (more precisely: returning undefined always).
A JavaScript function that does not contain a return statement at all or whose all return statements are within nested functions will never return anything but undefined.
Your are tring to return the value from withing the click callback function. Move the return outside that:
function hola() {
var result;
$("form[name=yN]").show("slow");
$('input[type=radio]').click( function (){
var opt = $(this).attr("value");
if (opt == "1") {
this.checked = false;
$("form[name=yN]").hide("slow");
result = 1;
}
if (opt == 0) {
$("p").html ("ok");
this.checked = false;
}
});
return result;
}