Refresh parent's KoGrid from child form - javascript

On the main page I have a grid
<div data-bind="setGridCell: 12,
component: {
name: 'ko.widget.koGrid',
params: {
id: 'gridId',
lazyLoad: true,
autoPopulate: false,
url : someurl;
}">
</div>
And a child component
<div data-bind="setGridCell: 12,
component: {
name: 'ko.view.report.confirmationWindow',
params: params()
}">
</div>
The child component will open a small window that allows me to change the data inside the grid component (both are linked to web services).
Right now, when I click the "Submit" button on the child component, the data change is sent to the service and update in the database, the child component is also closed.
However, display-wise, the grid still looks exactly the same. I'm new to knockout.js in general so I'm not sure what's the best way to go about refreshing (in-place) the data in the grid so that the user can immediately see the changes.
Thanks in advance!
(everything is inside a .NET C# application)

The easiest way is to pass the observable model to the component and use the params in your components bindings. The only thing to watch out for is when you are inserting a new row to a database and do not have the ID. You have to set the ID when your save is complete leaving the component open until you get a return from your message.

Related

How to update react component props (and rerender) from "outside React"

My application is mixed with vanilla JS and React components, and I have a component that I would like to rerender by changing the props from outside the react component. How would I accomplish this? And maybe I need to be using "state" instead?
This component is only shown when a user clicks a dropdown link in a list of items. Because the list can be quite long, I am trying to be efficient with creating only one component and then changing the props (rerendering) depending on which item in the list if clicked.
This is the code the initially creates the component with references to the "root" and "element"
// Render AdjustDateFormulaComponent
let rootContainer = document.getElementById('rc_dateFormulaComponent');
if (rootContainer) {
this.dataFormulaWidgetRoot = createRoot(rootContainer);
this.dataFormulaWidgetElement = createElement(AdjustDateFormulaComponent, {
id: null,
entityType: 'taskTemplateEntry',
onSave: _this._dateFormulaUpdated, // callback method
});
this.dataFormulaWidgetRoot.render(this.dataFormulaWidgetElement);
}
When item is clicked, rerender by changing props (specifically the "id" field) and show/move in the appropriate dropdown div
_this.$widgetDiv.find('.dueDateAdjustDropdown').on('show.bs.dropdown', function () {
// Change props/rerender here with correct id
this.dataFormulaWidgetElement.props = { id: 124 }; // <--- THIS DOESNT WORK OBVIOUSLY
// When dropdown shown, move react component into dropdown div
$(document.getElementById('rc_dateFormulaComponent'))
.detach()
.appendTo($(this).find('.dropdownContent'));
});
Many thanks in advance.

Unable to render component in a new page on a new route on button click

I am very new to react and just started to build a basic crud application with it. Everything is done besides the update functionality, i got stuck there.I have several bootstrap cards with 2 buttons , delete and update.The data comes from a mysql database and was persisted with hibernate (spring boot on backend).The update button when pressed should pass the id and render a new component(on a different route, guess i need to use Link here) in which a filled form with the respective objects details is presented. Once the user updates the form and clicks submit, he should be redirected to the Cards page. So far i am stuck at the button + Link and rendering the new component phase and for some reason i can't seem to understand how to make it work.This is my code so far
this is my JSX in which i have the Update button which is in the render method of CarList component which has all the cards.
<ReactBootstrap.Card.Body>
<ReactBootstrap.Card.Title>{cars.mark}-{cars.model}</ReactBootstrap.Card.Title>
<ReactBootstrap.Card.Header>Price: {cars.price}</ReactBootstrap.Card.Header>
<br />
<h6>Fabricated: {cars.year}</h6>
<h6>{cars.fuel}</h6>
<ReactBootstrap.Button variant="success" className="cardButtons" id="cardButtonGreen" onClick={() => this.handleClickUpdate(cars.id)}> Update</ReactBootstrap.Button>
<ReactBootstrap.Button variant="danger" className="cardButtons" id="cardButtonRed" onClick={() => this.handleClickDelete(cars.id)}> Delete</ReactBootstrap.Button>
</ReactBootstrap.Card.Body>
</ReactBootstrap.Card>
</div>
}
<br />
</div>
this is my CarList class and the constructor
class CarList extends Component {
constructor(props) {
super(props)
this.state = {
cars: [],
error: "",
deleteError: "",
updateError: "",
updateCarId: null,
buttonWasPressed: false
}
}
here i have the function that is triggered on click.I am sating the state to the id of the object that is in that specific card where the update button is.
handleClickUpdate = (carId) => {
console.log(carId);
this.setState(
{
updateCarId: carId,
buttonWasPressed: true
}
)
}
and lastly i am rendiring the Component MyComp i want to render by passing in the ID.Line is located in component CarList right under where the Card is.
{this.state.buttonWasPressed && <MyComp carId={this.state.updateCarId} />}
What this code gives me so far, is that i am able to set the state as the id, and then use the button to display the component, but it is displayed on the same page, right under the card (where the line of code is also located) instead of displaying it in a new page on a new route.I have tried adding Link,Switch, Route, Router, but i am afraid i am not sure how to use it in this exact context with the button, and it is confusing to me so i was not able to make it work.Can you please help me render "MyComp" on a new page with that id ?
Any help would be greatly appreciated.
what you need is a global store, such as Redux or Mobx. That way you can update the state with relevant data and retrieve them on the new page.
If you need a workaround, you could use history.pushState()
Basically you can push to your location and with it a state.
And on the next page, which is MyComp in this case, you could use history.state to retrieve the pushed data.

How do I update the parent of a nested route when child route is updated?

In my application, it is possible to manage a list of articles. The sequence of operations is:
The list of articles will render on the home page.
Clicking on an article in the list will cause a nested view to appear with the contents of the selected article. When this happens, the article list remains in view, so the user sees the full list of articles on the left and the selected article on the right.
The user can then click an EDIT link, which puts the ArticleView in edit mode.
The user edits the ArticleName and ArticleText and submits the change.
A function in ArticleView handles the submission by making an API call to edit the article on the backend, and then puts the ArticleView back in read only mode.
During this last step, router.push is called to refresh the view. My goal is for the ArticlesView to update so that it includes the new values for the article. However, this is not happening.
Here are some sections of the code:
Routes
{
path: "/articlesview",
name: "ArticlesView",
component: () =>
import(/* webpackChunkName: "articles" */ "../views/Home.vue"),
children: [
{
path: "/articleview/:ArticleID/:edit",
name: "ArticleView",
props: true,
component: () =>
import(/* webpackChunkName: "article" */ "../components/Article.vue")
}
]
}
ArticlesView
<div v-for="Article in Articles" :key="Article.ArticleID">
<router-link :to="{ name: 'ArticleView',
params: {
'ArticleID': Article.ArticleID,
'edit': false
}}"> {{Article.ArticleName}}</router-link>
</div>
ArticleView code that tries to refresh the page
this.$router.push({
name: 'ArticleView',
params: {
'ArticleID': Number(this.Article.ArticleID),
'edit': Boolean(false)
}
I have read through the Vue.js reactivity material on the Vue.js Web site, but I am unable to determine if this is intended behavior or not. As you can see, I did take care to include a key in the v-for of the ArticlesView to help Vue with updating that structure.
How can achieve the desired behavior?

p-tabPanel tab having an issue in rendering ngx-smart-modal when the tabs are added dynamically

Currently, I'm trying to add dynamic tabs which have child component, Within the child component, there are several ngx-smart-modal models. I'm able to create dynamic tabs with a close button on it. The issue arises when there are more than one tabs.
Issue
Instance 1: I'm on the first dynamically created tab and I try to click on the model present in a custom component, Model pops up in the last tab of the dynamically created tab. (With the last component details and not desired component details)
Instance 2: If it has only a single dynamically created a model then it works perfectly fine.
Code
HTML
<p-tabPanel [header]="doc.docName" leftIcon="ui-icon-web-asset" *ngFor="let doc of docProps; let i = index" [selected]="true" (onClose)="closeDocProps(doc)" [closable]="true">
<app-child-component [docId]="doc.docId" ></app-child-component>
</p-tabPanel>
app-child-component has several models present in it.
app-child-component (HTML)
<ngx-smart-modal #myModal identifier="myModal">
<h1>Title</h1>
<p>Some stuff...</p>
<button (click)="myModal.close()">Close</button>
</ngx-smart-modal>
TS (Parent component)
on document click operation in the parent component
this.docProps.push({
docId: document.id,
docName : document.docTitle
});
this.changeDetectorRef.detectChanges();
this.activeIndexNumber = this.docProps.length; // to open up the last tab clicked.
also, I'm changing the tab index number with the change of the tab.
onTabChange(event) {
this.changeDetectorRef.detectChanges();
this.activeIndexNumber = event.index;
}
Is there something that I'm doing wrong? Suggestions are highly welcomed.
stackblitz:
https://stackblitz.com/edit/angular-uy3kf5

React.JS, pass data between components

very new to react. you can say I have not yet started to think like React.
here is the problem:
<div>
<DropDown> </DropDown>
<Panel> </Panel>
</div>
In the dropdown, I select a value. Store it in state, as something as , currentLocation.
Then I go to Panel, hit a button, and I want to open a modal. When i open a modal, I need to pass the currentLocation to that model.
I can pass in arbitrary value to modal, but I cannot figure out a way to get the currently selected item from DropDown.
How do I get the value of the currently selected item to the Panel?
Am I even making sense?
When you call the setState in the dropdown that will force an update of the page.
Then if you call this.state in your component you should have the value you need there.
You should go over the basic tutorials to grasp the react basics.
But it goes like this:
getInitialState: function() {
return {
myVar: ''
//set your variables here
//getInitialState will get called before the component gets mounted
};
},
myCustomFunction: function(newVariable) {
this.setState({
myVar: newVariable
});
},
render: function() {
return (
<div>
<input
onChange={this.myCustomFunction}
/>
<MyCustomComponent myProp={this.state.myVar}/>
//everytime the state changes MyCustomComponent will have that new value as a prop
</div>
);
}
There is a lot of ambiguity in your question but I'll try for the simplest case.
You have a Panel component and a Dropdown component.
You want to the Panel to have access to a value that was set when the Dropdown was used.
Solution: When the Dropdown is actuated, it creates an Action that Stores the selected value.
When the modal button in the Panel is actuated, it creates an Action that requires the DropDownStore. Then it decides what to do based on that value.
The pattern I am loosely describing is known Facebook's Flux architecture which is basically just a more specific application architecture for React applications similar to pub/sub or an event bus.

Categories