I'm making an App using NativeScript with Angular. There is a page that has two labels that need to act as dropdown select boxes. They are set to show a listPicker.
A sample of the HTML
<StackLayout orientation="horizontal" class="field_row">
<Label text="Type:" class="field_label"></Label>
<Label text="{{ job_type }}" (tap)="showList('type')" class="type job_field dd-label"></Label>
</StackLayout>
<StackLayout orientation="horizontal" class="field_row">
<Label text="Category:" class="field_label"></Label>
<Label text="{{ job_category }}" (tap)="showList('category')" class="category job_field dd-label"></Label>
</StackLayout>
<StackLayout orientation="horizontal" class="field_row" [visibility]="assignActive ? 'visible' : 'collapse'">
<Label text="Assigned:" class="field_label"></Label>
<Label text="{{ job_worker }}" (tap)="showList('workers')" class="workers job_field dd-label"></Label>
</StackLayout>
The function to show the list
public showList(name){
this.showType = false;
this.showCat = false;
this.showPropStat = false;
this.showWorkers = false;
this.showListPicker = true;
switch(name) {
case 'type':
this.showType = true;
console.log(this.jobTypes);
break;
case 'category':
this.showCat = true;
console.log(this.jobCats);
break;
case 'status':
this.showPropStat = true;
break;
case 'workers':
this.showWorkers = true;
console.log(this.jobWorkers);
break;
}
}
When I click the labels for Type it shows correctly, but clicking the Category or Workers it displays an area for the listpicker, but there are no items showing in them.
The part where the list items are set will output the correct list to the console.
Strangely by adding another row to the GridLayout and putting the listpickers in their own row seems to have fixed the issue.
Related
I am developing an application using C# in Blazor Framework. I have designed some forms like the following, where the grey areas are populated with the button below which triggers a pop up window for selection. Then after selection is done the selected item description will populated into the gray area. This grey area is an InputText element.
If the grey InputTexts are marked as required & readonly, then the areas are grey and users cannot insert manually their values but only though selection window. This is good, but if the user did not populate the window for selection it can also submit the form.
If the grey InputTexts are marked as required and beeing readonly though css, then the validation works, so the user should populate the window selection first, but if he did not, then the grey area becomes editable for manual input.
Any ideas how I can protect the application from manual input but at the same time make the validation work?
Any ideas how I can protect the application from manual input but at the same time make the validation work?
If I'm reading the question correctly, the demo below shows how to link the selector (in this case a select control) and the display and show the correct validation information and UX without access to the readonly control.
As you show no code, I don't know whether this fits with your model and form.
#page "/"
#using System.ComponentModel.DataAnnotations;
<PageTitle>Index</PageTitle>
<h1>Demo</h1>
<EditForm Model="model" OnValidSubmit=#OnSubmit class="border border-dark p-3 m-2">
<DataAnnotationsValidator />
<div class="mb-2">
<label class="form-label">Country</label>
<InputText class="form-control" disabled #bind-Value="#model.Value" />
<ValidationMessage For="() => model.Value" />
</div>
#if (!show)
{
<div class="mb-2">
<button type="button" class="btn btn-dark" #onclick=OnShow>Select Country</button>
</div>
}
else
{
<div class="mb-2">
<InputSelect class="form-select" #bind-Value:get=#model.Value #bind-Value:set="this.OnSetCountry">
<option value="">-- Select a Country -- </option>
<option value="UK">UK</option>
<option value="France">France</option>
<option value="Portugal">Portugal</option>
</InputSelect>
</div>
}
<div class="col=12 mt-2 text-end">
<button class="btn btn-success" type="submit">Submit</button>
</div>
</EditForm>
<h3 class="mt-4">Hides the -- Select a Country -- once a value is selected</h3>
<EditForm Model="model2" OnValidSubmit=#OnSubmit class="border border-dark p-3 m-2">
<DataAnnotationsValidator />
<div class="mb-2">
<label class="form-label">Country</label>
<InputText class="form-control" disabled #bind-Value="#model2.Value" />
<ValidationMessage For="() => model2.Value" />
</div>
#if (!show2)
{
<div class="mb-2">
<button type="button" class="btn btn-dark" #onclick=OnShow2>Select Country</button>
</div>
}
else
{
<div class="mb-2">
<InputSelect class="form-select" #bind-Value:get=#model2.Value #bind-Value:set="this.OnSetCountry2">
#if (model2.Value is null)
{
<option selected disabled value="">-- Select a Country -- </option>
}
<option value="UK">UK</option>
<option value="France">France</option>
<option value="Portugal">Portugal</option>
</InputSelect>
</div>
}
<div class="col=12 mt-2 text-end">
<button class="btn btn-success" type="submit">Submit</button>
</div>
</EditForm>
#code {
private Model model = new();
private bool show = false;
private Model model2 = new();
private bool show2 = false;
private void OnSetCountry(string? value)
{
model.Value = null;
if (value is not null || value != string.Empty)
model.Value = value;
show = false;
}
private void OnSetCountry2(string? value)
{
model2.Value = null;
if (value is not null || value != string.Empty)
model2.Value = value;
show2 = false;
}
private void OnShow()
=> show = !show;
private void OnShow2()
=> show2 = !show2;
public void OnSubmit()
{ }
public class Model
{
[Required]
public string? Value { get; set; }
}
}
in my nativescript-angular project I have a component like this:
<StackLayout>
<Label *ngIf="ngContentIsEmpty"> ng-content is empty </Label>
<ng-content></ng-content>
</StackLayout>
Now, I would like to display some content if <ng-content> for this component is empty.Is there an easy way to do this?
I've tried this but not work in nativescript:
<StackLayout #wrapper>
<Label *ngIf="wrapper.childNodes.length == 0"> ng-content is empty </Label>
<ng-content></ng-content>
</StackLayout>
Try to this for check ng-content is empty.
Add In Html File:-
<StackLayout *ngIf="ngContentIsEmpty">Content</StackLayout>
<StackLayout #wrapper>
<ng-content></ng-content>
</StackLayout>
In TypeScript File:-
export class MyComponent implements OnInit, AfterContentInit {
#ContentChild('wrapper') wrapper:ElementRef;
public ngContentIsEmpty = false;
ngAfterContentInit() {
this.ngContentIsEmpty= this.wrapper.childNodes.length > 0;
}
}
I'm using TableSelectDialog to view some Carrier details. All I need is: If I select any item (row), then all the values from that row should get automatically populated to the form input fields.
In the attached image, if Carrier Name is selected from TableSelectDialog, then the remaining fields should be populated based on that value.
You can achieve the required functionality using the Binding context that you receive from the TableSelcect Dialog.
But for binding context to work properly, both form and the table select dialog should refer to the same Model.
Below is the working code:
VIEW.XML:
Has a Button to trigger the table select dialog.
Has a form.
<l:VerticalLayout class="sapUiContentPadding" width="100%">
<l:content>
<Button class="sapUiSmallMarginBottom" text="Show Table Select Dialog"
press="handleTableSelectDialogPress">
</Button>
<VBox class="sapUiSmallMargin">
<f:SimpleForm id="SimpleFormDisplay354">
<f:content>
<Label text="Supplier Name" />
<Text id="nameText" text="{SupplierName}" />
<Label text="Description" />
<Text text="{Description}" />
<Label text="ProductId" />
<Text text="{ProductId}" />
<Label text="Quantity" />
<Text id="countryText" text="{Quantity}" />
</f:content>
</f:SimpleForm>
</VBox>
</l:content>
</l:VerticalLayout>
Controller:
onInit: function () {
// set explored app's demo model on this sample
var oModel = new JSONModel(jQuery.sap.getModulePath("sap.ui.demo.mock", "/products.json"));
this.getView().setModel(oModel);
},
handleTableSelectDialogPress: function (oEvent) {
if (!this._oDialog) {
this._oDialog = sap.ui.xmlfragment("sap.m.sample.TableSelectDialog.Dialog", this);
}
this.getView().addDependent(this._oDialog);
// toggle compact style
this._oDialog.open();
},
handleClose: function (oEvent) {
var aContexts = oEvent.getParameter("selectedContexts");
if (aContexts && aContexts.length) {
// MessageToast.show("You have chosen " + aContexts.map(function(oContext) { return oContext.getObject().Name; }).join(", "));
this.byId('SimpleFormDisplay354').setBindingContext(aContexts[0]);
}
oEvent.getSource().getBinding("items").filter([]);
}
Now, we also have a Select dialog and on click of any Item we call method : handleClose
In handleClose, we obtain the clicked Item binding context and then tell the form : hey! refer to this context ( which is present in the model). Binding context has a path which tells the form from where to do the relative binding.
Please feel free to contact for more information.
I want to open and close my flyout from viewmodel.
Im using UWP and Template10. I intent to use Template10 OpenFlyoutAction and Template10 CloseFlyoutAction.
I created a bool property that stores open or close state. Not sure how to call OpenFlyoutAction in here.
bool _IsFlyoutOpen = default(bool);
public bool IsFlyoutOpen
{
get { return _IsFlyoutOpen; }
set
{
var ofa = new OpenFlyoutAction();
if (_IsFlyoutOpen)
{
// what should i call here to open flyout
}
else
{
// what should i call here to close flyout
}
Set(ref _IsFlyoutOpen, value);
}
}
I created 2 Command to open and close flyout by changing the field.
DelegateCommand _CloseFlyout;
public DelegateCommand CloseFlyout
=> _CloseFlyout ?? (_CloseFlyout = new DelegateCommand(() =>
{
_IsFlyoutOpen = false;
}, () => true));
DelegateCommand _OpenFlyout;
public DelegateCommand OpenFlyout
=> _OpenFlyout ?? (_OpenFlyout = new DelegateCommand(() =>
{
_IsFlyoutOpen = true;
}, () => true));
In xaml, i use DataTriggerBehaviour to monitor IsFlyoutOpen property and act accordingly. Not sure if this is the right way.
<Button Content="Open flyout" Command="{x:Bind ViewModel.OpenFlyout}">
<FlyoutBase.AttachedFlyout>
<Flyout Placement="Full">
<StackPanel>
<TextBlock Text="Awesome Flyout!" />
<Button Content="Close flyout" Command="{x:Bind ViewModel.CloseFlyout}"/>
</StackPanel>
</Flyout>
</FlyoutBase.AttachedFlyout>
<Interactivity:Interaction.Behaviors>
<Core:DataTriggerBehavior Binding="{x:Bind ViewModel.IsFlyoutOpen}" ComparisonCondition="Equal" Value="True">
<Behaviors:OpenFlyoutAction />
</Core:DataTriggerBehavior>
<Core:DataTriggerBehavior Binding="{x:Bind ViewModel.IsFlyoutOpen}" ComparisonCondition="Equal" Value="False">
<Behaviors:CloseFlyoutAction />
</Core:DataTriggerBehavior>
</Interactivity:Interaction.Behaviors>
</Button>
Full source code can be had here. Template10 Flyout Viewmodel
I think this is what you are looking for
<Button Content="Open flyout">
<FlyoutBase.AttachedFlyout>
<Flyout>
<StackPanel>
<TextBlock Text="Something Useful" />
<Button Content="Close">
<!-- Call CloseFlyoutAction -->
</Button>
</StackPanel>
</Flyout>
</FlyoutBase.AttachedFlyout>
<Interactivity:Interaction.Behaviors>
<Core:EventTriggerBehavior EventName="Tapped">
<Behaviors:OpenFlyoutAction />
</Core:EventTriggerBehavior>
</Interactivity:Interaction.Behaviors>
</Button>
Open Flyout Action
https://github.com/Windows-XAML/Template10/wiki/Behaviors-and-Actions#openflyoutaction
Close Flyout Action
https://github.com/Windows-XAML/Template10/wiki/Behaviors-and-Actions#closeflyoutaction
You can also throw in a ConditionalAction to indicate that a condition has to be met before you can call CloseFlyoutAction. Its all there on the wiki, almost all of the actual code is contained in XAML.
I am trying to get a simple button to be enabled/disabled when checkboxes are being selected, yet in Alloy UI within Liferay, it doesnt seem to work. Any suggestions?
<aui:form>
<aui:input checked="<%= true %>" cssClass="input-container" label="Decline" name="termsOfServiceRadio" type="radio" onClick='<%= renderResponse.getNamespace() + "disableCheckout();"%>'/>
<aui:input cssClass="input-container" label="Accept" name="termsOfServiceRadio" type="radio" onClick='<%= renderResponse.getNamespace() + "enableCheckout();"%>'/>
<aui:button-row>
<aui:button type="submit" name="submitButton" id="submitButtonID" disabled="true" />
</aui:button-row>
</aui:form>
<aui:script>
function <portlet:namespace />enableCheckout() {
document.<portlet:namespace />fm.<portlet:namespace />.getElementById("submitButtonID").disabled = false;
}
function <portlet:namespace />disableCheckout() {
document.<portlet:namespace />fm.<portlet:namespace />.getElementById("submitButtonID").disabled = true;
}
</aui:script>
To continue my trials with no success:
<aui:script>
function <portlet:namespace />enableCheckout() {
var mySubmittButton = A.one('#<portlet:namespace />submitButton');
mySubmittButton.set('disabled', false);
mySubmittButton.ancestor('.aui-button').removeClass('aui-button-disabled');
}
</aui:script>
<aui:script use="aui-base">
function <portlet:namespace />enableCheckout() {
var A = AUI();
var myBtn = A.one('.submitVisible-button');
myBtn.one(':button').attr('disabled', false);
myBtn.toggleClass('aui-button-disabled', false);
}
</aui:script>
<
<aui:button type="submit" name="submitButtonID" id="submitButtonID" cssClass="submitVisible-button" disabled="true" />
<aui:script use="aui-base">
Liferay.provide(
window,
'<portlet:namespace />enableCheckout',
function() {
var myButton = A.one('#<portlet:namespace />submitButtonID');
Liferay.Util.toggleDisabled(myButton, 'true');
myButton.set('disabled', false);
myButton.ancestor('.aui-button').removeClass('aui-button-disabled');
});
</aui:script>
<aui:script use="aui-base">
Liferay.provide(
window,
'<portlet:namespace />enableCheckout',
function() {
var A = AUI();
var myButton = A.one('#<portlet:namespace />submitButtonID');
Liferay.Util.toggleDisabled(myButton, true);
});
</aui:script>
So it appears you want to enable/disable submitButtonID based on termsOfServiceRadio.
You have several variations of essentially the same approach available. The basic concept is to assign click listeners to each radio button setting the state of the button based only on the "Accept" option being "checked". You can use either an id attribute to apply the listeners individually or some css class that will allow you to get both input elements at once and apply the listeners through the each method. A third option is to use the delegate function, which would require that you wrap the radio options in a "container".
YUI().use('aui-base', function(A){
var button = A.one('#mySubmitButton');
button.set('disabled', true);
var func = function(){button.set('disabled', !A.one('#AcceptRadioId').get('checked'));}
A.all('.tosRadioOption').each(function(node){
node.on('click', func)
})
})
Ultimately the set method using the disabled property on the submitButtonID node is the key components required to achieve the desired functionality. My fiddle contains the three approaches I mentioned. Considering you are using the aui taglib elements you'll need to prefix the ids with <portlet:namespace /> as you have done in some of your other attempts.
Ended up doing this a different way
<aui:form>
<aui:input checked="<%= true %>" cssClass="input-container" label="Decline" name="termsOfServiceRadio" type="radio" onClick="document.getElementById('test').style.visibility = this.checked ? 'hidden' : 'visible';"/>
<aui:input cssClass="input-container" label="Accept" name="termsOfServiceRadio" type="radio" onClick="document.getElementById('test').style.visibility = this.checked ? 'visible' : 'hidden';" />
<div id="test" style="visibility:hidden;">
<br/>
<strong>Choose a payment method:</strong>
<br/><br/>
<aui:input checked="<%= true %>" cssClass="input-container" label="Pay online with PayPal" name="paymentMethod" type="radio" onClick='<%= renderResponse.getNamespace() + "setPaypal();"%>'/>
<aui:input cssClass="input-container" label="Pay with check or wire transfer" name="paymentMethod" type="radio" onClick='<%= renderResponse.getNamespace() + "setOffline();"%>'/>
<aui:button-row>
<aui:button type="submit" name="submitButtonID" id="submitButtonID" cssClass="submitVisible-button" value='<%= shoppingPrefs.usePayPal() ? "continue" : "finished" %>' />
</aui:button-row>
</div>