I extend angular.dart.tutorial with basic CRUD operations. So in new edit_recipe_component.html I need to add some sort of selection input for recipe categories.
Currently I have
<select ng-model="ctrl.recipe.category">
<option ng-repeat="c in ctrl.categories" value="{{c}}">{{c}}</option></select>
That works perfectly well on the surface: I can select category from the list, selected category is successfully stored in model and so on.
But I get these errors in debug console:
NoSuchMethodError : method not found: 'ngValue'
Receiver: null
Arguments: []
STACKTRACE:
#0 Object.noSuchMethod (dart:core-patch/object_patch.dart:42)
#1 _SingleSelectMode.onModelChange.<anonymous closure> (package:angular/directive/input_select.dart:185:78)
#2 _SelectMode._forEachOption (package:angular/directive/input_select.dart:146:24)
#3 _SingleSelectMode.onModelChange (package:angular/directive/input_select.dart:183:19)
What I'm doing wrong?
Unfortunately APIDOCS to InputSelectDirective has no usage section
Update: I've created github project based on Chapter 6 sample where problem is reproduced
It is here: https://github.com/vadimtsushko/angular_tutorial_chapter_06
Some debugging shows that setting category in Edit form works immediately and successfully (I've added category in Recipes list view for debug purpose).
Error raised when I leave Edit form.
I believe that this issue has been fixed for a while (hence no need for a patch), but in any case, you could also have used ng-value:
<select ng-model="ctrl.recipe.category">
<option ng-repeat="c in ctrl.categories" ng-value="c">{{c}}</option></select>
do a little patch on _SingleSelectMode class in input_select.dart
onModelChange(value) {
var found = false;
_forEachOption((option, i) {
if (option == _unknownOption) return;
if (expando[option] == null ) return;
var selected = value == null ? option == _nullOption : expando[option].ngValue == value;
found = found || selected;
option.selected = selected;
});
Related
We are upgrading from jsf 1.2 to jsf 2.
We are using apache myfaces 2.1 and rich faces 4.3.
We are facing very strange issue with <rich:autocomplete>. Below is the xhtml code.
<rich:autocomplete mode="cachedAjax" minChars="2" autocompleteMethod="#{bean.getData}"
var="result" value="#{bean.inputData}">
<h:column>
<h:outputText value="#{result}" />
</h:column>
</rich:autocomplete>
Following is the scenario , when an input is entered in an autocomplete input box , suggetions are shown - that is bean.getData method is called.
Surprisingly , after any of the suggestion is selected , bean.getData method is called again with chosen option value , which I believe is not the correct behaviour
since user has selected an option and not typed any input.
I don't want the bean.getData method to be called again. Is there any alternative ?
Please help.
EDIT 1
Since I am running a db query to get suggestion values , they are different than the actual input value typed to get suggestions. That is if I type "at" , my sugegstions could be "check me" . I understand that once prefix for search is changed , suggestions are evaluated again , but here i am not changing the prefix but selecting the entire suggestion value.
EDIT 2
Providing the context the issue occured with.
When autoCompleted method is called , it populates a hashMap with all the suggestions with CustomUserObject as the value.
Below is the code for this :
public List<String> getData(FacesContext context, UIComponent component, String input) {
Map<String, CustomUserObject> userMap = new HashMap<String, CustomUserObject>();
//get users from db
List<CustomUserObject> users = bean.fetchUserList(input);
//put users in map
for (CustomUserObject user : users) {
userMap.put(user.id, user) ;
}
List<String> userList = new ArrayList<String>();
//convert the list to List<String>
if(userList != null && !userList.isEmpty()){
//convert the List<CustomUserObject> to List<String>
}
return userList;
}
Now because of the issue mentioned in the question , getData is called again and corrupts userMap.
This map is used to retrieve correct CustomUserObject by comparing it with selected Suggestion like below :
if(userMap != null && !userMap.isEmpty()){
for(CustomUserObject user : userMap.values()){
if(selectedSuggestion != null && selectedSuggestion.equals(user.name)){
//match is found
//set variables to update ui at re-render
}
//no match found
//set variables to update ui at re-render
}
}
EDIT 3
In addition to above issues , it seems that there is no "nothing label" attribute for rich:autocomplete which was present for rich:suggestionBox which comes into picture when there is no result found.
This issue alongwith above issue is really making a difficult job to get this component working same as rich:suggestionBox
I want to select a random HTML select option in my test, however the options are generated dynamically and their IDs aren't necessarily clear at the time of running the test.
I am using page objects and content DSL (actually just defining the form as form { $("form") } as I had issues otherwise), and I know that I can assign a particular ID or text value to the form.dropdown control, but I'm not sure what's the easiest way to obtain a list of all dropdown value IDs (or better yet their mapping to names) for this dropdown.
I've so far tried just to check the type of form.dropdown but it is reported as ArrayList and contains null values so that's not very useful.
I've read through the Geb guide but didn't manage to find a good solution in what I believe is the relevant section:
http://www.gebish.org/manual/current/all.html#setting_values
FWIW I'm using Groovy/Grails with Firefox WebRunner.
This is the way I did it. Having this form:
<form id="myform">
<select name="dropdown">
<option value="a">A</option>
<option value="b">B</option>
<option value="c">C</option>
</select>
</form>
First get the options, for simplicity:
def options = $('#myform select[name="dropdown"] option')
Then, generate a random index this way:
int numOptions = options.size()
int randomIndex = System.currentTimeMillis() % numOptions
Finally, because I haven't yet found how to set the option by index, I set it by value:
String randomValue = options[randomIndex].value()
$('#myform').dropdown = randomValue
Or, to make a long story short,
def options = $('#myform select[name="dropdown"] option')
$('#myform').dropdown = options[(System.currentTimeMillis() % options.size()) as int].value()
We can also reference the SELECT from the OPTION, avoiding unnecessary CSS selections:
def options = $('#myform select[name="dropdown"] option')
options.parent().value( options[(System.currentTimeMillis() % options.size()) as int].value() )
Hope it works.
Not sure if there is a 'gebish' way to do this, but you can get the values and labels using a selector
$('form select[name="dropdown"] option').each {
println it.text() + ' :: ' + it.value()
}
I am working on MVC4 App, and I am stuck at one point, I tried using google to help me, but without success. This might be more simple then I think, but coming from web forms and shifting to mvc is "painful" sometime.
I am trying to loop through the model I have and get the values stored in that model. I tried few approaches but I am getting an error everytime. This is what I have:
var modelAgentFilter = from s in _aa.Agents
where s.COUNTER == Convert.ToInt32(AgentID)
select s;
if (modelAgentFilter != null)
{
ViewBag.FirstName = // Get FirstName object here
}
Thanks in advance for your comments.
Laziale
EDIT:
I did include for loop like this:
if (modelAgentFilter != null)
{
foreach (var property in modelAgentFilter)
{
string test = property.ADDRESS;
}
}
But when the compiler will reach the foreach step I am getting this error: "LINQ to Entities does not recognize the method 'Int32 ToInt32(System.Object)' method, and this method cannot be translated into a store expression."
I can get to the properties of the var model using that foreach look but as soon as the compiler will try to loop the model that error pops up.
Thanks again
LINQ to Entities does not recognize any methods. You can't use even ToString() in LINQ expression. You need first convert your value and than add it in LINQ.
In your example you need to do something like following:
var _agentID = int.Parse(AgentID);
var modelAgentFilter = from s in _aa.Agents
where s.COUNTER == _agentID
select s;
We have an entity with three key fields, one of which is a date (don't ask - its a summary view with no other obvious key).
Breeze is throwing "This key is already attached" error when processing the response from the server after saving changes to the aforementioned entity.
The problem occurs in MergeEntity after saving changes. It seems that the initial lookup fails to find the entity on the client, so it tries to add it again resulting in the error.
Near the top of MergeEntity we find the following line...
var entityKey = EntityKey._fromRawEntity(node, entityType);
...which returns an entityKey._keyInGroup == "1535:::44:::2013-02-28T11:00:00.000Z". Note the third key field which looks like the JSON date string.
Later, when the new entity is (incorrectly) created its entityKey._keyInGroup == "1535:::44:::Fri Mar 01 2013 00:00:00 GMT+1300 (New Zealand Daylight Time)". Now the third field looks like a true javascript date.
The error finally occurs when we hit this line...
attachEntityCore(em, targetEntity, EntityState.Unchanged);
...get the "This key is already attached" error as the entity we've just saved was obviously already in the client cache all along.
Update: My hacks to Breeze to get this working...
1) I changed the _fromRawEntity function to check for dates and convert them properly so we get the same key values that are produced later for the real entity. (This code was copied from the updateEntity function so should behave identically).
ctor._fromRawEntity = function (rawEntity, entityType) {
var keyValues = entityType.keyProperties.map(function (p) {
var val = rawEntity[p.nameOnServer];
if (p.dataType.isDate && val) {
if (!__isDate(val)) {
val = DataType.parseDateFromServer(val);
}
}
return val;
});
return new EntityKey(entityType, keyValues);
};
2) Breeze now found the entity after saving changes but... I then got an error when Breeze tried to update the entities properties using the values returned from the server. I suspect this is due to an issue in the defaultPropertyInterceptor function which was checking to see if the property value had changed...
// exit if no change
if (newValue === oldValue) {
return;
}
This will always return false when comparing dates so I hacked this line to be:
if (newValue === oldValue || (dataType && dataType.isDate && newValue && oldValue && newValue.valueOf() === oldValue.valueOf())) {
return;
}
From my initial testing everything seems to be working but I'd greatly appreciate any thoughts from folks who are more familiar with breeze :)
Updated: Perhaps the last snippet would be more breeze-ish as...
// exit if no change
var comparable = dataType && getComparableFn(dataType);
if (newValue === oldValue || (comparable && comparable(newValue) === comparable(oldValue))) {
return;
}
...although that adds a bit more code considering it is running in every property set.
Edit: This was fixed in Breeze v1.3.0, available now.
Agreed, this is a bug! It will be fixed in the next release, out early next week. ( and we now have a test that involves a date as part of a primary key :)
and thanks for finding, analyzing and reporting it. The analysis really helped.
I have to write tests for a web site. I am trying to get the selected value of a dropdown box. So far i can get the contents of the dropdown by doing
find_field('restrictions__rating_movies').text
returns -
Don't Allow Movies
G
PG
M
R13
R15
R16
R18
R
RP16
Allow All Movies
I can get the value of the selected object.
find_field('restrictions__rating_movies').value
returns -
1000
This does not help me much though because i am trying to get the text of the selected item from a drop down box.
<select class="" id="restrictions__rating_movies" name="restrictions[][rating_movies]">
<option value="0">Don't Allow Movies</option>
<option value="100">G</option>
<option value="200">PG</option>
<option value="300">M</option>
<option value="325">R13</option>
<option value="350">R15</option>
<option value="375">R16</option>
<option value="400">R18</option>
<option value="500">R</option>
<option value="600">RP16</option>
<option value="1000" selected="selected">Allow All Movies</option></select>
in this case shown i need to get the value 'Allow All Movies' I have tried many different combinations of the above two examples.
There's a have_select matcher if you use Capybara with Rspec:
expect(page).to have_select(
'my-select', # locator
selected: 'Option 2' # option
)
Parameters:
Locator (String) (defaults to: nil) — The label, name or id of a select box
Options (Hash) using :selected (String, Array) — Options which should be selected
find_field('restrictions__rating_movies').find('option[selected]').text
Very simple way to get value of selected option is:
find("#restrictions__rating_movies").value
This will return selected select option value.
If you only need to assert if a field is selected with a given option, the straightforward answer is
#Find a select box by (label) name or id and assert the given text is selected
When /^select box "([^"]*)" is selected with "([^"]*)"$/ do |dropdown, selected_text|
assert page.has_select?(dropdown, selected: selected_text)
end
Source: http://rubydoc.info/github/jnicklas/capybara/master/Capybara/Node/Matchers#has_select%3F-instance_method
But the title of your question is "Get select value for dropdown".
And I've run into a similar problem where I would like not only to assert the selection, but also retrieve the text and value of the selected field. I've found no straight way on API. The easiest way I've found was: #all("option").find &:selected?
When /^ select box "([^"]*)" is selected with "([^"]*)"$/ do |dropdown, selected_text|
sb = find_field(dropdown)
sb_selected = sb.all("option").find &:selected?
msg = "Selected: #{sb_selected.text.inspect} - value:#{sb_selected.value.inspect}"
assert page.has_select?(dropdown, selected: selected_text), msg
end
This gives me a more comprehensive error message when the assertion fails.
If there's multiple selections you can use #select in place of #find, as in #all("option").select &:selected?. It will return an Array.
This answer doesn't rely on the 'option[selected]' trick as the previous ones, so it works even if the selection is done by Javascript (which was the reason why the previous answers didn't work for me at all).
Tested on:
capybara (2.2.1)
capybara-webkit (1.1.0)
cucumber (1.3.14)
cucumber-rails (1.4.0)
If you want to find the current selected text, without assuming what it might be so that you can just compare it to an expectation, the following works even if the selection was made by JS (so that there is no 'option[selected]').
First I find the value of the select, then I find the text of the option with that value:
def selected(selector)
value = find(selector).value
text = find(selector).find("option[value='#{value}']").text
end
Create a simple function to return the text given a select element (dropdown):
def get_dropdown_selected_item_text(dropdown)
value = dropdown.value
return dropdown.all(:css, "option").select {|opt| opt.value == value} .first.text
end
Would something like this work?
within("//select[#id='restrictions__rating_movies']") do
find_field("//option[#selected='selected']").text
end