how to remove states from stateProvider - angularjs

After removing the states from $stateProvider and its caches from cacheTemplate,it gives me a 'already defined' error when trying to add the same state name.
clearStates: function () {
var states = this.$state.get();
for (var i = 0; i < states.length; i++) {
if (states[i].name != 'shell.error404' &&
states[i].name != 'shell.error500' &&
states[i].name != 'shell' &&
states[i].name != '') {
var tmplUrl = states[i].templateUrl;
if (tmplUrl) {
this.templateCache.remove(tmplUrl);
}
delete states[i];
}
}
}
any way to do that ?

Try
clearStates: function () {
var states = this.$state.get();
var itemsToBeRemoved = [];
var removalIndex = 0;
for (var i = 0; i < states.length; i++) {
if (states[i].name != 'shell.error404' &&
states[i].name != 'shell.error500' &&
states[i].name != 'shell' &&
states[i].name != '') {
var tmplUrl = states[i].templateUrl;
if (tmplUrl) {
this.templateCache.remove(tmplUrl);
}
//delete states[i];
itemsToBeRemoved[removalIndex++] = i;
}
}
for(var j=0;j<itemsToBeRemoved.length;j++){
states.splice(itemsToBeRemoved[j],1);
}
}
Store the index(s) to be deleted and use states.splice(>index<,1) instead of delete states[i]
delete leaves an empty element in the array at the given index, this may be the cause of your issue.

Related

Is there any way to replace text in ChromiumBrowser like Chrome already has?

I'm making a web editor application using CefSharp WinForms library, but I couldn't find a way to replace text from CefSharp API.
There is a find method in WebBrowserExtensions but no replace method.
Question 1:
Does anyone know where replacing text method is in CefSharp?
Or there is no way to replace text in CefSharp? If yes, I need to find a detour for it.
Question 2:
There are yellow blocks marked found words when I try Find method, but those blocks are not a part of selection range of window object in HTML. Are those blocks made by native not web browser?
Answer:
I made "find and replace" function by myself using javascript, so if someone tries to do something like me then you can use below codes:
var lastsearchedNodeIndex = -1;
var lastSearchedTextIndex = -1;
var lastRange = null;
function getTextLengthFromStartTo(targetNodeIndex) {
var childNodes = editor.childNodes;
var textLength = 0;
if (targetNodeIndex >= childNodes.length) {
return editor.textContent.length;
}
for (var i = 0; i < targetNodeIndex; i++) {
if (childNodes[i].textContent != null) {
textLength += childNodes[i].textContent.length;
}
}
return textLength;
}
function getCurrentCaretIndex() {
var currentCaretIndex = 0;
var doc = editor.ownerDocument || editor.document;
var win = doc.defaultView || doc.parentWindow;
var sel;
if (typeof win.getSelection != "undefined") {
sel = win.getSelection();
if (sel.rangeCount > 0) {
var range = win.getSelection().getRangeAt(0);
var preCaretRange = range.cloneRange();
preCaretRange.selectNodeContents(editor);
preCaretRange.setEnd(range.endContainer, range.endOffset);
currentCaretIndex = preCaretRange.toString().length;
}
} else if ( (sel = doc.selection) && sel.type != "Control") {
var textRange = sel.createRange();
var preCaretTextRange = doc.body.createTextRange();
preCaretTextRange.moveToElementText(editor);
preCaretTextRange.setEndPoint("EndToEnd", textRange);
currentCaretIndex = preCaretTextRange.text.length;
}
return currentCaretIndex;
}
function getCurrentNodeIndexAtCaret(caretIndex) {
if (caretIndex == 0) {
return 0;
}
var currentNodeIndex = -1;
for (var i = 0; i < editor.childNodes.length; i++) {
var frontTextLength = getTextLengthFromStartTo(i);
var backTextLength = getTextLengthFromStartTo(i + 1);
if (caretIndex > frontTextLength && caretIndex <= backTextLength) {
currentNodeIndex = i;
break;
}
}
return currentNodeIndex;
}
function getCurrentTextIndexInNodexAtCaret(nodeIndex, caretIndex) {
var textLength = getTextLengthFromStartTo(nodeIndex);
var textIndex = caretIndex - textLength;
return (textIndex < 0) ? 0 : textIndex;
}
function clearSelection() {
if (window.getSelection().rangeCount > 0) {
if (lastRange != null) {
window.getSelection().removeAllRanges();
lastRange.collapse(true);
window.getSelection().addRange(lastRange);
}
}
}
function getTextNodesIn(node) {
var textNodes = [];
if (node.nodeType == 3) {
textNodes.push(node);
} else {
var children = node.childNodes;
for (var i = 0, len = children.length; i < len; ++i) {
textNodes.push.apply(textNodes, getTextNodesIn(children[i]));
}
}
return textNodes;
}
function setSelectionRange(el, start, end) {
if (document.createRange && window.getSelection) {
var range = document.createRange();
range.selectNodeContents(el);
var textNodes = getTextNodesIn(el);
var foundStart = false;
var charCount = 0, endCharCount;
for (var i = 0, textNode; textNode = textNodes[i++]; ) {
endCharCount = charCount + textNode.length;
if (!foundStart && start >= charCount && (start < endCharCount || (start == endCharCount && i <= textNodes.length))) {
range.setStart(textNode, start - charCount);
foundStart = true;
}
if (foundStart && end <= endCharCount) {
range.setEnd(textNode, end - charCount);
break;
}
charCount = endCharCount;
}
var sel = window.getSelection();
sel.removeAllRanges();
sel.addRange(range);
lastRange = range;
sel.anchorNode.parentElement.scrollIntoView();
} else if (document.selection && document.body.createTextRange) {
var textRange = document.body.createTextRange();
textRange.moveToElementText(el);
textRange.collapse(true);
textRange.moveEnd("character", end);
textRange.moveStart("character", start);
textRange.select();
}
}
function findText(text, caseSensitive) {
var currentCaretIndex = getCurrentCaretIndex();
clearSelection();
var regex;
if (caseSensitive) {
regex = text;
} else {
regex = new RegExp(text, "gi");
}
var childNodes = editor.childNodes;
var startNodeIndex = getCurrentNodeIndexAtCaret(currentCaretIndex);
var endNodeIndex = childNodes.length;
var startTextIndex = 0;
if (window.getSelection().focusOffset == 1) {
startTextIndex = lastSearchedTextIndex + 1;
} else {
startTextIndex = getCurrentTextIndexInNodexAtCaret(startNodeIndex, currentCaretIndex);
}
var searchedTextIndex = -1;
var searchedNodeIndex = 0;
var searchTargetSentence = null;
var searchLoopCount = 0;
if (currentCaretIndex == editor.textContent.length) {
startNodeIndex = 0;
startTextIndex = 0;
}
do
{
for (var i = startNodeIndex; i < endNodeIndex; i++) {
if (typeof (childNodes[i].textContent) == undefined || childNodes[i].textContent == null) {
startTextIndex = 0;
continue;
}
if (startTextIndex == childNodes[i].textContent.length) {
startTextIndex = 0;
continue;
}
if (startTextIndex > 0) {
searchTargetSentence = childNodes[i].textContent.substring(startTextIndex, childNodes[i].textContent.length);
} else {
searchTargetSentence = childNodes[i].textContent;
}
searchedTextIndex = searchTargetSentence.search(regex);
if (searchedTextIndex > -1) {
searchedTextIndex += startTextIndex;
searchedNodeIndex = i;
break;
}
startTextIndex = 0;
}
if (searchedTextIndex == -1) {
endNodeIndex = startNodeIndex + 1;
startNodeIndex = 0;
searchLoopCount++;
}
} while (searchLoopCount < 2 && searchedTextIndex == -1);
lastsearchedNodeIndex = searchedNodeIndex;
lastSearchedTextIndex = searchedTextIndex;
if (searchedNodeIndex > -1 && searchedTextIndex > -1) {
var textStartIndex = getTextLengthFromStartTo(searchedNodeIndex) + searchedTextIndex;
setSelectionRange(editor, textStartIndex, textStartIndex + text.length);
return true;
} else {
return false;
}
}
function replaceText(textToFind, textToReplace, caseSensitive) {
if (findText(textToFind, caseSensitive) == true) {
var sel, range;
if (window.getSelection) {
sel = window.getSelection();
if (sel.rangeCount) {
range = sel.getRangeAt(0);
range.deleteContents();
range.insertNode(document.createTextNode(textToReplace));
}
} else if (document.selection && document.selection.createRange) {
range = document.selection.createRange();
range.text = textToReplace;
}
return true;
} else {
return false;
}
}
There are no replace text method in CefSharp.
I think you have two options
Implement in javascript/html in the browser (DIY or something
like Tiny)
Manipulating the html from C# using GetSourceAsync and LoadHtml (Documentation)
Second question - I think you may be able to at least read the hits using the FindHandler. Have not tested this myself.

Getting Cannot read property 'indexOf' of null Custom Filter for search in angularjs

I am using custom filter for my table content search my custom filter function is
return function(data, search) {
if(angular.isDefined(search)) {
var results = [];
var i;
var searchVal = $filter('lowercase')(search);
for(i = 0; i < data.length; i++){
var name = $filter('lowercase')(data[i].name);
var description = $filter('lowercase')(data[i].description);
if(name.indexOf(searchVal) > -1 || description.indexOf(searchVal) > -1){
results.push(data[i]);
}
}
return results;
} else {
return data;
}
};
when i put any text in search box it will get
TypeError: Cannot read property 'indexOf' of null
if((name !=null && name.indexOf(searchVal) > -1) || (description!=null && description.indexOf(searchVal) > -1)){
results.push(data[i]);
}
name or description is giving null value try above code
Check null condition
return function(data, search) {
if(angular.isDefined(search)) {
var results = [];
var i;
var searchVal = $filter('lowercase')(search);
for(i = 0; i < data.length; i++){
var name = $filter('lowercase')(data[i].name);
var description = $filter('lowercase')(data[i].description);
if(name !== null && description !== null){
if(name.indexOf(searchVal) > -1 || description.indexOf(searchVal) > -1){
results.push(data[i]);
}
}
}
return results;
} else {
return data;
}
};

Handling Response datas and moving into array

I have a response from backend. Where I need to pass the state based on selected country in dropdown and City based on selected state in dropdown for my form.
I am able to push them into array , but it is getting replaced. For instance.Country India also will have states of USA ,it has been replaced with india states.Need Assistance.
Response :
Geography :
[{"countryname":"India",
"states":[{"statename":"Karnataka",
"cities":[{"city":"Bangalore","segments":[{"segment":""}]},
{"city":"Hubli","segments":[{"segment":""}]}]},
{"statename":"Tamil Nadu",
"cities":[{"city":"Chennai","segments":[{"segment":""}]},
{"city":"Coimbatore","segments":[{"segment":""}]}]}]},
{"countryname":"USA",
"states":[{"statename":"California",
"cities":[{"city":"San Francisco","segments":[{"segment":""}]},{"city":"San Jose","segments":[{"segment":""}]}]},
{"statename":"New Jersey",
"cities":[{"city":"Princeton","segments":[{"segment":""}]},
{"city":"South Brunswick","segments":[{"segment":""}]}]}]}]
JS :
UserService.Geography(json).then(function(response) {
$scope.model.countries = [];
$scope.model.countries.push("ALL");
if (response.json.response.statuscode == 0 && response.json.response.statusmessage == 'Success') {
var geography = response.json.response.geography;
console.log("Geography : " + JSON.stringify(geography));
$scope.geography = geography;
for (var i = 0; i < geography.length; i++) {
$scope.model.countries.push(geography[i].countryname);
console.log($scope.model.countries);
if (($scope.model.countries != []) || ($scope.model.countries != null)) {
$scope.model.states = [];
$scope.model.states.push("ALL");
for (var j = 0; j < geography[i].states.length; j++) {
if (geography[i].states) {
$scope.model.states.push(geography[i].states[j].statename);
} else {
$scope.model.states.push(geography[i].state[j].statename);
}
console.log($scope.model.states);
if (($scope.model.states != []) || ($scope.model.states != null)) {
$scope.model.cities = [];
$scope.model.cities.push("ALL");
// for first time combobox loading,
// load only cities for first state
if (j === 0) {
for (var k = 0; k < geography[i].states[j].cities.length; k++) {
console.log('======k=====:'+k);
console.log('geography[i].states[j].cities[k].city=====:'+geography[i].states[j].cities[k].city);
if (geography[i].states) {
$scope.model.cities.push(geography[i].states[j].cities[k].city);
} else {
$scope.model.cities.push(geography[i].state[j].cities[k].city);
};
console.log('$scope.model.cities: '+ $scope.model.cities);
if (($scope.model.cities != []) || ($scope.model.cities != null)) {
$scope.model.segments = "_ALL";
console.log($scope.model.segments);
}
}
}
$scope.model.selectedCity = $scope.model.cities[0];
}
}
$scope.model.selectedState = $scope.model.states[0];
}
}
$scope.model.selectedCountry = $scope.model.countries[0];
}
});
}
Just transform your data to array of objects with format like
{ country, state, city }
example transform with lodash:
var data = [];
var cities = _.flatMap(data, mapCountries);
function mapCountries(country){
return _.flatMap(country.states, mapStates).map(setAttr('country', country.countryname));
}
function mapStates(state){
return state.cities.map(setAttr('state', state.statename));
}
function setAttr(key, value){
return function(obj){
obj[key] = value;
return obj;
}
}

AngularJS : why is searching not working properly?

I am trying to search text on table using angular ..I am able to search text in table .But my search works when I press enter or “search button” .Example when I write “Active” it not show the result but when I press enter or press search button it show the output .can we do the like search like autocomplete .Example when I press “a’ it show all item which start from “a” .Then if user write “ac” then show “ac” value ..same like that .when user write “active “ it show rows which have “active” without using search button or enter .can we make add filter so that it works properly ?
here is my code
$scope.searchInvoices = function(evt, queryval) {
$scope.haveNorecordFound = true;
if (typeof queryval != "undefined" && queryval.length === 0 || evt.keyCode === 13 || evt.type === 'click') {
if (typeof queryval == "undefined" || queryval.length === 0) {
console.log("if===")
isfilterOccured = false;
$scope.tasklist_records = $scope.total_tasklist_records;
$scope.totalNumberOfrecord = $scope.tasklist_records.length + " records found."
} else {
console.log("esle===")
var recordset = $scope.serachObject;
results = [];
var recordsetLength = recordset.length;
var searchVal = queryval.toLowerCase();
var i, j;
for (i = 0; i < recordsetLength; i++) {
var record = recordset[i].columns;
for (j = 0; j < record.length; j++) {
if (record[j].value != null) {
var invoice = record[j].value.toLowerCase();
if (invoice.indexOf(searchVal) >= 0) {
results.push(recordset[i]);
}
}
}
}
var nameOrPathValues = results.map(function(o) {
var result = {};
o.columns.forEach(function(c) {
result[c.fieldNameOrPath] = c.value;
});
return result;
});
console.log("serach");
console.log(nameOrPathValues);
var objectarray = nameOrPathValues.map(function(o) {
var result = {};
collectNameOrPath.forEach(function(name) {
result[name] = o[name];
});
return result;
});
isfilterOccured = true;
$scope.tasklist_records = objectarray;
if ($scope.tasklist_records.length == 0) {
$scope.haveNorecordFound = false;
} else {
$scope.totalNumberOfrecord = $scope.tasklist_records.length + " records found."
}
}
}
};
After debugging in code, I found that you're biding function on either enter button press or search click. That's why it was not working on ng-keyup. Please replace your function from below code.
$scope.searchInvoices = function(evt, queryval) {
console.log(queryval)
$scope.haveNorecordFound = true;
var recordset = $scope.serachObject;
results = [];
var recordsetLength = recordset.length;
var searchVal = queryval.toLowerCase();
var i, j;
for (i = 0; i < recordsetLength; i++) {
var record = recordset[i].columns;
for (j = 0; j < record.length; j++) {
if (record[j].value != null) {
var invoice = record[j].value.toLowerCase();
if (invoice.indexOf(searchVal) >= 0) {
results.push(recordset[i]);
}
}
}
}
var nameOrPathValues = results.map(function(o) {
var result = {};
o.columns.forEach(function(c) {
result[c.fieldNameOrPath] = c.value;
});
return result;
});
console.log("serach");
console.log(nameOrPathValues);
var objectarray = nameOrPathValues.map(function(o) {
var result = {};
collectNameOrPath.forEach(function(name) {
result[name] = o[name];
});
return result;
});
isfilterOccured = true;
$scope.tasklist_records = objectarray;
if ($scope.tasklist_records.length == 0) {
$scope.haveNorecordFound = false;
} else {
$scope.totalNumberOfrecord = $scope.tasklist_records.length + " records found."
}
};

Dojo function not working on IE8

I have a piece of code to select/deselect all Dojo checkboxes using a single master checkbox (which acts as a toggle) that works fine on firefox but doesn't on IE8. I tried hard to find the issue but was clueless, can anybody help. Im attaching the code below:
<script type="text/javascript">
dojo.require("dojo.parser");
dojo.ready(function() {
var checkboxes = [];
dojo.query('#waferCheck_cb input[type=checkbox]').forEach(function(node, index, arr){
checkboxes.push(arr[index].id);
var handle = dojo.connect(dijit.byId(arr[index].id), "onchange", function(evt){
var cbClicked = evt.target.id;
var cbStatus = dijit.byId(cbClicked).get("checked");
setCBSelection(checkboxes,cbClicked,cbStatus );
dojo.disconnect(handle);
});
});
});
function setCBSelection(checkboxes,cb_Clicked, cb_Status) {
var len = checkboxes.length;
if(len > 0) {
// get index of the checkbox clicked
var cb_pos = 0;
for(var i = 0; i < len; i++) {
if(cb_Clicked == checkboxes[i]) {
cb_pos = i;
break;
}
}
// If Select All checkbox clicked, set the other checboxes accordingly
if(cb_pos == 0) {
for(var i = 1; i < len; i++) {
dijit.byId(checkboxes[i]).set("checked", cb_Status);
}
} else {
// If any other checkbox is clicked, set the Select All accordingly
var allCBSameStatus = true;
for(var i = 1; i < len; i++) {
var curCBStatus = dijit.byId(checkboxes[i]).get("checked");
if(curCBStatus != cb_Status) {
allCBSameStatus = false;
break;
};
}
if(allCBSameStatus){
dijit.byId(checkboxes[0]).set("checked", cb_Status)
}else{
if(cb_Status == false) {
dijit.byId(checkboxes[0]).set("checked", cb_Status)
}
}
}
}
}
</script>
I believe IE8 doesn't like missing semicolons. I see 2 lines that are missing semicolons.
dijit.byId(checkboxes[0]).set("checked", cb_Status)
Have you tried to define function setCBSelection(...) before dojo.ready(..) (see below)? Maybe this helps as it is used before it was defined? If that doesn't help, it may be useful if you post some kind of error-message IE might throw...
dojo.require("dojo.parser");
function setCBSelection(checkboxes,cb_Clicked, cb_Status) {
var len = checkboxes.length;
if(len > 0) {
// get index of the checkbox clicked
var cb_pos = 0;
for(var i = 0; i < len; i++) {
if(cb_Clicked == checkboxes[i]) {
cb_pos = i;
break;
}
}
// If Select All checkbox clicked, set the other checboxes accordingly
if(cb_pos === 0) {
for(i = 1; i < len; i++) {
dijit.byId(checkboxes[i]).set("checked", cb_Status);
}
} else {
// If any other checkbox is clicked, set the Select All accordingly
var allCBSameStatus = true;
for(i = 1; i < len; i++) {
var curCBStatus = dijit.byId(checkboxes[i]).get("checked");
if(curCBStatus != cb_Status) {
allCBSameStatus = false;
break;
}
}
if(allCBSameStatus){
dijit.byId(checkboxes[0]).set("checked", cb_Status);
}else{
if(cb_Status === false) {
dijit.byId(checkboxes[0]).set("checked", cb_Status);
}
}
}
}
}
dojo.ready(function() {
var checkboxes = [];
dojo.query('#waferCheck_cb input[type=checkbox]').forEach(function(node, index, arr){
checkboxes.push(arr[index].id);
var handle = dojo.connect(dijit.byId(arr[index].id), "onchange", function(evt){
var cbClicked = evt.target.id;
var cbStatus = dijit.byId(cbClicked).get("checked");
setCBSelection(checkboxes,cbClicked,cbStatus );
dojo.disconnect(handle);
});
});
});
Btw: you should always use === to compare with 0 or false... You can use jsFiddle to let JSLint check your code which detacts many issues one doesn't see in the first place. Hope i could help you.

Resources