Hello I want to know how to make a loop so that my js is through an id because I have an email id for 2 fields for 2 different forms
I would then be able to choose when I click on the id of my form right that displays the error only on the right form and vice versa
My code :
<script type="text/javascript">
$(document).ready(function(){
$("input#id_st-courriel").focusout(checkEmailField);
});
function checkEmailField() {
$fieldValue = $("input#id_st-courriel").val();
$.ajax({
url: '/ajax/checkEmailField',
data: ({
value: $fieldValue
}),
type: 'GET',
success: function($data, $textStatus, $XMLHttpRequest) {
if ($data != '') {
$("input#id_st-courriel").parent().prev('errorlist').remove();
$("input#id_st-courriel").parent().before($data);
}
}
})
}
</script>
I have an id : id_st-courriel
and an other id for my second formulaire : id_em-courriel
For the moment I're the error display on my first form with the id: id_st-courriel
Edit :
I have a second problem
My views.py
def ajax_check_email_field(request):
form = LoginForm(request.POST)
HTML_to_return = ''
if 'value' in request.GET:
field = forms.EmailField()
try:
field.clean(request.GET['value'])
except exceptions.ValidationError as ve:
HTML_to_return = '<ul class="errorList">'
for message in ve.messages:
HTML_to_return += '<li>' + message + '</li>'
HTML_to_return += '</ul>'
return HttpResponse(HTML_to_return)
<ul>
<li>foo</li>
<li>bar</li>
</ul>
//You can select the list items and iterate across them:
$( "li" ).each(function( index ) {
console.log( index + ": " + $( this ).text() );
});
You can make some minor changes to do it like
Update the selector to select both the fields - either use a class selector after add a common class to both the fields or use multiple selector syntax to select both the elements using their id
In the event handler dynamically select the current element by using this reference - in the event handler this will refer to the input element which triggered the event
So
$(document).ready(function() {
$("#id_st-courriel, #id_em-courriel").focusout(checkEmailField); //you can simplify the selector if you can add a common class to both these fields and then use the class selector to add the event handler
});
function checkEmailField() {
var $fileld = $(this);
var $fieldValue = $fileld.val();
$.ajax({
url: '/ajax/checkEmailField',
data: ({
value: $fieldValue
}),
type: 'GET',
success: function($data, $textStatus, $XMLHttpRequest) {
$fileld.parent().prev('.errorlist').remove();//may be .errorlist if it is a class
if ($data != '') {
$fileld.parent().before($data);
}
}
})
}
You could pass $(this) to you function checkEmailField to refer to the current focused out field, try :
$(document).ready(function(){
$("input#id_st-courriel, input#id_em-courriel").focusout(function(){
checkEmailField($(this));
});
});
function checkEmailField(_this) {
$fieldValue = _this.val();
$.ajax({
url: '/ajax/checkEmailField',
data: ({
value: $fieldValue
}),
type: 'GET',
success: function($data, $textStatus, $XMLHttpRequest) {
if ($data != '') {
$(_this).parent().prev('errorlist').remove();
$(_this).parent().before($data);
}
}
})
}
Hope this helps.
Related
I'm developing a ps module which let you classify the product attachment in categories an display them in the front product page.
I'm using a draggable list with the attachment, and when you drop them to the category it turns to an option tag, each category has a select tag where to drop the attachment.
I want to save the attachments and the category where they was dropped, so I thought make an ajax call to bring the data to my module class but I'm new with ajax and cant approach it.
this is what I've made:
the js code (inside the proper .tpl):
<script>
$( ".droptrue" ).droppable({
drop: function( event, ui ) {
//add <option> tag when an attachment is dropped to category's select
$(event.target).append('<option value="' + ui.draggable.attr('id') + '" selected>'+ui.draggable.text()+'</option>');
//remove the <li> wich contained the attachment data
ui.draggable.fadeOut("slow").remove();
var val = $('#categoryAttachmentArr').val();
//var tab = val.split(',');
//for (var i=0; i < tab.length; i++)
//if (tab[i] == $(this).val())
// return false;
//create an array with the next format: 'id_category(1)'-'id_attachment(1)','id_category(2)'-'id_attachment(2)'[....]
//the comma will be the main character that will be splitted
$('#categoryAttachmentArr').val(val + ui.doppable.attr('id') + '-' + ui.draggable.attr('id') +',');
}
});
$('#submitAddProduct').click(function(e){
$.ajax({
type: 'POST',
url: baseDir + 'modules/adjuntos/classes/CategoryAttachment.php',
data: {
ajax: true,
action: \'CategoryArray\',
cat_array: $('#categoryAttachmentArray').val(),
}
dataType: 'json',
success: function(json) {
console.log($('#categoryAttachmentArray').val());
}
});
})
$( ".ui-state-default" ).draggable({
revert: "valid",
});
</script>
And my class:
class CategoryAttachment extends Objectmodel
{
//other functions
public function ajaxProcessCategoryArray()
{
$CategoryAttachmentArr = Tools::getValue('cat_array')
}
}
you can't connect directly to any class. you have to use the controller to do this.
Ajax send data to controller
Controller save data using class
Controller return result to browser (javascript)
Finaly I got the solution, maybe one of you guys will have this problem in the future.
My code in the .tpl:
$( ".ui-state-default" ).draggable();
$( ".droptrue" ).droppable({
drop: function( event, ui ) {
//add <option> tag when an attachment is dropped to category's select
$(event.target).append('<option value="' + ui.draggable.attr('id') + '" selected>'+ui.draggable.text()+'</option>');
$('#selectAttachment1').append('<option value="' + ui.draggable.attr('id') + '" selected>'+ui.draggable.text()+'</option>')
//remove the <li> wich contained the attachment data
ui.draggable.fadeOut("slow").remove();
var val = $('#categoryAttachmentArr').val();
//make a serialize() type array
$('#categoryAttachmentArr').val(val + $(this).attr('id') + "=" + ui.draggable.attr('id') +"&");
var value = $('#arrayAttachments').val();
var tab = value.split(',');
for (var i=0; i < tab.length; i++)
if (tab[i] == ui.draggable.attr('id')){
return false;
}
$('#arrayAttachments').val(value+ui.draggable.attr('id')+',');
}
});
$('#submitCategories').click(function(e){
var array = $('#categoryAttachmentArr').val()
$.ajax({
url: '../modules/adjuntos/ajax-call.php',
data: {
action: 'handlearray',
token:new Date().getTime(),
cat: array
},
method: 'POST',
success:function(data){
$('#result').html(data);
}
});
});
the ajax call goes to my ajax-call.php file:
<?php
//load ps config
require_once(dirname(__FILE__).'../../../config/config.inc.php');
require_once(dirname(__FILE__).'../../../init.php');
require_once('adjuntos.php');
//adjuntos.php is the name of my module main file
if(Tools::getIsset('token') && Tools::getIsset('action'))
{
$mp = new Adjuntos;
echo $mp->handleArray();
}
The handleArray function in my module main file:(it make a call to my custom class)
public static function handleArray()
{
$html = '';
$array = Tools::getValue('cat');
$arrayExplode = explode("&", $array);
foreach($arrayExplode as $value)
{
$finalArr = explode("=", $value);
if (!CategoryAttachment::postProcess($finalArr))
{
$html .= '<p style="color:red;>Fallo</p>"';
}
}
$html .= '<p style="color:green;>Correcto</p>"';
return $html;
}
The function in my custom class:
public static function postProcess($finalArr)
{
return Db::getInstance()->execute(
'UPDATE ps_attachment SET id_category = '.$finalArr[0].' WHERE id_attachment = '.$finalArr[1]
);
}//end
This way is working like a charm, and make the code more scalable
I have created this code to filter the search by checkbox but I haven't find a final solution..!
This doesn't work when for example I click on 'All Colors' or 'All Brand'..
And not work when I recheck the checkbox because I haven't idea..!
This is a search to filter the results in eBay style, with combobox and much checkbox.. I want this to filter without the reload of the page..
This is the partial code..
function create_query(add){
var query = "SELECT * FROM computers WHERE 1 = 1 "+add+" ORDER BY " + ($("#ordine option:selected").val()) + " LIMIT " + ($("#risultati option:selected").val());
$.ajax({
type: "POST",
url: "static/cerca_prodotti.php",
data: "query="+query,
dataType: "html",
success: function(risposta){
$("div#risultati").html(risposta);
},
error: function(){
alert("Chiamata fallita!!!");
}
})
}
$( "[type=checkbox]" ).change(function() {
text = $(this).parent().text();
gruppo = this.getAttribute("name");
if(this.checked) {
}
else {
create_query('AND '+gruppo+' NOT LIKE "'+text+'"')
}
});
$("#ordine").change(function() {
create_query();
});
$("#risultati").change(function() {
create_query();
});
I have a dropdown which gets its value from a model and is first populated. On click of that dropdown, I populate other values using AJAX. I am able to populate the dropdown but once I select an option from the dropdown, it gets reset to first value in the dropdown. What I want is the dropdown to populate once on click and then function like a normal dropdown. How do I put a condition for it?
This is the code for initially setting the dropdown value with the defined value 'field.Value'
ddlValue = "<option value="+field.Value+ " selected='selected'>" + field.Value+"</option>";
<td><select id='#String.Format("selValue{0}", field.Field)' class='ddlValue'>#Html.Raw(ddlValue)</select></td>
And this is the AJAX function which populates it.
$('body').on('click', '.ddlValue', function () {
var target = event.target.id;
var rowId = $('#' + target).closest("tr").prop("id");
var field = $('#' + rowId).find(".fieldvalue").html();
$.ajax({
cache: false,
url: '#Url.Action("PopulateDropdown", "AdvancedSearch")',
type: "POST",
data: { Field: field }
}).done(function (data) {
var listb = $('#' + target);
listb.empty();
$.each(data.value, function (index, value) {
listb.append($('<option>', {
value: value,
text: value
}, '<option/>'))
});
});
});
If you want the ajax population to happen only once, you need to remove the event listener after it has occurred. Something like so:
$('.ddlValue').on('click', function () {
$(this).off('click'); //This removes the event after it has happened once.
var target = event.target.id;
var rowId = $('#' + target).closest("tr").prop("id");
var field = $('#' + rowId).find(".fieldvalue").html();
$.ajax({
cache: false,
url: '#Url.Action("PopulateDropdown", "AdvancedSearch")',
type: "POST",
data: { Field: field }
}).done(function (data) {
var listb = $('#' + target);
listb.empty();
$.each(data.value, function (index, value) {
listb.append($('<option>', {
value: value,
text: value
}, '<option/>'))
});
});
});
Please note, the follow will not work:
$('body').on('click', '.ddlValue', function () {
$(this).off('click');
...
This seems like a silly way of doing this. You could do the same operation on loan without having any interaction with the user to populate the dropdown.
That being said to fix your solution simply add a global variable
$first = true
$('body').on('click', '.ddlValue', function () {
if($first) {
$first = false
var target = event.target.id;
var rowId = $('#' + target).closest("tr").prop("id");
var field = $('#' + rowId).find(".fieldvalue").html();
$.ajax({
cache: false,
url: '#Url.Action("PopulateDropdown", "AdvancedSearch")',
type: "POST",
data: { Field: field }
}).done(function (data) {
var listb = $('#' + target);
listb.empty();
$.each(data.value, function (index, value) {
listb.append($('<option>', {
value: value,
text: value
}, '<option/>'))
});
}
});
});
I have dropdown list of country suggestions and input above. When i click on one of them - AJAX should work(and it does) and add value to #msg_native. HTML:
echo '<div class="search_native"><input type="text" name="native_input" id="native"/>';
echo "<div id='output'></div></div>";
All JQUERY :
<script type="text/javascript">
$(document).ready(function() {
$("input").keyup(function(){
$array = ['usa','france','germany'];
$input_val = $("input[name='native_input']").val();
$('#output').text('')
r = new RegExp($input_val)
for (i = 0; i < $array.length; i++) {
if ($array[i].match(r)) {
$('#output').append('<p class="match">' + $array[i] + '</p>')
}
}
});
$(document).on('click', '.match', function(){
$value = $(this).text();
$('#native').val($value);
});
});
</script>
<script type="text/javascript">
$(function() {
$('#native').change(function() {
alert('cl');
$.ajax({
type: "POST",
url: "home.php",
dataType: 'json',
encode: true,
data: {native_input: $("input[name='native_input']").val()},
cache: false,
success: function(data){
alert(data);
$("#msg_native").after(data);
}});
return false;
});
});
</script>
The problem is that the value that gets posted is only what Ive typed myself, regardless on clicked element. But I want complete value- not only typed letters...so it firstly posts value and then 'finishes' the input (if clicked)
What can you practically advice to me?
data: {native_input: $value},
returns empty string
Some of this might be debatable but I put those in place for maintainability of the code and/or to match the most recent jQuery.
Only use one document ready handler (if possible)
Remove all the global objects (put var in front of them)
Use the native id when possible as fastest selector (not $("input[name='native_input']") for instance)
use this in the event handler, not the full selector (see next item)
If I enter "France" not "france" match does not work so need to case that input to equality var $input_val = $(this).val().toLowerCase();
You start with an empty field, might be good to show the match for that - simply trigger the keyup on startup to show all the array: }).trigger('keyup'); Now they are available for your clicking.
Attach the click handler on the wrapper for the "match" elements: $('#output').on('click', '.match', function() {
Use the promise form of the ajax .done(
Create a new custom event instead of the "change" on the native. We can then trigger that event as/when needed (the real issue you describe) Example: $('#native').trigger('myMatch'); and as I use it here:
trigger the event on a full match:
if (jQuery.inArray($input_val, $array) !== -1) {
$(this).trigger('myMatch');
}
Revised code:
$(document).ready(function() {
$("#native").on('keyup', function() {
var $array = ['usa', 'france', 'germany'];
var $input_val = $(this).val().toLowerCase();
$('#output').html('');
var r = new RegExp($input_val);
for (var i = 0; i < $array.length; i++) {
if ($array[i].match(r)) {
$('#output').append('<p class="match">' + $array[i] + '</p>');
}
}
// full match entered, trigger the match
if (jQuery.inArray($input_val, $array) !== -1) {
$(this).trigger('myMatch');
}
}).on('myMatch', function() {
alert('cl');
var nativeMatch = {
native_input: $("#native").val()
};
$.ajax({
type: "POST",
url: "home.php",
dataType: 'json',
encode: true,
data: nativeMatch,
cache: false
}).done(function(data) {
alert(data);
$("#msg_native").after(data);
});
return false;
}).trigger('keyup');
$('#output').on('click', '.match', function() {
var $value = $(this).text();
$('#native').val($value).trigger('myMatch');
});
});
I hope I can explain my issue clearly.
I am running a function to get values from a database using ajax, and adding each result as a row in a table. This is so the user can delete or edit any row they want. I'm adding IDs dynamically to the columns and also the edit and delete buttons which are generated. So it looks like this:
My code:
function getstationdata(){
var taildata1 = $('#tailnumber2').val();
var uid = $('#uid').val();
$.ajax({
// give your form the method POST
type: "POST",
// give your action attribute the value ajaxadd.php
url: "ajaxgetstationdata.php",
data: {tailnumber:taildata1, uid:uid},
dataType: 'json',
cache: false,
})
.success(function(response) {
// remove all errors
$('input').removeClass('error').next('.errormessage').html('');
// if there are no errors and there is a result
if(!response.errors && response.result) {
var trHTML = '';
$.each(response.result, function( index, value) {
trHTML += '<tr><td><input type="text" value="' + value[2] + '"></td><td><input type="text" class="weightinputclass"value="' + value[3] + '"></td><td><input type="text" class="arminputclass"value="' + value[4] + '"></td><td><input type="text" class="momentinputclass" value="' + value[5] + '"></td><td><button id="updatecgbtn" onclick="updatecg()"class="editbuttonclass">Edit</button></td><td><button id="deletecgbtn" class="deletebuttonclass"">Delete</button></td></tr>';
});
$('#mbtbody').html('');
$('#mbtbody').html(trHTML);
var ID = 0;
$('.weightinputclass').each(function() {
ID++;
$(this).attr('id', 'weightinputboxID'+ID);
});
var ID = 0;
$('.arminputclass').each(function() {
ID++;
$(this).attr('id', 'arminputboxID'+ID);
});
var ID = 0;
$('.momentinputclass').each(function() {
ID++;
$(this).attr('id', 'momentinputboxID'+ID);
});
var ID = 0;
$('.editbuttonclass').each(function() {
ID++;
$(this).attr('id', 'editbutton'+ID);
});
var ID = 0;
$('.deletebuttonclass').each(function() {
ID++;
$(this).attr('id', 'deletebutton'+ID);
});
} else {
// append the error to the form
$.each(response.errors, function( index, value) {
// add error classes
$('input[name*='+index+']').addClass('error').after('<div class="errormessage">'+value+'</div>')
});
}
});
}
The code I have when adding the info is in a form and it looks like this:
$('#addstations').on('submit', function(e){
e.preventDefault();
$.ajax({
type: $(this).attr('method'),
url: $(this).attr('action'),
data: $(this).serialize(),
dataType: 'json',
cache: false,
})
.success(function(response) {
$('input').removeClass('error').next('.errormessage').html('');
if(!response.errors && response.result) {
$.each(response.result, function( index, value) {
chartdata4=(tailnumber3.value)
});
} else {
// append the error to the form
$.each(response.errors, function( index, value) {
// add error classes
$('input[name*='+index+']').addClass('error').after('<div class="errormessage">'+value+'</div>')
});
}
});
});
I searched a bit on the internet and found out that I can't add a form inside my table for each row which would have been easy to do and I can reuse my code which I use when adding new info.
So, can someone please point me in the right direction?
Here is the direction you could go
$('#formTable').on('click',"button" function(e){
var $row = $(this).closest("tr"), $form = $("#addstations");
var data = {
passenger:$row.find("passengerClass").val(),
weight :$row.find("weightClass").val()
} // no comma on the last item
data["type"]=this.className=="deletebuttonclass"?"delete":"edit";
$.ajax({
type: $form.attr('method'),
url: $form.attr('action'),
dataType: 'json',
cache: false,
})
...
I assume that the problem is that you want to add a form as a child of a table / tbody element to wrap your row. You cannot do that and the browser will most likely strip the form tags, leaving you with nothing to serialize.
There are different solutions for that, for example:
Build the data object manually in javascript when a button on a row is clicked;
Use a non-form grid solution for your layout.
Add each row in its own table and have the form wrap that table
The third solution is a bit of a hack, I would use the first or the second myself.