combined properties in expression angularjs - javascript

I have a controller with contact object in his scope.
If the contact has first name or last name, I want to show first-name<space>last-name.
My problem is that when the contact has no first name or last name. In this situation I want to show the user Create new contact but because there is a space between the first name and last name in the expression, it displays only the spacing.
Start typing in the inputs and you will that, basically, both of divs should show the same.
angular.module('myApp', []).
controller('ctrl', function($scope) {
//$scope.contact = {
// FirstName: 'first',
// LastName: 'last'
//}
$scope.contact = {};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div data-ng-app="myApp" data-ng-controller="ctrl">
<input type="text" data-ng-model="contact.FirstName" placeholder="first name" />
<input type="text" data-ng-model="contact.LastName" placeholder="last name" />
<hr />
<!-- If I add space between first and last name it will never show 'Create new conttact' -->
{{contact.FirstName + ' ' + contact.LastName || 'Create new contact'}}<br />
{{contact.FirstName + contact.LastName || 'Create new contact'}}
</div>

You can use ng-if to fix your issue.
I have updated the code to match your requirements. Hope this helps.
angular.module('myApp', []).
controller('ctrl', function($scope) {
//$scope.contact = {
// FirstName: 'first',
// LastName: 'last'
//}
$scope.contact = {};
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div data-ng-app="myApp" data-ng-controller="ctrl">
<input type="text" data-ng-model="contact.FirstName" placeholder="first name" />
<input type="text" data-ng-model="contact.LastName" placeholder="last name" />
<hr />
<!-- If I add space between first and last name it will never show 'Create new conttact' -->
{{contact.FirstName + ' ' + contact.LastName}}
<span ng-if="(contact.FirstName == null || contact.FirstName == '') && (contact.LastName == null || contact.LastName == '')">Create New Contact</span>
</div>
There can be many ways this can be achieved. But since you want to achieve this in expressions only it can be done as below.. Just use the trim() in the expression.
Second solution:
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div data-ng-app="myApp" data-ng-controller="ctrl">
<input type="text" data-ng-model="contact.FirstName" placeholder="first name" />
<input type="text" data-ng-model="contact.LastName" placeholder="last name" />
<hr />
<!-- If I add space between first and last name it will never show 'Create new conttact' -->
{{(contact.FirstName + ' ' + contact.LastName).trim() || 'Create New Contact'}}
</div>

If I understand your question correctly you can just use ng-show/ng-hide:
<div data-ng-app="myApp" data-ng-controller="ctrl">
<span ng-show="contact.FirstName && contact.LastName">
{{contact.FirstName + ' ' + contact.LastName}}
</span>
<span ng-hide="contact.FirstName && contact.LastName">
Create new contact
</span>
</div>
Is that what you were looking for?

You here have 2 options 1 create a function that return true or false if you have first or last name or do the verification into html:
Solution 1:
angular.module('myApp', []).
controller('ctrl', function($scope) {
$scope.contact = {};
$scope.verifyContacts = function(){
return contact.FirstName || contact.LastName;
}
});
<div data-ng-app="myApp" data-ng-controller="ctrl">
<span ng-hide="verifyContacts()">Create new contact</span>
<span ng-show="verifyContacts()">{{contact.FirstName + ' ' + contact.LastName}}</span>
</div>
Soution 2:
This soution will invole to write the expresion form the verifyContacts function from above solution inline so your html will look like:
<div data-ng-app="myApp" data-ng-controller="ctrl">
<span ng-hide="contact.FirstName || contact.LastName">Create new contact</span>
<span ng-show="contact.FirstName || contact.LastName">{{contact.FirstName + ' ' + contact.LastName}}</span>
</div>
I personally prefer the first solution.
Edit: presenting the third solution:P
Solution 3:
You can add a space at the end of the first name if the first name is available so you don't need to concat the strings with space
angular.module('myApp', []).
controller('ctrl', function($scope) {
$scope.contact = {};
contact.FirstName = contact.FirstName ? contact.FirstName + ' ' : contact.FirstName;
}
});
<div> {{contact.FirstName + contact.LastName || 'Create new contact'}} </div>
this will work but as you can see in your code that the input fields are not displayed so you most probably will need a back-end function for that or something.

Related

Unable to load 2 angularJS components in sharepoint content editor webparts

I have a requirement where I need to load 2 angular components on the same page.
First I have taken a content editor web part and in the HTML source, I have pasted my angular code where I'm fetching list from SharePoint and then displaying on the page.
My first Custom Editor web part Code:
<div ng-app="myApp" ng-controller="myCtrl">
First Name:
<input type="text" ng-model="firstName">
<br> Last Name:
<input type="text" ng-model="lastName">
<br>
<br> Full Name: {{firstName + " " + lastName}}
</div>
<script>
var app = angular.module('myApp', []);
app.controller('myCtrl', function ($scope) {
$scope.firstName = "John";
$scope.lastName = "Doe";
});
</script>
Now, I have taken a new custom editor web part and almost written the same code with just the property name changes, but I'm unable to bind the angular to the second web part.
My second web part code:
<div ng-app="myApp1" ng-controller="myCtrl1"> First Name:
<input type="text" ng-model="firstName1"/>
<br/> Last Name:
<input type="text" ng-model="lastName1"/>
<br/>
<br/> Full Name: {{firstName1 + " " + lastName1}} </div>
<script>
var app = angular.module('myApp1', []);
app.controller('myCtrl1', function($scope) {
$scope.firstName1 = "John";
$scope.lastName1 = "Doe";
});
</script><br/>
Can anyone tell me the mistake I'm doing here?
I was able to load the first component properly.
I need to load 2 components on the same page.
You cannot use 2 ng-app directives on the same page. This is by design.
However, you can use multiple controllers and initialize your angular component using angular.bootstrap method.
Modify your first webpart code as below:
<div id="myApp" ng-controller="myCtrl">
First Name:
<input type="text" ng-model="firstName">
<br> Last Name:
<input type="text" ng-model="lastName">
<br>
<br> Full Name: {{firstName + " " + lastName}}
</div>
<script>
var myfirstAppDivId = document.getElementById('myApp');
angular.bootstrap(myfirstAppDivId, ['myApp']);
var myfirstApp = angular.module('myApp', []);
myfirstApp.controller('myCtrl', function ($scope) {
$scope.firstName = "John";
$scope.lastName = "Doe";
});
</script>
Modify your second webpart code as below:
<div id="myApp1" ng-controller="myCtrl1"> First Name:
<input type="text" ng-model="firstName1"/>
<br/> Last Name:
<input type="text" ng-model="lastName1"/>
<br/>
<br/> Full Name: {{firstName1 + " " + lastName1}} </div>
<script>
var mysecondAppDivId = document.getElementById('myApp1');
angular.bootstrap(mysecondAppDivId, ['myApp1']);
var mysecondApp = angular.module('myApp1', []);
mysecondApp.controller('myCtrl1', function($scope) {
$scope.firstName1 = "John";
$scope.lastName1 = "Doe";
});
</script><br/>

How access form in ng-repeat?

Here is clear exampel about forms:
<div ng-form="namesForm_{{$index}}" ng-repeat="name in names">
<input type="text"
name="input_{{$index}}_0"></input>
<!-- ... -->
Ok, but how I should access $valid field from form? E.g this does not work:
{{namesForm_$index.$valid}}
Even {{namesForm_$index}} outputs 0.
It is need to "inline" $index before {{}} resolve a variable name. How to do that?
It's not easy to get it inside of single {{ }} expression, but if you only want to use it in directives accepting expressions without handlebar (like ng-disabled), you can achieve that:
<div ng-app>
<ng-form name="namesForm_{{$index}}" ng-repeat="name in [1, 2]">
<input type="text"
placeholder="{{$index}}"
ng-required="true"
ng-model="test"
name="hey" />
<button ng-disabled="!namesForm_{{$index}}.$valid">
send
</button>
<br />
</ng-form>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.1/angular.min.js"></script>
{{ IsFormValid($index) }}
$scope.IsFormValid = function(index) {
var form = angular.element("formName" + index);
return form.$valid;
};
UPDATED
Working example:
{{ IsFormValid($index) }}
$scope.IsFormValid = function(index) {
var form = angular.element(document.getElementById('#bucketForm-' + index);
return form.$valid;
};
New Approach
The below is an example for dynamic ngModel, same can be replicated for form name :
$scope.formData = {};
$scope.formData = {
settings:
{
apiEndpoint: '',
method: 'get'
},
parameters: {}
};
<div class="form-group" ng-repeat="parameter in apiParameters">
<label for="{{parameter.paramName}}" class="col-sm-2 control-label">{{parameter.paramTitle}}</label>
<div class="col-sm-3">
<input type="text" class="form-control" name="{{parameter.paramName}}" id="{{parameter.paramName}}" ng-model="formData.parameters[parameter.paramName]" placeholder="{{parameter.paramTitle}}">
</div>
</div>

Angular - Form won't submit

I seem to be overlooking something simple here but it has me stumped.
Why does nothing happen when i hit the submit button?
<section ng-controller="SavingsController as savingsCTRL">
<form name="createSavingForm" class="form-horizontal" novalidate>
<fieldset>
<!-- Title Box Start-->
<div class="form-group new-deal-form" show-errors>
<label for="title">Title</label>
<input name="title" type="text" ng-model="savingsCTRL.title" id="title" class="form-control" placeholder="Title" required>
<div class="sub-label">Enter the Title of the Deal.</div>
<div ng-messages="savingForm.savingsCTRL.title.$error" role="alert">
<p class="help-block error-text" ng-message="required">Saving title is required.</p>
</div>
</div>
<!-- Title Box End-->
<!--Submit Button Start-->
<div class="form-group buttons-cancel-submit">
<button class="btn btn-default " ng-click="savingsCTRL.cancel()">Cancel</button>
<input type="submit" class="btn btn-success " ng-click="savingsCTRL.create(); submitForm(createSavingForm.$valid)" >
</div>
</fieldset>
</form>
</div>
</div>
</section>
for simplicity i took most of the forms out but what else is wrong?
Savings Controller Function
// Create new Saving
$scope.create = function () {
$scope.error = null;
alert("create");
// Create new Saving object
var saving = new Savings({
title: this.title,
details: this.details,
retailer: this.retailer,
price: this.price,
link: this.link,
image: $scope.user.imageURL,
urlimage: this.urlimage,
tags: this.tags
//startdate: this.startdate,
//enddate: this.enddate
});
// Redirect after save
saving.$save(function (response) {
$location.path('savings/' + response._id);
// Clear form fields
$scope.title = '';
$scope.details = '';
$scope.retailer = '';
$scope.price = '';
$scope.link = '';
$scope.image = '';
$scope.urlimage = '';
$scope.tags = '';
}, function (errorResponse) {
$scope.error = errorResponse.data.message;
});
};
Main issue is, you are mixing controller as syntax with $scope.
According to documentation, we should use this instead of $scope.
... binds methods and properties directly onto the controller using this: ng-controller = "SettingsController1 as settings"
Than, submitForm is not a predefined method, it should be defined in controller first
this.submitForm = function(isValid){
console.log('Submitting form: ' + isValid)
}
In addition to that, bind that to form with ng-submit= "savingsCTRL.submitForm(createSavingForm.$valid)"
See Plunker, with working code. (I took ng-click="savingsCTRL.create()", since we don't have all parts of your application)
Bind the form submit event to ng-submit.
Example: ng-submit="submitForm(createSavingForm.$valid)"

AngularJS: Creating Query Form for Database

So I am having a little problem creating a very simple query form due to my lack of understanding about coding. As you can see in the app.js below, I have FormController, which retrieves information from the form, feeds it into the jsonUrlGen function which creates a custom URL, which is then sent to my SolrController which accesses that URL and pulls the JSON information from it.
However it is quite clear after taking a step back and looking at it that the structure of my code is wrong, and I am missing an app.service to link the shared variables between my two controllers. I'm also not even sure if I need two controllers in this instance, but it just happened as I was coding it.
If anybody can tell me what I'm doing wrong here I would really appreciate it, because the code just flat out does not work.
Thanks.
.HTML FILE
<html ng-app="solrApp">
<head>
<link link rel="stylesheet" href="bootstrap-3.3.5-dist/css/bootstrap.min.css" />
<link link rel="stylesheet" href="style.css" />
<script src="https://code.angularjs.org/1.4.3/angular.min.js"></script>
<script type= "text/javascript" src="app.js"></script>
</head>
<body>
<!--<h1 class="headline">Logo or Something Here</h1>-->
<div class="logo"><img src="images/CubedE.png" id="cubedE"/></div>
<div class = "queryForm" ng-controller="FormController">
<input type="text" class="queryBox" id="mainQueryString" placeholder="Query String" ng-model="fullQuery.queryString"><br />
<input type="text" class="queryBox" placeholder="Filter Query" ng-model="fullQuery.filterQuery"><br />
<input type="text" class="queryBox" placeholder="Sort By" ng-model="fullQuery.sortBy"><br />
<h2>Extract only from rows:</h2>
<input type="text" class="halfQueryBox" placeholder="Start" ng-model="fullQuery.startRow"><input type="text" class="halfQueryBox" placeholder="End" ng-model="fullQuery.endRow"><br />
<input type="text" class="queryBox" placeholder="Field List (Separate by comma)" ng-model="fullQuery.fieldList"><br />
<input type="text" class="queryBox" placeholder="Raw Query Parameters (key1=val1&key2=val2)" ng-model="fullQuery.rawQuery"><br />
<button type="button" ng-click="jsonUrlGen()">Submit Query</button>
</div>
<div class = "results" ng-controller="SolrController">
<ul>
<li ng-repeat="item in items">
{{ item.key }} - <em>{{ item.value }}</em>
</li>
</ul>
</div>
</body>
</html>
APP.JS
(function(){
var app = angular.module('solrApp', []);
app.controller('FormController', function($scope) {
$scope.fullQuery = {
queryString: '',
filterQuery: '',
sortBy: '',
startRow: '',
endRow: '',
fieldList: '',
rawQuery: ''
}
$scope.jsonUrlGen = function(){
var jsonURL = "http://localhost:8983/solr/core/select?";
if($scope.fullQuery.queryString !== '') {
jsonURL = jsonURL + "q=" + $scope.fullQuery.queryString;
}
else if($scope.fullQuery.filterQuery !== '') {
jsonURL = jsonURL + "&fq=" + $scope.fullQuery.filterQuery;
}
else if($scope.fullQuery.sortBy !== '') {
jsonURL = jsonURL + "&sort=" + $scope.fullQuery.sortBy;
}
else if($scope.fullQuery.startRow !== '') {
jsonURL = jsonURL + "&start=" + $scope.fullQuery.startRow;
}
else if($scope.fullQuery.endRow !== '') {
jsonURL = jsonURL + "&rows=" + $scope.fullQuery.endRow;
}
else if($scope.fullQuery.fieldList !== '') {
jsonURL = jsonURL + "&fl=" + $scope.fullQuery.fieldList;
}
else {
return "exception thrown";
}
jsonURL = jsonURL + "wt=json";
return jsonURL;
};
});
app.controller('SolrController', function($scope, $http){
$http.get($scope.jsonUrlGen)
.then(function(res){
$scope.items = res.data;
});
});
})();
Answers may be opinionated since there are multiple ways to accomplish this.
I would advise to restructure html. Have a single controller that wraps the "form" and the contents of SolrController. Also the "form" should really become a <form>. In angular there is a default controller created for this tag and it helps a lot with managing validation and handling submit.
<div class="results" ng-controller="SolrController">
<form class="queryForm" name="queryForm" ng-submit="submit()">
<input type="text" class="queryBox" id="mainQueryString" placeholder="Query String" ng-model="fullQuery.queryString"><br />
<input type="text" class="queryBox" placeholder="Filter Query" ng-model="fullQuery.filterQuery"><br />
<input type="text" class="queryBox" placeholder="Sort By" ng-model="fullQuery.sortBy"><br />
<h2>Extract only from rows:</h2>
<input type="text" class="halfQueryBox" placeholder="Start" ng-model="fullQuery.startRow"><input type="text" class="halfQueryBox" placeholder="End" ng-model="fullQuery.endRow"><br />
<input type="text" class="queryBox" placeholder="Field List (Separate by comma)" ng-model="fullQuery.fieldList"><br />
<input type="text" class="queryBox" placeholder="Raw Query Parameters (key1=val1&key2=val2)" ng-model="fullQuery.rawQuery"><br />
<button ng-disabled="queryForm.$invalid">Submit Query</button>
</form>
<ul>
<li ng-repeat="item in items">
{{ item.key }} - <em>{{ item.value }}</em>
</li>
</ul>
</div>
Mind name attribute for the form. It will help to access the form in the scope. Actually when there is a name angular creates $scope.queryForm in parent controller
By default all buttons (and <input type="submit") on form submit on click. But type="button" will prevent it. So remove it
Controller SolrController. It's inappropriate to perform a request before user had a change to input something. $http.get should work on a click handler which we choose to be submit event.
app.controller('SolrController', function($scope, $http){
$scope.fullQuery = {};//ng-model will take care of creating all properties
function jsonUrlGen(){ //same code here
}
$scope.submit = function(){
$http.get(jsonUrlGen())
.then(function(res){
$scope.items = res.data;
});
});
};
})
Hope this helps

Edit the form and new form add text throw angular js

Hi ,
I m write a code I m showing the two section and one form for add new text in my projects.
But i have two major Problem .
is if i click to edit button than show the form but if i change any text in form than i click to save button there is a nothing happen .
is if i fill the data in new form and just press submit button not add the data in my top li Please check this and solve my problem .
Thanks in advanced
Please help me
My Code is here
Angular Code is this
var app = angular.module('myApp', []);
app.controller('mySearchController', function($scope) {
$scope.searhBars = [{
title: "fiel 1",
description: 'What do you want'
}, {
title: "fiel 2",
description: "I want to this"
}, {
title: "fiel 3",
description: "Why do you want me "
}];
$scope.formSubmit = function(searhBar) {
showForm = false;
};
$scope.newItemAdd = function(title, description) {
if (this.newName === '') return;
$scope.searhBar.push({
title: title,
description: description
});
this.newName = '';
this.newDes = '';
};
});
HTML Code is
<body ng-app="myApp">
<ul ng-controller="mySearchController">
<li>Hello</li>
<li ng-repeat="searhBar in searhBars">
<h4 ng-show="!showForm">{{searhBar.title}}</h4>
<p ng-show="!showForm">{{searhBar.description}}</p>
<button ng-show="!showForm" ng-click="showForm=true">Edit me</button>
<form ng-submit="formSubmit(searhBar)" ng-show="showForm">
<label>Field 1.
<input type="text" ng-model="searhBar.title" />
</label>
<label>Enter Description
<textarea ng-model="searhBar.description"></textarea>
</label>
<input type="submit" value="Save" />
</form>
</li>
<li>
<form ng-submit="newItemAdd(newName, newDes)">
<label>Field
<input type="text" ng-model="newName" />
</label>
<label>Enter Description
<textarea ng-model="newDes"></textarea>
</label>
<input type="submit" value="submit" />
</form>
</li>
</ul>
</body>
Demo is
Is this what you wanted?
http://plnkr.co/edit/9ginpPiLUaVyEPdpu32f?p=preview
I fixed this part:
$scope.formSubmit = function(){
this.showForm = false;
};
$scope.newItemAdd = function(title, description){
if(this.newName === '') return ;
$scope.searhBars.push({
title:title,
description:description
});
this.newName= '';
this.newDes= '';
};
And this one:
<input type="submit" ng-click="formSubmit()" />
Oh, I also fixed this:
<label>Field {{$index + 1}}:
In order to display the correct number of the field.
Typo: $scope.searhBar[s].push({
for close form
<form ng-submit="formSubmit(searhBar); showForm=false"
http://plnkr.co/edit/Vq3U3sCcp4OeZlH1iXyM?p=preview
You need to write:
$scope.formSubmit = function(searhBar){
this.showForm = false;
};

Categories