Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 2 years ago.
Improve this question
Summary:
Goal: create a dynamic table of contents on start
Expected results: if the user clicks button that corresponds to page x, the user will be directed to page x
Actual results: if the user clicked button that corresponds to page x, the user will be directed to the last page
What I have tried:
Followed the code for OnClick events listed on the MRTK documents https://microsoft.github.io/MixedRealityToolkit-Unity/Documentation/README_Interactable.html
public static void AddOnClick(Interactable interactable)
{
interactable.OnClick.AddListener(() => Debug.Log("Interactable clicked"));
}
Looked into GitHub thread https://github.com/microsoft/MixedRealityToolkit-Unity/issues/4456
Looked into the GitHub thread https://github.com/microsoft/MixedRealityToolkit-Unity/issues/5013
Code: TOC = Table of Contents
private void TOCpage()
{
GameObject TOC = new GameObject(); // holds table of contents buttons
for(int i = 1; 1 <= pages.Count - 1; i++)
{
GameObject TOCgameObject = (GameObject)Instantiate(TOCButtonPrefab);
var TOCButton = TOCgameObject.GetComponent<Interactable>();
TOCbutton.OnClick.AddListener(() => TaskOnClick(i));
}
}
public void TaskOnClick(int TOCButtonNumber)
{
Debug.Log("Table of contents button number " + TOCButtonNumber + " clicked");
}
If user clicks on TOCbutton for page 1, and there are 7 pages, the user is directed to page 7.
TOCbutton.OnClick.AddListener(() => TaskOnClick(i));
This happens because i is not local to the lambdas, but is defined in the outer scope, and it is accessed when the lambda is called — not when it is defined. At the end of the loop, the value of i is 7, so all the functions log 7.
Instead, you can create a local variable within the loop and assign it the value of the iteration variable or use foreach statement to do it under C#5.0 or later.
As a solution, you can refer to the following code:
foreach (var i in Enumerable.Range(1, pages.Count))
{
GameObject TOCgameObject = (GameObject)Instantiate(TOCButtonPrefab);
var TOCButton = TOCgameObject.GetComponent<Interactable>();
TOCbutton.OnClick.AddListener(() => TaskOnClick(i));
}
Related
Apologies if this question has been answered elsewhere, I have had trouble finding any resources on this.
The scenario is this. I have created a custom field in the Tax Preferences screen called Usrapikey.
This value holds an api key for a call that gets done in some custom business logic.
The custom business logic however occurs on the Taxes screen.
So within the event handler I need to access that API key value from the other screen. I have tried instantiating graphs and using linq and bql but to no avail.
below is what I have currently and my error is: No overload for method 'GetExtension' takes 1 arguments
If I am going about this the wrong way please let me know if there is a more civilized way to do this
protected virtual void _(Events.FieldUpdated<TaxRev, TaxRev.startDate> e)
{
var setup = PXGraph.CreateInstance<TXSetupMaint>();
var TXSetupEX = setup.GetExtension<PX.Objects.TX.TXSetupExt>(setup);
var rateObj = GetValues(e.Row.TaxID, TXSetupEX.Usrapikey);
decimal rate;
var tryRate = (Decimal.TryParse(rateObj.rate.combined_rate, out rate));
row.TaxRate = (decimal)rate * (decimal)100;
row.TaxBucketID = 1;
}
Many Thanks!
Well, acumatica support got back. It seems if you want to access the base page use:
TXSetup txsetup = PXSetup<TXSetup>.Select(Base);
To get the extension use:
TXSetupExt rowExt = PXCache<TXSetup>.GetExtension<TXSetupExt>(txsetup);
Then you can access the extension fields like so:
var foo = rowExt.Usrfield;
Im using pdfkit to generate pdf invoice.
When all my content fit in one page I have no issue.
However when it doesn't fit and need an extra page, I have a strange behaviour:
Instead of adding the elements in the second page, it only add one line and the rest of the page is blank.
Then on 3rd page I have another element, and the rest it blank, then 4th page, 5th etc.
Here is the code corresponding to this part:
for (let i = 0; i < data.items.length; i++) {
const item = data.items[i];
this.itemPositionY = this.itemPositionY + 20;
if (item.bio) this.containBioProduct = true;
let itemName = item.bio ? `${item.item}*` : item.item;
this.generateTableRow(
doc,
this.itemPositionY,
itemName,
"",
this.formatCurrency(item.itemPriceDf.toFixed(2)),
item.quantity,
this.formatCurrency(item.itemPriceTotalDf.toFixed(2))
);
this.generateHr(doc, this.itemPositionY + 15);
}
Basically I just iterate over an array of products. For each line my Y position has +20.
Thanks for your help.
In case someone has this issue, here is a solution:
Everywhere in the code I know that an extra page could be generated, I add this:
if (this.position > 680) {
doc.addPage();
this.position = 50;
}
It allows you to control the generation of new pages (instead of pdfkit doing it automatically with potential problems)
You just need to track the position from the initialization of "this.position".
In that way, evertime it's superior than an Y position (680 in my case, it's a bit less than a page with pdfkit), you just do "doc.addPage()", which will create another page, and you reinitialize your position to the beginning of the new page.
First of all, I want to let you guys know that I know the basic work logic of how ElasticSearch Scroll API works. To use Scroll API, first, we need to call search method with some scroll value like 1m, then it will return a _scroll_id that will be used for the next consecutive calls on Scroll until all of the doc returns within loop. But the problem is I just want to use the same process on multi-thread basis, not on serially. For example:
If I have 300000 documents, then I want to process/get the docs this way
The 1st thread will process initial 100000 documents
The 2nd thread will process next 100000 documents
The 3rd thread will process remaining 100000 documents
So my question is as I didn't find any way to set the from value on scroll API how can I make the scrolling process faster with threading. Not to process the documents in a serialized manner.
My sample python code
if index_name is not None and doc_type is not None and body is not None:
es = init_es()
page = es.search(index_name,doc_type, scroll = '30s',size = 10, body = body)
sid = page['_scroll_id']
scroll_size = page['hits']['total']
# Start scrolling
while (scroll_size > 0):
print("Scrolling...")
page = es.scroll(scroll_id=sid, scroll='30s')
# Update the scroll ID
sid = page['_scroll_id']
print("scroll id: " + sid)
# Get the number of results that we returned in the last scroll
scroll_size = len(page['hits']['hits'])
print("scroll size: " + str(scroll_size))
print("scrolled data :" )
print(page['aggregations'])
Have you tried a sliced scroll? According to the linked docs:
For scroll queries that return a lot of documents it is possible to
split the scroll in multiple slices which can be consumed
independently.
and
Each scroll is independent and can be processed in parallel like any
scroll request.
I have not used this myself (the largest result set I need to process is ~50k documents) but this seems to be what you're looking for.
You should used sliced scroll for that, see https://github.com/elastic/elasticsearch-dsl-py/issues/817#issuecomment-372271460 on how to do it in python.
I met the same problem as yours, but the doc size is 1.4 million. I've had to use concurrency method and use 10 threads for data writting.
I wrote the code with Java thread pool, and you can find the similar way in Python.
public class ControllerRunnable implements Runnable {
private String i_res;
private String i_scroll_id;
private int i_index;
private JSONArray i_hits;
private JSONObject i_result;
ControllerRunnable(int index_copy, String _scroll_id_copy) {
i_index = index_copy;
i_scroll_id = _scroll_id_copy;
}
#Override
public void run(){
try {
s_logger.debug("index:{}", i_index );
String nexturl = m_scrollUrl.replace("--", i_scroll_id);
s_logger.debug("nexturl:{}", nexturl);
i_res = get(nexturl);
s_logger.debug("i_res:{}", i_res);
i_result = JSONObject.parseObject(i_res);
if (i_result == null) {
s_logger.info("controller thread parsed result object NULL, res:{}", i_res);
s_counter++;
return;
}
i_scroll_id = (String) i_result.get("_scroll_id");
i_hits = i_result.getJSONObject("hits").getJSONArray("hits");
s_logger.debug("hits content:{}\n", i_hits.toString());
s_logger.info("hits_size:{}", i_hits.size());
if (i_hits.size() > 0) {
int per_thread_data_num = i_hits.size() / s_threadnumber;
for (int i = 0; i < s_threadnumber; i++) {
Runnable worker = new DataRunnable(i * per_thread_data_num,
(i + 1) * per_thread_data_num);
m_executor.execute(worker);
}
// Wait until all threads are finish
m_executor.awaitTermination(1, TimeUnit.SECONDS);
} else {
s_counter++;
return;
}
} catch (Exception e) {
s_logger.error(e.getMessage(),e);
}
}
}
scroll must be synchronous, this is the logic.
You can use multi thread, this is exactly why elasticsearch is good for: parallelism.
An elasticsearch index, is composed of shards, this is the physical storage of your data. Shards can be on the same node or not (better).
Another side, the search API offers a very nice option: _preference(https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-preference.html)
So back to your app:
Get the list of index shards (and nodes)
Create a thread by shard
Do the scroll search on each thread
Et voilà!
Also, you could use the elasticsearch4hadoop plugin, which do exactly that for Spark / PIG / map-reduce / Hive.
I am using the autocomplete textbox from this MSDN link.
Question:
CSWPFAutoCompleteTextBox has property "AutoSuggestionList" which I bound this to observable string collection. Each string is made of id + description. When user selects an item from dropdown, how can I override the texbox content? I want to manipulate the text box content.
This is a textbox that extends a wpf combobox to make it searchable.
When the user types in a string in the textbox, it displays matching strings as a dropdown, user selects an item and the item is displayed in the textbox.
the question is how to override the textbox contents of this control.
Without actual format of your code it is hard to answer precisely, but for example, if your strings are
string[] suggestions = {"0: Yes", "1: No", "666: whatever"}
Then you could get the number by something like
sugestedString.Substring(0, sugestedString.IndexOf(':'));
EDIT: I misunderstood the question. So if I now understands correctly, you might do it with
for(int i = 0; i < suggestions.Length; i++) {
if(suggestions[i] == selectedString) {
return i;
}
}
If you seek only a number within your list of all possible suggestions.
If you seek a number within narrowed-down suggestions, it gets somewhat more difficult.
You firstly need to note down what user has typed so-far (e.g. "Aut"). Then you need what he actually selected (e.g. "Automotive"). With those things, you can then search all your possible suggestions, count how many of them satisfies the user-typed beginning and finaly which of them is the selected one. It might look like this:
int counter=0;
for(int i = 0; i < suggestions.Length; i++) {
if( suggestions[i].StartsWith(typedString)) {
counter++;
if(suggestions[i] == selectedString) {
counter;
}
}
}
I am trying to implement a functionality in opencart where it will be possible to enter a custom price at the product page via text area and when item is added to the cart if custom price entered it will apply the price specified in the custom price field.
Similar question was asked here someone kindly provided a good solution which applies to OpenCart 1.5.x. However I have tried to follow this approach on OpenCart 2 without any success. I have checked everything over and over for the last few days but I don't seem to be able to get this working as I am a newbie in programming world
I wondering if anyone is able to point me to right direction to what I may be missing.
I have search the web but unable to find any relevant information
I have checked and noticed that AJAX request is changed to #product div in 2.x, so I have enter my price input within this div underneath the quantity
<input name="custom_price" id="custom_price" value="" title="custom_price" class="input-text custom_price" type="textarea">
I have than moved on to the controller checkout/cart/add within the Add() method I have added this code
if(isset($this->request->post['custom_price'])) {
$custom_price = $this->request->post['custom_price'];
} else {
$custom_price = false;
}
Further down, I have changed this line
$this->cart->add($this->request->post['product_id'], $this->request->post['quantity'], $option, $recurring_id);
to:
$this->cart->add($this->request->post['product_id'], $this->request->post['quantity'], $option, $custom_price, $recurring_id);
Next, in the system/library/cart.php I have change the definition of the Add() method to the following
public function add($product_id, $qty = 1, $option = array(), $recurring_id = 0, $custom_price = false) {
Before the end of the Add()method I have added the following
if($custom_price) {
if(!isset($this->session->data['cart']['custom_price'])) {
$this->session->data['cart']['custom_price'] = array();
}
$this->session->data['cart']['custom_price'][$key] = $custom_price;
}
Within the GetProduct() I have added these lines
if(isset($this->session->data['cart']['custom_price'][$key])) {
$price = $this->session->data['cart']['custom_price'][$key];
}
right after this line:
$price = $product_query->row['price'];
Finally at after the array where product price is set to price + option price
'price' => ($price + $option_price),
I have added the following
if(isset($this->session->data['custom_price'][$key])) {
$this->data[$key]['price'] = $this->session->data['custom_price'][$key];
}