antd Table is not automatically rerendered when datasource data changes - datatable

Ant Design Table is not rerendered automatically when datasource data changes.
<Table
columns={columns}
dataSource={filteredData}
pagination={pagination}
loading={loading}
onChange={this.handleChange} />
filteredData is changed in a method based on a custom filter which is placed outside the table.
Shouldn't the table rerender automatically when filteredData is changed?
Does anybody know how to refresh the table when filteredData is changed?

If you want a Table to re-render automatically, filteredData should be state.
onSourceChange = (something) => {
this.setState({filteredData: something})
}
render(){
return (
<div>
<Table
columns={columns}
dataSource={this.state.filteredData}
pagination={pagination}
loading={loading}
onChange={this.handleChange} />
<button onClick={()=>onSourceChange(['a','b','c'])}>change datasource</button>
</div>
)}

I can imagine that people are still looking for answers specially with the newest version of antd.
So in Antd version 5.x table API, you could find a property call rowKey.
In version 4.0 table API, the property called key thou.
And to way to tackle the problem correctly is to set it like following:
<Table
columns={columns}
dataSource={this.state.filteredData}
rowKey={this.state.filteredData.key}
pagination={pagination}
loading={loading}
onChange={this.handleChange} />
Note: Please consider to have a key property in your array of course. key must be unique.

Related

meteorjs environment, getting element by id return strange value

I'm collaborating in a Meteorjs app, in wich i'm at first tries.
I builded some very simple templates to fit my needs.
In my code it happens that i have to check the value of a input text.
So i setup an event on that text box.
this is the text input:
<input type="text" name="meName" id="mockupName" />
<input type="button" {{buttonDisabled}} id="mockupCreate" value="New Mockup" />
The event check the text value and disable or enable the button. Very straight forward.
this is the event:
'keydown #mockupName': function(e) {
if (e.target.value.trim() == '') {
Session.set('buttonDisabled','disabled');
} else {
Session.set('buttonDisabled','');
}
},
It works just ok.
e.target has a reference to my text input, and value store its value.
Now i referenced this template from another page, in a big template i wrote:
{{#if mockupSelected}}
<input type="button" id="sw_product" value="switch to product view" />
{{> mockupEditor}}
{{else}}
Select product from the left
{{/if}}
And actually when mockupSelected returns true my template appears.
The event is not working anymore.
When the event fire ( and it fires ) i do a console.log(e.target)
Before i was getting: <input#mockupName> a reference to my input.
Now i m getting: Object { __impl4cf1e782hg__: <input#mockupName>, parentNode_: undefined, firstChild_: undefined, lastChild_: undefined, nextSibling_: undefined, previousSibling_: undefined, treeScope_: Object }
An object with a series of properties, one of which contains my reference.
This is the list of meteor packages installed:
meteor-platform
natestrauser:cart
http
iron:router
accounts-base
accounts-password
accounts-ui
alanning:roles
aldeed:autoform
aldeed:collection2
twbs:bootstrap
jeremy:velocity-animate
ajduke:bootstrap-tokenfield
sergeyt:typeahead
standard-app-packages
babrahams:editable-text-wysiwyg-bootstrap-3
differential:vulcanize
dburles:collection-helpers
fortawesome:fontawesome
yogiben:admin
I would like to know how i can access to that text input, considering that i do not know that key and that getElementById is returning me the same object.
I could iterate over all the object properties and testing if one of the values is actually a nodeElement of type text, but i do not think this is a solution.
Can anyone tell me how to get back to the normal behaviour?
I'm guessing here but have you tried:
.html
<input type="text" name="meName" id="mockupName" class="mockupName" />
<input type="button" {{buttonDisabled}} id="mockupCreate" value="New Mockup" />
.js
'keydown .mockupName': function(e) {
if (e.target.value.trim() == '') {
Session.set('buttonDisabled','disabled');
} else {
Session.set('buttonDisabled','');
}
},
either that, or try changing the name of the control (mockupname -> uniqueMockupName). I had strange behaviour once when there were duplicate field names.

object references an unsaved transient instance, Error only when trying to save with empty value

I have an object EvalQuestionType with a one-to-many relationship to another object EvalSelectGroup. I save the relationship in a spring form like so:
<tr>
<th><sf:label path="evalSelectGroup.id">Select Group</sf:label>
<td><sf:select path="evalSelectGroup.id">
<sf:option value="">None</sf:option>
<sf:options items="${selectGroups}" itemLabel="name" itemValue="id" />
</sf:select>
<br />
<sf:errors path="evalSelectGroup.id" cssClass="error" /></td>
</tr>
It works fine if I select an option, but if I try to save with None selected (empty) I get the transient instance error. The value can be null (in the db and my hibernate mapping file). Is there a special way to format empty values in a Spring form select?
Spring 3.2.1
Hibernate 3.6
This may not be the best or right way to do it, but in the controller if I take the EvalQuestionType object passed by the form and set the evalSelectGroup object to null it works fine.
//if none selected in form
if(questionType.getEvalSelectGroup().getId() == null){
questionType.setEvalSelectGroup(null);
}

entity framework telling the context an entity has been updated

I have a scenario where I have an image property that is part of a product entity.
When allowing a user to Edit this product via MVC3 screen, the image property is displayed as follows:
<div class="editor-label">Image</div>
<div class="editor-field">
#if (Model.ProductItem.ImageData == null)
{
#:None
}
else
{
<img alt="Product Image" width="125" height="125"
src="#Url.Action("GetImage", "Product", new { Model.ProductItem.ProductId })" />
}
</div>
<div>Upload new image: <input type="file" name="Image" /></div>
To edit the current image the user essentially selects a new one via the upload. This means that the current ImageData property is null and the model state is invalid. The new image is past back in the post so I set this to the ImageData property and clear the model validation error.
I then save the 'changes' via the context.savechanges() method, however the context doesn't think there are any changes to this particular entity. To get round this I have done the following when on Edit:
if (context.Products.Local.Count() == 0)
{
Product procurr = context.Products
.Where(p => p.ProductId == product.ProductId)
.FirstOrDefault();
context.Entry(procurr).CurrentValues.SetValues(product);
}
Essentially I am forcing an update on the item in the list of products that I want to updqate (procurr is the item in the list and product is the new edited values I want to save)
My questions would be (A) Is this the best way to do this in terms of using the context, and (B) Is there a better way to do this in the UI ie someway of tying together the old and new image so as the model automatically picks up the changes?
Thanks
What you have done looks correct.
The basic idea is that when you get data from the server and return it to the browser, the EF context that you are using gets closed.
When the reply comes back from the browser you need to connect the data with the row that you are trying to update.
Reading the row based on the id, updating the relevant fields and then running save changes, is a good approach.

How do you add fields to com_content in Joomla! with a plugin and store the data in its own table?

I'm running Joomla 1.7 and I know that it has the ability to add custom form fields to components with a plugin.
There is a sample plugin located at:
/plugins/user/profile
This plugin allows you to put custom form fields on the user profile front end and back end and these fields are stored in a custom table.
I created a similar plugin for user profiles and it worked perfectly.
However, when I go to create a plugin like this for com_content, I am met with a problem.
this is what my XML file looks like:
<?xml version="1.0" encoding="utf-8"?>
<form>
<fields name="additionalinfo">
<fieldset name="additionalinfo_fieldset" label="PLG_CONTENT_ADDITIONALINFO_FIELDSET_LABEL">
<field name="tagline" type="text" size="50" default="" label="PLG_CONTENT_ADDITIONALINFO_TAGLINE_LABEL" description="PLG_CONTENT_ADDITIONALINFO_TAGLINE_DESC" />
<field name="pseudocategory" type="category" extension="com_content" label="PLG_CONTENT_ADDITIONALINFO_PSEUDOCATEGORY_FIELD_LABEL" description="PLG_CONTENT_ADDITIONALINFO_PSEUDOCATEGORY_FIELD_DESC" />
</fieldset>
</fields>
</form>
This however does not work, whenever I do something like above, the form fields never show up on the admin form (even though I have it set correctly, and the only thing that changed between the user plugin and the content plugin is the name of the form i'd like the form to appear on
When I change my XML to this:
<?xml version="1.0" encoding="utf-8"?>
<form>
<fields name="attribs">
<fieldset name="additionalinfo_fieldset" label="PLG_CONTENT_ADDITIONALINFO_FIELDSET_LABEL">
<field name="tagline" type="text" size="50" default="" label="PLG_CONTENT_ADDITIONALINFO_TAGLINE_LABEL" description="PLG_CONTENT_ADDITIONALINFO_TAGLINE_DESC" />
<field name="pseudocategory" type="category" extension="com_content" label="PLG_CONTENT_ADDITIONALINFO_PSEUDOCATEGORY_FIELD_LABEL" description="PLG_CONTENT_ADDITIONALINFO_PSEUDOCATEGORY_FIELD_DESC" />
</fieldset>
</fields>
</form>
When I make this simple change, the form fields show up! BUT, the data isn't stored or retrieved from the custom table, it just goes into the 'attribs' column on the _content table. This stores the content in JSON, which is alright, but we'd like to be able to index the content by the custom fields (and not have to loop through each record in the database to find what we're looking for).
Any ideas on how to fix this?
thanks!
david barratt
I guess your plugin file ( for example, "yourplugin.php" ) will have one method called "onContentPrepareForm". If you want to add data to an article, this method should start like this:
function onContentPrepareForm($form, $data)
{
if (!($form instanceof JForm))
{
$this->_subject->setError('JERROR_NOT_A_FORM');
return false;
}
// Check we're manipulating an
if ( $form->getName() != "com_content.article" ) {
return true;
}
//[...] The rest of your code here
Besides, if you want to store these fields in another table in order to make it easier to search using this fields, maybe you should create a new table and save the data using the "onContentAfterSave" method:
public function onContentAfterSave( $context, &$article, $isNew )
On this method, you should always check that $context is "com_content.article", otherwise you might face problems when saving categories.
I hope it helps!

ASP.Net MVC3 Parent Child Model Binding

I have a partial template that uses a User object as a model. The user has a collection of Accounts. On this partial template I have a loop as follows. The _Account partial template is bound to the Account class
#foreach (var item in Model.Accounts)
{
<tr>
<td colspan="6">
<div>
#Html.Partial("_Account", item)
</div>
</td>
</tr>
}
In my controller method I initially tried
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult UserDetails(User user, string actionType)
But the User.Accounts collection is empty. Then I tried this. Still the Accounts collection is empty.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult UserDetails(User user,
[Bind(Prefix="User.Accounts")]
FixupCollection<Account> Accounts,
string actionType)
Can I use the default Modelbinder implementation to achieve this or do I need to do anything different?
Yep, you can use the default model binder. You just need to name your fields correctly. So you need your loop to output something like this:
...
<input type="text" name="user.Accounts[0].SomeTextField" />
<input type="text" name="user.Accounts[0].SomeOtherTextField" />
...
<input type="text" name="user.Accounts[1].SomeTextField" />
<input type="text" name="user.Accounts[1].SomeOtherTextField" />
...
If you need to add/remove accounts, the hardcoded indexes get a little trickier. You could re-assign the names using javascript before postback. But it's all possible. This question gives more detail on model binding:
ASP.NET MVC: Binding a Complex Type to a Select
Use Editor Templates instead of a partial view - no need to hard code your indexes as the template will automagically index all your objects correctly, even when you add and remove Accounts. See my answer to this question:
Pass values from multiple partial views
Small write up on Editor Templates here:
codenodes.wordpress.com - MVC3 Editor Templates

Resources