enable binding doesn't work - html

<div class="col-lg-6 col-md-6 col-sm-12 col-xs-12">
<button class="btn btn-danger pull-right btn-block" data-bind="enable: DeletedEnable">Delete</button>
</div>
Even when the DeletedEnable is false, the enable property doesn't work, and the button is still enabled.
self.CurrentStatusIsDraft= ko.pureComputed(function () {
return false;
});
self.DeletedEnable = ko.pureComputed(function () {
return self.CurrentStatusIsDraft() ;
});

Based on your example https://jsfiddle.net/3rnt2zsc/ :
A) it's not a good practice using inline onClick.
Since you are using knockout simply use click event binding.
B) Try to put less javascript logic in your view.
C) Apply binding by using new instance of your model.
Example: https://jsfiddle.net/of8qfdvL/1/
View:
<div class="col-lg-12 col-md-12 col-sm-12 col-xs-12">
<div class="col-lg-offset-6 col-md-offset-6 col-lg-6 col-md-6 col-sm-12 col-xs-12">
<div class="col-lg-6 col-md-6 col-sm-12 col-xs-12">
<button class="btn btn-default btn-gb-default btn-block pull-right" data-bind="enable: ContinuedEnabled, click:OnContinue">Continue</button>
</div>
<button class="btn btn-danger pull-right btn-block" data-bind="enable: DeletedEnabled(), click:OnDelete">Delete</button>
<pre data-bind="text: ko.toJSON(DeletedEnabled, null, 2)"></pre>
</div>
</div>
Model:
var viewModel = function() {
var self = this;
self.SubmissionId = ko.observable(1234);
self.LastPageId = ko.observable(2);
self.ContinuedEnabled = ko.observable(true); // you can set the value based on your logic
self.OnContinue = function(){
console.log("SubmissionId:",self.SubmissionId());
console.log("LastPageId:",self.LastPageId());
}
self.OnDelete = function(){
console.log("SubmissionId:",self.SubmissionId());
}
self.CurrentStatusIsDraft= ko.pureComputed(function () {
return false;
});
self.DeletedEnabled = ko.pureComputed(function () {
return self.CurrentStatusIsDraft() ;
});
}
ko.applyBindings(new viewModel()); // apply a new instance of your model

Related

Getting data from Json returned by controller action

I have a modal that I am trying to populate via sending a modal through a JSON obj from a controller action. It seems to be returning the model just fine, however I am having a hard time extracting the data from the model to populate HTML.. Below is my code.
If anyone can help correct my syntax in the JS, it would be greatly appreciated.
Controller action:
[HttpGet]
public ActionResult JobPollerParameters(int jobRequestId)
{
var model = new Dashboard.Web.Models.Tools.JobPollerMonitorResponseModel();
try
{
using (var client = new DashboardAPIClient())
{
var response = client.GetJobRequestParemeters(jobRequestId);
model.JobRequestParameters = response.JobRequestParameters;
}
}
catch (Exception ex)
{
ExceptionHandling.LogException(ex);
throw;
}
return Json( model.JobRequestParameters, JsonRequestBehavior.AllowGet);
}
Modal which JSON data needs to be displayed on:
<div class="modal fade" id="paramsModal" tabindex="-1" role="dialog">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header modal-header-primary">
<a class="btn btn-xs btn-primary pull-right" data-dismiss="modal" aria-label="Close"><span class="glyphicon glyphicon-remove"></span></a>
<h4 class="modal-title" id="modalTitleText"></h4>
</div>
<div class="modal-body">
<div class="row">
<div class="col-md-3 font-weight-bold">Name:</div>
<div class="col-md-9" id="modalName"></div>
</div>
<div class="row">
<div class="col-md-3 font-weight-bold">Message:</div>
<div class="col-md-9 text-break" id="modalMessage"></div>
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-primary" data-dismiss="modal">Close</button>
</div>
</div>
</div>
JS function:
$('#paramModalBtn').click(function () {
var col = $('#requestId');
var jobRequestId = col.data("id");
//console.log(jobRequestId);
$.ajax({
url: '#Url.Action("JobPollerParameters", "Tools")',
data: { "jobRequestId": jobRequestId},
success: function(results){
$modal = $('#paramsModal');
$modal.modal("show");
var name = JSON.parse(results.name);
var message = JSON.parse(results.message)
$('#modalName').text(name);
$('#modalMessage').text(message);
}
});
});
Also for some context, I would like to show that the Model I am returning should be a list of "JobRequestParameters", of which I need Model.JobRequestParameters.Name, and JobRequestParameters.value.
If I log results in the console, I can see what I need is actually there.
JobParameterId: 118190
JobRequestId: 118190
Name: "CUSTOMERTYPE"
Value: "Notary Pre-Assessment"
Name and Value are what I need.
The controller returns a string formatted as JSON, which can then be parsed into a JavaScript object and used as such.
You need to parse the data once and then you'll have an object you can use.
var obj = JSON.parse(results);
$('#modalName').text(obj.name);
$('#modalMessage').text(obj.message);
Here is the solution for deserializing the JSON object
$("button").click(function () {
var col = $('#requestId');
var jobRequestId = col.data("id");
$.ajax({
url: '#Url.Action("JobPollerParameters", "Tools")',
data: { "jobRequestId": jobRequestId},
success: function(results){
$modal = $('#paramsModal');
$modal.modal("show");
console.log(results);
var name = JSON.stringify(results[0].Name);
var value = JSON.stringify(results[0].Value);
$('#modalName').text(name);
$('#modalMessage').text(value);
}
});
});

Dynamic Form issue with Reactive Form

I want to create a Dynamic input field on button press and successfully I am able to create new input field on button press with the help of reactive form but now I want to set predefined value in input field as per API data. Like if from API if I am getting 6 names, I want to create that 6 input fields on Init and then I want to able to new input field on button press. Here is my code which I tried, I am able to create new input field but not able create input fields as per API data on Init.
Component.ts
export class ScreenmodalComponent implements OnInit {
#Input() screendetails;
personalForm : FormGroup;
arrayItems: any = [];
screenList: string;
constructor(private activeModal: NgbActiveModal, private formbuilder: FormBuilder, private pagesService: PagesService, private utilService: UtilService) { }
ngOnInit() {
this.personalForm = this.formbuilder.group({
other: this.formbuilder.array([ this.addanotherForm()])
});
// Api call
this.pagesService.GetScreens('').then(res => {
console.log('get screens api', res);
for (let i = 0; i < res['data']['length']; i++) {
this.arrayItems = res['data'][i]['name'] //names which I want to set as input field value and generate input fields for every name
}
}).catch(error => {
this.utilService.showError('Something went wrong', 'Error');
console.log('err is', error);
});
}
addanother():void {
(<FormArray>this.personalForm.get('other')).push(this.addanotherForm());
}
addanotherForm(): FormGroup{
return this.formbuilder.group({
screenname: [''],
});
}
clear(i : number){
(<FormArray>this.personalForm.get('other')).removeAt(i);
}
onSubmit(): void {
console.log(this.personalForm.value);
}
closeModel() {
this.activeModal.close();
}
}
Componenent.html code
<div class="custom_modal pb-3">
<div class="modal-header border-0 p-1 pl-3 pr-3 d-flex justify-content-between align-items-center">
<h3 class="m-0">Project: {{screendetails.name}}</h3>
<button type="button" class="close" data-dismiss="modal" (click)="closeModel()">×</button>
</div>
<div class="modal-body p-3">
<div class="body_top d-flex justify-content-between mb-4 mt-2 align-items-center">
<h3 class="title m-0">Add Screens</h3>
</div>
<form [formGroup]="personalForm" (ngSubmit)="onSubmit()">
<div formArrayName="other" class="form-group" *ngFor="let other of personalForm.get('other').controls; let i = index" >
<div [formGroupName] = "i">
<div class="screen_row mb-4">
<div class="row">
<div class="col-md-3 col-sm-3 d-flex align-items-center">
<label>Screen Name</label>
</div>
<div class="col-md-8 col-sm-8 pl-0 pl-sm-3">
<input type="text" class="form-control rounded-0" formControlName="screenname" name="screenname">
</div>
<div class="col-md-1 col-sm-1 d-flex align-items-center justify-content-center pl-0 pl-sm-3">
<button type="button" class="close" (click)="clear(i)">×</button>
</div>
</div>
</div>
</div>
</div>
<div class="modal-footer border-0 d-table w-100">
<button type="button" class="btn-primary float-left" (click)="addanother()">Add New Screen</button>
<div class="float-right">
<button type="button" class="btn-primary mr-3" data-dismiss="modal" (click)="onSubmit();">Apply</button>
<button type="button" class="btn-primary cancle" data-dismiss="modal" (click)="closeModel()">Cancel</button>
</div>
</div>
</form>
</div>
</div>
This is my code. Please help me setting up by default input fields as per the number of names in API call.Thannk you
Normally, you change your function addAnotherForm to allow pass data
addanotherForm(data:any): FormGroup{
return this.formbuilder.group({
screenname: [data],
});
}
In your case you must change the function addanother
addanother(data:any):void {
(<FormArray>this.personalForm.get('other')).push(this.addanotherForm(data));
}
So, your ngOnInit can be like.
//at first an Empty FormArray
this.personalForm = this.formbuilder.group({
other: this.formbuilder.array([])
});
// Api call
this.pagesService.GetScreens('').then(res => {
console.log('get screens api', res);
for (let i = 0; i < res['data']['length']; i++) {
this.arrayItems = res['data'][i]['name']
this.addanother(res['data'][i]['name'] //fill the array
}
}).catch(error => {
this.utilService.showError('Something went wrong', 'Error');
console.log('err is', error);
});
Well, really you can simply all the code -and really you needn't this.arrayItems- and we use a map
this.pagesService.GetScreens('').then(res => {
this.personalForm=new FormGroup({
other:new FormArray(
res['data'].map(d>=>{
return new FormGroup({
screenname:new FormControl(d.name))
})
})
)
})
}).catch(error => {
this.utilService.showError('Something went wrong', 'Error');
console.log('err is', error);
});
NOTE: You needn't make a ForGroup if you only want yo control a FormArray, and your formArray can be only a formArray of formControls not a FormArray of FormGroup

Angular how to post data with a button using (change) detector?

I am trying to post data to my REST server. When I use a (change) it sends the data to my rest server. When I try to activate the method on my button it doesnt even try to make a POST call. How can I solve this problem? I can't find anything about it.
HTML file:
<div class="container py-5">
<div class="row">
<div class="col-md-12">
<div class="row">
<div class="col-md-6 mx-auto">
<div class="card rounded-0">
<div class="card-header">
<h3 class="mb-0">Organize</h3>
</div>
<div class="form-group">
<label for="codes" class="m-2">Choose a restaurant:</label>
<form #f="ngForm">
<input
type="text"
list="codes"
class="m-2"
(change)="saveCode($event)">
<datalist id="codes">
<option *ngFor="let c of codeList" [value]="c.name">{{c.name}}</option>
</datalist>
</form>
<button
type="submit"
class="btn btn-primary btn-lg float-none m-2"
id="btnAanmaken"
routerLink="/menu"
(change)="saveCode($event)"
>Aanmaken</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
Typescript file:
// Method to post data to backend
public saveCode(e): void {
const name = e.target.value;
const list = this.codeList.filter(x => x.name === name)[0];
this.restaurant.name = list.name;
this.restaurant.address = list.address;
console.log(list.name);
console.log(list.address);
// Additional information to the server content type
const httpOptions = {
headers: new HttpHeaders({
'Content-Type': 'application/json'
})
};
// Making an array with the values of the restaurant
const data = {
name: list.name,
address: list.address
};
console.log(data);
// POST method
this.http.post('http://localhost:8080/aquadine-jee/resources/restaurant',
JSON.parse(JSON.stringify(data)) , httpOptions)
// wait till it gets posted to the backend
.subscribe( // subscribe to observable http.post
res => {
console.log("response" + " " + res); // log results otherwise log error
},
err => {
console.log('Error occured');
}
);
}
I tried to call the method by:
<button
type="submit"
class="btn btn-primary btn-lg float-none m-2"
id="btnAanmaken"
routerLink="/menu"
(change)="saveCode($event)"
>Aanmaken</button>
and:
<button
type="submit"
class="btn btn-primary btn-lg float-none m-2"
id="btnAanmaken"
routerLink="/menu"
(click)="saveCode($event)"
>Aanmaken</button>
In addition to the answer by #Moslem, change the button type from submit to button
<button type="button" .. > instead of <button type="submit" ...>
Conflict using routerLink routerLink="/menu" and click event.
change routing when back response.
Inject router: Router class and use this.router.navigateByUrl(url: string)
Router
constructor(private router: Router){
}
public saveCode(e): void{
// POST method
this.http.post('http://localhost:8080/aquadine-jee/resources/restaurant',
JSON.parse(JSON.stringify(data)) , httpOptions)
// wait till it gets posted to the backend
.subscribe( // subscribe to observable http.post
res => {
console.log("response" + " " + res); // log results otherwise log error
this.router.navigateByUrl("/menu")
},
err => {
console.log('Error occured');
}
);
}

Error: Reference.push failed: first argument contains a function in property - firebase

I'm trying to push the values into my firebase-database. When I try pushing the values it gives me an error in the console (Error: Reference.push failed: first argument contains a function in property). I looked it up on firebase and found out it was because of a function being pushed, but i'm not pushing any function at all. But I have a feeling that it might be because of datetimepicker. Need help!
MY JS
/*global angular*/
var app = angular.module('downtime', ['ngRoute', 'firebase']);
app.config(['$routeProvider', function ($routeProvider) {
'use strict';
$routeProvider.when('/downtime', {
templateUrl: 'downtime/downtime.html',
controller: 'downtimeCtrl'
});
}]);
app.controller('downtimeCtrl', ['$scope', '$firebaseObject', '$firebaseArray', function ($scope, $firebaseObject, $firebaseArray) {
'use strict';
$scope.allEquipments = [];
$scope.allSystems = [];
$scope.manageDowntime = function () {
var doesExist = false;
angular.forEach ($scope.data , function (d) {
angular.forEach (d.equipments, function (e) {
})
});
firebase.database().ref('downtime/' + $scope.equipment + '/downtime').push({
equipment: $scope.equipment,
type : $scope.type,
start: $scope.startDT,
end: $scope.endDT
});
};
var ref = firebase.database().ref();
var data = ref.child("data");
var list = $firebaseArray(data);
list.$loaded().then(function(data) {
$scope.data = data;
angular.forEach ($scope.data , function (d) {
$scope.allSystems.push(d.$id);
angular.forEach (d.equipments, function (e) {
$scope.allEquipments.push(e.equipment);
console.log($scope.allEquipments);
})
});
console.log($scope.data);
}).catch(function(error) {
$scope.error = error;
});
$('#datetimepicker1').datetimepicker();
$('#datetimepicker2').datetimepicker();
}]);
app.directive('customzdatetime', function () {
return {
restrict: 'A',
require: 'ngModel',
link: function (scope, element, attrs, ngModelCtrl) {
element.datetimepicker({
debug: false,
format: 'DD-MM-YYYY hh:mm'
}).on('dp.change', function (e) {
ngModelCtrl.$setViewValue(e.date);
scope.$apply();
});
}
};
});
My HTML
<div class="page-header">
<h1>MANAGE DOWNTIME </h1>
</div>
<div data-ng-app="downtime">
<div class="row">
<div class="col-xs-12">
<div class="form-group col-xs-6 col-xs-offset-3" id="equipList">
<label for="selectequ">Select Equipment</label>
<select class="form-control" id="selectequ" data-ng-model="equipment"
>
<option data-ng-repeat="eq in allEquipments" >{{eq}}</option>
</select>
{{equipment}}
</div>
<div class="form-group col-xs-6 col-sm-6 col-md-6 col-lg-6 col-xs-offset-3" id="Type">
<label for="searchType">Search by Type:</label>
<select class="form-control" id="searchType" data-ng-model="type">
<option value="" disabled="" selected="" style="display: none">Select type of maintenance</option>
<option>Corrective Maintenance</option>
<option>Preventive Maintenance</option>
<option>Standby</option>
</select>
</div>
{{type}}
</div>
</div>
<div class="row">
<div class="form-group col-xs-6 col-xs-offset-3">
<label for="date">Start of Downtime</label>
<!-- <input type="datetime-local" id="datetimepicker1" class="form-control" placeholder="Day, Month, Year" data-ng-model="startDT"/>-->
<input type="text" class="form-control" placeholder="Day, Month, Year" data-ng-model="startDT" customzdatetime />
</div>
{{startDT}}
<div class="form-group col-xs-6 col-xs-offset-3">
<label for="date">End of Downtime</label>
<input type="text" class="form-control" placeholder="Day, Month, Year" data-ng-model="endDT" customzdatetime/>
{{endDT}}
</div>
</div>
<div class="row">
<div class="col-xs-6 col-sm-6 col-md-6 col-lg-6" id="central">
<a class="btn cd-add-to-cart cd-add-to-cart:hover cd-add-to-cart:active" role="button" data-ng-click="manageDowntime()">MANAGE <span class="glyphicon glyphicon-tasks"></span></a>
</div>
</div>
</div>
firebase will not accept date as datatype, try to convert them as string or number and then try to push it into the firebase. I hope your problem is the $scope.startDT because it contains some function in it, your're trying to use it directly that is why it throws a error, try to convert them as string or number, then try to push.
firebase.database().ref('downtime/' + $scope.equipment + '/downtime').push({
equipment: $scope.equipment,
type : $scope.type,
start: new Date($scope.startDT).toLocaleString(),
end: new Date($scope.endDT).toLocaleString()
or
start: new Date($scope.startDT).getTime(), //this will get you unix timestamp as number
end: new Date($scope.endDT).getTime()
});

Use same input text for two button using ASP.NET MVC

I want to use the same text to go different View.At present I set two view one is PlaceInformation and another is Google Map View. How can I set condition to go both View using HTML Beginfrom.I want to use #using (Html.BeginForm("GoogleMapView", "Home")) here. My Code sample is look like this-
#using (Html.BeginForm("PlaceInformation", "Home"))
{
<div class="wrapper wrapper-content">
<div class="row">
<div class="col-sm-12">
#Html.TextBoxFor(m =>m.Name)
<label for="somevalue">City Name</label>
<div class="input-group-btn">
<button class="btn btn-lg btn-primary" type="submit">Search</button>
</div>
<div class="input-group-btn">
<button class="btn btn-lg btn-primary" type="submit">Map View</button>
</div>
</div>
</div>
</div>
}
This is how i modified code .But it is not working.
<form id="myForm">
<div class="wrapper wrapper-content">
<div class="row">
<div class="col-sm-12">
#Html.TextBoxFor(m => m.Name)
<label for="somevalue">City Name</label>
<div class="input-group-btn">
<button id="searchBtn" class="btn btn-lg btn-primary" type="submit">Search</button>
</div>
<div class="input-group-btn">
<button id="mapViewBtn" class="btn btn-lg btn-primary" type="submit">Map View</button>
</div>
</div>
</div>
</div>
<script> {
$("#searchBtn").on("click", function (event) {
event.preventDefault();
$.ajax({
type: "POST",
url: '/home/placeinformation',
data: $("#myForm").serialize(), // serializes the form's elements.
success: function (data) {
//here you will get the result from the Controllers, like a partial view or you can do a redirect to another view if form post is successful.
},
error: function (xhr, status, error) {
//Handle any errors here
}
});
});
}
</script>
<script>{
$("#mapViewBtn").on("click", function (event) {
event.preventDefault();
$.ajax({
type: "POST",
url: '/home/GoogleMap',
data: $("#myForm").serialize(), // serializes the form's elements.
success: function (data) {
//here you will get the result from the Controllers, like a partial view or you can do a redirect to another view if form post is successful.
},
error: function (xhr, status, error) {
//Handle any errors here
}
});
});
}
</script>
My Controller for GoogleMap is-
public ActionResult GoogleMap(City objCityModel)
{
string name = objCityModel.Name;
ViewBag.Title = name;
var ReadJson = System.IO.File.ReadAllText(Server.MapPath(#"~/App_Data/POI_Json/" + name + ".json"));
RootObject json = new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize<RootObject>(ReadJson);
List<Poi> mycities = new List<Poi>();
foreach (var item in json.poi)
{
Poi obj = new Poi()
{
Name = item.Name,
Shorttext = item.Shorttext,
GeoCoordinates = item.GeoCoordinates,
Images = item.Images,
};
mycities.Add(obj);
}
ViewBag.Cities = mycities;
return View();
}
For Getting the name-
[HttpPost]
public ActionResult Index(City objCityModel)
{
string name = objCityModel.Name;
return View();
}
in My PLace information I am using the same data as GoogleMap view
public ActionResult PlaceInformation(City objCityModel)
{
string name = objCityModel.Name;
ViewBag.Title = name;
var ReadJson = System.IO.File.ReadAllText(Server.MapPath(#"~/App_Data/POI_Json/" + name + ".json"));
RootObject json = new System.Web.Script.Serialization.JavaScriptSerializer().Deserialize<RootObject>(ReadJson);
List<Poi> mycities = new List<Poi>();
foreach (var item in json.poi)
{
Poi obj = new Poi()
{
Name = item.Name,
Shorttext = item.Shorttext,
GeoCoordinates = item.GeoCoordinates,
Images = item.Images,
};
mycities.Add(obj);
}
ViewBag.Cities = mycities;
return View();
}
This will only generate one html form and it is the form element that decides where the form is posted. In other words there is no way to post this form to different controller actions depending on the button being clicked. However, there are of course other ways. I would bind and post the two post buttons with jQuery like this:
Change .cshtml to this:
<form id="myForm">
#Html.TextBoxFor(m => m.Name)
<label for="somevalue">City Name</label>
<div class="input-group-btn">
<button id="searchBtn" class="btn btn-lg btn-primary" type="submit">Search</button>
</div>
<div class="input-group-btn">
<button id="mapViewBtn" class="btn btn-lg btn-primary" type="submit">Map View</button>
</div>
</form>
Add id to the buttons:
<div class="input-group-btn">
<button id="searchBtn" class="btn btn-lg btn-primary" type="submit">Search</button>
</div>
<div class="input-group-btn">
<button id="mapViewBtn" class="btn btn-lg btn-primary" type="submit">Map View</button>
</div>
script:
$("#searchBtn").on("click", function (event) {
event.preventDefault();
$.ajax({
type: "POST",
url: '/home/placeinformation',
data: $("#myForm").serialize(), // serializes the form's elements.
success: function (data) {
//here you will get the result from the Controllers, like a partial view or you can do a redirect to another view if form post is successful.
},
error: function (xhr, status, error) {
//Handle any errors here
}
});
});
}
second script (I changed the button you bind to and the controller action you want to call.
$("#mapViewBtn").on("click", function (event) {
event.preventDefault();
$.ajax({
type: "POST",
url: '/home/urlToTheOtherAction,
data: $("#myForm").serialize(), // serializes the form's elements.
success: function (data) {
//here you will get the result from the Controllers, like a partial view or you can do a redirect to another view if form post is successful.
},
error: function (xhr, status, error) {
//Handle any errors here
}
});
});
}