Issue with nested ng-controller in Angularjs - angularjs

I am stuck with strange issue. Actually I am fetching the data from ajax and showing it on text boxes.
So, basically I have 3 text box (City, City1, City2). By default City textbox is visible rest will show if they have data from Ajax.
User can add city by clicking + button or remove by click on - button.
I am able to fetch and show the data properly on textboxes.
But when I want to add/show City1 or City by clicking on + button. It is simply executing form submit event.
Here is code for Ajax call.
formApp.controller('getprofile', function($scope,$http){
$http({
url: 'get_job_city.php',
method: "GET",
params: {uid: uid}
})
.success(function(data) {
if (data.success) {
$scope.formData.city1 = data.city1;
$scope.formData.city = data.city;
$scope.formData.city2 = data.city2;
}
});
})
Code for form save and show hide city textboxes.
var formApp = angular.module('formApp', []);
formApp.controller('formProfile1', function($scope,$http){
$scope.secondcity1city1 = false;
$scope.thirdcity2 = false;
$scope.hidecity1 = function() { $scope.secondcity1 = false; }
$scope.hidecity2 = function() { $scope.thirdcity2 = false; }
$scope.showcity = function() { $scope.secondcity1 = true; }
$scope.showcity1 = function() { $scope.thirdcity2 = true; }
$scope.formData = {};
$scope.formprofile1 = function() {
$scope.ajaxload = true;
var allData={'formData': $scope.formData, 'uid': uid}
$http({
method : 'POST',
url : 'city_update_exec.php',
data : allData,
headers : { 'Content-Type': 'application/x-www-form-urlencoded' } // set the headers
})
.success(function(data) {
$scope.ajaxload = false;
if (!data.success) {
$scope.errorcity = data.errors.city;
$scope.errorcity1 = data.errors.city1;
$scope.errorcity2 = data.errors.city2;
}else{
alert('City has been updated.');
}
});
};
})
HTML codes are below.
<div class="container" ng-controller="formProfile1">
<form name="formProfile1" method="post" id="formProfile1"
ng-submit="formprofile1()" role="form">
<div ng-controller ="getprofile">
<div id="firstcity">
<div class="col-xs-10">
<div class="topjob_resumetitle" ng-class="{ 'has-error' : errorcity }">
<input name="city" id="city" type="text"
class="form-control textbox1 txt-auto"
required="required" placeholder="Job Location* "
ng-model="formData.city">
<div class = "errorba" ng-show="errorcity">{{errorcity}}
</div>
</div>
</div>
<div class="col-xs-2">
<!--<button class="remove" ng-click="removeChoice()">-</button>-->
</div>
<button class="addfields" ng-click="showcity()">+</button><br>
</div>
<div ng-show="secondcity1">
<div class="col-xs-9"><div class="topjob_resumetitle" ng-class="{ 'has-error' : errorcity1 }">
<input name="city1" id="city1" type="text"
class="form-control textbox1 txt-auto"
placeholder="Job Location* " ng-model="formData.city1">
<div class = "errorba" ng-show="errorcity">{{errorcity1}}
</div>
</div>
</div>
<div class="col-xs-3">
<button class="remove" ng-click="hidecity1()">-</button>
<button class="addfields" ng-click="showcity1()">+</button><br>
</div>
</div>
<div ng-show="thirdcity2">
<div class="col-xs-10"><div class="topjob_resumetitle"
ng-class="{ 'has-error' : errorcity2 }">
<input name="city2" id="city2" type="text"
class="form-control textbox1 txt-auto"
placeholder="Job Location* "
ng-model="formData.city2">
<div class = "errorba" ng-show="errorcity2">{{errorcity2}}
</div>
</div>
</div>
<div class="col-xs-2">
<button class="remove" ng-click="hidecity2()">-</button>
</div>
More text boxes are here
</div>

The problem is that you have not set a type for your buttons, and therefore are defaulting to submit types, which will submit the first parent form found in the DOM when clicked. To allow your custom click handlers to execute properly, change your button types to "button" like so:
<button type="button" class="addfields" ng-click="showcity()">+</button><br>

Remove method="post" and add novalidate on form tag it will stop html5 validation
<form name="formProfile1" novalidate id="formProfile1"
ng-submit="formprofile1()" role="form">
Also if its still not works then change all your button to
<input type="button">//for rest of the buttons
<input type="submit">//for submit button

To make an http request you don't need to use the separate controller. Use factory method in your code for ajax and inject it as a dependency in your controller. Refer Angular Factory method

Related

After uncheck the checkbox value is not inserted in mvc application

I have one checkbox and one textbox, now when I check the checkbox and write text in textbox at that time checkbox value and textbox value is inserted, but when I am uncheck the checkbox and write the text in textbox at that time textbox value is not inserted in database.
Here is my code
I used enum value for checkbox and textbox
Here is the enum code
public enum ChassisJobTypeEnum
{
LinerChange = 1,
ChainSetChange = 2
}
Here is the view design code
<div class="form-group row">
<label class="col-sm-3 col-form-label">Change Linear</label>
<div class="col-sm-3">
<input type="checkbox" class="form-group" id="ChassisJob#((int)ChassisJobTypeEnum.LinerChange)_Checked" placeholder="" />
</div>
<div class="col-sm-3">
<input type="text" class="form-group" id="ChassisJob.#((int)ChassisJobTypeEnum.LinerChange)_OtherJob" placeholder="" />
</div>
</div>
<div class="form-group row">
<label class="col-sm-3 col-form-label">Change Chain Set</label>
<div class="col-sm-3">
<input type="checkbox" class="form-group" id="ChassisJob#((int)ChassisJobTypeEnum.ChainSetChange)_Checked" placeholder="" />
</div>
<div class="col-sm-3">
<input type="text" class="form-group" id="ChassisJob.#((int)ChassisJobTypeEnum.ChainSetChange)_OtherJob" placeholder="" />
</div>
</div>
<div class="form-group row">
<div class="col-sm-12">
<button type="submit" class="btn btn-primary" id="submit-form">Submit</button>
</div>
</div>
Now, when submit the form at that time ajax is calling to the controller
$('form').submit(function (event) {
event.preventDefault();
var chassisJobs = [];
chassisJob = {
ChassisJobsTypeId: #((int)ChassisJobTypeEnum.LinerChange),
Checked: $("#ChassisJob#((int)ChassisJobTypeEnum.LinerChange)_Checked").prop('checked'),
OtherJob: document.getElementById("ChassisJob.#((int)ChassisJobTypeEnum.LinerChange)_OtherJob").value,
};
chassisJobs.push(chassisJob);
chassisJob = {
ChassisJobsTypeId: #((int)ChassisJobTypeEnum.ChainSetChange),
Checked: $("#ChassisJob#((int)ChassisJobTypeEnum.ChainSetChange)_Checked").prop('checked'),
OtherJob: document.getElementById("ChassisJob.#((int)ChassisJobTypeEnum.ChainSetChange)_OtherJob").value,
};
chassisJobs.push(chassisJob);
var serviceJobData = {
'Id': document.getElementById("Id").value,
'ChassisJob': chassisJobs
};
$.ajax({
type: "POST",
url: '/ServiceJob/AddUpdate',
data: serviceJobData,
dataType: "json",
success: function (data) {
if (data.success == true) {
alert("Data has been update successfully");
//RefreshTable();
location.reload(true);
// set focus on edit form
document.getElementById("service-job-list").scrollIntoView();
//reste form
var frm = document.getElementsByName('service-job-form')[0];
frm.reset();
}
else {
alert("Unable to insert data")
}
error: function (xhr, ajaxOptions, thrownError) {
alert('Failed to add Detail.');
}
});
});
Here is the controller in which the addupdate method is calling at submit button.
[HttpPost]
public IActionResult AddUpdate(ServiceJobModel model)
{
ServiceJob serviceJob = new ServiceJob();
bool iSInsertData = true;
var chassisJobs = _Db.ChassisJob.Where(x => x.ServiceJobId == model.Id).ToList();
if (chassisJobs.Any())
{
_Db.ChassisJob.RemoveRange(chassisJobs);
_Db.SaveChanges();
}
return Json(new { success = true });
}
Now, this is code which I tried.
For more clear, let see task image.
When I check the checkbox and enter the value in textbox at that time insert data properly and at the fetch time it shows the checkbox and textbox value properly.
now, when I uncheck the checkbox and enter the value in textbox at that time data is not inserted and at the fetch time it does not show any thing.
If you any issue to understand the question then feel free to ask.

ng-show not watching variable change

I have a progress bar I want to show after I click a button.
I set my variable to true on click, yet it's not working.
The ng-show in question is on the bottom of the html, and the button i click is on a different html page but i didn't include because it uses the successOnClick function in this same controller. I console logged the isEmailing variable inside the onclick and it is assigned true. Doesn't work for ng-if either
What gives?
module.exports = app => {
app.controller('ContactController', ($scope, $http) => {
$scope.isEmailing = false;
$scope.email = (e) => {
$scope.isEmailing = true;
const requestBody = {};
const id = e.target.id;
requestBody.name = document.getElementById(`${id}-name`).value;
requestBody.email = document.getElementById(`${id}-email`).value;
requestBody.subject = document.getElementById(`${id}-subject`).value;
requestBody.body = document.getElementById(`${id}-body`).value;
$http.post('/email', JSON.stringify(requestBody), {
'Content-Type': 'application/json'
})
.then(res => {
console.log('Success!');
document.getElementById(`${id}-name`).value = '';
document.getElementById(`${id}-email`).value = '';
document.getElementById(`${id}-subject`).value = '';
document.getElementById(`${id}-body`).value = '';
$scope.isEmailing = false;
})
.catch(err => {
console.log('Error!');
$scope.isEmailing = false;
})
}
$scope.successOnClick = () => {
$scope.isEmailing = true;
}
})
}
<footer class="footer" ng-controller="ContactController">
<div class="footer__block social-media-container">
<div class="social-media">
<img src="http://i.imgur.com/bVqv5Kk.png" alt="fb-icon">
<img src="http://i.imgur.com/sJWiCHV.png" alt="twitter-icon">
<img src="http://i.imgur.com/o7yTVyL.png" alt="insta-icon">
</div>
</div>
<div class="footer__block">
<form class="footer__form" ng-submit="email($event)" id="footer">
<textarea placeholder="Message" id="footer-body" required></textarea>
<input type="text" placeholder="Name" id="footer-name" required>
<input type="email" placeholder="Email" id="footer-email" required>
<input type="text" placeholder="Subject" id="footer-subject" required>
<input type="submit" placeholder="Email">
</form>
</div>
<div class="footer__block mailing-list">
<span>Join our Mailing List!</span>
<form>
<input type="email" placeholder="Email" required>
<input type="submit">
</form>
</div>
<!-- <div class="grey-screen">
<div class="success">
<h1>Success!</h1>
</div>
</div> -->
<div class="progress-bar" ng-show="isEmailing">
</div>
</footer>
If you have several controller of same type it is not mean, that they all are same the instance. AngularJS creates controllers not via singleton pattern. You should synchronize them by yourself by means of events:
angular.module('app', [])
.controller('MyController', ['$scope', '$rootScope', function($scope, $rootScope) {
$rootScope.$on('Changed', function(event, data){
$scope.isEmailing = data;
})
$scope.successOnClick = function(){
$scope.$emit('Changed', !$scope.isEmailing);
}
}]);
<script src="//code.angularjs.org/snapshot/angular.min.js"></script>
<div ng-app="app">
<div ng-controller="MyController">
<h3 ng-style="{'background-color' : isEmailing ? 'red' : 'white'}">First controller</h3>
<input type='button' ng-click='successOnClick()' value='Change color'/>
</div>
<div ng-controller="MyController">
<h3 ng-style="{'background-color' : isEmailing ? 'red' : 'white'}">Second controller</h3>
<input type='button' ng-click='successOnClick()' value='Change color'/>
</div>
</div>
If one controller located inside another you can try to use $scope.$parent.isEmailing(where .$parent can be typed several times, depending on nesting level), but it is very uncomfortable. If your controllers located at different routes, you should pass data from one controler to another via route parameters or custom AngularJS service or $rootScope.

angular: form submit with dynamic dropdown list

I have a small form and in that form i have a drop down list. List items are generated dynamically.
$http({
url: 'alljobs.php',
method: "GET",
params: {
uid: viewer_id
}
}).success(function(data) {
$scope.jobss = data.content;
});
Below is the code for form submit.
$scope.formprofile33 = function() {
var allData33 = {
'msg': $scope.msg,
'emp_id': viewer_id,
'job_id': job.job_id,
'job_title': $scope.jobss.SelectedOption.job_title,
// 'job':job,
'user_id': user_id
}
$http({
method: 'POST',
url: 'send_msg.php',
data: allData33,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
}).success(function(data) {
if (!data.success) {
$scope.message = data.errors.message;
} else {
$scope.message = '';
alert('Your message has been sent.');
$scope.message = '';
}
});
};
Here is the form.
<form name="formProfile33" method="post" id="formProfile33" role="form" ng-submit="formprofile33()">
<div class="container">
<div class="row">
<div class="col-xs-12">
<div class="row">
<div class="col-xs-10">
<div class="col-xs-12 s_ma">
<select id="job" name="job" class="search_color selectors form-control" ng-model="job" required="required" ng-options="item.job_title for item in jobss track by item.job_id">
<option value=""> Select Job *</option>
</select>
</div>
<textarea name="msg" ng-model="msg" class="form-control textbox1" id="msg" placeholder="Write your message" required="required" rows="3"></textarea>
</div>
</div>
</div>
</div>
<center>
<button type="submit" class="btn btn-home" name="btn-save1" id="btn-save1" required="required"><i class="icon ion-email"></i> Send Message </button>
</center>
</div>
</form>
Problem is i am not able to pass dropdown value and id during form submit.
I am getting below error.
TypeError: Cannot read property 'job_title' of undefined
Please advise how can i submit the form with dropdown id and value.
Your example set a job item to the scope field "job" => ng-model="job",
the full selected item is accessible with $scope.job.
Try $scope.job.job_title or $scope.job.job_id
A print out in your html is anytime a good helper: Full job item: {{job | json}}
https://plnkr.co/edit/VenFVchI0brGZNC2Q7Fn?p=preview

posting data through angular form without page reload in angular

$scope.createPermission= function(form){
AppFactory.createNewPermission(form)
.success(function(data) {
$scope.updatedPermissions = data;
$scope.navMode='getPermission'
var original = $scope.permission;
$scope.reset(original);
$scope.permission = {}; // clear the form
})
.error(function(data) {
console.log('Error in creating permission: ' + data);
});
$scope.Execute=function(id) {
if($scope.navMode=='updatePermission') {
$scope.editPermission(id);
} else if($scope.navMode=='createPermission') {
$scope.createPermission($scope.permission);
}
}
}
$scope.reset= function(original) {
$scope.permission= angular.copy(original)
$scope.form2.$setPristine(true);
//$scope.form2.$setUntouched(true);
}
HTML:
<div class="row">
<div class="container col-sm-6 col-sm-offset-2"
ng-show="navMode == 'createPermission' || navMode=='updatePermission' || navMode=='getPermission'">
<div>
<h1>Permissions</h1>
</div>
</div>
<form class="form2" ng-show="showHide('Create')" ng-if=""name="form2" ng-submit="Execute(permissionId)" novalidate>
<div class="form-group" ng-class="{ 'has-success': form2.name.$valid && submitted, 'has-error': form2.name.$invalid && submitted }">
<label>Permission Name</label>
<input type="text" name="name" class="form-control" ng-model="permission.name" required/>
<p class="help-block" ng-show="form2.name.$error.required && submitted">
A permission name is required
</p>
</div>
<div class="row col-lg-offset-3">
<button class="btn btn-primary" ng-disabled="form2.$invalid" type="submit">Save</button>
</div>
</form>
</div>
I have above piece of code in controller and is executed on submission of the form. Now , It does work fine on page reload but I can not add data through form back to back. I need to reload teh page everytime to post new data through the form.
Why exactly is that ?
How do I fix this?
Without seeing the HTML part of this, I would guess you are using the action attribute of <form>. AngularJS provides ng-submit which allows you to set a handler for the submit event, without actually 'submitting' the form in the traditional sense. See https://docs.angularjs.org/api/ng/directive/ngSubmit.

AngularJS : Hide and show radio button

<div class="filter_hide">
<div ng-cloak ng-repeat="web in website" >
<label ng-show="filter[web.websiteId]"><input type="radio" id="{{web.websiteId}}" ng-checked="webCheck" id="{{web.websiteId}}" value="{{web.websiteId}}" name="webname" ng-model="filter[web.websiteId]" />{{web.websiteName}} ({{web.couponCount}})</label>
</div>
</div>
<div class="filter_show">
<div class="check_box" ng-hide="filter[web.websiteId]" ng-repeat="web in website">
<label><input type="radio" value="{{web.websiteId}}" ng-checked="webCheck" id="{{web.websiteId}}" name="webname" ng-click="webcall(web)" ng-model="filter[web.websiteId]" />{{web.websiteName}} ({{web.couponCount}})</label>
</div>
</div>
I am trying to make when some one click on radio button form "filter_show" div then need to hide form there and show on "filter_hide" div and if user again click another radio button form "filter_show" div then need to hide previously select radio button form "filter_hide" div and show new one there.
I am using angular js 1.2.17
my controller -
app.controller('myCtrl', function ($scope, $http) {
$http({method: 'GET', url: '/asasa/asa/'}).success(function(data) {
$scope.website = data.websites;
$scope.onlinedata = data.coupons;
$scope.restdata = $scope.onlinedata;
$scope.webcall = function (web) {
$http({method: 'GET',url: '/asas/cccc/asas?websiteId='+web.websiteId}).success(function(data) {
$scope.onlinedata = data.coupons;
});
};
Take a look a this example
fiddle Example
<div ng-app>
<div ng-controller='contorller'>
<div class='to_hide' ng-if='hide === true'>
<input type="radio" name='hide' ng-click="showElement('show')" />Hide<br>
<input type="radio" name='hide' ng-click="showElement('show')" />Hide<br>
</div>
<br>
<div clas='to_show' ng-if='hide === false'>
<input type="radio" name='show' ng-click="showElement('hide')" />Show</br>
<input type="radio" name='show' ng-click="showElement('hide')" />Show</br>
</div>
</div>
</div>
<script>
function contorller($scope){
$scope.hide = true;
$scope.showElement = function(value){
if(value === 'hide'){
$scope.hide = true;
}else{
$scope.hide = false;
}
}
}
</script>

Resources