-
Notifications
You must be signed in to change notification settings - Fork 55
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix: #127 - generate unique ID upon creation #128
Conversation
@@ -109,6 +109,7 @@ public function editablesegment() | |||
} | |||
if (class_exists($className) && is_subclass_of($className, 'Widget')) { | |||
$obj = new $className(); | |||
$obj->write();// generate new id |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you move the comment above the line? The indentation on this also needs to be fixed up to match the rest of the code style
Thanks for the feedback, I'll have to get into the habit of using spaces instead of tabs! |
I'd be happy to merge this as it seems like a reasonable fix, but there is also a lot of handling for "new-" components already in place. If we make this change we should remove the "new-" handling from the code base and rely on the fact we always have an instantiated object. However I feel like it might be better to not save these at this point and instead change the way we handle the IDs for the interior elements so that they reflect the "new" state. @dhensby any thoughts here? |
@stevie-mayhew it looks like there's some JavaScript that uses maxid to work out the next id of the widget by referencing "new-". This could be dangerous as if two people create a widget at the same. I'll try and figure out what this javascript does |
From what I can tell WidgetAreaEditor.js checks if it's a new element and replaces the ID of what it thinks it is going to be. Though pretty poorly given #127 creates incorrect IDs for textareas. The JavaScript doesn't break with the code given that there's no new elements, though it can be tidied up by removing the references of "new-":
Let me know if you want me to put this in the PR |
If nobody else has any objections I'm going to merge this later today. |
The risk here is if validation is on for the object and that fails, then no one can ever start creating a widget again... |
@dhensby I've added a validation check before writing the dataobject. I guess there would be some people who don't want a blank DataObject written for validation purposes, but note this would enable duplicate IDs if the CMS author creates two or more objects that can't be blank. |
this feels so nasty... @tractorcow any thoughts? NB: this is why using increment-ing DB IDs is not a good idea for models :( |
A tidier solution would be to throw an exception if the blank object is invalid. This would prevent duplicate IDs and force the developer to use widgets that can't be blank. Thoughts? |
The trouble is an empty widget perhaps isn't valid... thus it could become impossible to create a valid widget in any context. Have you explored perhaps dis-entangling HTML form ID from the dataobject ID? Why does it need to be that field, rather than say an automatically generated That way it can exist (and be stored in a hidden field) prior to being written to the database. |
In Widget::CMSEditor() you can do something like // ...
$this->FormID = $this->FormID ?: uniqid();
$outputFields->push(new HiddenField('Widget[' + $this->FormID + '][FormID]', $this->FormID));
foreach ($fields as $field) {
// ...
$name = preg_replace("/([A-Za-z0-9\-_]+)/", "Widget[" . $this->FormID . "][\\1]", $name);
// ...
} |
@@ -109,6 +109,10 @@ public function editablesegment() | |||
} | |||
if (class_exists($className) && is_subclass_of($className, 'Widget')) { | |||
$obj = new $className(); | |||
// generate new id | |||
if(method_exists($obj, 'doValidate') && $obj->doValidate()->valid()) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Redundant check in any case... DataObject observably has a doValidate method :)
@tractorcow thanks, I've made a patch to do something similar to what you've suggested. Works as expected in MSIE, FFx and Chrome. |
How necessary is the ->write() that you've added? We still have the problem of writing invalid records before they are populated with content. E.g. widgets that fail validation if Title is empty. |
@tractorcow sweet - I didn't reset the patch before committing. ops. |
Great, please can you squash the commits and check the indentation around |
Fixes front end components that require a unique ID. Duplicate IDs in the DOM is invalid HTML. Fix: silverstripe#127 - code formatting Check validation before writing BUG fixes duplicate ID issue Fixes silverstripe#127 BUG fixes duplicate ID issue Fixes silverstripe#127 remove unneeded write() Fix: silverstripe#127 - generate unique ID upon creation
@dhensby sweet, rebase has been completed and works as expected |
thanks |
Good job @torleif |
Fixes front end components that require a unique ID. Duplicate IDs in the DOM is invalid HTML.