AUI datepicker: pop up datepicker on focus of element - liferay

How can i make AUI-datepicker to pop up on the focus of element. cuurrently it only pop up on click of element.
Here is code
Script:
YUI().use('aui-datepicker',
function(Y) {
new Y.DatePicker(
{
trigger: '.date-selector',
popover: {
zIndex: 1
},
}
);
}
);
and Tag
<aui:input id="startDate" name="startDate" cssClass="date-selector" label="startDate">
and one more thing how can i range date?

Try this something like this:
<aui:input name="taskStartDate" autocomplete="off" cssClass='font-size' id="taskStartDate" onFocus="onClickOfStartDate();" required="true" inlineLabel="true" label=" "/>
<aui:script>
function setactualStartDate(){
AUI().use('aui-datepicker', function(A) {
var simpleDatepicker1 = new A.DatePicker({
trigger: '#<portlet:namespace />taskActualStartDate',
mask: '%Y-%m-%d',
calendar: {
dateFormat: '%Y-%m-%d',
},
}).render('#<portlet:namespace />taskactualStartDatePicker');
});
}
function onClickOfStartDate(){
setStartDate();
}
</aui:script>

The Datepicker popup is handled by DatePickerPopover class of aui-datepicker module. There is show() method in datepicker class to open popup.
<input id="startDate" name="startDate" class="date-selector" onfocus="openDatePicker();">
<script>
var datePicker;
YUI().use('aui-base','aui-datepicker', function(Y) {
datePicker = new Y.DatePicker({
trigger: '#startDate',
popover: {
zIndex: 10,
},
calendar: {
maximumDate: new Date()
}
});
});
function openDatePicker() {
datePicker.getPopover().show();
}
</script>
Date can be ranged by adding maximumDate and minimumDate attribute.

Related

Adding Stripe Subscription to Blazor WASM

I am trying to add Stripe Subscription to my Blazor WASM Application following these instructions Since they are using JavaScript I am using the JavaScript interop. I added Stripe's script to my index.html and added a custom script with the javascript they have in the instructions.
Index.html inside the <head> tag
<script src="https://js.stripe.com/v3/"></script>
<script src="stripescript.js"></script>
stripescript.js:
let stripe = window.Stripe('MY PUBLIC KEY');
let elements = stripe.elements();
let card = elements.create('card', { style: style });
card.mount('#card-element');
card.on('change', function (event) {
displayError(event);
});
function displayError(event) {
changeLoadingStatePrices(false);
let displayError = document.getElementById('card-element-errors');
if (event.error) {
displayError.textContent = event.error.message;
} else {
displayError.textContent = '';
}
}
function createPaymentMethod(cardElement, customerId, priceId) {
return stripe
.createPaymentMethod({
type: 'card',
card: cardElement,
})
.then((result) => {
if (result.error) {
displayError(error);
} else {
//change this to call .net
createSubscription({
customerId: customerId,
paymentMethodId: result.paymentMethod.id,
priceId: priceId,
});
}
});
}
My assumption is that the variable initializations would happen when the application is loaded. However, when I add the following HTML to my Razor page is not populating the card component.
<form id="payment-form">
<div id="card-element">
<!-- Elements will create input elements here -->
</div>
<!-- We'll put the error messages in this element -->
<div id="card-element-errors" role="alert"></div>
<button type="submit">Subscribe</button>
</form>
I am lost on how to debug this, or if this is even possible in Blazor.
Thanks to #Umair's Comments, I realized that I had made a few mistakes and some of them were showing up in the console since I was trying to initialize the card element before the DOM was loaded. I was able to fix my problem by first changing the card mount into its own function. Here is the full stripescript.js for future people that have this problem:
let stripe = window.Stripe('MY KEY');
let elements = stripe.elements();
let style = {
base: {
fontSize: '16px',
color: '#32325d',
fontFamily:
'-apple-system, BlinkMacSystemFont, Segoe UI, Roboto, sans-serif',
fontSmoothing: 'antialiased',
'::placeholder': {
color: '#a0aec0',
},
},
};
let card = elements.create('card', { style: style });
function mountCard() {
card.mount('#card-element');
}
card.on('change', function (event) {
displayError(event);
});
function displayError(event) {
changeLoadingStatePrices(false);
let displayError = document.getElementById('card-element-errors');
if (event.error) {
displayError.textContent = event.error.message;
} else {
displayError.textContent = '';
}
}
function createPaymentMethod(cardElement, customerId, priceId) {
return stripe
.createPaymentMethod({
type: 'card',
card: cardElement,
})
.then((result) => {
if (result.error) {
displayError(error);
} else {
//todo change this to call .net
createSubscription({
customerId: customerId,
paymentMethodId: result.paymentMethod.id,
priceId: priceId,
});
}
});
}
and added the following C# code to my Blazor component to render the card:
[Inject] IJSRuntime js { get; set; }
protected override async Task OnAfterRenderAsync(bool firstRender)
{
await js.InvokeVoidAsync("mountCard");
}
I found a solution for this on Youtube that is super complicated, and I decided to create my own implementation following KISS.
I have streamlined youtube's implementation on a single StripeCard component that interacts with my custom Js StripeInterop. I hope this makes your life easier.
This will allow you to have different publishable keys for your different environments without hardcoding it and reuse the component in multiple pages if you wish. Also, it will destroy itself when the component is used.
Here is my solution for (blazor webassembly).
Add this to index.html
<!-- Stripe -->
<script src="https://js.stripe.com/v3/"></script>
<script src="stripescript.js"></script>
Here is stripescript.js
StripeInterop = (() => {
var stripe = null;
var elements = null;
var dotNetReference = null;
var card = null;
var style = {
base: {
color: '#32325d',
fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
fontSmoothing: 'antialiased',
fontSize: '16px',
'::placeholder': {
color: '#aab7c4'
}
},
invalid: {
color: '#fa755a',
iconColor: '#fa755a'
}
};
return {
init(dotnetHelper, publishableKey) {
stripe = window.Stripe(publishableKey);
elements = stripe.elements();
card = elements.create('card', { style: style });
dotNetReference = dotnetHelper;
card.mount('#card-element');
card.on('change', function (event) {
displayError(event);
});
},
createPaymentMethod(billingEmail, billingName) {
return stripe
.createPaymentMethod({
type: 'card',
card: card,
billing_details: {
name: billingName,
email: billingEmail
}
})
.then(function (result) {
if (result.error) {
displayError(result);
} else {
dotNetReference.invokeMethodAsync('ProcessPaymentMethod', result.paymentMethod.id);
}
});
},
destroy() {
dotNetReference.dispose();
card.destroy();
}
};
function displayError(event) {
var showError = document.getElementById('card-element-errors');
if (event.error) {
showError.textContent = event.error.message;
} else {
showError.textContent = '';
}
}
})();
Here is StripeCard.razor component
#namespace SmartApp.Components
<div id="card-element" style="display: block;
width: 100%;
padding: 0.52rem .75rem;
font-size: 1rem;
line-height: 1.5;
color: #495057;
background-color: #fff;
background-clip: padding-box;
border: 1px solid #ced4da;
border-radius: .25rem;
transition: border-color .15s ease-in-out,box-shadow .15s ease-in-out;">
</div>
<div id="card-element-errors" class="validation-message"></div>
Here is StripeCard.razor.cs
using Microsoft.AspNetCore.Components;
using Microsoft.JSInterop;
namespace SmartApp.Components
{
public partial class StripeCard : IDisposable
{
[Inject] IJSRuntime JS { get; set; }
[Parameter] public string PublishableKey { get; set; }
[Parameter] public EventCallback<string> CardProcessedCallBack { get; set; }
private bool _firstTime;
protected override async Task OnInitializedAsync()
{
_firstTime = true;
await base.OnInitializedAsync();
}
public async void Dispose()
{
await JS.InvokeVoidAsync("StripeInterop.destroy");
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (_firstTime)
{
_firstTime = false;
await JS.InvokeVoidAsync("StripeInterop.init", DotNetObjectReference.Create(this), PublishableKey);
}
}
[JSInvokable("ProcessPaymentMethod")]
public Task ProcessPaymentMethod(string paymentId)
{
return CardProcessedCallBack.InvokeAsync(paymentId);
}
}
}
Here is how we use StripeCard.razor in our Page.
#page "/subscription/payment"
#attribute [Authorize(Roles = "Admin,Organisation")]
#inject IJSRuntime JS
<div class="card card-custom card-shadowless rounded-top-0">
<div class="card-body p-0">
<div class="row justify-content-center py-8 px-8 py-lg-15 px-lg-10">
<div class="col-xl-12 col-xxl-7">
<!--begin: Wizard Form-->
<EditForm Model="#_model" OnValidSubmit="HandleValidSubmit" >
<DataAnnotationsValidator />
<h4 class="mb-10 font-weight-bold text-dark">Enter your Payment Details</h4>
<div class="row">
<div class="col-xl-6">
<!--begin::Input-->
<div class="form-group">
<label>Name on Card</label>
<InputText #bind-Value="_model.BillingName" name="ccname" class="form-control form-control-solid form-control-lg"
placeholder="Jane Doe" />
<ValidationMessage For="#(() => _model.BillingName)" />
</div>
<!--end::Input-->
</div>
<div class="col-xl-6">
<!--begin::Input-->
<div class="form-group">
<label>Notification Email</label>
<InputText #bind-Value="_model.BillingEmail" name="ccemail" class="form-control form-control-solid form-control-lg"
placeholder="jane.doe#domain.com" />
<ValidationMessage For="#(() => _model.BillingEmail)" />
</div>
<!--end::Input-->
</div>
</div>
<div class="row">
<div class="col-xl-12">
<!--begin::Input-->
<div class="form-group">
<label>Card Information</label>
<StripeCard PublishableKey="#_stripePublishableKey" CardProcessedCallBack="ProcessSubscriptionAsync"></StripeCard>
<span class="form-text text-muted">Powered by <strong>Stripe</strong>.</span>
</div>
<!--end::Input-->
</div>
</div>
<ValidationSummary />
<div class="d-flex justify-content-between border-top mt-5 pt-10">
<div>
<button type="button" class="btn btn-success font-weight-bolder text-uppercase px-9 py-4"
#onclick="HandleValidSubmit">
Submit
</button>
</div>
</div>
</EditForm>
<!--end: Wizard Form-->
</div>
</div>
</div>
</div>
#code{
private Model _model;
private string _stripePublishableKey;
protected override void OnInitialized()
{
_model = new Model();
_stripePublishableKey = "Here we put Development or Production publishableKey"; //Add publishable key here
base.OnInitialized();
}
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await JS.InvokeVoidAsync("KTSubscriptionCheckout.init");
}
await base.OnAfterRenderAsync(firstRender);
}
private async Task HandleValidSubmit()
{
await JS.InvokeVoidAsync("StripeInterop.createPaymentMethod", _model.BillingEmail, _model.BillingName);
}
//Callback method will return stripe paymentId
private async Task ProcessSubscriptionAsync(string paymentId)
{
//We process paymentId here and continue with our backend process
await Task.CompletedTask;
}
public class Model
{
[Required]
public string BillingName { get; set; }
[Required]
public string BillingEmail { get; set; }
}
}
Youtube video if you want to have a look. https://youtu.be/ANYvFHHfyy8
Good luck...

Lit-element children component not re rendering JS code based on updated props

Lit-Element updated .props not invoking full re-render of child component, i.e. the javascript code inside firstUpdated() of child constructs a leaflet map based on .props being passed in from parent component, when the parent component updates location and city, it doesn't create a re-render of the map with new location and city.
When user clicks on button to update location from Seattle to Toronto, the parents props are updated and passed to child, however, the map doesn't rebuild itself, how do I force the map to be "rebuilt" (re-rendered) based on the new .props being passed into the child ??
Git repo for my working sample code
THANKS! :) Been struggling with this for days on end - FYI new to Lit-Element.
Index.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link type="text/css" href="./styles.css"
<script src="./webcomponents/webcomponents-loader.js"></script>
<script>
if (!window.customElements) { document.write('<!--'); }
</script>
<script src="./webcomponents/custom-elements-es5-adapter.js"></script>
<!-- ! DO NOT REMOVE THIS COMMENT, WE NEED ITS CLOSING MARKERS -->
</head>
<body>
<app-view></app-view>
</body>
</html>
Index.js:
import './views/app-view.js'
Parent component app-view.js
import { html, LitElement } from 'lit-element';
import './esri-map.js'
class AppView extends LitElement{
static get properties() {
return {
location: { type: Object },
city: { type: String }
}
}
constructor() {
super();
// set fallback location to seattle -- GET will pull in coordinates for Toronto
this.location = { lat: "47.608013", long: "-122.335167" }
this.city = "Seattle"
}
render() {
return html`
<style>
#app-container{
width: 100%,;
height: 100%;
display: flex;
}
#map-container{
flex-grow: 1;
height: 800px;
}
</style>
<button #click=${ (event) => this.updateLocation() }
>Set to Toronto
</button>
<div id="app-container">
<div id="map-container">
<esri-map
.location=${this.location}
.city=${this.city}
>
</esri-map>
</div>
</div>
`;
}
updateLocation(){
var oldLocation = this.location;
this.location = { lat: "43.651070", long: "-79.347015"} // Set to Toronto
this.city = "Toronto"; // Set to Toronto
console.log("New location is: " + this.city)
console.log("Coordinates: ");
console.log(this.location);
}
}
customElements.define('app-view', AppView);
Child Component
import { html, LitElement } from 'lit-element';
import * as L from 'leaflet';
import * as esri from 'esri-leaflet';
class EsriMap extends LitElement{
static get properties() {
return {
location: { type: Object }, // prop passed from parent
city: { type: String } // prop passed from parent
}
}
render() {
return html`
<link rel="stylesheet" href="https://unpkg.com/leaflet#1.6.0/dist/leaflet.css"/>
<style>
#map{
height: 100%;
width: 100%;
}
</style>
<h2>Current City: ${this.city} </h2>
<h3>Coordinates: Lat: ${this.location.lat}</h3>
<div id="map"></div>
`
}
firstUpdated() {
const mapNode = this.shadowRoot.querySelector('#map');
// Render map with props from parent component
var map = L.map(mapNode, {
maxZoom: 18,
minZoom: 2,
}).setView([this.location.lat, this.location.long],8); // [Lat,Lng]
const esriLayer = esri.basemapLayer('Streets');
map.addLayer(esriLayer);
// Render circle with props from parent component
var circle = L.circle([this.location.lat, this.location.long], {
color: 'red',
fillColor: '#f03',
fillOpacity: 0.5,
radius: 20000,
}).addTo(map);
}
}
customElements.define('esri-map', EsriMap);
When properties change, the render() function gets invoked.
firstUpdated() gets only invoked after the first update and not on every property change.
Try this:
updated(changedProps) {
if (changedProps.has('location')) {
this._setMap();
}
}
_setMap() {
const mapNode = this.shadowRoot.querySelector('#map');
if (mapNode == null || this.location == null) {
return;
}
// Render map with props from parent component
var map = L.map(mapNode, {
maxZoom: 18,
minZoom: 2,
}).setView([this.location.lat, this.location.long],8); // [Lat,Lng]
const esriLayer = esri.basemapLayer('Streets');
map.addLayer(esriLayer);
// Render circle with props from parent component
var circle = L.circle([this.location.lat, this.location.long], {
color: 'red',
fillColor: '#f03',
fillOpacity: 0.5,
radius: 20000,
}).addTo(map);
}

How to add key press listener for IText objects in FabricJS?

I currently have this code
fabric.IText.prototype.keysMap[13] = 'onEnterKeyPress';
fabric.IText.prototype.onEnterKeyPress = (e) => {
console.log('onEnterKeyPress', e);
// this.insertChars(e);
// fabric.IText.insertChars(e);
// return true;
// return e;
};
let canvas = new fabric.Canvas('canvas', {
preserveObjectStacking: true,
width: 980,
height: 600
});
let itext = new fabric.IText(
'Edit this text',
{
editable: true,
left: 100,
top: 100,
fontSize: 24
}
);
canvas.add(itext);
canvas.requestRenderAll();
<html>
<body>
<canvas id="canvas"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.3.4/fabric.min.js"></script>
</body>
</html>
The issue is, once I attached the key press listener, if I hit enter key, it does fire my function callback but it won't add the carriage return character in the text.
If I remove my key press listener, it does go back to normal, that is adding the carriage return character on enter key press.
It seems I have to manually add the carriage return when I attached a key press listener? Not sure how to do it tho.
Thanks in advance.
BTW I'm using latest of FabricJS 2.3.4
You can override onKeyDown, then call original method.
DEMO*
fabric.IText.prototype.onKeyDown = (function(onKeyDown) {
return function(e) {
if (e.keyCode == 13)
console.log('enter key');
onKeyDown.call(this, e);
}
})(fabric.IText.prototype.onKeyDown)
let canvas = new fabric.Canvas('canvas', {
preserveObjectStacking: true,
width: 980,
height: 600
});
let itext = new fabric.IText(
'Edit this text', {
editable: true,
left: 100,
top: 100,
fontSize: 24
}
);
canvas.add(itext);
canvas.requestRenderAll();
<html>
<body>
<canvas id="canvas"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/fabric.js/2.3.4/fabric.js"></script>
</body>
</html>

Few newbie react-native questions

I'm new to react and react-native (and pretty much everything in general...), I'm trying to follow facebook's tutorial on state and props. I'm playing around with the code and I ran into some issues.
I've modified my Apps.js to look like this:
import React, { Component } from 'react';
import { Text, View, Image, StyleSheet } from 'react-native';
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f1f',
alignItems: 'center',
justifyContent: 'center',
},
});
class Blink extends Component {
constructor(props) {
super(props);
this.state = {showText: true};
// Toggle the state every second
setInterval(() => {
this.setState(previousState => {
return { showText: !previousState.showText };
});
}, 1000);
}
render() {
let display = this.state.showText ? this.props.text1 : this.props.text2;
let pic = this.state.showText ? {uri: this.props.url1} : {uri: this.props.url2}
return (
<View>
<Image source={pic} style={{width: 193, height: 110}}/>
<Text>{display}</Text>
</View>
);
}
}
export default class BlinkApp extends Component {
render() {
return (
<View style={styles.container}>
<Blink text1='test1' />
<Blink text2='test2' />
<Blink url1='https://www.gizbot.com/img/2015/08/10-1439192289-lolemoji.jpg' />
<Blink url2='http://s3.india.com/wp-content/uploads/2015/08/haha-nelson-simpsons.jpg' />
</View>
);
}
}
Instead of blinking three lines of text like the one in the tutorial, it's suppose to blink two different images with two different lines of text (text1 and text2) using my own StyleSheet. The issue I'm running into is that they are not properly aligned. I can't get them to center no matter what I try.
The two different images it displays/blinks are here and here
What I want them to look like are here and here
So my questions are:
1) Does it matter where I define style? e.g. in my code, I've included them inside the second render, but I've noticed that if I put them inside the first render, different results occur. What is the difference?
2) Am I using props incorrectly here? What should I be doing instead to define the two images and texts as part of my props?
3) Are setInterval and previousState native react libraries? How are they being called? i.e. what's triggering setInterval to change the value of showText?
4) when is setState being called?
I rewrite your code, and I think it works as your expect now.
to your questions:
1&2: the way you use style and props is wrong, see my code below.
3: setInterval is native react libraries, you can find the usage in https://facebook.github.io/react-native/docs/timers.html
4: setState is called by your code, please look at the document https://facebook.github.io/react-native/docs/state.html
import React, { Component } from 'react';
import { Text, View, Image, StyleSheet } from 'react-native';
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f1f',
alignItems: 'center',
justifyContent: 'center',
},
});
class Blink extends Component {
render() {
const { text, url } = this.props;
console.log('url' + url);
return (
<View>
<Image source={{uri:url, cache: 'force-cache'}} style={{width: 193, height: 110}}/>
<Text>{text}</Text>
</View>
);
}
}
export default class BlinkApp extends Component {
constructor(props) {
super(props);
this.state = {
showFirst: true,
};
}
componentDidMount() {
setInterval(() => {
this.setState({
showFirst: !this.state.showFirst
});
}, 1000);
}
render() {
const showFirst = this.state.showFirst;
return (
<View style={styles.container}>
{showFirst && <Blink url="https://www.gizbot.com/img/2015/08/10-1439192289-lolemoji.jpg" text='test1' />}
{!showFirst && <Blink url="http://s3.india.com/wp-content/uploads/2015/08/haha-nelson-simpsons.jpg" text='test2' />}
</View>
);
}
}

DropDown popup width (Telerik: Kendo UI for Angular)

How can I set DropDown popup width to auto, so all text is visible? I would like to keep small width for widget, but larger width for popup.
Updated:
Link to Plunkr.
import { Component } from '#angular/core';
#Component({
selector: 'my-app',
styles: ['kendo-dropdownlist { width: 6em;}'],
template: `
<kendo-dropdownlist
[data]="listItems"
[textField]="'text'"
[valueField]="'value'"
[value]="selectedValue"
>
<ng-template kendoDropDownListValueTemplate let-dataItem>
<span>{{ dataItem?.value }}</span> {{ dataItem?.text }}
</ng-template>
<ng-template kendoDropDownListItemTemplate let-dataItem>
<span>{{ dataItem.value }}</span> {{ dataItem.text }} - Dummy text
</ng-template>
</kendo-dropdownlist>
`
})
export class AppComponent {
public listItems: Array<{ text: string, value: number }> = [
{ text: "Small", value: 1 },
{ text: "Medium", value: 2 },
{ text: "Large", value: 3 }
];
public selectedValue: { text: string, value: number } = { text: "Foo", value: 1 };
}
I would suggest you to set the popup width to auto. Thus the items will not wrap:
<kendo-dropdownlist
[data]="listItems"
[textField]="'text'"
[valueField]="'value'"
[value]="selectedValue"
[popupSettings]="{ width: 'auto' }"
>
http://plnkr.co/edit/dqlInPutekCnwdt7KFek?p=preview

Resources