I am pretty new to Reactjs and i have a component that loads json from my db that looks like this
Array[2]
0: Object
_id: "56cf587fe46adb3b8960afe2"
price: 2000
title: "ps3"
url: "www.google.com"
__proto__: Object
1: Object
_id: "56db2bd434df9046e0643d22"
price: 499
title: "HENRIKSDAL"
url: "http://www.ikea.com/se/sv/catalog/products/S59847817/"
__proto__: Object
length: 2
__proto__: Array[0]
what i want to do is to load the data on to the table that looks like this
//start of loop
<tr>
<td className="col-sm-8 col-md-6">
<div className="media">
<div className="media-body">
<h4 className="media-heading">Product name</h4>
</div>
</div></td>
<td className="col-sm-1 col-md-1" styles="text-align: center">
<input type="number" name="quantity" min="1" max="10" className="form-control"/>
</td>
<td className="col-sm-1 col-md-1 text-center"><strong>500:-</strong></td>
<td className="col-sm-1 col-md-1 text-center"><strong>$14.61</strong></td>
<td className="actions" data-th="">
<button className="btn btn-info btn-sm"><i className="fa fa-refresh"></i></button>
<button className="btn btn-danger btn-sm"><i className="fa fa-trash-o"></i></button>
</td>
</tr>
<tr>
<td> </td>
<td> </td>
<td> </td>
<td><h3>Total</h3></td>
<td className="text-right"><h3><strong>$31.53</strong></h3></td>
</tr>
//end of loop
But i don't know how to iterate through the array so it will create a tablerow for each object in the array. Any suggestions?
You can map the array and pass the data through to the html
{this.state.data.map(( listValue, index ) => {
return (
<tr key={index}>
<td>{listValue.id}</td>
<td>{listValue.title}</td>
<td>{listValue.price}</td>
</tr>
);
})}
You can use map method (available in prototype of Array).
Iterating can be as simple as this...
const rows = [
{
_id: "56cf587fe46adb3b8960afe2",
price: 2000,
title: "ps3",
url: "www.google.com",
}, {
_id: "56db2bd434df9046e0643d22",
price: 499,
title: "HENRIKSDAL",
url: "http://www.ikea.com/se/sv/catalog/products/S59847817/",
}
];
var Hello = React.createClass({
renderRow(props) {
return (
<tr>
<td>{ props._id }</td>
<td>{ props.price }</td>
<td>{ props.title }</td>
<td>{ props.url }</td>
</tr>
);
},
render: function() {
return (
<table>
{ this.props.rows.map(this.renderRow) }
</table>
);
}
});
ReactDOM.render(
<Hello rows={rows} />,
document.getElementById('container')
);
Working Fiddle
https://jsfiddle.net/zwdjmozn/1/
This is an extension of #Andreyco answer where a separate template is defined however in my case I am referencing the JSX template within the map call (<Row />
const Table = (props) => (
<div>
<p>Your Table</p>
<table>
<tbody>
{props.rows.map((x,i) => <Row key={i} data={x} />) }
</tbody>
</table>
</div>
)
const Row = (props:any) => (
<tr>
<td>{props.data[0]}</td>
<td>{props.data[1]}</td>
<td>{props.data[2]}</td>
</tr>
)
See JSFiddle
Related
I have a dynamic Accordion in ReactJs. I am getting the message from my backend. but it's printing in every Accordion. I'm sharing the code
import React, { useState, useEffect } from "react";
import ApplicantDash from "./ApplicantDash";
import {
Accordion,
AccordionSummary,
AccordionDetails,
Typography,
} from "#material-ui/core";
import * as FcIcons from "react-icons/fc";
import ApplicantService from "../services/ApplicantService";
export default function AvailJobs() {
const [aplcntEmail, setAplcntEmail] = useState("aman#gmail.com"); //change to aplcntemail
const [isShow, setIsShow] = useState(false);
const [msg, setMsg] = useState([""]);
const [job, setJob] = useState([
{
jobTitle: "",
dateOfPosting: Date,
lastDateToApply: new Date().toLocaleDateString([], {
year: "numeric",
month: "long",
day: "numeric",
}),
preferableSkills: [],
requiredExp: 0,
recruiterEmail: "",
companyName: "",
companyAddress: "",
},
]);
useEffect(() => {
const data = ApplicantService.getAllJobs()
.then((response) => {
console.log(response.data);
setJob(response.data);
})
.catch((error) => {
alert(error.response.data);
});
}, []);
const onApplyButton = (item,key) => {
const data2 = ApplicantService.applyForJob(aplcntEmail, item)
.then((response) => {
console.log(response.data);
setIsShow(true);
setMsg(response.data)
})
.catch((error) => {
setIsShow(true);
setMsg(error.response.data);
});
};
return (
<div>
<ApplicantDash />
<div className="container bg-light">
<div className="card-bodies">
<section className="mb-4">
<h2 className="h1-responsive font-weight-bold text-center my-4">
All Available jobs
</h2>
</section>
{job.map((item, key) => (
<>
<Accordion key={key}>
<AccordionSummary
expandIcon={<FcIcons.FcExpand />}
aria-controls="panel1a-content"
id="panel1a-header"
className="Accordian"
>
<Typography>
<div className="d-flex p-1 justify-content-evenly">
<div className="p-1">
<b> Job: </b> {item.jobTitle}
</div>
<div className="p-2"></div>
<div className="p-1">
<b> Company: </b> {item.companyName}
</div>
<div className="p-2"></div>
<div className="p-1">
<b> Last Date: </b> {item.lastDateToApply}
</div>
</div>
</Typography>
</AccordionSummary>
<AccordionDetails>
<Typography>
<div className="container">
<table class="table table-borderless">
<tbody>
<tr>
<td>JOB TITLE</td>
<td>:</td>
<td>
<b>{item.jobTitle}</b>
</td>
</tr>
<tr>
<td>Company</td>
<td>:</td>
<td>
<b>{item.companyName}</b>
</td>
</tr>
<tr>
<td>Address</td>
<td>:</td>
<td>
<b>{item.companyAddress}</b>
</td>
</tr>
<tr>
<td>Last Date to Apply</td>
<td>:</td>
<td>
<b>{item.lastDateToApply}</b>
</td>
</tr>
<tr>
<td>Experience</td>
<td>:</td>
<td>
<b>{item.requiredExp}</b>
</td>
</tr>
<tr>
<td> Skills </td>
<td>:</td>
<td>
<table className="table table-condensed w-auto table-borderless table-hover">
{item.preferableSkills.map((S, index1) => {
return (
<tbody key={index1}>
<td scope="col">
{index1 + 1}.<b>{S}</b>
</td>
</tbody>
);
})}
</table>
</td>
</tr>
<tr>
<td></td>
<td></td>
<td>
<button
type="button"
class="btn btn-primary"
onClick={() => onApplyButton(item,key)}
>
Apply for the job{" "}
</button>
</td>
</tr>
</tbody>
{isShow && <>
{msg}
</>}
</table>
</div>
</Typography>
</AccordionDetails>
</Accordion>
</>
))}
</div>
</div>
</div>
);
}
Now when I click on Apply for this job button. The message I get from backend prints only to Active accordion
Here some pictures which might help.
enter image description here
As you can see the response from backend is prints in the both of the accordion
Issue
The issue here is that you've a single boolean isShow state and a single msg state, and all the accordion detail sections use the same single isShow state to conditionally render the msg state.
Solution
A simple solution would be to store the id, or title, or index, of the accordion to show the message of.
Example:
export default function AvailJobs() {
...
const [isShow, setIsShow] = useState({}); // <-- initially empty object
...
const onApplyButton = (item, key) => {
ApplicantService.applyForJob(aplcntEmail, item)
.then((response) => {
console.log(response.data);
setMsg(response.data);
})
.catch((error) => {
setMsg(error.response.data);
})
.finally(() => {
setIsShow(show => ({
...show,
[key]: true // <-- set true the specific key
}));
});
};
return (
<div>
...
{job.map((item, key) => (
<Accordion key={key}>
...
<AccordionDetails>
<Typography>
<div className="container">
<table class="table table-borderless">
<tbody>
...
<tr>
...
<td>
<button
type="button"
class="btn btn-primary"
onClick={() => onApplyButton(item, key)}
>
Apply for the job
</button>
</td>
</tr>
</tbody>
{isShow[key] && <>{msg}</>} // <-- check if isShow[key] is truthy
</table>
</div>
</Typography>
</AccordionDetails>
</Accordion>
))}
...
</div>
);
}
Ok. I am super lost here. I am attempting to return an a value from a nested array of objects. Here is what the database looks like.
Each object returns an array of staff as seen in this console log.
I cannot for the life of me display both names out of the array. I used the .flatMap() function to extract the data from the array, but when I go to render it in the component only the first name shows. Here is my codebase. Right now I am just console logging the data using .flatMap()
import React, { Fragment, useEffect } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { Table } from 'react-bootstrap';
import Moment from 'react-moment';
import Button from '../components/Button';
import ActivitySummary from '../components/ActivitySummary';
import { projectsInfoDetails } from '../actions/projectInfoActions';
import { projectContacts } from '../actions/projectContactActions';
import { projectStaff } from '../actions/accountableStaffActions';
import SectionHeader from '../components/SectionHeader';
import Loader from '../components/Loader';
import Message from '../components/Message';
const ProjectScreen = ({ match }) => {
const dispatch = useDispatch();
const projectInfoDetails = useSelector(state => state.projectInfoDetails);
const { loading, error, projects } = projectInfoDetails;
const contactDetails = useSelector(state => state.projectContactDetails);
const { projectContact } = contactDetails;
const projectAccountableStaff = useSelector(state => state.projectStaff);
const { accountableProjectStaff } = projectAccountableStaff;
useEffect(() => {
dispatch(projectsInfoDetails(match.params.id));
dispatch(projectContacts(match.params.id));
dispatch(projectStaff(match.params.id));
}, [dispatch, match]);
const lastName = projectContact.map(l => l.contact.lastName);
const firstName = projectContact.map(f => f.contact.firstName);
const accountableStaffLastNames = accountableProjectStaff.flatMap(
({ accountableStaff }) => accountableStaff.map(data => data.lastName)
);
console.log(accountableStaffLastNames);
return (
<Fragment>
<div>
<SectionHeader sectionName='Project' />
<Button buttonName='Edit Project' />
</div>
{loading ? (
<Loader />
) : error ? (
<Message variant='danger'>{error}</Message>
) : (
<div style={{ backgroundColor: '#F8F8F8' }}>
<Table className='borderless'>
<tbody>
<tr>
<td>
<strong>Name: </strong>
{projects.name}
</td>
<td>
<strong>Status: </strong>
{projects.status}
</td>
</tr>
<tr>
<td>
<strong>State: </strong>
{projects.state}
</td>
<td>
<strong>County: </strong>
{projects.county}
</td>
</tr>
<tr>
<td>
<strong>Congressional District: </strong>
{projects.district}
</td>
<td>
<strong>Type: </strong>
{projects.type}
</td>
</tr>
<tr>
<td>
<strong>Funding Source: </strong>
<br />
{`${projects.fundingSource} ${projects.fundingSourceName}`}
</td>
<td>
<strong>Funding Source Goal: </strong>
<br />
{projects.fundingSourceGoal}
</td>
<td>
<strong>Start Date: </strong>
<br />
<Moment format='MM/DD/YYYY'>{projects.startDate}</Moment>
</td>
<td>
<strong>End Date: </strong>
<br />
{projects.endDate === null ? (
''
) : (
<Moment format='MM/DD/YYYY'>{projects.endDate}</Moment>
)}
</td>
<td>
<strong>Funding Percent: </strong>
<br />
{projects.fundingPercent}
</td>
</tr>
<tr>
<td>
<strong>Contact: </strong>
{firstName} {lastName}
</td>
</tr>
<tr>
<td>
<strong>Start Date: </strong>
<Moment format='MM/DD/YYYY'>
{projects.projectStartDate}
</Moment>
</td>
<td>
<strong>End Date: </strong>
{projects.projectEndDate === null ? (
''
) : (
<Moment format='MM/DD/YYYY'>
{projects.projectEndDate}
</Moment>
)}
</td>
</tr>
<tr>
<td colSpan='5'>
<strong>Goals and Objectives: </strong>
{projects.goalsAndObjectives}
</td>
</tr>
<tr>
<td colSpan='5'>
<strong>Success Description: </strong>
{projects.successDescription}
</td>
</tr>
<tr>
<td>
<strong>Accountable Staff: </strong>
</td>
</tr>
<tr>
<td>
<strong>Project ID: </strong>
{projects.projectId}
</td>
</tr>
</tbody>
</Table>
</div>
)}
<ActivitySummary />
</Fragment>
);
};
export default ProjectScreen;
I have a component, called Bucket, each bucket can have multiple challenges, it looks like this,
The code I have is like this, (much-simplified version)
class CLL_Bucket extends Component {
constructor(props) {
super(props);
this.state = {};
this.state = {
…
bucketChallengesIdx: 0, // to track the index of challegnes
bucketChallenges: this.props.bucket.bucketChallenges || [],
…
};
…
this.onBucketChallengeAdd = this.onBucketChallengeAdd.bind(this);
this.onBucketChallengeIDChanged = this.onBucketChallengeIDChanged.bind(this);
this.onBucketChallengeWeightChanged = this.onBucketChallengeWeightChanged.bind(this);
}
render() {
const bucketIdx = this.props.idx;
return (
<div style={styles.container}>
<div key={bucketIdx} className="row" style={styles.bucketStyle}>
<div className="col-md-2">
…
</div>
<div key={bucketIdx} className="col-md-4">
<div>
<label>
<span className="text-center">Challenges<span>
</label>
<button type="button" className="btn btn-success btn-sm" onClick={() => this.onBucketChallengeAdd()}>Add Challenge</button>
</div>
<table className="table table-bordered table-striped show">
<thead>
<tr>
<th>Challenge ID</th>
<th>Weight</th>
<th>Action</th>
</tr>
</thead>
<tbody>
{this.state.bucketChallenges.map(this.renderBucketChallenges.bind(this))}
</tbody>
</table>
</div>
…
</div>
</div>
);
}
renderBucketChallenges(bucketIdx, idx){
return (
<tr key={idx}>
<td className="col-xs-3 input-group-sm">
<Select
options={challengeIDOptions}
defaultValue={challengeIDOptions[0]}
onChange={this.onBucketChallengeIDChanged.bind(this, idx)}
value={this.state.bucketChallengesID}
isSearchable={true}
/>
</td>
<td className="col-xs-1 input-group-sm">
<input type="text" className="form-control" value={this.state.bucketChallengesWeight}
onChange={(e) => this.onBucketChallengeWeightChanged(idx, e)} disabled={this.props.readOnly}>
</input>
</td>
<td className="col-xs-1 input-group-sm">
…
</td>
<td className="col-xs-1 input-group-sm">
<input className="btn btn-danger btn-sm" id="deleteButton" type="button" value="Delete" onClick={() => this.onDeleteChallenge.bind(this, bucketIdx, idx)} />
</td>
</tr>
);
}
onBucketChallengeAdd(){
var newChallengeIndex = this.state.bucketChallengesIdx + 1;
console.log("onBucketChallengeAdd(): " + newChallengeIndex);
this.setState({bucketChallengesIdx: newChallengeIndex});
this.props.onAddChallenge(this.props.idx, newChallengeIndex);
}
The problem I’m having is, when I click the “Add Challenge” button, I can see from the React developer tool that a new challenge is being added, even though the UI is not updated. When I go to a different tab of my app and come back, the UI is added (a new row for the added challenge is there). Why? Any suggestion on how to fix this? Thanks!
The bigger question is, am I on the right track to make this happen? or i should extract challenge portion to a different component?
i have a problem that i need to add the data from state and loop it using map. in my project im using redux and got the value from redux its self but in the state won't render again after map.
i already tried to using this.props.sendNameProduct in my array of map but when i added the new product the first product updated with the value of last product. i just want it to store the first product and then when im inputting the second product , the first product still there.
class OpenPositions extends Component {
constructor(props) {
super(props);
this.state = {};
}
render() {
console.log(this.props, "ini porpoaspdopa")
console.log(this.props.sendNameProduct, "ini send name")
console.log(this.props.sendNameProduct.sendNameProduct," ini kirik");
let dapetItem = this.props.cobaSend == null ? [] : this.props.cobaSend
let cobaSend = [{qty: '123'}];
let getItem = localStorage.getItem('storage')
let newData =[];
let newDataBaru = [];
let newArr = [];
newArr.push(this.props.cobaSend);
newData = newDataBaru.concat(newArr)
console.log(newArr, "ini new array");
console.log(newData, "ini new Data")
return (
<div style={{height:'100%', overflow:'auto'}}>
<table className="borderline" cellspacing="0" cellpadding="0" border="0" style={{height:'100%'}}>
<tbody>
<tr>
<td>
<div>
<div>
<table style={{height:"100%", width:"100%"}}>
<tbody>
<tr align="center" className="fieldtitle fieldbg">
<td align="left">Items</td>
<td>Qty</td>
<td>Sold</td>
<td>Bought</td>
<td>Avail</td>
<td>Date</td>
<td>Options</td>
</tr>
</tbody>
<tbody className="divOP2">
{this.props.cobaSend.map((item, index) =>{
console.log(item, "ini item bois");
console.log(index, "ini index")
return(
<tr align="center" className="contentbg">
<td align="left" nowrap className="bggradientleft" style={{backgroundImage: ' url(https://demo.sgberjangka.com/images/background_gradientleft.gif)', backgroundRepeat: 'repeat-y', backgroundRepeatX: 'repeat', boxSizing: "border-box", border: "1px solid black", backgroundSize:"100%"}}><font color="#FFFFFF"><strong>{item.product}</strong></font></td>
<td>{item.qty}</td>
<td>{item.sell}</td>
<td>{item.buy}</td>
<td>{item.avail}</td>
<td>{item.date}</td>
<td>
<input
className="checkbox"
type="checkbox"
checked={this.state.isChecked}
onChange={this.handleCheckBox}
/>
</td>
</tr>
)})}
</tbody>
</table>
</div>
</div>
</td>
</tr>
<table className="normal" cellspacing="0" cellpadding="0" border="0" style={{height:'100%'}}>
<tbody>
<tr>
<td>
<button type="submit" className="normalButton wide">GTC Order (Liq)</button>
</td>
<td>
<button type="submit" className="normalButton wide">Buy/Sell (Liq)</button>
</td>
</tr>
</tbody>
</table>
</tbody>
</table>
</div>
)
}
};
function stateProps(state){
console.log(state.main.sendNameProduct, "ini send Name Product")
console.log(state.main.sendValueSell, "ini send sell Product")
console.log(state.main.sendValueBuy, "ini send buy Product")
console.log(state.main.sendQuantity, "ini send qty Product")
return {
sendNameProduct : state.main,
sendValueSell : state.main,
sendValueBuy : state.main,
sendQuantity : state.main
};
};
function dispatchProps(dispatch){
return {
}
}
export default connect(
stateProps,
dispatchProps
)(OpenPositions);
the result its when im updating with new data the first one changed and got same values with new data.
lets assume with this.props.cobaSend got the objects like {product: "HKK50_BBJ", qty: "12", sell: "28579", buy: "--", avail: "12", …}, in mapping got the value product, qty ,sell ,and etc. but when im inserting the new data the value in map not updateing with the new array.
Your newData.map loop on the newData array, but display this.props.sendNameProduct... values in your DOM.
Might just be an error on accessing those values, try call the item return by the map callback :
{
newData.map((item, index) =>{
console.log(item, "ini item bois");
console.log(index, "ini index")
return(
<tr align="center" className="contentbg">
<td align="left" nowrap className="bggradientleft"><font color="#FFFFFF"><strong>{item.item}</strong></font></td>
<td>{item.qty}</td>
<td>{item.sell}</td>
<td>{item.buy}</td>
<td>{item.date}</td>
<td>{item.avail}</td>
<td>
<input
className="checkbox"
type="checkbox"
checked={this.state.isChecked}
onChange={this.handleCheckBox}
/>
</td>
</tr>
)
});
}
class OpenPositions extends Component {
constructor(props) {
super(props);
this.state = {
newArr : []
};
}
render() {
console.log(this.props, "ini porpoaspdopa")
console.log(this.props.sendNameProduct, "ini send name")
console.log(this.props.sendNameProduct.sendNameProduct," ini kirik");
console.log(this.props.cobaSend," ini COBA SEND");
// let dapetItem = this.props.cobaSend == null ? [] : this.props.cobaSend
// let cobaSend = [{qty: '123'}];
// let getItem = localStorage.getItem('storage')
let newArr = this.state.newArr;
newArr.push(this.props.cobaSend);
console.log(newArr, "ini new array");
console.log(newData, "ini new Data")
//let newData = [];
//let newDataBaru = newData.concat(data);
//newData.push(data[0])
//console.log(newData, "ini new Data")
//console.log(newDataBaru,"ini data baru")
//newData = newDataBaru.concat(data)
// for(let i =0 ; i< 5; i++){
// }
//console.log(newData, "ini new Data")
return (
<div style={{height:'100%', overflow:'auto'}}>
<table className="borderline" cellspacing="0" cellpadding="0" border="0" style={{height:'100%'}}>
<tbody>
<tr>
<td>
<div>
<div>
<table style={{height:"100%", width:"100%"}}>
<tbody>
<tr align="center" className="fieldtitle fieldbg">
<td align="left">Items</td>
<td>Qty</td>
<td>Sold</td>
<td>Bought</td>
<td>Avail</td>
<td>Date</td>
<td>Options</td>
</tr>
</tbody>
<tbody className="divOP2">
{newArr.map((item, index) =>{
console.log(item, "ini item bois");
console.log(index, "ini index")
return(
<tr align="center" className="contentbg">
<td align="left" nowrap className="bggradientleft" style={{backgroundImage: ' url(https://demo.sgberjangka.com/images/background_gradientleft.gif)', backgroundRepeat: 'repeat-y', backgroundRepeatX: 'repeat', boxSizing: "border-box", border: "1px solid black", backgroundSize:"100%"}}><font color="#FFFFFF"><strong>{item.product}</strong></font></td>
<td>{item.qty}</td>
<td>{item.sell}</td>
<td>{item.buy}</td>
<td>{item.avail}</td>
<td>{item.date}</td>
<td>
<input
className="checkbox"
type="checkbox"
checked={this.state.isChecked}
onChange={this.handleCheckBox}
/>
</td>
</tr>
)})}
</tbody>
</table>
</div>
</div>
</td>
</tr>
<table className="normal" cellspacing="0" cellpadding="0" border="0" style={{height:'100%'}}>
<tbody>
<tr>
<td>
<button type="submit" className="normalButton wide">GTC Order (Liq)</button>
</td>
<td>
<button type="submit" className="normalButton wide">Buy/Sell (Liq)</button>
</td>
</tr>
</tbody>
</table>
</tbody>
</table>
</div>
)
}
};
im using state to store it there and then when im inputting the data its worked.
I have the following angular table with an edit button
<table class="tableData" border="0" cellspacing="0" cellpadding="0">
<thead>
<tr>
<th></th>
<th>Budget Name</th>
<th>Year</th>
<th>Month</th>
<th></th>
</tr>
</thead>
<tbody ng-repeat="(ind,O) in budgetdetails">
<tr ng-class-even="'even'" ng-class-odd="'odd'">
<td class="CX"><span>+</span></td>
<td>{{O.budget.BudgetName}}</td>
<td>{{O.budget.Year}}</td>
<td>{{O.budget.Month}}</td>
<td><input type="button" value="Remove" class="btn btn-primary" data-ng-click='removeRow(O)' />
<input type="button" value="Edit" class="btn btn-primary" data-ng-click='EditRow(O)' /></td>
</tr>
<tr class="sub">
<td></td>
<td colspan="5">
<table class="tableData" border="0" cellspacing="0" cellpadding="0">
<tr>
<th>Category</th>
<th>SubCategory</th>
<th>Amount</th>
</tr>
<tr ng-repeat="(indx,a) in O.budgetdetails" ng-class-even="'even'" ng-class-odd="'odd'">
<td>{{a.Category}}</td>
<td>{{a.Subcategory}}</td>
<td>{{a.Amount| currency}}</td>
</tr>
#* <tr>
<td colspan="2">Total</td>
<td></td>
<td>{{Totals().Amount| currency}}</td>
</tr>*#
</table>
</td>
</tr>
</tbody>
</table>
I want to be able to edit the data when I click on the edit button so far I have been playing with the angular controller and I have this
$scope.EditRow = function (item) {
$scope.budget = item.budget;
$scope.idBudget = item.budget.idBudget;
$scope.BudgetName = item.budget.BudgetName;
$scope.Year = item.budget.Year;
$scope.Month = item.budget.Month;
resp=BDetail.FindBudgetById(item.budget.idBudget);
};
The last line call a json and returns a set of data which I want to send to the page were I create the budgets for editing. Now I am not sure how to send the json to another page and the page that receives it is the View were I create the budgets and it has an IEnumerable editor to repeat the budgets details. Code is as follows
#model BudgetPortalMVC4.Models.budget
#{
ViewBag.Title = "NewBudget";
Layout = "~/Views/Shared/_Layout.cshtml";
}
#Scripts.Render("~/bundles/jquery")
<script src="../../Scripts/jquery.validate.js" type="text/javascript"> </script>
<script src="~/Scripts/jquery.validate.unobtrusive.min.js" type="text/javascript"></script>
<h2>NewBudget</h2>
#using (Html.BeginForm())
{
#Html.ValidationSummary(true)
<div>
<table>
<tr>
<td>
<div class="editor-label">
#Html.LabelFor(model => model.BudgetName)
</div>
<div class="editor-field">
#Html.EditorFor(model => model.BudgetName)
#Html.ValidationMessageFor(model => model.BudgetName)
</div>
</td>
<td>
<div class="editor-label">
#Html.LabelFor(model => model.Year)
</div>
<div>
#Html.DropDownListFor(model => model.Year, BudgetPortalMVC4.Controllers.BudgetController.GetDropDownListForYears())
#Html.ValidationMessageFor(model => model.Year)
</div>
</td>
<td>
<div class="editor-label">
#Html.LabelFor(model => model.Month)
</div>
<div>
#Html.DropDownListFor(model => model.Month, BudgetPortalMVC4.Controllers.BudgetController.GetDropDownListForMonth())
#Html.ValidationMessageFor(model => model.Month)
</div>
</td>
</tr>
</table>
</div>
<div>
<h3>Budget Detail</h3>
<div> <input type="button" id="addbudgetdetail" value="Add row" /></div>
<div id="new-budgetdetail">
#Html.EditorForMany(x => x.budgetdetails)
</div>
<input type="submit" />
</div>
#section Scripts{
<script type="text/jscript">
var url = '#Url.Action("GetSubCategories", "Budget")'; // Do not hard code your url's
$(document).on('change', '.SelectedCategory', function () {
var subCategory = $(this).closest('.item').find('.SelectedSubCategory');
subCategory.empty();
$.getJSON(url, { id: $(this).val() }, function (data) {
if (!data) {
return;
}
subCategory.append($('<option></option>').val('').text('Please select')); // Do not give the option a value!
$.each(data, function (index, item) {
subCategory.append($('<option></option>').val(item.Value).text(item.Text));
});
});
});
$(function () {
$('#addbudgetdetail').on('click', function () {
jQuery.get('#Url.Action("AddBudgetDetail", "Budget")').done(function (html) {
$('#new-budgetdetail').append(html);
$('form').data('validator', null);
$.validator.unobtrusive.parse($('form'));
});
});
$(".deleteRow").on("click", '', function () {
$(this).parents("#budgetRow:first").remove();
return false;
});
});
</script>
}
}
How can I accomplish passing the json data to this view and turning the view into and updating form instead of a create form?