I have a inputs in a table filled out with ng-repeat, i want to be able to get the updated values by one click for all inputs.
My View:
<tr ng-repeat="sf in selectedFacture">
// displaying default values in the input
<td><input class="facture_item_name" ng-model="sf.facture_item_name" value="{{sf.facture_item_name}}" type="text"/></td>
<td><input class="fcls_crt" ng-model="sf.fcls_crt" value="{{sf.fcls_crt}}" type="number"/></td>
<td><input class="fpiece" ng-model="sf.fpiece" value="{{sf.fpiece}}" type="number"/></td>
<td colspan="4"><input type="text" class="form-control note" ng-model="sf.note" value="{{sf.note}}"/></td>
<tr>
<td ng-click="updateFacture(sf.id,sf,sf.facture_type,sf.item_id)">SUBMIT</td>
</tr>
</tr>
JS:
// getting new values and send them to server side
$scope.updateFacture=function(id,sf,type,item_id){
var url = '../php/history.php';
var func = "updateFacture";
sf = sf || {};
var editedQuanCls= sf.fcls_crt,
editedQuan_piece= sf.fpiece,
editedQuan_cls_crt_gate= sf.fcls_crt_gate,
editedQuan_piece_gate= sf.fpiece_gate,
editedNote= sf.note;
var data = {"function": func,
"factureId":id,
"item_id":item_id,
"facture_type":facture_type,
"editedQuanCls":editedQuanCls,
"editedQuan_cls_crt_gate":editedQuan_cls_crt_gate,
"editedQuan_piece":editedQuan_piece,
"editedQuan_piece_gate":editedQuan_piece_gate,
"editedNote":editedNote};
var options = {
type : "get",
url : url,
data: data,
dataType: 'json',
async : false,
cache : false,
success : function(response,status) {
alert("success")
},
error:function(request,response,error){
alert("errro: " + error)
}
};
$.ajax(options);
}
I tried to put the updated button in a td aside to the inputs and it works fine, but this will update each row separately, but my need is to updated them all in one click.
I'll attach a screen shot of my view.
Many Thanks in advance
<input class="facture_item_name" ng-model="sf.facture_item_name" value="{{sf.facture_item_name}}" ng-change="updateValues(sf.facture_item_name)" type="text"/>
$scope.updateValues=function(value){
$scope.sf.facture_item_name=value;
}
What you need is a wrapper function.
First add a button on the page that covers the All option like:
<button ng-click="updateAllFacture()">SUBMIT ALL</button>
Then add the wrapper function. All this does is loop through each item in the list and call the update function.
The wrapper function would look like:
$scope.updateAllFacture=function(){
angular.forEach($scope.res, function(sf, index) {
$scope.updateFacture=function(sf.id,sf,sf.facture_type,sf.item_id );
});
};
If you have an awful lot of items then there will be a lot of calls back to your api. Consider submitting all the inputs in the form as a post instead - then there will be just one call back, but you will need to program your controller for that.
Related
My problem is:
I have a list Student in a table with checkbox. Now i want to check this box and send a list Student to API. But i cannot to get them.
My code here!
HTML:
<tr dir-paginate="student in ClassStudents | filter: search | itemsPerPage: 20">
<td><input type="checkbox" ng-model="student.selected"></td>
<td style="display: none;">{{student.Class.ClassId}}</td>
<td>[Another property]</td>
</tr>
AngularJS:
function selectStudents(){
var listStudent = [];
$scope.ClassStudents.forEach(function(student){
if(student.checked){
var studentClone = angular.copy(student);
listStudent.push(studentClone)
}
})
return listStudent;
}
$scope.upGrade = function(){
$http({
method: 'POST',
url: host + "/api/APIClassStudents/Post",
data: {
Students: selectStudents(),
ClassId: 2
}
}).then(function(response){
alert("Upgrade Successful!")
})
}
Connect to WEB API is ok, response Upgrade success! but nothing change. When i debugging, i think selectStudent()[now is a array] is count = 0. And i dont know why.
Thanks for help!
The problem is, you are using selected in HTML and accessing checked in your controller. Just use filter as below in your upGrade function instead of selectStudents().
data: {
Students: $scope.ClassStudents.filter(student => student.selected),
ClassId: 2
}
filter function will return all selected students.
I'm trying to make a slight improvement to an existing widget that our team created, but can't seem to get it to work correctly. We have a widget that does a RowCount of tasks and groups them by state. I want the RowCount to auto update once a task is complete without having the user press the refresh button. I've read some documentation on $rootscope, $broadcast, and $on, but can't seem to get it to work.
Below is snippet of our HTML:
<table class="table table-sm table-responsive">
<tbody>
<tr class="h3">
<td colspan=2>Complete</td>
</tr>
<tr class="h2 bg-success" ng-repeat="x in data.values track by $index">
<td><span class="glyphicon glyphicon-check"></span></td>
<td>{{x.completedCount}}</td>
</tr>
</tbody>
</table>
A snippet of our Server Script:
var values = [];
var _completedCount;
var gsCompleted = new GlideRecordSecure('sn_hr_core_task');
//CLOSED COMPLETE, CLOSED INCOMPLETE,
gsCompleted.addQuery('state', 'IN', '3,4,7');
gsCompleted.addQuery('assigned_to', gs.getUserID());
gsCompleted.addQuery("parent.state", 'NOT IN', '1,800,900');
gsCompleted.query();
if(gsCompleted){
_completedCount = gsCompleted.getRowCount();
}
else{
_completedCount = 0;
}
values.push(
{
completedCount: _completedCount
});
data.values = values;
How do I get this widget to auto update the Completed row count without refreshing the page? I've been playing around with spUtil recordWatch, but cannot get it to work correctly:
function($scope, $sce, spUtil) {
var c = this;
c.data.loading = true;
//After page initially loads re-call server script to load data
c.server.get({
action: 'retrieve_data'
}).then(function(response) {
c.data.loading = false;
console.log('Response');
console.log(response);
c.data.values = response.data.values;
spUtil.recordWatch($scope, 'sn_hr_core_task', "", function(name,data) {
spUtil.update($scope);
})
});
}
Take a look at the widget Simple List, it has an example of one that may help a bit.
You should be able to change your recordWatch to this
var filter = "stateIN3,4,7^parent.stateNOT IN1,800,900^assigned_to=" + window.NOW.user_id;
spUtil.recordWatch($scope, 'sn_hr_core_task', filter);
You generally won't need a callback function unless there is some specific action you're triggering.
In an Index-gsp, I want to be able to select an arbitrary number of lines and then by clicking a link send all those lines to a controller for processing e.g. creating new objects of a different kind.
I've no idea how selection can be done or how to collect these selected lines in a GSP. Maybe I should use a checkbox on each line if that's possible?
It's a list of products which is displayed using a modified index.gsp.
Each product-line has a checkbox in front.
What I want is to make a list of the products that are checked an then transmit this list to a controller.
a part of this index.gsp:
<li><a class="home" href="${createLink(uri: '/')}"><g:message code="default.home.label"/></a></li>
<li><g:link class="create" action="create"><g:message code="default.new.label" args="[entityName]" /></g:link></li>
<li><g:link class="create" action="createOffer"><g:message code="default.new.label" args="[entityName]" params="toOffer" /></g:link></li>
</ul>
</div>
<div id="list-prodBuffer" class="content scaffold-list" role="main">
<h1><g:message code="default.list.label" args="[entityName]" /></h1>
<g:if test="${flash.message}">
<div class="message" role="status">${flash.message}</div>
</g:if>
<table>
<thead>
<tr>
<td> Välj</td>
<td> ID</td>
</tr>
</thead>
<tbody>
<g:each in="${prodBufferList}" status="i" var="prodBuffer">
<tr class="${ (i % 2) == 0 ? 'even': 'odd'}">
<td><g:checkBox name="toOffer" value="${prodBuffer.id}" checked="false" /></td>
<td>${prodBuffer.id}</td>
So this not an ordinary form, just a list where I want to use a link to transmit it to the controller.
I'm a beginner and have no idea how to do it.
You can collect all necessary data from page using javascript, and then send all data to your controller for processing.
There are a lot of ways to do it.
For example send via JQuery:
<script>
//some code
var items = [1,2,3];
//some code
$('#add-location').click(function () {
$.ajax({
type: "POST",
url: "${g.createLink(controller:'myController', action: 'myControllerMethod')}",
data: {items: items},
success: function (data) {
console.log(data)
}
});
});
</script>
I will answer this but have to slow down since it feels like i am beginning to write your project:
In gsp you will need to have a hidden field followed by a check box amongst data you are trying to capture, checkbox should contain all the data elements required to build your output.
<g:hiddenField name="userSelection" value=""/>
<g:checkBox name="myCheckBox" id='myCheckBox' value="${instance.id}"
data-field1="${instance.field1}" data-field1="${instance.field1}"
checked="${instance.userSelected?.contains(instance.id)?true:false}" />
In the java script segment of the page you will need to add the following
This will then auto select selection and add to javascript array
// Customized collection of elements used by both selection and search form
$.fn.serializeObject = function() {
if ($("[name='myCheckBox']:checked").size()>0) {
var data=[]
$("[name='myCheckBox']:checked").each(function() {
var field1=$(this).data('field1');
var field2=$(this).data('field2');
data.push({id: this.value, field1:field1, field2:field2 });
});
return data
}
};
Most importantly will your data sit across many different gsp listing pages if so you will need to hack pagination:
//Modify pagination now to capture
$(".pagination a").click(function() {
var currentUrl=$(this).attr('href');
var parsedUrl=$(this).attr('href', currentUrl.replace(/\&userSelection=.*&/, '&').replace(/\&userSelection=\&/, '&'));
var newUrl=parsedUrl.attr('href') + '&userSelection=' + encodeURIComponent($('#userSelection').val());
window.location.href=newUrl
return false;
});
Then in the controller parse the JSON form field and make it into what you want when posted
def u=[]
def m=[:]
if (params.userSelection) {
def item=JSON.parse(params.userSelection)
item?.each {JSONObject i->
// When field1 is null in JSON set it as null properly
if (JSONObject.NULL.equals(i.field1)) {
i.field1=null
}
if (resultsGroup) {
if (!resultsGroup.contains(i.id as Long)) {
u << i
}
} else {
u << i
}
}
m.userSelected=item?.collect{it.id as Long}
m.results=u
}
return m
I don't know what happen but this function seems like not working at all.
Here is my view:
<tr>
<th>Category</th>
<td>
<select class="form-control" ng-model="masterlist.category_id" ng-options="c.category_id as c.category_name for c in category" required data-ng-change="getSubCategory(c.category_id)"></select>
</td>
</tr>
<tr>
<th>Sub Category</th>
<td>
<select class="form-control" ng-model="masterlist.sub_category_id" ng-options="c.sub_category_id as c.sub_category_name for c in subCategory" required></select>
</td>
</tr>
Angular JS
$scope.getSubCategory = function (category_id) {
$http.get('/MasterList/SubCategory' + category_id).then(function ($response) {
$scope.subCategory = $response.data;
});
}
Controller:
public ActionResult SubCategory(int id)
{
db.Configuration.ProxyCreationEnabled = false;
return Json(db.Sub_Category.Where(x => x.active_flag == true && x.category_id == id).ToList(), JsonRequestBehavior.AllowGet);
}
I check on the console but nothing's error and here is the inspect element view:
My main goal is to once category is selected, the display for sub category will be only those under the category.
Thanks in advance for the help.
Your select element's ng-model is set to masterlist.category_id. So you should pass that to your getSubCategory method.
<select class="form-control" ng-model="masterlist.category_id"
ng-options="c.category_id as c.category_name for c in vm.category"
required data-ng-change="vm.getSubCategory(masterlist.category_id)"></select>
Also you need to send a request with the url pattern SubCategory/3 where 3 is the category id value. With your current code it is going to make a request to SubCategory3 and you will see a 404 error if you inpsect your browser network tab.
You should add a / between the catetory_id variable and the action method name,
$http.get('Home/SubCategory/' + category_id)
I also recommend moving your http calls to a data service which can be injeccted to your controller. Als, you should not hard code the url's like that in your js file. Try to use the Url.Action helper method to generate the proper relative urls to your action method/api endpoints as explained in this post and this post.
Change the scope only when the value changes.
if($scope.subCategory != $response.data)
$scope.subCategory = $response.data;
My need is to create multiple rows with 2 fields one dropdown and one textbox.
I created a Json array for holding the each row as an object.I want to add the dropdown as an json array of object to my json array of object containing the rows.
My code is below:
//Declare empty array to add new rows
$scope.searchList ={
sources: [{
id: $scope.rowId,
srcCd: '',
srcId:''
//want to add sourceCdMap property and assign the json array which is in another scope variable $scope.sourceCodeMap
}]
}
<table>
<tr ng-repeat="source in searchList.sources track by source.id">
<td>
<div >
<label >Source Name</label>
<div >
<select class="form-control selectWidth" autofocus ng-model="source.srcCd"
ng-change="changeSourceNew(source.id,source.srcCd)"
ng-options="source.value for source in source.sourceCdMap"></select>
</div>
</div>
</td>
<td>
<div >
<label >Source ID </label>
<div><textarea id="source.textarea" autofocus ng-model="source.srcId" rows="4" cols="50" placeholder="enter SrcIds"></textarea>
</div>
</div>
</td>
</tr>
</table>
I want to add a "sourceCdMap" property to the json array of object $scope.searchList which will contain the dropdown values from another json array of object stored inside $scope.sourceCodeMap.
I tried like below but the dropdown is null :
initializeSourceCodeMap();
var initializeSourceCodeMap = function () {
$searchUtilityRemoteService.getSourceCode().then(function (resultMap) {
$scope.sourceCodeMap = resultMap;
$scope.sourceCodeMap.sort(sortSrcCodeBy("value"));
$scope.selected = $scope.sourceCodeMap[0];
$scope.searchIdForm.srcCd = $scope.selected.code;
}, function (reason) {
$scope.sourceCodeMap = null;
//log error
})
};
//Declare empty array to add new rows
$scope.searchList ={
sources: [{
id: $scope.rowId,
srcCd: '',
srcId: '',
sourceCdMap: $scope.sourceCodeMap
}]
}
FYI the "$scope.sourceCodeMap" is working in other parts of the code or when I try to log it in my console.
Any help is appreciated on how to assign this scope variable "$scope.sourceCodeMap" (which is actually a json array of objects in itself) to the new property "sourceCdMap" in the Json Array "$scope.searchList"
Try logging inside this function
function (reason) {
$scope.sourceCodeMap = null;
//log error
}
to see if maybe your $scope.sourceCodeMap is always null because of it.
If that's not the case, try using $scope.apply();, so that the html can see your changes. Beware of asyncronously calling it.