I'm working on functions for form. Data for this form comes from api call and filling input fields. Submit button works well, but behavior of cancel button is weird, instead of cancel last changes it sends updated data to db. Could anybody help me to find my mistake?
Also I have tried to type="reset" and it returns default empty fields but I need that it has returned old value before editing
My form:
<form style="padding: 15px" ng-submit="submitForm()">
<div class="form-group row">
<div ng-repeat="k in rowKeys | filter: '!id' | filter: '!0' " ng-model="rowValue">
<label for="rowValue" class="col-sm-2">
{{k | hide:'.name' | makeUppercase}}:
</label>
<div class=" col-sm-2" >
<input class="form-control rowValue" id="rowValue" ng-model="rowData[k]" ng-disabled="isDisabled()"/>
</div>
</div>
</div>
<button type="submit" class="btn btn-default" ng-if="rowData" >Save</button>
<button type="button" class="btn" ng-if="rowData" ng-click="cancelForm()">Cancel</button>
js
$scope.submitForm = function() {
$scope.$watch('rowData', function(newValue, oldValue) {
console.log('being watched oldValue:', oldValue, 'newValue:', newValue);
}, true);
$http({
method : 'PUT',
url : $scope.globalUrl + $scope.id,
data : $scope.rowData //form
})
.then(function (res) {
return res;
})
.then(function (){
$('#table').bootstrapTable('refreshOptions', {
'url': $scope.globalUrl
});
})
};
$scope.cancelForm = function () {
$scope.$watch('rowData', function(newValue, oldValue) {
return oldValue;
console.log('being watched oldValue:', oldValue, 'newValue:', newValue);
}, true);
}
Change
<button type="submit" class="btn" ng-if="rowData" ng-click="cancelForm()">Cancel</button>
To
<button type="button" class="btn" ng-if="rowData" ng-click="cancelForm()">Cancel</button>
When you put type="submit" this means that on click it will do the submit action on your form
Related
I've setup a view which contains a search form:
<form>
<input type="hidden" id="product_id" value="{{$tour->id}}">
<div class="form-group col-md-4">
<label>Date:</label>
<div class="input-group date">
<div class="input-group-addon">
<i class="fa fa-calendar"></i>
</div>
<input type="text" class="form-control pull-right" id="start" placeholder="Start Date">
</div>
</div>
<div class="form-group col-md-4">
<label>End:</label>
<div class="input-group date">
<div class="input-group-addon">
<i class="fa fa-calendar"></i>
</div>
<input type="text" class="form-control pull-right" id="end" placeholder="End Date">
</div>
</div>
<div class="form-group col-md-4" id="dateprice-search">
<label></label>
<button type="submit" class="btn" id="btn-search" >
Search
</button>
</div>
The below is the ajax code to handle the request of the form:
$(document).ready(function() {
$('#dateprice-search').on('click', '#btn-search', function() {
$.ajax({
type: 'post',
url: '/date-price',
data: {
'_token': $('input[name=_token]').val(),
'product_id': $("#product_id").val(),
'start': $("#start").val(),
'end': $("#end").val()
},
success: function(data) {
$('.shadow-z-1').show();
$('.shadow-z-1').append("<tr class='liquid-row><td>" + data.start + "</td><td>"+ data.end + "</td><td>" + data.end + "</td><td><a class='btn-m btn btn-m-success'>Available</a></td></tr>");
}
});
});
});
Route:
Route::post('/date-price','GetPublicController#datePrice')
->name('searchDate');
And finally method in controller to give the results:
public function datePrice(Request $request){
$start = $request->start;
$end = $request->end;
$dates = DatePrice::where('tour_id','=',$request->product_id)
->whereBetween('start', array($request->start, $request->end))
->whereBetween('end', array($request->start, $request->end))
->get();
return response()->json($dates);
}
At first the url looks like this before submitting the form http://localhost:8000/trips/popular/trekking/test and url becomes http://localhost:8000/trips/popular/trekking/test? after clicking the search button. Console section of inspect element shows no error in script. What mistake I had made over here ?
It mean your form submiting to same page due to type="submit"
1) change to type="button"
<button type="button" class="btn" id="btn-search" >
2) Here click event should be for button not to div so change the selector and add e.preventDefault(); in jquery to prevent the default submit .
$('#btn-search').on('click', '#btn-search', function() { e.preventDefault(); });
note :
1st : your action attribute missing so form will be submit same page .
2nd : your method attribute missing so it will take default GET method
You have given button type as submit, either remove it as
<button type="button" class="btn" id="btn-search" >
Search
</button>
or use the jquery preventDeafult() function to prevent the default behavior of submit button i.e form submit in your button click event as
$(document).ready(function() {
$('#dateprice-search').on('click', '#btn-search', function(e) {
e.preventDefault();
//your ajax code
});
});
I'm using angularjs to create a modal used by a form.
In my javascript I receive only two fields of my form (name and clientVersion) the other two are omitted and I don't know why.
This is my modal:
<div class="modal" id="addUserModal" data-ng-app="myApp">
<div class="modal-dialog" data-ng-controller="modalController">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal"
aria-label="Close">
<span aria-hidden="true">×</span>
</button>
<h4 class="modal-title">New user</h4>
</div>
<div class="modal-body">
<form novalidate class="simple-form">
<!-- form start -->
<div class="box-body">
<div class="form-group">
<label>Name</label> <input id="name" type="text"
data-ng-model="newUser.name" class="form-control"
maxlength="30" placeholder="Version name" required>
</div>
<div class="form-group">
<label>Role</label> <select class="form-control select2"
style="width: 100%;" name="role" data-ng-model="newUser.role"
data-ng-options="user.idRole as role.role for role in roles track by role.role">
</select>
</div>
<div class="form-group">
<label>Client Version </label> (optional) <select
class="form-control select2" style="width: 100%;"
name="version" data-ng-model="newUser.clientVersion"
data-ng-options="version.idClientVersion as version.name for version in versions track by version.name">
</select>
</div>
<div class="form-group">
<label>Enable </label> <input type="checkbox"
data-ng-model="newUser.enabled" name="my-checkbox" checked>
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default pull-left"
data-dismiss="modal">Close</button>
<button id="uploadVersionButton" type="button"
class="btn btn-primary" data-ng-click="createUser(newUser)">Create
user</button>
</div>
</div>
<!-- /.modal-content -->
</div>
<!-- /.modal-dialog -->
</div>
In my javascript code I have
//Angular section for Select2 of modal create user
var app = angular.module('myApp',[]);
app.controller('modalController', function($scope, $http) {
$http({
method: 'GET',
url: 'roles'
}).then(function successCallback(response) {
$scope.roles = response.data.result;
// this callback will be called asynchronously
// when the response is available
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
$http({
method: 'GET',
url: 'version',
}).then(function successCallback(response) {
$scope.versions = response.data.result;
// this callback will be called asynchronously
// when the response is available
}, function errorCallback(response) {
// called asynchronously if an error occurs
// or server returns response with an error status.
});
$scope.createUser = function(newUser) {
$scope.master = angular.copy(newUser);
};
});
and newUser has only those two fields. Do you know why?
First error is in
data-ng-options="role.idRole as role.role for role in roles track by role.role"
I gave the wrong idRole.
The checkbox is a prolem of bootstrap plugin, without it all works.
I found this directive and work:
app.directive('bootstrapSwitch', [
function() {
return {
restrict: 'A',
require: '?ngModel',
link: function(scope, element, attrs, ngModel) {
element.bootstrapSwitch();
element.on('switchChange.bootstrapSwitch', function(event, state) {
if (ngModel) {
scope.$apply(function() {
ngModel.$setViewValue(state);
});
}
});
scope.$watch(attrs.ngModel, function(newValue, oldValue) {
if (newValue) {
element.bootstrapSwitch('state', true, true);
} else {
element.bootstrapSwitch('state', false, true);
}
});
}
};
}
]);
but perhaps it is better to use
$('input[name="my-checkbox"]').on('switchChange.bootstrapSwitch', function(event, state)
and store state into a variable.
I'm stuck with this simple form submission. I feel that everything is right, but it doesn't work.
My html :
<html ng-app = 'myApp'>
<div ng-controller="Tabs">
...
<form ng-submit="sendClicked()" >
<div class="input-group">
<input type="text" class="form-control" ng-model="text"/>
<span class="input-group-btn" >
<button class="btn btn-info" type="submit">SEND</button>
</span>
</div>
</form>
...
</div>
</html>
My app.js :
myApp.controller('Tabs', function ($scope) {
$scope.sendClicked = function () {
console.log('can reach here');
if($scope.text) {
socket.emit('send message', $scope.text);
$scope.text = null;
}
};
});
Must be input type submit, but you have button, that doesn't ever have type attribute property
I'm banging my head against the wall here. I'm using ng-repeat to populate a table. Inside each row i have 2 buttons, one for updating the row content and for uploading files. The upload button opens a bootstrap modal window, where the user selects the files and clicks on submit.
The submit button uses ng-click to run a function which uses $index as parameter. But the $index value is always the same no matter which row is selected.
The thing I don't understand is that I use the exact same syntax (although outside of a modal window) on my update button, which works just fine.
HTML:
<tr ng-repeat="item in items | filter:search " ng-class="{'selected':$index == selectedRow}" ng-click="setClickedRow($index)">
<td>{{$index}}</td>
<td ng-hide="idHidden" ng-bind="item.Id"></td>
<td ng-hide="titleHidden">
<span data-ng-hide="editMode">{{item.Title}}</span>
<input type="text" data-ng-show="editMode" data-ng-model="item.Title" data-ng-required />
<td>
<button type="button" class="btn btn-primary uploadBtn" data-ng-show="editMode" data-toggle="modal" data-target="#uploadModal">Upload file <i class="fa fa-cloud-upload"></i></button>
<!-- Upload Modal -->
<div class="modal fade" id="uploadModal" tabindex="-1" role="dialog" aria-labelledby="uploadModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h3 class="modal-title" id="uploadModalLabel">Options</h3>
</div>
<div class="modal-body">
<h4>Upload Documents</h4>
<form>
<div class="form-group">
<select data-ng-model="type" class="form-control" id="fileTypeSelect">
<option value="Policy">Policy</option>
<option value="SOP">SOP</option>
</select>
<br>
<div class="input-group"> <span class="input-group-btn">
<input type="file" id="file">
</span>
</div>
<br>
<button type="button" class="btn btn-default" data-ng-click="uploadAttachment($index, type)">Upload</button>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
</div>
</div>
</div>
<button type="button" data-ng-hide="editMode" data-ng-click="editMode = true;" class="btn btn-default pull-right">Edit <i class="fa fa-pencil-square-o"></i></button>
<button type="button" data-ng-show="editMode" data-ng-click="editMode = false; updateItem($index)" class="btn btn-default">Save</button>
<button type="button" data-ng-show="editMode" data-ng-click="editMode = false; cancel()" class="btn btn-default">Cancel</button>
</td>`
JS:
$scope.uploadAttachment = function executeUploadAttachment(index, type) {
var listname = "Risk Register";
var id = $scope.items[index].Id;
console.log(indexID);
readFile("uploadControlId").done(function(buffer, fileName) {
uploadAttachment(type, id, listname, fileName, buffer).done(function() {
alert("success");
}).fail(function() {
alert("error in uploading attachment");
})
}).fail(function(err) {
alert("error in reading file content");
});
}
So the function uploadAttachment($index, type) which is triggered by ng-click doesn't pass the right index number. It always passes the same, no matter what row it is clicked in.
I have omitted some of the code that is irrelevant. If needed i can provide the whole thing.
Any suggestions to what I am missing?
Edit:
I have tried to implement DonJuwe suggestions.
I have added this inside my controller:
$scope.openModal = function(index) {
var modalInstance = $modal.open({
templateUrl: 'www.test.xxx/App/uploadModal.html',
controller: 'riskListCtrl',
resolve: {
index: function() {
return index;
}
}
});
};
This is my modal template:
<div class="modal-header">
<h3 class="modal-title" id="uploadModalLabel">Options</h3>
</div>
<div class="modal-body">
<h4>Upload Documents</h4>
<form>
<div class="form-group">
<select data-ng-model="type" class="form-control" id="fileTypeSelect">
<option value="Policy">Policy</option>
<option value="SOP">SOP</option>
</select>
<br>
<div class="input-group"> <span class="input-group-btn">
<input type="file" id="file">
</span>
</div>
<br>
<button type="button" class="btn btn-default" data-ng-click="uploadAttachment($index, type)">Upload</button>
</form>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
</div>
</div>
And finally my function which resides inside RiskListCtrl (the only controller i use):
$scope.uploadAttachment = function executeUploadAttachment(index, type) {
var listname = "Risk Register";
var id = $scope.items[index].Id;
console.log(indexID);
readFile("uploadControlId").done(function(buffer, fileName) {
uploadAttachment(type, id, listname, fileName, buffer).done(function() {
alert("success");
}).fail(function() {
alert("error in uploading attachment");
})
}).fail(function(err) {
alert("error in reading file content");
});
}
It seems that $scope.items[index].Id is empty. Error: Cannot read property 'Id' of undefined
The modal window has its own scope. That means you need to resolve data you want to pass into the modal's scope. To do so, use resolve within the modals open(options) method.
Before I will give you an example, I want to suggest having only one modal for all your table items. This will let you keep a single template where you can easily use id (now, you create a template for each of your table items which is not valid). Just call a controller function and pass your $index:
<button type="button" class="btn btn-primary uploadBtn" data-ng-show="editMode" ng-click="openModal($index)">Upload file <i class="fa fa-cloud-upload"></i></button>
In your controller, create the modal instance and refer to the template:
$scope.openModal = function(index) {
var modalInstance = $modal.open({
templateUrl: 'myPath/myTemplate.html',
controller: 'MyModalCtrl',
resolve: {
index: function() {
return index;
}
}
});
};
Now you can access index in your MyModalCtrl's scope by injecting index:
angular.module('myModule', []).controller('MyModalCtrl', function($scope, index) {
$scope.index = index;
});
Since, you are getting the index value outside model then you can also use ng-click and then call a function in your controller and store the index value in a temporary variable and then when you are using submit button then just take make another variable and assign the value of temporary variable to your variable. for example:
<button type="button" data-ng-show="editMode" data-ng-click="editMode = false; updateItem($index)" class="btn btn-default">Save</button>
and then make a function in your controller
$scope.updateItem = functon(index)
{
$scope.tempVar = index;
}
now use the value of tempVar in you function
$scope.uploadAttachment = function executeUploadAttachment(index, type) {
var index = tempVar; //assign the value of tempvar to index
var listname = "Risk Register";
var id = $scope.items[index].Id;
console.log(indexID);
readFile("uploadControlId").done(function(buffer, fileName) {
uploadAttachment(type, id, listname, fileName, buffer).done(function() {
alert("success");
}).fail(function() {
alert("error in uploading attachment");
})
}).fail(function(err) {
alert("error in reading file content");
});
}
I've two forms on the same page. On clicking any one of the buttons, both queries of the buttons are being submitted as I've used the function IsPost like if(IsPost){ //run queries}
Since both the forms are on the same page, on submission of any button, both the events of the two buttons are triggered.
I want to run separate queries on submission of each of the buttons.
In php, we used if(isset($_REQUEST['buttonname'])){ //run queries }.
Is there any such way, I can achieve the same in cshtml?
Update
What if I already have passed a value in the buttons?
Like for eg:
<div class="btn-group pull-right">
#{
var followersearchcommand = "SELECT * from follow where follow_followerid = #0 and follow_followingid = #1";
var followsearch = db.Query(followersearchcommand, follower_id, row.student_id);
}
#if(followsearch.Count > 0){
<button class="btn btn-primary" type="submit" name="unfollow_followingid" value="#row.student_id" title="Follow" style="display: none"></button>
<button class="btn btn-primary" type="submit" name="unfollow_button" value="unfollow" title="Follow">UnFollow</button>
}
else{
<button class="btn btn-primary" type="submit" name="followingid" value="#row.student_id" title="Follow" style="display: none"></button>
<button class="btn btn-primary" type="submit" name="follow_button" value="follow" title="Follow">Follow</button>
}
</div>
Assign to both buttons the same name and test their value:
#{
if (IsPost){
if(Request["button"] == "buttonA"){
// button A is pressed
} else {
// button B is pressed
}
}
}
<form method="post">
<input type="submit" name="button" value="buttonA" />
<input type="submit" name="button" value="buttonB" />
</form>
Edited
If you want to have two distinct forms, you could use the IsEmpty() method:
#{
if (IsPost){
if(!Request["buttonA"].IsEmpty()){
// button A is pressed
} else {
// button B is pressed
}
}
}
<form method="post">
<input type="submit" name="buttonA" value="buttonA" />
</form>
<form method="post">
<input type="submit" name="buttonB" value="buttonB" />
</form>
html:
<form id="a">
<button type="submit">Submit A</button>
</form>
<form id="b">
<button type="submit">Submit B</button>
</form>
javascript:
$(function(){
$("#a").submit(function(e){
e.preventDefault();
// Query A
alert('A');
});
$("#b").submit(function(e){
e.preventDefault();
// Query B
alert('B');
});
});
Demo
Edit:
You can make an ajax call to your controller's action:
$.ajax({
type: "POST",
url: "#Url.Action("actionName", "controllerName")",
data: { /* your data */ },
success: function (data, textStatus, jqXHR) {
// success
},
error: function (jqXHR, textStatus, errorThrown) {
// error
}
});
And in your controller:
[AcceptVerbs(HttpVerbs.Post)]
public JsonResult actionName(/* your data */)
{
var success = DoSomething();
if (!success)
{
throw new HttpException(500, "Server error!");
}
return Json("");
}
Something along those lines...
Hope this helps!