I have 3 conditions which would render 3 different gritter notifications. The condition results should change the image, text and title. Do I have to $.gritter.add({...}) for every single condition?
Or is there a way to declare just one gritter notification before any of the conditions are met, and then within each condition, set the title, text, image as they may apply to that condition?
It seems the only return value from $.gritter.add({...}) is a unique id, which is great for removal, but from first glance, I don't see a way into an added gritter item from inspecting the DOM in firebug.
Any help is appreciated
I know this is years later but this is how you change the properties/values of gritter:
var unique_id = $.gritter.add({
// (string | mandatory) the heading of the notification
title: '<i class="fa fa-4x fa-bell"></i> New Page Enhancement!',
// (string | mandatory) the text inside the notification
text: 'Visit "New Page Enhancements" by clicking on the notifications icon.',
// (string | optional) the image to display on the left
image: '../images/logo.png',
// (bool | optional) if you want it to fade out on its own or just sit there
sticky: true,
// (int | optional) the time you want it to be alive for before fading out
time: '',
// (string | optional) the class name you want to apply to that specific message
class_name: 'my-sticky-class'
});
The unique_id can be named for each instance of gritter you plan to roll out.
Related
I have the following vue template:
<template>
<q-item tag="label" v-ripple>
<q-popup-edit
v-model="model"
:cover="false"
fit
buttons
:validate="validate"
#before-show="modelProxy = model"
>
<template v-slot:title>
<div class="text-mono">
{{ name }}
</div>
</template>
<q-input
color="indigo"
v-model="modelProxy"
dense
autofocus
counter
:type="dataType ? dataType : 'text'"
:hint="hint"
:error="error"
:error-message="errorMessage"
/>
</q-popup-edit>
<q-item-section>
<q-item-label class="text-mono">{{ name }}</q-item-label>
<q-item-label v-if="offset && model && model.length > offset" caption
>...{{
model.substring(model.length - offset, model.length)
}}</q-item-label
>
<q-item-label v-else caption>{{ model }}</q-item-label>
</q-item-section>
</q-item>
</template>
I would like to perform E2E test using Cypress with the following code snippet:
it('Verify Edit Box from auto-generated page', () => {
cy.get('[data-test="popup-edit-setting-1"]').contains("Auto Generated Edit box");
cy.get('[data-test="popup-edit-setting-2"]').contains("Auto Generated Edit box (Number)");
cy.get('[data-test="popup-edit-setting-1"]').should("be.enabled"); // XXX
cy.get('[data-test="popup-edit-setting-1"]').focus().click().type("Hello");//.click("SET");
cy.get('[data-test="popup-edit-setting-1"]').find("label").should('have.value', 'Hello') // XXX
});
It stumbles on the XXX points.
#Fody's solution works but there is one minor issue. I have 2 popup edit box. One with normal string, another with only numeric. There are 2 test cases for the numeric popup editbox. One with invalid normal string entry and another with valid numbers. The problem is that at the end of the test, the numeric popup edit box does NOT return to display mode. It stays popup.
This is the way I would test q-popup-edit. I used a generic example, yours may differ in some details.
I aimed to test based on what a user sees rather than any internal class or internal properties.
The user story is:
the text to be edited has a "hand" pointer when hovered
click on it to change it from "display" mode to "edit" mode
the input is automatically focused, user can start typing
user enters some text
user clicks away and the input loses focus, goes back to "display" mode
// activate popup editor
const initialText = 'Click me'
cy.contains('div.cursor-pointer', initialText) // displayed initial text
.should('be.visible') // with hand cursor
.click()
// initial condition
cy.focused() // after click <input> should have focus
.as('input') // save a reference
.should('have.prop', 'tagName', 'INPUT') // verify it is the input
cy.get('#input')
.invoke('val')
.should('eq', initialText) // displayed text is also in the input
cy.contains('8').should('be.visible') // character count
// edit action
cy.get('#input')
.clear()
.type('test input')
cy.get('#input')
.invoke('val')
.should('eq', 'test input') // verify input
cy.contains('10').should('be.visible') // character count has changed
// back to display mode
cy.get('body').click() // go back to display mode
cy.contains('div.cursor-pointer', 'test input')
.should('be.visible')
.and('contain', 'test input') // verify display element
cy.contains('10').should('not.exist') // edit counter has gone
Notes
To start the edit, you need to identify the display-mode element. It's easiest if you have some unique text in the field, so try to arrange that in the page initial data.
If no unique text, look for a label or some other selectable element nearby then navigate to it.
If you add a data-cy attribute to the <q-popup-edit>, it will not exist in the DOM until the component enters edit-mode (so you can't use it in the initial click()).
I have a TextEditingController which is for phone numbers. If text is pasted in it, I need to process and modify it, trimming whitespaces etc. But that should not happen if the user is typing in whitespaces. How can I differentiate between these two types of events, and call my function only when user pastes text into the field?
Currently my code looks like this and uses onChanged. I'm looking for something like onPaste:
String getCorrectedPhone(String phone) {
phone = phone.replaceAll(RegExp(r"\s+"), "");
return phone;
}
FormBuilderTextField(
controller: _phoneController,
name: "phone",
onChanged: (String txt) {
print('Phone field changed! Is now $txt');
_phoneController.text = getCorrectedPhone(txt);
},
),
You can do something like declare a length with the phone number field and add a listener to the text editing controller or in oNchanged which checks if its length - the old length is >1. Then its pasted
int length = 0;
...
_phoneController.addListener((){
if (abs(textEditingController.text.length - length)>1){
// Do your thingy
}
length = _phoneController.length;
});
So there is another way, that is to ignore any touches on the text field using the IgnorePointer widget and then use Gesture Detector to implement custom long tap and short taps. For long taps, you'll have to create your own small pop up menu for copy cut paste and stuff. Here is some sample code for the UI. As for the functioning, I would recommend using the https://api.flutter.dev/flutter/services/Clipboard-class.html class of flutter. If you need any help in doing this let me know but it should be mostly straightforward
Hi I just created the ionic accordion dropdowns by following a tutorial blog link which used widgets for creating an accordion dropdowns, Below is the link of that blog.
http://masteringionic.com/blog/2019-01-27-creating-a-simple-accordion-widget-in-ionic-4/
updated: here is the my project demo link https://stackblitz.com/github/dSaif/search-accordion
Everything is working perfect, but i want to add Ion-searchbar at the top of the accordions sothat the dropdowns gets filter by inputing text.
please assist me how can i do that. Thank you.
You are going to have to create a variable in your homepage to store your filtered results. Then you need to have a filter function that will take the input from the search bar and filter your master list. Keep in mind you should not set the new variable to the master list, this could cause issues due to object referencing.
So you should have something like
in your html
<ion-searchbar placeholder="Search a name." [(ngModel)]="searchValue" (ionChange)="filterList()"></ion-searchbar>
In your ts file
searchValue: string = '';
filteredList: Array<{ name: string, description: string, image: string }> = this.technologies;
// function called in the html whenever you change the ion searchbar value
private filterList(){
//Make a variable so as to avoid any flashing on the screen if you set it to an empty array
const localFilteredList = []
this.technologies.forEach(currentItem => {
//here goes your search criteria, in the if statement
if(currentItem.name && currentItem.name.toLowerCase().includes(this.searchValue.toLowerCase())) {
localFilteredList.push(currentItem);
}
});
//finally set the global filter list to your newly filtered list
this.filteredList = localFilteredList;
}
You also need to make sure to reference the filterList variable instead of the current one you are referencing.
I'm trying to get user's latest mouse click in order to display the right table. However, I can't find any way to implement this idea. How do i get user's latest mouse click by using mouseEvent function?
I tried using if else statements but it doesn't work when there is still value in the monstersTable1
def handleEditMonster(action : ActionEvent) = {
val selectedMonster1 = monstersTable1.selectionModel().selectedItem.value
val selectedMonster2 = monstersTable2.selectionModel().selectedItem.value
if (selectedMonster1 != null){
val okClicked = MainApp.showMonsterEditDialog(selectedMonster1)
if (okClicked) showMonstersDetails(Some(selectedMonster1))
} else if (selectedMonster2 != null) {
val okClicked = MainApp.showMonsterEditDialog(selectedMonster2)
if (okClicked) showMonstersDetails(Some(selectedMonster2))
} else {
// Nothing selected.
val alert = new Alert(Alert.AlertType.Warning){
initOwner(MainApp.stage)
title = "No Selection"
headerText = "No monsters Selected"
contentText = "Please select a monsters in the table."
}.showAndWait()
}
}
I want it to be able to access the second table even though selectedMonster1 is still != null
It's not entirely clear from your question what it is you're trying to do, so please bear with me... (For future reference, it's best if you can create a ''minimal, complete and verifiable example'' that illustrates your problem.)
I'm assuming that you have two scalafx.scene.control.TableView instances, referenced via monstersTable1 and monstersTable2. You want to allow the user to select either one of the monsters in the first table, or one of the monsters in the second table, but not to be able to select one monster from each table simultaneously.
I'm unclear when your handleEditMonster function is called, so I'm guessing that it's invoked when the user clicks, say, an Edit Monster button, as that button's clicked event handler.
Do I have that right?
Assuming the above is accurate, you should listen for changes in table selection, and clear the selection in the other table when a new selection is made. The currently selected item in each table is a property that we can add a listener to, so we can achieve this with the following code (in your scene's initialization):
// In the onChange handlers, the first argument references the observable property
// that has been changed (in this case, the property identifying the currently
// selected item in the table), the second is the property's new value and the third
// is its previous value. We can ignore the first and the third arguments in this
// case. If the newValue is non-null (that is, if the user has made a
// selection from this table), then clear the current selection in the other
// table.
monstersTable1.selectionModel.selectedItem.onChange {(_, newValue, _) =>
if(newValue ne null) monstersTable2.selectionModel.clearSelection()
}
monstersTable2.selectionModel.selectedItem.onChange {(_, newValue, _) =>
if(newValue ne null) monstersTable1.selectionModel.clearSelection()
}
This should do the trick for you, and your handleEditMonster function should now work. You might want to add an assertion to guard against both tables having a current selection, which would indicate a bug in the selection handler logic.
How to prevent select change event fires when the select biding is initiated? an add button on the page that will add select dynamically to the DOM. when each select box is adding to the DOM, the change event is firing rather than I select the item from the select?
The thing is that KnockoutJS attempts to find which element of your listbox matches the requiredItem observable. There is none in the beginning, which is why it then attempts to set it to the "caption" of the listbox. You did not provide one, so it sets requiredItem to the first element of the listbox.
What you could do is add a caption item to your array:
self.requireditems = ko.observableArray([
{ desc: "Select an option from the list...", key: 0, editable: false } // ... and then all other items]);
and if you really don't want requiredItem to be updated:
self.selectedItem = ko.observable(self.requiredItems()[0]);
Then if you want to know if a valid element has been selected from the list, you could add the following property:
self.isValidSelectedItem = ko.computed(function() {
return self.selectedItem().id;
});