ASP.NET MVC 3 Lambda (=>) Syntax - asp.net-mvc-3

Please, can anyone tell me what the meaning of => operator in Html helper syntax.
Eg: #Html.TextBoxFor(m => m.UserName)

It's not specific to the Razor engine. That is a C# lambda expression.

m => m.Username is equivalent to providing a method, something like
string GetUserName(TypeOfModel m)
{
return m.UserName;
}
However, because TextBoxFor takes an Expression, it is able to 'parse' the lambda and is able to infer that the name of the TextBox input should be 'Name' (viz the property scraped off the model). This is important and 'intuitive', since the MVC ModelBinder will then be able to map "Name" to a property or parameter when it is next sent back to a controller.

Related

How to query data-attribute for a whitespace-separated value in Cypress component tests?

When testing a complex component, I want to assign multiple whitespace-separated values to data-cy attribute, for example
<div data-cy="my-component disabled" />
and use the ~= attribute selector to query for the element:
cy.get('[data-cy~="my-component"]')
Now, having already queried for my-component, how can I further assert that it:
does contain "disabled" in data-cy
does not contain "disabled" in data-cy
in broader sense, does or does not satisfy a css selector?
I know I can explicitly re-query with all parameters for each assertion, eg.:
cy.get('[data-cy~="my-component"]:not([data-cy~="disabled"])').should('exist')
but this feels overly complicated and doesn't read very well - I want to query the element first, and further assert against it in a later step - for example:
cy.get('...').should(el => {
// assert here
})
The approach seems like a good one. If you used individual attributes, likely they would clash with other "native" attributes.
For example if data-cy="disabled" means the "Person" has a disability, but used unwrapped the browser would disable the element.
Ref Using data attributes
data-* attributes allow us to store extra information on standard, semantic HTML elements without other hacks such as non-standard attributes, or extra properties on DOM.
Also some frameworks (React) are fussy about the attributes allowed on an element.
You might be looking for a function to provide the selector for the test.
const asDataCy = (attrs) => {
return attrs.split(' ').map(attr => {
let op = '~'
if (item.charAt(0) === '!') {
op = '!'
attr = attr.slice(1)
}
return `[data-cy${op}="${attr}"]`
).join('')
}
cy.get(asDataCy('my-component !disabled'))
// [data-cy~="my-component"][data-cy!="disabled"])
The Chai-jQuery assertion expect($el).match(selector) does exactly that!
// should form
cy.get('[data-cy~="my-component"]')
.should('match', '[data-cy~="some-value"]')
.should('match', ':not([data-cy~="something-else"])')
// expect form
cy.get('[data-cy~="my-component"]')
.then(el => expect(el).to.match('[data-cy~="some-value"]'))
.then(el => expect(el).to.match(':not([data-cy~="something-else"])'))

Rails mongoid regex on an Integer field

I have some IDs 214001, 214002, 215001, etc...
From a searchbar, I want autocompletion with the ID
"214" should trigger autocompletion for IDs 214001, 214002
Apparently, I can't just do a
scope :by_number, ->(number){
where(:number => /#{number.to_i}/i)
}
with mongoid. Anyone know a working way of matching a mongoid Integer field with a regex ?
This question had some clue, but how can I do this inside Rails ?
EDIT : The context is to be able to find a project by its integer ID or its short description :
scope :by_intitule, ->(regex){
where(:intitule => /#{Regexp.escape(regex)}/i)
}
# TODO : Not working !!!!
scope :by_number, ->(numero){
where(:number => /#{number.to_i}/i)
}
scope :by_name, ->(regex){
any_of([by_number(regex).selector, by_intitule(regex).selector])
}
The MongoDB solution from the linked question would be:
db.models.find({ $where: '/^124/.test(this.number)' })
Things that you hand to find map pretty much one-to-one to Mongoid:
where(:$where => "/^#{numero.to_i}/.test(this.number)")
The to_i call should make string interpolation okay for this limited case.
Keep in mind that this is a pretty horrific thing to do to your database: it can't use indexes, it will scan every single document in the collection, ...
You might be better off using a string field so that you can do normal regex matching. I'm pretty sure MongoDB will be able to use an index if you anchor your regex at the beginning too. If you really need it to be a number inside the database then you could always store it as both an Integer and a String field:
field :number, :type => Integer
field :number_s, :type => String
and then have some hooks to keep :number_s up to date as :number changes. If you did this, your pattern matching scope would look at :number_s. Precomputing and duplicating data like this is pretty common with MongoDB so you shouldn't feel bad about it.
The way to do a $where in mongoid is using Criteria#for_js
Something like this
Model.for_js("new RegExp(number).test(this.int_field)", number: 763)

Is it possible to pass a JavaScript Object as an argument to the Locals Hash in a render: partial call?

I think this is easily explained by looking at code, so I'm posting a couple of snippets that show how I usually do Ajax things in Rails 3.2,
The following will work:
create.js.coffee
$("<%= raw j(render(partial: #comment, locals: { str: 'string' })) %>")
.appendTo("ul#comments")
_comment.html.haml
-puts "The variable's value is #{str}"
%li= comment.what
Now, I'd like to do the same as above, but instead of passing a JS string literal, I'd like to pass an object literal, like this:
create.js.coffee
obj =
'v1': 'value'
'v2': 'value'
$("<%= raw j(render(partial: #comment, locals: { o: obj })) %>")
.appendTo("ul#comments")
Which of course fails with the following reason:
ActionView::Template::Error (undefined local variable or method `obj'...
Does anybody know how to accomplish what I'm trying to do? Is it possible at all?
Let me know if what I'm trying to do is insane, and what would be the proper way if that's the case..
Thanks!
Well I guess clients objects are not shared with server object, unless untill we are doing remoting. So in this case you have to serialize JS object into JSON or any other string format (XML or any other structure) and then you have to de-serialize in Ruby object or you can manually parse the string and use the information provided.

Model Validation to allow only alphabet characters in textbox

How can I annotate my model so I can allow only alphabets like A-Z in my text-box?
I know that I can use regex but can anyone show how to do that on text-box property itself using data annotation.
You could annotate your model like this:
[RegularExpression(#"^[a-zA-Z]+$", ErrorMessage = "Use letters only please")]
string TextBoxData {get; set;}
Then in your view you would use the helper
#Html.EditorFor(model => model.TextBoxData)
#Html.ValidationMessageFor(model => model.TextBoxData )
You can use annotations for regular expression validation (if i understood your questions), something like that
[RegularExpression("[a-zA-Z]",ErrorMessage="only alphabet")]
You could write like this
It matches First character must be an alpha word
and following that matches any number of characters/hyphen/underscore/space
[RegularExpression(#"^[a-zA-Z]+[ a-zA-Z-_]*$", ErrorMessage = "Use Characters only")]

Using a Ternary Conditional with in Asp.Net MVC Razor

I am trying to get the following ternary conditional to work in Asp.Net MVC 3 Razor:
Next
All of the examples I am finding of using a ternary conditional in Razor have return values which are strings. But here I would like to use an expression (Model.PageNumber + 1) and return a number. Is this possible?
Drop the # sign before the value:
Next
Let me just add that in general, Razor doesn't need/want the # prefix unless it's absolutely necessary, for example:
<div>
#foreach(var value in Model.Values)
{
if(value.Flag)
{
<div>#value.Text</div>
}
}
<div>
Notice that you don't need a second # sign until you're actually inside the tag, where Razor wouldn't know whether you wanted to display the text "value.Text" or execute it as code. The if statement is assumed to be code. To escape this and write the line "if(value.Flag)" as text you'd need to explicitly say so with the #: prefix.

Resources