Play Framework: cannot read value of textfield with javascript - javascript

I could not figure out a way to read the current value of the email field. Everytime I read it, for example with a keyup event, nothing is retrieved. This issue just affects this field. I can read the values of the other textfields without a problem.
createFormOnly.scala.html
This is my view containing the form and jquery code to print the value of the text field. Note that the validation of the #fullname field works without any troubles.
#(signupForm: Form[models.Register], loginForm: Form[Application.Login])
#import helper._
#implicitFieldConstructor = #{
FieldConstructor(twitterBootstrapInput.render)
}
<div class="well">
<h3>#Messages("signup.new")</h3>
#if(flash.get("error")!=null) {
<p class="error">
<span class="label label-danger">#Messages(flash.get("error"))</span>
</p>
}
#form(controllers.account.routes.Signup.save(), 'id -> "signupForm") {
<script type="text/javascript">
$( document ).ready(
function()
{
// Setup form validation on the signupForm element
$("#signupForm").validate({
// Specify the validation rules
rules: {
email: {
required: true
},
fullname: {
required: true,
namecheck: true
}
},
// Specify the validation error messages
messages: {
email: "<p class='error'><span class='label label-danger'>Email missing.</span></p>",
fullname: "<p class='error'><span class='label label-danger'>Name is already used.</span></p>"
},
// handler which handles the submit
submitHandler: function(form) {
form.submit();
}
});
jQuery.validator.addMethod("namecheck", function(value) {
var dataString = {
"action" : "namecheck",
"display_name" : value
};
var check_result = false;
jQuery.ajax({
type: "GET",
url: "http://localhost:9000/checkName/"+$( '#fullname' ).val(),
async: false,
data: dataString,
dataType: "json",
success: function(data){
check_result = (data.toString() == "true");
}
});
console.log(check_result);
return check_result;
}, "error message");
$('body').on("keyup",'#email', function(){
console.log('keyed email');
console.log($('body #email').val());
console.log($('#email').val());
console.log($('#email').attr('value'));
});
$('body').on("keyup",'#fullname', function(){
console.log('keyed fullname');
console.log($('body #fullname').val());
console.log($('#fullname').val());
console.log($('#fullname').attr('value'));
});
}
);
</script>
<ul class="list-group">
<li class="list-group-item">
#inputText(
signupForm("email"),
'placeholder -> Messages("accout.register.create.email"),
'_label -> Messages("email"),
'class -> "form-control",
'_showConstraints -> false,
'id -> "email"
)
</li>
<li class="list-group-item">
#inputText(
signupForm("fullname"),
'placeholder -> Messages("accout.register.create.fullname"),
'_label -> Messages("fullname"),
'class -> "form-control",
'_showConstraints -> false,
'id -> "fullname"
)
</li>
<li class="list-group-item">
#inputPassword(
signupForm("inputPassword"),
'_label -> Messages("password"),
'placeholder -> Messages("accout.register.create.password"),
'class -> "form-control",
'_showConstraints -> false
)
</li>
<li class="list-group-item">
<div class="form-actions">
<input type="submit" class="btn btn-primary" value="#Messages("signup.signup")">
</div>
</li>
</ul>
}
</div>
View creating the form create.scala.html
#(signupForm: Form[models.Register], loginForm: Form[Application.Login])
#scripts = {
<script src="#routes.Assets.at("javascripts/password.js")" type="text/javascript"></script>
}
#main(null, scripts) {
#views.html.guestNavBar(loginForm)
#createFormOnly(signupForm, loginForm)
}
Running it in Chrome / Console output
Now i run the application an type values in the the text fields. An 'a' in the fullname textfield and an 'e' into the email textfield. As shown in the console it is empty.
keyed fullname signup:234
a signup:235
a signup:236
signup:237
true signup:222
keyed email signup:77
signup:78
signup:79
signup:80

A clue might be in the jQuery documentation for the 'val()' mathod:
"Get the current value of the first element in the set of matched elements"
So where you have:
console.log($('#email').val());
It could be in fact another element other than your input that's getting its value output.
Check the HTML that gets output to the browser for another element with ID 'email'. 'email' being quite a generic name there might be something else in the page using this ID.

Related

Select2 can't change value

I am dynamically loading a Select2 input with Ajax. Everything works fine, however, when I try to select a different value, It won't change for some reason. Here's an example of my problem: https://gyazo.com/f9ad7c3ead5fcd1d62740cc44f8d9691
As you can see, the value doesn't change when I click on it. Why does this happen? Maybe it helps when I say that both the first value and the other value have an ID of 1 (its data from different tables in the database) but different texts... How can I make it work?
$('.partnersupplierselect').select2({
ajax: {
dataType: "json",
type: "POST",
data: function (params) {
var group = $(this).parent().parent();
var choice = group.find('.partnersupplier:radio:checked').val();
return {
term: params.term,
'_token': token,
'choice': choice
};
},
url: '{{asset('logs/create/bmi/getpartnerssuppliers')}}',
cache: true,
processResults: function (data) {
return {
results: data
};
}
},
"language": {
"noResults": function () {
return "Geen partners / leveranciers gevonden.";
}
},
escapeMarkup: function (markup) {
return markup;
}
});
$('.partnersupplier').on('change', function(){
var group = $(this).parent().parent();
group.find('.partnersupplierselect').select2('val', '');
group.find('.partnersupplierselect').select2('data', null);
});
Here's the HTML, but that shouldn't be the problem. But in case someone wants to see it:
<div class="group">
<label class="mdl-radio mdl-js-radio mdl-js-ripple-effect" for="partner">
{{Form::radio('partnersupplier', 'partner', true, array('class' => 'mdl-radio__button partnersupplier', 'id' => 'partner'))}}
<span class="mdl-radio__label">Test1 </span>
</label>
<label class="mdl-radio mdl-js-radio mdl-js-ripple-effect margin-radio" for="supplier">
{{Form::radio('partnersupplier', 'supplier', false, array('class' => 'mdl-radio__button partnersupplier', 'id' => 'supplier'))}}
<span class="mdl-radio__label">Test2 </span>
</label>
<div class="form-group selectdiv" >
<label for="yearlypartnersuppliermaintainance">Blablabla<br></label>
<select id="yearlypartnersuppliermaintainance" name="yearlypartnersuppliermaintainance" class="searchselect searchselectstyle partnersupplierselect">
</select>
</div>
</div>
I figured it out!
I changed:
$('.partnersupplier').on('change', function(){
var group = $(this).parent().parent();
group.find('.partnersupplierselect').select2('val', '');
group.find('.partnersupplierselect').select2('data', null);
});
to:
$('.partnersupplier').on('change', function(){
var group = $(this).parent().parent();
group.find('.partnersupplierselect').empty().trigger('change');
});
For some reason, this works and the first thing doesn't. Weird, but at least I got it working!

Select TypeError ui.item undefined Jquery Autocomplete

here is my autocomplete select code:
$('.js-main-search').autocomplete({
minLength: 3,
source: function(request, response) {
$.getJSON('/dashboard/searchDocumentsAndCompanies.do',
{ q: request.term},
function(data) {
if(data.length == 0){
data = [
{name: 'No matches found', resultType: 'COMPANY', noResults: true},
{name: 'No matches found', resultType: 'BRANCHES', noResults: true}
];
}
data.unshift({name: 'Search from documents ยป',resultType: 'DOCUMENT', reqQuery: request.term});
response(data);
});
},
select: function(event, ul) {
event.preventDefault();
selected = true;
if (ul.item.resultType == 'DOCUMENT' && !wasSearched) {
wasSearched = true;
$(".textbox.ui-front li:eq(1)").before('<li class="search-category ui-menu-item">Documents</li>');
$.getJSON(Telema.CONTEXT_PATH + '/dashboard/searchDocumentsAndCompanies.do',
{q: ul.item.reqQuery, resultType: ul.item.resultType},
function (data) {
if (data.length == 0) {
data = [
{name: 'No matches found', resultType: 'DOCUMENT', noResults: true}
];
}
$.each(data, function (index, document) {
$(".textbox.ui-front li:eq(1)").after('<li class="ui-menu-item">' + document.name + '</li>');
});
});
}
}
});
Html:
<div class="search">
<form id="searchForm" action="/">
<div class="search-form cfx">
<input id="topSearchButton" type="submit" class="btn" value="">
<div class="textbox ui-front">
<input id="topSearchInput" type="text" class="textbox-input js-main-search ui-autocomplete-input" autocomplete="off">
<ul class="ui-autocomplete ui-front ui-menu ui-widget ui-widget-content" id="ui-id-1" tabindex="0" style="display: none;"></ul></div>
</div>
</form>
</div>
I have TypeError ul.item undefined when I click one of the menu items. Could anyone suggest on that. If any more information is needed, I'd be happy to supply it!
Per the jQuery UI docs, the ui parameter to the select event handler has a property called item, which is an object with -- by default -- two properties: a label and a value. If you need an additional resultType property, you must explicitly define it as part of the source property when you initialize the autocomplete widget. Something like this:
source: (request, response) ->
$.get .............
response $.map data, (request_data) ->
{
label: request_data.value.replace(regex, "<strong>$1</strong>"),
value: if request_data.id == "" then $('#q').val() else request_data.value,
id: request_data.id
resultType: request_data.resulttype
}
Source: http://www.codedisqus.com/0mNVUVekWW/jquery-autocomplete-select-ignores-custom-data-fields.html

Disable button unless Selected from Typeahead Autocomplete

--- EDIT: Explaining the Flow ---
In the input field, the user is supposed to enter any string which is basically the name of a company they are searching for. Once the user has entered 3 or more characters, an AJAX call goes to the database, and fetches results matching the users query and displays them like search suggestions in Google or your browser URL bar. One the user selects an item from the suggestions, and clicks on the button, a function called setCompany() is triggered which performs different actions.
What I want is that the button which triggers further actions based on the search query, should be disabled UNTIL the user selects an item from the suggestions that Bloodhound, Typeahead has come up with.
--- End EDIT ---
I am using the code below to enable user to select values from the dropdown list that is generated by Typeahead, Bloodhound.
$(document).ready(function() {
//Set up "Bloodhound" Options
var my_Suggestion_class = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('keyword'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: "{{ URL::to('user/company/%compquery') }}",
filter: function(x) {
return $.map(x, function(item) {
return {keyword: item['name']};
});
},
wildcard: "%compquery"
}
});
// Initialize Typeahead with Parameters
my_Suggestion_class.initialize();
var typeahead_elem = $('.typeahead');
typeahead_elem.typeahead({
hint: false,
highlight: true,
minLength: 3
},
{
// `ttAdapter` wraps the suggestion engine in an adapter that
// is compatible with the typeahead jQuery plugin
name: 'results',
displayKey: 'keyword',
source: my_Suggestion_class.ttAdapter(),
templates: {
empty: 'No Results'
}
});
});
Here is the HTML:
<div class="iner-sub-header" style="border-bottom: 1px solid #ccc;">
<div class="row" style = "background-color: white;">
<div class="col-md-12 heading">
<div id = "results" class="col-md-12 col-xs-12 results">
<span class="glyphicon glyphicon-search span-search" aria-hidden="true"></span>
<input type="search" class="typeahead custom-input-padding" placeholder="Search Company" id="keyword" onselect="setCompany();">
<button class="btn go-btn" id="go" onclick="setCompany()">SEARCH</button>
</div>
</div>
</div>
</div>
I want to make sure that the button that will trigger setCompany() funtion is disabled until the user selects something from the dropdown that is generated by Typeahead.
Can anyone please help me out?
Try
html
<button class="btn go-btn" id="go" onclick="setCompany()" disabled="true">SEARCH</button>
js
typeahead_elem.bind("typeahead:select", function(ev, suggestion) {
$("#go").prop("disabled", false);
});
See disabled , typeahead.js - Custom Events
This made it work for me. Now its working perfectly.
$(document).ready(function() {
//Set up "Bloodhound" Options
var my_Suggestion_class = new Bloodhound({
datumTokenizer: Bloodhound.tokenizers.obj.whitespace('keyword'),
queryTokenizer: Bloodhound.tokenizers.whitespace,
remote: {
url: "{{ URL::to('user/company/%compquery') }}",
filter: function(x) {
return $.map(x, function(item) {
return {keyword: item['name']};
});
},
wildcard: "%compquery"
}
});
// Initialize Typeahead with Parameters
my_Suggestion_class.initialize();
var typeahead_elem = $('.typeahead');
typeahead_elem.typeahead({
hint: false,
highlight: true,
minLength: 3
},
{
// `ttAdapter` wraps the suggestion engine in an adapter that
// is compatible with the typeahead jQuery plugin
name: 'results',
displayKey: 'keyword',
source: my_Suggestion_class.ttAdapter(),
templates: {
empty: 'No Results'
}
}).on("typeahead:selected typeahead:autocompleted", function(ev, my_Suggestion_class) {
$("#go").prop("disabled", false);
});
});
I wanted a way to re-disable the button if the button if the textbox's content changes and isn't a typeahead selected value. On typeahead:select I store the display text. On every key up I ensure the text still matches the stored variable. Otherwise I disable the button again.
this.searchbox = $('.js-patient-search');
this.searchbox.typeahead({
hint: true
}, {
source: Bloodhound,
display: function(obj) {
return obj.first_name + ' ' + obj.last_name;
}
});
this.searchbox.on('typeahead:select', (function(_this) {
return function(e, suggestion) {
_this.displayName = _this.searchbox.val();
return $('.js-add-encounter').prop('disabled', false);
};
})(this));
return this.searchbox.keyup((function(_this) {
return function(e) {
if (_this.searchbox.val() !== _this.displayName) {
return $('.js-add-encounter').prop('disabled', true);
}
};
})(this));
NOTE: This is parsed coffeescript but I think it should be fairly clear what's going on.

PHP and JQuery Variables in CodeIgniter

I was wondering if someone could explain me to the best way to go about this situation.
I have a sidebar that is populated with Li Elements from a foreach loop, that works fine.
Each element has an link that when clicked triggers a Jquery UI Dialog in which there is a text field to add a note and press Submit or cancel, this opens fine, submits fine.
I can't figure out how to retrieve say the link tag's id value and the dialogs
textarea value to submit them to the DB, so the DB is getting populated with 0's, from within the $.ajax Function, I'm sure it can be done and I'm sure I could hack it working but I want to know the right way to do it. Below is my attempt.
The JS
<script>
$(document).ready(function(){
var note;
$("#dialog").dialog({ autoOpen: false,
buttons:{"Add Note": function() {
$.ajax({
url:"<?php echo base_url();?>PropertyAdmin/addNoteToProperty",
data: {name: '20', value: note},
success:function(result){
alert("added");
},
error: function(result){
alert("fail");
},
cache : false
});
},
Cancel: function() {
$( this ).dialog( "close" );
}
},
});
$(".clickable").click(function (e) {
// open and move the dialog
$("#dialog").dialog('option', 'position',[e.clientX+100,e.clientY]).dialog("open");
var element = $(this).find("#prop_note");
note = element.attr("value");
var myTag = $(this).attr('name');
return false;
})
})
</script>
The Dialog
<div id="dialog" title="Add Note">
<div>
<?php $attributes = array('role' => 'form'); echo form_open('PropertyAdmin/addProperty', $attributes); ?>
<div class="form-group">
<label for="prop_note" class="control-label">Note :</label>
<textarea id="prop_note" class="form-control" rows="3" name="prop_note"></textarea>
</div>
</form>
</div>
</div>
The CONTROLLER Function
function addNoteToProperty(){
$id = $this->input->post('name');
$note = $this->input->post('value');
$this->load->model('PropertyModel');
$this->PropertyModel->addNoteToProperty($id,$note);
}
The Model
function addNoteToProperty($propid, $note){
$data = array('prop_note'=> $note, 'prop_id' => $propid, 'prop_note_date' => now());
$this->db->insert('property_notes', $data);
}
One of my unparsed Li's
<li>Investment Properties
<ul>
<?php foreach($property as $row){ if($row['type_id'] != 1) { } else{ ?>
<li style="color: white" class="investmentitems inactive"><a id="<?php echo $row['id']; ?>" href="#"><?php echo $row['property_name'] ." ".$row['property_address1']; ?></a><?php echo anchor("FinancialInput/listproperty/".$row['id'],"Edit" ); ?><a class="clickable" href="" name="<?php echo $row['id']; ?>">Add Note</a></li>
<?php }} ?>
</ul>
</li>
Errors
PHP Error was encountered
Severity: Warning
Message: Missing argument 1 for PropertyAdmin::addNoteToProperty()
Filename: controllers/PropertyAdmin.php
Line Number: 44
A PHP Error was encountered
Severity: Warning
Message: Missing argument 2 for PropertyAdmin::addNoteToProperty()
Filename: controllers/PropertyAdmin.php
Line Number: 44
A PHP Error was encountered
Severity: Notice
Message: Undefined variable: id
Filename: controllers/PropertyAdmin.php
Line Number: 49
A PHP Error was encountered
Severity: Notice
Message: Undefined variable: note
Filename: controllers/PropertyAdmin.php
Line Number: 49
A Database Error Occurred
Error Number: 1048
Column 'prop_note' cannot be null
INSERT INTO `property_notes` (`prop_note`, `prop_id`, `prop_note_date`) VALUES (NULL, NULL, 1396465225)
Filename: E:\wamp\www\oak\system\database\DB_driver.php
I believe getting the name value of the a just involves defining your variable outside of the click
<script>
$(document).ready(function(){
var note;
var name; //ADDED HERE
$("#dialog").dialog({ autoOpen: false,
buttons:{"Add Note": function() {
$.ajax({
url:"<?php echo base_url();?>PropertyAdmin/addNoteToProperty",
data: {name: name, value: $(prop_note).val()},
success:function(result){
alert("added");
},
error: function(result){
alert("fail");
},
cache : false
});
},
Cancel: function() {
$( this ).dialog( "close" );
}
},
});
$(".clickable").click(function (e) {
// open and move the dialog
e.preventDefault();
$("#dialog").dialog('option', 'position',[e.clientX+100,e.clientY]).dialog("open");
name = $(this).attr('name'); //Changing the Value here
return false;
})
})
</script>
There you are defining the variable before the click event and changing it to the ID of the clickable link before sending it to the PHP controller in the AJAX request

jQuery Validate Plugin - How to create a simple custom rule?

How do you create a simple, custom rule using the jQuery Validate plugin (using addMethod) that doesn't use a regex?
For example, what function would create a rule that validates only if at least one of a group of checkboxes is checked?
You can create a simple rule by doing something like this:
jQuery.validator.addMethod("greaterThanZero", function(value, element) {
return this.optional(element) || (parseFloat(value) > 0);
}, "* Amount must be greater than zero");
And then applying this like so:
$('validatorElement').validate({
rules : {
amount : { greaterThanZero : true }
}
});
Just change the contents of the 'addMethod' to validate your checkboxes.
$(document).ready(function(){
var response;
$.validator.addMethod(
"uniqueUserName",
function(value, element) {
$.ajax({
type: "POST",
url: "http://"+location.host+"/checkUser.php",
data: "checkUsername="+value,
dataType:"html",
success: function(msg)
{
//If username exists, set response to true
response = ( msg == 'true' ) ? true : false;
}
});
return response;
},
"Username is Already Taken"
);
$("#regFormPart1").validate({
username: {
required: true,
minlength: 8,
uniqueUserName: true
},
messages: {
username: {
required: "Username is required",
minlength: "Username must be at least 8 characters",
uniqueUserName: "This Username is taken already"
}
}
});
});
// add a method. calls one built-in method, too.
jQuery.validator.addMethod("optdate", function(value, element) {
return jQuery.validator.methods['date'].call(
this,value,element
)||value==("0000/00/00");
}, "Please enter a valid date."
);
// connect it to a css class
jQuery.validator.addClassRules({
optdate : { optdate : true }
});
Custom Rule and data attribute
You are able to create a custom rule and attach it to an element using the data attribute using the syntax data-rule-rulename="true";
So to check if at least one of a group of checkboxes is checked:
data-rule-oneormorechecked
<input type="checkbox" name="colours[]" value="red" data-rule-oneormorechecked="true" />
addMethod
$.validator.addMethod("oneormorechecked", function(value, element) {
return $('input[name="' + element.name + '"]:checked').length > 0;
}, "Atleast 1 must be selected");
And you can also override the message of a rule (ie: Atleast 1 must be selected) by using the syntax data-msg-rulename="my new message".
NOTE
If you use the data-rule-rulename method then you will need to make sure the rule name is all lowercase. This is because the jQuery validation function dataRules applies .toLowerCase() to compare and the HTML5 spec does not allow uppercase.
Working Example
$.validator.addMethod("oneormorechecked", function(value, element) {
return $('input[name="' + element.name + '"]:checked').length > 0;
}, "Atleast 1 must be selected");
$('.validate').validate();
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.14.0/jquery.validate.min.js"></script>
<form class="validate">
red<input type="checkbox" name="colours[]" value="red" data-rule-oneormorechecked="true" data-msg-oneormorechecked="Check one or more!" /><br/>
blue<input type="checkbox" name="colours[]" value="blue" /><br/>
green<input type="checkbox" name="colours[]" value="green" /><br/>
<input type="submit" value="submit"/>
</form>
Thanks, it worked!
Here's the final code:
$.validator.addMethod("greaterThanZero", function(value, element) {
var the_list_array = $("#some_form .super_item:checked");
return the_list_array.length > 0;
}, "* Please check at least one check box");
You can add a custom rule like this:
$.validator.addMethod(
'booleanRequired',
function (value, element, requiredValue) {
return value === requiredValue;
},
'Please check your input.'
);
And add it as a rule like this:
PhoneToggle: {
booleanRequired: 'on'
}
For this case: user signup form, user must choose a username that is not taken.
This means we have to create a customized validation rule, which will send async http request with remote server.
create a input element in your html:
<input name="user_name" type="text" >
declare your form validation rules:
$("form").validate({
rules: {
'user_name': {
// here jquery validate will start a GET request, to
// /interface/users/is_username_valid?user_name=<input_value>
// the response should be "raw text", with content "true" or "false" only
remote: '/interface/users/is_username_valid'
},
},
the remote code should be like:
class Interface::UsersController < ActionController::Base
def is_username_valid
render :text => !User.exists?(:user_name => params[:user_name])
end
end
Step 1 Included the cdn like
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.validate/1.11.1/jquery.validate.min.js"></script>
Step 2 Code Like
$(document).ready(function(){
$("#submit").click(function () {
$('#myform').validate({ // initialize the plugin
rules: {
id: {
required: true,
email: true
},
password: {
required: true,
minlength: 1
}
},
messages: {
id: {
required: "Enter Email Id"
},
password: {
required: "Enter Email Password"
}
},
submitHandler: function (form) { // for demo
alert('valid form submitted'); // for demo
return false; // for demo
}
});
}):
});

Categories

Resources