I have a widget with validation params such as "min" and "max". I want "min" to be set dynamically, because it depends on value contained in another widget.
<input id="test" type="text"
data-dojo-type="dijit/form/NumberTextBox"
name= "elevation"
required="true"
value="3000"
data-dojo-props="constraints:{min:-20000,max:20000,places:0},
invalidMessage:'Invalid elevation.'" />
How can I do something like min: testWidget.getValue()
Thanks.
All you need to do is use the _WidgetBase#set method. Here is the description from Dojo's API documentation:
Set a property on a widget
Sets named properties on a widget which may potentially be handled by a setter in the widget.
For example, if the widget has properties "foo" and "bar" and a method named _setFooAttr(), calling myWidget.set("foo", "Howdy!") would be equivalent to calling widget._setFooAttr("Howdy!") and myWidget.set("bar", 3) would be equivalent to the statement widget.bar = 3;
set() may also be called with a hash of name/value pairs, ex:
So with your widget reference you can simply do:
var elevationInput = dijit.byId("test");
var constraints = {
min: testWidget.getValue(); // or testWidget.get("value")
max: elevationInput.constraints.max
};
elevationInput.set("constraints", constraints);
Related
I want to allow a user to provide a list of one-word attributes without parameter values. For example,
<container row crosscenter wrap spacearound ...>
which results in something like this in container.html
<div [ngClass]="{ 'flexDisplay': true, 'directionRow': isRow, 'directionCol': isCol, 'contentSpaceAround': isSpaceAround}" ...>
What I'm missing is how to set
#Input('row') isRow = false;
to true if 'row' was present in the container line.
Any ideas?
Thanks in advance.
Yogi
This can be handled in ngOnChanges. The value can be assigned either back to input property or to some object that will be passed to ngClass
ngOnChanges(changes: SimpleChanges) {
if ('foo' in changes) {
this.options.foo = true;
}
}
Since there's no way how inputs can become unassigned, there's no reason to provide bindings for them. #Attribute can be used instead:
constructor(#Attribute('foo') public foo: boolean|null) {
this.foo = (foo != null);
}
Using attributes for regular options isn't a good decision, design-wise. This prevents from setting them dynamically. Instead, it is always preferable to accept options input. If all options are supposed to be flags, it can be a string input that will be split and processed in ngOnChanges, like:
<container options="row crosscenter wrap spacearound">
or
<container [options]="'row crosscenter wrap spacearound'">
I think the answer to my question is to create directives for each of the "one-word" tags (attributes) I want to use.
:-)
I'm new to ASP.NET MVC but I haven't been able to find an explanation for this.
My questions is regarding the difference in the value attribute in the generated HTML when I use #HtmlTextBox() vs. #HtmlTextBoxFor().
I can set the initial value for an <input> using #Html.TextBox() like this:
#Html.TextBox("Phone", "Initial Value", htmlAttributes: new { id = "txt_phone" })
The generated HTML is just what you'd expect:
<input id="txt_phone" name="Phone" type="text" value="Initial Value" />
Please notice the generated value attribute above.
Using #HtmlTextBoxFor() is a different. Please note that I have a very simple model in my view. It has a Phone property which is a String.
Here's an attempt at setting an initial value using #Html.TextBoxFor():
#Html.TextBoxFor(x => x.Phone, htmlAttributes: new { id = "txt_phone", value="Initial Value" })
The generated HTML, however, does not reflect the value attribute:
<input id="txt_phone" name="Phone" type="text" value="" />
My first question is, "why did the generated HTML not reflect the 'Initial Value' text in my value attribute?"
As many of you know, the "right way" to set the initial value with #HtmlTextBoxFor() is like this:
#Html.TextBoxFor(x => x.Phone, htmlAttributes: new { id = "txt_phone", Value = "Initial Value" })
But look at the generated HTML:
<input Value="Initial Value" id="txt_phone" name="Phone" type="text" value="" />
As you can see it generates a Value attribute (with a capital V) yet it still generates a value attribute with a lowercase v and an empty string!.
My second question then, is, why does #Html.TextBoxFor() require a captial V in Value yet still generate a lower-case v, value with an empty string?
Thanks
The answer to "why?" is because this is not the way you're supposed to pass a value. The HTML helpers use a bit of fairly complex logic to determine what the value of a field should be, and because it varies based on a number of different circumstances, your attempt at adding a manual value are largely ignored.
The first place Razor looks for a value is in ModelState, which is composed of the data from Request, ViewData and ViewBag. Then, it looks on the view's Model. Finally, it will fallback to the "default" value, which really only applies with the non-For helpers, where you can specify the value to default to. The reason you can't do the same with the For helpers is because they are bound to an actual property, and therefore, take that property's value, even if it's just the default of null or 0 or something.
Long and short, if you want to bind to a property and have it default to a specific value, then that value needs to be the default for the property. For example:
private string phone;
public string Phone
{
get { return phone ?? "Initial Value"; }
set { phone = value; }
}
Now, the property itself will always return "Initial Value" if it's previously unset, so your form field will as well.
I would like to create a Form in ExtJS 5.0 completely based on a Store. Every store item represents a "line in the form". A "line" consists three or more form widgets.
Basically this is a search panel, where you define search conditions. Every condition consits of: FieldName selector, an operator selector, and a widget to write/select a condition operand. For example search for people with:
name starting with Joe (FieldName:name, operator:starting with, widget:textfield)
birtday before 1980.01.01. (FieldName:birthday, operator:before, widget:datepicker)
I get the conditions in JSON, and load them in a Store. I would like to dynamically generate the form based on this store, make modifications in the form, and ask the Store for a new JSON with the modifications (new conditions, etc).
I have problems with the first step: simply generate form widgets based on store content.
How can this be done?
I'm going to assume here that the JSON data represents a variety of dynamic data, and you can't simply use a pre-canned control like a grid, or a fixed form.
What you need to do is to make your own container class, which dynamically creates widgets based on the JSON content. You'll have to write this yourself, of course.
One extreme is to make your JSON content in the store be valid arguments to, say, Ext.widget - but that's probably not feasible, or even desirable.
For a more middling position, use the JSON data to determine, based on conditions, what widgets to add.
As a rough outline, you want something like this:
Ext.define('MyFormContainer', {
extend: 'Ext.form.FormPanel',
config: {
// A store or MixedCollection of JSON data objects, keyable by id.
formData: null
},
layout: 'vbox',
initComponent: function() {
this.callParent(arguments);
this.getFormData().each(this.addField, this)
},
addField: function(fieldData) {
var widgetConfig = this.buildWidgetConfig(fieldData);
this.add(widgetConfig);
},
buildWidgetConfig: function(fieldData) {
// The heart of the factory. You need a way to determine what sort of widget to make for
// the field. For the example config, a fieldset with three fields would probably be
// appropriate:
var fieldSet = { xtype: 'fieldset', layout: 'hbox' };
var items = [];
items[0] = { xtype: 'textfield', name: fieldData['FieldName'] };
// this would be a link to a custom widget to handle the operator. Or maybe you could
// just spit out text, if it's not meant to be alterable.
items[1] = { xtype: 'myoperator_' + fieldData['operator'], name: 'operator' };
items[2] = { xtype: fieldData['widget'], name: 'value' }
fieldSet.items = items;
return fieldSet;
}
})
This is a simple and contrived example, but it should (after you fill in the blanks, such as missing requires and the custom operator widgets) render a form based on the JSON data.
(I personally use this approach - with a great deal more sophistication that I can show in a simple example - to generate dynamic forms based on server-supplied form descriptions)
I'd like to define a new mapping annotation. For instance, wouldn't it be nice if #NgAttr added the mustache (the braces {{ and }}) automatically if the attribute looks like a controller value? So that it doesn't matter whether I write
<pui-input pattern="{{ctrl.pattern}}" ng-model="ctrl.value">
or
<pui-input pattern="ctrl.pattern" ng-model="ctrl.value">
Is it possible to add a custom mapping to AngularDart? My first approach was to simply derive from NgAttr, but it doesn't work because annotations must not contain methods in Dart:
/**
* When applied as an annotation on a directive field specifies that
* the field is to be mapped to DOM attribute with the provided [attrName].
* The value of the attribute to be treated as a string, equivalent
* to `#` specification.
* If the value of the attribute looks like a property of a controller, it
* is surrounded by a mustache ({{ }}) if it is missing.
*/
class PuiAttr extends AttrFieldAnnotation {
final mappingSpec = '#';
const PuiAttr(String attrName) : super(attrName);
String get attrName => addMustache(super.attrName);
String addMustache(String attrName)
{
if (attrName.indexOf("{{") == 0) // Todo: find a nice regexp
if (attrName.indexOf("\.")>0)
return "{{$attrName}}";
return attrName;
}
}
Please note the mustaches are only an example. My question is whether it's possible to add custom mappings to the standard set #NgAttr, #NgOneWay, #NgTwoWay, #NgOneWayOneTime and #NgCallback.
Any ideas or suggestions?
I'm passing parameters to a server from a Flash Builder application. I want to search both for "teachers" and for "rooms". I can do this via an HTML page, as follows:
<input type="checkbox" name="searchFor" value="teachers" />teachers
<input type="checkbox" name="searchFor" value="rooms" />rooms
So there are two inputs, both named searchFor. When submitted, the request looks like this:
searchFor: teachers
searchFor: rooms
In other words, two parameters are passed.
I'm trying to do the same thing in Flash Builder using an object called param:
param.query = pQuery;
param.searchFor = "teachers";
param.searchFor = "rooms";
searchUsersService(param);
Flex overwrites the one with the other, as I suspected it would, so all that is submitted is "rooms". Is it possible to pass two parameters with the same name? (or do I need to ask the server guys to rename their search parameters?)
Thanks.
You can't. It will only override the previous value:
param.query = pQuery;
param.searchFor = "teachers";
param.searchFor = "rooms"; //Will obviously override the previous value
searchUsersService(param);
What you can do is:
param.searchFor = [ "teachers", "rooms" ];
Or
param.searchFor = new ArrayCollection();
param.searchFor.add( "teachers" );
param.searchFor.add( "rooms" );
And then in the server side you can get all the values from your array.