Repeater issue/problm - javascript

We are trying to use this repeater:
https://www.jqueryscript.net/form/Form-Fields-Repeater.html
It seems there is problem if you look at the demo.
https://www.jqueryscript.net/demo/Form-Fields-Repeater/
Try on demo to add for example four groups.(press three times add button).
Then remove all four groups by pressing Delete button.
Then press add again to add a new group.
If you inspect the name element it is:
The problem is with test[4]name. Normally it should be test[0]name.
It seems that when you delete element does not delete the counting.
So if you play a little bit with delete/add buttons counting is wrong.
Javascript of this is :
jQuery.fn.extend({
createRepeater: function () {
var addItem = function (items, key) {
var itemContent = items;
var group = itemContent.data("group");
var item = itemContent;
var input = item.find('input,select');
input.each(function (index, el) {
var attrName = $(el).data('name');
var skipName = $(el).data('skip-name');
if (skipName != true) {
$(el).attr("name", group + "[" + key + "]" + attrName);
} else {
if (attrName != 'undefined') {
$(el).attr("name", attrName);
}
}
})
var itemClone = items;
$("<div class='items'>" + itemClone.html() + "<div/>").appendTo(repeater);
};
/* find elements */
var repeater = this;
var items = repeater.find(".items");
var key = 0;
var addButton = repeater.find('.repeater-add-btn');
var newItem = items;
if (key == 0) {
items.remove();
addItem(newItem, key);
}
/* handle click and add items */
addButton.on("click", function () {
key++;
addItem(newItem, key);
});
}
});
Have anyone ever used this repeater? or have a version of this that works correct?

Related

Delete duplicate object(JSON) nodes - JavaScript

I have a JSON string:
var jsn = '{"header-v1":{"archives":{"is_author":"all"}},"header-v4":{"archives":{"is_author":"all"}}}';
This object is constantly updated and I want to remove duplicate values. For example, if it is:
var jsn = '{"header-v4":{"archives":{"is_author":"all"}}}';
And if the new rule set which should be added will be equal to
"header-v1":{"archives":{"is_author":"all"}}
then I want to remove "header-v4":{"archives":{"is_author":"all"}} from there, because there is a duplicate of {"archives":{"is_author":"all"}}.
Is that even possible with JavaScript?
var result = [];
$.each(subservices, function (i, e) {
var matchingItems = $.grep(result, function (item) {
return item.name === e.name && item.label === e.label;
});
if (matchingItems.length === 0){
result.push(e);
}
});
//displays result [{"name":"hello","label":"world"},{"name":"abc","label":"xyz"}]
alert(JSON.stringify(result));
JS fiddel
http://jsfiddle.net/defujjhp/
Maybe something like this you can do
var jsn = '{"header-v4":{"archives":{"is_author":"all"}}}';
var jsonObject = JSON.parse(jsn);
var newJsn = '{header-v1":{"archives":{"is_author":"all"}}}';
var newJsonObject = JSON.parse(newJsn);
var matchingKey = [];
Object.keys(newJsonObject).forEach(key => {
Object.keys(jsonObject).forEach(nkey => {
if(newJsonObject[key].toString() === jsonObject[nkey].toString()) {
matchingKey.push(nkey);
}
});
});
matchingKey.forEach(mkey => {
delete jsonObject[mkey];
});

show and hide element options for my case

I'm having a little bit of difficulties when I need to hide an element on a page.
I am using this script to create my multiselect dropdown element which is the main controller for the elements on the page (http://wenzhixin.net.cn/p/multiple-select/docs/#the-basics1).
It returns an array of selected elements and my elements have their showIfValues set in a JSON file.
My functions should do this:
I get selected values from the dropdown element in array (ex. ["value1", "value2"]).
Going through all the elements and find where in showIfValue is any value from the array above, show it
In the change of the multiselect dropdown, if any of the fields are removed, remove the element but leave the rest on the page.
Legend in showHideHendler function:
inp is the id of the input field I would like to show on the page
controlInp is the control input (in this case multiselect dropdown)
value is the array populated with the showIfValues from JSON file of the elements
So far I made it here. These are the things I have implemented.
function diffArray(arr1, arr2) {
return arr1.concat(arr2).filter(function (val) {
if (!(arr1.includes(val) && arr2.includes(val)))
return val;
});
}
function getSelectedValues(controlInput){
if($('#' + controlInput).attr("multiple") === "multiple"){
// var selectValues = $('#' + controlInput).multipleSelect("getSelects");
var selectValues = [];
if($('#' + controlInput).multipleSelect("getSelects") != null) {
selectValues = $('#' + controlInput).multipleSelect("getSelects");
}
return selectValues;
}
}
var multipleShowHideHandler = (function() {
var selectedValues = [];
function setSelectedValues(value){
selectedValues.push(value);
}
function overrideSelected(value){
selectedValues = value;
}
function getSelectedValues(){
return selectedValues;
}
return {
setSelectedValues: setSelectedValues,
getSelectedValues: getSelectedValues,
overrideSelected: overrideSelected
}
})();
function showHideHandler(inp, controlInp, value) {
if (!$('#' + controlInp).is(':checkbox') && !($.isArray(value))) {
value = $.makeArray(value);
}
var selectedValues = getSelectedValues(controlInp);
if(($('#' + controlInp).attr("multiple") === "multiple") && !$.isEmptyObject(selectedValues)){
$('#' + controlInp).change(function(){
var oldState = multipleShowHideHandler.getSelectedValues();
var selectedValues = getSelectedValues(controlInp);
if($.isEmptyObject(oldState)){
$.each(selectedValues, function(i, val){
multipleShowHideHandler.setSelectedValues(val);
});
}
var differentArray = diffArray(selectedValues, oldState);
if(!$.isEmptyObject(differentArray)){
if(($.inArray(differentArray[0], value) !== -1)){
$('#' + inp + 'Container').hide();
}
multipleShowHideHandler.overrideSelected(selectedValues);
}
//check diff
/*if(!$.isEmptyObject(selectedValues) && !$.isEmptyObject(oldState)){
var diff = diffArray(selectedValues, oldState);
}*/
$.each(selectedValues, function(i, val){
if(($.inArray(val, value) !== -1)){
$('#' + inp + 'Container').show();
}
});
});
}else if (($.inArray($('#' + controlInp).val(), value) > -1) || $('#' + controlInp).prop('checked') === value) {
$('#' + inp + 'Container').show();
} else {
$('#' + inp + 'Container').hide();
}
}
This works on some elements, but the moment it overrides my oldState the fields are not hidden.
Any kind of help is much appreciated. Thanks in advance.
After looking and trying many things, I have found that the easiest way is basically to remove all elements and show them again on any change of the multiple select dropdown element.
So the final code looks like this:
if(($('#' + controlInp).attr("multiple") === "multiple") && !$.isEmptyObject(selectedValues)){
$('#' + controlInp).change(function(){
var selectedValues = getSelectedValues(controlInp);
if(!$.isEmptyObject(selectedValues)){
$('#' + inp + 'Container').hide();
$.each(selectedValues, function(i, val){
if(($.inArray(val, value) !== -1)){
$('#' + inp + 'Container').show();
}
});
}else{
$('#' + inp + 'Container').hide();
}
});
}
There is no need to add a before state and after so this is the only thing I need.
DiffArray and multipleShowHideHandler are no longer needed.
Hope this helps someone in the future.

Custom JQuery dynamic link creation

I'm pretty new to js and having a hard time figuring out the best way to generate a custom url depending on what links are selected. You can view what I have done here. http://jsfiddle.net/1fz50z1y/26/ I will also paste my info here.
var products = [];
var quantity = [];
qstring = '';
$('input.product-radio, select.products-howmany').change(function() {
var $this = $(this)
var $product = $(this).closest('.product-options-left');
var $radio = $product.find('input.product-radio');
var $select = $product.find('select.products-howmany')
var qid = $select.val();
var pid = $radio.val();
currentStatus = $radio.prop('checked'),
theString = '';
qString = '';
pString = '';
if (currentStatus) {
products.push(pid);
quantity.push(qid);
if ($product.find('div.quantity').removeClass('q-hidden')) {
//code
}
} else {
products.splice(products.indexOf(pid), 1);
quantity.splice(quantity.indexOf(qid), 1);
$product.find('div.quantity').addClass('q-hidden');
}
if ((products.length > -1) || (quantity.length > -1)) {
if ((products.length === 0) || (quantity.length === 0)) {
console.log("Q Length: " + quantity.length);
pString += products[0];
qString += quantity[0];
console.log("qString = " + quantity);
} else {
pString = products.join('-p');
qString = quantity.join('_q');
if (quantity.length > 1) {
qString = quantity.splice(quantity.indexOf(qid), 1);
pString = products.splice(products.indexOf(pid), 1);
}
console.log("+ Q Length: " + quantity.length);
console.log("ADDING " + "p" + pString + "_q" + qString);
}
if ((qString == 'undefined') || (pString == 'undefined')) {
$('a.options-cart').prop("href", "#");
} else {
//$('a.options-cart').prop("href", "/cart/add/p" + theString + "_q" + qstring + "?destination=/cart");
//$('a.options-cart').prop("href", "/cart/add/p" + theString + "?destination=/cart");
$('a.options-cart').prop("href", "/cart/add/p" + pString + "_q" + qString + "?destination=/cart");
}
}
});
$('a.options-cart').click(function() {
alert(qstring);
var $this = $(this);
href = $this.attr('href');
if (href == '#') {
alert("You must select a product.");
return false;
}
});
When you click on the add link icon it displays a drop down where you can select the quantity. So changing the quantity should also update the link and how it is created. I am trying to figure out how to create the link so the end result looks like so.
cart/add/p123_q1?destination=/cart this is how it would look with a single item. Where p = the product ID and q = the quantity. Unclicking the add to cart should remove those items and changing the drop down should update the quantity. If there is more than one item it should append to the link like so. cart/add/p123_q1-p234_q2-p232_q4?destination=/cart and then unclicking or changing quantity on any of those items should reflect the change in the link. I am not sure if I am going about this all wrong but I have been trying forever and many different routes to go about trying to achieve this effect. If anyone could please help me figure this out I would be greatly appreciated!
I was able to get this to work properly using this piece of code. Hope this maybe helps someone.
$('input.product-radio, select.products-howmany').change(function () {
var $product = $(this).closest('.product-options-left');
var $radio = $product.find('input.product-radio');
var $select = $product.find('select.products-howmany')
$product.find('div.quantity').toggleClass('q-hidden', !$radio.prop('checked'));
$product.find('label.quantity').toggleClass('q-hidden', !$radio.prop('checked'));
var string = $('.product-radio')
.filter(':checked')
.map(function(){
return $(this)
.closest('.product-options-left')
.find('.products-howmany')
.val();
})
.get()
.join('-');
$('a.options-cart').prop("href", "/cart/add/" + string + "?destination=/cart");
});
$('a.options-cart').click(function() {
alert(qstring);
var $this = $(this);
href = $this.attr('href');
if (href == '#') {
alert("You must select a product.");
return false;
}
});

change array to json

I've been playing around with javascript and casperjs. I have the following lines of code.
casper.thenOpen('somesite', function() {
console.log('clicked ok, new location is ' + this.getCurrentUrl());
// Get info on all elements matching this CSS selector
var town_selector = 'div tr';
var town_names_info = this.getElementsInfo(town_selector); // an array of object literals
// Pull out the town name text and push into the town_names array
var town_names = [];
for (var i = 0; i < town_names_info.length; i++) {
town_names.push(town_names_info[i].text.trim());}
// Dump the town_names array to screen
utils.dump(town_names);
casper.capture('capture5.png');
});
my output is this.
[
"Address:\n \n address",
"City:\n \ncity",
"State:\n \nstate",
"Zip:\n \nzip",
]
how can I make it json? like this.
{
"Address":"address",
"City":"city",
"State":"state",
"Zip":"zip"
}
Thanks in advance.
You can use something like this:
function arrayToObject(arr) {
var out = {};
arr.forEach(function (element) {
var keyvalue = element.replace(/[\n\s]+/, '').split(':');
var key = keyvalue[0];
var value = keyvalue[1];
out[key] = value;
});
return out;
}
then you can do:
var json = JSON.stringify(arrayToObject(myArray));
Update:
> How can I change this to split only the first occurrence of colon?
Use this:
arr.forEach(function (element) {
var keyvalue = element.replace(/[\n\s]+/, '');
var key = keyvalue.substring(0, element.indexOf(':'));
var value = keyvalue.substring(key.length + 1);
out[key] = value;
});

Dynamically building array, appending values

i have a bunch of options in this select, each with values like:
context|cow
context|test
thing|1
thing|5
thing|27
context|beans
while looping through the options, I want to build an array that checks to see if keys exist, and if they don't they make the key then append the value. then the next loop through, if the key exists, add the next value, comma separated.
the ideal output would be:
arr['context'] = 'cow,test,beans';
arr['thing'] = '1,5,27';
here's what i have so far, but this isn't a good strategy to build the values..
function sift(select) {
vals = [];
$.each(select.options, function() {
var valArr = this.value.split('|');
var key = valArr[0];
var val = valArr[1];
if (typeof vals[key] === 'undefined') {
vals[key] = [];
}
vals[key].push(val);
});
console.log(vals);
}
Existing code works by changing
vals=[];
To
vals={};
http://jsfiddle.net/BrxuM/
function sift(select) {
var vals = {};//notice I made an object, not an array, this is to create an associative array
$.each(select.options, function() {
var valArr = this.value.split('|');
if (typeof vals[valArr[0]] === 'undefined') {
vals[valArr[0]] = '';
} else {
vals[valArr[0]] += ',';
}
vals[valArr[0]] += valArr[1];
});
}
Here is a demo: http://jsfiddle.net/jasper/xtfm2/1/
How about an extensible, reusable, encapsulated solution:
function MyOptions()
{
var _optionNames = [];
var _optionValues = [];
function _add(name, value)
{
var nameIndex = _optionNames.indexOf(name);
if (nameIndex < 0)
{
_optionNames.push(name);
var newValues = [];
newValues.push(value);
_optionValues.push(newValues);
}
else
{
var values = _optionValues[nameIndex];
values.push(value);
_optionValues[nameIndex] = values;
}
};
function _values(name)
{
var nameIndex = _optionNames.indexOf(name);
if (nameIndex < 0)
{
return [];
}
else
{
return _optionValues[nameIndex];
}
};
var public =
{
add: _add,
values: _values
};
return public;
}
usage:
var myOptions = MyOptions();
myOptions.add("context", "cow");
myOptions.add("context","test");
myOptions.add("thing","1");
myOptions.add("thing","5");
myOptions.add("thing","27");
myOptions.add("context","beans");
console.log(myOptions.values("context").join(","));
console.log(myOptions.values("thing").join(","));
working example: http://jsfiddle.net/Zjamy/
I guess this works, but if someone could optimize it, I'd love to see.
function updateSiftUrl(select) { var
vals = {};
$.each(select.options, function() {
var valArr = this.value.split('|');
var key = valArr[0];
var val = valArr[1];
if (typeof vals[key] === 'undefined') {
vals[key] = val;
return;
}
vals[key] = vals[key] +','+ val;
});
console.log(vals);
}
Would something like this work for you?
$("select#yourselect").change(function(){
var optionArray =
$(":selected", $(this)).map(function(){
return $(this).val();
}).get().join(", ");
});
If you've selected 3 options, optionArray should contain something like option1, option2, option3.
Well, you don't want vals[key] to be an array - you want it to be a string. so try doing
if (typeof vals[key] === 'undefined') {
vals[key] = ';
}
vals[key] = vals[key] + ',' + val;

Categories

Resources