Fix selection on <select> box. Fixes #157
This commit is contained in:
parent
03ac95f086
commit
a02ac60c8c
|
|
@ -2,6 +2,7 @@
|
|||
import { getRenderTreeEditPtr, renderTreeEdit, RenderTreeEditPointer, EditType } from './RenderTreeEdit';
|
||||
import { getTreeFramePtr, renderTreeFrame, FrameType, RenderTreeFramePointer } from './RenderTreeFrame';
|
||||
import { platform } from '../Environment';
|
||||
const selectValuePropname = '_blazorSelectValue';
|
||||
let raiseEventMethod: MethodHandle;
|
||||
let renderComponentMethod: MethodHandle;
|
||||
|
||||
|
|
@ -226,8 +227,24 @@ export class BrowserRenderer {
|
|||
if (isCheckbox(element)) {
|
||||
(element as HTMLInputElement).checked = value === 'True';
|
||||
} else {
|
||||
// Note: this doen't handle <select> correctly: https://github.com/aspnet/Blazor/issues/157
|
||||
(element as any).value = value;
|
||||
|
||||
if (element.tagName === 'SELECT') {
|
||||
// <select> is special, in that anything we write to .value will be lost if there
|
||||
// isn't yet a matching <option>. To maintain the expected behavior no matter the
|
||||
// element insertion/update order, preserve the desired value separately so
|
||||
// we can recover it when inserting any matching <option>.
|
||||
element[selectValuePropname] = value;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
case 'OPTION':
|
||||
element.setAttribute('value', value!);
|
||||
// See above for why we have this special handling for <select>/<option>
|
||||
const parentElement = element.parentElement;
|
||||
if (parentElement && (selectValuePropname in parentElement) && parentElement[selectValuePropname] === value) {
|
||||
this.tryApplyValueProperty(parentElement, value);
|
||||
delete parentElement[selectValuePropname];
|
||||
}
|
||||
return true;
|
||||
default:
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ using BasicTestApp;
|
|||
using Microsoft.AspNetCore.Blazor.E2ETest.Infrastructure;
|
||||
using Microsoft.AspNetCore.Blazor.E2ETest.Infrastructure.ServerFixtures;
|
||||
using OpenQA.Selenium;
|
||||
using OpenQA.Selenium.Support.UI;
|
||||
using Xunit;
|
||||
|
||||
namespace Microsoft.AspNetCore.Blazor.E2ETest.Tests
|
||||
|
|
@ -74,5 +75,25 @@ namespace Microsoft.AspNetCore.Blazor.E2ETest.Tests
|
|||
Assert.False(target.Selected);
|
||||
Assert.Equal("False", boundValue.Text);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CanBindSelect()
|
||||
{
|
||||
var target = new SelectElement(Browser.FindElement(By.Id("select-box")));
|
||||
var boundValue = Browser.FindElement(By.Id("select-box-value"));
|
||||
Assert.Equal("Second choice", target.SelectedOption.Text);
|
||||
Assert.Equal("Second", boundValue.Text);
|
||||
|
||||
// Modify target; verify value is updated
|
||||
target.SelectByText("Third choice");
|
||||
Assert.Equal("Third", boundValue.Text);
|
||||
|
||||
// Also verify we can add and select new options atomically
|
||||
// Don't move this into a separate test, because then the previous assertions
|
||||
// would be dependent on test execution order (or would require a full page reload)
|
||||
Browser.FindElement(By.Id("select-box-add-option")).Click();
|
||||
Assert.Equal("Fourth", boundValue.Text);
|
||||
Assert.Equal("Fourth choice", target.SelectedOption.Text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,10 +22,35 @@
|
|||
<span id="checkbox-initially-checked-value">@checkboxInitiallyCheckedValue</span>
|
||||
</p>
|
||||
|
||||
<h2>Select</h2>
|
||||
<p>
|
||||
<select id="select-box" @bind(selectValue)>
|
||||
<option value=@SelectableValue.First>First choice</option>
|
||||
<option value=@SelectableValue.Second>Second choice</option>
|
||||
<option value=@SelectableValue.Third>Third choice</option>
|
||||
@if (includeFourthOption)
|
||||
{
|
||||
<option value=@SelectableValue.Fourth>Fourth choice</option>
|
||||
}
|
||||
</select>
|
||||
<span id="select-box-value">@selectValue</span>
|
||||
<button id="select-box-add-option" @onclick(AddAndSelectNewSelectOption)>Add and select new item</button>
|
||||
</p>
|
||||
|
||||
@functions {
|
||||
string textboxInitiallyBlankValue = null;
|
||||
string textboxInitiallyPopulatedValue = "Hello";
|
||||
|
||||
bool checkboxInitiallyUncheckedValue = false;
|
||||
bool checkboxInitiallyCheckedValue = true;
|
||||
|
||||
bool includeFourthOption = false;
|
||||
enum SelectableValue { First, Second, Third, Fourth }
|
||||
SelectableValue selectValue = SelectableValue.Second;
|
||||
|
||||
void AddAndSelectNewSelectOption()
|
||||
{
|
||||
includeFourthOption = true;
|
||||
selectValue = SelectableValue.Fourth;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue