ng_change doesn't copy time value of angular-moment-picker into other fields - angularjs

I have a dynamically generated form with a time field which is filled in with angular-moment-picker. I want this value to be copied to the other time fields using a function assigned to ng_change. Currently this function is not called however my input field includes ng_change. When I don't use moment-picker then value is copied without any issues.
input field:
#Html.TextBoxFor(model => model.Mymodels.Model[i].Time,
new
{
#class = "form-control",
ng_Model = "Model_Time" + (i + 1),
ng_change = "copyTime(" + (i + 1) + ")",
moment_picker = "Model_Time" + (i + 1),
format = "LT",
locale = "nl",
ng_model_options = "{ updateOn: 'blur' }",
set_on_select = true
})
Copy function:
$scope.copyTime = function (index) {
console.log("Check if function is called");
$scope.Model_Time2 = $scope.Model_Time1;
$scope.Model_Time3 = $scope.Model_Time1;
$scope.Model_Time4 = $scope.Model_Time1;
};

According to the docs, it has its own function called change:
#Html.TextBoxFor(model => model.Mymodels.Model[i].Time,
new
{
change = "copyTime(" + (i + 1) + ")"
// ...
})
That said, if angular-moment is using ngModelController underneath to update the model, I'd have expected ng-change to work as well since it is invoked automatically once the model has changed. Maybe it doesn't play nice with ng-model-options?

Related

Need a helping hand on Creatable - Select in React

I am trying to have a React-Select which adds a custom option by giving manual inputs and I am trying it to have a Multi drop-down.
Below is my code that I tried. I want to send this in a JSON format along with few other data.
`<CreatableSelecttype="text"class="amat-form-control"isMultioptions={showSpecificationMaterial}id="subtierspecificationmaterial"name="subtierspecificationmaterial"isSearchable={true}closeMenuOnSelect={true}isClearable// value={showSpecificationMaterial.filter(// ({ value }) => value === data.specificationmaterial// )}value={showSpecificationMaterial}placeholder="Specification/Material"onChange={(e) => {setFormData(showSpecificationMaterial)controlChanges()}}onBlur={(e) => onBlur1(e)}></CreatableSelect>
This is my OnChange Event:
const onChangeSubTier = (event) => {console.log("Multi Check")console.log(event);let selected = [];let specmaterialControl = "";let specmaterialtext = "";
if (event.length > 0) {
event.forEach(element => {
selected.push(element.value);
specmaterialControl = specmaterialControl + "," + element.value;
specmaterialtext = specmaterialtext + "," + element.label;
});
}
//setSpecificationmaterialvalue(selected);
console.log(specificationmaterialvalue);
//specificationmaterialvalue.push(event[0]);
console.log(event[0]);
specmaterialControl = specmaterialControl.slice(1)
specmaterialtext = specmaterialtext.slice(1)
formData.specificationmaterial = specmaterialtext;
formData.specmaterialControl = specmaterialControl;
setSpecificationmaterialvalue(selected)
setControlSelectedvalue(selected);
setFormData(formData)
}`

Redux Form Async validation infinite recursion

I use redux-form#7.0.4 in my application. There is some fields where i need to define a validate function dynamically.
Note that I need id and slice to look for the correct field in values
<Field
component={SemanticFormField}
as={Input}
placeholder="From"
name={"participation-card-" + id + "-slice-" + slice + "-min"}
validate={[number]}
/>
<Field
component={SemanticFormField}
as={Input}
placeholder="to"
name={"participation-card-" + id + "-slice-" + slice + "-max"}
validate={[number, validateMaxSlice(slice, id)]}
/>
When i define validateMaxSlice like this
const validateMaxSlice = (slice, id) => (value, values) => {
const min = values["participation-card-" + id + "-slice-" + slice + "-min"];
return min >= value ? "Invalid slice" : undefined;
};
Or inline like this
validate={[number, (value, values) => {
const min = values["participation-card-" + id + "-slice-" + slice + "-min"];
return min >= value ? "Invalid slice" : undefined;}]
The application goes in an infinite loop the moment it renders the component.
The question is why and how to fix it ?
Edit:
Thank you for your help ! Here is how I implement it
Container part:
createSlice() {
const id = uuidv4();
return {
id,
validators: (value, values) => {
const min = values["participation-card-" + this.props.id + "-slice-" + id + "-min"];
return valSup(value, "Tranche incorrecte")(min);
},
};
}
addParticipationSlice() {
let participationSlices = this.state.participationSlices;
participationSlices.push(this.createSlice());
this.setState({
participationSlices,
});
}
Scene part:
<Field
component={SemanticFormField}
as={Input}
name={"participation-card-" + id + "-slice-" + slice.id + "-max"}
size="mini"
width={7}
validate={[number, slice.validators]}
/>
As you are creating validators on the fly, it create a new validator instance every time it redraw.
On the first redraw, React try to validate the value, then redraw to update the view. This, in turn, create a new validate function and change the related props value.
As you change the props to the component, react will trigger a re-render of the Field. Thus causing it to revalidate again, causing again a re-render.
One way to correct it is to generate one and only one version of each callback, reusing functions instances when appropriate.
You can for example store a this.validators associative array then change your function generator to something like this:
validateMaxSlice(slice, id) => {
if (!this.validators[`${slice}-${id}`]) {
this.validators[`${slice}-${id}`] = (value, values) => { ...Actual validation code... }
}
return this.validators[`${slice}-${id}`]
}
This way, validators are created on the fly but reused where they need to be.

Angular function

I need to execute a function inside ng-repeat to convert date. How can i parse a angular result in a function?
Field name in database is dataf
I tried diferent ways but no one works...
<tr ng-repeat="detail in details| filter:search_query">
<td><b>{{detail.nom}}</b></td>
<td>{{detail.descripcio}}</td>
<td>{{datareves(detail.datafet) }} </td>
<td>{{detail.visible}}</td>
and
getInfo();
function getInfo(){
$http.post('empDetails.php').success(function(data){
$scope.details = data;
});
}
$scope.datareves = function(details.datafet) {
var res = dataf.split(" ");
var res2 = res[0].split("-");
var final = res2[2] + "-" + res2[1] + "-" + res2[0];
return (final);
};
Your function should look like this
$scope.datareves = function(dataf) {
var res = dataf.split(" ");
var res2 = res[0].split("-");
var final = res2[2] + "-" + res2[1] + "-" + res2[0];
return (final);
};
notice the change to the first line. The name of the variable you used in the function was not the same as the name being passed into the function.
You can read more about javascript function definitions here https://www.w3schools.com/js/js_function_definition.asp

addEventListener(object[i]) in for loop gives me one object not multiple

i am making a leaderboard for a game. this leaderboard gets its scores from the an array. but when i add the eventListener i get only one of the object from the array.
this is mine object array:
[{gamenr:1,naam:"wilbert", score:60},{gamenr:1,naam:"joost", score:20},
{gamenr:2,naam:"harry", score:50},{gamenr:2,naam:"john", score:10},
{gamenr:3,naam:"carl", score:30},{gamenr:3,naam:"dj", score:16}]
code:
public function toonHighscoreArray():Array {
highScoreTabel.sortOn(["score"], [Array.NUMERIC]).reverse();//get highest score on top
var returnArray:Array = new Array();
for ( var i:int = 0; i < 6; i++ ) {
var scores:TextField = new TextField();
scores.addEventListener(MouseEvent.CLICK, function(e:MouseEvent){toon2deSpeler(highScoreTabel[i])});
scores.y = (i * 50) - 50;
scores.height = 50;
scores.text = "" + (i + 1) + ".\t" + highScoreTabel[i].naam + " met " + highScoreTabel[i].score + " punten.";
scores.autoSize = "left";
returnArray.push(scores);
}
return returnArray;
}
private function toon2deSpeler(score:Object) {
trace(score.naam);
}
i want the function toon2deSpeler to trace wilbert when i click the textfield where wilbert is in the textfield is clicked and harry when harry's textfield is clicked
but it gives me joost when i click wilbert but also when i click harry or joost ect.
how do i get the right object as parameter in toon2deSpeler?
Closures inside loops are not going to work as you expect, once the event handler is called it will use the last value of i.
Change your for loop to this :
for ( var i:int = 0; i < 6; i++ ) {
var scores:TextField = new TextField();
addScoreListener(scores, i);
scores.y = (i * 50) - 50;
scores.height = 50;
scores.text = "" + (i + 1) + ".\t" + highScoreTabel[i].naam + " met " + highScoreTabel[i].score + " punten.";
scores.autoSize = "left";
returnArray.push(scores);
}
private function addScoreListener(score:TextField, index:int):void
{
scores.addEventListener(MouseEvent.CLICK, function(e:MouseEvent):void{
toon2deSpeler(highScoreTabel[index]);
});
}
Functions run in the scope in which they were created (See this page on Function scope), so your inline listener:
function(e:MouseEvent){toon2deSpeler(highScoreTabel[i])}
is using the i from toonHighscoreArray(), not it's "own" copy of i. Given your code there though, you would be getting a null object reference instead of "joost", as you're trying to access highScoreTabel[6].
I would really recommend extending TextField and creating objects with the properties from highScoreTabel, then using Barış Uşaklı's method. However, it is possible to create each listener function in its own scope like this:
function getScoreClickListener(scoreID:uint):Function {
return function(e:MouseEvent){toon2deSpeler(highScoreTabel[scoreID])}
}
Then use that when adding your even listener:
scores.addEventListener(MouseEvent.CLICK, getScoreClickListener(i));
This makes it difficult to remove the event listeners later though, so you'd need to keep track of them separately.

How can I make a grid with checkboxes that maintain state between page loads?

How can we make checkboxes remain checked when the page is refreshed in a Sencha ExtJS 3.3.0 GridPanel?
I have a GridPanel which displays some information with checkboxes. When the page is refreshed, the checkbox should still be checked.
Any suggestions, ideas, or code samples?
Had the same problem and I fixed it in such way - manually save id's of records that I show in cookies. Solution is not beautiful, but works for me.
store.on({
'beforeload': function () {
var checkeditems = [];
for(var i=0;i<gridResources.selModel.selected.length;i++)
{ checkeditems.push(grid.selModel.selected.items[i].data.ID);
}
if(checkeditems.length>0)
setCookie("RDCHECKBOXES", checkeditems.join("|"));
},
'load': function () {
if (getCookie("RDCHECKBOXES")) {
var checkeditems = getCookie("RDCHECKBOXES").split("|");
for (var i = 0; i<gridResources.store.data.items.length && checkeditems.length>0; i++) {
for(var j=0;j<checkeditems.length;j++) {
if (gridResources.store.data.items[i].data.ID == checkeditems[j]) {
gridResources.selModel.select(gridResources.store.data.items[i], true);
checkeditems.splice(j, 1);
break;
}
}
}
}
}
});
Here are code for functions getCookie() and setCookie():
// Example:
// setCookie("foo", "bar", "Mon, 01-Jan-2001 00:00:00 GMT", "/");
function setCookie (name, value, expires, path, domain, secure) {
document.cookie = name + "=" + escape(value) +
((expires) ? "; expires=" + expires : "") +
((path) ? "; path=" + path : "") +
((domain) ? "; domain=" + domain : "") +
((secure) ? "; secure" : "");
}
// Example:
// myVar = getCookie("foo");
function getCookie(name) {
var cookie = " " + document.cookie;
var search = " " + name + "=";
var setStr = null;
var offset = 0;
var end = 0;
if (cookie.length > 0) {
offset = cookie.indexOf(search);
if (offset != -1) {
offset += search.length;
end = cookie.indexOf(";", offset)
if (end == -1) {
end = cookie.length;
}
setStr = unescape(cookie.substring(offset, end));
}
}
return(setStr);
}
Have you looked at all at the ExtJS documentation or the included samples? There's a sample grid using the CheckColumn extension that does exactly what you ask.
In the example linked, take note that the checkbox column is linked to a boolean record field
// in your record
{name: 'indoor', type: 'bool'}
and represented in the grid's column model by a CheckColumn:
// in the grid's column model
xtype: 'checkcolumn',
header: 'Indoor?',
dataIndex: 'indoor',
width: 55
This way, when boolean data comes into the store from the server in JSON or XML, the values are represented as checkboxes in the grid. As long as you write your changes to the server, your checkbox boolean values will be preserved.

Resources