I want to display telephone field on create account page along with the first name and last name. Telephone field is mapped to Address Fields so cannot display telephone field separately and hiding the other address fields.
Help me to display just the telephone field and not the address fields.
Replace the following html file by above given code :- "vendor\magento\module-checkout\view\frontend\web\template\shipping-address\address-renderer\default.html
<!--
/**
* Copyright © 2016 Magento. All rights reserved.
* See COPYING.txt for license details.
*/
-->
<div class="shipping-address-item" data-bind="css: isSelected() ? 'selected-item' : 'not-selected-item'">
<!-- ko text: address().firstname --><!-- /ko --> <!-- ko text: address().lastname --><!-- /ko --><br/>
<!-- ko text: address().telephone --><!-- /ko --><br/>
<!-- ko if: (address().isEditable()) -->
<button type="button"
class="action edit-address-link"
data-bind="click: editAddress, visible: address().isEditable()">
<span data-bind="i18n: 'Edit'"></span>
</button>
<!-- /ko -->
<button type="button" data-bind="click: selectAddress" class="action action-select-shipping-item">
<span data-bind="i18n: 'Ship Here'"></span>
</button>
</div>
Related
<span class="counter qty empty"
data-bind="css: { empty: !!getCartParam('summary_count') == false }, blockLoader: isLoading">
<span class="counter-number">
<!-- ko if: getCartParam('summary_count') --><!-- ko text: getCartParam('summary_count') --><!-- /ko --><!-- /ko -->
<!-- ko ifnot: getCartParam('summary_count') --><!-- /ko -->
</span>
<span class="counter-label">
<!-- ko i18n: 'items' --><!-- /ko -->
</span>
</span>
the span counter bind some data via KnockoutJS! , i need to know the before and after data bind states in the span ??
There is a beforeChange event that you can subscribe to in your view model:
myViewModel.counterObservable.subscribe(function(oldValue) {
alert("The counters's previous value is " + oldValue);
}, null, "beforeChange");
I want to set up a partial to render a generic, customizable modal. {{> myModal }}.
I want to customize the modal from the calling view by sending an object.
I have tried the approach as recommended here: Passing an array of objects to a partial - handlebars.js
Here is my code from within the view which calls the partial:
{{# getJsonContext '
{
"id": "deleteModal",
"title": "Are you sure?",
"formId": "delete-form",
"body": "Press Yes to delete this record. Press No to cancel."
}
'}}
{{> myModal this }}
{{/ getJsonContext }}
Here is my helper:
getJsonContext: function(data, options) {
console.log(data); <-- The result is correct.
let jsonReturn = JSON.parse(data);
console.log(jsonReturn.title); <-- The result is correct.
return jsonReturn;
},
Here is my partial:
<div class="modal fade" id="{{ id }}">
<div class="modal-dialog">
<div class="modal-content">
<!-- Modal Header -->
<div class="modal-header bg-light">
<h4 class="modal-title">{{ title }}</h4>
<button type="button" class="close" data-dismiss="modal">×</button>
</div>
<!-- Form -->
<form id="{{ formId }}" method="post">
<!-- Modal body -->
<div class="modal-body">
{{ body }}
</div>
<!-- Modal footer -->
<div class="modal-footer rounded-bottom bg-light">
</div>
</form>
</div>
</div>
</div>
I expect the partial view to render the customized modal.
The partial does not seem to render at all. When I "View Page Source" in the browser, in the place of all of the partial <html>, all it shows is [object Object].
If I place the {{> myModal this}} outside of the helper, "View Page Source" shows all the modal's <html>, but naturally, the id, title, formId and body are all blank (null).
After racking my brain with lots of trial and error and research, I finally found out the problem. I had to pass the JSON as a named parameter in the main view's call to the partial. The syntax should have been:
{{> jeff-modal <anyVariableName> = getJsonContext }}
I finished up and made my generic {{> jeff-modal }} accept a list of buttons, which can be customized.
The modal is now useful as a generic, customizable, simple modal which can be rendered as a partial from within any view to require the user to press one of x-number of buttons to make a choice.
Example
The main (calling) view has a list of journal entries (transactions) in date order. For each transaction, there is a clickable "delete" icon. The modal opens when the user presses the icon. When the modal is opened, we need to know which transaction to delete. We have its _id.
After setting up the table and columns in <html> and starting an {{# each }} iterator, the following is how the "delete" icon is set up for each transaction. Notice how the data-id's value is set to the transaction's _id property:
<!-- table stuff up here -->
{{# each transactions}}
<tr class="journal-entry-row">
<!-- some `<td>`'s -->
<span class="journalData">
<a href='#' class="open-deleteDialog"
data-id="{{this._id}}" data-backdrop="static"
data-toggle="modal" data-target="#deleteModal">
<span class="material-icons md-24 md-dark">delete</span>
</a>
</span>
<!-- more table stuff -->
{{/ each }}
The material-icons, above, can be found here: https://material.io/icons/
"delete" is a trash can.
Below is the javascript to set the onclick for all the trash cans. Notice how the transaction's _id makes the trip from the <html> into the javascript via the data-id (above). (I thought that was pretty clever, whoever thought of it.)
Also, since our custom modal was assigned an id of "delete-form", we can get it to set the modal's <form> action.
Finally, a little CSS is added to highlight the row being deleted.
$(document).on("click", ".open-deleteDialog", function () {
var myTransactionId = $(this).data('id');
// Set form action to call delete with _id parameter
$("#delete-form").attr("action", "/transaction/delete?_id=" + myTransactionId );
// Highlight the selected row.
$(this).closest(".journal-entry-row").addClass("table-warning");
});
Now, let's go back to the calling view after the end of the <table>. This is where the modal is called within the handlebars helper block (but only when the trash can is clicked):
<!-- The Delete modal -->
{{# getJsonContext '
{
"id": "deleteModal",
"title": "Are you sure?",
"formId": "delete-form",
"body": "Press \"Yes\" to delete this record. Press \"No\" to cancel.",
"buttons":
[
{ "type": "submit", "onclick": "", "class": "btn btn-primary", "text": "Yes" },
{ "type": "button", "onclick": "removeHighlightEffect()", "class": "btn btn-secondary", "dataDismiss": "modal", "text": "No" }
]
}'
}}
{{> jeff-modal options = getJsonContext }}
{{/ getJsonContext }}
Here's the helper:
getJsonContext: function(data, options) {
let jsonReturn = options.fn(JSON.parse(data));
return jsonReturn;
},
Finally, the partial {{> jeff-modal }}:
<div class="modal fade" id="{{ id }}">
<div class="modal-dialog">
<div class="modal-content">
<!-- Modal Header -->
<div class="modal-header bg-light">
<h4 class="modal-title">{{ title }}</h4>
<button type="button" class="close" data-dismiss="modal">×</button>
</div>
<!-- Form -->
<form id="{{ formId }}" method="post">
<!-- Modal body -->
<div class="modal-body">
{{ body }}
</div>
<!-- Modal footer -->
<div class="modal-footer rounded-bottom bg-light">
{{# each buttons }}
<button type = "{{ type }}" onclick = "{{ onclick }}" class = "{{ class }}" data-dismiss = "{{ dataDismiss }}" >{{ text }}</button>
{{/ each }}
</div>
</form>
</div>
</div>
</div>
I am not sure whether I can call multiple instances of this modal from the same view with different titles, bodies, buttons, etc. Some tweaking might be required for that, and I'm not going to worry about it until the need arises.
I have a dynamic form that's using <core-ajax> to bind data into multiple <paper-dropdown-menu>'s. My question: What is the preferred way to change the data in each dropdown based upon the previous one's selection. Right now, there is no javascript for it, only Polymer data-binding. Here is the code:
<polymer-element name="example-element" attributes="">
<template>
<link rel="stylesheet" href="example-element.css">
<core-ajax auto
url="http://example.json"
response="{{regionData}}"
handleAs="json">
</core-ajax>
<!-- global user object -->
<pvc-globals id="globals" values="{{globals}}"></pvc-globals>
<!-- page container -->
<div class="background" vertical layout>
<!-- toolbar -->
<template is="auto-binding">
<!-- Add teams dialog -->
<paper-action-dialog heading="Add A Example" backdrop autoCloseDisabled
id="addTeamDialog">
<p>Once this form is complete, you will have a new example on your account.</p>
<br>
<!-- Region Name -->
<paper-dropdown-menu label="Choose Your Region" style="width: 100%;">
<paper-dropdown class="dropdown">
<core-menu class="menu" selected="{{selection}}">
<template repeat="{{region in regionData}}">
<paper-item name="{{region.name}}">{{region.name}}</paper-item>
</template>
</core-menu>
</paper-dropdown>
</paper-dropdown-menu>
<br><br>
<!-- State Name depending on what region you choose -->
<paper-dropdown-menu label="Choose Your State" style="width: 100%;">
<paper-dropdown class="dropdown">
<core-menu class="menu">
<template ref="{{region.name}}" repeat="{{region, regionIndex in regionData}}">
<paper-item>{{region.states[regionIndex]}}</paper-item>
</template>
</core-menu>
</paper-dropdown>
</paper-dropdown-menu>
<br><br>
<!-- Club Name -->
<paper-dropdown-menu label="Choose Your Club depending on what region you choose" style="width: 100%;">
<paper-dropdown class="dropdown">
<core-menu class="menu">
<template repeat="{{region, regionIndex in regionData}}">
<template repeat="{{clubs in region.clubs}}">
<paper-item>{{clubs.name}}</paper-item>
</template>
</template>
</core-menu>
</paper-dropdown>
</paper-dropdown-menu>
<br><br>
<!-- Team Name -->
<paper-dropdown-menu label="Choose Your Team" style="width: 100%;">
<paper-dropdown class="dropdown">
<core-menu class="menu">
<template repeat="{{region, regionIndex in regionData}}">
<template repeat="{{clubs in region.clubs}}">
<paper-item>{{clubs.teams[regionIndex]}}</paper-item>
</template>
</template>
</core-menu>
</paper-dropdown>
</paper-dropdown-menu>
<!-- <paper-input-decorator label="Your Team Name" floatingLabel
error="Team Name is required!" autovalidate>
<input is="core-input" type="text" value="{{teamName}}" required>
</paper-input-decorator> -->
<paper-button dismissive on-tap="{{openInfo}}">More Info...</paper-button>
<paper-button affirmative>Cancel</paper-button>
<paper-button affirmative>Add Team</paper-button>
</paper-action-dialog>
<!-- more info dialog (At time, adding `backdrop` attr to this caused error on close) -->
<paper-dialog heading="More Info For Adding Teams" transition="core-transition-top"
id="infoDialog">
<p>If you're region or team is missing, please email us at
info#mintonette.io so we can contact the
neccessary region/authorities to request your addition to join our community!</p>
</paper-dialog>
<!-- toast -->
<paper-toast id="toast1" text="{{message}}" onclick="discardDraft(el)"></paper-toast>
</div>
</template>
<script src="example-element.js"></script>
</polymer-element>
Here is my example of dependent(cascading) drop-down's: JSBin
It is commented, but shortly this is what it does:
it assumes that there is saved state(in the DB) and at load it
initiate the drop-downs according to that state.
it catches selection changes(for storing them after).
Found what I feel to be the most 'Polymer-way' possible to this question (until a Polymer team member answers it). Once you have access to your JSON data via <core-ajax> element, then bind and loop through it in your <paper-dropdown-menu> like so:
<core-ajax auto
url="http://jsonexample.com/example.json"
response="{{yourData}}"
handleAs="json">
</core-ajax>
<!-- Region Name -->
<paper-dropdown-menu label="Your Label" style="width: 100%;">
<paper-dropdown class="dropdown">
<core-menu class="menu" selected="{{selection}}" on-core-select="{{DDSelected}}">
<template repeat="{{something in yourData}}">
<paper-item name="{{something.name}}">{{something.name}}</paper-item>
</template>
</core-menu>
</paper-dropdown>
</paper-dropdown-menu>
Notice that on the <core-menu> element there is the on-core-selected attribute that binds to a function in our script, which looks like this:
regionSelected: function(e) {
var convert = [];
// save selected item
this.item = this.DDSelection;
// Loop through ajax data to find obj selected that matches selection
for (var i = 0; i <= this.yourData.length - 1; i++) {
if (this.yourData[i].name === this.item) {
this.yourObj = this.yourData[i];
// convert obj to array b/c Polymer doesn't loop -> obj
convert.push(this.yourObj);
this.convert = convert;
}
}
}
What this is basically doing is taking the selection that the user chose and looping through your ajax data to find a matching property name. Once it has, then convert that object into an array (if necessary). This is crucial because as of now, Polymer only loops through arrays - not objects. Then, store it as a variable called convert
Once you do this, in your next dropdown, loop through convert and you are golden:
...
<paper-dropdown-menu label="Choose Your Second" style="width: 100%;"
disabled?="{{!selection}}">
<paper-dropdown class="dropdown">
<core-menu class="menu">
<template repeat="{{key, index in convert}}">
<template repeat="{{prop in key.props}}">
<paper-item>{{prop}}</paper-item>
</template>
</template>
</core-menu>
</paper-dropdown>
</paper-dropdown-menu>
A good UX move is to also disable the dropdown until the first has been selected. Notice the disabled?="{{selection}}" attribute on the <paper-dropdown-menu> element which is doing that...
That's it!
I have a list of items and I want to highlight the "selected" one (this is linked to another interface, so using pure CSS will not work). I'm guessing I could do this:
<!-- ko if: isSelected -->
<span class="selected">
<!-- ko endif -->
<span class="myItem">content goes here</span>
<!-- ko if: isSelected -->
</span>
<!-- ko endif -->
and maybe even this:
<span class="myItem<!-- ko if: isSelected --> selected<!-- ko endif -->">
content goes here
</span>
But I suspect there is a better way. I have been unable to find it.
According to the documentation here: http://knockoutjs.com/documentation/css-binding.html
<span class="myItem" data-bind="html: name, css: { selected: isSelected()"><span>
Works great!
I am receiving the following error when trying to edit some of my Component Presentations using SiteEdit.
Sys.FormatException: Could not get the type info from component xml
schema. Field: cf_tcm:32-204267_title XPath:
Content/custom:Content/custom:title[1]
It's strange because some of the Components with the same Template work fine (these do not have an image set,but the ones with an image set do not work).
Here is the code for my CT:
<div class="column v-2 siteedit">
<!-- TemplateBeginIf cond = "Component.thumbnail" -->
<!-- TemplateBeginIf cond = "Component.image" -->
<a href="##Component.Fields.image##" class="fb ajax">
<!-- TemplateEndIf -->
<img src="##Component.Fields.thumbnail##" class="align-left"
alt="##thumbnail0.Metadata.alt##" height="69" width="99"/>
<!-- TemplateBeginIf cond = "Component.image" -->
</a>
<!-- TemplateEndIf -->
<!-- TemplateEndIf -->
<h2>
<tcdl:ComponentField name="title">##Component.Fields.title##</tcdl:ComponentField>
</h2>
<p>##Component.Fields.summary##</p>
</div>
(I have removed other editable fields just to make sure that it wasn't a problem with a specific field)
Any ideas?
Update
As requested here's my (anonymized) HTML, the 1st and 3rd components have the issue, the middle one is fine:
<div class="general-content columns-three">
<div class="column v-2 siteedit" style="height: 209px; ">
<!-- Start SiteEdit Component Presentation: {
"ID" : "97829119-68f0-4e41-9862-b042d480cb71",
"ComponentID" : "tcm:32-204859",
"ComponentTemplateID" : "tcm:32-204536-32",
"Version" : "2",
"IsQueryBased" : false
} -->
<a href="http://REDACTED:84/_images/REDACTED.png?__Proxy=0" class="fb ajax" target="_self">
<img src="/_images/REDACTED.gif" class="align-left" alt="REDACTED" height="69" width="99">
</a>
<h2>
<span style="">
<!-- Start SiteEdit Component Field: {
"ID" : "cf_tcm:32-204267_title",
"XPath" : "tcm:Content/custom:Content/custom:title[1]",
"IsMultiValued" : false
} -->REDACTED
</span>
</h2>
<p>REDACTED</p>
</div>
<div class="column v-2 siteedit" style="height: 209px; ">
<!-- Start SiteEdit Component Presentation: {
"ID" : "2933b5e0-2006-440d-bc03-2224650bdd7d",
"ComponentID" : "tcm:32-204268",
"ComponentTemplateID" : "tcm:32-204536-32",
"Version" : "5",
"IsQueryBased" : false
} -->
<h2> <span style="">
<!-- Start SiteEdit Component Field: {
"ID" : "cf_tcm:32-204268_title",
"XPath" : "tcm:Content/custom:Content/custom:title[1]",
"IsMultiValued" : false} -->REDACTED</span>
</h2>
<p>REDACTED</p>
</div>
<div class="column v-2 siteedit" style="height: 209px; ">
<!-- Start SiteEdit Component Presentation: {
"ID" : "fac3c467-7c71-4be9-b319-8a35524ee172",
"ComponentID" : "tcm:32-204860",
"ComponentTemplateID" : "tcm:32-204536-32",
"Version" : "2",
"IsQueryBased" : false
} -->
<a href="http://REDACTED:84/_images/REDACTED.png?__Proxy=0" class="fb ajax" target="_self">
<img src="/_images/REDACTED.gif" class="align-left" alt="REDACTED" height="69" width="99">
</a>
<h2> <span style="">
<!-- Start SiteEdit Component Field: {
"ID" : "cf_tcm:32-204269_title",
"XPath" : "tcm:Content/custom:Content/custom:title[1]",
"IsMultiValued" : false
} -->REDACTED</span>
</h2>
<p>REDACTED</p>
</div>
</div>
I explained when that error message appears here: "Could not get the type info from component xml schema" when loading a page in SiteEdit 2009
Your use-case may be different from that question, the product always shows this for the same reason: it can't find a field (that is identified in a <!-- Start SiteEdit Component Field command) in the current Component (that is identified in the enclosing <!-- Start SiteEdit Component Presentation command).
Given your error message:
cf_tcm:32-204267_title XPath: Content/custom:Content/custom:title[1]
It seems like Component tcm:32-204267 doesn't have a field named title.
In these cases it is always easiest if you look at the HTML that SiteEdit ends up processing, so what your staging/preview server returns. Find the title field and its enclosing Component Presentation and verify that indeed that Component Presentation has a field named title.
If you'd like a more direct answer to "what am I doing wrong?", add the relevant HTML-with-the-SiteEdit-commands to your question and I'll update my answer to match.
Update based on the HTML provided
If I look at the IDs of the Component and Fields you provided:
Component: tcm:32-204859 Field: cf_tcm:32-204267_title
Component: tcm:32-204268 Field: cf_tcm:32-204268_title
Component: tcm:32-204860 Field: cf_tcm:32-204269_title
The ID in the JSON is only used by SiteEdit to ensure some meaningless uniqueness. But in this case the Field ID seems to indicate from which Component the field comes.
If you then look at the data closely, you can see that for Component 2 the field points to the same Component. For Components 1 and 3 the fields actually point to another Component. Again, the ID properties of the Field commands are in themselves not used. But the relation between what works and what doesn't seems to coincide pretty well with the knowledge that SiteEdit loads the Schema of the Component indicated in the containing Component Presentation command and cannot find the field at the XPath indicated in the Component Field command.
I suspect that in #1 and #3 you have put some regular Component on the page, but are rendering the title of a Multimedia Component that is linked that Component. In #2 you are most likely rendering the title of an MMC that is explicitly put on the page.