I am using Ionic 3 as a framework for my app. the app has a small configuration page. the user can choose different ranges via three dualknob sliders. the idea is, that those upper and lower limits are used to validate data which the user can enter on other pages. if a value is not between this range, the user gets an alert-toast.
im using firebase/angularfire2 as a database.
my html code with 3 sliders looks like this:
<ion-item>
<ion-label>Range 1</ion-label>
<ion-range min="-250" max="250" pin="true" dualKnobs="TRUE" [(ngModel)]="config.range1" color="secondary">
<ion-label range-left>-250g</ion-label>
<ion-label range-right>250g</ion-label>
</ion-range>
</ion-item>
<ion-item>
<ion-label>Range2</ion-label>
<ion-range min="0" max="200" pin="true" dualKnobs="TRUE" [(ngModel)]="config.range2" color="secondary">
<ion-label range-left>0</ion-label>
<ion-label range-right>200</ion-label>
</ion-range>
</ion-item>
<ion-item>
<ion-label>Range3</ion-label>
<ion-range min="0" max="200" pin="true" dualKnobs="TRUE" [(ngModel)]="config.range3" color="secondary">
<ion-label range-left>0</ion-label>
<ion-label range-right>200</ion-label>
</ion-range>
</ion-item>
I want to bind these three ranges to a single model to directly store it in firebase. So I created an interface, but I only manage to bind one range to this interface. the knobs of the other 2 ranges can't be moved and say "NaN" on their knobs. I tried to bind them to different elements of my interface called "config", but that didn't work. I also created fields called upper/lower in the limit but it didnt work.
Binding the ranges to three differentImodels worked. i then mapped it to my database model and saved them to firefase. but the other they round didnt work - the knobs didnt accept the values from the database.
thank you for your help.
Solved it myself by using a single model per Range-Slider and mapping the values in both directions to and from my database object before commiting.
slider1 = {} as any;
this.slider1.upper = (this.config.slider1max) ? this.config.slider1max : '100';
config.slider1max = this.slider1.upper;
Related
I'm a volunteer at a Coffee Shop. I've built an app that presents the drink recipe to the barista. Here's a quick snapshot:
The data come from a firebase realtime database. Here's a snippet from that database:
What I want to do is to put some HTML into the instructions to format it for easy reading. I do that by binding the content in the template file to [innerHTML] as shown below:
<ion-item>
<ion-grid>
<ion-row *ngIf="!item.temperature">
<ion-col>
<ion-label><strong>Instructions</strong></ion-label>
</ion-col>
</ion-row>
<ion-row>
<ion-col>
<h5 *ngIf="this.compactMode">
<span [innerHTML]="item.instructions"></span>
</h5>
<span *ngIf="!this.compactMode" [innerHTML]="item.instructions">
</span>
</ion-col>
<ion-col *ngIf="item.image"
><ion-img
(click)="onClickImage(item.image)"
src="{{item.image}}"
></ion-img
></ion-col>
</ion-row>
</ion-grid>
</ion-item>
THE PROBLEM
This works really well for <b> <ol> <ul> <li> <br> and so on. But it does not work for <ion-checkbox> nor <input type="checkbox"> The input tags get filtered out somewhere before being presented.
SECURITY
I'm aware that putting HTML into a database can increase my security surface, so I'm using sanitizer to filter the HTML and then I attempt to add the after the fact. Here's how I do it:
stringFormat(inputString: string) {
const re1 = /\[\]/gi;
let returnString = this.sanitizer.sanitize(1, inputString);
returnString = returnString.replace(re1, '<ion-checkbox id=\'input\'></ion-checkbox>');
return returnString;
}
You'll notice that I first sanitize the string, and then I do a substitution, replacing [] with the checkbox.
(In case you're interested, I'm just making a opening/closing checklist and it would be nice if people could touch the checkbox after they've completed a task... I don't plan to store the checkbox values, I just want the checkbox user experience.)
I have checked that item.instructions in fact includes the substituted string in the item object, but when rendered by ionic/angular, the actual text seems to have filtered out anything but vanilla HTML tags.
Finally the Question
So here's the question: Are there some sort of limits to what can be inserted into the DOM using [innerHTML] binding? Am I overthinking this?
Thanks.
After reading https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML, I've concluded that there really is not a safe way to do this using the approach suggested above.
Instead of embedding HTML in the database, I'm going to set up an array of paragraphs in the item.instructions fields of the database. Each element in the array can have a key:value pair to indicate if the element represents a plain paragraph, or a checkbox.
Then I can iterate through the array of instructions (*ngFor), and for each instruction I can check the instruction type (<div *ngIf="item.type===...>) to determine whether to wrap the text with an <ion-text> or an <ion-checkbox>.
I am using Ionic 5 in a project.
One thing I need is an input type number with up / down increment arrows like this image:
How can I do that as I cannot see any examples of that on the UI Components on their website.
Set the type attribute of ion-input to "number":
<ion-input type="number" value="5" min="1" max="9"></ion-input>
i have a requirement where presently im displaying the dynamic data using ion-col in that i m displaying column more than 8 Fields but it is not cumming responsive & here i require a suggestion how to display a table which have more than 5 max 14 fields using ionic 2
By default Ionic 2 grid comes with a 12 columns pattern, you can change it using SASS ans styling guides
Here's a link to Number of columns. What you need to do is simply add the following code in your variables.scss under theme folder:
$grid-columns: 14;
This will force your grid to have 14 columns instead of the default 12.
About the minimun of 5 columns there's no way to controll it, there's no minimun columns value, you'll need to proramatically assure that there's at least 5 columns, a way of doing this is using a total of columns that'll end up beeing represented in the screen as 5 columns, something like:
<ion-grid>
<ion-row>
<!-- assuming you're using 14 columns, if you're not all col- attributes must be col-2 -->
<ion-col col-3></ion-col>
<ion-col col-3></ion-col>
<ion-col col-3></ion-col>
<ion-col col-3></ion-col>
<ion-col col-2></ion-col>
</ion-row>
</ion-grid>
Hope this helps.
If you have maximum 14 columns requirement, then you need to do some customization.
Like, You have to divide 100% width by 14 (100/14= 7.14 %), Give width of 7.14% to the div or td you are using. and you will be able to manage 14 columns in your app.
.div_width{
width:7.14%;
display:inline-block;
}
<ion-list>
<ion-grid>
<ion-row>
<ion-col col-12 text-center>
<div class="div_width">
content here
</div>
</ion-col>
</ion-row>
</ion-grid>
</ion-list>
How can I use ngModel for inputs across multiple forms that's repeated by ngFor?
Angular2 gives me error when I'm trying to do so.
Error: Permission denied to access property "rejection"
Example block of problematic code:
<div *ngFor="let item of items">
<form name="itemForm">
{{item.name}}<input [(ngModel)]="item.name">
</form>
</div>
Here is the plunker
https://plnkr.co/edit/YNZiCBeyqJoxO5ox5nlC?p=preview
If I remove the form tag, it all run without problem, but I need it so I can use enter key on all input to update corresponding data in their own form.
If ngModel is used within a form tag, either the name attribute must be set or the form control must be defined as 'standalone' in ngModelOptions.
Below will work without any error :
<div *ngFor="let item of items">
<form name="itemForm">
{{item.name}}<input [(ngModel)]="item.name" [ngModelOptions]="{standalone: true}">
</form>
</div>
As pointed out by #ranakrunal9 you can use a unique name attribute for your input. Here the code:
<div *ngFor="let item of items; let index=index">
<form name="itemForm">
{{item.name}}<input [(ngModel)]="item.name" name={{index}}>
</form>
</div>
I have a repeating component in wicked which needs to be added and deleted as per the user requirement. The maximum number of component is predefined. So I am adding the components at start up and hiding and showing based on need. I am required to change the arrangement of the components in the HTML markup when there is any deletion of the component. I use JavaScript for this. I want to know if wicket would lose hold of the components if I do this.
<div wicket:id="borrowerTabs" id="borrowerTabs">
<span wicket:id="borrowerTab1" id="borrowerTab1" ></span>
<span wicket:id="borrowerTab2" id="borrowerTab2" ></span>
<span wicket:id="borrowerTab3" id="borrowerTab3" ></span>
<span wicket:id="borrowerTab4" id="borrowerTab4" ></span>
<button wicket:id="addBorrower" id="addBorrower" type="button"></button>
<button wicket:id="deleteBorrower" id="deleteBorrower" onclick="updateUIForDeleteBorrower()" type="button"></button>
</div>
If delete the borrowerTab3, contents inside borrowerTab4 will be replacing the contents inside borrowerTab3 and the model objects too will be swapped though I do not do a target.add(borrowerTab3). Now while form submission, I am not getting the values of the fields inside borrowerTab3.
I'm not sure if it helps but try component.setVisible(false) in your java code to hide it.