HTML: Ограничение ввода числа, с дробной частью более двух знаков

Задача: позволять вносить в поле input числа со значимой частью не более 2-х знаков после запятой.

Решение: к сожалению стандарт HTML на текущий момент не предусматривает в штатном виде такое колдовство. Единственно что возможно — проставить в теге тип равным «число», и шаг равным .01, например вот так:

<input type="number" step=".01">

Но это будет действовать только если пользователь ввод числа осуществляет при помощи стрелочки. Если руками — то поле всё равно позволит ввести любое число. Значит придётся задействовать javascript. На обработчик onchange навесим задание приводить любое значение в поле к числу с разрядностью 2:

<input type="number" step=".01" onchange="this.value = parseFloat(this.value).toFixed(2);">
два знака после запятой в поле input

Текущая дата в input

Задача: Необходимо чтобы при отображении на HTML странице поля input с типом дата, автоматически подставлялась определенная дата (заполнение текущей датой поля input). Ну например текущая+14 дней.

Решение: собственно без javascript тут не обойтись (ну если исключить вариант, что html генерируется на сервере, и соответственно заполняется поле value. Но это не наш метод (с)

HTML:

    <div class="formbuilder-date form-group field-date_start">
        <label for="date_start" class="formbuilder-date-label">Дата начала отпуска
            <br>
        </label>
        <input type="date" class="form-control" name="date_start" access="false" id="date_start">
    </div>

JavaScript:

<script>
    var date = new Date(Date.now());
    date.setDate(date.getDate() + 14);    
    date_start.value=date.toISOString().split("T")[0];
</script>    

Что тут интересного? Ну фактически мы пользуемся тем, что value у тега input с типом даты обязательно должно быть в формате гггг-мм-дд, т.е. ISO формат, а в ISO формат мы можем пере конвертировать дату полученную при помощи функции Date. Время нам не нужно, поэтому отсекаем его, разделив дату по разделителю «Т», и взяв первый элемент массива.

заполнение текущей датой поля input

Android: Не работает диалог выбора файла в webview

Задача: в контексте webview приложения для android, не открывается диалоговое окно выбора файла, в виду отсутствия в «базовом» варианте работы webview необходимых обработчиков. Решение описываемое в статье 2020года не работает в 2022 году

Решение: в конце 2022 года, рабочая минимальная обвязка для обработки выбора файлов такова:

public class MainActivity extends AppCompatActivity {
    private ValueCallback<Uri[]> fileChooserCallback;
    private WebView mbrowser;
    Uri home = Uri.parse("https://цукмсцумкцу.ru/choser.php");
    //загрузки изображений
    private ValueCallback<Uri> mUploadMessage;
    public ValueCallback<Uri[]> uploadMessage;
    public static final int REQUEST_SELECT_FILE = 100;
    public static final int REQUEST_QR_CODE = 200;
    private final static int FILECHOOSER_RESULTCODE = 1;
    public final static int CHILD_FINISH = 1;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mbrowser=(WebView) findViewById(R.id.main_webview);

        mbrowser.getSettings().setJavaScriptEnabled(true); // разрешен javascript

        mbrowser.getSettings().setDatabaseEnabled(true); // хранение данных во встроенной БД в браузере
        mbrowser.getSettings().setDomStorageEnabled(true);
        mbrowser.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);   // разрешать открывать окна

        mbrowser.setWebViewClient(new WebViewClient() {
            @Override
            public boolean shouldOverrideUrlLoading(WebView vw, WebResourceRequest request) {
                if (request.getUrl().toString().contains(home.getHost())) {
                    vw.loadUrl(request.getUrl().toString());
                } else {
                    Intent intent = new Intent(Intent.ACTION_VIEW, request.getUrl());
                    vw.getContext().startActivity(intent);
                }

                return true;
            }
        });

        mbrowser.setWebChromeClient(new WebChromeClient() {
            @Override
            public void onPermissionRequest(final PermissionRequest request) {
                request.grant(request.getResources());
            }

            @Override
            public boolean onShowFileChooser(WebView vw, ValueCallback<Uri[]> filePathCallback,
                                             FileChooserParams fileChooserParams) {
                if (fileChooserCallback != null) {
                    fileChooserCallback.onReceiveValue(null);
                }
                fileChooserCallback = filePathCallback;

                Intent selectionIntent = new Intent(Intent.ACTION_GET_CONTENT);
                selectionIntent.addCategory(Intent.CATEGORY_OPENABLE);
                selectionIntent.setType("*/*");

                Intent chooserIntent = new Intent(Intent.ACTION_CHOOSER);
                chooserIntent.putExtra(Intent.EXTRA_INTENT, selectionIntent);
                startActivityForResult(chooserIntent, 0);

                return true;
            }
        });

        mbrowser.setOnKeyListener((v, keyCode, event) ->
        {
            WebView vw = (WebView) v;
            if (event.getAction() == KeyEvent.ACTION_DOWN && keyCode == KeyEvent.KEYCODE_BACK && vw.canGoBack()) {
                vw.goBack();

                return true;
            }

            return false;
        });
        mbrowser.setDownloadListener((uri, userAgent, contentDisposition, mimetype, contentLength) -> handleURI(uri));
        mbrowser.setOnLongClickListener(v -> {
            handleURI(((WebView) v).getHitTestResult().getExtra());

            return true;
        });

        mbrowser.loadUrl(home.toString());
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
        super.onActivityResult(requestCode, resultCode, intent);

        fileChooserCallback.onReceiveValue(new Uri[]{Uri.parse(intent.getDataString())});
        fileChooserCallback = null;
    }

    private void handleURI(String uri) {
        if (uri != null) {
            Intent i = new Intent(Intent.ACTION_VIEW);
            i.setData(Uri.parse(uri.replaceFirst("^blob:", "")));

            startActivity(i);
        }
    }
}

JqGrid-Free: в модальных окнах Bootstrap 4 не активны поля Input

Неожиданно обнаружилось, что в модальных окнах использование jqgrid черевато тем, что в вызываемых диалогах add / edit не работают поля select и input.

Купирование проблемы (не решение): в модальном окне заменить tabindex=»-1″ на style=»overflow:hidden;»

<div class="modal hide fade" id="DialogWindowModal" style="overflow:hidden;" role="dialog" aria-labelledby="DialogWindowModalLabel" aria-hidden="true">
  <div class="modal-dialog modal-lg">
    <div class="modal-content">
      <div class="modal-header">
        <h5 class="modal-title" id="DialogWindowModalName">Диалоговое окно</h5>
        <button type="button" class="close" data-dismiss="modal" aria-label="Close">
          <span aria-hidden="true">&times;</span>
        </button>
      </div>
      <div class="modal-body" id="DialogWindowModalDiv">
                                                         
      </div>   
    </div>
  </div>
</div>

Список выбора с checkbox на карте yandex

Чтобы получилось примерно такое:

 

Нужно выполнить довольно много телодвижений:




1 2