Dynamically inserted React Components - javascript

I'm building a WYSIWYG tool in React/flux where you build interfaces by dragging and dropping elements onto a page. So for instance, I have a list of droppable elements: List, Form, Input Box, Text Box, etc. When the user drops one of those elements on the page, I need to insert the associated react component (and I store a name property of the object they drop, so I will know the component name I need). So if a user drops a list onto the page, and my associated component tag is <list />, I can't do just <{component.name} /> and it will turn it into <list />...yet I need a method of doing so. Any thoughts?

So fiddling around with this, I ended up getting it to work like this:
var Sort = require('./sort')
var List = require(./list')
var allComponents = {
sort: Sort,
list: List
}
React.createElement(allComponents[component.componentName], {data:component.data})
so now if my component.componentName is list, it will render the component, and data will become my properties

Related

how can I Re-position after editing a table value in React?

There is an UI I have created using React. There are two text fields to enter value, after entering and saving those values will be populated in a table below the two fields(we are using antd for designing).
However when I click a single record in the table and click edit in that particular record data from that record will be populated to the above mentioned text fields. When this happens I want my app to scroll up and show those two text fields which are ready to be edited.
But currently it stays at the same position after clicked edit, without scrolling up and showing two text fields. Here's an image descripting my experience
Check this answer to find how to control srollTop: https://stackoverflow.com/a/55184755/2360631
But I don't think it's a good idea, maybe you can consider to freeze the edit area otherwise when you finish edit you may need to scroll back again...
Basically you want to set focus to some component after a re-render.
To refer to a particular component, use react refs
make a react ref of whatever you want to set focus to and assign it as a ref prop
constructor() {
super();
this.foo = React.createRef();
}
componentDidUpdate() {
this.foo.current.focus();
}
<Bar ref={this.foo}> .... </Bar>
foo is the name of ref
Bar is the component you want to set focus to
in your case it can be a parent of both input fields or any one of the input fields

Is there an elegant way with React-Router to clear the current component's rendered data, when one of its routes are matched?

I have a component called PastIssues, which lists all of the past editions of a magazine. The output of the component is an ordered list where each item is the year of release followed by the season. For example:
Spring:2014
Autumn:2015
Each of these items is a Link that points to a specific path. I've dynamically added to this component, such that my ShowArticleInfo component will be displayed. My issue lies, when the user clicks one of the Links, my ShowArticleInfo component gets rendered, but only below ordered list. I would like my ordered list to disappear, such that the only remaining component is ShowArticleInfo.
So before the user clicks anything, I want a list of links, one for each article (in the example above). After a user clicks one of them, I want the list to disappear and only ShowArticleInfo to appear.
Is there an elegant way to do this?
Use local storage to set a key with value true
componentDidMount(){
localStorage.setItem('loaded','true');
}
and clear local storage when u unmount component ShowArticleInfo.
In your ordered list component render.
render(){
let loaded = localStorage.getItem('loaded');
return(
<div style={{display:{loaded ==='true' ? 'none':'block'}}>
</div>
)
}
For further info on localstorage MDN/localstorage.

The last created element isn't the one I dropped

I have to do a drag and drop program so i use Vue.Draggable but when i drop my element into the second list the last created element on that list isn't the one i dropped but the one who had the value replaced.
So for instance if i have a drop array like that:
var a = [
{
name: 'element1'
},
{
name: 'element2'
},
...
]
and I drop an element before the first element of the second list, the last created element will be 'element1' and I need my program to make the last created element the one droped
I don't know how Vue.Draggable does that but when I had programmatically
an element somewhere in the second list like so secondList.splice(3, 0, newElement) the last created element is the one i want (newElement)
Here's the code from the first list:
<draggable v-model="blocks" :clone="clone" :options="draggableOptions" #end="reGenerateUuid">
<block
v-for="b in blocks"
:key="b.props.uuid"
:title="b.title"
:image="b.image"
#click.native="addBlock(blocks[key])" />
</draggable>
the second list is a rendered component so I can't share it because it's massive.
The second list doesn't use v-model with the draggable component but the list prop, because from what I understood I can't put a v-model on a rendered element in VueJS.
The elements draggable on the second list doesn't have the key prop because I don't want them to regenerate.
Maybe I need to specify how draggable should add the element to the second list?
Does anyone have an idea?
The elements draggable on the second list doesn't have the key prop
because i don't want them to regenerate.
You need the key prop. Otherwise Vue doesn't properly keep track of the order of elements.

Ember. Rerender custom array that is in a component. Selector

I have an Ember app that has a template with several dropdown menus(the dropdown menus are in a component.hbs).
Inside the component.js, there is a custom array (ingredients) that takes objects from the model and filters them depending of the selections.
The problem is that the data doesn't refresh automatically for the following selectors, I have to refresh the website to be able to see the next options.
For example: 2 selectors: "recipies" and "ingredients"
A user selects "meatloaf". The ingredients selector, that would take the data from a custom array in the component, doesn't refresh itself in order to display only the ingredients for meatloaf.
I'm assuming this is happening because the component.hbs (and the ingredientes array)have been rendered and loaded when the user visits the website, but I need to find a way to refresh the ingredients array everytime a user selects a recipe
So, I just figured it out.
It was way more simple than I thought.
In the same action that is triggered when the user selects a recipe, I empty the array for ingredients, and then fill it out with what the ingredients related to the selection.
Define computed property in the component, which will be recalculated whenever selectedRecipe changes.
ingredients:Ember.computed('selectedRecipe', function(){
// do filtering stuff and return the result
return this.get('customArray').filterBy('name',this.get('selectedRecipe'));
})

If I have multiple instances of the same javascript object on a page, how can I select data from a dropdown within a specific one?

So I have a widget that needs to be able to run multiple times within the same webpage. I have a dropdown with a list of names, and an Update button. Using:
updateBtn.onclick = function() {
var selected = document.getElementById("list");
var selectedCompany = selected.options[selected.selectedIndex].text;
getData(selectedCompany);
}
I'm searching the whole webpage for the first instance of the 'list' drop-down box.
How can I search so I find the value of the drop-down within the same instance of the widget instead?
If you attach the event listener to all instances of the button, you can use this to search up the document tree to get your parent container. Since this will reffer to the button you clicked.
Or, attach a unique attribute like data-button="firstOne" data-button="secondOne" if your system allows for that.
Loose example
var selected = this.parentNode.querySelector('#list');
Let me know if I misinterpreted your question in any way.

Categories