In my Rails I have two models, both with a method giving JSON back. One model is rent.rb the other is buy.rb. I also have a map.js, which will show a map with different pins, depending on the model, basically. So one map shows pins with apartments to rent, another - with apartments to buy. So, now I need a tooltip with a different information, depending on buy / rent. So I defined this part (as it's not coming from database), for rent.rb:
information {
...
type: "rent"
}
and for buy.rb with :
information {
...
type: "buy"
}
So now, in my map.js I wish to find out type and depending on what I get show the right information
(type == "rent") ? (show information for rent) : (type == "buy") ? (show information for buy)
But somehow JS won't access this value and won't customize information shown. Unfortunatelly I can't show the code, as it's for work. But maybe I am just using the wrong syntax here ...
You cannot join conditional operators like way you showed. Also you cannot have a function between ? and :
It will be better to do something like this
var rentInformation="some value";
var buyInformation="some other value";
var displayInformation = (type == "rent") ? rentInformation : buyInformation;
somePopupFunction(displayInformation);
Related
Let's assume I have a database with 2 tables. First table is location codes. Second table is event records. Event records contain a location code ID.
Edit: tables weren't working apparently, so I took a screenshot of the preview
And I am using Kendo Grid to display the data. On the server when I get the data I package it so that my location column is stored as an array.
$rowdata['location'] = array('location_id' => $data['location_id'], 'location_code' => $data['location_code']);
I use a template in my grid to display only the code.
The trouble that I am having is when using client-side filtering on this or other similarly formatted columns. I am aware that this would be much easier to accomplish using server-side filtering, however there are reasons why this is not being used.
What I am attempting to do is to modify the operator value during the filter event of the grid.
var customOperators = {};
$('#grid').kendoGrid({
...
filterMenuOpen: function (e) {
// since the custom operator does not exist, no operator is selected when the menu is re-opened. select the one last used for this field.
if (customOperators.hasOwnProperty(e.field)) {
$(e.container.find('select[data-bind="value: filters[0].operator"]')).data('kendoDropDownList').value(customOperators[e.field]);
}
},
filter: filterOpChange
});
function filterOpChange(e) {
if (e.filter === null) {
if (customOperators.hasOwnProperty(e.field)) {
delete customOperators[e.field];
}
return;
}
let oldOp = e.filter.filters[0]['operator'];
if (typeof window[e.field + '_' + oldOp] === "function") {
customOperators[e.field] = oldOp; // store the old operator in an object to re-select it from the list when the filter menu opens
e.filter.filters[0]['operator'] = window[e.field + '_' + oldOp]; // assign function named [field_name]_[operator] to the operator
}
}
// eq
function location_eq(itemVal, filterVal) {
return (itemVal && itemVal.location_id !== null && filterVal !== null && parseInt(itemVal.location_id) === parseInt(filterVal));
}
// neq
function location_neq(itemVal, filterVal) {
return (itemVal && itemVal.location_id !== null && filterVal !== null && parseInt(itemVal.location_id) !== parseInt(filterVal));
}
And this works. It filters as I expect it to. However, there is a problem if I attempt to change the filter for this field. If I change the filter menu from equals to does not equal I get a JavaScript error. In Chrome the error message is:
In Firefox the error message is (cut off the last file which is the file that has the grid on it):
The reason that I am using custom operators instead of a standard dropdown list is because I want to be able to filter based only on the text values so that a user can filter for "locA" and locA_1, locA_2, and locA_3 will all be displayed. The sample code I provided does not do this exactly, instead it looks at the ID, but that was easier to include here. I would appreciate any help with resolving the issue of applying a filter to a column that uses objects for values whether that means fixing my current error or going about it in a different way so long as it stays client-side.
For a node application I have a list of uploaded files shown with Ractive which works great so far. One of the fields I use is the Filetype (in my Data stored as extension e.g. FileType: pptx).
In my ractive Template I'd like to show a corresponding Image to the type of File uploaded for visual aid, but that tends to end in an endless if-statement.
So for now the template looks (simplified) like
'<span class="fa
{{#if FileType == "pptx" || FileType == "ppt" || FileType == "ppts" || //going on here forever}}
fa-file-powerpoint-o
{{elseif FileType == "xls" || FileType == "xlsx" || ...}}
fa-file-excel-o
//then the same follows for Videos, Word, pdf, ...
{{else}}
fa fa-file-o
{{/if}}
"></span>'
Does anybody know a decent way to shorten that horrible piece of code?
I think the easiest way would be to have a mapping of extension -> class stored in your data at e.g. ~/fileType. So { ppt: 'fa-file-powerpoint-o', pptx: 'etc' } could then be used in the template as class="fa {{~/fileType[FileType] || 'fa-file-o'}}".
You could shrink the data a bit by shipping a list of list of name -> type e.g.
const types = [[['ppt', 'pptx', 'ppty', 'pptz'],'fa-file-powerpoint-o'], [['exe'], 'fa-file-boom']]
const map = {};
types.forEach(entry => entry[0].forEach(extension => map[extension] = entry[1]));
this.set('fileType', map);
I would think the best way to tackle that particular problem is by using a database.
So you can add a record for a specified icon and assign multiple extensions to it. Then retrieve a dataset with all records and just loop through it and check for that field containing that extension.
And then of course you can set a 'default' record that will show a default icon.
And as a plus, if you only need to make one comparison, that logic execution can be handed off to the DBMS server in the SELECT query.
EDIT:
I realise now the 'database' would have to be client side.
So instead just use a xml file.
I have a situation that is only for users convenience, but is creating a headache for me.
Scenario:
I have (2) custom entities I am concerned with. (1) called "Job" and (1) called "Job Resource." Each have their own form. Job Resource is an N:1 Relationship to a Job.
"Jobs" is just our custom term for an awarded opportunity.
The "Job Resource" is a choice of multiple persons to be associated with that particular job. Those choices are also parameter driven to show "Is Supervisor."
The request I have is to add a "Point of Contact" on the "Job" form, and make it default the "Job Resource, (where 'Is Supervisor'=yes).
I have tried to use Quick View form, but there is no filtered choice for the supervisor or not. I believe I am left to do this with JavaScript. However, I have only done some simple web resources.
I would picture something like:
function xxx_pointOfContactid_onchange() {
xxxToolkit.Common.writeToConsole("begin xxx_pointOfContact_onchange()");
var jobResourceLookup = Xrm.Page.getAttribute("xxx_pointOfContact").getValue();
var select = "xxx_firstname,xxx_lastname,xxx_issupervisor";
if (jobResourceLookup != null) {
xxxToolkit.Rest.Retrieve(
jobResourceLookup[0].id
, "Resource"
, select
, null
, function (retrievedResource) {
if (retrievedResource.issupervisor == 1) {
if (retrievedResource.firstname != null) Xrm.Page.getAttribute("xxx_firstname").setValue(retrievedResource.firstname);
if (retrievedResource.lastname != null) Xrm.Page.getAttribute("xxx_lastname").setValue(retrievedResource.lastname);
} else {
return;
}
, xxxToolkit.Common.errorHandler
, true //asynchronous
);
}
}
When I tried to place this as onChange event, nothing happens.
Again, I am a JavaScript rookie, so if I apologize in advance for rookie question.
Any help appreciated. Thanks so much!
I have a dashboard that is displayed on the main screen when the user logs on.
Initially I have two graphics, one of lines and one of bars. The problem is that the graphical queries are a bit heavy and take about 30 seconds to load.
I already did optimization of the queries and they improved a little, the problem is that when wanting to access other options of the system does not leave me, because I have to wait until the graphs are loaded.
It is difficult for the user to wait until the graphs load, I would like to know if there is a way that other system options can be accessed, regardless of the graphs being loaded.
The code I have is the following:
/*
* You get the urls that the user has access to in the dashboard. This is executed * when the user is on the main screen.
*/
$.getJSON(getBaseUri() + 'dashboard/index', function(data) {
var datas = data['return'];
if(datas == ""){
$productivities.removeClass('chartID');
$productions.removeClass('chartID');
$combox.addClass('hidden');
}
for (var i in datas) {
receiveData({
div : datas[i].div,
title : datas[i].privilege,
sign : datas[i].sign,
iconClass : datas[i].class,
id : datas[i].id,
label : datas[i].label,
xaxis : datas[i].xaxis,
yaxis : datas[i].yaxis,
background: datas[i].background,
url : datas[i].route,
type : datas[i].type
});
}
});
/*
* The function receiveData () receives the parameters of the dashboard that the user has access and brings the data of each url consulted, and according to the type of graph the function is executed.
*/
function receiveData(param) {
$.ajax({
url: param.url,
method: 'GET',
dataType: 'json',
success: function(data){
var datas = data['return'];
if(param.type === "LineChart"){
lineChart({
data : datas,
div : param.div,
title: param.title,
url : param.url
});
$loaderProduction.addClass("hidden");
}
if (param.type === "BarChart") {
barCharts({
data : datas,
div : param.div,
title : param.title,
url : param.url,
label : param.label,
xaxis : param.xaxis,
yaxis : param.yaxis,
background: param.background
});
$loaderProductivity.addClass('hidden');
}
if (param.type === "Indicator") {
indicatorsChart({
data : datas,
div : param.div,
title : param.title,
icon : param.sign,
class : param.iconClass,
idDash: param.id
});
}
if (param.type === "Sowing") {
sowingIndicator({
data : datas,
div : param.div,
title : param.title,
idDash: param.id
});
}
},
error: function(error){
console.log(error);
}
});
}
Basically these are the functions I'm using to display dashboard graphs.
I think that this case I need to use WebWorkers, but I donĀ“t know how to use it
Right now you're making an AJAX call for every iteration of your for...in loop. Depending on the number of iterations this could mean a huge overhead, although it is best to reduce the number of round trips to the server in all cases.
You could try to modify both the front- and backend logic to combine multiple datasets into one request instead of one dataset per request and multiple requests.
Other than this there are no obvious bottlenecks in your code, so if the slowness persists the problem is most likely with your backend code.
Of course you got some options:
go through a Single Page Application, i.e. make your app in the way that, when user navigate other application options, the execution remains always in the same page. It may be heavy, exspecially if your application is already structured. Angular (or AngularJs), as other frontend frameworks, do this for you in an automated way.
let execute your loading js in an iframe, old and dirty but it works. When finished send a notification message in the main page,
Anyway you should optimize your code too, reducing number of calls from n (one for each element in datas) to 1.
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);
}
}