two jQuery UI datepickers in one form, 'missing instance data' - jquery-ui-datepicker

I've got two date pickers in one form. They have different id's so this shouldn't be related to similar errors such as this one.
jQuery. Apply selector to every field in a dynamic form
The error I'm getting in firebug is
'uncaught exception: Missing instance data for this datepicker'
Which is triggered when I select a day from the '#copyTo' datepicker which is the second datepicker on the form. The first datepicker works perfectly.
The form I have is
<form name="copy" action="copyEvents.php" method="post">
<input type="hidden" id="copyFromHid" name="copyFromHid"/>
<input type="hidden" id="copyToHid" name="copyToHid"/>
Copy From <input id="copyFrom" name="copyFrom"/>
Copy To <input type="text" id="copyTo" name="copyTo"/>
<input type="hidden" name="gid" id="gid"/>
<input type="submit" value="copy"/>
</form>
The jquery is
jQuery('input#copyFrom','div#copyFromHistory form')
.datepicker({
altField: 'input#copyFromHid',
altFormat: 'yy-mm-d',
dateFormat: 'd MM yy',
firstDay: 1,
beforeShowDay: function(date) {
return (date.getDay() == 1) ? [true, ""] : [false, ""]; }
});
jQuery('input#copyTo','div#copyFromHistory form')
.datepicker({
altField: 'input#copyToHid',
altFormat: 'yy-mm-d',
dateFormat: 'd MM yy',
firstDay: 1,
beforeShowDay: function(date) {
return (date.getDay() == 1) ? [true, ""] : [false, ""]; }
});
Any suggestions as to why the first field would work, but not the second?

Easy to solve, change your code to something like this:
$('.date').live('focus', function(){
$(this).datepicker({
changeMonth: true,
changeYear: true,
yearRange: '1930:'+(new Date).getFullYear()
});
});

Two things come to mind:
One is in your jQuery selectors:
jQuery('input#copyFrom','div#copyFromHistory form')
jQuery('input#copyTo','div#copyFromHistory form')
In both cases you pass the context/ownerDocument parameter to jQuery() but that is looking for DOM element or document... not a string.
And the second thing is:
Copy From <input id="copyFrom" name="copyFrom"/>
Copy To <input type="text" id="copyTo" name="copyTo"/>
Copy To has type="test" and Copy From does not (though the default input type is text... so probably not that)
I suspect you really want:
jQuery('input#copyFrom').datepicker(....)
jQuery('input#copyTo').datepicker(....)

Related

Datepicker jQuery does not update ngModel AngularJS 4

I tried to put the datepicker value to an angle variable but it did not work, if someone can help me, I am very grateful.
My code AngularJS & jQuery:
public inicializaDatepicker() {
$('#datepicker').datepicker({
showOn: "focus",
autoSize: this.tamanioAuto,
dateFormat: this.formato,
changeMonth: this.mesEnCombo,
changeYear: this.anioEnCombo,
yearRange: this.anioMin + ':' + this.anioMax,
onSelect: function () {
$(this).trigger('input');
$(this).trigger('change');
}
});
}
The problem is that ngModel does not detect any change in the input.
My HTML:
<input class="form-control input-sm" type="text" id="datepicker [(ngModel)]="valor" (ngModelChange)="handleSelected()" />

How to clear the typeahead input after a result is selected?

I'm using the ng-bootstrap typeahead component to search a customer database. When the user selects a customer from the typeahead results list, I navigate to a customer details page. I've got this working, but I want to clear the input field after navigation has taken place. I've tried setting the model to null or an empty string in the selectItem event logic, but this isn't working:
customer-search-typeahead.component.html
<template #resultTemplate let-r="result" let-t="term">
<div>
<div>
{{r.resource.name[0].given}} {{r.resource.name[0].family}}
</div>
<div>
{{r.resource.birthDate | date: 'dd/MM/yyyy'}}
</div>
</div>
</template>
<input type="text" class="form-control" [resultTemplate]="resultTemplate" (selectItem)="onSelect($event)"
[(ngModel)]="model" placeholder="Start typing a customer name..." [ngbTypeahead]="search"/>
customer-search-typeahead.component.ts
#Component({
selector: 'customer-search-typeahead',
template: require('./customer-search-typeahead.component.html'),
styles: [`.form-control { width: 300px; }`]
})
export class CustomerSearchTypeaheadComponent {
model: any;
searching: boolean;
constructor(private customerService: CustomerService, private router: Router) {}
onSelect($event) {
this.router.navigate(['/customers', $event.item.resource.id]);
this.model = null;
};
search = (text$: Observable<string>) =>
//omitted for brevity
}
The typeahead input looks like this after a selection has been made:
Solution
customer-search-typeahead.component.html
<input type="text" class="form-control" #input [ngbTypeahead]="search" (selectItem)="onSelect($event); input.value='' ">
customer-search-typeahead.component.ts
onSelect($event, input) {
$event.preventDefault();
this.router.navigate(['/customers', $event.item.resource.id]);
};
The issue you witnessing arises from the fact that the NgModel directive is updating model binding asynchronously and the actual model is updated after the onSelect method gets executed. So your model update gets overridden by the NgModel functionality.
Fortunately we (ng-bootstrap authors) got all the flex points in place to cover your use-case :-) There are a couple of things that you could do.
Firstly the $event object passed to the onSelect method has the preventDefault() method and you can call it to veto item selection (and as a result writing back to the model and input field update).
$event.preventDefault() will make sure that the model is not updated and the input field is not updated with the selected item. But text entered by a user will still be part of the input so if you want to clear up this as well you can directly update the input's value property.
Here is code demonstrating all those techniques together:
onSelect($event, input) {
$event.preventDefault();
this.selected.push($event.item);
input.value = '';
}
where input argument is a reference to the input DOM element:
<input type="text" class="form-control" #input
[ngbTypeahead]="search" (selectItem)="onSelect($event, input)">
Finally here is a plunker showing all this in practice: http://plnkr.co/edit/kD5AmZyYEhJO0QQISgbM?p=preview
The above one is template ref value solution.
This is for ngModel solution.
Html code:
<input type="text" class="form-control" [resultTemplate]="resultTemplate" (selectItem)="onSelect($event)"
[(ngModel)]="model" placeholder="Start typing a customer name..." [ngbTypeahead]="search"/>
Component code:
onSelect($event) {
$event.preventDefault();
this.model = null;
this.router.navigate(['/customers', $event.item.resource.id]);
};
$event.preventDefault();
for ngModel value change empty

How to submit a CFInput type=file within a CFDiv container

I am submitting a file in a cfdiv container, but the value of the file is not submitting to the processing page. If I submit the file outside of the cfdiv, it sees the file value. However, if the file is inside a cfdiv or div container, the form field is undefined. I have also added the enctype="multipart/form-data" to the cfform, but it is still not working.
UPDATE:
This is the first page (index.cfm)
<div name="loadcontainer" id="loadcontainer">
<cfinclude template="homepage.cfm">
</div>
The homepage.cfm
<cfform name="school_create" id="school_create"
action="pro_create_school.cfm"
enctype="multipart/form-data"
method="post">
<cfinput size="50" type="file" id="school_logo" name="school_logo">
<button type="submit">Save</button>
</cfform>
When the save button is clicked, it doesn't see the form.school_logo value in the action processing page.
I have also tried using a normal form and input, instead of a cfform/cfinput, but the form is being loaded into another tab when submitted, instead of the div container.
"File" is an incorrect "type" for a CFINPUT in earlier CF Versions (not sure what version you are using). I did check the docs and it is allowed in current versions.
Meanwhile, Instead change your CFINPUT to:
<input size="50" type="file" id="school_logo" name="school_logo">
Or better yet, get rid of <cfform> - you aren't using it for anything and you don't need it. A good JS library (jquery) will provide you with better functionality for validation etc.
In this case you could easily do:
<form name="school_create" id="school_create"
action="pro_create_school.cfm"
enctype="multipart/form-data"
method="post">
<input size="50" type="file" id="school_logo" name="school_logo">
<button type="submit">Save</button>
</form>
And it would work as expected. Cfform is designed to provide simple validation functions in a native CF Fashion, but outside of tutorials and books explaining CFML almost no one uses it. When we see it used here at CF Webtools, we refactor it as soon as we are able.
I was able to Submit the form both the <cfinput type="file"..../> and other form field in the form with ajax.
<script>
function validateForm() {
var x = document.forms["add_academic_year"]["start_year"].value;
var y = document.forms["add_academic_year"]["end_year"].value;
if (x == null || x == "" || y == null || y == "") {
alert("Start Year and End Year Must be Selected");
return false;
}
if (y <= x) {
alert("End Year must be greater than Start Year ");
return false;
}
console.log("submit event");
var fd = new FormData(document.getElementById("add_academic_year"));
$.ajax({
url: "pro_academic_year.cfm",
type: "POST",
data: fd,
enctype: 'multipart/form-data',
processData: false, // tell jQuery not to process the data
contentType: false // tell jQuery not to set contentType
}).done(function( response ) {
// display response in DIV
$("#loadcontainer").html( response.toString());
})
.fail(function(jqXHR, textStatus, errorMessage) {
// display error in DIV
$("#outputf").html(errorMessage);
})
return false;
}
</script>

polymer-cookie generates duplicate Django csrf cookie

Odd issue I just ran into. Django seems to be generating 2 cookies on when I go to this page. The two cookies doesn't have the same token, so that causes my post to fail because it's validating against the wrong cookie.
Anyone know why this might be happening?
Nothing special in the view:
class ListingDetailView(TemplateView):
template_name = "bidding/listing_detail.html"
def get(self, request, *args, **kwargs):
c = self.get_context_data(**kwargs)
c['listing'] = get_object_or_404(Listing, id=kwargs['id'])
return self.render_to_response(c)
... though it seems that the offending code may be inside one of my custom components (when I hide it, the extra cookie ain't generated):
<polymer-element name="bts-place-bid" attributes="href">
<template>
<polymer-cookie id="csrfcookie" name="csrftoken"></polymer-cookie>
<core-ajax
id="bidxhr"
method="post"
body=""
url="{{ href }}"
headers='{"X-CSRFToken": "{{ csrftoken }}"}'
on-core-response="{{ handleResponse }}">
</core-ajax>
<core-style ref="bts-place-bid"></core-style>
<paper-button on-click="{{ toggleDialog }}">Place Bid</paper-button>
<paper-action-dialog heading="Place Bid"
transition="core-transition-center"
id="bidDialog">
<core-style ref="bts-bid-dialog"></core-style>
<bts-field>
<label for="id_amount">Bid Amount in Rands</label>
<input type="number" name="amount" id="id_amount" value="{{ amount }}">
</bts-field>
<bts-field vertical layout>
<label for="id_proposal">Short note or proposal for this bid</label>
<textarea rows="4" id="id_proposal" name="proposal" value="{{ proposal }}"></textarea>
</bts-field>
<paper-button dismissive><core-icon icon="cancel"></core-icon> Cancel</paper-button>
<paper-button on-click="{{ placeBid }}" affirmative><core-icon icon="note-add"></core-icon> Place Bid!</paper-button>
</paper-action-dialog>
<paper-toast id="toastMsg" text=""></paper-toast>
</template>
<script>
Polymer({
amount: 0,
proposal: "",
bidPayload: "",
ready: function() {
this.csrftoken = this.$.csrfcookie.value;
},
toggleDialog: function(ev, detail, sender) {
this.$.bidDialog.toggle();
},
placeBid: function(ev, detail, sender) {
this.$.toastMsg.text = "Placing bid, please wait..."
this.$.toastMsg.show();
this.$.bidxhr.body = "amount=" + this.amount + "&proposal=" + this.proposal;
this.$.bidxhr.go();
},
handleResponse: function(ev, detail, sender) {
this.$.toastMsg.text = "Bid placed, refreshing...";
this.$.toastMsg.show();
// Auto refresh the page...
window.location = window.location;
}
});
</script>
</polymer-element>
I suspect the issue may be with <polymer-cookie>, I'll dig around it's source a bit.
So... you are definitely creating this second cookie. It's not a bug. But let's see if we can't get you back on track.
The source for polymer-cookie shows several "hidden" attributes:
<polymer-element name="polymer-cookie" hidden attributes="name value expires secure domain path max-age">
The cookie you're setting has the same name as the CSRF token, but an arbitrary value. So the easiest fix probably is to specify the value you want it to have:
<polymer-cookie id="csrfcookie" name="csrftoken" value="{{ csrftoken }}"></polymer-cookie>
I'd expect that you will still have duplicate cookies, but at least now they will have the same value.
As for how you should do this... skip polymer-cookie and just put {% csrftoken %} in your template. That will create a hidden input with the name "csrfmiddlewaretoken" that you can inspect the value of on the client side. Then you can return that value with your ajax POSTs.
In the end the solution was quite simple. Should have thought about it earlier.
I simply modified my custom component to accept a extra attribute called csrftoken, and to this attribute I can just pass the django {{ csrf_token }} variable. No need to look up the cookie, no need to add a extra input field etc.
Here is the final component:
<polymer-element name="bts-place-bid" attributes="href csrftoken">
<template>
<core-ajax
id="bidxhr"
method="post"
body=""
url="{{ href }}"
headers='{"X-CSRFToken": "{{ csrftoken }}"}'
on-core-response="{{ handleResponse }}">
</core-ajax>
<core-style ref="bts-place-bid"></core-style>
<paper-button on-click="{{ toggleDialog }}">Place Bid</paper-button>
<paper-action-dialog heading="Place Bid"
transition="core-transition-center"
id="bidDialog">
<core-style ref="bts-bid-dialog"></core-style>
<bts-field>
<label for="id_amount">Bid Amount in Rands</label>
<input type="number" name="amount" id="id_amount" value="{{ amount }}">
</bts-field>
<bts-field vertical layout>
<label for="id_proposal">Short note or proposal for this bid</label>
<textarea rows="4" id="id_proposal" name="proposal" value="{{ proposal }}"></textarea>
</bts-field>
<paper-button dismissive><core-icon icon="cancel"></core-icon> Cancel</paper-button>
<paper-button on-click="{{ placeBid }}" affirmative><core-icon icon="note-add"></core-icon> Place Bid!</paper-button>
</paper-action-dialog>
<paper-toast id="toastMsg" text=""></paper-toast>
</template>
<script>
Polymer({
amount: 0,
proposal: "",
bidPayload: "",
toggleDialog: function(ev, detail, sender) {
this.$.bidDialog.toggle();
},
placeBid: function(ev, detail, sender) {
this.$.toastMsg.text = "Placing bid, please wait..."
this.$.toastMsg.show();
this.$.bidxhr.body = "amount=" + this.amount + "&proposal=" + this.proposal;
this.$.bidxhr.go();
},
handleResponse: function(ev, detail, sender) {
this.$.toastMsg.text = "Bid placed, refreshing...";
this.$.toastMsg.show();
// Auto refresh the page...
window.location = window.location;
}
});
</script>
</polymer-element>
... and this is then used in the main django template as such:
<bts-place-bid href="{% url 'bidding_listing_bid' id=listing.id %}"
csrftoken="{{ csrf_token }}"></bts-place-bid>

Returning a proper response for post request in Django

<form id="login_frm" method="post" action = "/login/user_auth/">
<fieldset>
<legend>Login:</legend>
<label for="id_email">Email</label>
<input type="text" name="email" id="id_email" />
<label for="id_password">Password</label>
<input type="password" name="password" id="id_password" />
</fieldset>
<input name = "login" type="submit" value="Login" />
</form>
$(document).ready(function () {
$('#login_frm').submit(function() {
var $form = $(this);
$.post('/login/user_auth/' , form.serialize(), function(data) {
// alert ("function");
alert (data);
});
return false;
});
});
Django View:
def login_user(request):
if request.method == 'POST':
# perform all logic / and db access
data = "hello"
return HttpResponse(data)
# return HttpResponse ('success.html')
I have been stuck on this all afternoon.
When I return data as my response, for some reason, the browser displays "Hello" by loading a blank webpage with just "Hello" written on it; in the JavaScript function above, alert (data); is never called (I cannot understand why).
I am unable to render the success.html. I believe that if I write render_to_response inside the HttpResponse, I will solve this problem. However I think making point 1 work is a first priority.
Goal
After the post, I would like to capture the returned response from the server (whether it is just the "hello" message, or a webpage that displays a success message- stored in "success.html") and display it in place of the login_frm without having the browser refresh a new webpage.
Interesting. form is undefined (you defined it as $form) and changing to $form fixed the problem.
$(document).ready(function () {
$('#login_frm').submit(function() {
var $form = $(this);
$.post('/login/user_auth/' , $form.serialize(), function(data) {
// alert ("function");
alert (data);
});
return false;
});
});
You might want to use something like event.preventDefault() so that future errors are not hidden from you like this. $('form').submit(function(e){ e.preventDefault(); .....})