My application doesn't have user accounts, the users anonymously interact with it.
I want to be able to remember what a user has searched for previously without attaching it to their account (as they don't have one). How would I go about doing this?
Is cookies the answer I am looking for? If so, can you point me in the right direction.
Clarification: when the users clicks the search bar to search for something, I want to be able to display what that specific user has searched for in the past in a drop-down box.
you can use localStorage in this situation
There are code snippets which will help you (preliminarily add jQuery in you project for example in head of html
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
). Just add it in your templates
//selector by id - #selector, by class - .selector, by tag - selector
function getItemsFromLS(){
return JSON.parse(localStorage.getItem('search'))
}
function addNewItemToLS(item){
localStorage.setItem('search',JSON.stringify([...getItemsFromLS(), item]))
}
$(document).ready(function(){
//if there are no storage create it
if(!localStorage.getItem('search')){
localStorage.setItem('search', JSON.stringify([]))
}
//click on the search button
$('search-button-selector').click(function(){
//get item form input
let newItem = $('input-type-selector').val()
addNewItemToLS(newItem)
})
//show items on focus of search bar
$('input-type-selector').focus(function(){
let searchItems = []
$(this).change(function(){
searchItems = getItemsFromLS().filter((item)=>item.includes($(this).val()))
$('list-of-search').empty()
searchItems.forEach((item)=>{
$('list-of-search').append(`<span>${item}</span>`)
})
})
})
})
Related
I'm trying to customize a page so that the edit button (the pencil icon one) directs the user to a specific page. In my case, the edit button is linked to a BAccountID field :
By default, it opens the Business Account's page (page CR303000):
I would like it to open a different page that I created that has a similar BAccount view (page AR303001) :
Can this be done ? And how ? I can't seem to find the code behind this logic.
The target graph is declared in the PXPrimaryGraph attribute decorating the DAC.
BAccount DAC is a special case that uses a more complex attribute (CRCacheIndependentPrimaryGraphList) that inherits from PXPrimaryGraph.
[CRCacheIndependentPrimaryGraphList(new Type[]{
typeof(CR.BusinessAccountMaint),
typeof(EP.EmployeeMaint),
typeof(AP.VendorMaint),
typeof(AP.VendorMaint),
typeof(AR.CustomerMaint),
typeof(AR.CustomerMaint),
typeof(AP.VendorMaint),
typeof(AR.CustomerMaint),
typeof(CR.BusinessAccountMaint)},
new Type[]{
typeof(Select<CR.BAccount, Where<CR.BAccount.bAccountID, Equal<Current<BAccount.bAccountID>>,
And<Current<BAccount.viewInCrm>, Equal<True>>>>),
typeof(Select<EP.EPEmployee, Where<EP.EPEmployee.bAccountID, Equal<Current<BAccount.bAccountID>>>>),
typeof(Select<AP.VendorR, Where<AP.VendorR.bAccountID, Equal<Current<BAccount.bAccountID>>>>),
typeof(Select<AP.Vendor, Where<AP.Vendor.bAccountID, Equal<Current<BAccountR.bAccountID>>>>),
typeof(Select<AR.Customer, Where<AR.Customer.bAccountID, Equal<Current<BAccount.bAccountID>>>>),
typeof(Select<AR.Customer, Where<AR.Customer.bAccountID, Equal<Current<BAccountR.bAccountID>>>>),
typeof(Where<CR.BAccountR.bAccountID, Less<Zero>,
And<BAccountR.type, Equal<BAccountType.vendorType>>>),
typeof(Where<CR.BAccountR.bAccountID, Less<Zero>,
And<BAccountR.type, Equal<BAccountType.customerType>>>),
typeof(Select<CR.BAccount,
Where2<Where<
CR.BAccount.type, Equal<BAccountType.prospectType>,
Or<CR.BAccount.type, Equal<BAccountType.customerType>,
Or<CR.BAccount.type, Equal<BAccountType.vendorType>,
Or<CR.BAccount.type, Equal<BAccountType.combinedType>>>>>,
And<Where<CR.BAccount.bAccountID, Equal<Current<BAccount.bAccountID>>,
Or<Current<BAccount.bAccountID>, Less<Zero>>>>>>)
},
VerifyRightsBy = new [] { typeof(CR.BusinessAccountMaint) })]
There is no way to easily customize this attribute. To change it would you need to replace the BAccount DAC with another one. The preferred method for your use case is to avoid usage PXPrimaryGraph attribute by using a regular action button.
The action button can be configured to show the pencil icon:
Make PXButton appear as pencil icon
And it can be displayed beside the field using PXLayout Merge property or you can use LinkCommand to redirect:
https://stackoverflow.com/a/60446714/7376238
I have multiple File Browser Item fields on one page of Application in Oracle Apex.
What happens: When I miss any Item for which validation error fires, I want to hold that file to the browser but I usually loose it if I get that validation error. Is there a solution for the same like other Items fields hold previous value except File Browser Item field. Please see below ss:
Anshul,
APEX 4.2 is very old and no longer supported. A later (or preferably latest) version of APEX will behave differently as Dan explained above.
Can you import your application into apex.oracle.com (which is running APEX 20.1) and you will probably see better results. Based on this you can hopefully use it as justification to upgrade your environment.
Regards,
David
Go to your page-level attributes and a function like the following in the Function and Global Variable Declaration:
function validateItems(request) {
var $file1 = $('#P68_FILE_1');
var $file2 = $('#P68_FILE_2');
var errorsFound = false;
if ($file1.val() === '') {
errorsFound = true;
// Show item in error state
}
if ($file2.val() === '') {
errorsFound = true;
// Show item in error state
}
if (!errorsFound) {
// I think doSubmit was the name of the function back then. If not, try apex.submit
doSubmit(request);
} else {
// Show error message at top of page, I'll use a generic alert for now
alert('You must select a file for each file selector.');
}
}
Then, right-click the Create button and select Create a Dynamic Action. Set the name of the Dynamic Action to Create button clicked.
For the Action, set Type to Execute JavaScript Code. Enter the following JS in code:
validateItems('CREATE');
Finally, ensure that Fire on Initialization is disabled.
Repeat the process for the Save button, but change the request value passed to validateItems to SAVE.
I'd like to reconfigure the default "Publish" menu. The default configuration is this:
I'd like to make Publish the default action, and move it to the top. I'd also like to remove Submit for Moderation, as our site has no current need for that feature.
Ideally, I'd love to be able to override the menu config on a per-app basis - we will likely have other sections of our site in the future where we want a different config.
Is this possible?
This isn't currently possible I'm afraid - the menu items are fixed in wagtailadmin/pages/create.html and edit.html.
This is possible as of Wagtail 2.4 using the register_page_action_menu_item hook, as per Yannic Hamann's answer. Additionally, Wagtail 2.7 (not released at time of writing) provides a construct_page_listing_buttons hook for modifying existing options.
You can add a new item to the action menu by registering a custom menu item with the help of wagtail hooks.
To do so create a file named wagtail_hooks.py within any of your existing Django apps.
from wagtail.core import hooks
from wagtail.admin.action_menu import ActionMenuItem
class GuacamoleMenuItem(ActionMenuItem):
label = "Guacamole"
def get_url(self, request, context):
return "https://www.youtube.com/watch?v=dNJdJIwCF_Y"
#hooks.register('register_page_action_menu_item')
def register_guacamole_menu_item():
return GuacamoleMenuItem(order=10)
Source
If you want to remove an existing menu item:
#hooks.register('construct_page_action_menu')
def remove_submit_to_moderator_option(menu_items, request, context):
menu_items[:] = [item for item in menu_items if item.name != 'action-submit']
The default button SAVE DRAFT is still hardcoded and therefore cannot be configured so easily. See here.
It seems it can't be done on server side without some monkey-patching.
However if you want it for yourself (or have access to computers of those who will publish) you can modify your browser instead.
Install Tampermonkey browser addon
Create new script with a content below
Change http://127.0.0.1:8000/admin/* to your wagtail admin panel url pattern
Save script and check admin panel
Result should look:
// ==UserScript==
// #name Wagtail: replace "Save draft" with "Publish"
// #match *://127.0.0.1:8000/admin/*
// #require https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js
// ==/UserScript==
let $ = window.jQuery;
function modify() {
let draft = $("button.button-longrunning:contains('Save draft')");
let publish = $("button.button-longrunning:contains('Publish')");
if (draft.length && publish.length) {
swap(publish, draft);
}
};
function swap(a, b) {
a = $(a); b = $(b);
var tmp = $('<span>').hide();
a.before(tmp);
b.before(a);
tmp.replaceWith(b);
};
$(document).ready(function() {
setTimeout(function() {
try {
modify();
}
catch (e) {
console.error(e, e.stack);
}
}, 100);
});
Modifying the code above, these selectors works for every admin language:
let draft = $("button.button-longrunning.action-save");
let publish = $("button.button-longrunning[name='action-publish']");
I’m displaying dropdowns in HTML to alter a SAS output. The values of the dropdowns only affect SAS each time the page loads. I want to link to a second page and pass the values of the dropdown. However SAS is unaware of what the values are unless the current page reloads and saves the dropdown values. So I want to reload the same page when the user clicks a button. Then redirect the user to a second page. All of the redirect code I see redirects the user 100% of the time while I only want to redirect the based on a condition.
The method I described in my comment would look something like this.
HTML:
<button onclick="saveData()">Save</button>
JS:
(function() {
if ( getQueryVariable("data") == "saved" ) {
alert("true");
}
})();
function saveData() {
var newPage = window.location.href + "?data=saved";
window.location.replace(newPage);
}
function getQueryVariable(variable) {
var query = window.location.search.substring(1);
var vars = query.split("&");
for (var i=0;i<vars.length;i++) {
var pair = vars[i].split("=");
if(pair[0] == variable){return pair[1];}
}
return(false);
}
I added this to the dropdownlists
onchange='this.form.submit()'
Which made the refresh button not needed.
I am creating a custom item editor, and am using the following blog post as a reference for responding to the "save" event in the Content Editor, so that I do not need to create a second, confusing Save button for my users.
http://www.markvanaalst.com/sitecore/creating-a-item-editor/
I am able to save my values to the item, but the values in the normal Content tab are also being saved, overriding my values. I have confirmed this via Firebug. Is there a way to prevent this, or to ensure my save is always after the default save?
I have this in as a support ticket and on SDN as well, but wondering what the SO community can come up with.
Thanks!
Took a shot at an iframe-based solution, which uses an IFrame field to read and save the values being entered in my item editor. It needs to be cleaned up a bit, and feels like an interface hack, but it seems to be working at the moment.
In my item editor:
jQuery(function () {
var parentScForm = window.parent.scForm;
parentScForm.myItemEditor = window;
});
function myGetValue(field) {
var values = [];
jQuery('#myForm input[#name="' + field + '"]:checked').each(function () {
values.push(jQuery(this).val());
});
var value = values.join('|');
return value;
}
In my Iframe field:
function scGetFrameValue() {
var parentScForm = window.parent.scForm;
if (typeof (parentScForm.myItemEditor) != "undefined") {
if (typeof (parentScForm.myItemEditor.myGetValue) != "undefined") {
return parentScForm.myItemEditor.myGetValue("myLists");
}
}
return null;
}
In theory, I could have multiple fields on the item which are "delegated" to the item editor in this way -- working with the content editor save rather than trying to fight against it. I'm a little uneasy about "hitchhiking" onto the scForm to communicate between my pages -- might consult with our resident Javascript hacker on a better method.
Any comments on the solution?
EDIT: Blogged more about this solution