Rails Client side validation not passing true even after selecting jquery datepicker - ruby-on-rails-3

In my application I have implemented jquery datepicker as well as rails client side validations. But even after I select the dates, I get the error as "can't be blank" and the form doesn't gets submitted.. How do I pass the validation after selecting a date.
Please find my code for datepicker below.
jQuery(document).ready(function($){
$('#project_start_date').datepicker({ dateFormat: "yy-mm-dd",onSelect: function(selected) {
$("#project_end_date").datepicker("option","minDate", selected)
}
});

As described on the Client Side Validations wiki, you can add this option to make jQueryUI DatePicker compatible with Client Side Validations:
onClose: function(dateText, inst) { $(inst.input).change().focusout(); }
In your example:
$('#project_start_date').datepicker({
dateFormat: "yy-mm-dd",
onSelect: function(selected) { $("#project_end_date").datepicker("option","minDate", selected) },
onClose: function(dateText, inst) { $(inst.input).change().focusout(); }
})

The main issue is that the validation is triggered when focus is out... as a workaround you can trigger the focus events manually after the datapicker is closed
$('#project_start_date').datepicker({ dateFormat: "yy-mm-dd",onSelect: function(selected) {
$("#project_end_date").datepicker("option","minDate", selected)
}, onClose: function(){
//workaround to trigger javascript validation
$(this).focusout();
}
});

Related

Onbeforeunload Event calling

I am new to vuejs. Does anyone help me?
If I click the browser refresh button, I need to show the popup. So I used below code here.
I am using the code like,
window.onbeforeunload=function(){
return "Your work will be lost.";
}
I used this function under the beforeMount() lifecycle instance in a single page. But, this popup showed the multiple pages, when I click the browser refresh button. I want to show this pop up in a single page. Can Anyone help me??
I see this is an old post, but maybe this will help you in the future or others. As mentioned above, it would help a lot to see the actual code implementation, but maybe this will help.
<script>
export default {
data: () => ({
shouldPrevent: false
}),
beforeMount() {
window.addEventListener("beforeunload", this.preventNav)
},
beforeDestroy() {
// Don't forget to clean up event listeners
window.removeEventListener("beforeunload", this.preventNav)
},
methods: {
preventNav(e) {
if (!this.shouldPrevent) return
e.preventDefault()
e.returnValue = ""
},
},
}
</script>

Sweetalert2 won't close

using
aurelia-cli - 0.30.1
sweetalert2 - 6.6.5
typescript - 2.3.3
latest browsers (FF, Chrome, IE, Opera)
ts code
public showHelp() {
swal('Test').then((out) => {
console.log(out);
}).catch((error) => console.log(error));
}
alert displays with no problems, but clicking on confirm button does not dismis the alert. alert also won't dismiss on outside click. pressing ESC or ENTER works fine.
no errors throw ...
any idea why this will not accept click?
I have put breakpoints on these
// Mouse interactions
var onButtonEvent = function onButtonEvent(event) {
// Closing modal by close button
getCloseButton().onclick = function () {
// Closing modal by overlay click
container.onclick = function (e) {
in swal source, but they never get hit...
also tried setting target to something else than body, with the same result.
I had the exact same issue and apparently this is what was giving me the problem:
.swal2-container:not(.swal2-in) {
pointer-events: none;
}
Just comment that line or change none to all (Although I don't know yet if it breaks anything else)
I'm using:
paper-dashboard (free angular2 version) - 1.0.0
angular.cli - 1.1.1
sweetalert2 - 6.6.6
typescript - 2.3.3
latest browsers (same)
I'm unable to reproduce what you're experiencing. Using sweetalert2 v6.6.6 (oh dear), the alert displays and hides properly on all scenarios you mention: the [OK] button, clicking outside the alert dialog and the keyboard modifiers.
I'm using the configuration below. You're probably already aware, but please do note that I'm explicitly including the css file in the aurelia.json and referencing it in the app.html view.
Here is the full app:
aurelia.json
{
"name": "sweetalert2",
"path": "../node_modules/sweetalert2/dist",
"main": "sweetalert2",
"resources": [
"sweetalert2.css"
]
}
app.ts
import swal from 'sweetalert2';
export class App {
attached() {
this.showHelp();
}
public showHelp() {
swal('Test').then((out) => {
console.log(out);
}).catch((error) => console.log(error));
}
}
app.html
<template>
<require from="sweetalert2/sweetalert2.css"></require>
</template>

beforeRouteLeave and mixin

I am using Vue.js for a CRUD system, tracking a number of different domain classes, such as Customer, Product, etc. I have a validation mixin which I use in each editor component (e.g, CustomerDetail, ProductDetail). Because I would like common behaviour when a user moves away from the page without saving, I'd like to be able to have a method in my validation mixin which I can call in 'beforeRouteLeave'. The method I have come up with is this:
checkOnLeave(obj,message,confirmText="Leave",cancelText="Continue Editing",next){
if (this.isDirty(obj)) { //isDirty checks whether object has been changed
bootbox.confirm({
message: message,
buttons: {
confirm: {
label: confirmText,
},
cancel: {
label: cancelText,
}
},
callback: function (result) {
if (result) {
next();
} else {
next(false);
}
}
});
} else {
next();
}
}
When I try to use this, though, it doesn't have any idea what to do with 'next'. Clearly this is something from vue-router which it is unaware of. So how can I make my mixin vue-router aware so that I can use this?
Red herring alert. It actually works fine as is - it must have been a delay in compiling which caused the problem before (it happens from time to time with 'npm run dev', the compile occasionally doesn't kick in).

How to use durandal router to activate dialogs?

I would love to a #signin route that would open a dialog on top of whatever page there was before.
Let's consider this example app this the following routes:
router.map([
{route: '', moduleId: 'vm/home', title: "Home"},
{route: 'about', moduleId: 'vm/about', title: "About"},
{route: 'signin', moduleId: 'vm/signin', title: 'Sign In'}
]);
Here are example use cases:
User is on # and navigates to #signin: we should see a Sign In dialog on top of Home page
User is on #about and navigates to #signin: we should see a Sign In dialog on top of About page
User navigates to http://localhost:9000/#signin: we should see a Sign In dialog on top of Home page
User is on #signin and closes dialog: we should see a page that was behind the dialog (there's always a page behind).
The dialog and router are both plugins and have no interactions between eachother.
Also having the router display dialog would ignore how the router works - it has a div which it dumps content into. Dialogs exist outside of all of this.
However if you wanted to (I may do this aswell), you could try this.
Add dialog: true to the route map.
Override router.loadUrl method. Check if the route is a dialog route as we marked before, and activate the dialog instead.
I would make the dialog a child route, so then you can know which view to display beneath the dialog. Otherwise you could just have to show the dialog over anything and ignore routing entirely.
Edit: I don't think this would entirely work actually. loadUrl returns a boolean. You could open the dialog and return false to cancel navigation.
Edit2:
My Attempt
The loadUrl method loops through all routes, and each has a callback, so ideally we need to insert our logic into this array.
for (var i = 0; i < handlers.length; i++) {
var current = handlers[i];
if (current.routePattern.test(coreFragment)) {
current.callback(coreFragment, queryString);
return true;
}
}
This array is added to using the routers route method. Durandal calls this method when you map routes, so ideally we could add some extra parameters to the route config and let Durandal handle these. However the configureRoute function is internal to the routing module, so we will need to edit that and make sure we copy changes over when updating Durandal in the future.
I created a new list of dialog routes:
{ route: 'taxcode/add(/:params)', moduleId: 'admin/taxcode/add', title: 'Add Tax Code', hash: '#taxcode/add', nav: false, dialog: true, owner: '#taxcodes' },
{ route: 'taxcode/edit/:id', moduleId: 'admin/taxcode/edit', title: 'Edit Tax Code', hash: '#taxcode/edit', nav: false, dialog: true, owner: '#taxcodes' }
The idea of an owner, is that if there is a case where the initial route is this, we need something behind the dialog.
Now replaced the router.route call in configureRoute with this:
router.route(config.routePattern, function (fragment, queryString) {
if (config.dialog) {
if (!router.activeInstruction()) {
// No current instruction, so load one to sit in the background (and go back to)
var loadBackDrop = function (hash) {
var backDropConfig = ko.utils.arrayFirst(router.routes, function (r) {
return r.hash == hash;
});
if (!backDropConfig) {
return false;
}
history.navigate(backDropConfig.hash, { trigger: false, replace: true });
history.navigate(fragment, { trigger: false, replace: false });
queueInstruction({
fragment: backDropConfig.hash,
queryString: "",
config: backDropConfig,
params: [],
queryParams: {}
});
return true;
};
if (typeof config.owner == 'string') {
if (!loadBackDrop(config.owner)) {
delete config.owner;
}
}
if (typeof config.owner != 'string') {
if (!loadBackDrop("")) {
router.navigate("");
return; // failed
}
}
}
var navigatingAway = false;
var subscription = router.activeInstruction.subscribe(function (newValue) {
subscription.dispose();
navigatingAway = true;
system.acquire(config.moduleId).then(function (dialogInstance) {
dialog.close(dialogInstance);
});
})
// Have a route. Go back to it after dialog
var paramInfo = createParams(config.routePattern, fragment, queryString);
paramInfo.params.unshift(config.moduleId);
dialog.show.apply(dialog, paramInfo.params)
.always(function () {
if (!navigatingAway) {
router.navigateBack();
}
});
} else {
var paramInfo = createParams(config.routePattern, fragment, queryString);
queueInstruction({
fragment: fragment,
queryString: queryString,
config: config,
params: paramInfo.params,
queryParams: paramInfo.queryParams
});
}
});
Make sure you import dialog into the module.
Well maybe all of that is not needed when using a trick with the activation data of your home viewmodel.
Take a look at my Github repo I created as an answer.
The idea is that the route accepts an optional activation data, which the activate method of your Home VM may check and accordingly show the desired modal.
The benefit this way is that you don't need to touch the existing Durandal plugins or core code at all.
I'm though not sure if this fully complies with your request since the requirements didn't specify anything detailed.
UPDATE:
Ok I've updated the repo now to work with the additional requirement of generalization. Essentially now we leverage the Pub/Sub mechanism of Durandal inside the shell, or place it wherever else you want. In there we listen for the router nav-complete event. When this happens inspect the instruction set and search for a given keyword. If so then fire the modal. By using the navigation-complete event we ensure additionally that the main VM is properly and fully loaded.
For those hacks where you want to navigate to #signin, just reroute them manually to wherever you want.
Expanding on my suggestion in the comments, maybe something like this would work. Simply configure an event hook on router:route:activating or one of the other similar events and intercept the activation of /#signin. Then use this hook as a way to display the dialog. Note that this example is for illustrative purposes. I am unable to provide a working example while I'm at work. :/ I can complete it when I get home, but at least this gives you an idea.
router.on('router:route:activating').then(function (instance, instruction) {
// TODO: Inspect the instruction for the sign in route, then show the sign in
// dialog and cancel route navigation.
});

ExtJS4 MVC Architecture walkthrough on sencha doc giving me errors

I'm following the ExtJS4.0 MVC Application Architecture walk through and modifying it to my own project as I go to make sure I get things right. So far it's working perfectly. I've just completed the 'Defining a View' section and I'm about to start the 'Controlling the grid' section. Before I do, I want to remove the console.log code as I don't want or need it for my own project. I find I can replace it with an alert message but can't remove it all together without generating an error against ext-all-debug.js.
Here's my functioning code on the controller and the error it's generating after I remove the consol.log function. In the example doc, it's AM.controllers.list.
Ext.define('ChatAgent.controller.queues', {
extend: 'Ext.app.Controller'
, views: [
'queue.list'
]
, init: function() {
this.control({
'viewport > panel': {
render: this.onPanelRendered
}
});
}
, onPanelRendered: function() {
console.log('The panel was rendered');
}
});
The error it generates is:
'fireFn' is null or not an object
All I've removed is:
onPanelRendered: function() {
console.log('The panel was rendered');
}
So why the error???
You need to get rid of the event listener as well. When the render event fires it is trying to call onPanelRendered which doesn't exist anymore.
If you aren't listening for any events, you don't even need to have that entire this.control block. Comment this out and see what happens.
this.control({
'viewport > panel': {
render: this.onPanelRendered
}
});