Aug
13

Why thousands of landlords could be missing their best-selling option

Author admin    Category Uncategorized     Tags

Property118

Why thousands of landlords could be missing their best-selling option

Landlords across the country are facing one dilemma after another. From proposed changes to tenancy deposits to HMRC’s tougher penalty regime, it’s no wonder so many of the landlords we speak to feel stuck between a rock and a hard place.

Every week, we speak to landlords who believe they have just two choices: wait for the tenant to leave or sell at a huge discount.

The reality is there are often several other options, but many landlords simply never hear about them.

Whether you have one property or an entire portfolio, Landlord Sales Agency specialises in finding the right solution. We sell individual properties, partial portfolios and entire portfolios, regardless of condition, and often complete sales in less than 28 days.

One of the reasons we’re able to achieve such strong results is that we don’t limit ourselves to one type of buyer. Every property is different, so we explore every possible route to a sale. That could mean finding an investor, another landlord, an owner-occupier or, where appropriate, helping the existing tenant buy the property themselves.

Keeping every option open gives landlords the best possible chance of achieving a successful sale at the strongest possible price.

That’s exactly what happened for landlord Ian.

Ian approached Landlord Sales Agency because he had “a rented property which still had the tenant in and I needed to sell the property, hopefully with the tenant in place.”

Within a short space of time, he had been matched with one of our property experts, agreed the sale price and fees, and the property was marketed. Within just one month, a firm offer had been accepted and the buyer had paid a deposit.

As with many tenanted sales, however, the transaction wasn’t completely straightforward. That’s where our team stepped in.

Ian explained: “The purchaser wanted the tenant to vacate. I left this totally in the hands of Landlord Sales Agency, who served notice on the tenant. They were in contact with the tenant and helped her with relocation expenses.”

Everything was resolved without Ian having to deal with the day-to-day stress, the tenant moved out and the sale completed successfully.

Ian said of his experience: “I am extremely happy with the service received and thoroughly recommend Landlord Sales Agency.”

Another landlord, Ali, shared a similar experience.

“Excellent experience using this company. Many other agents were not interested because I had a tenant in situ, but these guys reassured me they would sell the property and contribute towards costs to help make the transaction as smooth as possible.”

He described the service as “5-star” and said the team “goes above and beyond to help.”

We typically achieve 85–90% of vacant possession market value, but we encourage clients to think about that figure differently. Rather than finding cash for estate agency fees, legal costs, tenant incentives, refurbishment, mortgage payments, insurance, council tax and other holding costs, we use a small proportion of the equity already tied up in the properties to fund the sale itself. It is instead of a fees and commission, not in addition to them.

It’s an example of capital deployment — using existing wealth to reduce future spending, minimise risk and achieve a better overall business outcome.

In business, that’s a far more efficient use of capital than paying costs upfront while waiting for a property to become vacant, redecorating it, marketing it, finding a buyer and hoping the sale completes first time.

Depending on when a tenant leaves, whether rent continues to be paid, how much work the property needs and how long the sales process takes, that approach can require 6 to 18 months of ongoing expenditure before the landlord receives a penny from the sale.

By contrast, we use the wealth already locked into the properties being sold to fund the entire exit strategy. Instead of paying estate agency commission, legal fees (when using our independent panel solicitors), tenant cooperation, sales progression and other selling costs from your own pocket, they are covered as part of the transaction.

It allows landlords to preserve cash flow, reduce financial exposure and convert equity into a faster, simpler and more certain exit.

In a time of dilemmas and uncertainty, you may have more options than you think when it comes to selling your rental property. Why not have a no-obligation conversation with Landlord Sales Agency and discover the solution that’s right for you?

(function(){var el=document.getElementById(“ts-607776b5-3f7b-431c-b5cc-fc304603fee3″);if(!el)return;var b=document.body,h=document.documentElement;var dark=b.classList.contains(“dark-mode”)||b.classList.contains(“dark”)||b.classList.contains(“night-mode”)||h.classList.contains(“dark”);if(!dark){var bg=window.getComputedStyle(b).backgroundColor,m=bg.match(/d+/g);if(m)dark=(m[0]*0.299+m[1]*0.587+m[2]*0.114)<128;}el.setAttribute("data-theme",dark?"dark":"light");if(window.turnstile&&el.childElementCount===0){try{window.turnstile.render(el,{sitekey:el.getAttribute("data-sitekey"),theme:el.getAttribute("data-theme")});}catch(e){}}})();

(function(){
var uid = “crm-form-ba09a29b”;
var form = document.getElementById(uid + ‘-form’);
var wrap = document.getElementById(uid);
var msg = wrap.querySelector(‘.crm-message’);
var totalPages = 1;
var curPage = 0;

// ── Conditional logic ────────────────────────────────────────────────
var condMap = {};

function getFieldValue(fieldId) {
var els = form.querySelectorAll(‘[name=”‘ + fieldId + ‘”], [name=”‘ + fieldId + ‘[]”]’);
if (!els.length) return ”;
var first = els[0];
if (first.type === ‘checkbox’ || first.type === ‘radio’) {
var checked = [];
els.forEach(function(el){ if (el.checked) checked.push(el.value); });
return checked.join(‘,’);
}
return first.value;
}

function evalRule(rule) {
var val = getFieldValue(rule.fieldId);
var cmp = rule.value;
switch (rule.operator) {
case ‘is': return val === cmp;
case ‘isnot': return val !== cmp;
case ‘greaterthan': return parseFloat(val) > parseFloat(cmp);
case ‘lessthan': return parseFloat(val) < parseFloat(cmp);
case 'contains': return val.indexOf(cmp) !== -1;
case 'startswith': return val.indexOf(cmp) === 0;
case 'endswith': return val.slice(-cmp.length) === cmp;
default: return false; // fail closed — mirror the CRM shared matcher
}
}

function applyConditionals() {
Object.keys(condMap).forEach(function(fieldId) {
var cond = condMap[fieldId];
var rules = cond.rules || [];
var match = cond.logicType === 'any'
? rules.some(evalRule)
: rules.every(evalRule);
var show = cond.actionType === 'show' ? match : !match;
var wrapper = form.querySelector('[data-field-id="' + fieldId + '"]');
if (!wrapper) {
var el = form.querySelector('[name="' + fieldId + '"], [name="' + fieldId + '[]"]');
if (el) wrapper = el.closest('.crm-field, .crm-half');
}
if (wrapper) wrapper.style.display = show ? '' : 'none';
});
}

form.addEventListener('change', applyConditionals);
form.addEventListener('input', applyConditionals);
applyConditionals();

// ── Required-field validation (Next + Submit) ────────────────────────
// Validate from the form's field config (id + type), NOT the [required]
// HTML attribute: a checkbox group can't carry a meaningful `required`
// (native means "tick every box"), so attribute checks skip it — which is
// why empty checkbox questions slipped past Next straight to submit.
var crmRequired = [{"id":"c364951b-ecb0-4a12-bfa4-9dbe564310e8","type":"name","label":"Name"},{"id":"910107df-b8a8-4541-879f-541cef9449e4","type":"email","label":"Email"},{"id":"3b317ed9-d327-4fe2-b92e-67efede67e6d","type":"phone","label":"Phone"},{"id":"c6fae2f0-c335-452b-aa03-2cc066163d71","type":"textarea","label":"Please give us details of how we can help and the properties in question"},{"id":"34c27d9f-b3d1-4a6d-b720-24000e9fa468","type":"checkbox","label":"Privacy Policy"}];
function crmWrapper(id) {
var w = form.querySelector('[data-field-id="' + id + '"]');
if (!w) { var el = form.querySelector('[name="' + id + '"], [name="' + id + '[]"]'); if (el) w = el.closest('.crm-field, .crm-half'); }
return w;
}
function crmFilled(fld) {
var els = form.querySelectorAll('[name="' + fld.id + '"], [name="' + fld.id + '[]"]');
if (!els.length) return true;
if (['checkbox','radio','product','consent'].indexOf(fld.type) !== -1) { return Array.prototype.some.call(els, function(el){ return el.checked; }); }
return (els[0].value || '').trim() !== '';
}
function crmFirstInvalid(pageIdx) {
for (var i = 0; i < crmRequired.length; i++) {
var fld = crmRequired[i]; var w = crmWrapper(fld.id);
if (!w) continue;
if (w.style.display === 'none') continue;
if (pageIdx != null) { var pd = w.closest('[data-page]'); if (!pd || parseInt(pd.getAttribute('data-page')) !== pageIdx) continue; }
if (!crmFilled(fld)) return fld;
}
return null;
}
// Shows the error in a red box UNDER the field, matching the form's own
// .crm-message error styling, and scrolls to it.
function crmMarkError(w, text) {
if (!w) return;
var e = w.querySelector('.crm-inline-error');
if (!e) { e = document.createElement('div'); e.className = 'crm-inline-error'; w.appendChild(e); }
e.style.cssText = 'background:#fee2e2;color:#991b1b;padding:.55rem .75rem;border-radius:4px;margin-top:.4rem;font-size:.9rem';
e.textContent = text || 'Please answer this before continuing.';
}
function crmClearError(w) { if (!w) return; var e = w.querySelector('.crm-inline-error'); if (e) e.parentNode.removeChild(e); }
function crmReportInvalid(fld) {
var w = crmWrapper(fld.id);
var t = (['checkbox','product'].indexOf(fld.type) !== -1) ? 'Please select at least one option.' : (fld.type === 'radio' ? 'Please choose an option.' : 'Please fill this in.');
crmMarkError(w, t);
if (w && w.scrollIntoView) w.scrollIntoView({ behavior: 'smooth', block: 'center' });
}
form.addEventListener('change', function(e){ var w = e.target && e.target.closest ? e.target.closest('.crm-field, .crm-half, [data-field-id]') : null; if (w) crmClearError(w); });
form.addEventListener('input', function(e){ var w = e.target && e.target.closest ? e.target.closest('.crm-field, .crm-half, [data-field-id]') : null; if (w) crmClearError(w); });

// ── Multi-page navigation ────────────────────────────────────────────

// ── Submit ────────────────────────────────────────────────────────────
var submitBtn = form.querySelector('button[type=submit]');
var btnText = submitBtn ? submitBtn.textContent : 'Submit';

var crmApiUrl = "https://crm-api.property118.com";

function collectFormData() {
var data = {};
for (var j = 0; j < form.elements.length; j++) {
var el = form.elements[j];
if (!el.name) continue;
if (el.type === 'file') continue; // handled by uploadFiles()
if (el.type === 'radio' && !el.checked) continue;
if (el.type === 'checkbox') {
if (!el.checked) continue;
var k = el.name.replace('[]','');
data[k] = data[k] ? data[k].concat([el.value]) : [el.value];
} else {
data[el.name] = el.value;
}
}
// Repeater fields: sub-inputs are named "[][]”.
// Group those flat keys into an array of row objects under the repeater
// id. Plain fields, checkbox “[]” arrays and single-bracket composites
// (name[first], address[city]) don’t match the double-bracket pattern, so
// ordinary submissions are unchanged.
var _repRe = /^(.+?)[(d+)][(.+)]$/;
var _repIds = {};
Object.keys( data ).forEach( function ( key ) {
var m = key.match( _repRe );
if ( ! m ) { return; }
var rid = m[1], row = parseInt( m[2], 10 ), sub = m[3];
_repIds[ rid ] = true;
if ( ! Array.isArray( data[ rid ] ) ) { data[ rid ] = []; }
if ( ! data[ rid ][ row ] || typeof data[ rid ][ row ] !== ‘object’ ) { data[ rid ][ row ] = {}; }
data[ rid ][ row ][ sub ] = data[ key ];
delete data[ key ];
} );
Object.keys( _repIds ).forEach( function ( rid ) {
if ( Array.isArray( data[ rid ] ) ) {
data[ rid ] = data[ rid ].filter( function ( r ) { return r && typeof r === ‘object'; } );
}
} );
// GF auto-substituted {user_agent} / {referer} on hidden fields
// at render time. We do the equivalent right before submit so
// fields whose default value carries these placeholders
// resolve to the browser’s actual values rather than being
// stored as literal “{user_agent}” / “{referer}” strings.
// The last ARTICLE the visitor read (set client-side on post views by
// P118_Article_Views). Used to attribute the enquiry to the article
// even after navigating away or with a stripped/absent referer.
var lastPost = ”;
try {
var lpm = document.cookie.match(/(?:^|;s*)p118_last_post=([^;]+)/);
if (lpm) lastPost = decodeURIComponent(lpm[1]);
} catch (e) {}
var subs = {
‘{user_agent}': navigator.userAgent || ”,
// Prefer the last article read; fall back to the (lossy) HTTP referer.
‘{referer}': lastPost || document.referrer || ”,
‘{last_post}': lastPost || ”,
‘{embed_url}': window.location.href || ”,
};
for (var name in data) {
if (!data.hasOwnProperty(name)) continue;
var v = data[name];
if (typeof v !== ‘string’) continue;
for (var tag in subs) {
if (v.indexOf(tag) !== -1) v = v.split(tag).join(subs[tag]);
}
data[name] = v;
}
// Agent/BDM attribution — read LIVE so it works even on a fully cached
// page (the browser always sees the real URL + cookie). URL ?ataid=/?cid=
// first, then the 30-day agent_id/cid cookies set by atat-tracking.php.
var _qp = new URLSearchParams(window.location.search);
var _ataid = _qp.get(‘ataid’) || (document.cookie.match(/(?:^|;s*)agent_id=([^;]+)/) || [])[1] || ”;
var _cid = _qp.get(‘cid’) || (document.cookie.match(/(?:^|;s*)cid=([^;]+)/) || [])[1] || ”;
if (_ataid) data.agent_id = decodeURIComponent(_ataid);
if (_cid) data.bdm_id = decodeURIComponent(_cid);
return data;
}

function uploadFiles(data) {
var fileInputs = form.querySelectorAll(‘input[type=file][data-crm-file-field]’);
var uploads = [];
fileInputs.forEach(function(el) {
if (!el.files || !el.files[0]) return;
var fd = new FormData();
fd.append(‘file’, el.files[0]);
var fieldName = el.name;
uploads.push(
fetch(crmApiUrl + ‘/public/forms/’ + “08ceeaae-4809-444e-ba0f-88da5836c463″ + ‘/upload’, { method: ‘POST’, body: fd })
.then(function(r) {
if (!r.ok) throw new Error(‘File upload failed (‘ + r.status + ‘)’);
return r.json();
})
.then(function(res) {
if (res.path) data[fieldName] = res.path;
else throw new Error(res.error || ‘File upload failed’);
})
);
});
return Promise.all(uploads).then(function() { return data; });
}

function submitFormData(data) {
var body = new FormData();
body.append(‘action’, ‘p118_crm_submit’);
body.append(‘form_id’, “08ceeaae-4809-444e-ba0f-88da5836c463″);
body.append(‘data’, JSON.stringify(data));
// Embed-page context for GF-style merge tags ({embed_url},
// {embed_post:post_title}, {embed_post:ID}). Captured PHP-side
// at render time, then echoed to JS so the submit fetch can
// forward to V2 as request headers.
body.append(‘embed_url’, “”);
body.append(‘embed_post_id’, “0”);
body.append(‘embed_post_title’, “”);

return fetch(“https://www.property118.com/wp-admin/admin-ajax.php”, { method: ‘POST’, body: body, credentials: ‘same-origin’ })
.then(function(r){ return r.json(); })
.then(function(res){
var p = res.data || res;
if (p && p.success) {
if (p.confirmationType === ‘form’ && p.nextFormId) {
return swapInNextForm(p.nextFormId, p.prefill || {});
}
if (p.confirmationType === ‘redirect’ && p.confirmationRedirectUrl) {
window.location.href = p.confirmationRedirectUrl;
} else {
form.style.display = ‘none';
msg.className = ‘crm-message success';
msg.innerHTML = p.confirmationMessage || ‘Thank you for your submission.';

// Carry the calculator’s own results across. A calculator form
// renders its figures into [data-iht-results] as the visitor
// types; hiding the form hid those too, so the completion
// screen went blank and the visitor lost what they had just
// worked out. Nothing happens on forms without that element.
var resultsEl = form.querySelector(‘[data-iht-results]’);
if (resultsEl && resultsEl.innerHTML.trim()) {
var carried = document.createElement(‘div’);
carried.className = ‘crm-message-results';
carried.innerHTML = resultsEl.innerHTML;
msg.appendChild(carried);
}

// Download link for a generated report, present only when the
// API filed the PDF before responding. Built through the DOM
// rather than concatenated into innerHTML so the URL cannot
// inject markup.
if (p.reportDownloadUrl) {
var dlWrap = document.createElement(‘p’);
dlWrap.className = ‘crm-report-download';
var dl = document.createElement(‘a’);
dl.className = ‘crm-report-button';
dl.href = p.reportDownloadUrl;
dl.target = ‘_blank';
dl.rel = ‘noopener noreferrer';
dl.textContent = ‘Download your report (PDF)';
dlWrap.appendChild(dl);
msg.appendChild(dlWrap);
}

msg.style.display = ‘block';
if (msg.scrollIntoView) {
msg.scrollIntoView({ behavior: ‘smooth’, block: ‘start’ });
}
}
} else {
throw new Error((p && p.error) || ‘Submission failed.’);
}
});
}

// Replace this whole form widget with another form, rendered server-side
// with the carried-over values seeded in. Inline injected via
// innerHTML won’t run, so we re-create each script node to execute it
// (this is what wires up the new form’s submit / conditional logic).
function swapInNextForm(nextFormId, prefill) {
var rbody = new FormData();
rbody.append(‘action’, ‘p118_crm_render_form’);
rbody.append(‘form_id’, nextFormId);
rbody.append(‘prefill’, JSON.stringify(prefill || {}));
return fetch(“https://www.property118.com/wp-admin/admin-ajax.php”, { method: ‘POST’, body: rbody, credentials: ‘same-origin’ })
.then(function(r){ return r.json(); })
.then(function(res2){
var pd = res2.data || res2;
if (!pd || !pd.html) { throw new Error((pd && pd.error) || ‘Could not load the next form.’); }
var frag = document.createElement(‘div’);
frag.innerHTML = pd.html;
var parent = wrap.parentNode;
var nodes = [];
while (frag.firstChild) {
var node = frag.firstChild;
parent.insertBefore(node, wrap);
nodes.push(node);
}
parent.removeChild(wrap);
function reexec(old) {
var s = document.createElement(‘script’);
for (var a = 0; a < old.attributes.length; a++) {
s.setAttribute(old.attributes[a].name, old.attributes[a].value);
}
if (!old.src) { s.textContent = old.textContent; }
old.parentNode.replaceChild(s, old);
}
nodes.forEach(function(n){
if (n.tagName === 'SCRIPT') { reexec(n); }
else if (n.querySelectorAll) {
var scripts = n.querySelectorAll('script');
for (var k = 0; k < scripts.length; k++) { reexec(scripts[k]); }
}
});
var first = nodes[0];
try { if (first && first.scrollIntoView) first.scrollIntoView({ behavior: 'smooth', block: 'start' }); } catch (e) {}
});
}

form.addEventListener('submit', function(e){
e.preventDefault();
// Validate required fields before submitting. Next only guards the pages
// before it, so the final page (and single-page forms) are checked here;
// jump to the first page that has a problem.
var vbad0 = crmFirstInvalid(null);
if (vbad0) { crmReportInvalid(vbad0); return; }
var data = collectFormData();
if (submitBtn) { submitBtn.disabled = true; submitBtn.textContent = 'Processing…'; }
msg.style.display = 'none';

// Standard form (no payment)
uploadFiles(data)
.then(function(d) { return submitFormData(d); })
.catch(function(err){
if (submitBtn) { submitBtn.disabled = false; submitBtn.textContent = btnText; }
msg.className = 'crm-message error';
msg.textContent = err.message;
msg.style.display = 'block';
});
});

// ── Repeater fields (add / remove rows) ──────────────────────────
form.querySelectorAll( '.crm-repeater' ).forEach( function ( rep ) {
var rowsWrap = rep.querySelector( '.crm-repeater-rows' );
var tpl = rep.querySelector( '.crm-repeater-template' );
var addBtn = rep.querySelector( '.crm-repeater-add' );
if ( addBtn && tpl && rowsWrap ) {
addBtn.addEventListener( 'click', function () {
var idx = parseInt( rep.getAttribute( 'data-next-index' ) || '1', 10 );
var tmp = document.createElement( 'div' );
tmp.innerHTML = tpl.innerHTML.split( '__ROW__' ).join( idx );
var row = tmp.firstElementChild;
if ( ! row ) { return; }
row.setAttribute( 'data-row', idx );
rowsWrap.appendChild( row );
rep.setAttribute( 'data-next-index', idx + 1 );
rep.dispatchEvent( new CustomEvent( 'crm-repeater-change', { bubbles: true } ) );
} );
}
if ( rowsWrap ) {
rowsWrap.addEventListener( 'click', function ( e ) {
var btn = e.target.closest ? e.target.closest( '.crm-repeater-remove' ) : null;
if ( ! btn ) { return; }
if ( rowsWrap.querySelectorAll( '.crm-repeater-row' ).length <= 1 ) { return; }
var r = btn.closest( '.crm-repeater-row' );
if ( r ) { r.remove(); }
rep.dispatchEvent( new CustomEvent( 'crm-repeater-change', { bubbles: true } ) );
} );
}
} );
})();

The post Why thousands of landlords could be missing their best-selling option appeared first on Property118.

View Full Article: Why thousands of landlords could be missing their best-selling option

Post comment

Categories

Archives

Calendar

September 2026
M T W T F S S
« Aug    
 123456
78910111213
14151617181920
21222324252627
282930  

Recent Posts

Quick Search

RSS More from Letting Links

Facebook Fan Page