I've been working with checkboxes recently thought it would make sense to include a select all function, which can be found in my HTML and AngularJS code:
HTML:
<button class="btn btn-default btn-sm" ng-click="selectChosenServices()">Select All
</button>
AngularJS:
$scope.selectChosenServices = function () {
for (var i = 0; i < $scope.siteUserServicesTable.data.length; i++) {
$scope.siteUserServicesTable.data[i].chosen = true;
}
};
The code itself I've noticed does work for the current rows shown (which is set at 10), however, if I clicked to view the next page, it won't select them unless I click on the button again. I was wondering what might be the issue.
I don't know why but sometimes for loop not working proper, can you try below code ?
angular.forEach($scope.siteUserServicesTable, function(TableRow, Index){
TableRow.chosen = true;
})
My guess is that you are loading only 10 records at a time. And when you go to next page the next 10 records are loaded? If this is the case, it is not getting selected because while you are on the first page, you only have 10 records. The next 10 records are just not there.
First identify that How many records are you getting when it's render first time on page?
If your are getting only 10 records set each time then you have to
call this function in initialization of each render.
If you are getting all records then it should definitively work.
for better performance and efficiency I would suggest you to use lodash library
Related
I'm trying to add an attribute to the first column in my debatable so I just add a class in the columns[] setting called popperup.
However for the bootstrap popover to work I need to add the attribute "tabindex":"0"
This can be done with $(".popperup").attr({"tabindex":"0"})
however this only adds it to the first entries that load 10 in my datatable which then allows the popover to work the problem is when you click the next paginate button or numbered buttons it will not work as the tabindex:0 is missing
I have tried using
$("#Ttable3").on('page.dt', function() {
console.log("here")
$(".popperup").attr({"tabindex":"0"})
});
This only works once you have gone to the next page and then go back again. so you click next page or go to page 2/3/4 etc nothing happens. you go back to page 1 then back to page 2/3/4 and it will work
how can I get it so "tabindex":"0" is on every cell in a column
spend hours working on an issue and fix it the moment you post it on Stackoverflow
I needed to use draw.dt in the on call.
so this
$("#Ttable3").on('page.dt', function() {
console.log("here")
$(".popperup").attr({"tabindex":"0"})
});
becomes this
$("#Ttable3").on('draw.dt', function() {
console.log("here")
$(".popperup").attr({"tabindex":"0"})
});
Assuming you have defined your DataTable and assigned it to a variable...
var table = $('#example').DataTable( {
// your options here
} );
Then you can use the following to iterate over every node in the first column, using the table reference you defined:
var selectedCol = table.column(0).nodes();
for (var i = 0; i < selectedCol.length; i++) {
$(selectedCol).attr({ "tabindex": "0" })
}
Using angularjs (1.3) with webapi here.
I have UI where the user can upload a excel file. My api reads the excel file and returns rows data back to the UI in JSON.
The UI then reads the JSON and binds it back the UI table.
The rows and columns of this UI table are dynamically generated and are not fixed, because of which I am using contenteditable in HTML as the user can add more rows.
I can read from the the JSON fine and populate the array that holds these json values. The issue is while rendering, the screen is frozen and takes time to render all the data.
I am currently binding about 800 rows and the screen freezes and takes about 10-15 seconds or more to fill up the UI table. I would be having lot more data so looking for a solution for this.
I tried to debug and can see that there is no issue getting data back from the API, and reading JSON from the API. There is also no issue while populating the array.
Once the array populates thats when the issue comes. The UI freezes and takes time to render this data.
I am not sure whats going on here or why it takes so time to render. Below is some sample relevant code:
//Read json from the API
$http.get('https://api.myjson.com/bins/d1ugw').success(function(data) {
if (data.length > 0) {
$scope.setJson = data;
$scope.initializeTable(true);
var columns = $scope.targetTable.columns;
//These are the 3 columns of the Table but can vary dynamically(currently just hardcoding it)
var refColName = "state, month , year";
//Push the columns to the table array
var colArray = refColName.split(',');
for (var i = 0; i < colArray.length; i++) {
$scope.targetTable.columns.push({
id: columns.length,
refColName: refColName.split(',')[i]
});
}
//Read the values from the json
var idValues = $scope.getTableValues($scope.setJson, 'id');
var commentValues = $scope.getTableValues($scope.setJson, 'comment');
var rowValues = $scope.getTableValues($scope.setJson, 'refcol');
var setIdValues = $scope.getTableValues($scope.setJson, 'sid');
//Push the data back to the table array.
$scope.pushRowData($scope.targetTable, rowValues, commentValues, idValues, setIdValues);
//Till the above steps everything happens quickly and I can see $scope.targetTable being populated with my json.
//But after the above step the screen just freezes and takes time to show the entire data on the UI table.
}
});
Below is the relevant code for the UI:
<tbody>
<tr ng-repeat="r in targetTable.rows">
<td class="fixed-width">
<span>
<a class="btn-xs" ng-show="row == $index" ng-if="targetTable.rows.length > 1"><i class="fa fa-times-circle" aria-hidden="true"></i></a>
</span>
<span contenteditable="true" ng-model="r.tableId" ng-change="addNewRow(r.tableId, r)">{{r.tableId}}</span>
</td>
<td class="fixed-width" contenteditable="true" ng-repeat="column in targetTable.columns" ng-model="r[column.id]" ng-change="rowDataChange(r[column.id])"></td>
<td class="comment-fixed-width" contenteditable="true" ng-model="r.comment" ng-change="rowDataChange(r.comment)"></td>
<td class="blank fixed-width" colspan="2" ng-model="r[column.id]"></td>
</tr>
</tbody>
I have created the below JSFiddle to show my example and issue I am facing.
http://jsfiddle.net/aman1981/u1vbeos5/312/
I have also added comments in my jsfiddle for showing what method does what.
Would appreciate if anyone can help my resovling this issue.
Here are some performance stats:
with contenteditable (~4000 digest calls) = 1.800ms -> http://prntscr.com/lweugn
without contenteditable (~4 digest calls) = 1.300ms -> http://prntscr.com/lweusn
with pagination just showing the first 50 results = 0.200ms -> http://prntscr.com/lwev09
You loose the most performance because of the DOM changes obviously. But keep in mind that the number and duration of digest cycles is key for good performance. Especially when you have a huge amount of watchers. Here is a Direct comparison:
http://prntscr.com/lwf1nn As you can see the digest loop is burning 30% of your performance overall but is not the reason for your frame drop. The frame drop is mostly caused of the DOM changes. Drawing such a big table takes some time.
Further the table starts rendering when your REST call is finished. This call takes in my case roughly additional 1.700ms. So it takes nearly 3.500ms from start until rendered results. Even with pagination 1.900ms.
I would recommend a pagination with search but you can try to increase the performance anyway.
Helpful links would be:
https://stackoverflow.com/a/47347260/8196542
https://www.codeproject.com/Articles/1173869/%2FArticles%2F1173869%2Fng-repeat-performance-degradation-at-case-of-very
First, I recommend that you upgrade the Angular version to the most advanced of course if possible.
Also check the animate version.
Beyond that you thought of using an advanced tabular component such as ag-grid ?,
I can load 10000 rows without any problem with it.
https://www.ag-grid.com/
Your code is triggering the $digest loop over and over.
The "watch" method counts how often the $digest cycle is actually called:
var nbDigest = 0;
$scope.$watch(function() {
nbDigest++;
console.log(nbDigest);
});
I bet this is the cause of your performance issues.
I am trying to replace some text in an input field using JS but the view model overrides my commands each time. This is the HTML I start with:
<td class="new-variants-table__cell" define="{ editVariantPrice: new Shopify.EditVariantPrice(this) }" context="editVariantPrice" style="height: auto;">
<input type="hidden" name="product[variants][][price]" id="product_variants__price" value="25.00" bind="price" data-dirty-trigger="true">
<input class="mock-edit-on-hover tr js-no-dirty js-variant-price variant-table-input--numeric" bind-event-focus="onFocus(this)" bind-event-blur="onBlur(this)" bind-event-input="onInput(this)">
</td>
I run this JS:
jQuery('#product_variants__price').siblings().removeAttr('bind-event-focus');
jQuery('#product_variants__price').siblings().removeAttr('bind-event-input');
jQuery('#product_variants__price').siblings().removeAttr('bind-event-blur');
jQuery('#product_variants__price').siblings().focus()
jQuery('#product_variants__price').siblings().val("34.00");
jQuery('#product_variants__price').val("34.00");
And I'm left with the following HTML:
<td class="new-variants-table__cell" define="{ editVariantPrice: new Shopify.EditVariantPrice(this) }" context="editVariantPrice" style="height: auto;">
<input type="hidden" name="product[variants][][price]" id="product_variants__price" value="34.00" bind="price" data-dirty-trigger="true">
<input class="mock-edit-on-hover tr js-no-dirty js-variant-price variant-table-input--numeric">
</td>
The problem is that each time I click the input field the value is reverted to what it was when the page loaded.
I've also tried running the command in the parent td along with my value change, to simulate the editing of a variant and preventing default with no success:
jQuery('#product_variants__price').siblings().bind('input', function (e) {
e.preventDefault();
return false;
});
jQuery('#product_variants__price').siblings().bind('focus', function (e) {
e.preventDefault();
return false;
});
jQuery('#product_variants__price').siblings().focus()
jQuery('#product_variants__price').siblings().val("£34.00");
jQuery('#product_variants__price').val("£34.00");
jQuery('#product_variants__price').siblings().keydown()
Parent td function:
new Shopify.EditVariantPrice(jQuery('#product_variants__price').parent())
So how can I successfully edit this value in the inputs and also update the Shopify view model?
You can try this for yourself by going here:
https://jebus333.myshopify.com/admin/products/2521183043
login jebus333#mailinator.com
password shop1
EDIT: I've tried to find the view model on the page but with no success. Plus, there are no network calls when editing the values in the input fields, leading me to believe the values are being pulled back from somewhere on page.
Try this:
var old = Shopify.EditVariantPrice.prototype.onFocus;
Shopify.EditVariantPrice.prototype.onFocus = function(t) {
this.price = '50.00'; // Use the price you want here
old.call(this, t);
};
jQuery('#product_variants__price').siblings().triggerHandler("focus");
jQuery('#product_variants__price').siblings().triggerHandler("blur");
If it works for you, it's possible that the following will be sufficient:
Shopify.EditVariantPrice.prototype.onFocus = function(t) {
this.price = '50.00'; // Use the price you want here
};
Well, there is a kind of a dirty solution...
First of all you'll need a sendkeys plugin. In fact that means you'll need to include this and this JS libraries (you can just copy-paste them in the console to test). If you don't want to use the first library (I personally find it quite big for such a small thing) you can extract only the key things out of it and use only them.
The next step is creating the function which is going to act like a real user:
function input(field, desiredValue) {
// get the currency symbol while value is still pristine
var currency = field.val()[0];
// move focus to the input
field.click().focus();
// remove all symbols from the input. I took 10, but of course you can use value.length instead
for (var i = 0; i < 10; i++) field.sendkeys("{backspace}");
// send the currency key
field.sendkeys(currency);
// send the desired value symbol-by-symbol
for (var i = 0; i < desiredValue.length; i++) field.sendkeys(desiredValue[i]);
}
Then you can simply call it with the value you wish to assign:
input($("#product_variants__price").next(), "123.00");
I did not really manage to fake the blur event because of lack of the time; that is why I was forced to read the currency and pass .00 as a string. Anyway you already have a way to go and a quite working solution.
Looks like you're trying to automate editing of variant prices of products in Shopify's admin panel.
Instead of playing around with the DOM of Shopify's admin page, I'll suggest using Shopify's bulk product editor which lets you set prices of all variants in a single screen. I feel that you'll have better luck setting the variant prices using JavaScript on the bulk product editor page.
Clicking on the 'Edit Products' button as shown in the screenshot below will open the bulk product editor.
Also check if browser based macro recording plugins like iMacro can be of your help (you can also code macros with JS in iMacro).
i asked a similar question before however the solution no longer works for my application, i need a button click to create a new row (FailureInstance) in a table (failuretable) and i need it to populate three of the cells with data from fields that are elsewhere filled in. here is my code: form1.failuretable.AddFailureButton::click - (JavaScript, client)
xfa.host.messageBox("Failure Recorded and Added To Table Below. Please Continue Filling Out the Form Until All Failures Have Been Recorded. Then Please Save and Submit the Form.", "Continue/Save/Submit", 3);
if (xfa.host.version < 8) {
xfa.form.recalculate(1);
}
var newRow = failuretable._FailureInstance.addInstance(1);
newRow.FailureCode.rawValue = form1.FailureType.rawValue;
newRow.Location.rawValue = form1.CellLocation.rawValue;
newRow.Comments.rawValue = form1.AdditionalComments.rawValue;
right now this doesn't even create a new row for my table... any help is appreciated!
You should check whether multiple instances for a row are allowed. Select FailureInstance in hierarchy view and then in Object->Binding (if you dont see it go to window menu and select Object) check wheter "Repeat Row for Each Data Item" is selected. If not then select it and your code should work fine.
I advice also to enable JavaScript debugging in your Adobe Reader because it than you should see when error appears and what is it about. Open Reade go to Edit->Preferences->JavaScript and select "Show console on errors and messages". Then you will need to restart Designer.
At design time remember to enable:
Object > Data Binding > Repeat Table For Each Data Item
In code, I believe that lack invoking "instaceManager":
...
var newRow = failuretable.FailureInstance.instanceManager.addInstance(1);
...
http://help.adobe.com/en_US/livecycle/9.0/designerHelp/index.htm?content=000178.html
I have created a table in HTML, consisting of table rows in a tbody tag.
I've used a javascript code snippet from mredkj.com to be able to add rows and delete them, too. The rows are sorted and their rank is in the first TD (cell) in every TR (row).
Now I would like the add the functionality of being able to manually 'resort' the tablerows.
The problems are:
my javascript/jquery knowledge is
very limited
the ranks of tablerows
do not get updated(when you delete a row, the
rowranks get updated by the
'reorderRows function, but calling this function from within my jQuery does not seem to
sort out the problem)
the user's input in textarea's gets erased as soon as up or down button is clicked.
For example: user adds a TR, that gets added at the bottom of the current list of tablerows, fills in the textarea and desides that the row (s)he filled should be ranked first, so she clicks the up arrow a couple of times, until it's on top.
The rank of the row is now #1 and the input is still in the textarea's.
My questions are:
Does anyone know how I can make the
rows update their ranking when the
user moves the row?
How do I maintain the user's input?
Any help is very much appreciated and if you have any other suggestions, please share them.
Code here: http://jsbin.com/eyefu5/edit - for some reason, the moving up and down doesn't work in js bin, it does however when I run it in my browser.
I updated your code to do what I think you were trying to do: http://jsbin.com/eyefu5/9/
My primary changes were to the following swap logic:
function swap(a, b){
b.before(a);
reorderRows(document.getElementById(TABLE_NAME), 0);
}
function getParent(cell){ return $(cell).parent('tr'); }
$('#diagnosetabel').on('click', '.upArrow', function(){
var parent = getParent(this);
var prev = parent.prev('tr');
if(prev.length == 1){ swap(parent, prev); }
});
$('#diagnosetabel').on('click', '.downArrow', function(){
var parent = getParent(this);
var next = parent.next('tr');
if(next.length == 1){ swap(next, parent); }
});
The biggest difference is that I switched the swap code to using jQuery's before method, which should take care of just about everything for you. I also added a call to the reorderRows method which you were already using. At the moment it starts at the beginning and reorders all the numbers after the swap, but you could narrow this down as needed because you know the only two rows which were modified.
Hope that helps!