Vue - Checkbox all to handle global editing of selects - Object sticking - javascript

Codepen
https://codepen.io/ainsleyclark/pen/yLNqmRq?editors=1011
Objective
I'm trying to create a dynamic ordering system for customers.
Files are uploaded which are stored as an array of objects. A table is then created which loops over those files and spits out table rows containing products.
When a user hits one of those products, it makes an ajax request and gets all available options for that product.
When the checkbox all is hit, the user should be able to edit all products and options globally, and when unselected it reverts back to normal behaviour.
The problem:
The v-modelling works absolutely flawlessly when you are not using any checkboxes. You can see
the order being built out with its options. However after you have used the checkboxes, its like the v-modelling is sticking and the options aren't independent of each other any more.
Steps to reproduce:
Hit the checkbox all (top left checkbox in table head)
Select a product (first product entry)
Select an option (first product entry)
Unselect checkbox all
Try and change the options and you will see the order object updating for all objects.
Data:
I have a products array containing products as objects.
A order array, which is where the problem lies, which contains the file key then the product then the options associated with the product.
There is also an options array of objects which gets updated when a user hits the select button, again it contains the file key so I can link it.
Checkbox all:
I believe it has to do with the way Im selecting the product as show below:
checkboxAllHandler(checked) {
if (checked) {
this.files.forEach((file, index) => {
this.selectedFiles.push(index)
});
const product = Object.assign({}, this.order['products'][this.getSelectedFile]);
console.log(product);
const order = Object.assign({}, this.order);
this.selectedFiles.forEach(fileIndex => {
order['products'][fileIndex] = product || {};
});
this.order = {};
this.order = order;
} else {
this.selectedFiles = [];
}
}
Any help is greatly appreciative in advance, It's been a tough problem!

First, you missed :key property in v-for, so all yours rows are treated as same - change this line like this: <tr v-for="(file, fileKey) in files" :key="file">
Second, in you loop you are assigning to all rows the same product, and this is leads to behaviour you want to avoid:
const product = Object.assign({}, this.order['products'][this.getSelectedFile]);
...
this.selectedFiles.forEach(fileIndex => {
order['products'][fileIndex] = product || {};
});

Related

Dynamic Dropdown from Mongo

I have a mongoDB with a DB = Staff and a collection = records. It contains a list of employees, and one of the fields is workgroup and it has items like "management", "union", "support staff", etc.
I want to populate a dropdown list with the values of the workgroup field and then use it to retrieve all records from the specified value selected in the dropdown.
I am using Ruby and I can retrieve the values ok (I can see them in the console), but they do not populate the dropdown list.
This is my Ruby statement:
get '/workgroup' do
Record.all.to_a.collect(&:workgroup).uniq.to_json
end
My attempt at the javascript is:
<script>
//var json = 'http://localhost:4567/api/v1/workgroup';
$(document).ready(function()
{
$.getJSON("/api/v1/workgroup",function(obj)
{
$.each(json.records,function(key,value)
{
var option = $('<option />').val(value.workgroup);
$("#dropDownDest").append(option);
})
})
});
</script>
Once I get the information in the dropdown, I want to use it to return all records with that workgroup value to a table. I haven't figured that part out yet. One step at a time!
Thanks!!
Within your $.getJSON call back you are referencing json.records, but there is no json variable or object.
The argument you are passing to the callback is obj. I think you really want to be doing $.each(obj, function(key, value)...

Filter a SharePoint list via dynamic checkboxes instantly (with C# and/or Ajax)

I'm currently looking for a way to add a filter function to a list in SharePoint, which filters the lists content via checkbox selection.
This little mockup might help to understand what I'm talking about:
The idea is to have a normal SharePoint custom list on the right and a checkboxlist on the left side, which will be generated dynamically from the content of the list -> One column is a "filter group" and all the field contents are the filter values.
When selecting one or multiple values on the left side, the items in the list should instantly be filtered accordingly (ajax, without reloading the page).
For example in the mockup, selecting "New York" and "Blue" would only show the item "Steve's Car".
You now, like a product filter in almost every online shop and so on.
How can that be achieved? Would be awesome if this could be included in my solution package (which includes other stuff in C#/jQuery already).
I'm new to frontend customization in SharePoint, but I'm sure there's a way :-)
Edit: I'm using SP2016 by the way.
Pandora!
As i understand it, your first question is how you can dinamically get values for left side filter. I see there two ways: first way, you can build caml query and get items from list; second way, you can use ctx.ListData, which sharepoint initialize by itself and in ctx.ListData.Row (array of items) process items and get unique field values. Note, that ctx.ListData.Row contains only items loaded in list view on the page.
For list filtration you can concat filter link for hash of the page. Example: "?List={ListID}&View={ViewID}&FilterField1=Color-FilterValue1=Blue". Try to filter columns on list and you will see url modification. ListID and ViewId you can retrieve by ctx.listName and ctx.view.
And then pass it in function MyRefreshPageToEx. List will be filtered.
More list filtration info
function FilterList(){
var tableId = $(".ms-listviewtable").attr("id");
var filterUrl = "?List={ListID}&View={ViewID}&FilterField1=Color-FilterValue1=Blue";
MyRefreshPageToEx(tableId, filterUrl, false);
}
function MyRefreshPageToEx(lvTableID, url, bForceSubmit) {
var tblv = document.getElementById(lvTableID);
var clvp = CLVPFromCtx(tblv);
if (clvp != null && clvp.ctx.IsClientRendering) {
clvp.RefreshPaging(url);
clvp.ctx.queryString = url;
if ((typeof clvp.ctx.operationType == "undefined" || clvp.ctx.operationType == SPListOperationType.Default) && Boolean(clvp.ctx.ListData)) {
var fromPage = clvp.ctx.ListData.FirstRow - 1;
var toPage = Number(GetUrlKeyValue("PageFirstRow", false, url));
if (!isNaN(fromPage) && !isNaN(toPage) && fromPage != toPage)
fromPage < toPage ? (clvp.ctx.operationType = SPListOperationType.PagingRight) : (clvp.ctx.operationType = SPListOperationType.PagingLeft);
}
}
else {
SubmitFormPost(url, bForceSubmit);
}
}

Dynamically adding new item extremly slow

I use ASP.NET MVC and Razor. User needs to populate some form which consists of list of objects. So I pass list of empty objects from controller to view. This is part of my main view:
foreach ( var product in Model.Products )
{
Html.RenderPartial( "ProductPartial", product );
}
In ProductPartial user enters some fields for each product.
User can dynamically add or remove products from list. Removing I solved with jquery live function, and it is fine. But I have problem with adding new products.
I solved it in this way: On plus sign click javascript function calls controller action:
public ActionResult NewProduct()
{
Product product = new Product();
product.UniqueId = Guid.NewGuid();
return PartialView( "ProductPartial", product );
}
I need unique id for every product because I want to be able to access products from jquery by ids.
Adding works correctly, but it is extremly slow, since I go on server for every new product. Is there some good way to make it faster?
Well, instead of asking the server for more of the same HTML, you could use jQuery.clone();
In the example I'm copying the first product in the list and giving it a new id, and then adding the copy to the end of the list.
var newProductHtml = $('.MyProducts')[0].clone();
newProductHtml.attr('id', MyNewId);
newProductHtml.appendTo('.MyProductsContainer');

Selecting customer addresses with radio inputs and knockoutjs

I have an address selection screen. Address data are coming from server. Data covers these values:
Id = Address Id,
Address = Address itself,
TypeCode = 1 or 2 (1 is shipping, 2 is billing address),
IsDefault = boolean (is this default address)
I map these data in two arrays. One of them contains shipping addresses and the other one billing addresses.
I have couple of problems.
I can't set default addresses when server data comes.
When I want to set a new address I click another radio button. When I do that I gave two address id's in "selectedShippingAddress" loop. I think this is not the right way to do this.
Here is the example: http://jsfiddle.net/sevilyilmaz/HnGS4/
Thanks.
You are using checked binding wrong way. It doesn't point to property of object which should be selected, it points to observable which has ID of selected object. i.e.: checked: $parent.selectedShippingAddres and selectedShippingAddres = ko.observable();. Now when you populate your data in updateAddresses you can check and save the default ID:
$.map(data.AddressListItems, function (v) {
if (v.TypeCode === 1) {
viewModel.shippingAddresses.push(v);
if (v.IsDefault) {
viewModel.selectedShippingAddress(v.Id);
}
} else {
viewModel.billingAddresses.push(v);
if (v.IsDefault) {
viewModel.selectedBillingAddress(v.Id);
}
}
});
Working sample: http://jsfiddle.net/HnGS4/4/

fine-uploader unique but ascending ID in filename on submit and cancel

this issue relates to Widen Fine-Uploader ( https://github.com/Widen/fine-uploader )
i got this multipart upload form. no autoupload. i want to upload a couple of images and safe them under an unique name for each image.
eg. you pick 4 images. upload via fine-upload. i already got a gallery id. all images should be saved under a filename using the gallery-id and an unique ascending number. like this:
1234-1.jpg
1234-2.jpg
1234-3.jpg
1234-4.jpg
sounds easy, but there are two problems:
the image-id needs to be ascending without skipping any one. That may happen, if you cancel (remove) a file before upload. so the image-id needs to be set up AFTER selecting all files OR it needs to fill up empty IDs on removing a file.
the order of the images must be strictly adhered to the order you choose files on input. the first image you pick, becomes 1234-1.jpg, the second one 1234-2.jpg ... so i'm not able to set the ID at the imageHandler script after reload. It would grab the first complete image that must not be the first image in order, because i use several simultaneous connections on upload.
I tried something like that:
.on('submitted', function(event, id, name) {
var picId = id+1;
$(this).fineUploader('setParams', {
'currentGid': 1234,
'picId':picId
});
})
or
params: {
fileNum: function() {
return $(this).attr('id');
}
}
or using a fileCount++ but nothing works like i need..
Your application sounds a bit brittle, and it is probably in your best interests to address that.
You'll simply need to maintain a map of your unique ids along with the ids maintained for each file by Fine Uploader. In your "submitted" handler, add a key/value pair to the map. In a "cancel" handler, adjust the items in the map appropriately. In an "upload" handler, call the "setParams" API method. Your parameters will by the gallery ID, the unique ID you've been tracking in your map for that specific file, and be sure to pass the id of the file as your last parameter to the "setParams" call. This lets Fine Uploader know that this parameter is only for that specific file.
Please see the callbacks documentation for more info.
Here's a code example:
var fileIds = [];
$('#myFineuploaderContainer').fineUploader({
//set your options here
})
.on('submitted', function(event, id, name) {
fileIds.push(id);
})
.on('cancel', function(event, id, name) {
var fileIdPosition = $.inArray(id, fileIds);
fileIds.splice(fileIdPosition, 1);
})
.on('upload', function(event, id, name) {
var params = {
currentGid: 1234,
picId: $.inArray(id, fileIds)
};
$(this).fineUploader('setParams', params, id);
});

Categories

Resources