making a dropdown selector date for airbnb SingleDatePicker - datepicker

I've got my setup like this, I'm absolutely squeezing the limits of what is possible from outside a library:
const [customDate, setCustomDate] = useState(moment());
const [focused, setFocused] = useState(false);)
const onDropDownChangeMonth = ()=>{
setCustomDate(moment('07-12-2020', dateFormat.MM_DD_YYYY));
setFocused(true);
}
<SingleDatePicker
date={customDate}
onDateChange={onDateChange}
focused={focused}
placeholder={props.placeholder}
onFocusChange={(e) => {
setFocused(e.focused);
}}
navPrev={<div></div>}
navNext={<div></div>}
keepFocusOnInput={true}
renderMonthText={() => (
<div style={{ display: 'flex', flexDirection: 'row' }}>
<select style={{ border: 'none', background: '#ffffff' }} onChange={onDropDownChangeMonth}>
<option>January</option>
<option>February</option>
<option>March</option>
<option>April</option>
<option>May</option>
<option>June</option>
<option>July</option>
<option>August</option>
<option>September</option>
<option>October</option>
<option>November</option>
<option>December</option>
</select>
</div>
)}
/>
so, my current implementation gives me correct result like this:
Since, this would re-render, I wanted to keep it open(I can bear the flicker), the date changes, the calendar changes,the calendar stays open, but, the children they render blank:
Only when I manually defocus, and reopen then the calendar gets rendered, and I see the changes reflected. How do I get the calendar rendered? How to make it so that I don't have to manually defocus it, I don't mind the flicker.
BTW: I'm using the SingleDatePicker by airbnb

Well, this is a possible solution for anyone who doesn't mind a blink instead of a flicker(please read the question above). It's a hacky solution, and it doesn't do much good in my case, just noting here for someone who might be okay with this, or someone who knows how to reduce this blink to a flicker or nothing:
put this in the `onDropDownChangeMonth`:
const onDropDownChangeMonth = ()=>{
setCustomDate(moment('07-12-2020', dateFormat.MM_DD_YYYY));
setFocused(false);
setTimeout(()=>setFocused(true), 1);
}
Even though I put a 1ms timeout, the delay for the re-render is about 1 second, and this is not good in my case.. Please mention anything to reduce or get rid of that delay-for-re-render.

Related

Can I use an `sx` prop in a `styled` component

So my question really isn't should I, but rather can I.
If I opt to use styled components for my more common components then I style them once and export.
const MyBlueButton = styled('button')({
backgroundColor: 'blue'
})
Great export that and I have a blue button.
I can also use sx
const MyBlueButton = (props) => {
return <button sx={{backgroundColor: 'blue'}}>{props.children}</button>
}
My question is can I have both, one where I've already made my common component but then want to customize it just a bit unique for one use.
'components/buttons.jsx':
export const MyBlueButton = styled('button')({
backgroundColor: 'blue'
})
--------
'FooBar.jsx':
import {MyBlueButton} from 'components/buttons'
const FooBar = (props) => {
return (
<div>
<p>Some text</p>
<MyBlueButton sx={{fontSize: '20px'}}>Large Blue Button</MyBlueButton>
</div>
)
}
I didn't find anything stating that you couldn't do it. I'm sure you quite possibly can, but can you, and what would be the expected order of css properties?
If I have a styled component with a matching css property in the sx prop would sx win since it's closer to the render? Should I have to worry about injection order with the StyledEngineProvider?
I'm really just hoping I can use a healthy mix of both styled components and one off sx modifications.
I went ahead and made a codesand box to test my idea and it does work to combine both styled wrappers and sx props.
Again probably not for everyday use, but it's nice to know it is possible.
CodeSandbox: https://codesandbox.io/s/keen-roman-s6i7l?file=/src/App.tsx
I have been into such issue;
the way I had to implement the sx props to be passed before passing the component to styled engine was neglecting the props:
const AutoComplete = withThemeProvider(styled(Autocomplete)(autoCompleteStyles));
and when to use it, it gets neglected
<Autocomplete sx={neglectedProps}>

Can't style slider (or maybe anything) in Material UI

There was an issue requesting documentation for theming which the author subsequently closed. The author found their answer. A non-programmer will probably not. At least, the non-programmer designer I'm helping doesn't even know where to start (and I still don't have a working different colored slider). This kind of documentation would be great. Even if it's just a link to the code #jdelafon found with some explanation that would suffice to answer the following specific example.
Ultimately, we want a set of sliders with each one a different color. It seems like the appropriate way to do this is with per-element inline styles.
I made a simple example here. Can you change the color of the slider? (We started down the path of breaking out to CSS, but the widget is so dynamic that this approach ends up being quite ugly.)
Slider has two different slots for theming, neither of which seems to respond to an embedded object with a selectionColor key.
Should be simple. Probably it is, but it appears to be undocumented. Otherwise it's a rad UI toolkit, thanks devs!
Take a look at this line of getMuiTheme.js. You can find there that slider can have those styles overridden:
{
trackSize: 2,
trackColor: palette.primary3Color,
trackColorSelected: palette.accent3Color,
handleSize: 12,
handleSizeDisabled: 8,
handleSizeActive: 18,
handleColorZero: palette.primary3Color,
handleFillColor: palette.alternateTextColor,
selectionColor: palette.primary1Color,
rippleColor: palette.primary1Color,
}
In material-ui you need to use MuiThemeProvider in order to use your custom theme. Taking your example:
...
import MuiThemeProvider from 'material-ui/styles/MuiThemeProvider';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import { Slider } from 'material-ui';
const theme1 = getMuiTheme({
slider: {
selectionColor: "red",
trackSize: 20
}
})
const theme2 = getMuiTheme({
slider: {
selectionColor: "green",
trackSize: 30
}
})
const HelloWorld = () => (
<div>
...
<MuiThemeProvider muiTheme={theme1}>
<Slider defaultValue={0.5}/>
</MuiThemeProvider>
<MuiThemeProvider muiTheme={theme2}>
<Slider defaultValue={0.5}/>
</MuiThemeProvider>
</div>
);
export default HelloWorld;
Your modified webpackbin: http://www.webpackbin.com/EyEPnZ_8M
The sliderStyle you tried to use is for different styles :-) Like marginTop / marginBottom, a full list can be found here.

How to get work Infinite scroll depending on div container's scroll position?

I'm looking for a infinite scroll script, but can't find one which really fits my needs. I have found one which would be great, but the problem is that the script works after the User scrolls down using the browser SCROLLBAR. Instead it should load and display more data depending on the div "scroll" position.
How can i do that? It doesn't have to be this script but it should include a mysql query function so I can implement mine easily, because I'm really a newbie in Javascript, jQuery etc. A tutorial would do it also...but can't really find one. All of them are depending on the browser's scroll position.
That's the script I'm using:
github.com/moemoe89/infinite-scroll/blob/master/index.php
I made only one modification:
news_area{ width:400px; height:95px; overflow:auto;}
Thanks in advance!
Instead of $(window).scrollTop() use any container that you would want to get it's scrolling position from, like $('.scrollable').scrollTop().
$('.scrollable').on('scroll', function(){
var $el = $(this);
$('.scrolled').text($(this).scrollTop());
if( $el.innerHeight()+$el.scrollTop() >= this.scrollHeight-5 ){
var d = new Date();
$el.append('more text added on '+d.getHours()+':'+d.getMinutes()+':'+d.getSeconds()+'<br>');
}
});
div {
height: 50px;
border: 1px solid gray;
overflow: auto;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<p>Scrolled from top: <span class="scrolled">0</span></p>
<div class="scrollable">
text<br>
text<br>
text<br>
text<br>
text<br>
text<br>
</div>

Reactjs together with TinyMCE editor code plugin

I'm using Reactjs together with the tinyMCE 4.1.10 html editor (together with the code plugin) and bootsrap css + js elements. A fairly working setup after a few quirks with the editor have been removed (manual destruction if the parent element unmounts)
Now the question: The textarea input of the code plugin does not receive any focus, click or key events and is basically dissabled. Setting the value via javascript works just fine, but it does not function as a normal html input.
It is opened as the following:
datatable as react components
opens bootsrap modal as react component
initializes tinymce on textareas inside of the modal
loads the code plugin (which itself then is not accepting any kind of input anymore)
My initilization of the editor looks like this:
componentDidMount: function(){
tinymce.init({
selector: '.widget-tinymce'
, height : 200
, resize : true
, plugins : 'code'
})
}
My guess would be, that react.js is somehow blocking or intersepting the events here. If I remove the react modal DOM, it is just working fine.
Does anybody has an idea, what is causing this or how to simply debug it further?
Thx a lot!
if you are using Material UI. disable Material UI Dialog's enforce focus by adding a prop disableEnforceFocus={true} and optionally disableAutoFocus={ true}
What does your html/jsx look like in your component?
My guess is that react might be treating your input as a Controlled Component
If you're setting the value attribute when you render, you'll want to wait, and do that via props or state instead.
Alright, so it turned out that bootstrap modals javascript is somehow highjacking this. In favor of saving some time I decided not to dig realy into this but just to create my own modal js inside of the jsx.
Aparently there is also React Bootstrap, but it looks at the moment to much beta for me in order to take this additional dependency in.
The final code looks like this, in case it becomes handy at some point:
Modal = React.createClass({
show: function() {
appBody.addClass('modal-open');
$(this.getDOMNode()).css('opacity', 0).show().scrollTop(0).animate({opacity: 1}, 500);
}
, hide: function(e){
if (e) e.stopPropagation();
if (!e || $(e.target).data('close') == true) {
appBody.removeClass('modal-open');
$(this.getDOMNode()).animate({opacity: 0}, 300, function(){
$(this).hide();
});
}
}
, showLoading: function(){
this.refs.loader.show();
}
, hideLoading: function(){
this.refs.loader.hide();
}
, render: function() {
return (
<div className="modal overlay" tabIndex="-1" role="dialog" data-close="true" onClick={this.hide}>
<div className="modal-dialog">
<div className="modal-content">
<div className="modal-header">
<button type="button" className="close" onClick={this.hide} data-close="true" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 className="modal-title" id="myModalLabel">{this.props.title}</h4>
</div>
<div className="modal-body" id="overlay-body">
{this.props.children}
<AjaxLoader ref="loader"/>
</div>
</div>
</div>
</div>
);
}
})
Best wishes
Andreas
Material UI: disable Dialog's enforce focus by adding a prop disableEnforceFocus={true} and optionally disableAutoFocus={ true}

JQuery UI Slider Without Numbers

I am trying to build a rating form and want to use the JQuery UI increment slider except I don't want the value to be numbers, I'd like it to say something like "great" or "bad"
I'm great with HTML & CSS not so much with JavaScript or JQuery. I am taking a class in NYC next month to help me become more fluent in these languages. In the mean time any and all help is appreciated. I tried to hack other scripts I have found but keep running into problems. I ran into this script which is close to what I want, except the increments show #s.
I feel as if this code can be easily modified to do what I want.
http://jsfiddle.net/dmcgrew/EquTn/3/
<html>
<div class="kpa_rate kpa_rate1">
<label for="kpa1_rating_value">Parking:</label>
<div id="1" class="slider"></div>
<input type="text" class="kpa1_rating_value" name="kpa1_rating" value="0" />
</div>
<div class="kpa_rate kpa_rate2">
<label for="kpa2_rating_value">Entrance:</label>
<div id="2" class="slider"></div>
<input type="text" class="kpa2_rating_value" name="kpa2_rating" value="0" />
</div>
</html>
JavaScript
<script>
$(function() {
$( ".slider" ).slider({
range: "max",
min: 0,
max: 5,
value: $("input", this).val(),
slide: function( event, ui ) {
//get the id of this slider
var id = $(this).attr("id");
//select the input box that has the same id as the slider within it and set it's value to the current slider value.
$("span[class*=" + id + "]").text(ui.value);
$("input[class*=" + id + "]").val(ui.value);
}
});
});
</script>
Did you want different words ("great, good, neutral, etc") for each value, or just good/bad at the ends?
If you want diff words for each of the 5 values, then like j08691 said, make an array that has the words you want at the indexes you want.
After this, replace the ui.value in .val(ui.value) with the array of value (Arr[ui.value]).
(I'm not sure you actually need the "span" part, but I don't do jquery, so I'm not sure).
$(function() {
var Array = ["die","very bad", "bad", "neutral","good","great"];
$( ".slider" )...etc
...
$("input[class*=" + id + "]").val(Array[ui.value]);
This worked for me.
I did a bit of tinkering, and I think I've found a way to superficially solve your problem. Since the number inputted as the first value doesn't affect the slider button/thing, I'd say just put the first word that the slider should indicate (in my case, "die").
//value does not equal a number here
In the next bit of code, just change input to Array[input], and you should be all set!
min: 0,
max: 5,
value: $("Array[input]"
I hope this works well enough for you.