How can i display a confirmation alert only if i want to change radio button on previous step? So if i confirm my action all steps below should be removed.
I've binded a #change directive to the radio button with a method implementing the expected confirmation alert, but it appears on each change i make.
Here is my fiddle
Thanks for your advices in advance
new Vue({
el: "#app",
data() {
return {
answer: ["1"],
stepsData: [
{
id: "1",
yes_section: "2",
no_section: "4",
name: "Step 1",
},
{
id: "2",
yes_section: "5",
no_section: "1",
name: "Step 2",
},
{
id: "3",
yes_section: "2",
no_section: "4",
name: "Step 3",
},
{
id: "4",
yes_section: "2",
no_section: "4",
name: "Step 4",
},
{
id: "5",
yes_section: "2",
no_section: "4",
name: "Step 5",
},
],
};
},
computed: {
quation() {
return this.answer.map((answer) => {
return this.stepsData.find((step) => step.id === answer);
});
},
},
methods: {
pushAnswer(answer) {
this.answer.push(answer);
},
confirmPopup() {
alert('Are you sure?')
},
},
});
.step {
background: #ccc;
padding: 20px;
margin-bottom: 15px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div v-for="(step, id) in quation" :key="id" class="step">
<div v-html="step.name"></div>
<div>
<input
type="radio"
:id="step.UF_NO_SECTION"
:name="step.ID"
:value="step.yes_section"
#click="pushAnswer(step.yes_section)"
#change="confirmPopup"
/>
<label
:for="step.UF_NO_SECTION"
class="legal-aid__step-btn button _outline _no"
>
YES {{ step.yes_section }}
</label>
</div>
<div class="legal-aid__step-action_no">
<input
type="radio"
:id="step.UF_NO_SECTION"
:name="step.ID"
:value="step.no_section"
#click="pushAnswer(step.no_section)"
#change="confirmPopup"
/>
<label
:for="step.UF_NO_SECTION"
class="legal-aid__step-btn button _outline _no"
>
NO {{ step.no_section }}
</label>
</div>
</div>
</div>
I would add a property on every stepData that is called isSelected which will be initialized to false and once it was clicked, it will be changed to true.
So you data will look like this:
stepsData: [
{
id: "1",
yes_section: "2",
no_section: "4",
name: "Step 1",
isSelected: false
},
....
]
You will need to change pushAnswer to set isSelected to `true:
#click="pushAnswer(step)"
pushAnswer(answer) {
answer.isSelected = true;
this.answer.push(answer.yes_section);
},
And confirmPopup function will check if the answer is already selcted or not:
#change="confirmPopup(step)"
confirmPopup(step) {
if (step.isSelected) {
alert('Are you sure?')
}
},
Of course you can change anything to your liking, but this is the basic idea
Related
HelloWorld.vue
<template>
<div>
<div v-for="(piza, index) in pizas" :key="piza.pname">
{{ piza.pname }}
<List
:content="matchpizza"
:pname="piza.pname"
:qname="quantitys[index] ? quantitys[index].qname : ''"
/>
</div>
</div>
</template>
<script>
import List from "./List.vue";
export default {
name: "HelloWorld",
components: {
List,
},
data() {
return {
pizas: [
{
pname: "chicken pizza",
},
{
pname: "chicken pizza spl",
},
{
pname: "mutton pizza",
},
{
pname: "plain pizza",
},
],
quantitys: [
{
qname: "one",
},
{
qname: "two",
},
{
qname: "three",
},
{
qname: "four",
},
{
qname: "five",
},
],
matchpizza: [
{
matchnum: "1",
availability: "later",
pname: "plain pizza",
qname: "five",
},
{
matchnum: "2",
availability: "buy now",
pname: "chicken pizza",
qname: "one",
},
{
matchnum: "3",
availability: "buy now",
pname: "plain pizza",
qname: "five",
},
{
matchnum: "4",
availability: "buy now",
pname: "chicken pizza spl",
qname: "five",
},
{
matchnum: "5",
availability: "later",
pname: "mutton pizza",
qname: "five",
},
],
};
},
};
</script>
List.vue
<template>
<div>
<div v-if="matchpizza.length > 0">
<div
v-for="match in matchpizza"
:key="match.matchnum"
:class="{
green: match.availability === 'buy now',
red: match.availability === 'later',
}"
>
<div v-for="quantity in quantitys" :key="quantity.qname">
{{ quantity.qname }}
</div>
<div class="next-data-two">{{ match.availability }}</div>
</div>
</div>
<div v-else class="next-data"><p>No availability</p></div>
</div>
</template>
<script>
export default {
components: {},
props: {
content: {
type: Array,
required: true,
},
pname: {
type: String,
required: true,
},
qname: {
type: String,
required: true,
},
},
data: function () {
return {};
},
methods: {},
computed: {
quantitys() {
return this.content.filter((a) => a.qname === this.qname);
},
matchpizza() {
return this.content.filter((a) => a.pname === this.pname);
},
},
};
</script>
<style scoped>
.next-data {
display: flex;
flex-direction: row-reverse;
margin-top: -2%;
margin-right: 40%;
color: blue;
}
.next-data-two {
display: flex;
flex-direction: row-reverse;
margin-top: -1%;
margin-right: 42%;
color: red;
margin-bottom: 1%;
}
</style>
See my working code here:-
https://codesandbox.io/s/data-display-tcr8oj?file=/src/components/HelloWorld.vue
From the helloworld.vue you can see this line :qname="quantitys[index] ? quantitys[index].qname : ''"
Where as per the above code, from the quantitys array. it is not pointing to the particular index value correctly?.
According to my output from codesandbox:-
For chicken pizza it showing as , chicken pizza --> one --> later
But correct path is, chicken pizza --> later --> five
Similarly for others too, having same issue....
Is it because of index position wrong or issue with logic??
As you mentioned your required pathe is chicken pizza --> later --> five.
This path doesnot have to do anything with the quantitys array. You could simply display the details using the content prop itself.
Working Fiddle https://codesandbox.io/s/data-display-forked-kjxuyv
I'm working with form that contain select element. I need to fill select with the data coming via json format. How to use jquery template to fill the select element?
I read about jquery template, it's documentation. But still can't get right result.
2 question: Is it good way to use jQuery Template for big data, for example: 4000 columns?
<div class="col-lg-5">
<select id="sel"></select>
</div>
<script id="optionTmpl" type="text/x-jquery-tmpl">
{{each $options}}
<option value="${$code}">${$title}</option>
{{/each}}
</script>
var options = [
{ code: "1", title: "A" },
{ code: "2", title: "B" },
{ code: "3", title: "C" },
{ code: "4", title: "D" },
{ code: "5", title: "E" },
];
$('#optionTmpl').tmpl(options).appendTo('#sel');
You may have a little change in the code as follows,
var options = [
{ code: "1", title: "A" },
{ code: "2", title: "B" },
{ code: "3", title: "C" },
{ code: "4", title: "D" },
{ code: "5", title: "E" },
];
$('#optionTmpl').tmpl(options).appendTo('#sel');
<!-- These are added to execute the code -->
<script src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.4.4.min.js" type="text/javascript"></script>
<script src="http://ajax.aspnetcdn.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js" type="text/javascript"></script>
<div class="col-lg-5">
<select id="sel"></select>
</div>
<!--
These was your code,
<script id="optionTmpl" type="text/x-jquery-tmpl">
{{each $options}}
<option value="${$code}">${$title}</option>
{{/each}}
</script>
which is changed to =>
-->
<script id="optionTmpl" type="text/x-jquery-tmpl">
<option value="${code}">${title}</option>
</script>
If your json format is fixed from server side then you can try this.
var options = [
{ code: "1", title: "A" },
{ code: "2", title: "B" },
{ code: "3", title: "C" },
{ code: "4", title: "D" },
{ code: "5", title: "E" },
];
$.each(options , function(i, obj){
$('#select').append($('<option>').text(obj.title).attr('value', obj.code));
});
we can also append the json to the input type select field if the key and value are same like this.
Reference : https://jocapc.github.io/jquery-view-engine/
var options = [ "A" ,"B" ,"C" ,"D"];
$('#myselect').view(json);
Variables in template are defined incorrectly
${$code} should be ${code}
You can use the following method instead of a for loop as explained in the plugin
$(document).ready(function() {
var options = [
{ code: "1", title: "A" },
{ code: "2", title: "B" },
{ code: "3", title: "C" },
{ code: "4", title: "D" },
{ code: "5", title: "E" },
];
var markup = '<option value="${code}">${title}</option>';
// Compile the markup as a named template
$.template( "optionsTemplate", markup );
// Render the template with the options data and insert
// the rendered HTML under the "sel" element
$.tmpl("optionsTemplate", options ).appendTo("#sel");
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.2.4/jquery.min.js"></script>
<script src="http://ajax.microsoft.com/ajax/jquery.templates/beta1/jquery.tmpl.min.js"></script>
<div class="col-lg-5">
<select id="sel"></select>
</div>
But I have problem when I checked radio button doesn't change ng-model="title"
I changed this code a lot but I can not find a solution. Can someone help, I think there is a problem here in ng-repeat?
Can someone help solve this problem?
I have code:
<div class="container">
<label data-ng-repeat="option in dbQuestion">
<input type="radio" name="form-field" ng-model="title" value="{{option.title}}" ng-checked="$index == 0" />
{{option.title}}
</label>
<span>{{title}}</span>
</div>
__
var app = angular.module("SampleApp", []);
app.controller("SampleAppCtrl", function($scope) {
$scope.dbQuestion = [{
title: "Question 1",
descripton: "Description 1",
answers: [{
item1: "item1",
value: true
},
{ item2: "item2", value: true },
{ item3: "item3", value: true },
{
item4: "item4",
value: true
}
]
},
{
title: "Question 5",
descripton: "Description 5",
answers: [{
item1: "item1",
value: true
},
{ item2: "item2", value: true },
{ item3: "item3", value: true },
{
item4: "item4",
value: true
}
]
},
];
$scope.title = $scope.dbQuestion[0].title;
});
New AngularJS developers often do not realize that ng-repeat, ng-switch, ng-view, ng-include and ng-if all create new child scopes, so the problem often shows up when these directives are involved. (See this example for a quick illustration of the problem.)
This issue with primitives can be easily avoided by following the "best practice" of always have a '.' in your ng-models – watch 3 minutes worth. Misko demonstrates the primitive binding issue with ng-switch.
Having a '.' in your models will ensure that prototypal inheritance is in play. So, use
<label data-ng-repeat="option in dbQuestion">
<input type="radio" name="form-field"
ng-model="title.selected"
value="{{option.title}}"
ng-checked="$index == 0" />
{{option.title}}<br>
</label>
<p>Selected - {{title.selected}}</p>
app.controller("ctrl", function($scope) {
$scope.title = { selected: ''};
$scope.dbQuestion = [{ /*..*/ }];
});
For more information, see AngularJS Wiki - The Nuances of Scope Prototypal Inheritance.
The DEMO
angular.module("app", [])
.controller("ctrl", function($scope) {
$scope.title = { selected: ''};
$scope.dbQuestion = [{
title: "Question 1",
descripton: "Description 1",
answers: [{
item1: "item1",
value: true
},
{ item2: "item2", value: true },
{ item3: "item3", value: true },
{
item4: "item4",
value: true
}
]
},
{
title: "Question 5",
descripton: "Description 5",
answers: [{
item1: "item1",
value: true
},
{ item2: "item2", value: true },
{ item3: "item3", value: true },
{
item4: "item4",
value: true
}
]
},
];
});
<script src="//unpkg.com/angular/angular.js"></script>
<body ng-app="app" ng-controller="ctrl">
<div class="container">
<label data-ng-repeat="option in dbQuestion">
<input type="radio" name="form-field"
ng-model="title.selected"
value="{{option.title}}"
ng-checked="$index == 0" />
{{option.title}}<br>
</label>
<p>Selected - {{title.selected}}</p>
</div>
</body>
You need to use $parent.title instead of title, like this :
<input type="radio" name="form-field" ng-model="$parent.title" value="{{option.title}}" ng-checked="$index == 0" />
ng-repeat creates its own scope and in order to assign the value to the parent scope from the child scope we need to use $parent
I have recently started learning KendoUI and have come up with this issue. I am trying to include a dropdownlist in kendo grid using MVVM approach. The grid has 3 columns- Checkbox, text and dropdownlist. I want to manually set the dropdownlist value based on whether the checkbox is checked or not. As an example here i am trying to set the Class as 'Class 3' if checkbox is unchecked. Even though index is set to 2, it gets reverted back to the class from the model at the end of the event dataBound. Can anyone help me with this? I need to forcefully set the dropdown index. Thank you.
<script type="text/x-kendo-template" id="checkboxGrid">
<input type="checkbox" data-bind="checked: IsChecked" />
</script>
<script type="text/x-kendo-template" id="ddlGrid">
<input data-role="dropdownlist"
data-auto-bind="true"
data-text-field="name"
data-value-field="id"
data-auto-bind="true"
data-bind="source: actionSource, value: class, events:{dataBound: dataBound }"/>
</script>
<div id="content" >
<div id="my-grid"
data-role="grid"
data-sortable="true"
data-selectable="true"
data-columns='[
{"field": "IsChecked", "title":" ", template: kendo.template($("#checkboxGrid").html())},
{"field": "Name", "title":"Name" },
{"field": "class", "title":"Class", template: kendo.template($("#ddlGrid").html())}
]'
data-bind="source: dataSource">
</div>
</div>
<script>
$(document).ready(function() {
var viewModel = new kendo.data.ObservableObject({
dataSource: [
{ IsChecked: true, Name: "Student 1", class: { name: "Class 1", id:"1" }},
{ IsChecked: false, Name: "Student 2", class: { name: "-Please Select-", id:"999" } },
{ IsChecked: false, Name: "Student 3", class: { name: "-Please Select-", id:"999" }},
{ IsChecked: true, Name: "Student 4", class: { name: "Class 3", id:"3" } }
],
actionSource: [
{ name: "-Please Select-", id:"999"},
{ name: "Class 1", id:"1" },
{ name: "Class 2", id:"2" },
{ name: "Class 3", id:"3" }
],
dataBound: function(e) {
var ddl = e.sender;
var gridRow = $(ddl.element).closest( "tr" );
var checkbox = $(gridRow).find('input[type=checkbox]');
debugger;
if(checkbox.prop("checked") == false){
console.log("Checkbox checked : " + false);
//explicitly trying to set class to 'Class 3'
ddl.select(2);
debugger;
}
//Even though index is set to 2, it gets reverted back to the class from the model at the end of the event
}
});
kendo.bind($('#my-grid'), viewModel);
});
</script>
I have the below JS:
function RowData(Township, Range, Section,Crop, Acres) {
var self = this;
self.Township = Township;
self.Range = Range;
self.Section = Section;
self.Crop = [{ value: "1", crop: "Irrigated Corn" }, { value: "2", crop: "Irrigated Sugar Beets" }, { value: "3", crop: "Irrigated Soybeans" }, { value: "4", crop: "Irrigated Sorghum (Milo, Sudan)" }, { value: "5", crop: "Irrigated Dry Edible Beans" }, { value: "6", crop: "Irrigated Potatoes" }, { value: "7", crop: "Irrigated Alfalfa" }, { value: "8", crop: "Irrigated Small Grains" }, { value: "9", crop: "Range/Pasture/Grass (Brome, Hay, CRP)" }, { value: "10", crop: "Urban Land" }, { value: "11", crop: "Open Water" }, { value: "12", crop: "Riparian Forest and Woodlands" }, { value: "13", crop: "Wetlands" }, { value: "14", crop: "Other Agricultural Lands (Farmsteads, Feedlots, etc.)" }, { value: "15", crop: "Irrigated Sunflower" }, { value: "16", crop: "Summer Fallow" }, { value: "17", crop: "Roads" }, { value: "18", crop: "Dryland Corn" }, { value: "19", crop: "Dryland Soybeans" }, { value: "20", crop: "Dryland Sorghum" }, { value: "21", crop: "Dryland Dry Edible Beans" }, { value: "22", crop: "Dryland Alfalfa" }, { value: "23", crop: "Dryland Small Grains" }, { value: "24", crop: "Dryland Sunflower" }, { value: "25", crop: "Dryland Sugar Beets" }, { value: "26", crop: "Dryland Potatoes" }, { value: "27", crop: "Irrigated Hay" }, { value: "28", crop: "Irrigated Rotation Pasture" }];
self.Acres = Acres;
}
function PBHEPViewModel() {
var self = this;
//Present Conditions
self.present_conditions = ko.observableArray([
new RowData()
]);
self.present_AddRow = function () {
self.present_conditions.push(new RowData())
}
self.present_RemoveRow = function (row) { self.present_conditions.remove(row) };
//Future Conditions
self.future_conditions = ko.observableArray([
new RowData()
]);
self.future_AddRow = function () {
self.future_conditions.push(new RowData())
}
self.future_RemoveRow = function (row) { self.future_conditions.remove(row) };
//submit the data
self.submit_conditions = function () {
var PC_data = ko.toJSON(self.present_conditions());
var FC_data = ko.toJSON(self.future_conditions());
$.post("/Home/PBHEP", { "PC": PC_data, "FC": FC_data});
}
}
ko.applyBindings(new PBHEPViewModel());
And my HTML is:
<tbody data-bind="foreach:future_conditions">
<tr>
<td style =" text-align:center">
<input class="input-small" type="text" placeholder="Township" data-bind="value: Township"></td>
<td style =" text-align:center">
<input class="input-small" type="text" placeholder="Range"data-bind="value: Range"></td>
<td style =" text-align:center">
<input class="input-small" type="text" placeholder="Section"data-bind="value: Section"></td>
<td style =" text-align:center">
<select name="" data-bind="options: Crop, optionsValue: 'value', optionsText: function (i) { return i.crop }, optionsCaption: 'Choose a Crop...'"></select>
</td>
<td style =" text-align:center">
<input class="input-small" type="text" placeholder="Acres"data-bind="value: Acres"></td>
<td>
<button class="btn btn-small btn btn-danger" type="button" data-bind="click: $root.future_RemoveRow"><i class="icon-minus-sign icon-white"></i></button>
</td>
</tr>
</tbody>
When I do the post I have all the entire array in the crop field where i only want to post the value that has been selected.
How do I achieve this where am I going wrong.
Thank you in advance
For a single-select list, you use the value binding to write the selected value to your viewmodel. See the note near the top of the documentation for details.
Try the below binding:
<select name="" data-bind="options: Crop, value: Crop, optionsText: 'crop', optionsCaption: 'Choose a Crop...'"></select>
This displays the text in the drop down as the crop property of your array items. It also assigns the selected value from the drop down to the Crop property of the RowData object.
You may want to change the name of the array, Crop, to Crops or something to differentiate it from the singular property on the RowData object. It is a little confusing, as is.