ASP.NET MVC and AngularJS - submitting a dynamic list to the controller - asp.net

I don't know how I look for this or how this method is called, but what I am trying to do is adding items dynamically with a form using AngularJS.
This is all working fine, but how are these items passed to the controller when submitted?
These are snippets from code:
AngularJS part:
angular
.module('Administration', [])
.controller('addParents', ['$scope', function ($scope) {
$scope.parents = [];
$scope.addParent = function () {
$scope.parents.push({
'firstname': $scope.Firstname,
'lastname' : $scope.Lastname,
'done': false
})
$scope.Firstname = ''
$scope.Lastname = ''
}
$scope.deleteParent = function (index) {
$scope.parents.splice(index, 1);
}
}])
The list:
<div role="tablist" aria-multiselectable="true" class="panel-group" id="accordion-1">
<div class="panel panel-default {'fadeOut' : parent.done}" ng-repeat="parent in parents">
<div role="tab" class="panel-heading">
<h4 class="panel-title"><a role="button" data-toggle="collapse" data-parent="#accordion-1" aria-expanded="true" href="#accordion-1 .item-1">{{parent.firstname}}</a> <span class="fa fa-close pull-right" ng-click="deleteParent($index)"></span></h4>
</div>
<div role="tabpanel" class="panel-collapse collapse in item-1">
<div class="panel-body">
<fieldset>
<legend>Personal</legend>
<div class="form-group row">
<label class="col-sm-2 col-form-label">Firstname</label>
<div class="col-sm-10">
<p class="form-control-static">{{parent.firstname}}</p>
</div>
</div>
<div class="form-group row">
<label class="col-sm-2 col-form-label">Lastname</label>
<div class="col-sm-10">
<p class="form-control-static">{{parent.lastname}}</p>
</div>
</div>
</fieldset>
</div>
</div>
</div>
</div>
As you can see I am using an accordion, it is a personal touch to have a nice layout of added items and to have a nice overview of all items.
Hope you can help me in this issue or give me some usefull links
Thanks!

Related

VueJS3 : radio v-model doesn't update when switch changed

I want my input radio that is default checked to update the value in the v-model. But when I switch plan the v-model doesn't update dynamically. I'm stuck. Maybe I have to take a look at "watch" or "ref".
My formValues is reactive and returns the good answer in the v-model. But when I switch plan... doesn't update the check output.
<template>
<!-- Second step -->
<section id="second-step">
<div class="row mt-4 px-2">
<div class="col-12">
<h1 class="h2 fw-bold">Select your plan</h1>
<p class="pt-1">
You have the option of monthly or yearly billing.
</p>
</div>
</div>
<!-- Form 2 -->
<form class="row justify-content-xl-between px-3 pe-xl-0" id="form-plan">
<!-- Plan 1 -->
<div class="col-12 col-xl plan mt-3 p-0">
<label for="arcade-plan" class="plan-label"></label>
<input v-model="check" type="radio" v-if="formValues.billing.monthly" :value="formValues.plan[0].name" name="plan" id="arcade-plan" checked>
<input v-model="check" type="radio" v-else="formValues.billing.yearly" :value="formValues.plan[1].name" name="plan" id="arcade-plan" checked>
<div class="plan-content card ps-2">
<div class="plan-icon mt-1">
<img src="assets/images/icon-arcade.svg" alt="">
</div>
<div class="plan-description">
<span class="plan-title mb-0">Arcade</span>
<div class="price monthly">
<div class="amount mb-0 fs-6 fw-medium text-cool-gray">$9/mo</div>
</div>
<div class="price yearly d-none">
<div class="amount fs-6 fw-medium text-cool-gray">$90/yr</div>
<div class="billing-msg text-primary">2 months free</div>
</div>
</div>
</div>
</div>
<!-- Plan 2 -->
<div class="col-12 col-xl plan mt-3 p-0">
<label for="advanced-plan" class="plan-label"></label>
<input v-model="check" type="radio" v-if="formValues.billing.monthly" :value="formValues.plan[2].name" name="plan" id="advanced-plan">
<input v-model="check" type="radio" v-else="formValues.billing.yearly" :value="formValues.plan[3].name" name="plan" id="advanced-plan">
<div class="plan-content card ps-2">
<div class="plan-icon mt-1">
<img src="assets/images/icon-advanced.svg" alt="">
</div>
<div class="plan-description">
<span class="plan-title mb-0">Advanced</span>
<div class="price monthly">
<div class="amount mb-0 fs-6 fw-medium text-cool-gray">$12/mo</div>
</div>
<div class="price yearly d-none">
<div class="amount fs-6 fw-medium text-cool-gray">$120/yr</div>
<div class="billing-msg text-primary">2 months free</div>
</div>
</div>
</div>
</div>
<!-- Plan 3 -->
<div class="col-12 col-xl plan mt-3 p-0">
<label for="pro-plan" class="plan-label"></label>
<input v-model="check" type="radio" v-if="formValues.billing.monthly" :value="formValues.plan[4].name" name="plan" id="pro-plan">
<input v-model="check" type="radio" v-else="formValues.billing.yearly" :value="formValues.plan[5].name" name="plan" id="pro-plan">
<div class="plan-content card ps-2">
<div class="plan-icon mt-1">
<img src="assets/images/icon-pro.svg" alt="">
</div>
<div class="plan-description">
<span class="plan-title mb-0">Pro</span>
<div class="price monthly">
<div class="amount mb-0 fs-6 fw-medium text-cool-gray">$15/mo</div>
</div>
<div class="price yearly d-none">
<div class="amount fs-6 fw-medium text-cool-gray">$150/yr</div>
<div class="billing-msg text-primary">2 months free</div>
</div>
</div>
</div>
</div>
<!-- Switch billing -->
<div class="col-12 py-3 rounded">
<div class="row bg-alabaster justify-content-center px-2">
<div class="col-10 col-sm-8 col-md-6">
<div class="switch-wrapper py-2 mb-0">
<input id="monthly" type="radio" name="switch" checked>
<input id="yearly" type="radio" name="switch">
<label id="billing-monthly" for="monthly" class="mx-sm-5">Monthly</label>
<label id="billing-yearly" for="yearly" class="mx-sm-5">Yearly</label>
<span class="toggler"></span>
</div>
</div>
</div>
</div>
</form>
</section>
<div class="container">
Selected :
{{ check }}
</div>
</template>
<script>
import { onMounted } from 'vue';
export default {
data() {
return {
check: 'Arcade (Monthly)'
}
},
props: {
step: Number,
formValues: Object
},
setup(props) {
onMounted(() => {
const switchInputs = document.querySelectorAll(".switch-wrapper input");
const prices = document.querySelectorAll(".price");
const toggleClass = "d-none";
/* Switch */
for (const switchInput of switchInputs) {
switchInput.addEventListener("input", function () {
for (const price of prices) {
price.classList.add(toggleClass);
}
const activePrices = document.querySelectorAll(
`.price.${switchInput.id}`
);
for (const activePrice of activePrices) {
activePrice.classList.remove(toggleClass);
}
/* Change billing type */
props.formValues.updateBilling()
console.log(props.formValues.billing.yearly)
})
}
})
}
}
</script>
I didn't find any sources about this problem yet. I think I can do something with a watch or ref.
I think that you're overcomplicating things.
Computed properties are used when you need to combine multiple reactive properties. In this case it would be the message output on selected plan + period.
Here is a working example in CodeSandbox.
Also, you are not using conditional rendering properly, which may be why your data isn't updating correctly.
v-if="logical expression"
v-else-if="logical expression"
v-else
References:
Computed properties
Conditional rendering
Here is a very basic sample of Radio input binding with Vue:
const { createApp } = Vue;
const App = {
data() {
return {
check: 'Arcade (Monthly)',
items: ['Arcade (Monthly)', 'Advanced (Monthly)']
}
}
}
const app = createApp(App)
app.mount('#app')
<div id="app">
<div>Picked: {{ check }}</div><br />
<div v-for="(item, index) in items">
<input type="radio" :id="`item_${index}`" :value="item" v-model="check" />
<label :for="`item_${index}`">{{item}}</label>
</div>
</div>
<script src="https://unpkg.com/vue#3/dist/vue.global.prod.js"></script>

How to develop search suggestion text box using angular 2/4

I'am new in Angular. How can i develop a drop down suggestion search box in angular 2/4. when clicking on search button the details are shown using below codes.But am trying while typing on text box the suggestion details need to show. same like Auto complete (During searching, ‘as-you-type’ suggestion to be displayed.)
component.HTML
<form role="form">
<div class="row">
<div class="form-group">
<div class="input-group">
<input name="search"
class="form-control"
type="text"
placeholder="Search"
required="" [(ngModel)]='searchcontent'>
<span class="input-group-btn">
<button
class="btn btn-success ProductSearchBtn"
type="button"
(click)='FetchItemDetailsSearch(searchcontent)'>
<i class="glyphicon glyphicon-search"
aria-hidden="true"></i>
<span style="margin-left:10px;">Search</span>
</button>
</span>
</div>
</div>
</div>
</form>
</div>
</section>
<section class="CommonsubWhiteBg"
style='height:850px;overflow-y:scroll; overflow-x:hidden'
(scroll)="onScroll($event)">
<ng-container *ngFor="let item of itemdetails;">
<article class="row" style="margin:0px;">
<div class="col-md-12 col-sm-12 col-xs-12 EnquiryMore">
<a [routerLink]="['/productdetails',item.ItemID]">
<h5>{{item.ItemCode + ' - ' + item.ItemDescription}}</h5>
</a>
</div>
</article>
</ng-container>
<ng-container *ngIf="!itemdetails" style="margin:0px;">
<article class="col-md-12">
<h3>Loading data...</h3>
</article>
</ng-container>
<ng-container *ngIf="itemdetails&&itemdetails.length==0"
class="ItemNotfoundArea row" style="margin:0px;">
<article class="col-md-12">
<h1>Sorry</h1>
<p>Item Not Found</p>
</article>
</ng-container>
</section>
component.ts file
FetchItemDetailsSearch(itemcodeordesc: string): void {
this.pageIndex = 1;
this.searchflag = 1;
if (itemcodeordesc.length > 0)
this.searchcontent = itemcodeordesc;
else {
itemcodeordesc = undefined
this.searchcontent = itemcodeordesc;
}
this.prevScrollPosition = 0;
this._enqService
.FetchItemDetailsSearch(this.searchcontent, this.pageIndex)
.subscribe(itemsData => this.itemdetails = itemsData,
error => {
console.error(error);
this.statusMessage =
"Problem with the service.Please try again after sometime";
}
);
}
**Service.ts **
FetchItemDetailsSearch(itemcodeordesc: string, pageIndex: number):
Observable<IEnquiryDetails[]> {
return this._http.get('http://localhost:1234/api/enquirydetails/',
{ params:
{ itemcodeordesc: itemcodeordesc,
pageIndex: pageIndex }
})
.map((response: Response) => <IEnquiryDetails[]>response.json())
.catch(this.handleError)
}
condition: trying only with Angular 4/2 not jQuery
Take a look at angular material auto complete component.
https://material.angular.io/components/autocomplete/examples.
You can also have your own custom filter function. Below sample code would give you a way out to achieve the same.
https://stackblitz.com/angular/krlrmgepmrv?file=app%2Fautocomplete-filter-example.ts
or
Try this
http://www.angulartutorial.net/2017/03/simple-search-using-pipe-in-angular-2.html
Please check this answer
<form role="form">
<div class="row">
<div class="form-group">
<div class="input-group">
<input name="search" class="form-control" type="text" placeholder="Search" (keyup)="FetchItemDetailsSearch(searchcontent)" [(ngModel)]="searchcontent">
<span class="input-group-btn">
<button class="btn btn-success ProductSearchBtn" type="button" (click)='FetchItemDetailsSearch(searchcontent)'><i class="glyphicon glyphicon-search" aria-hidden="true"></i><span style="margin-left:10px;">Search</span></button>
</span>
</div>
</div>
</div>
</form>
You can use auto complete plugin like this .

AngularJS1 : ng-blur inside the ng-if

I'm trying to use ng-blur. Below is my HTML code:
<div ng-if="CurrentStage==='SaveQuery'">
<div class="col-sm-12">
<div class="form-group row">
<label class="col-sm-3 control-label text-right">Query Name</label>
<div class="col-sm-9">
<input type="text" ng-blur="performValidationQueryName()" ng-model="QueryName" ng-class="QueryNameError?'form-control validation_error':'form-control'" placeholder="Query Name" />
<span ng-if="QueryNameErrorMsg!=''" class="errorMsg">{{QueryNameErrorMsg}}</span>
</div>
<div class="clearfix"></div>
</div>
</div>
</div>
JavaScript code for blur event call is:
$scope.performValidationQueryName = function () {
if($scope.QueryName != null && $scope.QueryName != '') {}
};
The issue I'm facing is:
When ng-if="CurrentStage==='SaveQuery'" is there inside div, my ng-model="QueryName" is not getting updated. And with blur of the text, I get $scope.QueryName = "" with performValidationQueryName function.
If, I remove ng-if="CurrentStage==='SaveQuery'", all things works perfectly and I get the value inside the $scope.QueryName.
How can I call ng-blur which is placed inside the div with an ng-if condition?
You should use object in your input model will solve your problem because it comes under ng-if as shown below,
Template:
<div ng-if="CurrentStage==='SaveQuery'">
<div class="col-sm-12">
<div class="form-group row">
<label class="col-sm-3 control-label text-right">Query Name</label>
<div class="col-sm-9">
<input type="text" ng-blur="performValidationQueryName(Query.Name)" ng-model="Query.Name" ng-class="QueryNameError?'form-control validation_error':'form-control'" placeholder="Query Name" />
<span ng-if="QueryNameErrorMsg!=''" class="errorMsg">{{QueryNameErrorMsg}}</span>
</div>
<div class="clearfix"></div>
</div>
</div>
</div>
Controller:
$scope.performValidationQueryName = function (queryName) {
if (queryName != null && queryName != ''){
//do something..
}
};

Semantic.ui dropdown not working with React.js

I'm trying to use Semantic.ui's dropdown in my Meteor.js + React.js app. Everything else with Semantic.ui works fine, but I can't make the dropdown menu work. Here's my code:
NavigationMain = React.createClass({
componentDidMount() {
$('.ui.dropdown.right').dropdown();
},
componentDidUpdate() {
$('.ui.dropdown.right').dropdown('refresh');
},
_openChat(){
console.log("click");
},
render(){
return (
<div className="ui top attached menu">
<div className="ui dropdown icon item" onClick={this._openChat}>
<i className="comments outline icon"></i>
</div>
<div className="ui dropdown right icon item">
<i className="wrench icon"></i>
<div className="menu">
<div className="item">
<i className="dropdown icon"></i>
<span className="text">New</span>
<div className="menu">
<div className="item">Document</div>
<div className="item">Image</div>
</div>
</div>
<div className="item">
Open...
</div>
<div className="item">
Save...
</div>
<div className="item">Edit Permissions</div>
<div className="divider"></div>
<div className="header">
Export
</div>
<div className="item">
Share...
</div>
</div>
</div>
</div>
);
}
});
I have also tried using Reacts ref attribute to reference the element like this:
$(this.refs.menu).dropdown();
But it doesn't seem to help either.
All the examples I've found, for example the Semantic.ui's official integration doc (http://semantic-ui.com/introduction/integrations.html), work like this and I've made it work before without React. That's why I'm starting to feel helpless.
Any help with this would be appreciated.
Works for me.
var Content = React.createClass({
componentDidMount: function() {
$('.ui.dropdown').dropdown()
},
render: function () {
return <div className="ui dropdown">
<div className="text">File</div>
<i className="dropdown icon" />
<div className="menu">
<div className="item">New</div>
<div className="item">
<span className="description">ctrl + o</span>
Open...
</div>
<div className="item">
<span className="description">ctrl + s</span>
Save as...
</div>
<div className="item">
<span className="description">ctrl + r</span>
Rename
</div>
<div className="item">Make a copy</div>
<div className="item">
<i className="folder icon" />
Move to folder
</div>
<div className="item">
<i className="trash icon" />
Move to trash
</div>
<div className="divider"></div>
<div className="item">Download As...</div>
<div className="item">
<i className="dropdown icon" />
Publish To Web
<div className="menu">
<div className="item">Google Docs</div>
<div className="item">Google Drive</div>
<div className="item">Dropbox</div>
<div className="item">Adobe Creative Cloud</div>
<div className="item">Private FTP</div>
<div className="item">Another Service...</div>
</div>
</div>
<div className="item">E-mail Collaborators</div>
</div>
</div>
}
});
ReactDOM.render(
<Content />,
document.getElementById('container')
);
Here is a fiddle
https://jsfiddle.net/85z7o3n2/

Angular-material's tabs and ui-bootstrap's datepicker conflict

I have a modal window with angular-material tabs and a ui-bootstrap datepicker. When I open datepicker, the text field moves up, and I cannot access either the datepicker or the field.
Here's a demo in jsFiddle
Here's my code:
var app = angular.module('myApp', ['ui.bootstrap', 'ngAnimate', 'ngAria', 'ngMaterial'])
.controller('myController', function ($scope, $modal) {
$scope.showModal = function () {
var modalInstance;
modalInstance = $modal.open({
templateUrl: "addNew.html",
controller: 'myController2',
size: 'lg'
});
};
$scope.showModal();
})
.controller('myController2', function ($scope, $modal) {
$scope.datepickers = {
start: false
}
$scope.openDatepicker = function ($event, which) {
$event.preventDefault();
$event.stopPropagation();
$scope.datepickers[which] = true;
};
$scope.dateOptions = {
formatYear: 'yy',
startingDay: 1
};
$scope.dateFormat = 'mediumDate';
});
<div ng-app="myApp">
<div ng-controller="myController">
<script type="text/ng-template" id="addNew.html">
<div class="modal-body">
<div class="panel panel-default">
<div class="panel-heading">
<h3 class="panel-title">Add</h3>
</div>
<div class="panel-body">
<md-tabs md-dynamic-height md-border-bottom>
<md-tab label="date">
<div class="form-horizontal">
<div class="row">
<div class="col-md-6">
<div class="row form-group">
<label for="dateStart" class="col-sm-2 col-md-4 control-label">
Date Start
</label>
<div class="col-sm-10 col-md-8">
<div class="input-group ui-datepicker">
<input type="text"
class="form-control"
name="dateStart"
id="dateStart"
datepicker-popup="{{dateFormat}}"
ng-model="campaign.dateStart"
is-open="datepickers.start"
datepicker-options="dateOptions"
ng-required="true"
ng-click="openDatepicker($event, 'start')"
close-text="Close"/>
<span class="input-group-addon" ng-click="openDatepicker($event, 'start')">
<i class="glyphicon glyphicon-calendar"></i>
</span>
</div>
</div>
</div>
</div>
</div>
</div>
</md-tab>
<md-tab label="other tabs"></md-tab>
<md-tab label="other tabs"></md-tab>
<md-tab label="other tabs"></md-tab>
<md-tab label="other tabs"></md-tab>
</md-tabs>
</div>
</div>
</div>
</script>
</div>
</div>
I used a css trick to add the scroll bar in this fiddle, but it's not very neat. So I was wondering if there is a way to expand the tab height when the datepicker is opened or the datepicker is shown over a modal window like the select window opens.
You'll want to have the dropdown datepicker appear as part of the regular document flow, that way it will occupy space and the tab picker will automatically make room for it. It doesn't do that currently because it uses .dropdown-menu, to which Bootstrap adds position: absolute;
Just override like this:
.dropdown-menu[datepicker-popup-wrap] {
position: static;
}
There are some other stylistic things you can do, but that is the basic principle.
Demo in jsFiddle

Resources