I created a form that contains a textbox. If you try to submit the form without filling in the textbox, a validation message is displayed.
If the textbox is filled, I intend to clean all its content when submitting the form. My problem is that I can clean the textbox after submitting without the validation message appearing, however, when I switch to another Tab and then return to it, that validation message is displayed. How can I solve this?
PROBLEM
DEMO
html
<div class="container">
<div class="tab-slider--nav">
<ul class="tab-slider--tabs">
<li class="tab-slider--trigger" [class.active]="viewMode == 'tab1'" rel="tab1" (click)="viewMode ='tab1'">
Tab 1 - list</li>
<li class="tab-slider--trigger" [class.active]="viewMode == 'tab2'" rel="tab2" (click)="viewMode ='tab2'">
Tab 2 - Create</li>
</ul>
</div>
<div class="tab-slider--container" [ngSwitch]="viewMode">
<div id="tab1" class="tab-slider--body" *ngSwitchCase="'tab1'">
LIST
</div>
<div id="tab2" class="tab-slider--body" *ngSwitchCase="'tab2'">
<form (submit)="SaveGroup($event)" style="width: 100%; height: 92%;">
<dx-validation-group #CreateGroup>
<div style="width: 100%; height: 100%; overflow: auto;">
<div style="
display: flex;
align-items: center;
flex-direction: column;
width: 100%;
">
<span class="title1">Name</span>
<div class="mytextbox">
<dx-text-box [(ngModel)]="Name" [ngModelOptions]="{standalone: true}"
placeholder="Enter Name">
<dx-validator>
<dxi-validation-rule type="required" message="Name is required">
</dxi-validation-rule>
</dx-validator>
</dx-text-box>
</div>
</div>
</div>
<div style="padding-top: 10px;">
<dx-button class="customButtom" type="submit" id="button" text="Save"
[useSubmitBehavior]="true">
</dx-button>
</div>
</dx-validation-group>
</form>
</div>
</div>
</div>
.TS
SaveGroup(e) {
let self = this;
self.viewMode = 'tab1';
self.validationGroup1.instance.reset();
}
If you comment this line self.viewMode = 'tab1'; (do not change the tab after submitting) the textbox is successfully cleared. If you change tab and then return to the one with the textbox, the validation message is always displayed.
It seems that field is in "touched mode" because the value is stored in two way binding in Name.
I have tried this :
SaveGroup(e) {
const savedNameValue = this.Name;
this.validationGroup1.instance.reset();
this.Name = null;
this.viewMode = 'tab1';
}
Related
I created a angular dropdown component "app-ec-dropdown" using https://www.npmjs.com/package/#ng-select/ng-select
<div class="inline required">
*
</div>
<div class="input-container inline">
<ng-select
class="custom"
[items]="items"
bindLabel="Name"
bindValue="Id"
(focus)="focus()"
(close)="close()"
(clear)="clear()"
(blur)="blur()"
placeholder="Select"
[(ngModel)]="selectedId"
[required]="required"
>
</ng-select>
<div *ngIf="!validatationPassed()">
<div class="row alert alert-danger alert-div">
<span>
Required field
</span>
</div>
</div>
</div>
CSS for above component
.input-container {
width: 95%;
}
.inline {
display: inline;
}
.required {
vertical-align: top;
color: red;
width: 2%;
}
Now i am using above component in parent component
<div class="col-sm-4">
<app-ec-dropdown
name="RegionId"
[items]="regions"
(onChange)="onRegionChange($event)"
[selectedId]="state.RegionId"
[required]="regionDropDownValidator.required"
[ecDropDownValidator]="regionDropDownValidator"
[(ngModel)]="regionDropDownValidator.selectedId"
ngDefaultControl
> </app-ec-dropdown>
</div>
for Region Dropdown, I want red asterisk, to be placed as in "State Name" textbox and then dropdown and validation message in the adjacent div.
Screen grab:
After playing around with your code, I thought about the way that I would do it.
I noticed that the actual label isn't included in your example above, so I assume that it's being included within a column to the left of the <div class="col-sm-4"> element where you're consuming the <app-ec-dropdown> component which I assume that you have defined with the first code block.
My advice which will be the easiest and most correct (in my opinion), would be to add the label as an #Input property in your code for the <app-ec-dropdown> component.
Then you can place it closer to the asterisk character.
So add this to your EcDropdownComponent TypeScript:
#Input()
public label: string = '';
Then add the input attribute where you consume your component:
<app-ec-dropdown
name="RegionId"
[items]="regions"
label="State Name"
(onChange)="onRegionChange($event)"
[selectedId]="state.RegionId"
[required]="regionDropDownValidator.required"
[ecDropDownValidator]="regionDropDownValidator"
[(ngModel)]="regionDropDownValidator.selectedId"
ngDefaultControl>
</app-ec-dropdown>
Then you can use the CSS grid to define the layout within your component:
<div class="row">
<!-- Label -->
<div class="col-sm-4">
<div class="label">
{{label}}
<span class="inline required"> * </span>
</div>
</div>
<!-- Select Input -->
<div class="col-md-8">
<div class="input-container inline">
<ng-select
class="custom"
[items]="items"
bindLabel="Name"
bindValue="Id"
(focus)="focus.emit()"
(close)="close.emit()"
(clear)="clear.emit()"
(blur)="blur.emit()"
placeholder="Select"
[(ngModel)]="selectedId"
[required]="required">
</ng-select>
<div *ngIf="!validatationPassed()">
<div class="row alert alert-danger alert-div">
<span>
Required field
</span>
</div>
</div>
</div>
</div>
</div>
The nice thing about this approach is that you have a completely self-contained component which doesn't need to worry about anything outside of it's scope.
If you're concerned about variable widths using Bootstrap and the grid system.
You can also pass the grid column style in as an #Input property to the component so that you're providing more control to the consuming component.
I have a chat box with a single input field. I want to make handle new line input like Facebook's chatbox.
My Chat Box:
[1]: https://i.stack.imgur.com/NeG7d.png
My HTML of input field:
<form class="form" #msgForm="ngForm" (ngSubmit)="send(msgForm)" focus>
<div class="form-group">
<div class="col-xs-5">
<div class="input-group">
<input type="search" autocomplete="off" class="form-control left-border-none"
name="message" [(ngModel)]="message" placeholder="Say Something..."
(input)="onChange($event.target.value)" />
<span class="input-group-addon transparent">
<button type="submit" (keyup.enter)="send(msgForm)"
style="border: 0; background: none;cursor: pointer;"><i class="fa fa-paper-plane" [hidden]="isHidden"
style="font-size:20px;color: #6d5cae;"></i></button>
</span>
</div>
</div>
</div>
</form>
Here's my solution.
Brief Note It's not the exact answer because I had the same problem and after a lot of testing, found more adequate to let "Enter" for newlines and"Shift+Enter" for sending messages
This is the opposite logic of popular apps like WS and MSg but I found
more suitable for people having a conversations over a web based chat, since in a conversation you want sometimes to write long messages, and for people habituated to type on text editors, this is the logic function of pushing "Enter".
People may disagree, but just hope you can find it useful
What I did was to using a text-area as container, for easier auto-sizing and multi-line configuration
After that, I created a button that posts the message once clicked,and a #Hostlistener for the event to bind the button to the method.
Please refer to the code.
Best regards
HTML from the typing bar component
<!-- (keydown)="onKey($event)" -->
<!-- submit message with enter -->
<!-- (keydown.enter)="postMessage(messageContainer)" -->
<!-- (keyup.enter)="onKeydown($event)" // for event methods -->
<div class="typing-bar prim-color" >
<textarea
matInput
matAutosize
name=""
cdkTextareaAutosize
#messageContainer
#autosize="cdkTextareaAutosize"
cdkAutosizeMinRows="2"
cdkAutosizeMaxRows="7"
>
</textarea>
<button
mat-stroked-button
color="accent"
(click)="postMessage(messageContainer)"
[disabled]="messageContainer.value===''"
><mat-icon>send</mat-icon> Send</button>
</div>
TS Code for the component
import { Component, HostListener, OnInit } from '#angular/core';
#Component({
selector: 'app-typing-bar',
templateUrl: './typing-bar.component.html',
styleUrls: ['./typing-bar.component.scss']
})
export class TypingBarComponent implements OnInit {
displayBar: boolean = true;
constructor() { }
ngOnInit(): void {
}
#HostListener('body:keydown.shift.enter',['$event'])launchPost($event: KeyboardEvent): void{
return this.postMessage($event.target as HTMLTextAreaElement)
}
postMessage(textarea:HTMLTextAreaElement){
//post message here
// ....logic...
//reset textarea
textarea.value = ""
//give focus back
textarea.focus();
//debug: this is for test only. Delete after testing
alert('sent')
}
}
SCSS code for the component (maybe not the final version)
.typing-bar{
display: flex;
justify-content: space-around;
padding: 3px;
padding-right: 10px;
margin: 1px;
position: sticky;
bottom: 0;
}
textarea {
overflow: auto;
width: 93%;
// max-height: 20%;
border-radius: 10px;
font-size: 1.3em;
font-family: Arial, Helvetica, sans-serif;
}
// .typing-bar button{
// }
I'm very new to CSS and HTML and I'm facing a very strange issue here, I have text area in my html as below.
<div class="ContentBox BPMSectionBody LastContentBox noHeader" id="div_3_1_1_2_11_1_1_1_1_1_1_10_1" data-view-managed="false">
<div class="Text_Area fullWidthTextArea CoachView CoachView_hidden CoachView_show" id="div_3_1_1_2_11_1_1_1_1_1_1_10_1_1" data-eventid="" data-viewid="Text_Area8" data-config="config99" data-bindingtype="String" data-binding="local.userAction.comments"
data-type="com.ibm.bpm.coach.Snapshot_7a0c03cc_ccef_4582_a1bc_7ccc8e9be488.Text_Area">
<div class="textLabel">
<label class="text controlLabel" id="div_3_1_1_2_11_1_1_1_1_1_1_10_1_1_label">Enter Cancellation Comments</label>
<div class="coachValidationDiv">
<img class="coachValidationImg smallImg CoachView_hidden" role="alert" alt="Error" src="/teamworks/webasset/2064.7a0c03cc-ccef-4582-a1bc-7ccc8e9be488/W/Error_icon_24x24.png">
<span class="coachValidationText" style="visibility: hidden;">!</span>
</div>
</div>
<textarea tabindex="0" class="dijitTextBox dijitTextArea dijitExpandingTextArea BPMTextAreaFont" id="dijit_form_Textarea_16" aria-labelledby="div_3_1_1_2_11_1_1_1_1_1_1_10_1_1_label" style="-ms-overflow-x: auto; -ms-overflow-y: hidden; box-sizing: border-box;"
rows="1" data-dojo-attach-point="focusNode,containerNode,textbox" widgetId="dijit_form_Textarea_16" autocomplete="off" value=""></textarea>
</div>
</div>
And a button as below :
<div class="Button pageFlowButton CoachView CoachView_show" id="div_3_1_1_2_12_1_2" data-eventid="boundaryEvent_17" data-viewid="Button10" data-config="config83" data-bindingtype="" data-binding="" data-type="com.ibm.bpm.coach.Snapshot_7a0c03cc_ccef_4582_a1bc_7ccc8e9be488.Button">
<button class="BPMButton BPMButtonBorder" type="button">Continue With Selected Action</button>
</div>
when I start typing in textarea and having my cursor still in the textarea and i click on button for the first time instead of action being taken, text area gets focused.
When I click button second time it works fine.
Can any body please help,what can be the possible reason here??
In case you are using jQuery, I guess you should use:
$('.Text_Area').click(function(noFocus){
noFocus.preventDefault();
});
when I'm using my phone to test the app, I use the back device button to show the previous page this is working with all the pages except one page that shows a not styled page when trying to get to the pervious page so there somthing Odd. Here a briefe explanation.
there is 3 page #main_menu , #first_map , #second_map
when I'm into the #second_map page it should go to the #first_page when I press back button
but actually its showing the #main_menu page with not css styling.
could you plz tell me what is the problem an how we can fix it thank you in advance .
I provide the source code :
this is the main_page
</div>
<h2 id="thx_msg" style="margin:0 auto;"></h2>
<div class="grid2">
<div class="first" id="search_btn">
<div>
<img src="images/loupe.jpg"/>
<div>
</div>Search for a Spot</div>
</div>
<div class="second" id="submit_spot_btn">
<div>
<img src="images/spot.jpg"/>
</div>
<div>Submit a spot</div>
</div>
</div>
<ul style="margin:0 auto;" class="spaced_list" style="widht:280px;" >
<li><input type="button" data-role="none" value="Account info" class="btn" style="margin:0 auto;" id="main_page_account_info"/></li>
<li><input type="button" data-role="none" value="Log Out" class="btn" style="margin:0 auto;"id="main_page_log_out"/></li>
</ul>
</div>
here is the first_map page is named spot_page
<div data-role="page" id="spot_page" data-theme="b">
<div data-role="header" style="overflow:hidden;">
<img class="logo_icon" src="images/logo_icon.png">
</div><!-- header -->
<div class="clear"></div>
<div id="search_form_holder" style="margin:0px 25px" >
<p class="center" style="font-size:16px;font-weight:bold;">
Search for a Spot
</p>
<ul class="some_space" style="margin:0 auto;
margin-left:auto;
margin-right:auto;
align:center;
text-align:center;
width:280px;">
<li><input type="text" id="address_zip" class="field black" placeholder="Address/Zip Code"/></li>
<li id="to"></li>
<li><input type="button" data-role="none" style="width:200px;margin:15px auto;" id="search_spot_btn" class="btn" value="Search for a Spot"></li>
</ul>
<div id="hidden_scroller" style="display:none">
<select id="distance" name="Within">
<option value="1">1 Mile</option>
<option value="3">3 Miles</option>
<option value="5">5 Miles</option>
<option value="10">10 Miles</option>
</select>
</div>
</div><!-- search form -->
<div id="first_map" style="width: 100%;
height: 247px;border:1px solid black;margin:0 auto">
</div>
</div><!-- split view -->
and finally the second map here :
<div data-role="page" id="nearby_page">
<div data-role="header" style="overflow:hidden;">
<img class="logo_icon" src="images/logo_icon.png">
</div><!-- header -->
<div class="clear"></div>
<div class="second_header">Spots nearby</div>
<div id="map" style="width: 100%;
height: 398px;border:1px solid black;margin:0 auto">
</div>
</div>
As you can see the pages are separate from each other.
I have a last question could a navigation plugin help to fix the problem like jquery history plugin and thanks for your help.
Make sure to have your pages on different separate pages. If not these kind of errors will occur. Mostly, you will encounter abnormal navigation error. That is what I have experienced in my experience.
BTW, you should show more of your code for people here to help you out.
Update
PhoneGap and Android's back button do behaves odd. What I have done in my application is disabled the back button and given the soft back button on the top header. Simple history.back() will do the magic for back buttons.
You can disable as follows.
$(function(){
document.addEventListener("deviceready", onDeviceReady, false);
})
// PhoneGap is loaded and it is now safe to call PhoneGap methods
//
function onDeviceReady() {
// Register the event listener
document.addEventListener("backbutton", onBackKeyDown, false);
}
// Handle the back button
//
function onBackKeyDown() {
console.log("Back button pressed but nothing happened");
}
Anyway this is my approach. You may choose to be different.
I am writing an MVC3 page, and I have images with radio buttons next to them. I want each radio button to be on the same line as it's image, but not one image per line, I want it to flow through many lines, but in pairs. I've tried wrapping the two in a div and display:inline-block works, except the radio button is above my image, not next to it. white-space: nowrap; works, but by putting only one image per line ( I could do that with a ).
Here is the code, FWIW:
#foreach (xxx.Image im in Model.Images)
{
<div style="white-space: nowrap;">
#Html.RadioButtonFor(m => m.EmailImage, im.Id, Model.EmailImage == im.Id ? new { Checked = "checked" } : null)
<a href="/preview/#im.Url&h=251&w=600" target="_blank">
<img height="41" width="97" src="#im.ThumbUrl"/></a>
</div>
}
Thanks for looking.
The following example seems to be working: jsfiddle.
HTML:
<div class="left">
<input type="radio" value="check" />
google
<img src="http://placehold.it/41x97"></img>
</div>
<div class="left">
<input type="radio" value="check" />
google
<img src="http://placehold.it/41x97"></img>
</div>
<div class="left">
<input type="radio" value="check" />
google
<img src="http://placehold.it/41x97"></img>
</div>
CSS:
.left
{
float:left;
}
.left a, .left input, .left img
{
display:inline-block;
vertical-align:middle;
}