Ionic 2/3 :Dynamically set RootPage - ionic2

I have a scenario where I have 2 profiles (user and admin) and I have a selection page once a person logs in. On the selection page, there are 2 radio buttons for (User and Admin profiles), what I am trying to achieve is, the person can choose only 1 profile (this is achieved by the radio button), now assuming I have saved the selected value, I want to set the rootPage to AdminPage or UserPage, but I don't want to immediately navigate, I just want to update/set the path so that when the person goes back (by pressing the back key or previous button) it will take the person to the desired page. Please let me know your thoughts.

Maby this will put you in the right direction:
https://ionicframework.com/docs/api/navigation/NavController/#insert
do not set adminPage or userPage as rootPage but insert the page on the stack

The trick here is that you want to set the root to a new page after the user tries to go back, the easiest way to achieve this is using the NavController navguards to execute a code before leaving the page, this way it'll check wich page the user has selected and then set the root.
Since the select can be easy impemented following the docs i'll leave that aside. Let's just say you have a property userType that is a string and can be 'user' or 'admin', in your select page you'll do the following:
public canLeave: boolean = false; //this'll controll if the user can leave the page or not
public userType: string = 'user'; // just setting a default value to your select
// this is a navguard
ionViewCanLeave() {
if(!this.canLeave){
if(this.userType == 'user'){
this.canLeave = true; // you'll need to set canLeave to true so when setting the rootpage it doesn't enters the if statemente again
this.navCtrl.setRoot('UserPage');
} else {
this.canLeave = true;
this.navCtrl.setRoot('AdminPage');
}
}
return true;
}
Hope this helps.

I got the solution to the error,
ionViewCanLeave() {
if(!this.canLeave){
if(this.userType == 'user'){
this.canLeave = true; // you'll need to set canLeave to true so when setting the rootpage it doesn't enters the if statemente again
this.navCtrl.setRoot('UserPage'); // <-- this should be UserPage instead of 'UserPage'
} else {
this.canLeave = true;
this.navCtrl.setRoot('AdminPage'); // <-- this should be AdminPage instead of 'AdminPage'
}
}
return true;
}

Related

How to remember past searches for anonymous users

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>`)
})
})
})
})

Attachments moved away from Item after validation and before submit process in Apex

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.

How to abort saveui pipeline in Sitecore and then reset values?

I am trying to implement a saveui pipeline processor in Sitecore 6. Basically I have created a custom processor that presents the user with a popup message depending on which fields they may have changed on the item and what the new data is. If they made certain changes then they are presented with a popup asking them if they want to continue. If they answer no then the pipeline is aborted. That is all working. However I noticed that when you abort the pipeline all Sitecore seems to do is not save. All of the changes that the user made to the content item are still there in the UI. If you navigate away from the item in Sitecore, it will prompt you if you want to save the changes. Is there some way that I can get the Sitecore UI to cancel all of the changes and revert all of the fields back to their initial values? Aborting the pipeline is good because I don't want to save, but I also want to cancel the save in the UI too. Does anyone know how to do this?
Sample Code:
public class CustomSaveProcessor
{
public void Process(SaveArgs args)
{
Sitecore.Diagnostics.Assert.ArgumentNotNull(args, "args");
if(args.Items == null)
{ return; }
if(args.IsPostback)
{
if(args.Parameters["runContext"] == "firstQuestion")
{
if((args.Result == null) || (args.Result == "null") || (args.Result == "no") || (args.Result == "cancel"))
{
args.AbortPipeline();
//Should there be something here to tell the Sitecore UI to reset the values?
return;
}
else
{
//User has answered first question Yes
//This means they want to save the changes to the item
//We also want to ask a second question that effects other content items
SheerResponse.YesNoCancel("Do you want to also modify other items?", "300px", "200px");
args.Parameters["runContext"] = "secondQuestion";
args.WaitForPostBack();
}
}
else
{
if(args.Result == "yes")
{
//This is the answer to second question
//Custom code here to modify other content items
}
//We are completely done now.
return;
}
}
else
{
//Ask the user the first question
SheerResponse.YesNoCancel("Are you sure you want to proceed?", "300px", "200px");
args.Parameters["runContext"] = "firstQuestion";
args.WaitForPostback();
}
}
}
You can just reload the content tree with the following code.
String refresh = String.Format("item:refreshchildren(id={0})", Sitecore.Context.Item.Parent.ID);
Sitecore.Context.ClientPage.SendMessage(this, refresh);
Or as Corey discovered if you want to refersh the item you'd use
String refresh = String.Format("item:load(id={0})", myOriginalItem.ID);
Sitecore.Context.ClientPage.SendMessage(this, refresh);
See this post for more details
I think you can try to reload the current content item after aborting your custom save handler to set the intial values of the content item. Not sure if you then still get the "alert message".
Take a look at this post with a similiar issue

How to flag new items as unpublished items?

In sitecore, if I add a new item to the master database(Unpublished), it does not show any indication regarding the published state.
For an example, if a user has added 10 items, he might get confused to figureout the items added by him which are pending for publishing.
Is there a way to identify newly added items as unpublished or in new and display a validation in the "Quick action bar"?
Never thought about this, but it's actually pretty easy to fix.
I created a GutterRenderer that indicates wether an item has been published to at least one, to all, or to none of the publishing targets.
EDIT: Added Click behaviour. When you click the gutter icon, the Publish dialog will be shown for that item.
First I will show you the code that I wrote for this and then I'll show you screenshots of the setup and the result.
Here is the code:
using System.Collections.Generic;
using System.Linq;
using Sitecore;
using Sitecore.Data;
using Sitecore.Data.Items;
using Sitecore.Globalization;
using Sitecore.Shell.Applications.ContentEditor.Gutters;
namespace ParTech.Library.Gutters
{
public class PublicationStatus : GutterRenderer
{
private readonly ID publishingTargetsFolderId = new ID("{D9E44555-02A6-407A-B4FC-96B9026CAADD}");
private readonly ID targetDatabaseFieldId = new ID("{39ECFD90-55D2-49D8-B513-99D15573DE41}");
protected override GutterIconDescriptor GetIconDescriptor(Item item)
{
bool existsInAll = true;
bool existsInOne = false;
// Find the publishing targets item folder
Item publishingTargetsFolder = Context.ContentDatabase.GetItem(publishingTargetsFolderId);
if (publishingTargetsFolder == null)
{
return null;
}
// Retrieve the publishing targets database names
List<string> publishingTargetsDatabases = publishingTargetsFolder.GetChildren()
.Select(x => x[targetDatabaseFieldId])
.ToList();
// Check for item existance in publishing targets
publishingTargetsDatabases.ForEach(delegate(string databaseName)
{
if (Database.GetDatabase(databaseName).GetItem(item.ID) != null)
{
existsInOne = true;
}
else
{
existsInAll = false;
}
});
// Return descriptor with tooltip and icon
string tooltip = Translate.Text("This item has not yet been published");
string icon = "People/16x16/flag_red.png";
if (existsInAll)
{
tooltip = Translate.Text("This item has been published to all targets");
icon = "People/16x16/flag_green.png";
}
else if (existsInOne)
{
tooltip = Translate.Text("This item has been published to at least one target");
icon = "People/16x16/flag_yellow.png";
}
return new GutterIconDescriptor()
{
Icon = icon,
Tooltip = tooltip,
Click = string.Format("item:publish(id={0})", item.ID)
};
}
}
}
And this is how so set it up and how it will look once it's running:
Figure 1: Create a new Gutter item in the Core database:
Figure 2: Switch back to your Master database and activate the Gutter by right-clicking in the gutter area.
Figure 3: The Gutter now indicates the publication status of your items
From the top of my head it's not available out of the box. In the core database however, there's the definitions of the gutter, etc. You could create your own.
There's the 'published' field on items though, but I'm not sure if that takes different versions into account.
Maybe you can check the differences between the item in the master and web (i.e. Item doesn't exist or is different version in web, then it's waiting to be published).
Alternatively, have a read through this: http://webcmd.wordpress.com/2011/08/31/sitecore-ribbon-that-displays-published-state-of-an-item/
It'll explain how to check if an item is published as a ribbon.

Insert more records at once in raw_id_fields

I have a m2m relation where in my AdminForm I would use raw_id_fields instead of the filter_horizontal option. For explanation I prefer the raw_id_fields instead of the filter_horizontal option, because the records are already categorized. So in the popup-window the user has the ability to search and filter via category.
But there are two points that I can't figure out:
possibility to selecting more than one record in the popup window
showing the real names instead of the pk in the input_field
It's possible. In order to select more than one record, you need to override default dismissRelatedLookupPopup() in django/contrib/admin/static/admin/js/admin/RelatedObjectLookups.js by including your script in the Media class of your ModelAdmin or widget:
var dismissRelatedLookupPopup = (function(prev, $) {
return function(win, chosenId) {
var name = windowname_to_id(win.name);
var elem = document.getElementById(name);
// 1. you could add extra condition checking here, for example
if ($(elem).hasClass('my_raw_id_ext_cls')) { // add this class to the field
// ...logic of inserting picked items from the popup page
}
else { // default logic
prev(win, chosenId);
}
// 2. or you could copy the following part from RelatedObjectLookups.js ...
if (elem.className.indexOf('vManyToManyRawIdAdminField') != -1 && elem.value) {
elem.value += ',' + chosenId;
// 2. and add a return. Remember this acts globally.
return;
} else {
document.getElementById(name).value = chosenId;
}
// 3. the following line cause the popup to be closed while one item is picked.
// You could comment it out, but this would also affect the behavior of picking FK items.
win.close();
}
})(dismissRelatedLookupPopup, django.jQuery);
Django does not support this by default. There are some snippets at djangosnippets.org, you may want to take a look at them.
Finally I'm using a modified https://django-salmonella.readthedocs.org/en/latest/. I don't show the input field and show the selected records in a table.