I am using Dynamsoft Web TWAIN In My Scanner.I am getting error with bellow code,
Html Code -
<button (click)="acquireImage()">Scan Document</button>
<div id="dwtcontrolContainer"></div>
Angular code -
acquireImage(): void {
const dwObject = Dynamsoft.WebTwainEnv.GetWebTwain('dwtcontrolContainer');
dwObject.IfShowIndicator = false;
const bSelected = dwObject.SelectSource();
if (bSelected) {
const onAcquireImageSuccess = () => { dwObject.CloseSource(); };
const onAcquireImageFailure = onAcquireImageSuccess;
dwObject.OpenSource();
dwObject.AcquireImage({}, onAcquireImageSuccess, onAcquireImageFailure);
}
}
The namespace of Dynamic Web TWAIN has been changed. You can refer to the latest sample code https://github.com/Dynamsoft/dwt-angular-simple/blob/master/src/app/dwt/dwt.component.ts
Initialize Dynamic Web TWAIN Object:
ngOnInit(): void {
Dynamsoft.DWT.Containers = [{ WebTwainId: 'dwtObject', ContainerId: this.containerId, Width: '300px', Height: '400px' }];
Dynamsoft.DWT.RegisterEvent('OnWebTwainReady', () => { this.Dynamsoft_OnReady(); });
Dynamsoft.DWT.ResourcesPath = 'assets/dwt-resources';
Dynamsoft.DWT.ProductKey = 't00891wAAAKBfWo4sRRVNTyLqdC7nKomEJIfBYqfXWg5mblnP0eeJi+LsMIUdQvrBf//ocS3z8MJA47R4VdO4x24uJwlqKgkuZOa7BUQHPkFNA5hFSi6lG2qOK6I=';
let checkScript = () => {
if (Dynamsoft.Lib.detect.scriptLoaded) {
Dynamsoft.DWT.Load();
} else {
setTimeout(() => checkScript(), 100);
}
};
checkScript();
}
Dynamsoft_OnReady(): void {
this.DWObject = Dynamsoft.DWT.GetWebTwain(this.containerId);
this.bWASM = Dynamsoft.Lib.env.bMobile || !Dynamsoft.DWT.UseLocalService;
if (this.bWASM) {
this.DWObject.Viewer.cursor = "pointer";
} else {
let sources = this.DWObject.GetSourceNames();
this.selectSources = <HTMLSelectElement>document.getElementById("sources");
this.selectSources.options.length = 0;
for (let i = 0; i < sources.length; i++) {
this.selectSources.options.add(new Option(<string>sources[i], i.toString()));
}
}
}
Acquire images from scanners:
acquireImage(): void {
if (!this.DWObject)
this.DWObject = Dynamsoft.DWT.GetWebTwain();
if (this.bWASM) {
alert("Scanning is not supported under the WASM mode!");
}
else if (this.DWObject.SourceCount > 0 && this.DWObject.SelectSourceByIndex(this.selectSources.selectedIndex)) {
const onAcquireImageSuccess = () => { this.DWObject.CloseSource(); };
const onAcquireImageFailure = onAcquireImageSuccess;
this.DWObject.OpenSource();
this.DWObject.AcquireImage({}, onAcquireImageSuccess, onAcquireImageFailure);
} else {
alert("No Source Available!");
}
}
Related
I have two functions I need to write unit test for it. I tried some test but I don't know to check whether my variable value is changing according to the condition.
ifAllowed: Boolean = false;
checkRoleModifierExists() {
if (this.userDetails && this.userDetails.roles) {
for (
let userRolesIndex = 0;
userRolesIndex < this.userDetails.roles.length;
userRolesIndex++
) {
if (this.userDetails.roles[userRolesIndex] === 'ROLE_ADMIN_SUPPORT' &&
this.roleModifiers.body &&
this.roleModifiers.body.length) {
this.ifAllowed = this.ifAllowedFun();
}
if (this.userDetails.roles[userRolesIndex] === 'ROLE_ADMIN') {
this.ifAllowed = true;
}
}
}
}
ifAllowedFun() {
let ifRole = false;
for (const roleModifier of this.roleModifiers.body) {
if (roleModifier === 'PC-ABC') {
ifRole = true;
}
}
return ifRole;
}
this is test which I tried but it's failing.
it('should check roles modifiers ', () => {
component.ifAllowed = false;
component.ngOnInit();
spyOn(component, 'checkRoleModifierExists').and.callThrough();
component.userDetails = {
roles: ''
};
component.userDetails.roles = [ 'ROLE_ADMIN_SUPPORT' ];
component.roleModifiers = {
body: [ 'PC-ABC' ]
};
component.checkRoleModifierExists();
expect(component.ifAllowed).toEqual(true);
});
I want to override a function in companyService but have no idea how to do it.
Here is the code in company_service.js and I want to override the start function.
/** #odoo-module **/
import { browser } from "#web/core/browser/browser";
import { registry } from "#web/core/registry";
import { symmetricalDifference } from "#web/core/utils/arrays";
import { session } from "#web/session";
function parseCompanyIds(cidsFromHash) {
const cids = [];
if (typeof cidsFromHash === "string") {
cids.push(...cidsFromHash.split(",").map(Number));
} else if (typeof cidsFromHash === "number") {
cids.push(cidsFromHash);
}
return cids;
}
function computeAllowedCompanyIds(cids) {
const { user_companies } = session;
let allowedCompanyIds = cids || [];
const availableCompaniesFromSession = user_companies.allowed_companies;
const notReallyAllowedCompanies = allowedCompanyIds.filter(
(id) => !(id in availableCompaniesFromSession)
);
if (!allowedCompanyIds.length || notReallyAllowedCompanies.length) {
allowedCompanyIds = [user_companies.current_company];
}
return allowedCompanyIds;
}
export const companyService = {
dependencies: ["user", "router", "cookie"],
start(env, { user, router, cookie }) {
let cids;
if ("cids" in router.current.hash) {
cids = parseCompanyIds(router.current.hash.cids);
} else if ("cids" in cookie.current) {
cids = parseCompanyIds(cookie.current.cids);
}
let allowedCompanyIds = Object.values(session.user_companies.allowed_companies).map(company => company.id);
const stringCIds = allowedCompanyIds.join(",");
router.replaceState({ cids: stringCIds }, { lock: true });
cookie.setCookie("cids", stringCIds);
user.updateContext({ allowed_company_ids: allowedCompanyIds });
const availableCompanies = session.user_companies.allowed_companies;
return {
availableCompanies,
get allowedCompanyIds() {
return allowedCompanyIds.slice();
},
get currentCompany() {
return availableCompanies[allowedCompanyIds[0]];
},
setCompanies(mode, ...companyIds) {
// compute next company ids
let nextCompanyIds;
if (mode === "toggle") {
nextCompanyIds = symmetricalDifference(allowedCompanyIds, companyIds);
} else if (mode === "loginto") {
const companyId = companyIds[0];
if (allowedCompanyIds.length === 1) {
// 1 enabled company: stay in single company mode
nextCompanyIds = [companyId];
} else {
// multi company mode
nextCompanyIds = [
companyId,
...allowedCompanyIds.filter((id) => id !== companyId),
];
}
}
nextCompanyIds = nextCompanyIds.length ? nextCompanyIds : [companyIds[0]];
// apply them
router.pushState({ cids: nextCompanyIds }, { lock: true });
cookie.setCookie("cids", nextCompanyIds);
browser.setTimeout(() => browser.location.reload()); // history.pushState is a little async
},
};
},
};
registry.category("services").remove("company").add("company", companyService);
You can use the patch utility
However, there are situations for which it is not sufficient. In those cases, we may need to modify an object or a class in place. To achieve that, Odoo provides the utility function patch. It is mostly useful to override/update the behavior of some other component/piece of code that one does not control.
Example:
/** #odoo-module **/
import { patch } from "#web/core/utils/patch";
import { companyService } from "#web/webclient/company_service";
patch(companyService, 'module_name.companyService', {
start(env, { user, router, cookie }) {
return this._super(env, { user, router, cookie });
}
});
I'm trying to write a todo list project with pure JS using MVC pattern. It's my first project with MVC and I have a real problem that I can't solve.
I have three buttons, each button gets a value as filter value (in Model class) for complete, active and all task. default value for filter is 0 that refers to all button.
when complete button is active, new todo adds to page, but that page is only for complete todo and new todo must add to all pages while complete page is still active.
I write some methods for handle it, but they doesn't work and I can't understand where is the problem.
how can I solve it?
this is my code:
class Model {
constructor() {
this.todoS = [];
this.filter = 0;
}
bindTodoListChanged(callback) {
this.onTodoListChanged = callback;
}
_commit(todoS) {
this.onTodoListChanged(todoS);
}
addTodo(todoText) {
var todo = {
id:
this.todoS.length > 0
? this.todoS[this.todoS.length - 1].id + 1
: 0,
text: todoText,
complete: false
};
this.todoS.push(todo);
this._commit(this.todoS);
}
toggleTodo(id) {
this.todoS = this.todoS.map(todo =>
todo.id === id
? {
id: todo.id,
text: todo.text,
complete: !todo.complete
}
: todo
);
this._commit(this.todoS);
}
filterTodo(filter) {
this.todoS.filter(todo => {
if (filter === 0) return true;
return filter === 1 ? !todo.complete : todo.complete;
});
}
}
class View {
constructor() {
this.form = document.querySelector("#taskForm");
this.input = document.getElementById("taskInput");
this.list = document.querySelector("#taskList");
this.filterBtnS = document.getElementById("filterButtons");
this.allBtn = document.querySelector(".all");
this.activeBtn = document.querySelector(".active");
this.completeBtn = document.querySelector(".complete");
}
createElement(tag, className) {
var element = document.createElement(tag);
if (className) element.classList.add(className);
return element;
}
getElement(selector) {
var element = document.querySelector(selector);
return element;
}
get _todoText() {
return this.input.value;
}
_resetInput() {
this.input.value = "";
}
displayTodoS(todoS) {
// Faster way for clear tasks
while (this.list.firstChild) {
this.list.removeChild(this.list.firstChild);
}
if (todoS.length !== 0) {
todoS.forEach(todo => {
var li = this.createElement("li", "task"),
span = this.createElement("span");
li.id = todo.id;
var checkbox = this.createElement("input");
checkbox.type = "checkbox";
checkbox.checked = todo.complete;
if (todo.complete) {
var strike = this.createElement("s");
strike.textContent = todo.text;
span.innerHTML = "";
span.append(strike);
} else {
span.textContent = todo.text;
}
li.append(checkbox, span);
this.list.append(li);
});
}
}
bindAddTodo(handler) {
this.form.addEventListener("submit", e => {
e.preventDefault();
if (this._todoText) {
handler(this._todoText);
this._resetInput();
}
});
}
bindToggleTodo(handler) {
this.list.addEventListener("change", event => {
if (event.target.type === "checkbox") {
var id = +event.target.parentElement.id;
handler(id);
}
});
}
bindFilterTodo(handler) {
this.filterBtnS.addEventListener("click", e => {
var filter = +e.target.getAttribute("value");
handler(filter);
});
}
}
class Controller {
constructor(model, view) {
this.model = model;
this.view = view;
this.model.bindTodoListChanged(this.onTodoListChanged);
this.view.bindAddTodo(this.handleAddTodo);
this.view.bindToggleTodo(this.handleToggleTodo);
this.view.bindFilterTodo(this.handleFilterTodo);
this.onTodoListChanged(this.model.todoS);
}
onTodoListChanged = todoS => {
this.view.displayTodoS(todoS);
};
handleAddTodo = todoText => {
this.model.addTodo(todoText);
};
handleToggleTodo = id => {
this.model.toggleTodo(id);
};
handleFilterTodo = filter => {
this.model.filterTodo(filter);
};
}
var app = new Controller(new Model(), new View());
<div id="main">
<h2>Task List</h2>
<form id="taskForm">
<input
id="taskInput"
placeholder="New task..."
autocomplete="off"
/>
<input class="submit" type="submit" value="Add Task" />
</form>
<div id="filterButtons" class="buttons">
<div class="all" value="0">All</div>
<div class="active" value="1">Active</div>
<div class="complete" value="2">Completed</div>
</div>
<ul id="taskList"></ul>
</div>
The issue is that in filterTodo, you just filter the tasks but not _commit the change.
So
Store the filter in the model
Move the filter to _commit (so it will keep filter for any other actions such as add todo)
class Model {
constructor() {
this.todoS = [];
this.filter = 0;
}
bindTodoListChanged(callback) {
this.onTodoListChanged = callback;
}
_commit(todoS = this.todoS) {
this.onTodoListChanged(todoS.filter(todo => {
if (this.filter === 0) return true;
return this.filter === 1 ? !todo.complete : todo.complete;
}));
}
addTodo(todoText) {
var todo = {
id:
this.todoS.length > 0
? this.todoS[this.todoS.length - 1].id + 1
: 0,
text: todoText,
complete: false
};
this.todoS.push(todo);
this._commit(this.todoS);
}
toggleTodo(id) {
this.todoS = this.todoS.map(todo =>
todo.id === id
? {
id: todo.id,
text: todo.text,
complete: !todo.complete
}
: todo
);
this._commit(this.todoS);
}
filterTodo(filter) {
this.filter = filter;
this._commit();
}
}
class View {
constructor() {
this.form = document.querySelector("#taskForm");
this.input = document.getElementById("taskInput");
this.list = document.querySelector("#taskList");
this.filterBtnS = document.getElementById("filterButtons");
this.allBtn = document.querySelector(".all");
this.activeBtn = document.querySelector(".active");
this.completeBtn = document.querySelector(".complete");
}
createElement(tag, className) {
var element = document.createElement(tag);
if (className) element.classList.add(className);
return element;
}
getElement(selector) {
var element = document.querySelector(selector);
return element;
}
get _todoText() {
return this.input.value;
}
_resetInput() {
this.input.value = "";
}
displayTodoS(todoS) {
// Faster way for clear tasks
while (this.list.firstChild) {
this.list.removeChild(this.list.firstChild);
}
if (todoS.length !== 0) {
todoS.forEach(todo => {
var li = this.createElement("li", "task"),
span = this.createElement("span");
li.id = todo.id;
var checkbox = this.createElement("input");
checkbox.type = "checkbox";
checkbox.checked = todo.complete;
if (todo.complete) {
var strike = this.createElement("s");
strike.textContent = todo.text;
span.innerHTML = "";
span.append(strike);
} else {
span.textContent = todo.text;
}
li.append(checkbox, span);
this.list.append(li);
});
}
}
bindAddTodo(handler) {
this.form.addEventListener("submit", e => {
e.preventDefault();
if (this._todoText) {
handler(this._todoText);
this._resetInput();
}
});
}
bindToggleTodo(handler) {
this.list.addEventListener("change", event => {
if (event.target.type === "checkbox") {
var id = +event.target.parentElement.id;
handler(id);
}
});
}
bindFilterTodo(handler) {
this.filterBtnS.addEventListener("click", e => {
var filter = +e.target.getAttribute("value");
handler(filter);
});
}
}
class Controller {
constructor(model, view) {
this.model = model;
this.view = view;
this.model.bindTodoListChanged(this.onTodoListChanged);
this.view.bindAddTodo(this.handleAddTodo);
this.view.bindToggleTodo(this.handleToggleTodo);
this.view.bindFilterTodo(this.handleFilterTodo);
this.onTodoListChanged(this.model.todoS);
}
onTodoListChanged = todoS => {
console.log(todoS);
this.view.displayTodoS(todoS);
};
handleAddTodo = todoText => {
this.model.addTodo(todoText);
};
handleToggleTodo = id => {
this.model.toggleTodo(id);
};
handleFilterTodo = filter => {
this.model.filterTodo(filter);
};
}
var app = new Controller(new Model(), new View());
<div id="main">
<h2>Task List</h2>
<form id="taskForm">
<input id="taskInput" placeholder="New task..." autocomplete="off" />
<input class="submit" type="submit" value="Add Task" />
</form>
<div id="filterButtons" class="buttons">
<div class="all" value="0">All</div>
<div class="active" value="1">Active</div>
<div class="complete" value="2">Completed</div>
</div>
<ul id="taskList"></ul>
</div>
https://stackblitz.com/edit/js-1u6dxi
I suspect the biggest issues in the returning of values. For example this:
handleFilterTodo = filter => {
this.model.filterTodo(filter);
};
This code does not return anything, it only calls this.model.filterTodo. In the corresponding method filterTodo, you are creating a new array by using this.todoS.filter but you do not return it anywhere:
filterTodo(filter) {
this.todoS.filter(todo => {
if (filter === 0) return true;
return filter === 1 ? !todo.complete : todo.complete;
});
}
You could do something like what you did with toggleTodo and the map function here:
filterTodo(filter) {
this.todoS = this.todoS.filter(todo => {
if (filter === 0) return true;
return filter === 1 ? !todo.complete : todo.complete;
});
}
...but that would only work once, as setting the filter would remove the other todos from your database.
From my understanding of the code (without trying it out), I'd probably set the filter only and whenever _commit gets called, pass the filtered version of the todos based on the selected filter
constructor() {
...
this.possibleFilters = {
0: () => true,
1: todo => !todo.completed,
2: todo => todo.completed
};
}
filterTodo(filter) {
this.filter = filter;
}
_commit(todoS) {
const selectedFilter = this.possibleFilters[this.filter];
this.onTodoListChanged(todoS.filter(selectedFilter));
}
export class EstimateForm extends React.Component<IEstimateFormProps,
IEstimateFormState> {
state: IEstimateFormState = {
cellUpdateCss: 'red',
toRow: null,
fromRow: null,
estimateList: null,
estimateItemList: [],
poseList: null,
levelList: null,
partList: null,
selectedEstimate: null,
totalEstimateItems: 0,
selectedIndexes: [],
totalEstimateAmount: 0,
grid: null,
projectId: 0,
};
constructor(props, context) {
super(props, context);
this.state.estimateList = this.props.estimateList;
}
rowGetter = i => {
const row = this.state.estimateItemList[i];
const selectRevison = this.state.selectedEstimate.revision;
if (row['pose.poseName']) {
const poseCode = row['pose.poseName'].substring(row['pose.poseName'].lastIndexOf('[') + 1, row['pose.poseName'].lastIndexOf(']'));
for (const pose of this.state.poseList) {
if (pose.poseCode === poseCode) {
row.pose = pose;
}
}
}
if (row['level.levelName']) {
const levelCode = row['level.levelName'].substring(
row['level.levelName'].lastIndexOf('[') + 1,
row['level.levelName'].lastIndexOf(']')
);
for (const level of this.state.levelList) {
if (level.levelCode === levelCode) {
row.level = level;
}
}
}
if (row['level.part.partName']) {
const partCode = row['level.part.partName'].substring(
row['level.part.partName'].lastIndexOf('[') + 1,
row['level.part.partName'].lastIndexOf(']')
);
for (const part of this.state.partList) {
if (part.partCode === partCode) {
row.part = part;
}
}
}
row.get = key => eval('row.' + key);
row.totalCost = (row.materialCost + row.laborCost) * row.amount;
if (row.revision > selectRevison) {
for (let i = 0; i < row.length; i++) {
row[i].style.color = 'red'; // here color is nor change
}
return row;
} else {
return row;
}
}
handleGridRowsUpdated = ({ fromRow, toRow, updated }) => {
const rows = this.state.estimateItemList.slice();
for (let i = fromRow; i <= toRow; i++) {
const rowToUpdate = rows[i];
const updatedRow = update(rowToUpdate, { $merge: updated });
rows[i] = updatedRow;
}
this.setState({ estimateItemList: rows, fromRow: (fromRow), toRow: (toRow)
}, () => {
});
};
saveEstimateItems = () => {
if (this.state.selectedEstimate == null) {
toast.warn(<Translate
contentKey="bpmApp.estimateForm.pleaseSelectEstimate">Please select an
estimate</Translate>);
return;
}
render() {
return ()
}
I wanna to change the row color when the condition row.revision > this.state.selectedEstimate.revision . How can I prevent the change of this.color. However im not get any error but row color is not change. how can i solve this problem it is my first project in react and i dont know where is the problemThanks for your feedback guys.
export class EstimateForm extends React.Component<IEstimateFormProps,
IEstimateFormState> {
state: IEstimateFormState = {
cellUpdateCss: 'red',
toRow: null,
fromRow: null,
estimateList: null,
estimateItemList: [],
poseList: null,
levelList: null,
partList: null,
selectedEstimate: null,
totalEstimateItems: 0,
selectedIndexes: [],
totalEstimateAmount: 0,
grid: null,
projectId: 0,
};
constructor(props, context) {
super(props, context);
this.state.estimateList = this.props.estimateList;
}
rowGetter = i => {
const row = this.state.estimateItemList[i];
const selectRevison = this.state.selectedEstimate.revision;
if (row['pose.poseName']) {
const poseCode =
row['pose.poseName'].substring(row['pose.poseName'].lastIndexOf('[') + 1,
row['pose.poseName'].lastIndexOf(']'));
for (const pose of this.state.poseList) {
if (pose.poseCode === poseCode) {
row.pose = pose;
}
}
}
if (row['level.levelName']) {
const levelCode = row['level.levelName'].substring(
row['level.levelName'].lastIndexOf('[') + 1,
row['level.levelName'].lastIndexOf(']')
);
for (const level of this.state.levelList) {
if (level.levelCode === levelCode) {
row.level = level;
}
}
}
if (row['level.part.partName']) {
const partCode = row['level.part.partName'].substring(
row['level.part.partName'].lastIndexOf('[') + 1,
row['level.part.partName'].lastIndexOf(']')
);
for (const part of this.state.partList) {
if (part.partCode === partCode) {
row.part = part;
}
}
}
row.get = key => eval('row.' + key);
row.totalCost = (row.materialCost + row.laborCost) * row.amount;
const changeColor = {
backgroundcolor: 'red'
};
const all = document.getElementsByClassName('react-grid-Row') as
HTMLCollectionOf<HTMLElement>;
debugger; if (row.revision > selectRevison) {
for (let i = this.state.fromRow; i <= this.state.toRow; i++) {
all[i].style.color = 'red'; //HERE
}
return row;
}
}
handleGridRowsUpdated = ({ fromRow, toRow, updated }) => {
const rows = this.state.estimateItemList.slice();
for (let i = fromRow; i <= toRow; i++) {
const rowToUpdate = rows[i];
const updatedRow = update(rowToUpdate, { $merge: updated });
rows[i] = updatedRow;
}
this.setState({ estimateItemList: rows, fromRow: (fromRow), toRow: (toRow)
}, () => {
});
};
saveEstimateItems = () => {
if (this.state.selectedEstimate == null) {
toast.warn(<Translate
contentKey="bpmApp.estimateForm.pleaseSelectEstimate">Please select an
estimate</Translate>);
return;
}
render() {
return ()
}
I wanna to change the row color when the condition row.revision > this.state.selectedEstimate.revision . How can I prevent the change of this.color. However TypeError: Cannot read property 'style' of undefined get error but row color is not change. how can i solve this problem it is my first project in react and i dont know where is the problemThanks for your feedback guys.
Okay, so without the rest of the context because your pasted code is difficult to read and understand, the simplest reason for your issue is in this chunk:
const all = document.getElementsByClassName('react-grid-Row') as
HTMLCollectionOf<HTMLElement>;
debugger; if (row.revision > selectRevison) {
for (let i = this.state.fromRow; i <= this.state.toRow; i++) {
all[i].style.color = 'red'; //HERE
}
Essentially there's multiple things that could go wrong here, but most likely there are either no rows with that class on the page, or less than your this.state.fromRow, I see you've got the debugger in there, but you are missing a few things:
You aren't doing a null check on all to make sure you are finding something
You aren't checking whether all.length > this.state.fromRow
You aren't breaking the for loop if all.length < this.state.toRow
It's failing because all[i] doesn't exist, or there's no values:
all = [0, 1]
and you are looking for all[3] for example
Throw in those fallbacks and check what all is on page load and you should be able to figure it out.