I have a form generated by angular-formly.
I format the date using angular date filter
this.formlyFields = [
{
key: 'fromDate',
type: 'datepicker',
templateOptions: {
label: this.i18n.text('searchCase_FromDate'),
type: 'text',
placeholder: this.i18n.text('searchCase_FromDatePlaceholder'),
required: true,
datepickerOptions: {
format: 'shortDate',
'show-weeks': false,
}
},
expressionProperties: {
'templateOptions.label': '"searchCase_FromDate" | translate',
'templateOptions.placeholder': '"searchCase_FromDatePlaceholder" | translate'
}
}
]
Here is the template I'm using:
<input type="text"
id="{{::id}}"
name="{{::id}}"
ng-model="model[options.key]"
class="form-control"
uib-datepicker-popup="{{to.datepickerOptions.format}}"
is-open="datepicker.opened"
datepicker-options="to.datepickerOptions"
current-text="{{'datepickerCurrent' | translate}}" clear-text="{{'datepickerClear' | translate}}" close-text="{{'datepickerClose' | translate}}" />
When I'm on this view and change the locale the date won't be reformated.
It will if I change the locale before arriving on this page.
I'm changing the locale with angular-dynamic-locale.
It works if in a view I display like this:
<div>{{vm.formlyModel.fromDate | date:'shortDate'}}</div>
But how to have the same rresult with angular-formly ?
Thnaks for your help.
Related
I am really stuck with getting the issue resolved. I am very new to coding and hasn't been able to find any solution online.
These are the fields that I wish to be an array. I have created multiple inputs such as PIC#2 etc.
I am linking this model to another model schema so I would like that when I have selected the company, their corresponding PICs will be in another dropdown list. At the moment, it is showing all PIC1 which includes other companies' staffs. Please help out if you can make the coding simpler! Thank you in advance!
html
<div class="mb-3 col">
<label class="form-label" for="pic"><b>Person In Charge (PIC) #1</b></label>
<input class="form-control"type="text" id="pic" name="company[pic]" required>
</div>
<div class="row">
<div class="mb-3 col">
<label class="form-label" for="mobile"><b>Mobile</b></label>
<input class="form-control"type="text" id="mobile" name="company[mobile]" required>
</div>
<div class="mb-3 col">
<label class="form-label" for="email"><b>Email</b></label>
<input class="form-control"type="email" id="email" name="company[email]" required>
</div>
</div>
model schema
const companySchema = new Schema({
name: [{
type: String,
uppercase: true,
}],
code: String,
pic: [{
type: String,
uppercase: true,
}],
mobile: String,
email: [{
type: String,
lowercase: true,
}],
pic1: [{
type: String,
uppercase: true,
}],
pic2: [{
type: String,
uppercase: true,
}],
pic3: [{
type: String,
uppercase: true,
}],
pic4: [{
type: String,
uppercase: true,
}],
pic5: [{
type: String,
uppercase: true,
}],
pic6: [{
type: String,
uppercase: true,
}],
pic7: [{
type: String,
uppercase: true,
}],
pic8: [{
type: String,
uppercase: true,
}],
pic9: [{
type: String,
uppercase: true,
}],
pic10: [{
type: String,
uppercase: true,
}],
mobile1: String,
mobile2: String,
mobile3: String,
mobile4: String,
mobile5: String,
mobile6: String,
mobile7: String,
mobile8: String,
mobile9: String,
mobile10: String,
email1: [{
type: String,
lowercase: true,
}],
email2: [{
type: String,
lowercase: true,
}],
email3: [{
type: String,
lowercase: true,
}],
email4: [{
type: String,
lowercase: true,
}],
email5: [{
type: String,
lowercase: true,
}],
email6: [{
type: String,
lowercase: true,
}],
email7: [{
type: String,
lowercase: true,
}],
email8: [{
type: String,
lowercase: true,
}],
email9: [{
type: String,
lowercase: true,
}],
email10: [{
type: String,
lowercase: true,
}],
remarks: String,
status: String,
upload: String,
companyimage: String
});
route
app.get("/companies/new", (req,res) => {
res.render("companies/new")
});
app.post("/companies",async(req,res) => {
// res.send(req.body)
const company = new Company(req.body.company);
await company.save();
res.redirect(`/companies/${company._id}`)
});
Since I don't have much context on what you're trying to achieve, I'll go through all I can think of to best answer this thread
| NodeJS is not a front-end framework
NodeJS is a JavaScript runtime environment, which roughly means it reads and executes JS code you're giving it. A front-end framework is a set of tools and method that greatly helps you to code faster. It generally gives you higher level components so that you don't have to deal with low-level JS code yourself. Some examples are ReactJS, VueJS, Angular, etc...
I strongly advise you to take a look at these if you're going to build a web-app.
| You might want to rework your database model
I won't tell you to rework your entire base code because that can be tiring and that's not the point of the question.
I'd put all PICs in a single array instead of having 10 fields, same thing goes for emails and mobiles. We can chat about it later on if you want to.
| Answering the question
Given that I don't have much context about the stack used regarding the front-end, I sticked to plain JS and HTML. Here's one method (among many others):
index.js (to put front-end side)
//initializing the company object
const addedData = {
id: 1,
company: 'companyname',
pic: [],
mobile: [],
email: []
}
//getting the buttons elements
const addPIC = document.getElementById('addpic');
const form = document.getElementById('sendform');
//listening on click event on the form
form.addEventListener('click', (e) => {
// do what you have to here, e.g sending form
const res = fetch("http://localhost:3000/companies", {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(picArray)
}).then(data => {
console.log(data);
});
});
// listening on click event when adding data
addPIC.addEventListener('click', (e) => {
//getting input tags
const pic = document.getElementById('pic');
const mobile = document.getElementById('mobile');
const email = document.getElementById('email');
//pushing into respective arrays
addedData.pic.push(pic.value);
addedData.mobile.push(mobile.value);
addedData.email.push(email.value);
//resetting values to ease the process of mass adding PICs
pic.value = '';
mobile.value = '';
email.value = '';
//console.log(addedData);
});
and your html file (took your original file and just added 2 buttons, that's why it's not formatted properly):
<div class="mb-3 col">
<label class="form-label" for="pic"><b>Person In Charge (PIC) #1</b></label>
<input class="form-control"type="text" id="pic" name="company[pic]" required>
</div>
<div class="row">
<div class="mb-3 col">
<label class="form-label" for="mobile"><b>Mobile</b></label>
<input class="form-control"type="text" id="mobile" name="company[mobile]" required>
</div>
<div class="mb-3 col">
<label class="form-label" for="email"><b>Email</b></label>
<input class="form-control"type="email" id="email" name="company[email]" required>
</div>
</div>
<button id="addpic">Add PIC</button>
<button id="sendform">Send form</button>
</div>
Now your back-end will receive the datas, but you'll have to process it once again to match your database model, which is not optimal.
I wrote a little program in Angular using ui-select elements. Here is the html code :
<ui-select ng-model="test.selectedContract">
<ui-select-match >
{{$select.selected.name}} - {{$select.selected.value}} ---- {{$select.selected.id.id}} *** {{$select.selected.policy.info.name }}
</ui-select-match>
<ui-select-choices group-by="groupByLetter"
repeat="contract in (contracts |
orSearchFilter: {id.id: $select.search, policy.info.name : $select.search} |
orderBy: 'name') track by contract.name">
{{contract.name}} - {{contract.value}} ---- {{contract.id.id}} *** {{contract.policy.info.name }}
</ui-select-choices>
</ui-select>
And here is the structure of my contracts object :
$scope.contracts = [{
name: "contract1.00",
value: 10,
id: {
id: 8000,
code: 2
},
policy: {
info: {
name: "test1",
country: "test"
}
}
}, //other contract objects
Finally, there is my plunker code : http://plnkr.co/edit/PigjGCj5ukxscJC7Wl97?p=preview
The problem is that I want to display "All" as a default value (if there is no selection) while my default value in my plunker is : " - ---- *** "
Can you please help me to set this default value please?
Thanks !
You could define a sort of toString function in your controller and put the result of that in the ui-select tag, instead of hard-code dashes and stars. If value is null, it should return "All"
Just set the
$scope.test.selectedContract = {
name: "all",
value: 10,
id: {
id: 8000,
code: 2
},
policy: {
info: {
name: "test1",
country: "test"
}
}
}
DEMO
I have the following list from which I need to create a multiple multi-select dropdown using ui-select
[
{
"Id":1,
"name":"Return on Equity (IFRS)",
"type":"profitability",
},
{
"Id":2,
"name":"Return on Assets (IFRS)",
"type":"profitability",
},
{
"Id":3,
"name":"EBITDA Margin (IFRS)",
"type":"profitability",
},
{
"Id":4,
"name":"EBIT Margin (IFRS)",
"type":"profitability",
},
{
"Id":5,
"name":"Net Profit Margin (IFRS)",
"type":"profitability",
},
{
"Id":8,
"name":"Cash Ratio",
"type":"liquidity",
},
{
"Id":9,
"name":"Quick Ratio",
"type":"liquidity",
},
{
"Id":10,
"name":"Current Ratio",
"type":"liquidity",
},
{
"Id":11,
"name":"Net Financial Liabilities",
"type":"debt",
}
];
I need to be able to select multiple "types" in the first dropdown based on which the corresponding "names" should be shown in the second dropdown. I seem to have hit a roadblock with this. Any help would be appreciated.
This is what I have tried so far. Plunker
let's use 2 custom filters:
app.filter('unique', function() {
return function(collection, keyname) {
return Object.keys(collection.reduce((res, curr) => {
res[curr.type] = curr;
return res;
}, {}));
};
});
app.filter('matchType', function() {
return function(collection, keynames) {
return collection.filter(item => ~keynames.indexOf(item.type));
};
});
unique filter returns an array of strings with unique types and matchType filters array by selected types.
HTML:
<ui-select multiple
ng-model="ctrl.multipleDemo.type"
theme="bootstrap"
style="width: 800px;">
<ui-select-match placeholder="Select type...">{{$item}}</ui-select-match>
<ui-select-choices repeat="type in ctrl.people | unique : 'type'">
<div ng-bind-html="type | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
<pre>{{ ctrl.multipleDemo.type | json }}</pre>
<br><br>
<ui-select multiple
ng-model="ctrl.multipleDemo.name"
ng-disabled="!ctrl.multipleDemo.type.length"
theme="bootstrap"
style="width: 800px;">
<ui-select-match placeholder="Select name...">{{$item.name}}</ui-select-match>
<ui-select-choices repeat="person in ctrl.people | matchType : ctrl.multipleDemo.type">
<div ng-bind-html="person.name | highlight: $select.search"></div>
</ui-select-choices>
</ui-select>
<pre>{{ ctrl.multipleDemo.name | json }}</pre>
plunker: http://plnkr.co/edit/6aqPwuRwoJdHUmvFOquI?p=preview
TODO: when type is removed from the first select, make sure to remove persons with removed type from the second ng-model
Example code
There are three type web, tab and mobile in this json
Target :
1) ng-repeat limitTo:6
2) Type mobile limitTo: 2
{
type: 'web',
data: 'lipsum....'
},
{
type: 'mobile',
data: 'lipsum....'
},
{
type: 'tab',
data: 'lipsum....'
},
{
type: 'web',
data: 'lipsum....'
},
{
type: 'mobile',
data: 'lipsum....'
},
{
type: 'tab',
data: 'lipsum....'
}
Target :
1) ng-repeat limitTo:6
2) Type mobile limitTo: 2
<div ng-repeat="work in works.work | limitTo:6 | filter: ">
Not sure, this is what you required,
<div ng-repeat="res in data|filter:{type:'mobile'} | limitTo:2 ">
{{res.data}}
</div>
Working App
I'm using a Kendo UI Grid with AngularJS. The grid has a 'popup' mode editable kendo template. The grid invokes the create, destroy & delete functions; however the update function won't get called. Strangely when I change the edit mode to 'inline', the update function is called. Below are the code snippets from my application :
Main UI Grid:
<div class="container-fluid">
<kendo-grid style="margin-top: 2em" k-options="ctrl.fundGridOptions" k-scope-field="kgrid" id="myGrid"></kendo-grid>
</div>
Edit Template:
<script id="edit-template" type="text/x-kendo-template">
<div class="container">
<div class="well">
Fund :
<select kendo-drop-down-list k-options="ctrl.fundOptions" style="width: 130px;" ng-model="dataItem.GenevaId"></select>
<!--<select kendo-drop-down-list k-data-source="ctrl.funds" style="width: 130px;" ng-model="dataItem.GenevaId"></select>-->
NAV Change Threshold
<input kendo-numeric-text-box k-min="0" k-max="100" k-ng-model="value" style="width: 60px;" ng-model="dataItem.NAVThreshold" />
NAV Source
<select k-data-source="ctrl.navSources" kendo-drop-down-list k-option-label="'-Select-'" style="width: 130px;" ng-model="dataItem.NAVSource"></select>
Frequency
<select k-data-source="ctrl.frequencyList" kendo-drop-down-list k-option-label="'-Select-'" style="width: 130px;" ng-model="dataItem.Frequency"></select>
Type
<select k-data-source="ctrl.typeList" kendo-drop-down-list k-option-label="'-Select-'" style="width: 130px;" ng-model="dataItem.Type"></select>
</div>
<div kendo-grid="ctrl.currencyKendoGrid" style="margin-top: 2em" k-options="ctrl.currencyGridOptions"></div>
</div>
</script>
Grid Options:
ctrl.fundGridOptions = {
dataSource: {
transport: {
update: function (options) {
DataSvc.updateFund(e.data).then(function (response) {
e.success(e.data);
});
},
},
schema: {
model: {
id: "FundId",
fields: {
FundId: { type: "number", editable: false, nullable: true },
GenevaId: { type: "string", editable: true },
NAVThreshold: { type: "number", editable: true },
NAVSource: { type: "string", editable: true },
Frequency: { type: "string", editable: true },
Type: { type: "string", editable: true },
}
}
},
},
sortable: true,
columns: [
{ field: "GenevaId", title: "Fund Name" },
{ field: "NAVThreshold*100", title: "NAV Threshold", template: '#=kendo.format("{0:p}", NAVThreshold)#' },
{ field: "NAVSource", title: "NAV Source" },
{ field: "Frequency", title: "Frequency" },
{ field: "Type", title: "Type" },
{ command: ["edit", "destroy"], title: " " }
],
detailTemplate: kendo.template($("#detail-template").html()),
detailInit: function (e) {
kendo.bind(e.detailRow, e.data);
},
dataBound: function (e) {
var grid = e.sender;
if (grid.dataSource.total() == 0) {
var colCount = grid.columns.length;
$(e.sender.wrapper)
.find('tbody')
.append('<tr class="kendo-data-row"><td colspan="' + colCount + '" class="no-data">Sorry, no data :(</td></tr>');
}
},
editable: {
mode: "popup",
template: kendo.template($("#edit-template").html()),
window: {
title: "Edit Fund Details",
animation: false,
height: "600",
width: "1200"
}
},
edit: function (e) {
if (e.model.Currencies)
ctrl.currencyKendoGrid.dataSource.data(e.model.Currencies);
},
toolbar: [
{
name: 'create',
text: 'Add Fund',
}],
};
Could anyone help me understand the reason why the 'update' function won't be called in 'popup' mode, but gets called in 'inline' mode ? Appreciate any responses in advance.
I know this is question old, but I came across it searching for an answer. I think the issue might be that your (and my) edit template uses ng-model binding to edit the dataItem ie we're using angularjs. This doesn't actually seem to change the dirty property on the dataItem. I solved the issue by using ng-change on each control. It's a pain, but seems to work.
<input id="Title" type="text" class="k-textbox" ng-model="dataItem.Title" ng-change="dataItem.dirty=true"/>