I have a AngularJS app developed.
On a view I have a list of items - each with its own set of radio buttons. The list and buttons are built at run-time from an API call.
Both the list and radio buttons can be of any length e.g. list item 1 might contain 3 radio buttons while list item n might contain 2 radio buttons.
When the user selects a radio button I fire a ng-click method that sends both the list ID as well as the radio button ID to the controller.
The view looks as follows and I have tested this and the values are being sent to the controller.
<label class="radio-button" ng-repeat="option in checkItemDescription.options">
<input type="radio" name="option_question_id_{{checkItemDescription.fleetcheckitemid}}"
ng-model="checkItemDescription.selected_id"
ng-click="doSomething(checkItemDescription.fleetcheckitemid, option.fleetcheckid)"
ng-value="option.fleetcheckid">
<div class="radio-button__checkmark"></div>
Description: {{option.checkvaluedesc}}
</label>
In my doSomething() method i am trying to see if either the checkItemDescription.fleetcheckitemid or the option.fleetcheckid id is in a existing array.
I use indexOf() method to compare the values but the method does not seem to work - even though console.log() shows values are sent to the controller.
Below is my doSomething() method.
$scope.doSomething = function(fleetCheckItemID, fleetCheckID)
{
if ( $scope.initialFleetCheckIssueItemIDArray.indexOf(fleetCheckItemID))
{
console.log("Yeah!"); // Never gets to here even though logs show values exist
}
else
{
console.log("Ah!"); // Always get here
}
}
What I need to do is to to create a JSON object with the list item ID, radio button ID and some other values e.g. date/time based on the user selection to send to my Database.
Is this the best way to do it or is there a better way?
The indexOf() method returns the first index at which a given element can be found in the array, or -1 if it is not present.
-referenced from MDN.
so if your element is first in the collection then indexOf would return 0 which would result in the execution of else block so change your if condition like this.
if ( $scope.initialFleetCheckIssueItemIDArray.indexOf(fleetCheckItemID) != -1 )
{
//element found, do stuff here.
}
else
{
//element does not found, else stuff here.
}
Related
In my angular code on page load there are list of buttons like button 1, button 2, button 3.. etc on click of every button it shows J-SON on console the structure is same for all buttons but the values vary. There are two more buttons on page on up and down.
My question is if button 2 is selected and i click on up button then the position of button 2 should moved up to button 1 for that we have use one attribute in j-son but problem m facing is that how should i swap whole j-son like how to swap position of button 2 to button 1 and vice-versa for down arrow
searched for swapping on google but it showing items in array to swap. i want whole j-son to swap
up(){
exchange(this.jsondata,up,up+1);
}
private exchange(array: any, x: any, y: any) {
const temp = array[x];
array[x] = array[y];
array[y] = temp;
return array;
}
it should change the position of buttons on click of up down buttons
If what you want is swapping two elements in an array, your exchange function seems ok.
But you are calling it with only 2 parameters : up(up, up+1) while your function takes 3 parameters :
the array where the items are
the first item
the second item
If your buttons were in an array named myButtons, you would probably want to call it that way :
up(myButtons, up, up+1);
Side notes :
be careful what you're naming your parameters. Array is a global JavaScript object. It's not a good practice to use that name for a variable.
up is obviously the name of a function and a variable. That is kind of confusing.
your function returns the array that was passed as a paramter. That is not necessary since arrays are passed as references. You can make your function immutable and have it return a different array. Or modify the reference and not return anything.
I know it's trivial but I have a doubt to be clarified.
I have a collection vm.groups that has almost 1000 objects. Now, each object has name, id, links etc. property fields.
Grid only displays name and id.
Now, there is a text box where we enter some text and we have to filter data, according to whatever we entered but filtering must happen only within name and id fields of the objects not the other fields that are present within the objects.
So, both things can be done,
1) I create a temp collection from the original collection objects with only name and id fields and then bind the collection to view.
// vm.groups.forEach(function(element) {
// vm.displayedFieldGroups.
// push({name: element.name,id: element.id,transformedId: element.transformedId});
// });
2) Or, I create a custom filter vm.customSearch :
vm.customSearch = function(searchVal) {
if(vm.filter.length) {
if(vm.filter.toLowerCase().indexOf(searchVal.name.toLowerCase) !== -1 ||
vm.filter.toLowerCase().indexOf(searchVal.name.toLowerCase) !== -1) {
console.log(searchVal);
return true;
}else {
return false;
}
} else {
console.log(searchVal);
return true;
}
};
And in the view vm.groups | filter: vm.customSearch.
But I think second method is slower because each value in the collection would be passed to the filter which is obviously tedious for huge collection.
Am I right?
Which is the right way to do?
UPDATE
This was for a legacy application. There was a filter already implemented but that just goes through all the fields in the object. I need to only filter for name and id fields of objects.
Hence, I need to either create a custom filter or choose the first approach that I depicted.
You're right in your assumption that the filter would go over every item in the source array and run your filter function each time there's a digest cycle.
You should proceed with the first approach.
There is a page with a lot of different checkbox questions which then get submitted and populate the next page, this page however gets refreshed and the already annoyed potential client needs to go back and fill out the form again.
Now I have localstorage set up so he doesn't need to reselect all the checkbox again, he just needs to resubmit the form and his back in action.
How does one keep the values populated on the problem page so this fella doesn't have to go back to resubmit?
//SIZE SAVE
function save() {
localStorage.setItem('100', checkbox.checked);
var checkbox = document.getElementById('100');
localStorage.setItem('200', checkbox.checked);
var checkbox = document.getElementById('200');
//SIZE LOAD
function load() {
var checked = JSON.parse(localStorage.getItem('100'));
document.getElementById("100").checked = checked;
var checked = JSON.parse(localStorage.getItem('200'));
document.getElementById("200").checked = checked;
//THIS PAGE NEEDS THE CHECKMARK
echo get_site_url().
"/the/checkmark/selected/was/".$_POST['check_group'].
"/.png";
}
I think is much simple for now and especially for the feature if you write some code to make the management for all checkboxes form your form.
First of all it will be best if you group all your checkboxes into a single place.
Into a function like this you can declare all your checkbox selectors you want to save into the localStoarge (now you don't need to make variables for each selector into multiple places into your code)
function getCheckboxItems() {
return ['100', '200']
.map(function(selector) {
return {
selector: selector,
element: document.getElementById(selector)
}`enter code here`
});
}
Then to make things much simpler you can store all the values from the checkbox into a single object instead of save the result in multiple keys, in this way is much simpler to make management (let's say you want to erase all values or to update only a part)
The following function will take as argument all checkbox items from the function above, the point is the function above will return an array with the checkbox id and the checkbox element, than you just reduce all that array into this function into an single object containing all the ids and values, after this you just store the object into the localStorage
function serializeCheckboxes(elements) {
var container = elements.reduce(function (accumulator, item) {
accumulator[item.selector] = item.element.checked;
return accumulator;
}, {})
localStorage.setItem('container', JSON.stringify(container));
}
function save() {
var elements = getCheckboxItems();
serializeCheckboxes(elements);
}
After this you need another function who will read all the values from the localStorge and place them into your checkbox "checked" state
function readCheckboxes() {
var storage = localStorage.getItem('container'), //Your key
container = (storage) ? JSON.parse(storage) : {};
Object.keys(container).forEach(function(key) {
var element = document.getElementById(key);
if(element) {
element.checked = container[key];
}
});
}
This is just a simple service who can manage your problem but I think, for any additional changes you can customize this solution much simpler instead of keeping all into multiple variables, also if you add more checkbox elements into your application with this solution you just add the corresponding id into the array from the first function.
A live example here:
https://jsbin.com/xejibihiso/edit?html,js,output
localStorage has two main functions, getItem and setItem. For setItem you pass in a key and a value. If you write to that key again, it will rewrite that value. So in your case, if a box is checked you would do
localStorage.setItem("checkbox_value", true)
and when it is unchecked you would pass in false instead. To get the value you can look at using jQuery like so:
$(checkbox).is(':checked')
and use a simple if-else clause to pass in true or false. then when you reload your page, on $(document).ready() you can get the values using
localStorage.getItem(key)
and use JavaScript to set the check boxes values.
localStorage only allows you to store strings. What you can do is use a loop to create a string that has all the check boxes values separated by some delimiter. So, for example, if there are four check boxes with values true false false true your string would be "true\nfalse\nfalse\ntrue" where \n is the delimiter. then you can store that string in localStorage and when you retrieve it you can put all the values into an array like so:
array = localStorage.getItem(key).split('\n').
Then you can populate your check boxes with that newly retrieved array. Ask if anything needs clarification.
In ExtJS panel I need to set value of all items (e.g. textfield, pathfield) to blank. I don't want to set value of each individual item to blank but of whole panel in one go.
I am able to get list of items
function getAllChildren (panel) {
/*Get children of passed panel or an empty array if it doesn't have thems.*/
var children = panel.items ? panel.items.items : [];
/*For each child get their children and concatenate to result.*/
CQ.Ext.each(children, function (child) {
children = children.concat(getAllChildren(child));
});
return children;
}
but how to set to blank for whole panel? Please suggest what need to be done in this case.
Actually, it's not possible to do it with one liner - all at the same time. What your method returns is purely an array of objects. In fact if such syntax existed, it would iterate over all fields anyway.
Though clearing all fields, having the method you've proposed is very trivial to do. Just iterate over them all and call reset method. Mind some (especially custom) widgets might not handle it.
var fields = getAllChildren(panel);
CQ.Ext.each(fields, function(field) {
if (child.reset) {
child.reset();
}
});
You've got similar loop in your getAllChildren code - you might reset field at the same place.
The method is defined in Field type which is usually a supertype of each dialog widget. You can read more here.
I am working offline with SQLite, Javascript and Chrome
In my main page (main.html), I have two div: <div id="menuLeft"> that contains the list of items name with buttons to edit each item, and
<div id="content">
The list of item is written as follows:
<li>ItemName1
<div id="idItem1" class="editItem_btn">
<img src="btn_edit.png">`
</div>
</li>
In main.html, I have the following code:
$("#menuLeft").delegate(".editItem_btn", "click", function(e0)
{
e0.preventDefault();
var editItemId = $(this).attr("id");
editItemId = parseInt(editItemId);
var url="edititem.html"
$("#content").load(url,function(){
loadRecord(editItemId);`
});
});
When I click on the edit button of a given Item, the id of the Item is first retrieved from the id of the div around the edit button. Then I load the page edititem.html content. On success, I run the function loadRecord(editItemId), where loadRecord(i) is contained in edititem.html:
function loadRecord(j)
{
var item = dataset.item(j);
idItem.value = item['id'];
ItemName.value = item['ItemName'];
dateStart.value = item['dateStart'];
dateEnd.value = item['dateEnd'];
notes.value = item['notes'];
}
This function enables to display the parameters of Item (id, ItemName....) contained in the database.
Here is my problem, the code works but in a weird way meaning that if I click on the edit button of Item1, the parameters of Item2 are displayed. Same thing if I click on edit Item2, parameters of Item3 are displayed.
I then replaced:
var item = dataset.item(j);
with:
var item = dataset.item(j-1);
and that works. But I need to understand why it's behaving like that, and why I need to use (j-1). I placed some alert() in the jquery code to check that I have the right editItemId number, and in the function loadRecord(j). The right id number is retrieved after the click and the right id number is passed to the function. I have no idea what's the bug here!
Without seeing the sql side of things, and how that data is passed back to your script it's impossible to tell you exactly what's happening, but this is simply a case of some lists being 0 based and some lists being 1 based. For example, arrays are generally 0 based (unless you specifically create them a different way), but $("#id").each(function(Index)... is 1 based. You just have to know what you're working with and occasionally do as you have found and use -1 or +1 when relevant.
While I'm not familiar with the intricacies of SQLite, I suspect that dataset.item(j):
is accepting a 0-based index
that you are passing in the record_id (which in itself is not actually an array index)
and that the record_id for the dataset you are testing just happens to be the index + 1 (meaning you're getting lucky right now and that it will probably change when the next dataset is loaded).
I would check to see if there's an equivalent for dataset.item(j) which accepts a record_id and not an index. Otherwise, you'll probably want to store the index of the record somewhere in the record itself to be able to pass it to your loadRecord function.
Hope this helps,
Pete