Redux - How to get updated input value on changing qty in handleChange - redux

I fetched data and show the cart information of user,
Now i want to change the quantity of product from input field.
But when i change the quantity, it always get that value (see in handleChange) which stored in database.
Bydefault value is 1, but i if change to 2 (from input value), it should go 2 in const qty in handleChange function.
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { cartItems, removeCart, updateCart } from '../actions/cartAction';
class Cart extends Component {
constructor(props) {
super(props);
this.state = {
};
}
componentWillMount() {
let getValue = localStorage.getItem("userData");
this.setState({
getValue: JSON.parse(getValue),
});
}
componentDidMount() {
const emailData = this.state.getValue.email;
this.props.cartItems(emailData);
}
handleChange = (share) => (event) => {
this.setState({ [event.target.name]: event.target.value });
const cID = share._id;
const pprice = share.pprice;
const qty = share.qty;
const updateData = {cID: cID, pprice: pprice, qty: qty}
this.props.updateCart(updateData);
};
render() {
return (
<tbody>
{this.props.cartDetails.length && this.props.cartDetails.map(share => {
return (
<tr key={share._id}>
<td class="text-center">
<p> {share.pid} </p>
</td>
<th class="text-center" scope="row">
<img src="assets/img/product/2.jpg" alt="img" height="150px"/>
</th>
<td class="text-center">
<span class="whish-title">{share.pname}</span>
</td>
<td class="text-center">
<span class="whish-list-price">
{share.pprice}
</span>
</td>
<td class="text-center">
<div class="product-count style">
<div class="count d-flex justify-content-center">
<input type="number" onChange={this.handleChange(share)} defaultValue={share.qty} name="qty" min="1" max="10" step="1"/>
</div>
</div>
</td>
<td class="text-center">
<span class="whish-list-price">
{share.total_price}
</span>
</td>
<td class="text-center">
<span class="whish-list-price">
<button onClick={this.deleteCart(share)} className="btn theme-btn--dark1 btn--md">Delete</button>
</span>
</td>
</tr>
);
})}
</tbody>
)
}
}
const mapStateToProps = (state) => ({ cartDetails: state.cartDetails });
const mapDispatchToProps = {cartItems, removeCart, updateCart};
export default connect(mapStateToProps,mapDispatchToProps)(Cart);

I think the issue is on
const updateData = {cID: cID, pprice: pprice, qty: qty}
Why you use share.qty instead of event.target.value?
I also don't understand the sense of
this.setState({ [event.target.name]: event.target.value });
Where do you use these values?

Related

how to I add a scrollbar for the table

i am mapping values on the table, i want the table to have scrollbar when it reaches some max-height,
adding overflow: scrollbar, width max-height: 600px did not work, the table just keeps extending downwards
return (
<div className='journaltable-div'>
<table className='table table-journal'>
<thead className='table-head'>
<tr className='table-head-row'>
<th>Task</th>
<th>Date-created</th>
<th>Action</th>
</tr>
</thead>
<tbody className='table-body'>
{ journalList.map((entry) => {
const { key, journal, time } = entry
return (
<tr key={key} className="table-body-row">
<td>{journal}</td>
<td>{time}</td>
<td><button
className='button button-complete'
onClick={(e) => {
e.stopPropagation
addToLog(key, "completed")
removeJournal(key)
}}>completed</button><button
className='button button-delete'
onClick={(e) => {
e.stopPropagation
addToLog(key, "deleted")
removeJournal(key)
}}>delete</button></td>
</tr>
)
}) }
</tbody>
</table>
<div className='redirect-div'>
<button className='redirect-logs' style={{cursor: 'pointer'}} onClick={() => {handleLogs()}}> Check Logs</button>
</div>
</div>
.table-journal {
overflow: scroll;
max-height: 600px;
}
also tried placing on tbody did not work either
put all of your return values from the map function in a div with scrollit style class and add these codes to your CSS:
.scrollit {
overflow:scroll;
height:100px;
}
your code have look like this:
return (
<div className='journaltable-div'>
<table className='table table-journal'>
<thead className='table-head'>
<tr className='table-head-row'>
<th>Task</th>
<th>Date-created</th>
<th>Action</th>
</tr>
</thead>
<tbody className='table-body'>
<div className="scrollit">
{ journalList.map((entry) => {
const { key, journal, time } = entry
return (
<tr key={key} className="table-body-row">
<td>{journal}</td>
<td>{time}</td>
<td><button
className='button button-complete'
onClick={(e) => {
e.stopPropagation
addToLog(key, "completed")
removeJournal(key)
}}>completed</button><button
className='button button-delete'
onClick={(e) => {
e.stopPropagation
addToLog(key, "deleted")
removeJournal(key)
}}>delete</button></td>
</tr>
)
}) }
</div>
</tbody>
</table>
<div className='redirect-div'>
<button className='redirect-logs' style={{cursor: 'pointer'}} onClick={() => {handleLogs()}}> Check Logs</button>
</div>
</div>

Can't add parameters to getStaticProps for reloading a page with page 2, 3, 4, etc... of API fetched data

I have this project here https://github.com/ChristianOConnor/custom-bp-one. It's just an experiment/learning experience for how to query GraphQL APIs via a Next.js app. I have a page that populates a table with Rick and Morty characters on page load. It looks like this:
And the code for the page looks like this:
characters.tsx
import Head from 'next/head'
import styles from '../styles/Home.module.css'
import client from '../lib/apolloClient';
import { gql } from '#apollo/client';
export async function getStaticProps() {
const { data } = await client.query({
query: gql`
query getCharacters {
characters(page: 1) {
results {
id
name
species
status
}
}
}`,
});
console.log(data);
return {
props: {
characters: data.characters.results,
},
};
}
export default function Characters({ characters }: { characters: JSON[] }) {
return (
<div className={styles.container}>
<Head>
<title>Create Next App</title>
<meta name="description" content="Generated by create next app" />
<link rel="icon" href="/favicon.ico" />
</Head>
<div>
<div className="container flex flex-wrap items-center justify-between mx-auto">
<div>
Page #
</div>
</div>
</div>
<br />
<div className="overflow-x-auto relative shadow-md sm:rounded-lg">
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400">
<thead className="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
<tr>
<th scope="col" className="py-3 px-6">NAME</th>
<th scope="col" className="py-3 px-6">ROLE</th>
<th scope="col" className="py-3 px-6">STATUS</th>
</tr>
</thead>
<tbody>
{characters?.map((section: any) => {
return (
<tr className="bg-white border-b dark:bg-gray-800 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600" key={section.id}>
<td className="py-4 px-6">{section.name}</td>
<td className="py-4 px-6">{section.species}</td>
<td className="py-4 px-6">{section.status}</td>
</tr>
)
})}
</tbody>
</table>
</div>
</div>
)
}
But I want to add a page 2 button. I changed the code to what I have below in an attempt to change the query parameter for page in the line characters(page: 1) and reload this next.js page on button presses.
import Head from 'next/head'
import styles from '../styles/Home.module.css'
import client from '../lib/apolloClient';
import { gql } from '#apollo/client';
import Link from 'next/link';
interface DataObj {
characters: {
[results: string]: JSON;
}
}
export async function getStaticProps({ params }: { params: string }) {
const preData = `{
"data": {
"characters": {
"results": [
{
"id": "1",
"name": "Rick Sanchez",
"species": "Human",
"status": "Alive"
}
]
}
}
}`;
let data: DataObj = JSON.parse(preData);
if (!params) {
const { data } = await client.query({
query: gql`
query getCharacters {
characters(page: 1) {
results {
id
name
species
status
}
}
}`,
});
} else {
const { data } = await client.query({
query: gql`
query getCharacters {
characters(page: ${params}) {
results {
id
name
species
status
}
}
}`,
});
}
return {
props: {
characters: data.characters.results,
},
};
}
export default function Characters({ characters }: { characters: JSON[] }) {
return (
<div className={styles.container}>
<Head>
<title>Create Next App</title>
<meta name="description" content="Generated by create next app" />
<link rel="icon" href="/favicon.ico" />
</Head>
<div>
<div className="container flex flex-wrap items-center justify-between mx-auto">
<Link href="/characters/2">
<button type="button" className="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center mr-3 md:mr-0 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">
<span>
Page 2
</span>
</button>
</Link>
</div>
</div>
<br />
<div className="overflow-x-auto relative shadow-md sm:rounded-lg">
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400">
<thead className="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
<tr>
<th scope="col" className="py-3 px-6">NAME</th>
<th scope="col" className="py-3 px-6">ROLE</th>
<th scope="col" className="py-3 px-6">STATUS</th>
</tr>
</thead>
<tbody>
{characters?.map((section: any) => {
return (
<tr className="bg-white border-b dark:bg-gray-800 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600" key={section.id}>
<td className="py-4 px-6">{section.name}</td>
<td className="py-4 px-6">{section.species}</td>
<td className="py-4 px-6">{section.status}</td>
</tr>
)
})}
</tbody>
</table>
</div>
</div>
)
}
But it fails with this error:
So how do I get this to work? How do I add a parameter for a load page 2 functionality?
Also, I can't do anything with getServerSideProps because I want to build this as a static site.
I fixed it by changing the characters page to a dynamic routing characters page. So the characters page used to be located at pages/characters, but now it's located at pages/characters/[page].tsx. [page].tsx's code looks like this:
page/characters/[page].tsx
import Head from 'next/head'
import styles from '../../styles/Home.module.css'
import client from '../../lib/apolloClient';
import { gql } from '#apollo/client';
import Link from 'next/link';
import { GetStaticPaths } from 'next';
export const getStaticPaths: GetStaticPaths<{ page: string }> = async () => {
return {
paths: [], //indicates that no page needs be created at build time
fallback: 'blocking' //indicates the type of fallback
}
}
export async function getStaticProps({ params }: { params: any }) {
let processedParam;
if (!params || params?.page == null) {
processedParam = 1;
} else {
processedParam = params.page
}
const { data } = await client.query({
query: gql`
query getCharacters {
characters(page: ${processedParam}) {
results {
id
name
species
status
}
}
}`,
});
return {
props: {
characters: data.characters.results,
},
};
}
export default function Characters({ characters }: { characters: JSON[] }) {
return (
<div className={styles.container}>
<Head>
<title>Create Next App</title>
<meta name="description" content="Generated by create next app" />
<link rel="icon" href="/favicon.ico" />
</Head>
<div>
<div className="container flex flex-wrap items-center justify-between mx-auto">
<Link href="/characters/2">
<button type="button" className="text-white bg-blue-700 hover:bg-blue-800 focus:ring-4 focus:outline-none focus:ring-blue-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center mr-3 md:mr-0 dark:bg-blue-600 dark:hover:bg-blue-700 dark:focus:ring-blue-800">
<span>
Page 2
</span>
</button>
</Link>
</div>
</div>
<br />
<div className="overflow-x-auto relative shadow-md sm:rounded-lg">
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400">
<thead className="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
<tr>
<th scope="col" className="py-3 px-6">NAME</th>
<th scope="col" className="py-3 px-6">ROLE</th>
<th scope="col" className="py-3 px-6">STATUS</th>
</tr>
</thead>
<tbody>
{characters?.map((section: any) => {
return (
<tr className="bg-white border-b dark:bg-gray-800 dark:border-gray-700 hover:bg-gray-50 dark:hover:bg-gray-600" key={section.id}>
<td className="py-4 px-6">{section.name}</td>
<td className="py-4 px-6">{section.species}</td>
<td className="py-4 px-6">{section.status}</td>
</tr>
)
})}
</tbody>
</table>
</div>
</div>
)
}

How to Send Foreign key id along with Form data in angular?

I'mm creating an Angular application with ASP.NET.
I need to create:
courses,
course contents
course schedules for the selected course.
After creating the course I will select that particular course and create the content for that.
But while submitting the form, I also need to save the selected course id as a foreign key in database.
Can anyone help me on this please?
createcontent.component.ts
import { Component, OnInit, EventEmitter, Output } from '#angular/core';
import { FormBuilder, FormGroup, Validators } from '#angular/forms';
import { CoursesService } from 'src/app/shared/courses.service';
import { Content } from '#angular/compiler/src/render3/r3_ast';
import {ActivatedRoute} from '#angular/router';
import { HttpClient } from '#angular/common/http';
#Component({
selector: 'app-createcontent',
templateUrl: './createcontent.component.html',
styleUrls: ['./createcontent.component.css']
})
export class CreatecontentComponent implements OnInit {
contentForm: FormGroup;
contents:Content[];
courseName: string;
courseid;
isSubmitted:boolean;
constructor(private courseservice:CoursesService,private fb: FormBuilder,private route:ActivatedRoute,private http:HttpClient) {
}
setValue(){
this.contentForm.setValue({
courseid:this.route.snapshot.params['id']
});
}
ngOnInit(): void {
this.courseName=this.route.snapshot.params['cname'];
this.courseid=this.route.snapshot.params['id']
this.contentForm = this.fb.group({
contentname: ['', Validators.required ],
contentdescription: ['', Validators.required ],
duration: ['', Validators.required ],
courseid:['']
});
this.courseservice
.getContents()
.subscribe((data: Content[]) => {
this.contents = data;
});
}
OnSubmit(){
console.log(this.contentForm);
this.http.post('https://localhost:44319/api/contents1',this.contentForm.value,this.courseid).subscribe(data=>{
console.log(data);
})
}
}
createtraining.component.ts
import { Component, OnInit, Input } from '#angular/core';
import { FormBuilder, FormGroup, Validators } from '#angular/forms';
import { CoursesService } from 'src/app/shared/courses.service';
import { Course } from 'src/app/shared/course.model';
import { HttpClient } from '#angular/common/http';
#Component({
selector: 'app-createtraining',
templateUrl: './createtraining.component.html',
styleUrls: ['./createtraining.component.css']
})
export class CreatetrainingComponent implements OnInit {
courseForm: FormGroup;
courses: Course[];
loading:false;
toggleState:boolean= false;
coursename = 'angular';
clickedCourse:string;
dayFinished:boolean=true;
constructor(private courseservice:CoursesService,private fb: FormBuilder,private http:HttpClient) {
}
getCourse(course:string){
this.clickedCourse=course;
}
ngOnInit(): void {
this.courseForm = this.fb.group({
coursename: ['', Validators.required ],
coursedescription: ['', Validators.required ]
});
this.courseservice
.getCourses()
.subscribe((data: Course[]) => {
this.courses = data;
this.toggleState=true;
});
}
OnSubmit(){
console.log(this.courseForm);
this.http.post('https://localhost:44319/api/courses',this.courseForm.value).subscribe(data=>{
console.log(data);
})
}
}
cretecontent.component.html
<div id="training-page" class="row">
<div class="col s8 offset-s2">
<div class="card">
<div class="sm-jumbotron center-align">
<h2>Create Content for {{courseName}}</h2>
</div>
</div>
<div class="card">
<form [formGroup]="contentForm" novalidate (ngSubmit)="OnSubmit()">
<div class="row"></div>
<div class="input-field col s6">
<input name="course_name" id="register-firstname" formControlName="contentname" type="text" class="form-input form-control" #contentname>
<label for="course_name" class="center-align">Topic Name<span class="required">*</span></label>
<div *ngIf="contentForm.controls['contentname'].invalid && (contentForm.controls['contentname'].dirty || contentForm.controls['contentname'].touched)">
<div *ngIf="contentForm.controls['contentname'].errors.required" style="color: red;font-size: 11px;">
Topic Name is required.
</div>
</div>
</div>
<div class="input-field col s6">
<input name="coursedesc" id="course-description" type="text" formControlName="contentdescription" class="form-input form-control" #contentdescription>
<label for="course_description" class="center-align">Topic Description<span class="required">*</span></label>
<div *ngIf="contentForm.controls['contentdescription'].invalid && (contentForm.controls['contentdescription'].dirty || contentForm.controls['contentdescription'].touched)">
<div *ngIf="contentForm.controls['contentdescription'].errors.required" style="color: red;font-size: 11px;">
Topic Description is required.
</div>
</div>
</div>
<div class="input-field col s6">
<input name="contenttime" id="course-description" type="text" formControlName="duration" class="form-input form-control" #duration>
<label for="course_description" class="center-align">Duration<span class="required">*</span></label>
<div *ngIf="contentForm.controls['duration'].invalid && (contentForm.controls['duration'].dirty || contentForm.controls['duration'].touched)">
<div *ngIf="contentForm.controls['duration'].errors.required" style="color: red;font-size: 11px;">
Duration is required.
</div>
</div>
</div>
<input type="text" id="courseid" formControlName="courseid" class="form-input form-control" #courseid>
<div class="row">
<div class="input-field col s12 valign center">
<button [disabled]="!contentForm.valid" (click)="setValue()" type="submit" class="btn-primary">Create</button>
</div>
</div>
</form>
</div>
<table class="table">
<thead class="thead-light">
<tr>
<th scope="col">Topic Name</th>
<th scope="col">Topic Description</th>
<th scope="col">Duration</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let content of contents">
<td>{{ content.contentname }}</td>
<td>{{ content.contentdescription }}</td>
<td>{{ content.duration}}</td>
</tr>
</tbody>
</table>
<div class="row">
<div class="input-field col s12 valign center">
<button type="button" class="btn-primary" [routerLink]="['/trainer']">Back to Course</button>
</div>
</div>
</div>

VueJS data bind related

I use vueJS to display a table data,when I click the delete button, the table always delete the last row,rather not a specific row.I use my custom UIComponent 'lovTable',it changes a input element to another style,how to avoid it and make the data and page change the same way.Here's the code.Tks.
<script>
//服务类型下拉列表数据转化
var mServiceTypeData = $.map(serviceTypeData, function (obj) {
obj.id = obj.value;
obj.text = obj.meaning;
return obj;
});
$(function(){
var vm = new Vue({
el: '#div-rms-memo',
data: {
sub:[]
},
methods:{
//添加子项目
addSubProject:function () {
vm.sub.push({
subPrjServeType:'',
subPrjBelongToDept:'',
});
},
//移除当前行的子项目
removeCurrentRow:function(index){
var $del=vm.sub.splice(index,1);
},
}
});
function renderLines(el, lineIndex){
//渲染select2
$("#subPro"+lineIndex).find(".subPrjServeType").select2Ext({
placeholder: '请选择服务类型',
data: mServiceTypeData,
width:150
}).on('change', function () {
vm.sub[lineIndex].subPrjServeType = $(this).val();
});
//归属部门LOV
$("#subPro"+lineIndex).find(".subPrjBelongToDept").lovTable({
title:'归属部门',
placeholder:'请选择',
valueField:'unitId',
textField:'unitName',
query:[
{
text:'部门ID',
name:'unitId'
},
{
text:'部门名称',
name:'unitName'
}
],
rowSelected:function(row){
vm.sub[lineIndex].subPrjBelongToDept=row.unitId;
},
textClear:function(){
vm.sub[lineIndex].subPrjBelongToDept = "";
}
},{
url : '${base.contextPath}/project/prjBranchView/queryConditionPage?'+_header+'='+_token,
columns: [{
title:'部门ID',
field:'unitId'
},{
title:'部门名称',
field:'unitName'
}]
});
}
Vue.directive('line-bind', {
bind: function (el, binding) {
var lineIndex = binding.value;
console.info('binding index='+lineIndex)
vm.$nextTick(function () {
renderLines(el,lineIndex);
})
},
unbind:function(el,binding){
vm.$nextTick(function () {
for(var i=0;i<vm.sub.length;i++){
renderLines(vm.sub[i],i);
}
})
}
});
})
</script>
<div class="content-wrapper">
<section class="content">
<div id="div-rms-memo" >
<div class="box box-blue">
<div class="form-group">
<a href="javascript:void(0)" class="btn btn-crm" v-on:click="addSubProject">
<span class="glyphicon glyphicon-plus">添加</span>
</a>
</div>
<table align="center" class="table table-bordered" v-line-bind="index" v-for="(el,index) in sub" :id="'subPro'+index" :cindex="index">
<tr class="crm-title">
<td align="center" valign="middle" rowspan="2" style="width:5%;">
<a href="javascript:void(0)" class="btn btn-default btn-xs removeSubPrj" id="removeSubPrjBtn" v-on:click="removeCurrentRow(index)">
<span class="glyphicon glyphicon-minus"></span>
</a>
</td>
<td align="center" style="width:15%;"class="required">服务类型</td>
<td align="center" style="width:15%;"class="required">归属部门</td>
<td align="center" style="width:15%;" class="required">人天</td>
</tr>
<tr>
<td align="center">
<input type="text" id="subPrjServeType" v-model="el.subPrjServeType" class="form-control input-sm subPrjServeType"/>
</td>
<td align="center">
<input type="text" class="form-control input-sm subPrjBelongToDept" v-model="el.subPrjBelongToDept">
</td>
<td align="center">
<input type="number" class="form-control input-sm subPrjPeoplePerDay" v-model="el.subPrjPeoplePerDay">
</td>
</tr>
</table>
</div>
</div>
</section>
</div>

Angular2 submit a form to the server

I have googled for this problem and I found a lot of links which couldn't help me solve my problem. All I want to do is to send forms data to the controller. it goes to the controller but the data is not present in there.
here are my codes:
app.component.ts
import {Component, OnInit} from "angular2/core";
import {AsyncRoute, Router, RouteDefinition, ROUTER_PROVIDERS, RouteConfig, Location, ROUTER_DIRECTIVES, RouteParams} from "angular2/router";
import {CitiesComponent} from "./components/cities.component";
import { CitiesService } from './components/cities.service';
import { HTTP_PROVIDERS } from 'angular2/http';
import 'rxjs/Rx';
declare var System: any;
#Component({
selector: "app",
templateUrl: "/app/app.html",
providers: [CitiesService, HTTP_PROVIDERS, ROUTER_PROVIDERS],
directives: [ROUTER_DIRECTIVES]
})
export class AppComponent implements OnInit {
public routes: RouteDefinition[] = null;
constructor(private router: Router,
private location: Location) {
}
ngOnInit() {
if (this.routes === null) {
this.routes = [
new AsyncRoute({
path: "/City",
name: "City",
loader: () => System.import("app/components/cities.component").then(c => c["CitiesComponent"])
})
];
this.router.config(this.routes);
}
}
getLinkStyle(route: RouteDefinition) {
return this.location.path().indexOf(route.path) > -1;
}
}
cities.ts
export interface ICities {
Id: string;
State: string;
Title: string;
}
cities.component.ts
import {Component, OnInit} from "angular2/core";
import { FORM_DIRECTIVES } from 'angular2/common';
import { RouteParams, Router } from 'angular2/router';
import { ICities } from './cities';
import { CitiesService } from './cities.service';
#Component({
selector: "cities",
templateUrl: "/partial/cities",
directives: [FORM_DIRECTIVES]
})
export class CitiesComponent implements OnInit {
public City: ICities;
cities: ICities[];
errorMessage: string;
constructor(private _citiesService: CitiesService, private _router: Router,
private _routeParams: RouteParams) { }
ngOnInit() {
this._citiesService.getCities()
.subscribe(
cities => this.cities = cities,
error => this.errorMessage = <any>error);
//this.message = "anything!"
}
onSubmit(form: ICities): void {
console.log('you submitted value 23:', form);
this._citiesService.addCity(form);
}
}
cities.services.ts
import { Injectable } from 'angular2/core';
import { Http, Response, Headers, RequestOptions, RequestMethod, Request} from 'angular2/http';
import { Observable } from 'rxjs/Observable';
import { ICities } from './cities';
#Injectable()
export class CitiesService {
private _citiesInsert = '/Cities/CitiesInsert';
private _citiesList = '/Cities/GetCities';
constructor(private _http: Http) { }
getCities(): Observable<ICities[]> {
return this._http.get(this._citiesList)
.map((response: Response) => <ICities[]>response.json())
.do(data => console.log('All: ' + JSON.stringify(data)))
.catch(this.handleError);
}
addCity(city: ICities) {
let body = JSON.stringify({ city });
let headers = new Headers({ 'Content-Type': 'application/json' });
//let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded' });
let options = new RequestOptions({ headers: headers });
var url = '/Cities/CitiesInsert';
this._http.post(this._citiesInsert, JSON.stringify(city), headers)
.map(this.extractData)
.catch(this.handleError)
.subscribe(
(res2) => {
console.log('subsribe %o', res2)
}
);
}
private extractData(res: Response) {
let body = res.json();
alert("extract data: " + body);
return body.data || {};
}
private handleError(error: Response) {
// in a real world app, we may send the server to some remote logging infrastructure
// instead of just logging it to the console
alert("error: " + error);
console.error(error);
return Observable.throw(error.json().error || 'Server error');
}
}
cities.cshtml
<cities>
<div class="col-md-12">
<div class="portlet box blue ">
<div class="portlet-title">
<div class="caption">
<i class="fa fa-gift"></i> مشخصات
</div>
<div class="tools">
<a title="" data-original-title="" href="" class="collapse"> </a>
<a title="" data-original-title="" href="#portlet-config" data-toggle="modal" class="config"> </a>
<a title="" data-original-title="" href="" class="reload"> </a>
<a title="" data-original-title="" href="" class="remove"> </a>
</div>
</div>
<div class="portlet-body form">
<form role="form" #f="ngForm" (ngSubmit)="onSubmit(f.value)" >
<div class="form-body">
<div class="row">
<div class="col-sm-8">
<div class="form-group">
<label>وضعیت</label>
<select ngControl="State" class="form-control input-small selectpicker">
<option value="ACTIVATED" selected="selected">فعال</option>
<option value="DEACTIVE">غیرفعال</option>
</select>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-8">
<div class="form-group">
<label>عنوان</label>
<div class="input-group">
<span class="input-group-addon">
<i class="fa fa-envelope"></i>
</span>
<input class="form-control" ngControl ="Title" placeholder="عنوان شهر" type="text">
</div>
</div>
</div>
</div>
</div>
<div class="form-actions right">
<button class="btn">
<i class="fa fa-ban"></i> صرفنظر
</button>
<button class="btn green" type="submit">
<i class="fa fa-save"></i> ذخیره
</button>
</div>
</form>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="portlet mt-element-ribbon light portlet-fit ">
<div class="ribbon ribbon-right ribbon-clip ribbon-shadow ribbon-border-dash-hor ribbon-color-success uppercase">
<div class="ribbon-sub ribbon-clip ribbon-right"></div> لیست اطلاعات
</div>
<div class="portlet-title">
<div class="caption">
<i class="icon-layers font-green"></i>
<span class="caption-subject font-green bold uppercase">شهرها</span>
</div>
</div>
<div class="portlet-body">
<div class='table-responsive'>
<table class='table' *ngIf='cities && cities.length'>
<thead>
<tr>
<th>
Title
</th>
</tr>
</thead>
<tbody>
<tr *ngFor='#city of cities'>
<td>{{ city.Title }}</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</cities>
CitiesController.cs
[HttpPost]
public void CitiesInsert(Cities city)
{
Console.Write(city);
}
Try something like this:
<form [ngFormModel]="loginForm" (submit)="doLogin($event)"
and in your component
doLogin(event) {
console.log(this.loginForm.value);
event.preventDefault();
}

Resources