I want to use a select HTML element to filter items in a table. For that I have a model value selectedCategoryId and event callback onFilterCategory for the change event. But when callback gets called the value selectedCategoryId is null.
I have the following HTML snippet:
<select id="category"
class="form-control"
[(ngModel)]="selectedCategoryId"
(change)="onFilterCategory()">
<option *ngFor="let category of categories"
value="{{category.id}}">
{{category.name}}
</option>
</select>
And the following dart snippet:
void onFilterCategory() {
print('onFilterCategory');
print('this.selectedCategoryId: ' + this.selectedCategoryId);
}
Do I need to use another callback?
ngModelChange is the event and $event the value
(ngModelChange)="onFilterCategory($event)"
with
void onFilterCategory(String value) {
Because you have 2-way binding
[(ngModel)]="selectedCategoryId"
you can also use
(ngModelChange)="onFilterCategory()"
with the onFilterCategory() as it is in your question.
The change event doesn't work because it fires too early - before [(ngModel)]="selectedCategoryId" was able to update selectedCategoryId.
Related
I have a datalist with some options and I want to select the first one using Cypress. How do I do that?
I need to click on the option, simply typing in the value is not what I want, because when an option is selected, a Javascrip function is called. So it's more like How do I click on a datalist option using Cypress?
cy.get('#foods').first().click({force:true})
Does not work.
Presuming the Ruby datalist is like this
<datalist id="foods">
<% Foods.all.each do |food| %>
<option value="<%= food.name %>"></option>
<% end %>
</datalist>
gives this in the DOM
<datalist id="foods">
<option value="Lamb">
<option value="Beef">
<option value="Fruit">
</datalist>
You can get the first option with
cy.get('#foods') // gets the outer datalist
.find('option') // returns all options inside
.first() // take the first
.click({force:true})
for other option, e.g 3rd
cy.get('#foods') // gets the outer datalist
.find('option') // returns all options inside
.eq(2) // take the third
.click({force:true})
The {force:true} is only required because the list is not opened.
It may be better to open it first and click without force, as a page error can be masked by using {force:true}.
cy.get('#foods') // gets the outer datalist
.invoke('show') // open list
.should('be.visible')
.find('option') // returns all options inside
.first() // take the first
.click()
I'm trying to figure out how to pass event parameters from a component back to my class handling the event.
In my case, I'm trying to register a "KeyPressed" event in a component, like so:
<textarea ng-keypress="cmp.KeyPressed(event)" rows="1" cols="100"></textarea>
And the code handling the event looks like this:
void KeyPressed(event) {
print("keypressed!");
}
Whenever a key is pressed, the KeyPressed() function fires. However, the "event" being passed in is null. How do I pass in event parameters correctly, and what is the event type?
You need to use $event
<textarea ng-keypress="cmp.KeyPressed($event)" rows="1" cols="100"></textarea>
How can I change value of combobox using Tchromium Delphi?
Version Tchromimum DCEF3
<td class="droplabels" nowrap="nowrap">Лист</td>
<td colspan="3">
<div class="ui-widget">
<select id="sheet" name="sheet" style="font-size:0.7em;width:761px;"
class="form_select" onchange="showSheet(this.value);">
<option value="1" selected="selected">Account List </option>
<option value="2">Merchant list</option>
</select>
</div>
</td>
try this but not worked...
Chromium1.Browser.MainFrame.ExecuteJavaScript('document.getElementById("sheet").selectedIndex=2;', 'about: blank', 0);
Chromium1.Browser.MainFrame.ExecuteJavaScript('document.getElementById("providerField").onchange();', 'about: blank', 0);
There's an ExecuteJavascript on it. So you can manipulate everything on it with Javascript.
If you want to change that combobox value , then change it with using DOM.Get its id using "document.getElementById", then change its selectedIndex by accessing its selectedIndex.
But , that'll not triggering onChange event.
So , you need to call it manually using javascript again.
Here's the code to change it's selectedIndex :
Chromium1.Browser.MainFrame.ExecuteJavaScript('document.getElementById("sheet").selectedIndex='+comboboxIndex+';', 'about: blank', 0);
To trigger onChange event manually :
Chromium1.Browser.MainFrame.ExecuteJavaScript('document.getElementById("providerField").onchange();', 'about: blank', 0);
Change Chromium1 to your TChromium variable object name.
Here's for more information about Select
http://www.w3schools.com/jsref/dom_obj_select.asp
If you don't know anything about DOM , read it here
http://www.w3schools.com/htmldom/default.asp
In simple way , you just need to get the DOM object of it then do what you want by accessing and modifying its properties
Sorry for my bad English.
edited
I am creating a Jira plugin which provides a version tab panel. In the velocity of this version tab panel i am providing a select list . the code of select list is as below
<form name="input" action="AddParent" method="post">
<select name="parentVersion">
<option value="-1">--select Parent--</option>
#foreach($version in $versions )
<option value="$version" selected="true">$version</option>
<input type="submit" value="Add Parent"/>
</form>
Now in my plugin i have included a webwork module to handle this action . when i click the "Add Parent" button nothing is happening. I need the value which i have selected in my java action class . I am surely missing something . can someone please help me with this ?
Thanks in advance .
As an alternative, you can declare a local variable named same as your select list, create getter and setter and the variable will get the selected value.
Also, yo can specify the form action as action="YourClass!yourMethod.jspa"
private String parentVersion;
public String getParentVersion() {
return parentVersion;
}
public void setParentVersion(String parentVersion) {
this.parentVersion = parentVersion;
}
I'm not sure what's missing in your code, but the WebWork Sample Plugin has more information about this.
I'm just now starting to learn ASP.NET MVC. How would I go about creating a reusable tri-state checbox? In WebForms this would be a control, but I don't know the MVC equivalent.
Add a TriStateCheckBox (or TriStateCheckBoxFor if you use the strongly typed overloads) extension method to HtmlHelper and add the namespace of that extension method class to the namespaces section of your web.config.
As for the implementation, I'd recommend having at look at the InputExtensions source on codeplex and using that to create your own.
Limitations:
View Rendering - When rendering HTML content, there is no attribute you can possibly place on an <input type="checkbox" /> that will give it the property indeterminate.
At some point, you'll have to use JavaScript to grab the element and set the indeterminate property:
// vanilla js
document.getElementById("myChk").indeterminate = true;
// jQuery
$("#myCheck).prop("indeterminate", true);
Form Data - model binding will always be limited to what values are actually sent in the request, either from the url or the data payload (on a POST).
In this simplified example, both unchecked and indeterminate checkboxes are treated identically:
And you can confirm that for yourself in this Stack Snippet:
label {
display: block;
margin-bottom: 3px;
}
<form action="#" method="post">
<label >
<input type="checkbox" name="chkEmpty">
Checkbox
</label>
<label >
<input type="checkbox" name="chkChecked" checked>
Checkbox with Checked
</label>
<label >
<input type="checkbox" name="chkIndeterminate" id="chkIndeterminate">
<script> document.getElementById("chkIndeterminate").indeterminate = true; </script>
Checkbox with Indeterminate
</label>
<label >
<input name="RegularBool" type="checkbox" value="true">
<input name="RegularBool" type="hidden" value="false">
RegularBool
</label>
<input type="submit" value="submit"/>
</form>
Model Binding - Further, model binding will only occur on properties that are actually sent. This actually poses a problem even for regular checkboxes, since they won't post a value when unchecked. Value types do always have a default value, however, if that's the only property in your model, MVC won't new up an entire class if it doesn't see any properties.
ASP.NET solves this problem by emitting two inputs per checkbox:
Note: The hidden input guarantees that a 'false' value will be sent even when the checkbox is not checked. When the checkbox is checked, HTTP is allowed to submit multiple values with the same name, but ASP.NET MVC will only take the first instance, so it will return true like we'd expect.
Render Only Solution
We can render a checkbox for a nullable boolean, however this really only works to guarantee a bool by converting null → false when rendering. It is still difficult to share the indeterminate state across server and client. If you don't need to ever post back indeterminate, this is probably the cleanest / easiest implementation.
Roundtrip Solution
As there are serious limitations to using a HTML checkbox to capture and post all 3 visible states, let's separate out the view of the control (checkbox) with the tri-state values that we want to persist, and then keep them synchronized via JavsScript. Since we already need JS anyway, this isn't really increasing our dependency chain.
Start with an Enum that will hold our value:
/// <summary> Specifies the state of a control, such as a check box, that can be checked, unchecked, or set to an indeterminate state.</summary>
/// <remarks> Adapted from System.Windows.Forms.CheckState, but duplicated to remove dependency on Forms.dll</remarks>
public enum CheckState
{
Checked,
Indeterminate,
Unchecked
}
Then add the following property to your Model instead of a boolean:
public CheckState OpenTasks { get; set; }
Then create an EditorTemplate for the property that will render the actual property we want to persist inside of a hidden input PLUS a checkbox control that we'll use to update that property
Views/Shared/EditorTemplates/CheckState.cshtml:
#model CheckState
#Html.HiddenFor(model => model, new { #class = "tri-state-hidden" })
#Html.CheckBox(name: "",
isChecked: (Model == CheckState.Checked),
htmlAttributes: new { #class = "tri-state-box" })
Note: We're using the same hack as ASP.NET MVC to submit two fields with the same name, and placing the HiddenFor value that we want to persist first so it wins. This just makes it easy to traverse the DOM and find the corresponding value, but you could use different names to prevent any possible overlap.
Then, in your view, you can render both the property + checkbox using the editor template the same way you would have used a checkbox, since it renders both. So just add this to your view:
#Html.EditorFor(model => model.OpenTasks)
The finally piece is to keep them synchronized via JavaScript on load and whenever the checkbox changes like this:
// on load, set indeterminate
$(".tri-state-hidden").each(function() {
var isIndeterminate = this.value === "#CheckState.Indeterminate";
if (isIndeterminate) {
var $box = $(".tri-state-box[name='" + this.name + "'][type='checkbox']");
$box.prop("indeterminate", true);
}
});
// on change, keep synchronized
$(".tri-state-box").change(function () {
var newValue = this.indeterminate ? "#CheckState.Indeterminate"
: this.checked ? "#CheckState.Checked"
: "#CheckState.Unchecked";
var $hidden = $(".tri-state-hidden[name='" + this.name + "'][type='hidden']");
$hidden.val(newValue);
});
Then you can use however you'd like in your business model. For example, if you wanted to map to a nullable boolean, you could use the CheckState property as a backing value and expose/modify via getters/setters in a bool? like this:
public bool? OpenTasksBool
{
get
{
if (OpenTasks == CheckState.Indeterminate) return null;
return OpenTasks == CheckState.Checked;
}
set
{
switch (value)
{
case null: OpenTasks = CheckState.Indeterminate; break;
case true: OpenTasks = CheckState.Checked; break;
case false: OpenTasks = CheckState.Unchecked; break;
}
}
}
Alternative Solution
Also, depending on your domain model, you could just use Yes, No, ⁿ/ₐ radio buttons
ASP.NET MVC certainly doesn't provide such component, actually it simply relies on the standard elements available in HTML but you may want to check out this solution.