Simplify jQuery code - slide and slideToggle - javascript

How can I simplify current JavaScript code? It looks too complicated.
// Data from AJAX response
var errorsJSON = {
"name-pl": ["The name-pl field is required."],
"name-en": ["The name-en field is required."]
}
var errorString = $(this).data('validate-multiple');
var errorNamesArray = errorString.split(", ");
var ul = $('<ul class="list-unstyled">');
$.each(errorNamesArray, function(key, value) {
if (errorsJSON.hasOwnProperty(value)) {
ul.append(`<li><span class="help-block">${errorsJSON[value]}</span></li>`);
}
});
if (! $(this).is(':visible') && ul.children('li').length > 0) {
$(this).find('div.controls').empty().append(ul);
$(this).slideDown(500);
} else if ($(this).is(':visible') && ul.children('li').length === 0) {
$(this).slideUp(500);
} else if ($(this).is(':visible') && ul.children('li').length > 0) {
$(this).slideUp(500, function() {
$(this).find('div.controls').empty().append(ul);
$(this).slideDown(500);
});
}
Here I pasted both html and js code http://jsfiddle.net/ecLjnnhm/
I would like to point out that errorsJSON can change and depends what user put in the input fields.

Readability: Use variables to store the conditions of your if statements instead of lengthy declarations each time.
Efficiency: Cache $(this) as a variable so jQuery only has to do the work once.
Personal preference: I'd suggest prefacing any jQuery object variables (like ul in your case) with a $ to indicate that they're a jQuery object.
// Data from AJAX response
var errorsJSON = {
"name-pl": ["The name-pl field is required."],
"name-en": ["The name-en field is required."]
}
var errorString = $(this).data('validate-multiple');
var errorNamesArray = errorString.split(", ");
var $ul = $('<ul class="list-unstyled">');
var $t = $(this);
var isVisible = $t.is(':visible');
var hasErrors = false;
$.each(errorNamesArray, function(key, value) {
if (errorsJSON.hasOwnProperty(value)) {
$ul.append(`<li><span class="help-block">${errorsJSON[value]}</span></li>`);
hasErrors = true;
}
});
if (!isVisible && hasErrors) {
$t.find('div.controls').empty().append(ul);
$t.slideDown(500);
} else if (isVisible && !hasErrors) {
$t.slideUp(500);
} else if (isVisible && hasErrors) {
$t.slideUp(500, function() {
$t.find('div.controls').empty().append(ul);
$t.slideDown(500);
});
}

Related

How to display default message when no results found on Jquery search filter

I'm currently building a page where a search field acts as a filter. It works perfectly fine and shows data against related word, but there is one issue that I'd like to solve. When the entered string or other words is not found in all the existing the page remains blank.
How could I display a default message on my page when no results are found by the filter? Something like a simple <p> explaining that no results were found.
The idea is to display it only once as long as the string is not found.
$('#search_field').on('keyup', function() {
var value = $(this).val();
var patt = new RegExp(value, "i");
$('#userFind').find('tr').each(function() {
var $table = $(this);
if (!($table.find('td').text().search(patt) >= 0)) {
$table.not('.t_head').hide();
}
if (($table.find('td').text().search(patt) >= 0)) {
$(this).show();
}
});
});
This is untested since you haven't provided any table to your question.
After you have looped though all tr, then check if any is visible. If not then append a tr with custom message and remove it and new search.
$('#search_field').on('keyup', function() {
var value = $(this).val();
// console.log(value);
var patt = new RegExp(value, "i");
$(".noRecord").remove();
$('#userFind').find('tr').each(function() {
var $table = $(this);
if (!($table.find('td').text().search(patt) >= 0)) {
$table.not('.t_head').hide();
} else {
$(this).show();
}
});
if ($('#userFind tr:visible').length == 0) {
$('#userFind tbody').append("<tr class='noRecord'><td>No records found.</td></tr>")
}
});
Assuming you have a div:
<div id="zeroHits">no results were found</div>
You can hide/show the #zeroHits div as follows:
$('#search_field').on('keyup', function() {
var value = $(this).val();
var patt = new RegExp(value, "i");
var zeroHits = true;
$('#userFind').find('tr').each(function() {
var $table = $(this);
if (!($table.find('td').text().search(patt) >= 0)) {
$table.not('.t_head').hide();
}
if (($table.find('td').text().search(patt) >= 0)) {
$(this).show();
zeroHits = false;
}
});
if(zeroHits) {
$('#zeroHits').show();
} else {
$('#zeroHits').hide();
}
});
Try this untested code
post your HTML and I can test
const $rows = $('#userFind tbody tr'); // only tbody rows
$('#search_field').on('keyup', function() {
var value = $(this).val();
// console.log(value);
var patt = new RegExp(value, "i");
$rows.each(function() {
const found = $(this).find('td').filter(function() {
return $(this).text().search(patt) != -1
}).length > 0
$(this).toggle(found);
});
$("#notFound").toggle($rows.filter(":visible").length === 0)
});

How to put a condition in jQuery's map function?

I am trying to put a condition in jQuery's map function. My issue is that I don't want the same number in the map function value. When it is the same I want to display an alert box. My map function code is like this:
var rankbox= $('input[type=text][class = cate_rank]').map(function() {
return this.value;
}).get();
If I get a value like 1,2,3,4,5 it's ok, but if I get a value like 1,2,3,2,5, I want to display an alert box. Is it possible?
How to put a condition in jQuery's map function?
function change_rank() {
var rankbox= $('input[type=text][class = cate_rank]').map(function() {
if() {
} else { }
return this.value;
}).get();
var vals = []
$('input[type=text][class = cate_rank]').each(function(){
if($(this).val() && (typeof vals[$(this).val()] == 'undefined')){
vals[$(this).val()] = 1;
var last_val = $(this).val();
}else if($(this).val() && (typeof last_val != 'undefined') && parseInt(last_val) > parseInt($(this).val())){
alert('Whooah! Something went terribly wrong! Inputs don\'t have values ordered incrementally!');
}else{
alert('Whooah! Something went wrong! We got two inputes with same value!');
}
});
Check this,
var rankbox= $(".test").map(function() {
return this.value;
}).get();
var sorted_arr = rankbox.slice().sort();
var results = [];
for (var i = 0; i < rankbox.length - 1; i++) {
if (sorted_arr[i + 1] == sorted_arr[i]) {
results.push(sorted_arr[i]);
}
}
var rankbox= $(".test").map(function() {
if($.inArray(this.value, results) > -1){
alert(this.value+" is duplicate");
}
return this.value;
}).get();
I took reference of this link
If you are Looking to check dup you can try this:
var x=[1,2,3,2,5]
var has=!x.every(function(v,i) {
return x.indexOf(v) == i;
});
console.log(has);//true means dup found else not found.
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
you can try with a object. check this:
function change_rank() {
var temp = {};
var rankbox= $('input[type=text][class = cate_rank]').map(function() {
if(temp[this.value]==undefined) {
temp[this.value] = this.value;
} else {
alert('the same value');
}
return this.value;
}).get();

Any better way to declare variables avoiding repetition of code?

Here is the js code which i am trying to use. I don't like the same code repeating again and I couldn't help myself to do this in a better way.
$(function(){
$('[data-behavior~=quick-reject]').on("click", function(){
var form = $(this).closest("[data-behavior~=modal-footer]").find("form");
var some_action = form.find("#some_actions").val();
var some_reasons = form.find("[data-behavior~=escalation-reason-select-box]");
if((some_reasons.val() === "") && ( some_action === "reject")){
var errorReason = "Please select a reason";
form.addClass("error").
parent().
find("div.error").
html(errorReason);
}else{
form.submit();
}
});
$(document).on("change", "#some_actions", function (){
var form = $(this).closest("[data-behavior~=modal-footer]").find("form");
var some_action = form.find("#some_actions").val();
var some_reasons = form.find("[data-behavior~=escalation-reason-select-box]");
if(some_action === "verify"){
some_reasons.hide();
}else{
some_reasons.show();
}
});
});
You could just make a little utility function, something like.
function getVars(that) {
var form = $(that).closest("[data-behavior~=modal-footer]").find("form");
return {
form: form,
some_action: form.find("#some_actions").val(),
some_reasons: form.find("[data-behavior~=escalation-reason-select-box]")
}
}
$('[data-behavior~=quick-reject]').on("click", function(){
var v = getVars(this);
if((v.some_reasons.val() === "") && ( v.some_action === "reject")){
var errorReason = "Please select a reason";
v.form.addClass("error").
parent().
find("div.error").
html(errorReason);
}else{
v.form.submit();
}
});
$(document).on("change", "#some_actions", function (){
var v = getVars(this);
if(v.some_action === "verify"){
v.some_reasons.hide();
}else{
v.some_reasons.show();
}
});

Send single CheckBox value in array to server

I am having multiple checkboxes on form and I am going to submit the form.
$.fn.serializeObject = function () {
'use strict';
debugger;
var result = {};
var extend = function (i, element) {
var node = result[element.name];
// If node with same name exists already, need to convert it to an array as it
// is a multi-value field (i.e., checkboxes)
if ('undefined' !== typeof node && node !== null) {
if ($.isArray(node)) {
node.push(element.value);
} else {
result[element.name] = [node, element.value];
}
} else {
result[element.name] = element.value;
}
};
$.each(this.serializeArray(), extend);
return result;
};
and code is like
var that = $(this);
var temp = $(JSON.stringify());
form_data = that.serializeObject(temp);
form_data = JSON.stringify(form_data);
everything works fine but if I single select a checkbox then the value is like
"checkboxName":"value1"
and if I select multiple values of checkboc then the vale is like
"checkboxName":["value1","value2","value3"]
I want that a single value should also be selected in array format that is
"checkboxName":["value1"]
Thanks in advance.
If you try:
$.fn.serializeObject = function () {
'use strict';
debugger;
var result = {};
var extend = function (i, element) {
var node = result[element.name];
// If node with same name exists already, need to convert it to an array as it
// is a multi-value field (i.e., checkboxes)
if ('undefined' !== typeof node && node !== null) {
if ($.isArray(node)) {
node.push(element.value);
} else {
result[element.name] = [node, element.value];
}
} else {
//Here you are the checkbox condition
if(element.tagName == "INPUT" && element.getAttribute("type") == "checkbox") {
result [element.name] = [element.value];
} else {
result[element.name] = element.value;
}
}
};
$.each(this.serializeArray(), extend);
return result;
};

how to find the string element that match with string only from starting?

In my application i want display the suggestion names based on the character that user types in that input box. I get the user input using keyup event and i have a array of names from that i want to select the names that matches with the user input only from the starting letters. For Example if the user types A the suggestion show the name start with A,(For Ro-Root Valuation) How to do this?
$( document ).ready(function() {
var usernames = ["Abisi","Bentaven", "Root Valuation", "Leidos Health", "Visante", "vendor1", "yest1", "example"];
var displayname = [];
$('#input-text').keyup(function(event){
var $textValue = $(this).val();
jQuery.each( usernames,function( i, val ) {
*** find that matching name ***
if($textValue == val){
displayname.push(val);
}
});
});
You can try something like this:
JSFIDDLE: http://jsfiddle.net/bqkobo79/1/
var length= $textValue.length;
displayname=jQuery.grep(usernames, function( element, i ) {
if(element.toLowerCase().substr(0,length)===$textValue.toLowerCase())
return element;
});
You have to make sure that the text typed matches the name:
$textValue = $textValue.toLowerCase();
val = val.toLowerCase();
var is_matched = ($textValue.substr(0, ($textValue.length)) == val.substr(0, ($textValue.length)))
To make sure that you get suggestions you need to send after checking if it is true:
if (is_matched == true) {
displayname.push(val);
} else {
return false;
}
Final Code:
$( document ).ready(function() {
var usernames = ["Abisi","Bentaven", "Root Valuation", "Leidos Health", "Visante", "vendor1", "yest1", "example"];
var displayname = [];
$('#input-text').keyup(function (event) {
var $textValue = $(this).val();
jQuery.each(usernames, function (i, val) {
$textValue = $textValue.toLowerCase();
val = val.toLowerCase();
var is_matched = ($textValue.substr(0, ($textValue.length)) == val.substr(0, ($textValue.length)))
if (is_matched == true) {
displayname.push(val);
} else {
return false;
}
});
});
String.prototype.indexOf can tell you if a string contain another string and the index of the first match of that substring.
"Abisi".indexOf("A") == 0
In your case you can use it to retrieve a set of strings that start with the value of the text input
var usernames = ["Abisi","Bentaven", "Root Valuation", "Leidos Health", "Visante", "vendor1", "yest1", "example"];
var displayname = [];
$('#input-text').keyup(function(event){
var $textValue = $(this).val();
displayname = [];
if ($textValue.length > 0){
jQuery.each( usernames,function( i, val ) {
if(val.indexOf($textValue) === 0){
displayname.push(val);
}
});
}
console.log(displayname);
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
<input type="text" id="input-text"/>

Categories

Resources