i have a webpage where user can select one of different packages to buy from a list. Package details are coming from a database.
HTML Code
<div data-package='2346343' class="retail-package">Cost : 10$</div>
<div data-package='5465654' class="retail-package">Cost : 20$</div>
<div data-package='3455675' class="retail-package">Cost : 30$</div>
Jquery Code
$('.retail-package').on('click', function() {
$(this).addClass("selected-package");
var selectedPackage = $(this).data("package");
});
Now above code shows how we(specially i) normally select a particular thing out of a list when clicked, In this procedure, as you can see in HTML Code, i am giving out or showing the pakcageId to users i.e. anyone can do a inspect element in a browser and view or even manipulate the data-package attribute, for safety i do a server side check of selected data.
My Question
Is there a way to hide this data exposure, or is there any other cleaner way to accomplish this, because i have seen people using Angular, Webpack etc able to implement a list selection without giving out or showing any data which can be seen by inspect element feature in a browser.
Note : i am sorry if my question is too basic, if this cannot done using jquery what are other technologies which i can use ?
You may create a Map where keys are arbitrary, auto-incremented identifiers, and values are package numbers:
const idPackageMap = new Map()
// id generator: whenever you call it, "i" is incremented and returned
const id = (() => {
let i = 0
return () => ++i
})()
const addPackage = package =>
idPackageMap.set(id(), package)
addPackage(2346343)
addPackage(5465654)
addPackage(3455675)
console.log('contents: ', [...idPackageMap.entries()])
console.log('package number for id 2: ', idPackageMap.get(2))
Now, when you insert those <div> elements you may set the arbitrary identifier, and when you need to locate the actual package number is just about using Map#get: idPackageMap.get(1) (change 1 with any arbitrary identifier).
Related
I am going to do live data streaming on ag-grid datatable, so I used DeltaRowData for gridOptions and added getRowNodeId method as well which return unique value 'id'.
After all, I got a live update result on my grid table within some period I set, but some rows are duplicated so I can notice total count is a bit increased each time it loads updated data. The question title is warning message from browser console, I got bunch of these messages with different id number. Actually it is supposed not to do this from below docs. This is supposed to detect dups and smartly added new ones if not exist. Ofc, there are several ways to get refreshed data live, but I chose this one, since it says it helps to persist grid info like selected rows, current position of scroll on the grid etc. I am using vanilla js, not going to use any frameworks.
How do I make live data updated periodically without changing any current grid stuff? There is no error on the code, so do not try to speak about any bug. Maybe I am wrong with current implementation, Anyway, I want to know the idea or hear any implementation experience on this.
let gridOptions = {
....
deltaRowDataMode: true,
getRowNodeId = (data) => {
return data.id; // return the property you want set as the id.
}
}
fetch(loadUrl).then((res) => {
return res.json()
}).then((data) => {
gridOptions.api.setRowData(data);
})
...
If you get:
duplicated node warning
it means your getRowNodeId() has 1 value for 2 different rows.
here is part from source:
if (this.allNodesMap[node.id]) {
console.warn("ag-grid: duplicate node id '" + node.id + "' detected from getRowNodeId callback, this could cause issues in your grid.");
}
so try to check your data again.
if u 100% sure there is an error not related with your data - cut oof the private data, create a plinkr/stackblitz examples to reproduce your issue and then it would be simpler to check and help you.
I am attempting to use JSLink ..finally.. and I am having some trouble that I cannot seem to straighten out. For my first venture down the rabbit hole I chose something super simple for use as proof of concept. So I looked up a tutorial and came up with a simple script to draw a box around the Title field of each entry and style the text. I cannot get this to work. Is there any chance you can take a look at this code for me? I used the following tokens in the JSLink box.
~sitecollection/site/folder/folder/file.js
And
~site/folder/folder/file.js
The .js file is stored on the same site as the List View WebPart I am attempting to modify. The list only has the default “Title” column.
(function () {
var overrideContext = {};
overrideContext.Templates = {};
overrideContext.Templates.Item = overrideTemplate;
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideContext);
}) ();
function overrideTemplate(ctx) {
return “<div style=’font-size:40px;border:solid 3px black;margin-bottom:6px;padding:4px;width:200px;’>” + ctx.CurrentItem.Title + “</div>”;
}
It looks as though you are attempting to override the context (ctx) item itself, where you actually just want to override the list field and the list view in which the field is displayed. Make sense?
Firstly, change overrideContext.Templates.Item to overrideContext.Templates.Fields :
(function () {
var overrideContext = {};
overrideContext.Templates = {};
overrideContext.Templates.Fields = {
// Add field and point it to your rendering function
"Title": { "View": overrideTemplate },
};
SPClientTemplates.TemplateManager.RegisterTemplateOverrides(overrideContext);
}) ();
Then when the JSLink runs the renderer looks for the Title field in the List view, and applies your overrideTemplate function.
function overrideTemplate(ctx) {
return “<div style=’font-size:40px;border:solid 3px black;margin-bottom:6px;padding:4px;width:200px;’>” + ctx.CurrentItem.Title + “</div>”;
}
In terms of running multiple JSLinks on a SharePoint page, it is quite possible to run multiple JSLink scripts, they just need to be separated by the pipe '|' symbol. I use SharePoint Online a lot and I see the following formatting working all the time (sorry Sascha!).
~site/yourassetfolder/yourfilename.js | ~site/yourassetfolder/anotherfilename.js
You can run as many scripts concurrently as you want, just keep separating them with the pipe. I've seen this on prem also, however you might want to swap out '~sites' for '~sitecollection' and make sure the js files you are accessing are at the top level site in the site collection if you do so!
I have noticed when running multiple JSLinks on a list or page because they are all doing Client Side Rendering, too many will slow your page down. If this happens, you might want to consider combining them into one JSLink script so that the server only has to call one file to return to the client to do all the rendering needed for your list.
Hope this helps.
Here is a drop down list in SmartClient: http://www.smartclient.com/#dropdownGrid.
I want to make a selection using JavaScript. Like, I run some JavaScript in console, and the drop list will select a specific item.
I did some research, found a code snap to do this (the code is in Java, but I think there should be similar functions in JavaScript):
Record rec = perdomainGrid.getRecordList().find("domaine_id", domaine_id);
perdomainGrid.selectSingleRecord(rec);
If I want to make selection, first I need to obtain perdomainGrid object. In my above giving link, the drop down list id in GWT is exampleForm (can be seen in dropDownGrid.js tab). I try to get the object by:
var form = isc.DynamicForm.getById("exampleForm");
form does exist, but there is no getRecordList() function on it, there is selectSingleRecord() function on it though.
I try to check form's class by form.className, its value is normal. I don't know what does that mean.
I'm kind of confused now. Could somebody help me on this?
isc_SelectItem_5 has a function called pickValue(), it takes one parameter SKU. This function can be used to select item.
var itemName = "Letter Tray Front Load Tenex 200 Class Blk #23001";
var data = isc_SelectItem_5.optionDataSource.cacheData;
var targetSKU = data.find(function(e) {
if (e.itemName == itemName) {
return e;
}
}).SKU;
isc_SelectItem_5.pickValue(targetSKU);
I have an <a> tag which I'm using to redirect the user to another xpage.
Its href property is:
<a target="_blank" href="http://serv/MyBase.nsf">
I use a simple view listing a doc. which contains the server and the name of the application.
So, I want to use some #DbLookup function in javascript to get into 2 var the above server and app name:
var server = #Unique(#DbColumn(#DbName(), "myVw", 1);
var name = #Unique(#DbColumn(#DbName(), "myVw", 2);
var concat = server+"/"+name;
return concat;
How can I compute the href property to return the concat variable?
Create a Link control xp:link and calculate the URL in attribute value:
<xp:this.value><![CDATA[#{javascript:var server .... }]]></xp:this.value>
Knut's approach is correct, but your code isn't :-). For every XPages load (or refresh) you do 4 #DbLookup. You can do a set of optimisations here:
Combine the result you want in the view itself, so you only need one lookup
Cache the value in the session (or application scope)
something like this (add nice error handling):
if (sessionScope.myHref) {
// Actually do nothing here
} else {
sessionScope.myHref = #Unique(#DbColumn(#DbName(), "myVw", 3);
}
return sessionScope.myHref;
The 3rd column would have the concatenation in the view already. That little snippet does a lookup only once per session. If it is the same for all users, use the applicationScope then it is even less.
I have asp.net web application.where i am creating the User as registration for a particular Firm.In this firm there are 3 type of user as of now. as Admin, Dealer, Manager. so according to this I am changing the UI page.
Means When Admin (Admin is default entry) going create let say Dealer, then there is different UI except General information fields (like name ,contact details and all). and when creating the manager there is different UI fields, except than General information fields.
To reuse the page i am using this way , when selected Manager then related his UI fields get only visible, same for dealer. obviously there is a dropdown control from where i am selecting User type.
But some how , later on if one more User type get added by firm, I need to generate functionality according to New User type. how can i handle if I don not want to change existing code. sense is how can i write the generic code so that I should not need to change in code behind or in javascript again.
Where as all this things are in planning and under implementation for now. but before to go a head I must clear this thing. I am planning to change the UI structure in javascript as usual way , i means
if selected User Type is "Dealer then make visible these div's ELSE If User Type is Manager then make visible these divs
I want to write generic javacript , though new user type get added.
You could maintain the field <-> user type relation in a database and dynamically add labels and textboxes in the PageLoad of your Page.
Then when a new type of user comes along you'd simply need to add to your data.
Your user type should also be in a database.
Of course, the code that lets your users create other users would also have to be flexible enough. So you'd need a CanCreate table that dictates who can create what type of user. :)
EDIT Expanded how to build your Content
Actually, I like your idea about storing the html elements in the database. That'd save you using reflection to dynamically get the propertyvalue. However, I don't think you'll be able to use databinding and all that.
So instead I'd do something like this:
public enum ControlType
{
Label,
TextBox,
...
}
Make a table something like
UserType
PropertyName
PropertyLabelName
FieldLabelType (int)
FieldContentType (int)
Then on pageload you get the UserType, pull the data from the table, find the div where you want to put the data and then add the controls like:
(pseudocode)
Control label = null;
switch (FieldLabelType)
{
case ControlType.Label:
var label = new Label()
{
.. all kinds of properties
Text = PropertyLabelName
};
control = label;
break;
case ???
...
}
if (label != null)
fielddiv.Add(label);
Control field = null;
switch (FieldContentType)
{
case ControlType.TextBox:
var textbox = new TextBox()
{
.. all kinds of properties
Text = new Binding( ... Path = PropertyName)
};
control = textbox;
break;
case ???
}
if (field != null)
fielddiv.Add(field);
Of course, you'd need to do some positioning to get it all looking pretty. Perhaps chuck in a table or something in code?