Mobile browser time inputs don't work inside vue element - ios

I have a laravel webapp that uses multiple forms. I have recently introduced Vue.js v2 to deal with some specific custom input types which are working well.
Problem is that ordinary html5 input[type=time] inputs that are inside the vue instance element are not rendered properly in iOS safari/chrome - they appear as native timepickers but appear to have a blank value. When you click to change they do display the correct value.
I can workaround by using a custom vue component that just passes the value property into the vue instance but I figure I must be doing something wrong because I can't find a single mention of this anywhere.
I have managed to reproduce this on JSFiddle problem only appears in mobile browsers
html
<div id="app" style="background-color:lightblue; padding:30px">
<h3>This div is the Vue element</h3>
<form action="">
<p>
<label for="">Standard Input</label>
<input type="time" value="23:24:00" />
</p>
<p>
<label for="">Vue Component</label>
<vue-time value="13:45:00"></vue-time>
</p>
</form>
</div>
<div style="background-color:lightyellow; padding:30px">
<h3>This div is outside the Vue instance</h3>
<form action="">
<label for="">Standard Input</label>
<input type="time" value="23:24:00" />
</form>
</div>
js
Vue.component('vue-time', {
template: '<input type="time" :value="value">',
data() {
return {
value: ''
}
}
});
const vue = new Vue({
el: '#app',
data() {
return {
value: ''
}
}
});

I had a somewhat similar problem and I found this thread that helped me, see if it helps you:
https://forum.vuejs.org/t/solved-fixed-position-element-disappears-during-transition-on-mobile-browsers/8960
I would comment on your question instead of proposing this as an answer but I don't have the reputation to do so yet.

Related

Booststrap v5 textform class="form-label" prepopulate data in a way that can be copied to clipboard

Using bootstrap 5, specifically going over this: https://getbootstrap.com/docs/5.3/forms/form-control/
I am trying to create a simple example text area with some text in it pre-populated, so that I can add a button that will copy the propulated text into clipboard.
Method 1-
Sample code from Bootstrap looks like this:
<div class="mb-3">
<label for="exampleFormControlTextarea1" class="form-label">Example textarea</label>
<textarea class="form-control" id="exampleFormControlTextarea1" rows="3"></textarea>
</div>
If I use something like 'placeholder' the text box gets prepopulated but I can't "grab" that text neither manually or via a js script. The placeholder my understaning is just a hint of what is to be filled out in the box.
Method 2-
If I used for example a regular HTML textarea element I can do this, no problem, with something like this:
<textarea id="textbox" rows="3" cols="80">{{prepopulated_date_variable}}</textarea><br />
<button type="button" class="btn btn-primary"onclick="copyTextBoxData()">Copy Copy Data</button>
So if I use a regular "textbox" like in Method 2, it does not leverage the cool look and resizing capabilities of bootstrap, hence why I am trying to get Method 1- or similar to work.
Any queues? tips? maybe another element?
I am new to this all, but the concept is that I am passing from a another piece of code the prepopulated data for user to see (leveraging Jinja template with Python if that makes any difference) and then idea is that button allows my user to copy to mem clipboard what is in the text box, so that they can past in something else.
Appreciate any support or ideas.
I am using Method 2- described in problem statement. What I am expecting is that I can use Method 1 or alternative with bootstrap component to leverabe the styling and features of bootstrap.
You can use JavaScript to set the value of the form inputs when the page loads.
This code creates a form with two inputs (email and password) and a button that, when clicked, copies the values of the inputs to the clipboard. The copyToClipboard function uses the document.getElementById method to get the values of the inputs, concatenates them into a string, creates a temporary input element, sets its value to the string, selects it, and then executes the document.execCommand("copy") command to copy the value to the clipboard. Finally, it removes the temporary input element and alerts the user that the data has been copied.
function copyToClipboard() {
var email = document.getElementById("exampleInputEmail1").value;
var password = document.getElementById("exampleInputPassword1").value;
var data = "Email: " + email + "\nPassword: " + password;
var tempInput = document.createElement("input");
tempInput.style = "position: absolute; left: -1000px; top: -1000px";
tempInput.value = data;
document.body.appendChild(tempInput);
tempInput.select();
document.execCommand("copy");
document.body.removeChild(tempInput);
alert("Copied to clipboard: " + data);
}
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap#5.2.3/dist/css/bootstrap.min.css" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
<form>
<div class="form-group">
<label class="form-label" for="exampleInputEmail1">Email address</label>
<input type="email" class="form-control" id="exampleInputEmail1" aria-describedby="emailHelp" value="example#email.com">
</div>
<div class="form-group">
<label class="form-label" for="exampleInputPassword1">Password</label>
<input type="password" class="form-control" id="exampleInputPassword1" value="password123">
</div>
<button type="button" class="btn btn-primary" onclick="copyToClipboard()">Copy to Clipboard</button>
</form>

Vue + Asp.net rendering issue

I have a new asp.net mvc project (not .net core) and I am trying to incorporate Vue js into the project. I have everything working in a sample project using Webpack+Vue+Asp.Net Mvc, which was created following this article https://medium.com/corebuild-software/vue-js-and-net-mvc-b5cede228626.
The app works great, except for the split second before Vue renders. There is noticable flashing/popping of the Vue templated code before its rendered to html. Below is a gif of me refreshing the page and users are able to see the template before Vue renders it into html.
I know why this is happening, but I do not know any ways around it. Would Server Side Rendering fix this? Can SSR be done in a non .net core project?
Unfortunately, switching to asp.net core is not an option. The project will be using Umbraco 7, which cannot run on asp.net core (https://our.umbraco.com/forum/using-umbraco-and-getting-started/93640-net-core).
Below are my files
Index.cshtml
#{
ViewBag.Title = "Home Page";
}
<div class="jumbotron">
<h1>ASP.NET</h1>
<p class="lead">ASP.NET is a free web framework for building great Web sites and Web applications using HTML, CSS and JavaScript.</p>
<p>Learn more »</p>
</div>
<div id="app" controller-data="{ name: 'James' }">
<h3>Test</h3>
{{ vueMessage }}
{{ controllerData }}
<first-component v-bind:time="new Date()" data="#Model"></first-component>
<button v-on:click="test">Test</button>
</div>
<div class="row">
<div class="col-md-4">
<h2>Getting started</h2>
<p>
ASP.NET MVC gives you a powerful, patterns-based way to build dynamic websites that
enables a clean separation of concerns and gives you full control over markup
for enjoyable, agile development.
</p>
<p><a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkId=301865">Learn more »</a></p>
</div>
<div class="col-md-4">
<h2>Get more libraries</h2>
<p>NuGet is a free Visual Studio extension that makes it easy to add, remove, and update libraries and tools in Visual Studio projects.</p>
<p><a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkId=301866">Learn more »</a></p>
</div>
<div class="col-md-4">
<h2>Web Hosting</h2>
<p>You can easily find a web hosting company that offers the right mix of features and price for your applications.</p>
<p><a class="btn btn-default" href="https://go.microsoft.com/fwlink/?LinkId=301867">Learn more »</a></p>
</div>
</div>
#Scripts.Render("~/Scripts/bundle/home.js")
index.js (gets compiled to Scripts/bundle/home.js by webpack)
import Vue from 'vue';
import FirstComponent from './sub-components/first-component.vue'
new Vue({
el: '#app',
components: {
FirstComponent
},
props: {
controllerData: Object
},
methods: {
test: function () {
console.log(this);
}
},
data: function () {
return {
vueMessage: 'Message from Vue'
};
}
})
first-component.vue
<template>
<div class="time">
{{ time }}
{{ data }}
</div>
</template>
<script>
export default {
props: {
time: {
type: Object,
required: true,
},
data: Object
}
}
</script>
<style>
.time {
color: #F44336;
}
</style>
Make use of the v-cloak attribute.
<div id="app" v-cloak>
...
</div>
The attribute is automatically removed by vue when the framework has finished mounting.
The v-cloack attribute does not show or hide your elements - it is basically a marker that indicates if mounting is finished. You write a css selector to target v-cloack to hide the elements or show a loading indicatior.
<style>
[v-cloak] > * { display:none }
[v-cloak]::before { content: "Please wait…" }
</style>
Switching to .net core or any other server side technology would not help.
The issue is because the html is rendered by the browser as it downloads & before all the script resources have downloaded/parsed/run & rendered the html from the Vue component.
When dealing with mixed rendering (partially server side & partially client side) your best option is to hide the template by default & "show" it once the vue component is setup & ready.
For example in your server side view, hide <div id="app"> either with an attribute, style or class.
<style>#app.loading {display:none;}</style>
<div id="app" v-bind:class="{ loading: !isloaded }">
Then in your vue component mounted method set isLoaded to true. This is just one of many ways to hide the component before it's ready.

ASP.NET MVC Unobtrusive validation not working on IE9

I am working on code written by someone else.
Its a Reset Password form. The current client side validation works on most browsers including IE 10 and IE 11. On IE 9 the Confirm Password does not match error keeps getting displayed even though I am sure I am typing the exact same thing in both fields.
The code:
<div class="form-group">
<div class="input-group input-phone">
<span class="input-group-addon"><span class="glyphicon glyphicon-lock"></span></span>
<input type="password" id="Password" name="Password" class="form-control input-lg default-focus" data-val="true" data-val-required="Password is required." placeholder="Password" autocomplete="off">
</div>
<div class="field-validation-valid" data-valmsg-for="Password" data-valmsg-replace="true"></div>
</div>
<div class="form-group form-group-login-bottom">
<div class="input-group input-pin">
<span class="input-group-addon"><span class="glyphicon glyphicon-lock"></span></span>
<input type="password" id="ConfirmPassword" name="ConfirmPassword" class="form-control input-lg" data-val="true" data-val-equalto="Confirm Password does not match." data-val-equalto-other="*.Password" placeholder="Confirm Password" autocomplete="off">
</div>
<div class="field-validation-valid" data-valmsg-for="ConfirmPassword" data-valmsg-replace="true"></div>
</div>
I searched a lot yesterday but none of the solution seems to work.
I tried: updating the jquery.validate.js and jquery.validate.unobtrusive.js files.
I tried debugging, in the jquery.validate.js file, this snippet,
// http://docs.jquery.com/Plugins/Validation/Methods/equalTo
equalTo: function( value, element, param ) {
// bind to the blur event of the target in order to revalidate whenever the target field is updated
// TODO find a way to bind the event just once, avoiding the unbind-rebind overhead
var target = $(param);
if ( this.settings.onfocusout ) {
target.unbind(".validate-equalTo").bind("blur.validate-equalTo", function() {
$(element).valid();
});
}
return value === target.val();
},
target is the input field with id Password. On IE 10 and IE 11, alerting target.val()
returns the correct value of type in. On IE 9 it returns empty. Cannot figure out why it does not work on IE 9 specifically. Any suggestions would be helpful.
What versions of jQuery, jQuery validate and ASP MVC are you using?
I just created a fiddle using your html and including the latest versions of those libraries (jquery 2.1.0, validate 1.13 and validate-unobtrusive from MVC 5). I verified the validation works on IE9 (Mine is version 9.0.8112.16421)
However I have found this issue which means you may find this error in IE9 with incorrect html on your page. You could make sure you don´t have any open tags (like a <p> without its corresponding </p>). For example if in the fiddle you just add a <p> right before the <form> the validation stops working in IE9 but not in Firefox. (See this updated fiddle that doesn´t work on IE9)
In case this doesn´t help, I would check the library versions and any other library that you might be loading in your page that could interfere (If you could replicate your issue in a fiddle that would be great!). If nothing helps, you can try removing the validate-unobtrusive library from the fiddle (it is added on external references) and uncomment the JS code to manually use the validation plugin. At least that would let you find out if the issue is related with jquery.validate or with Microsoft´s jquery.validate-unobtrusive:
//This is commented in the fiddle. Only uncomment to try jquery.validate without jquery.validate-unobtrusive
$(document).ready(function () {
$("#testForm").validate({
debug: false,
rules: {
Password: {
required: true
},
ConfirmPassword: {
required: true,
equalTo: "#Password"
}
},
submitHandler: function (form) {
// just for the fiddle demo
alert('valid form submitted');
return false;
}
});
});

jQuery UI dialog form submit that is defined with method=POST some how turns into a GET

I can use some help to understand jQuery and jQuery UI dialog a bit better.
I'm using jQuery v1.8.18 UI Dialog and jQuery v1.7.1 to load an html page that contains a form. The form itself was generated by a Django template. After filling out the form and click on 'Submit', I looked at the HTTP request as seen on the Django server side. The server sees it as an ajax request of type GET with empty GET and POST dictionaries.
The expected result would be a POST with actual submission data in it. Can someone help me understand how UI Dialog changed a POST request into a GET? I'm using Firebug but need some debugging ideas. Thanks.
This is how I created the UI Dialog:
<script>
$(document).ready(function() {
var $dialog = $('<div></div>').load('/friend-request/').dialog({autoOpen:false, title:'Friend Request', modal:true});
$('#friend-request').click(function() {
$dialog.dialog('open');
// prevent the default action, e.g., following a link
return false;});
});
</script>
The element #friend-request is just an HTML anchor. My form loaded just fine into the dialog. Here is the HTML form code that was generated.
<form id="id-friendreq" method="post">
<div style="display:none"><input type="hidden" value="12a94012df543b050d69f46f0012345" name="csrfmiddlewaretoken"></div>
<div class="ctrlHolder" id="div_id_to_user">
<label for="id_to_user">
To user<span class="asteriskField">*</span>
</label>
<input type="text" maxlength="15" name="to_user" id="id_to_user">
</div>
<div class="ctrlHolder" id="div_id_message">
<label for="id_message">
Message<span class="asteriskField">*</span>
</label>
<textarea class="textarea" cols="40" id="id_message" name="message">Hi, please add me as your friend.</textarea>
</div>
<div class="buttonHolder">
<input type="submit" id="submit-id-submit" class="submit submitButton button white" value="Submit" name="submit">
</div>
</form>
If you aren't setting the ajax option type to "POST" or using a convenience method like $.post(), default is "GET"
http://api.jquery.com/jQuery.ajax/
The post method is used only if you submit some data.
$(el).load(url,data,success)
If you are not supplying any data, then it is equivalent to a blank get query. Even on server side, if you don't send any data, there is no way for the server to know if you made a post or get request. Honestly, its just about data, you can send post data with a get query as well
If you must use a POST request explicitly use:
$.post(url,{},function(data){$('<div></div>').html(data)});

Form checkboxes not being displayed correctly second time shown

I have a weird problem with a simple form with checkboxes..
The first time it's shown it looks fine.. But then after navigating back to the previous page and be to it again - the ui is not updates resulting in plain checkboxes without jQuery mobile style..
I've Googled like crazy and found a couple of hints like .fieldcontain(); but it's doesn't work =(
The data is being retrieved through knockout bindings..
Any good ideas?
Here's the code...
<div id="searchCitiesPage" data-role="page" data-theme="a" class="page searchCities">
<header data-role="header" data-theme="b">
</header>
<div data-role="content" class="content" data-theme="a">
<script id="countyListTemplate" type="x-jquery-tmpl">
<form id="fieldform" action="form.php" method="post">
<fieldset id="fieldsetgroup" data-role="controlgroup">
{{each BoligPortal.AdSearch.postalcodesInSelectedCounty}}
<input type="checkbox" name="checkbox-${zipcode}-${timestamp}" id="checkbox-${zipcode}-${timestamp}" class="zipcodecheckbox"/>
<label for="checkbox-${zipcode}-${timestamp}">${zipcode} ${city}</label>
{{/each}}
</fieldset>
</form>
</script>
<div data-bind="template: 'countyListTemplate'"></div>
<div class="submit">
Næste
</div>
</div>
I was having a problem like this too, but in my case, the checkboxes were being redrawn dynamically before loading the page. I tried refreshing:
$("input[type='checkbox']").checkboxradio("refresh");
But it gave me an error stating that checkboxradio hadn't been initialized. However, when I tried this instead:
$("input[type='checkbox']").checkboxradio();
It made the checkboxes appear correctly every time. I'm still fumbling in the dark with JQuery Mobile and can't say exactly what happens where and why (I think I'm initializing the checkboxes?), but I thought I would share for the next time someone like me googles their way to this thread.
You can add some javascript to re-initialize the jQuery Mobile markup for your checkbox on each page load. Something like this:
<script type="text/javascript">
$(function() {
$('[data-role=page]').live('pageshow',function(){
$('#fieldform').find('input').checkboxradio();
});
});
</script>
I would suspect this code
{{each BoligPortal.AdSearch.postalcodesInSelectedCounty}}
<input type="checkbox" name="checkbox-${zipcode}-${timestamp}" id="checkbox-${zipcode}-${timestamp}" class="zipcodecheckbox"/>
<label for="checkbox-${zipcode}-${timestamp}">${zipcode} ${city}</label>
{{/each}}
is being called again when you transition back to the page. I would suggest pulling the infomation/tags/etc.. before the page displays (on the first load) and display it statically. So when transitioning back it shows the same data.
of you could use one of the live events and restyle it before the page shows, example:
$('.zipcodecheckbox').live('pagebeforeshow',function(event, ui){
$("input[type='checkbox']").checkboxradio("refresh");
// or
$(".zipcodecheckbox").checkboxradio("refresh");
});

Resources